Failed Conditions
Pull Request — master (#3074)
by Sergei
31:20
created

PDOStatement   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 218
Duplicated Lines 0 %

Test Coverage

Coverage 69.57%

Importance

Changes 0
Metric Value
wmc 38
dl 0
loc 218
ccs 48
cts 69
cp 0.6957
rs 8.3999
c 0
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A execute() 0 12 3
A convertFetchMode() 0 11 3
A bindValue() 0 8 2
B setFetchMode() 0 20 5
A convertParamType() 0 7 2
A bindParam() 0 8 2
B fetch() 0 20 8
A fetchColumn() 0 6 2
A closeCursor() 0 8 2
B fetchAll() 0 20 8
A __construct() 0 3 1
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 MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\DBAL\Driver;
21
22
use Doctrine\DBAL\FetchMode;
23
use Doctrine\DBAL\ParameterType;
24
use PDO;
25
26
/**
27
 * The PDO implementation of the Statement interface.
28
 * Used by all PDO-based drivers.
29
 *
30
 * @since 2.0
31
 */
32
class PDOStatement extends \PDOStatement implements Statement
33
{
34
    /**
35
     * @var int[]
36
     */
37
    private const PARAM_TYPE_MAP = [
38
        ParameterType::NULL         => PDO::PARAM_NULL,
39
        ParameterType::INTEGER      => PDO::PARAM_INT,
40
        ParameterType::STRING       => PDO::PARAM_STR,
41
        ParameterType::LARGE_OBJECT => PDO::PARAM_LOB,
42
        ParameterType::BOOLEAN      => PDO::PARAM_BOOL,
43
    ];
44
45
    /**
46
     * @var int[]
47
     */
48
    private const FETCH_MODE_MAP = [
49
        FetchMode::ASSOCIATIVE     => PDO::FETCH_ASSOC,
50
        FetchMode::NUMERIC         => PDO::FETCH_NUM,
51
        FetchMode::MIXED           => PDO::FETCH_BOTH,
52
        FetchMode::STANDARD_OBJECT => PDO::FETCH_OBJ,
53
        FetchMode::COLUMN          => PDO::FETCH_COLUMN,
54
        FetchMode::CUSTOM_OBJECT   => PDO::FETCH_CLASS,
55
    ];
56
57
    /** @var PDOConnection|null */
58
    private $connection;
59
60
    /**
61
     * Protected constructor.
62
     *
63
     * @todo do we need to keep BC here? Or can we make $connection mandatory?
64
     */
65 257
    protected function __construct(?PDOConnection $connection = null)
66
    {
67 257
        $this->connection = $connection;
68 257
    }
69
70
    /**
71
     * {@inheritdoc}
72
     */
73 227
    public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
74
    {
75 227
        $fetchMode = $this->convertFetchMode($fetchMode);
76
77
        // This thin wrapper is necessary to shield against the weird signature
78
        // of PDOStatement::setFetchMode(): even if the second and third
79
        // parameters are optional, PHP will not let us remove it from this
80
        // declaration.
81
        try {
82 227
            if ($arg2 === null && $arg3 === null) {
83 227
                return parent::setFetchMode($fetchMode);
84
            }
85
86 2
            if ($arg3 === null) {
87 2
                return parent::setFetchMode($fetchMode, $arg2);
88
            }
89
90
            return parent::setFetchMode($fetchMode, $arg2, $arg3);
91
        } catch (\PDOException $exception) {
92
            throw new PDOException($exception);
93
        }
94
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99 33
    public function bindValue($param, $value, $type = ParameterType::STRING)
100
    {
101 33
        $type = $this->convertParamType($type);
102
103
        try {
104 33
            return parent::bindValue($param, $value, $type);
105
        } catch (\PDOException $exception) {
106
            throw new PDOException($exception);
107
        }
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113 7
    public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null)
114
    {
115 7
        $type = $this->convertParamType($type);
116
117
        try {
118 7
            return parent::bindParam($column, $variable, $type, $length, $driverOptions);
119
        } catch (\PDOException $exception) {
120
            throw new PDOException($exception);
121
        }
122
    }
123
124
    /**
125
     * {@inheritdoc}
126
     */
127 20
    public function closeCursor()
128
    {
129
        try {
130 20
            return parent::closeCursor();
131
        } catch (\PDOException $exception) {
132
            // Exceptions not allowed by the interface.
133
            // In case driver implementations do not adhere to the interface, silence exceptions here.
134
            return true;
135
        }
136
    }
137
138
    /**
139
     * {@inheritdoc}
140
     */
141 133
    public function execute($params = null)
142
    {
143
        try {
144 133
            $result = parent::execute($params);
145
146 128
            if ($this->connection) {
147 128
                $this->connection->trackLastInsertId();
148
            }
149
150 128
            return $result;
151 7
        } catch (\PDOException $exception) {
152 3
            throw new PDOException($exception);
153
        }
154
    }
155
156
    /**
157
     * {@inheritdoc}
158
     */
159 68
    public function fetch($fetchMode = null, $cursorOrientation = \PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
160
    {
161 68
        $fetchMode = $this->convertFetchMode($fetchMode);
162
163
        try {
164 68
            if ($fetchMode === null && \PDO::FETCH_ORI_NEXT === $cursorOrientation && 0 === $cursorOffset) {
165 9
                return parent::fetch();
166
            }
167
168 59
            if (\PDO::FETCH_ORI_NEXT === $cursorOrientation && 0 === $cursorOffset) {
169 59
                return parent::fetch($fetchMode);
170
            }
171
172
            if (0 === $cursorOffset) {
173
                return parent::fetch($fetchMode, $cursorOrientation);
174
            }
175
176
            return parent::fetch($fetchMode, $cursorOrientation, $cursorOffset);
177
        } catch (\PDOException $exception) {
178
            throw new PDOException($exception);
179
        }
180
    }
181
182
    /**
183
     * {@inheritdoc}
184
     */
185 101
    public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
186
    {
187 101
        $fetchMode = $this->convertFetchMode($fetchMode);
188
189
        try {
190 101
            if ($fetchMode === null && null === $fetchArgument && null === $ctorArgs) {
191 88
                return parent::fetchAll();
192
            }
193
194 54
            if (null === $fetchArgument && null === $ctorArgs) {
195 53
                return parent::fetchAll($fetchMode);
196
            }
197
198 1
            if (null === $ctorArgs) {
199 1
                return parent::fetchAll($fetchMode, $fetchArgument);
200
            }
201
202
            return parent::fetchAll($fetchMode, $fetchArgument, $ctorArgs);
203
        } catch (\PDOException $exception) {
204
            throw new PDOException($exception);
205
        }
206
    }
207
208
    /**
209
     * {@inheritdoc}
210
     */
211 43
    public function fetchColumn($columnIndex = 0)
212
    {
213
        try {
214 43
            return parent::fetchColumn($columnIndex);
215
        } catch (\PDOException $exception) {
216
            throw new PDOException($exception);
217
        }
218
    }
219
220
    /**
221
     * Converts DBAL parameter type to PDO parameter type
222
     *
223
     * @param int $type Parameter type
224
     */
225 40
    private function convertParamType(int $type) : int
226
    {
227 40
        if (! isset(self::PARAM_TYPE_MAP[$type])) {
228
            throw new \InvalidArgumentException('Invalid parameter type: ' . $type);
229
        }
230
231 40
        return self::PARAM_TYPE_MAP[$type];
232
    }
233
234
    /**
235
     * Converts DBAL fetch mode to PDO fetch mode
236
     *
237
     * @param int|null $fetchMode Fetch mode
238
     */
239 227
    private function convertFetchMode(?int $fetchMode) : ?int
240
    {
241 227
        if ($fetchMode === null) {
242 97
            return null;
243
        }
244
245 227
        if (! isset(self::FETCH_MODE_MAP[$fetchMode])) {
246
            throw new \InvalidArgumentException('Invalid fetch mode: ' . $fetchMode);
247
        }
248
249 227
        return self::FETCH_MODE_MAP[$fetchMode];
250
    }
251
}
252