Completed
Push — master ( 20b0ec...0fa80a )
by Siad
15:26
created

DefaultPDOQuerySplitter::nextQuery()   D

Complexity

Conditions 19
Paths 32

Size

Total Lines 84
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 43
CRAP Score 19.0042

Importance

Changes 0
Metric Value
cc 19
eloc 44
c 0
b 0
f 0
nc 32
nop 0
dl 0
loc 84
ccs 43
cts 44
cp 0.9773
crap 19.0042
rs 4.5166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 <[email protected]>
28
 * @author  Alexey Borzov <[email protected]>
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 2
    public function __construct(PDOSQLExecTask $parent, Reader $reader, $delimiterType = PDOSQLExecTask::DELIM_NORMAL)
55
    {
56 2
        parent::__construct($parent, $reader);
57 2
        $this->delimiterType = $delimiterType;
58 2
    }
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 2
    public function nextQuery()
70
    {
71 2
        $sql = "";
72 2
        $hasQuery = false;
73
74 2
        while (($line = $this->sqlReader->readLine()) !== null) {
75 2
            $delimiter = $this->parent->getDelimiter();
76 2
            $project = $this->parent->getOwningTarget()->getProject();
77 2
            $line = $project->replaceProperties(trim($line));
78
79
            if (
80 2
                ($line != $delimiter)
81 2
                && (StringHelper::startsWith("//", $line)
82 2
                    || StringHelper::startsWith("--", $line)
83 2
                    || StringHelper::startsWith("#", $line))
84
            ) {
85 2
                continue;
86
            }
87
88
            if (
89 2
                strlen($line) > 4
90 2
                && strtoupper(substr($line, 0, 4)) == "REM "
91
            ) {
92
                continue;
93
            }
94
95
            // MySQL supports defining new delimiters
96 2
            if (preg_match('/DELIMITER [\'"]?([^\'" $]+)[\'"]?/i', $line, $matches)) {
97 1
                $this->parent->setDelimiter($matches[1]);
98 1
                continue;
99
            }
100
101 2
            if ($this->sqlBacklog !== "") {
102 1
                $sql = $this->sqlBacklog;
103 1
                $this->sqlBacklog = "";
104
            }
105
106 2
            $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 2
            if (strpos($line, "--") !== false) {
112 2
                $sql .= "\n";
113
            }
114
115
            // DELIM_ROW doesn't need this (as far as i can tell)
116 2
            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 2
            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 2
                $sql = StringHelper::substring(
137 2
                    $sql,
138 2
                    0,
139 2
                    strlen($sql) - strlen($delimiter)
140 2
                    - ($this->delimiterType == PDOSQLExecTask::DELIM_ROW ? 2 : 1)
141
                );
142
143 2
                return $sql;
144
            }
145
        }
146
147
        // Catch any statements not followed by ;
148 2
        if ($sql !== "") {
149 2
            return $sql;
150
        }
151
152 2
        return null;
153
    }
154
}
155