Completed
Pull Request — 2.11.x (#3956)
by David
14:33
created

PDOStatement   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 213
Duplicated Lines 0 %

Test Coverage

Coverage 72.21%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 32
eloc 84
c 1
b 0
f 0
dl 0
loc 213
ccs 52
cts 72
cp 0.7221
rs 9.84

11 Methods

Rating   Name   Duplication   Size   Complexity  
A convertParamType() 0 13 2
A fetchColumn() 0 6 2
A setFetchMode() 0 20 5
A __construct() 0 2 1
A bindValue() 0 8 2
A execute() 0 6 2
A convertFetchMode() 0 14 2
A bindParam() 0 8 2
A fetch() 0 12 3
A closeCursor() 0 8 2
B fetchAll() 0 25 9
1
<?php
2
3
namespace Doctrine\DBAL\Driver;
4
5
use Doctrine\DBAL\FetchMode;
6
use Doctrine\DBAL\ParameterType;
7
use PDO;
8
use const E_USER_DEPRECATED;
9
use function array_slice;
10
use function assert;
11
use function func_get_args;
12
use function is_array;
13
use function sprintf;
14
use function trigger_error;
15
16
/**
17
 * The PDO implementation of the Statement interface.
18
 * Used by all PDO-based drivers.
19
 */
20
class PDOStatement extends \PDOStatement implements Statement
21
{
22
    private const PARAM_TYPE_MAP = [
23
        ParameterType::NULL         => PDO::PARAM_NULL,
24
        ParameterType::INTEGER      => PDO::PARAM_INT,
25
        ParameterType::STRING       => PDO::PARAM_STR,
26
        ParameterType::BINARY       => PDO::PARAM_LOB,
27
        ParameterType::LARGE_OBJECT => PDO::PARAM_LOB,
28
        ParameterType::BOOLEAN      => PDO::PARAM_BOOL,
29
    ];
30
31
    private const FETCH_MODE_MAP = [
32
        FetchMode::ASSOCIATIVE     => PDO::FETCH_ASSOC,
33
        FetchMode::NUMERIC         => PDO::FETCH_NUM,
34
        FetchMode::MIXED           => PDO::FETCH_BOTH,
35
        FetchMode::STANDARD_OBJECT => PDO::FETCH_OBJ,
36
        FetchMode::COLUMN          => PDO::FETCH_COLUMN,
37
        FetchMode::CUSTOM_OBJECT   => PDO::FETCH_CLASS,
38
    ];
39
40
    /**
41
     * Protected constructor.
42
     */
43 4192
    protected function __construct()
44
    {
45 4192
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50 4176
    public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
51
    {
52 4176
        $fetchMode = $this->convertFetchMode($fetchMode);
53
54
        // This thin wrapper is necessary to shield against the weird signature
55
        // of PDOStatement::setFetchMode(): even if the second and third
56
        // parameters are optional, PHP will not let us remove it from this
57
        // declaration.
58
        try {
59 4176
            if ($arg2 === null && $arg3 === null) {
60 4176
                return parent::setFetchMode($fetchMode);
61
            }
62
63 3211
            if ($arg3 === null) {
64 3211
                return parent::setFetchMode($fetchMode, $arg2);
65
            }
66
67
            return parent::setFetchMode($fetchMode, $arg2, $arg3);
68
        } catch (\PDOException $exception) {
69
            throw new PDOException($exception);
70
        }
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76 3723
    public function bindValue($param, $value, $type = ParameterType::STRING)
77
    {
78 3723
        $type = $this->convertParamType($type);
79
80
        try {
81 3723
            return parent::bindValue($param, $value, $type);
82 3422
        } catch (\PDOException $exception) {
83
            throw new PDOException($exception);
84
        }
85
    }
86
87
    /**
88
     * @param mixed    $column
89
     * @param mixed    $variable
90
     * @param int      $type
91
     * @param int|null $length
92
     * @param mixed    $driverOptions
93
     *
94
     * @return bool
95
     */
96 4082
    public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null)
97
    {
98 4082
        $type = $this->convertParamType($type);
99
100
        try {
101 4082
            return parent::bindParam($column, $variable, $type, ...array_slice(func_get_args(), 3));
0 ignored issues
show
Bug introduced by
array_slice(func_get_args(), 3) is expanded, but the parameter $length of PDOStatement::bindParam() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

101
            return parent::bindParam($column, $variable, $type, /** @scrutinizer ignore-type */ ...array_slice(func_get_args(), 3));
Loading history...
102 426
        } catch (\PDOException $exception) {
103
            throw new PDOException($exception);
104
        }
105
    }
106
107
    /**
108
     * {@inheritdoc}
109
     */
110 2431
    public function closeCursor()
111
    {
112
        try {
113 2431
            return parent::closeCursor();
114
        } catch (\PDOException $exception) {
115
            // Exceptions not allowed by the interface.
116
            // In case driver implementations do not adhere to the interface, silence exceptions here.
117
            return true;
118
        }
119
    }
120
121
    /**
122
     * {@inheritdoc}
123
     */
124 4181
    public function execute($params = null)
125
    {
126
        try {
127 4181
            return parent::execute($params);
128 2719
        } catch (\PDOException $exception) {
129 2719
            throw new PDOException($exception);
130
        }
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136 3992
    public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
137
    {
138 3992
        $args = func_get_args();
139
140 3992
        if (isset($args[0])) {
141 3992
            $args[0] = $this->convertFetchMode($args[0]);
142
        }
143
144
        try {
145 3992
            return parent::fetch(...$args);
0 ignored issues
show
Bug introduced by
$args is expanded, but the parameter $fetch_style of PDOStatement::fetch() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

145
            return parent::fetch(/** @scrutinizer ignore-type */ ...$args);
Loading history...
146
        } catch (\PDOException $exception) {
147
            throw new PDOException($exception);
148
        }
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154 4175
    public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
155
    {
156 4175
        $args = func_get_args();
157
158 4175
        if (isset($args[0])) {
159 4165
            $args[0] = $this->convertFetchMode($args[0]);
160
        }
161
162 4175
        if ($fetchMode === null && $fetchArgument === null && $ctorArgs === null) {
163 3919
            $args = [];
164 4165
        } elseif ($fetchArgument === null && $ctorArgs === null) {
165 4165
            $args = [$fetchMode];
166 3243
        } elseif ($ctorArgs === null) {
167 3243
            $args = [$fetchMode, $fetchArgument];
168
        } else {
169
            $args = [$fetchMode, $fetchArgument, $ctorArgs];
170
        }
171
172
        try {
173 4175
            $data = parent::fetchAll(...$args);
0 ignored issues
show
Bug introduced by
$args is expanded, but the parameter $fetch_style of PDOStatement::fetchAll() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

173
            $data = parent::fetchAll(/** @scrutinizer ignore-type */ ...$args);
Loading history...
174 4175
            assert(is_array($data));
175
176 4175
            return $data;
177
        } catch (\PDOException $exception) {
178
            throw new PDOException($exception);
179
        }
180
    }
181
182
    /**
183
     * {@inheritdoc}
184
     */
185 4086
    public function fetchColumn($columnIndex = 0)
186
    {
187
        try {
188 4086
            return parent::fetchColumn($columnIndex);
189
        } catch (\PDOException $exception) {
190
            throw new PDOException($exception);
191
        }
192
    }
193
194
    /**
195
     * Converts DBAL parameter type to PDO parameter type
196
     *
197
     * @param int $type Parameter type
198
     */
199 4181
    private function convertParamType(int $type) : int
200
    {
201 4181
        if (! isset(self::PARAM_TYPE_MAP[$type])) {
202
            // TODO: next major: throw an exception
203
            @trigger_error(sprintf(
204
                'Using a PDO parameter type (%d given) is deprecated and will cause an error in Doctrine DBAL 3.0',
205
                $type
206
            ), E_USER_DEPRECATED);
207
208
            return $type;
209
        }
210
211 4181
        return self::PARAM_TYPE_MAP[$type];
212
    }
213
214
    /**
215
     * Converts DBAL fetch mode to PDO fetch mode
216
     *
217
     * @param int $fetchMode Fetch mode
218
     */
219 4176
    private function convertFetchMode(int $fetchMode) : int
220
    {
221 4176
        if (! isset(self::FETCH_MODE_MAP[$fetchMode])) {
222
            // TODO: next major: throw an exception
223 2614
            @trigger_error(sprintf(
224
                'Using a PDO fetch mode or their combination (%d given)' .
225
                ' is deprecated and will cause an error in Doctrine DBAL 3.0',
226 2614
                $fetchMode
227 2614
            ), E_USER_DEPRECATED);
228
229 2614
            return $fetchMode;
230
        }
231
232 4176
        return self::FETCH_MODE_MAP[$fetchMode];
233
    }
234
}
235