Passed
Push — 2.7 ( 6f9fcf...2cc12a )
by Michael
40:51 queued 38:03
created

PDOStatement   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 219
Duplicated Lines 0 %

Test Coverage

Coverage 67.12%

Importance

Changes 0
Metric Value
wmc 37
dl 0
loc 219
rs 8.6
c 0
b 0
f 0
ccs 49
cts 73
cp 0.6712

11 Methods

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