Passed
Push — main ( c100f9...14c5bb )
by Siad
07:13
created

DefaultPDOQuerySplitter::nextQuery()   F

Complexity

Conditions 23
Paths 122

Size

Total Lines 89
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 46
CRAP Score 23.0051

Importance

Changes 0
Metric Value
eloc 47
c 0
b 0
f 0
dl 0
loc 89
rs 3.9833
ccs 46
cts 47
cp 0.9787
cc 23
nc 122
nop 0
crap 23.0051

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
/**
4
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
14
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
 *
16
 * This software consists of voluntary contributions made by many individuals
17
 * and is licensed under the LGPL. For more information please see
18
 * <http://phing.info>.
19
 */
20
21
namespace Phing\Task\System\Pdo;
22
23
use Phing\Io\Reader;
24
use Phing\Util\StringHelper;
25
26
/**
27
 * Splits SQL source into queries using simple regular expressions.
28
 *
29
 * Extracted from PDOSQLExecTask::runStatements()
30
 *
31
 * @author  Hans Lellelid <[email protected]>
32
 * @author  Alexey Borzov <[email protected]>
33
 */
34
class DefaultPDOQuerySplitter extends PDOQuerySplitter
35
{
36
    /**
37
     * Delimiter type, one of PDOSQLExecTask::DELIM_ROW or PDOSQLExecTask::DELIM_NORMAL.
38
     *
39
     * @var string
40
     */
41
    private $delimiterType;
42
43
    /**
44
     * Leftover SQL from previous line.
45
     *
46
     * @var string
47
     */
48
    private $sqlBacklog = '';
49
50
    /**
51
     * Constructor, sets the parent task, reader with SQL source and delimiter type.
52
     *
53
     * @param string $delimiterType
54
     */
55 3
    public function __construct(PDOSQLExecTask $parent, Reader $reader, $delimiterType = PDOSQLExecTask::DELIM_NORMAL)
56
    {
57 3
        parent::__construct($parent, $reader);
58 3
        $this->delimiterType = $delimiterType;
59 3
    }
60
61
    /**
62
     * Returns next query from SQL source, null if no more queries left.
63
     *
64
     * In case of "row" delimiter type this searches for strings containing only
65
     * delimiters. In case of "normal" delimiter type, this uses simple regular
66
     * expression logic to search for delimiters.
67
     *
68
     * @return null|string
69
     */
70 3
    public function nextQuery(): ?string
71
    {
72 3
        $sql = '';
73 3
        $hasQuery = false;
74
75 3
        while (($line = $this->sqlReader->readLine()) !== null) {
76 3
            $delimiter = $this->parent->getDelimiter();
77 3
            $project = $this->parent->getOwningTarget()->getProject();
78 3
            if (!$this->keepformat) {
79 3
                $line = trim($line);
80
            }
81 3
            if ($this->expandProperties) {
82 3
                $line = $project->replaceProperties($line);
83
            }
84
85
            if (
86 3
                !$this->keepformat
87 3
                && ($line !== $delimiter)
88 3
                && (StringHelper::startsWith('//', $line)
89 3
                    || StringHelper::startsWith('--', $line)
90 3
                    || StringHelper::startsWith('#', $line))
91
            ) {
92 3
                continue;
93
            }
94
95
            if (
96 3
                strlen($line) > 4
97 3
                && stripos($line, 'REM ') === 0
98
            ) {
99
                continue;
100
            }
101
102
            // MySQL supports defining new delimiters
103 3
            if (preg_match('/DELIMITER [\'"]?([^\'" $]+)[\'"]?/i', $line, $matches)) {
104 1
                $this->parent->setDelimiter($matches[1]);
105
106 1
                continue;
107
            }
108
109 3
            if ('' !== $this->sqlBacklog) {
110 2
                $sql = $this->sqlBacklog;
111 2
                $this->sqlBacklog = '';
112
            }
113
114 3
            $sql .= ' ' . $line . "\n";
115
116
            // SQL defines "--" as a comment to EOL
117
            // and in Oracle it may contain a hint
118
            // so we cannot just remove it, instead we must end it
119 3
            if (!$this->keepformat && false !== strpos((string) $line, '--')) {
120 2
                $sql .= "\n";
121
            }
122
123
            // DELIM_ROW doesn't need this (as far as i can tell)
124 3
            if (PDOSQLExecTask::DELIM_NORMAL === $this->delimiterType) {
125 2
                $reg = "#((?:\"(?:\\\\.|[^\"])*\"?)+|'(?:\\\\.|[^'])*'?|" . preg_quote($delimiter, null) . ')#';
126
127 2
                $sqlParts = preg_split($reg, $sql, 0, PREG_SPLIT_DELIM_CAPTURE);
128 2
                $this->sqlBacklog = '';
129 2
                foreach ($sqlParts as $sqlPart) {
130
                    // we always want to append, even if it's a delim (which will be stripped off later)
131 2
                    $this->sqlBacklog .= $sqlPart;
132
133
                    // we found a single (not enclosed by ' or ") delimiter, so we can use all stuff before the delim as the actual query
134 2
                    if ($sqlPart === $delimiter) {
135 2
                        $sql = $this->sqlBacklog;
136 2
                        $this->sqlBacklog = '';
137 2
                        $hasQuery = true;
138
                    }
139
                }
140
            }
141
142 3
            if ($hasQuery || (PDOSQLExecTask::DELIM_ROW === $this->delimiterType && $line === $delimiter)) {
143
                // this assumes there is always a delimter on the end of the SQL statement.
144 3
                return StringHelper::substring(
145 3
                    $sql,
146 3
                    0,
147 3
                    strlen($sql) - strlen($delimiter)
148 3
                    - (PDOSQLExecTask::DELIM_ROW === $this->delimiterType ? 2 : 1)
149
                );
150
            }
151
        }
152
153
        // Catch any statements not followed by ;
154 3
        if ('' !== $sql) {
155 2
            return $sql;
156
        }
157
158 3
        return null;
159
    }
160
}
161