Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Core\Database;
|
Chris@0
|
4
|
Chris@0
|
5 /**
|
Chris@0
|
6 * An implementation of StatementInterface that prefetches all data.
|
Chris@0
|
7 *
|
Chris@0
|
8 * This class behaves very similar to a \PDOStatement but as it always fetches
|
Chris@0
|
9 * every row it is possible to manipulate those results.
|
Chris@0
|
10 */
|
Chris@0
|
11 class StatementPrefetch implements \Iterator, StatementInterface {
|
Chris@0
|
12
|
Chris@0
|
13 /**
|
Chris@0
|
14 * The query string.
|
Chris@0
|
15 *
|
Chris@0
|
16 * @var string
|
Chris@0
|
17 */
|
Chris@0
|
18 protected $queryString;
|
Chris@0
|
19
|
Chris@0
|
20 /**
|
Chris@0
|
21 * Driver-specific options. Can be used by child classes.
|
Chris@0
|
22 *
|
Chris@17
|
23 * @var array
|
Chris@0
|
24 */
|
Chris@0
|
25 protected $driverOptions;
|
Chris@0
|
26
|
Chris@0
|
27 /**
|
Chris@0
|
28 * Reference to the Drupal database connection object for this statement.
|
Chris@0
|
29 *
|
Chris@0
|
30 * @var \Drupal\Core\Database\Connection
|
Chris@0
|
31 */
|
Chris@0
|
32 public $dbh;
|
Chris@0
|
33
|
Chris@0
|
34 /**
|
Chris@0
|
35 * Reference to the PDO connection object for this statement.
|
Chris@0
|
36 *
|
Chris@0
|
37 * @var \PDO
|
Chris@0
|
38 */
|
Chris@0
|
39 protected $pdoConnection;
|
Chris@0
|
40
|
Chris@0
|
41 /**
|
Chris@0
|
42 * Main data store.
|
Chris@0
|
43 *
|
Chris@17
|
44 * @var array
|
Chris@0
|
45 */
|
Chris@0
|
46 protected $data = [];
|
Chris@0
|
47
|
Chris@0
|
48 /**
|
Chris@0
|
49 * The current row, retrieved in \PDO::FETCH_ASSOC format.
|
Chris@0
|
50 *
|
Chris@17
|
51 * @var array
|
Chris@0
|
52 */
|
Chris@0
|
53 protected $currentRow = NULL;
|
Chris@0
|
54
|
Chris@0
|
55 /**
|
Chris@0
|
56 * The key of the current row.
|
Chris@0
|
57 *
|
Chris@0
|
58 * @var int
|
Chris@0
|
59 */
|
Chris@0
|
60 protected $currentKey = NULL;
|
Chris@0
|
61
|
Chris@0
|
62 /**
|
Chris@0
|
63 * The list of column names in this result set.
|
Chris@0
|
64 *
|
Chris@17
|
65 * @var array
|
Chris@0
|
66 */
|
Chris@0
|
67 protected $columnNames = NULL;
|
Chris@0
|
68
|
Chris@0
|
69 /**
|
Chris@0
|
70 * The number of rows affected by the last query.
|
Chris@0
|
71 *
|
Chris@0
|
72 * @var int
|
Chris@0
|
73 */
|
Chris@0
|
74 protected $rowCount = NULL;
|
Chris@0
|
75
|
Chris@0
|
76 /**
|
Chris@0
|
77 * The number of rows in this result set.
|
Chris@0
|
78 *
|
Chris@0
|
79 * @var int
|
Chris@0
|
80 */
|
Chris@0
|
81 protected $resultRowCount = 0;
|
Chris@0
|
82
|
Chris@0
|
83 /**
|
Chris@0
|
84 * Holds the current fetch style (which will be used by the next fetch).
|
Chris@0
|
85 * @see \PDOStatement::fetch()
|
Chris@0
|
86 *
|
Chris@0
|
87 * @var int
|
Chris@0
|
88 */
|
Chris@0
|
89 protected $fetchStyle = \PDO::FETCH_OBJ;
|
Chris@0
|
90
|
Chris@0
|
91 /**
|
Chris@0
|
92 * Holds supplementary current fetch options (which will be used by the next fetch).
|
Chris@0
|
93 *
|
Chris@17
|
94 * @var array
|
Chris@0
|
95 */
|
Chris@0
|
96 protected $fetchOptions = [
|
Chris@0
|
97 'class' => 'stdClass',
|
Chris@0
|
98 'constructor_args' => [],
|
Chris@0
|
99 'object' => NULL,
|
Chris@0
|
100 'column' => 0,
|
Chris@0
|
101 ];
|
Chris@0
|
102
|
Chris@0
|
103 /**
|
Chris@0
|
104 * Holds the default fetch style.
|
Chris@0
|
105 *
|
Chris@0
|
106 * @var int
|
Chris@0
|
107 */
|
Chris@0
|
108 protected $defaultFetchStyle = \PDO::FETCH_OBJ;
|
Chris@0
|
109
|
Chris@0
|
110 /**
|
Chris@0
|
111 * Holds supplementary default fetch options.
|
Chris@0
|
112 *
|
Chris@17
|
113 * @var array
|
Chris@0
|
114 */
|
Chris@0
|
115 protected $defaultFetchOptions = [
|
Chris@0
|
116 'class' => 'stdClass',
|
Chris@0
|
117 'constructor_args' => [],
|
Chris@0
|
118 'object' => NULL,
|
Chris@0
|
119 'column' => 0,
|
Chris@0
|
120 ];
|
Chris@0
|
121
|
Chris@0
|
122 /**
|
Chris@0
|
123 * Is rowCount() execution allowed.
|
Chris@0
|
124 *
|
Chris@0
|
125 * @var bool
|
Chris@0
|
126 */
|
Chris@0
|
127 public $allowRowCount = FALSE;
|
Chris@0
|
128
|
Chris@0
|
129 public function __construct(\PDO $pdo_connection, Connection $connection, $query, array $driver_options = []) {
|
Chris@0
|
130 $this->pdoConnection = $pdo_connection;
|
Chris@0
|
131 $this->dbh = $connection;
|
Chris@0
|
132 $this->queryString = $query;
|
Chris@0
|
133 $this->driverOptions = $driver_options;
|
Chris@0
|
134 }
|
Chris@0
|
135
|
Chris@0
|
136 /**
|
Chris@0
|
137 * {@inheritdoc}
|
Chris@0
|
138 */
|
Chris@0
|
139 public function execute($args = [], $options = []) {
|
Chris@0
|
140 if (isset($options['fetch'])) {
|
Chris@0
|
141 if (is_string($options['fetch'])) {
|
Chris@0
|
142 // Default to an object. Note: db fields will be added to the object
|
Chris@0
|
143 // before the constructor is run. If you need to assign fields after
|
Chris@0
|
144 // the constructor is run. See https://www.drupal.org/node/315092.
|
Chris@0
|
145 $this->setFetchMode(\PDO::FETCH_CLASS, $options['fetch']);
|
Chris@0
|
146 }
|
Chris@0
|
147 else {
|
Chris@0
|
148 $this->setFetchMode($options['fetch']);
|
Chris@0
|
149 }
|
Chris@0
|
150 }
|
Chris@0
|
151
|
Chris@0
|
152 $logger = $this->dbh->getLogger();
|
Chris@0
|
153 if (!empty($logger)) {
|
Chris@0
|
154 $query_start = microtime(TRUE);
|
Chris@0
|
155 }
|
Chris@0
|
156
|
Chris@0
|
157 // Prepare the query.
|
Chris@0
|
158 $statement = $this->getStatement($this->queryString, $args);
|
Chris@0
|
159 if (!$statement) {
|
Chris@0
|
160 $this->throwPDOException();
|
Chris@0
|
161 }
|
Chris@0
|
162
|
Chris@0
|
163 $return = $statement->execute($args);
|
Chris@0
|
164 if (!$return) {
|
Chris@0
|
165 $this->throwPDOException();
|
Chris@0
|
166 }
|
Chris@0
|
167
|
Chris@0
|
168 if ($options['return'] == Database::RETURN_AFFECTED) {
|
Chris@0
|
169 $this->rowCount = $statement->rowCount();
|
Chris@0
|
170 }
|
Chris@0
|
171 // Fetch all the data from the reply, in order to release any lock
|
Chris@0
|
172 // as soon as possible.
|
Chris@0
|
173 $this->data = $statement->fetchAll(\PDO::FETCH_ASSOC);
|
Chris@0
|
174 // Destroy the statement as soon as possible. See the documentation of
|
Chris@0
|
175 // \Drupal\Core\Database\Driver\sqlite\Statement for an explanation.
|
Chris@0
|
176 unset($statement);
|
Chris@0
|
177
|
Chris@0
|
178 $this->resultRowCount = count($this->data);
|
Chris@0
|
179
|
Chris@0
|
180 if ($this->resultRowCount) {
|
Chris@0
|
181 $this->columnNames = array_keys($this->data[0]);
|
Chris@0
|
182 }
|
Chris@0
|
183 else {
|
Chris@0
|
184 $this->columnNames = [];
|
Chris@0
|
185 }
|
Chris@0
|
186
|
Chris@0
|
187 if (!empty($logger)) {
|
Chris@0
|
188 $query_end = microtime(TRUE);
|
Chris@0
|
189 $logger->log($this, $args, $query_end - $query_start);
|
Chris@0
|
190 }
|
Chris@0
|
191
|
Chris@0
|
192 // Initialize the first row in $this->currentRow.
|
Chris@0
|
193 $this->next();
|
Chris@0
|
194
|
Chris@0
|
195 return $return;
|
Chris@0
|
196 }
|
Chris@0
|
197
|
Chris@0
|
198 /**
|
Chris@0
|
199 * Throw a PDO Exception based on the last PDO error.
|
Chris@0
|
200 */
|
Chris@0
|
201 protected function throwPDOException() {
|
Chris@0
|
202 $error_info = $this->dbh->errorInfo();
|
Chris@0
|
203 // We rebuild a message formatted in the same way as PDO.
|
Chris@0
|
204 $exception = new \PDOException("SQLSTATE[" . $error_info[0] . "]: General error " . $error_info[1] . ": " . $error_info[2]);
|
Chris@0
|
205 $exception->errorInfo = $error_info;
|
Chris@0
|
206 throw $exception;
|
Chris@0
|
207 }
|
Chris@0
|
208
|
Chris@0
|
209 /**
|
Chris@0
|
210 * Grab a PDOStatement object from a given query and its arguments.
|
Chris@0
|
211 *
|
Chris@0
|
212 * Some drivers (including SQLite) will need to perform some preparation
|
Chris@0
|
213 * themselves to get the statement right.
|
Chris@0
|
214 *
|
Chris@0
|
215 * @param $query
|
Chris@0
|
216 * The query.
|
Chris@16
|
217 * @param array|null $args
|
Chris@16
|
218 * An array of arguments. This can be NULL.
|
Chris@0
|
219 * @return \PDOStatement
|
Chris@0
|
220 * A PDOStatement object.
|
Chris@0
|
221 */
|
Chris@0
|
222 protected function getStatement($query, &$args = []) {
|
Chris@0
|
223 return $this->dbh->prepare($query);
|
Chris@0
|
224 }
|
Chris@0
|
225
|
Chris@0
|
226 /**
|
Chris@0
|
227 * {@inheritdoc}
|
Chris@0
|
228 */
|
Chris@0
|
229 public function getQueryString() {
|
Chris@0
|
230 return $this->queryString;
|
Chris@0
|
231 }
|
Chris@0
|
232
|
Chris@0
|
233 /**
|
Chris@0
|
234 * {@inheritdoc}
|
Chris@0
|
235 */
|
Chris@0
|
236 public function setFetchMode($mode, $a1 = NULL, $a2 = []) {
|
Chris@0
|
237 $this->defaultFetchStyle = $mode;
|
Chris@0
|
238 switch ($mode) {
|
Chris@0
|
239 case \PDO::FETCH_CLASS:
|
Chris@0
|
240 $this->defaultFetchOptions['class'] = $a1;
|
Chris@0
|
241 if ($a2) {
|
Chris@0
|
242 $this->defaultFetchOptions['constructor_args'] = $a2;
|
Chris@0
|
243 }
|
Chris@0
|
244 break;
|
Chris@0
|
245 case \PDO::FETCH_COLUMN:
|
Chris@0
|
246 $this->defaultFetchOptions['column'] = $a1;
|
Chris@0
|
247 break;
|
Chris@0
|
248 case \PDO::FETCH_INTO:
|
Chris@0
|
249 $this->defaultFetchOptions['object'] = $a1;
|
Chris@0
|
250 break;
|
Chris@0
|
251 }
|
Chris@0
|
252
|
Chris@0
|
253 // Set the values for the next fetch.
|
Chris@0
|
254 $this->fetchStyle = $this->defaultFetchStyle;
|
Chris@0
|
255 $this->fetchOptions = $this->defaultFetchOptions;
|
Chris@0
|
256 }
|
Chris@0
|
257
|
Chris@0
|
258 /**
|
Chris@0
|
259 * Return the current row formatted according to the current fetch style.
|
Chris@0
|
260 *
|
Chris@0
|
261 * This is the core method of this class. It grabs the value at the current
|
Chris@0
|
262 * array position in $this->data and format it according to $this->fetchStyle
|
Chris@0
|
263 * and $this->fetchMode.
|
Chris@0
|
264 *
|
Chris@0
|
265 * @return mixed
|
Chris@0
|
266 * The current row formatted as requested.
|
Chris@0
|
267 */
|
Chris@0
|
268 public function current() {
|
Chris@0
|
269 if (isset($this->currentRow)) {
|
Chris@0
|
270 switch ($this->fetchStyle) {
|
Chris@0
|
271 case \PDO::FETCH_ASSOC:
|
Chris@0
|
272 return $this->currentRow;
|
Chris@0
|
273 case \PDO::FETCH_BOTH:
|
Chris@0
|
274 // \PDO::FETCH_BOTH returns an array indexed by both the column name
|
Chris@0
|
275 // and the column number.
|
Chris@0
|
276 return $this->currentRow + array_values($this->currentRow);
|
Chris@0
|
277 case \PDO::FETCH_NUM:
|
Chris@0
|
278 return array_values($this->currentRow);
|
Chris@0
|
279 case \PDO::FETCH_LAZY:
|
Chris@0
|
280 // We do not do lazy as everything is fetched already. Fallback to
|
Chris@0
|
281 // \PDO::FETCH_OBJ.
|
Chris@0
|
282 case \PDO::FETCH_OBJ:
|
Chris@0
|
283 return (object) $this->currentRow;
|
Chris@0
|
284 case \PDO::FETCH_CLASS | \PDO::FETCH_CLASSTYPE:
|
Chris@0
|
285 $class_name = array_unshift($this->currentRow);
|
Chris@0
|
286 // Deliberate no break.
|
Chris@0
|
287 case \PDO::FETCH_CLASS:
|
Chris@0
|
288 if (!isset($class_name)) {
|
Chris@0
|
289 $class_name = $this->fetchOptions['class'];
|
Chris@0
|
290 }
|
Chris@0
|
291 if (count($this->fetchOptions['constructor_args'])) {
|
Chris@0
|
292 $reflector = new \ReflectionClass($class_name);
|
Chris@0
|
293 $result = $reflector->newInstanceArgs($this->fetchOptions['constructor_args']);
|
Chris@0
|
294 }
|
Chris@0
|
295 else {
|
Chris@0
|
296 $result = new $class_name();
|
Chris@0
|
297 }
|
Chris@0
|
298 foreach ($this->currentRow as $k => $v) {
|
Chris@0
|
299 $result->$k = $v;
|
Chris@0
|
300 }
|
Chris@0
|
301 return $result;
|
Chris@0
|
302 case \PDO::FETCH_INTO:
|
Chris@0
|
303 foreach ($this->currentRow as $k => $v) {
|
Chris@0
|
304 $this->fetchOptions['object']->$k = $v;
|
Chris@0
|
305 }
|
Chris@0
|
306 return $this->fetchOptions['object'];
|
Chris@0
|
307 case \PDO::FETCH_COLUMN:
|
Chris@0
|
308 if (isset($this->columnNames[$this->fetchOptions['column']])) {
|
Chris@0
|
309 return $this->currentRow[$this->columnNames[$this->fetchOptions['column']]];
|
Chris@0
|
310 }
|
Chris@0
|
311 else {
|
Chris@0
|
312 return;
|
Chris@0
|
313 }
|
Chris@0
|
314 }
|
Chris@0
|
315 }
|
Chris@0
|
316 }
|
Chris@0
|
317
|
Chris@0
|
318 /**
|
Chris@0
|
319 * {@inheritdoc}
|
Chris@0
|
320 */
|
Chris@0
|
321 public function key() {
|
Chris@0
|
322 return $this->currentKey;
|
Chris@0
|
323 }
|
Chris@0
|
324
|
Chris@0
|
325 /**
|
Chris@0
|
326 * {@inheritdoc}
|
Chris@0
|
327 */
|
Chris@0
|
328 public function rewind() {
|
Chris@0
|
329 // Nothing to do: our DatabaseStatement can't be rewound.
|
Chris@0
|
330 }
|
Chris@0
|
331
|
Chris@0
|
332 /**
|
Chris@0
|
333 * {@inheritdoc}
|
Chris@0
|
334 */
|
Chris@0
|
335 public function next() {
|
Chris@0
|
336 if (!empty($this->data)) {
|
Chris@0
|
337 $this->currentRow = reset($this->data);
|
Chris@0
|
338 $this->currentKey = key($this->data);
|
Chris@0
|
339 unset($this->data[$this->currentKey]);
|
Chris@0
|
340 }
|
Chris@0
|
341 else {
|
Chris@0
|
342 $this->currentRow = NULL;
|
Chris@0
|
343 }
|
Chris@0
|
344 }
|
Chris@0
|
345
|
Chris@0
|
346 /**
|
Chris@0
|
347 * {@inheritdoc}
|
Chris@0
|
348 */
|
Chris@0
|
349 public function valid() {
|
Chris@0
|
350 return isset($this->currentRow);
|
Chris@0
|
351 }
|
Chris@0
|
352
|
Chris@0
|
353 /**
|
Chris@0
|
354 * {@inheritdoc}
|
Chris@0
|
355 */
|
Chris@0
|
356 public function rowCount() {
|
Chris@0
|
357 // SELECT query should not use the method.
|
Chris@0
|
358 if ($this->allowRowCount) {
|
Chris@0
|
359 return $this->rowCount;
|
Chris@0
|
360 }
|
Chris@0
|
361 else {
|
Chris@0
|
362 throw new RowCountException();
|
Chris@0
|
363 }
|
Chris@0
|
364 }
|
Chris@0
|
365
|
Chris@0
|
366 /**
|
Chris@0
|
367 * {@inheritdoc}
|
Chris@0
|
368 */
|
Chris@0
|
369 public function fetch($fetch_style = NULL, $cursor_orientation = \PDO::FETCH_ORI_NEXT, $cursor_offset = NULL) {
|
Chris@0
|
370 if (isset($this->currentRow)) {
|
Chris@0
|
371 // Set the fetch parameter.
|
Chris@0
|
372 $this->fetchStyle = isset($fetch_style) ? $fetch_style : $this->defaultFetchStyle;
|
Chris@0
|
373 $this->fetchOptions = $this->defaultFetchOptions;
|
Chris@0
|
374
|
Chris@0
|
375 // Grab the row in the format specified above.
|
Chris@0
|
376 $return = $this->current();
|
Chris@0
|
377 // Advance the cursor.
|
Chris@0
|
378 $this->next();
|
Chris@0
|
379
|
Chris@0
|
380 // Reset the fetch parameters to the value stored using setFetchMode().
|
Chris@0
|
381 $this->fetchStyle = $this->defaultFetchStyle;
|
Chris@0
|
382 $this->fetchOptions = $this->defaultFetchOptions;
|
Chris@0
|
383 return $return;
|
Chris@0
|
384 }
|
Chris@0
|
385 else {
|
Chris@0
|
386 return FALSE;
|
Chris@0
|
387 }
|
Chris@0
|
388 }
|
Chris@0
|
389
|
Chris@0
|
390 public function fetchColumn($index = 0) {
|
Chris@0
|
391 if (isset($this->currentRow) && isset($this->columnNames[$index])) {
|
Chris@0
|
392 // We grab the value directly from $this->data, and format it.
|
Chris@0
|
393 $return = $this->currentRow[$this->columnNames[$index]];
|
Chris@0
|
394 $this->next();
|
Chris@0
|
395 return $return;
|
Chris@0
|
396 }
|
Chris@0
|
397 else {
|
Chris@0
|
398 return FALSE;
|
Chris@0
|
399 }
|
Chris@0
|
400 }
|
Chris@0
|
401
|
Chris@0
|
402 /**
|
Chris@0
|
403 * {@inheritdoc}
|
Chris@0
|
404 */
|
Chris@0
|
405 public function fetchField($index = 0) {
|
Chris@0
|
406 return $this->fetchColumn($index);
|
Chris@0
|
407 }
|
Chris@0
|
408
|
Chris@0
|
409 /**
|
Chris@0
|
410 * {@inheritdoc}
|
Chris@0
|
411 */
|
Chris@0
|
412 public function fetchObject($class_name = NULL, $constructor_args = []) {
|
Chris@0
|
413 if (isset($this->currentRow)) {
|
Chris@0
|
414 if (!isset($class_name)) {
|
Chris@0
|
415 // Directly cast to an object to avoid a function call.
|
Chris@0
|
416 $result = (object) $this->currentRow;
|
Chris@0
|
417 }
|
Chris@0
|
418 else {
|
Chris@0
|
419 $this->fetchStyle = \PDO::FETCH_CLASS;
|
Chris@0
|
420 $this->fetchOptions = ['constructor_args' => $constructor_args];
|
Chris@0
|
421 // Grab the row in the format specified above.
|
Chris@0
|
422 $result = $this->current();
|
Chris@0
|
423 // Reset the fetch parameters to the value stored using setFetchMode().
|
Chris@0
|
424 $this->fetchStyle = $this->defaultFetchStyle;
|
Chris@0
|
425 $this->fetchOptions = $this->defaultFetchOptions;
|
Chris@0
|
426 }
|
Chris@0
|
427
|
Chris@0
|
428 $this->next();
|
Chris@0
|
429
|
Chris@0
|
430 return $result;
|
Chris@0
|
431 }
|
Chris@0
|
432 else {
|
Chris@0
|
433 return FALSE;
|
Chris@0
|
434 }
|
Chris@0
|
435 }
|
Chris@0
|
436
|
Chris@0
|
437 /**
|
Chris@0
|
438 * {@inheritdoc}
|
Chris@0
|
439 */
|
Chris@0
|
440 public function fetchAssoc() {
|
Chris@0
|
441 if (isset($this->currentRow)) {
|
Chris@0
|
442 $result = $this->currentRow;
|
Chris@0
|
443 $this->next();
|
Chris@0
|
444 return $result;
|
Chris@0
|
445 }
|
Chris@0
|
446 else {
|
Chris@0
|
447 return FALSE;
|
Chris@0
|
448 }
|
Chris@0
|
449 }
|
Chris@0
|
450
|
Chris@0
|
451 /**
|
Chris@0
|
452 * {@inheritdoc}
|
Chris@0
|
453 */
|
Chris@0
|
454 public function fetchAll($mode = NULL, $column_index = NULL, $constructor_arguments = NULL) {
|
Chris@0
|
455 $this->fetchStyle = isset($mode) ? $mode : $this->defaultFetchStyle;
|
Chris@0
|
456 $this->fetchOptions = $this->defaultFetchOptions;
|
Chris@0
|
457 if (isset($column_index)) {
|
Chris@0
|
458 $this->fetchOptions['column'] = $column_index;
|
Chris@0
|
459 }
|
Chris@0
|
460 if (isset($constructor_arguments)) {
|
Chris@0
|
461 $this->fetchOptions['constructor_args'] = $constructor_arguments;
|
Chris@0
|
462 }
|
Chris@0
|
463
|
Chris@0
|
464 $result = [];
|
Chris@0
|
465 // Traverse the array as PHP would have done.
|
Chris@0
|
466 while (isset($this->currentRow)) {
|
Chris@0
|
467 // Grab the row in the format specified above.
|
Chris@0
|
468 $result[] = $this->current();
|
Chris@0
|
469 $this->next();
|
Chris@0
|
470 }
|
Chris@0
|
471
|
Chris@0
|
472 // Reset the fetch parameters to the value stored using setFetchMode().
|
Chris@0
|
473 $this->fetchStyle = $this->defaultFetchStyle;
|
Chris@0
|
474 $this->fetchOptions = $this->defaultFetchOptions;
|
Chris@0
|
475 return $result;
|
Chris@0
|
476 }
|
Chris@0
|
477
|
Chris@0
|
478 /**
|
Chris@0
|
479 * {@inheritdoc}
|
Chris@0
|
480 */
|
Chris@0
|
481 public function fetchCol($index = 0) {
|
Chris@0
|
482 if (isset($this->columnNames[$index])) {
|
Chris@0
|
483 $result = [];
|
Chris@0
|
484 // Traverse the array as PHP would have done.
|
Chris@0
|
485 while (isset($this->currentRow)) {
|
Chris@0
|
486 $result[] = $this->currentRow[$this->columnNames[$index]];
|
Chris@0
|
487 $this->next();
|
Chris@0
|
488 }
|
Chris@0
|
489 return $result;
|
Chris@0
|
490 }
|
Chris@0
|
491 else {
|
Chris@0
|
492 return [];
|
Chris@0
|
493 }
|
Chris@0
|
494 }
|
Chris@0
|
495
|
Chris@0
|
496 /**
|
Chris@0
|
497 * {@inheritdoc}
|
Chris@0
|
498 */
|
Chris@0
|
499 public function fetchAllKeyed($key_index = 0, $value_index = 1) {
|
Chris@0
|
500 if (!isset($this->columnNames[$key_index]) || !isset($this->columnNames[$value_index])) {
|
Chris@0
|
501 return [];
|
Chris@0
|
502 }
|
Chris@0
|
503
|
Chris@0
|
504 $key = $this->columnNames[$key_index];
|
Chris@0
|
505 $value = $this->columnNames[$value_index];
|
Chris@0
|
506
|
Chris@0
|
507 $result = [];
|
Chris@0
|
508 // Traverse the array as PHP would have done.
|
Chris@0
|
509 while (isset($this->currentRow)) {
|
Chris@0
|
510 $result[$this->currentRow[$key]] = $this->currentRow[$value];
|
Chris@0
|
511 $this->next();
|
Chris@0
|
512 }
|
Chris@0
|
513 return $result;
|
Chris@0
|
514 }
|
Chris@0
|
515
|
Chris@0
|
516 /**
|
Chris@0
|
517 * {@inheritdoc}
|
Chris@0
|
518 */
|
Chris@0
|
519 public function fetchAllAssoc($key, $fetch_style = NULL) {
|
Chris@0
|
520 $this->fetchStyle = isset($fetch_style) ? $fetch_style : $this->defaultFetchStyle;
|
Chris@0
|
521 $this->fetchOptions = $this->defaultFetchOptions;
|
Chris@0
|
522
|
Chris@0
|
523 $result = [];
|
Chris@0
|
524 // Traverse the array as PHP would have done.
|
Chris@0
|
525 while (isset($this->currentRow)) {
|
Chris@0
|
526 // Grab the row in its raw \PDO::FETCH_ASSOC format.
|
Chris@0
|
527 $result_row = $this->current();
|
Chris@0
|
528 $result[$this->currentRow[$key]] = $result_row;
|
Chris@0
|
529 $this->next();
|
Chris@0
|
530 }
|
Chris@0
|
531
|
Chris@0
|
532 // Reset the fetch parameters to the value stored using setFetchMode().
|
Chris@0
|
533 $this->fetchStyle = $this->defaultFetchStyle;
|
Chris@0
|
534 $this->fetchOptions = $this->defaultFetchOptions;
|
Chris@0
|
535 return $result;
|
Chris@0
|
536 }
|
Chris@0
|
537
|
Chris@0
|
538 }
|