summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2008-12-09 11:22:11 +0000
committerDries Buytaert <dries@buytaert.net>2008-12-09 11:22:11 +0000
commit7c30a1bac9ce4843178203040306c7ffd4dbc20c (patch)
treea2e3f02902ca6e36229e22db12f8945ebcedeede /includes
parent6f859fdd8fa5272a3491074792c0c0015051cee9 (diff)
downloadbrdo-7c30a1bac9ce4843178203040306c7ffd4dbc20c.tar.gz
brdo-7c30a1bac9ce4843178203040306c7ffd4dbc20c.tar.bz2
- Patch #342693 by Damien Tournoud et al: DatabaseStatement Prefect iterator did not implement a proper forward-only one cursor.
Diffstat (limited to 'includes')
-rw-r--r--includes/database/prefetch.inc94
-rw-r--r--includes/database/sqlite/database.inc16
2 files changed, 59 insertions, 51 deletions
diff --git a/includes/database/prefetch.inc b/includes/database/prefetch.inc
index 1132114d9..964256ffa 100644
--- a/includes/database/prefetch.inc
+++ b/includes/database/prefetch.inc
@@ -53,11 +53,18 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
protected $data = array();
/**
- * Flag indicating whether $data contains valid data.
+ * The current row, retrieved in PDO::FETCH_ASSOC format.
*
- * @var bool
+ * @var Array
*/
- protected $isValid = FALSE;
+ protected $currentRow = NULL;
+
+ /**
+ * The key of the current row.
+ *
+ * @var int
+ */
+ protected $currentKey = NULL;
/**
* The list of column names in this result set.
@@ -177,11 +184,9 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
if ($this->resultRowCount) {
$this->columnNames = array_keys($this->data[0]);
- $this->isValid = TRUE;
}
else {
$this->columnNames = array();
- $this->isValid = FALSE;
}
if (!empty($logger)) {
@@ -189,9 +194,8 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
$logger->log($this, $args, $query_end - $query_start);
}
- // We will iterate this array so we need to make sure the array pointer is
- // at the beginning.
- reset($this->data);
+ // Initialize the first row in $this->currentRow.
+ $this->next();
return $return;
}
@@ -267,22 +271,23 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
* The current row formatted as requested.
*/
public function current() {
- $row = current($this->data);
- if ($row !== FALSE) {
+ if (isset($this->currentRow)) {
switch ($this->fetchStyle) {
case PDO::FETCH_ASSOC:
- return $row;
+ return $this->currentRow;
case PDO::FETCH_BOTH:
- return $row + array_values($row);
+ // PDO::FETCH_BOTH returns an array indexed by both the column name
+ // and the column number.
+ return $this->currentRow + array_values($this->currentRow);
case PDO::FETCH_NUM:
- return array_values($row);
+ return array_values($this->currentRow);
case PDO::FETCH_LAZY:
// We do not do lazy as everything is fetched already. Fallback to
// PDO::FETCH_OBJ.
case PDO::FETCH_OBJ:
- return (object) $row;
+ return (object) $this->currentRow;
case PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE:
- $class_name = array_unshift($row);
+ $class_name = array_unshift($this->currentRow);
// Deliberate no break.
case PDO::FETCH_CLASS:
if (!isset($class_name)) {
@@ -295,18 +300,18 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
else {
$result = new $class_name();
}
- foreach ($row as $k => $v) {
+ foreach ($this->currentRow as $k => $v) {
$result->$k = $v;
}
return $result;
case PDO::FETCH_INTO:
- foreach ($row as $k => $v) {
+ foreach ($this->currentRow as $k => $v) {
$this->fetchOptions['object']->$k = $v;
}
return $this->fetchOptions['object'];
case PDO::FETCH_COLUMN:
if (isset($this->columnNames[$this->fetchOptions['column']])) {
- return $row[$k][$this->columnNames[$this->fetchOptions['column']]];
+ return $this->currentRow[$k][$this->columnNames[$this->fetchOptions['column']]];
}
else {
return;
@@ -318,26 +323,26 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
/* Implementations of Iterator. */
public function key() {
- return key($this->data);
+ return $this->currentKey;
}
public function rewind() {
- reset($this->data);
- if (count($this->data)) {
- $this->isValid = TRUE;
- }
+ // Nothing to do: our DatabaseStatement can't be rewound.
}
public function next() {
- // We fetch rows as PDO::FETCH_ASSOC in execute(),
- // so no element of the array can ever be FALSE.
- if (next($this->data) === FALSE) {
- $this->isValid = FALSE;
+ if (!empty($this->data)) {
+ $this->currentRow = reset($this->data);
+ $this->currentKey = key($this->data);
+ unset($this->data[$this->currentKey]);
+ }
+ else {
+ $this->currentRow = NULL;
}
}
public function valid() {
- return $this->isValid;
+ return isset($this->currentRow);
}
/* Implementations of DatabaseStatementInterface. */
@@ -347,7 +352,7 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
}
public function fetch($fetch_style = NULL, $cursor_orientation = PDO::FETCH_ORI_NEXT, $cursor_offset = NULL) {
- if ($this->isValid) {
+ if (isset($this->currentRow)) {
// Set the fetch parameter.
$this->fetchStyle = isset($fetch_style) ? $fetch_style : $this->defaultFetchStyle;
$this->fetchOptions = $this->defaultFetchOptions;
@@ -368,10 +373,9 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
}
public function fetchField($index = 0) {
- if ($this->isValid && isset($this->columnNames[$index])) {
+ if (isset($this->currentRow) && isset($this->columnNames[$index])) {
// We grab the value directly from $this->data, and format it.
- $current = current($this->data);
- $return = $current[$this->columnNames[$index]];
+ $return = $this->currentRow[$this->columnNames[$index]];
$this->next();
return $return;
}
@@ -381,10 +385,10 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
}
public function fetchObject($class_name = NULL, $constructor_args = array()) {
- if ($this->isValid) {
+ if (isset($this->currentRow)) {
if (!isset($class_name)) {
// Directly cast to an object to avoid a function call.
- $result = (object) current($this->data);
+ $result = (object) $this->currentRow;
}
else {
$this->fetchStyle = PDO::FETCH_CLASS;
@@ -406,8 +410,8 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
}
public function fetchAssoc() {
- if ($this->isValid) {
- $result = current($this->data);
+ if (isset($this->currentRow)) {
+ $result = $this->currentRow;
$this->next();
return $result;
}
@@ -428,7 +432,7 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
$result = array();
// Traverse the array as PHP would have done.
- while ($this->isValid) {
+ while (isset($this->currentRow)) {
// Grab the row in the format specified above.
$result[] = $this->current();
$this->next();
@@ -445,9 +449,8 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
$column = $this->columnNames[$index];
$result = array();
// Traverse the array as PHP would have done.
- while ($this->isValid) {
- $current = current($this->data);
- $result[] = $current[$this->columnNames[$index]];
+ while (isset($this->currentRow)) {
+ $result[] = $this->currentRow[$this->columnNames[$index]];
$this->next();
}
return $result;
@@ -466,9 +469,8 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
$result = array();
// Traverse the array as PHP would have done.
- while ($this->isValid) {
- $row = current($this->data);
- $result[$row[$key]] = $row[$value];
+ while (isset($this->currentRow)) {
+ $result[$this->currentRow[$key]] = $this->currentRow[$value];
$this->next();
}
return $result;
@@ -480,12 +482,12 @@ class DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface
$result = array();
// Traverse the array as PHP would have done.
- while ($this->isValid) {
+ while (isset($this->currentRow)) {
// Grab the row in its raw PDO::FETCH_ASSOC format.
- $row = current($this->data);
+ $row = $this->currentRow;
// Grab the row in the format specified above.
$result_row = $this->current();
- $result[$row[$key]] = $result_row;
+ $result[$this->currentRow[$key]] = $result_row;
$this->next();
}
diff --git a/includes/database/sqlite/database.inc b/includes/database/sqlite/database.inc
index e10c7c1f0..e580e8c3f 100644
--- a/includes/database/sqlite/database.inc
+++ b/includes/database/sqlite/database.inc
@@ -246,21 +246,27 @@ class DatabaseStatement_sqlite extends DatabaseStatementPrefetch implements Iter
}
}
if ($rename_columns) {
+ // DatabaseStatementPrefetch already extracted the first row,
+ // put it back into the result set.
+ if (isset($this->currentRow)) {
+ $this->data[0] = &$this->currentRow;
+ }
+
+ // Then rename all the columns across the result set.
foreach ($this->data as $k => $row) {
foreach ($rename_columns as $old_column => $new_column) {
$this->data[$k][$new_column] = $this->data[$k][$old_column];
unset($this->data[$k][$old_column]);
}
}
- }
- // We will iterate this array so we need to make sure the array pointer is
- // at the beginning.
- reset($this->data);
+ // Finally, extract the first row again.
+ $this->currentRow = $this->data[0];
+ unset($this->data[0]);
+ }
return $return;
}
-
}
/**