Failed Conditions
Push — master ( 30b923...92920e )
by Marco
19s queued 13s
created

PDOStatement::fetch()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3.2098

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 12
ccs 5
cts 7
cp 0.7143
rs 10
c 0
b 0
f 0
cc 3
nc 4
nop 3
crap 3.2098
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 4811
    protected function __construct()
44
    {
45 4811
    }
46
47
    /**
48
     * {@inheritdoc}
49
     */
50 4508
    public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
51
    {
52 4508
        $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 4508
            if ($arg2 === null && $arg3 === null) {
60 4508
                return parent::setFetchMode($fetchMode);
61
            }
62
63 34
            if ($arg3 === null) {
64 34
                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 625
    public function bindValue($param, $value, $type = ParameterType::STRING)
77
    {
78 625
        $type = $this->convertParamType($type);
79
80
        try {
81 625
            return parent::bindValue($param, $value, $type);
82
        } catch (\PDOException $exception) {
83
            throw new PDOException($exception);
84
        }
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90 171
    public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null)
91
    {
92 171
        $type = $this->convertParamType($type);
93
94
        try {
95 171
            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

95
            return parent::bindParam($column, $variable, $type, /** @scrutinizer ignore-type */ ...array_slice(func_get_args(), 3));
Loading history...
96
        } catch (\PDOException $exception) {
97
            throw new PDOException($exception);
98
        }
99
    }
100
101
    /**
102
     * {@inheritdoc}
103
     */
104 346
    public function closeCursor()
105
    {
106
        try {
107 346
            return parent::closeCursor();
108
        } catch (\PDOException $exception) {
109
            // Exceptions not allowed by the interface.
110
            // In case driver implementations do not adhere to the interface, silence exceptions here.
111
            return true;
112
        }
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     */
118 2445
    public function execute($params = null)
119
    {
120
        try {
121 2445
            return parent::execute($params);
122 176
        } catch (\PDOException $exception) {
123 112
            throw new PDOException($exception);
124
        }
125
    }
126
127
    /**
128
     * {@inheritdoc}
129
     */
130 1574
    public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
131
    {
132 1574
        $args = func_get_args();
133
134 1574
        if (isset($args[0])) {
135 1421
            $args[0] = $this->convertFetchMode($args[0]);
136
        }
137
138
        try {
139 1574
            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

139
            return parent::fetch(/** @scrutinizer ignore-type */ ...$args);
Loading history...
140
        } catch (\PDOException $exception) {
141
            throw new PDOException($exception);
142
        }
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148 2240
    public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
149
    {
150 2240
        $args = func_get_args();
151
152 2240
        if (isset($args[0])) {
153 547
            $args[0] = $this->convertFetchMode($args[0]);
154
        }
155
156 2240
        if ($fetchMode === null && $fetchArgument === null && $ctorArgs === null) {
157 1923
            $args = [];
158 547
        } elseif ($fetchArgument === null && $ctorArgs === null) {
159 530
            $args = [$fetchMode];
160 17
        } elseif ($ctorArgs === null) {
161 17
            $args = [$fetchMode, $fetchArgument];
162
        } else {
163
            $args = [$fetchMode, $fetchArgument, $ctorArgs];
164
        }
165
166
        try {
167 2240
            $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

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