1
|
|
|
<?php |
2
|
|
|
/* |
3
|
|
|
* This file is part of the QueryResourcesLoaderBundle, an RunOpenCode project. |
4
|
|
|
* |
5
|
|
|
* (c) 2017 RunOpenCode. |
6
|
|
|
* |
7
|
|
|
* For the full copyright and license information, please view the LICENSE |
8
|
|
|
* file that was distributed with this source code. |
9
|
|
|
*/ |
10
|
|
|
namespace RunOpenCode\Bundle\QueryResourcesLoader\Executor; |
11
|
|
|
|
12
|
|
|
use Doctrine\DBAL\Driver\Statement; |
13
|
|
|
use RunOpenCode\Bundle\QueryResourcesLoader\Exception\NonUniqueResultException; |
14
|
|
|
use RunOpenCode\Bundle\QueryResourcesLoader\Exception\NoResultException; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Class DoctrineDbalExecutorResult |
18
|
|
|
* |
19
|
|
|
* Doctrine Dbal executor result statement wrapper that provides you with useful methods when fetching results from |
20
|
|
|
* SELECT statement. |
21
|
|
|
* |
22
|
|
|
* @package RunOpenCode\Bundle\QueryResourcesLoader\Executor |
23
|
|
|
*/ |
24
|
|
|
final class DoctrineDbalExecutorResult implements \IteratorAggregate, Statement |
25
|
|
|
{ |
26
|
|
|
/** |
27
|
|
|
* @var Statement |
28
|
|
|
*/ |
29
|
|
|
private $statement; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* DoctrineDbalExecutorResult constructor. |
33
|
|
|
* |
34
|
|
|
* @param Statement $statement Wrapped statement. |
35
|
|
|
*/ |
36
|
7 |
|
public function __construct(Statement $statement) |
37
|
|
|
{ |
38
|
7 |
|
$this->statement = $statement; |
39
|
7 |
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Get single scalar result. |
43
|
|
|
* |
44
|
|
|
* @return mixed A single scalar value. |
45
|
|
|
* |
46
|
|
|
* @throws NoResultException |
47
|
|
|
* @throws NonUniqueResultException |
48
|
|
|
*/ |
49
|
3 |
View Code Duplication |
public function getSingleScalarResult() |
|
|
|
|
50
|
|
|
{ |
51
|
3 |
|
$scalar = $this->statement->fetchColumn(0); |
52
|
|
|
|
53
|
3 |
|
if (false === $scalar) { |
54
|
1 |
|
throw new NoResultException('Expected on result for given query.'); |
55
|
|
|
} |
56
|
|
|
|
57
|
2 |
|
if (false !== $this->statement->fetch()) { |
58
|
1 |
|
throw new NonUniqueResultException('Expected only one result for given query.'); |
59
|
|
|
} |
60
|
|
|
|
61
|
1 |
|
return $scalar; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* Get single scalar result or default value if there are no results of executed |
66
|
|
|
* SELECT statement. |
67
|
|
|
* |
68
|
|
|
* @param mixed $default A default single scalar value. |
69
|
|
|
* @return mixed A single scalar value. |
70
|
|
|
*/ |
71
|
|
|
public function getSingleScalarResultOrDefault($default) |
72
|
|
|
{ |
73
|
|
|
try { |
74
|
|
|
return $this->getSingleScalarResult(); |
75
|
|
|
} catch (NoResultException $e) { |
76
|
|
|
return $default; |
77
|
|
|
} |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Get single scalar result or NULL value if there are no results of executed |
82
|
|
|
* SELECT statement. |
83
|
|
|
* |
84
|
|
|
* @return mixed|null A single scalar value. |
85
|
|
|
*/ |
86
|
|
|
public function getSingleScalarResultOrNull() |
87
|
|
|
{ |
88
|
|
|
return $this->getSingleScalarResultOrDefault(null); |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Get collection of scalar values. |
93
|
|
|
* |
94
|
|
|
* @return array A collection of scalar values. |
95
|
|
|
*/ |
96
|
1 |
|
public function getScalarResult() |
97
|
|
|
{ |
98
|
1 |
|
$result = []; |
99
|
|
|
|
100
|
1 |
|
while ($val = $this->statement->fetchColumn()) { |
101
|
1 |
|
$result[] = $val; |
102
|
|
|
} |
103
|
|
|
|
104
|
1 |
|
return $result; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Get collection of scalar vales, or default value if collection is empty. |
109
|
|
|
* |
110
|
|
|
* @param mixed $default A default value. |
111
|
|
|
* @return array|mixed A collection of scalar values or default value. |
112
|
|
|
*/ |
113
|
|
|
public function getScalarResultOrDefault($default) |
114
|
|
|
{ |
115
|
|
|
$result = $this->getScalarResult(); |
116
|
|
|
|
117
|
|
|
if (count($result) < 0) { |
118
|
|
|
return $default; |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
return $result; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* Get collection of scalar vales, or NULL value if collection is empty. |
126
|
|
|
* |
127
|
|
|
* @return array|mixed A collection of NULL value. |
128
|
|
|
*/ |
129
|
|
|
public function getScalarResultOrNull() |
130
|
|
|
{ |
131
|
|
|
return $this->getScalarResultOrDefault(null); |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* Get single (first) row result from result set. |
136
|
|
|
* |
137
|
|
|
* @return array A single (first) row of result set. |
138
|
|
|
* |
139
|
|
|
* @throws NoResultException |
140
|
|
|
* @throws NonUniqueResultException |
141
|
|
|
*/ |
142
|
1 |
View Code Duplication |
public function getSingleRowResult() |
|
|
|
|
143
|
|
|
{ |
144
|
1 |
|
$row = $this->statement->fetch(\PDO::FETCH_BOTH); |
145
|
|
|
|
146
|
1 |
|
if (false === $row) { |
147
|
|
|
throw new NoResultException('Expected on result for given query.'); |
148
|
|
|
} |
149
|
|
|
|
150
|
1 |
|
if (false !== $this->statement->fetch()) { |
151
|
|
|
throw new NonUniqueResultException('Expected only ine result for given query.'); |
152
|
|
|
} |
153
|
|
|
|
154
|
1 |
|
return $row; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
/** |
158
|
|
|
* Get single (first) row result from result set or default value if result set is empty. |
159
|
|
|
* |
160
|
|
|
* @param mixed $default Default value if result set is empty. |
161
|
|
|
* @return array A single (first) row of result set. |
162
|
|
|
* |
163
|
|
|
* @throws NoResultException |
164
|
|
|
* @throws NonUniqueResultException |
165
|
|
|
*/ |
166
|
|
|
public function getSingleRowOrDefault($default) |
167
|
|
|
{ |
168
|
|
|
try { |
169
|
|
|
return $this->getSingleRowResult(); |
170
|
|
|
} catch (NoResultException $e) { |
171
|
|
|
return $default; |
172
|
|
|
} |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* Get single (first) row result from result set or NULL value if result set is empty. |
177
|
|
|
* |
178
|
|
|
* @return array A single (first) row of result set. |
179
|
|
|
* |
180
|
|
|
* @throws NoResultException |
181
|
|
|
* @throws NonUniqueResultException |
182
|
|
|
*/ |
183
|
|
|
public function getSingleRowOrNull() |
184
|
|
|
{ |
185
|
|
|
$this->getSingleRowOrDefault(null); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* {@inheritdoc} |
190
|
|
|
*/ |
191
|
|
|
public function closeCursor() |
192
|
|
|
{ |
193
|
|
|
return $this->statement->closeCursor(); |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
/** |
197
|
|
|
* {@inheritdoc} |
198
|
|
|
*/ |
199
|
|
|
public function columnCount() |
200
|
|
|
{ |
201
|
|
|
return $this->statement->columnCount(); |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
/** |
205
|
|
|
* {@inheritdoc} |
206
|
|
|
*/ |
207
|
|
|
public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) |
208
|
|
|
{ |
209
|
|
|
return $this->statement->setFetchMode($fetchMode, $arg2, $arg3); |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* {@inheritdoc} |
214
|
|
|
*/ |
215
|
|
|
public function fetch($fetchMode = null) |
216
|
|
|
{ |
217
|
|
|
return $this->statement->fetch($fetchMode); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
/** |
221
|
|
|
* {@inheritdoc} |
222
|
|
|
*/ |
223
|
|
|
public function fetchAll($fetchMode = null) |
224
|
|
|
{ |
225
|
|
|
return $this->statement->fetchAll($fetchMode); |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
/** |
229
|
|
|
* {@inheritdoc} |
230
|
|
|
*/ |
231
|
|
|
public function fetchColumn($columnIndex = 0) |
232
|
|
|
{ |
233
|
|
|
return $this->statement->fetchColumn($columnIndex); |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* {@inheritdoc} |
238
|
|
|
*/ |
239
|
|
|
public function bindValue($param, $value, $type = null) |
240
|
|
|
{ |
241
|
|
|
return $this->statement->bindValue($param, $value, $type); |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
/** |
245
|
|
|
* {@inheritdoc} |
246
|
|
|
*/ |
247
|
|
|
public function bindParam($column, &$variable, $type = null, $length = null) |
248
|
|
|
{ |
249
|
|
|
return $this->statement->bindParam($column, $variable, $type, $length); |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
/** |
253
|
|
|
* {@inheritdoc} |
254
|
|
|
*/ |
255
|
|
|
public function errorCode() |
256
|
|
|
{ |
257
|
|
|
return $this->statement->errorCode(); |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
/** |
261
|
|
|
* {@inheritdoc} |
262
|
|
|
*/ |
263
|
|
|
public function errorInfo() |
264
|
|
|
{ |
265
|
|
|
return $this->statement->errorInfo(); |
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
/** |
269
|
|
|
* {@inheritdoc} |
270
|
|
|
*/ |
271
|
|
|
public function execute($params = null) |
272
|
|
|
{ |
273
|
|
|
return $this->statement->execute($params); |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
/** |
277
|
|
|
* {@inheritdoc} |
278
|
|
|
*/ |
279
|
|
|
public function rowCount() |
280
|
|
|
{ |
281
|
|
|
return $this->statement->rowCount(); |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
/** |
285
|
|
|
* {@inheritdoc} |
286
|
|
|
*/ |
287
|
|
|
public function __get($name) |
288
|
|
|
{ |
289
|
|
|
return $this->statement->{$name}; |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
/** |
293
|
|
|
* {@inheritdoc} |
294
|
|
|
*/ |
295
|
|
|
public function __set($name, $value) |
296
|
|
|
{ |
297
|
|
|
$this->statement->{$name} = $value; |
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
/** |
301
|
|
|
* {@inheritdoc} |
302
|
|
|
*/ |
303
|
|
|
public function __isset($name) |
304
|
|
|
{ |
305
|
|
|
return isset($this->statement[$name]); |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
/** |
309
|
|
|
* {@inheritdoc} |
310
|
|
|
*/ |
311
|
|
|
public function __call($name, $arguments) |
312
|
|
|
{ |
313
|
|
|
return call_user_func_array(array($this->statement, $name), $arguments); |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
/** |
317
|
|
|
* {@inheritdoc} |
318
|
|
|
*/ |
319
|
|
|
public function getIterator() |
320
|
|
|
{ |
321
|
|
|
while (false !== ($row = $this->statement->fetch(\PDO::FETCH_BOTH))) { |
322
|
|
|
yield $row; |
323
|
|
|
} |
324
|
|
|
} |
325
|
|
|
} |
326
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.