1
<?php
2
/**
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the LGPL. For more information please see
17
 * <http://phing.info>.
18
 *
19
 * @package phing.tasks.ext.pdo
20
 */
21

22
/**
23
 * Splits SQL source into queries using simple regular expressions
24
 *
25
 * Extracted from PDOSQLExecTask::runStatements()
26
 *
27
 * @author  Hans Lellelid <hans@xmpl.org>
28
 * @author  Alexey Borzov <avb@php.net>
29
 * @package phing.tasks.ext.pdo
30
 */
31
class DefaultPDOQuerySplitter extends PDOQuerySplitter
32
{
33
    /**
34
     * Delimiter type, one of PDOSQLExecTask::DELIM_ROW or PDOSQLExecTask::DELIM_NORMAL
35
     *
36
     * @var string
37
     */
38
    private $delimiterType;
39

40
    /**
41
     * Leftover SQL from previous line
42
     *
43
     * @var string
44
     */
45
    private $sqlBacklog = '';
46

47
    /**
48
     * Constructor, sets the parent task, reader with SQL source and delimiter type
49
     *
50
     * @param PDOSQLExecTask $parent
51
     * @param Reader $reader
52
     * @param string $delimiterType
53
     */
54 1
    public function __construct(PDOSQLExecTask $parent, Reader $reader, $delimiterType = PDOSQLExecTask::DELIM_NORMAL)
55
    {
56 1
        parent::__construct($parent, $reader);
57 1
        $this->delimiterType = $delimiterType;
58
    }
59

60
    /**
61
     * Returns next query from SQL source, null if no more queries left
62
     *
63
     * In case of "row" delimiter type this searches for strings containing only
64
     * delimiters. In case of "normal" delimiter type, this uses simple regular
65
     * expression logic to search for delimiters.
66
     *
67
     * @return string|null
68
     */
69 1
    public function nextQuery()
70
    {
71 1
        $sql = "";
72 1
        $hasQuery = false;
73

74 1
        while (($line = $this->sqlReader->readLine()) !== null) {
75 1
            $delimiter = $this->parent->getDelimiter();
76 1
            $project = $this->parent->getOwningTarget()->getProject();
77 1
            $line = $project->replaceProperties(trim($line));
78

79
            if (
80 1
                ($line != $delimiter)
81 1
                && (StringHelper::startsWith("//", $line)
82 1
                    || StringHelper::startsWith("--", $line)
83 1
                    || StringHelper::startsWith("#", $line))
84
            ) {
85 1
                continue;
86
            }
87

88
            if (
89 1
                strlen($line) > 4
90 1
                && strtoupper(substr($line, 0, 4)) == "REM "
91
            ) {
92 0
                continue;
93
            }
94

95
            // MySQL supports defining new delimiters
96 1
            if (preg_match('/DELIMITER [\'"]?([^\'" $]+)[\'"]?/i', $line, $matches)) {
97 1
                $this->parent->setDelimiter($matches[1]);
98 1
                continue;
99
            }
100

101 1
            if ($this->sqlBacklog !== "") {
102 1
                $sql = $this->sqlBacklog;
103 1
                $this->sqlBacklog = "";
104
            }
105

106 1
            $sql .= " " . $line . "\n";
107

108
            // SQL defines "--" as a comment to EOL
109
            // and in Oracle it may contain a hint
110
            // so we cannot just remove it, instead we must end it
111 1
            if (strpos($line, "--") !== false) {
112 1
                $sql .= "\n";
113
            }
114

115
            // DELIM_ROW doesn't need this (as far as i can tell)
116 1
            if ($this->delimiterType == PDOSQLExecTask::DELIM_NORMAL) {
117 1
                $reg = "#((?:\"(?:\\\\.|[^\"])*\"?)+|'(?:\\\\.|[^'])*'?|" . preg_quote($delimiter) . ")#";
118

119 1
                $sqlParts = preg_split($reg, $sql, 0, PREG_SPLIT_DELIM_CAPTURE);
120 1
                $this->sqlBacklog = "";
121 1
                foreach ($sqlParts as $sqlPart) {
122
                    // we always want to append, even if it's a delim (which will be stripped off later)
123 1
                    $this->sqlBacklog .= $sqlPart;
124

125
                    // we found a single (not enclosed by ' or ") delimiter, so we can use all stuff before the delim as the actual query
126 1
                    if ($sqlPart === $delimiter) {
127 1
                        $sql = $this->sqlBacklog;
128 1
                        $this->sqlBacklog = "";
129 1
                        $hasQuery = true;
130
                    }
131
                }
132
            }
133

134 1
            if ($hasQuery || ($this->delimiterType == PDOSQLExecTask::DELIM_ROW && $line == $delimiter)) {
135
                // this assumes there is always a delimter on the end of the SQL statement.
136 1
                $sql = StringHelper::substring(
137 1
                    $sql,
138 1
                    0,
139 1
                    strlen($sql) - strlen($delimiter)
140 1
                    - ($this->delimiterType == PDOSQLExecTask::DELIM_ROW ? 2 : 1)
141
                );
142

143 1
                return $sql;
144
            }
145
        }
146

147
        // Catch any statements not followed by ;
148 1
        if ($sql !== "") {
149 1
            return $sql;
150
        }
151

152 1
        return null;
153
    }
154
}

Read our documentation on viewing source code .

Loading