Failed Conditions
Pull Request — master (#3359)
by Sergei
25:01 queued 22:04
created

PDOStatement::fetchColumn()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.3332

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 10
ccs 4
cts 6
cp 0.6667
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 3.3332
1
<?php
2
3
namespace Doctrine\DBAL\Driver;
4
5
use Doctrine\DBAL\DBALException;
6
use Doctrine\DBAL\FetchMode;
7
use Doctrine\DBAL\ParameterType;
8
use PDO;
9
use const E_USER_DEPRECATED;
10
use function sprintf;
11
use function trigger_error;
12
13
/**
14
 * The PDO implementation of the Statement interface.
15
 * Used by all PDO-based drivers.
16
 */
17
class PDOStatement extends \PDOStatement implements Statement
18
{
19
    private const PARAM_TYPE_MAP = [
20
        ParameterType::NULL         => PDO::PARAM_NULL,
21
        ParameterType::INTEGER      => PDO::PARAM_INT,
22
        ParameterType::STRING       => PDO::PARAM_STR,
23
        ParameterType::BINARY       => PDO::PARAM_LOB,
24
        ParameterType::LARGE_OBJECT => PDO::PARAM_LOB,
25
        ParameterType::BOOLEAN      => PDO::PARAM_BOOL,
26
    ];
27
28
    private const FETCH_MODE_MAP = [
29
        FetchMode::ASSOCIATIVE     => PDO::FETCH_ASSOC,
30
        FetchMode::NUMERIC         => PDO::FETCH_NUM,
31
        FetchMode::MIXED           => PDO::FETCH_BOTH,
32
        FetchMode::STANDARD_OBJECT => PDO::FETCH_OBJ,
33
        FetchMode::COLUMN          => PDO::FETCH_COLUMN,
34
        FetchMode::CUSTOM_OBJECT   => PDO::FETCH_CLASS,
35
    ];
36
37
    /**
38
     * Protected constructor.
39
     */
40 4188
    protected function __construct()
41
    {
42 4188
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 3921
    public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null)
48
    {
49 3921
        $fetchMode = $this->convertFetchMode($fetchMode);
50
51
        // This thin wrapper is necessary to shield against the weird signature
52
        // of PDOStatement::setFetchMode(): even if the second and third
53
        // parameters are optional, PHP will not let us remove it from this
54
        // declaration.
55
        try {
56 3921
            if ($arg2 === null && $arg3 === null) {
57 3921
                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

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