Failed Conditions
Pull Request — master (#3339)
by Sergei
15:21
created

PDOStatement::setFetchMode()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 20
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 9.2876

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 20
ccs 4
cts 9
cp 0.4444
rs 9.6111
c 0
b 0
f 0
cc 5
nc 6
nop 3
crap 9.2876
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 sprintf;
10
use function trigger_error;
11
12
/**
13
 * The PDO implementation of the Statement interface.
14
 * Used by all PDO-based drivers.
15
 */
16
class PDOStatement extends \PDOStatement implements Statement
17
{
18
    private const PARAM_TYPE_MAP = [
19
        ParameterType::NULL         => PDO::PARAM_NULL,
20
        ParameterType::INTEGER      => PDO::PARAM_INT,
21
        ParameterType::STRING       => PDO::PARAM_STR,
22
        ParameterType::BINARY       => PDO::PARAM_LOB,
23
        ParameterType::LARGE_OBJECT => PDO::PARAM_LOB,
24
        ParameterType::BOOLEAN      => PDO::PARAM_BOOL,
25
    ];
26
27
    private const FETCH_MODE_MAP = [
28
        FetchMode::ASSOCIATIVE     => PDO::FETCH_ASSOC,
29
        FetchMode::NUMERIC         => PDO::FETCH_NUM,
30
        FetchMode::MIXED           => PDO::FETCH_BOTH,
31
        FetchMode::STANDARD_OBJECT => PDO::FETCH_OBJ,
32
        FetchMode::COLUMN          => PDO::FETCH_COLUMN,
33
        FetchMode::CUSTOM_OBJECT   => PDO::FETCH_CLASS,
34
    ];
35
36
    /**
37
     * Protected constructor.
38
     */
39 3585
    protected function __construct()
40
    {
41 3585
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46 3357
    public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
47
    {
48 3357
        $fetchMode = $this->convertFetchMode($fetchMode);
49
50
        // This thin wrapper is necessary to shield against the weird signature
51
        // of PDOStatement::setFetchMode(): even if the second and third
52
        // parameters are optional, PHP will not let us remove it from this
53
        // declaration.
54
        try {
55 3357
            if ($arg2 === null && $arg3 === null) {
56 3357
                return parent::setFetchMode($fetchMode);
0 ignored issues
show
Bug introduced by
It seems like $fetchMode can also be of type null; however, parameter $mode of PDOStatement::setFetchMode() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

56
                return parent::setFetchMode(/** @scrutinizer ignore-type */ $fetchMode);
Loading history...
57
            }
58
59
            if ($arg3 === null) {
60
                return parent::setFetchMode($fetchMode, $arg2);
61
            }
62
63
            return parent::setFetchMode($fetchMode, $arg2, $arg3);
64
        } catch (\PDOException $exception) {
65
            throw new PDOException($exception);
66
        }
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72 480
    public function bindValue($param, $value, $type = ParameterType::STRING)
73
    {
74 480
        $type = $this->convertParamType($type);
75
76
        try {
77 480
            return parent::bindValue($param, $value, $type);
78
        } catch (\PDOException $exception) {
79
            throw new PDOException($exception);
80
        }
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86 134
    public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null)
87
    {
88 134
        $type = $this->convertParamType($type);
89
90
        try {
91 134
            return parent::bindParam($column, $variable, $type, $length, $driverOptions);
92
        } catch (\PDOException $exception) {
93
            throw new PDOException($exception);
94
        }
95
    }
96
97
    /**
98
     * {@inheritdoc}
99
     */
100 253
    public function closeCursor()
101
    {
102
        try {
103 253
            return parent::closeCursor();
104
        } catch (\PDOException $exception) {
105
            // Exceptions not allowed by the interface.
106
            // In case driver implementations do not adhere to the interface, silence exceptions here.
107
            return true;
108
        }
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114 1827
    public function execute($params = null)
115
    {
116
        try {
117 1827
            return parent::execute($params);
118 132
        } catch (\PDOException $exception) {
119 84
            throw new PDOException($exception);
120
        }
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     */
126 1164
    public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0)
127
    {
128 1164
        $fetchMode = $this->convertFetchMode($fetchMode);
129
130
        try {
131 1164
            if ($fetchMode === null && $cursorOrientation === PDO::FETCH_ORI_NEXT && $cursorOffset === 0) {
132 104
                return parent::fetch();
133
            }
134
135 1060
            if ($cursorOrientation === PDO::FETCH_ORI_NEXT && $cursorOffset === 0) {
136 1060
                return parent::fetch($fetchMode);
137
            }
138
139
            if ($cursorOffset === 0) {
140
                return parent::fetch($fetchMode, $cursorOrientation);
141
            }
142
143
            return parent::fetch($fetchMode, $cursorOrientation, $cursorOffset);
144
        } catch (\PDOException $exception) {
145
            throw new PDOException($exception);
146
        }
147
    }
148
149
    /**
150
     * {@inheritdoc}
151
     */
152 1614
    public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null)
153
    {
154 1614
        $fetchMode = $this->convertFetchMode($fetchMode);
155
156
        try {
157 1614
            if ($fetchMode === null && $fetchArgument === null && $ctorArgs === null) {
158 1385
                return parent::fetchAll();
159
            }
160
161 408
            if ($fetchArgument === null && $ctorArgs === null) {
162 408
                return parent::fetchAll($fetchMode);
163
            }
164
165
            if ($ctorArgs === null) {
166
                return parent::fetchAll($fetchMode, $fetchArgument);
167
            }
168
169
            return parent::fetchAll($fetchMode, $fetchArgument, $ctorArgs);
170
        } catch (\PDOException $exception) {
171
            throw new PDOException($exception);
172
        }
173
    }
174
175
    /**
176
     * {@inheritdoc}
177
     */
178 859
    public function fetchColumn($columnIndex = 0)
179
    {
180
        try {
181 859
            return parent::fetchColumn($columnIndex);
182
        } catch (\PDOException $exception) {
183
            throw new PDOException($exception);
184
        }
185
    }
186
187
    /**
188
     * Converts DBAL parameter type to PDO parameter type
189
     *
190
     * @param int $type Parameter type
191
     */
192 614
    private function convertParamType(int $type) : int
193
    {
194 614
        if (! isset(self::PARAM_TYPE_MAP[$type])) {
195
            // TODO: next major: throw an exception
196
            @trigger_error(sprintf(
197
                'Using a PDO parameter type (%d given) is deprecated and will cause an error in Doctrine 3.0',
198
                $type
199
            ), E_USER_DEPRECATED);
200
201
            return $type;
202
        }
203
204 614
        return self::PARAM_TYPE_MAP[$type];
205
    }
206
207
    /**
208
     * Converts DBAL fetch mode to PDO fetch mode
209
     *
210
     * @param int|null $fetchMode Fetch mode
211
     */
212 3363
    private function convertFetchMode(?int $fetchMode) : ?int
213
    {
214 3363
        if ($fetchMode === null) {
215 1489
            return null;
216
        }
217
218 3357
        if (! isset(self::FETCH_MODE_MAP[$fetchMode])) {
219
            // TODO: next major: throw an exception
220 13
            @trigger_error(sprintf(
221
                'Using a PDO fetch mode or their combination (%d given)' .
222 13
                ' is deprecated and will cause an error in Doctrine 3.0',
223 13
                $fetchMode
224 13
            ), E_USER_DEPRECATED);
225
226 13
            return $fetchMode;
227
        }
228
229 3357
        return self::FETCH_MODE_MAP[$fetchMode];
230
    }
231
}
232