class DatabaseStatement_sqlite in Drupal 7
Specific SQLite implementation of DatabaseConnection.
See DatabaseConnection_sqlite::PDOPrepare() for reasons why we must prefetch the data instead of using PDOStatement.
Hierarchy
- class \DatabaseStatementPrefetch implements \Iterator, DatabaseStatementInterface
- class \DatabaseStatement_sqlite implements \Iterator, DatabaseStatementInterface
Expanded class hierarchy of DatabaseStatement_sqlite
See also
DatabaseConnection_sqlite::PDOPrepare()
File
- includes/
database/ sqlite/ database.inc, line 423 - Database interface code for SQLite embedded database engine.
View source
class DatabaseStatement_sqlite extends DatabaseStatementPrefetch implements Iterator, DatabaseStatementInterface {
/**
* SQLite specific implementation of getStatement().
*
* The PDO SQLite layer doesn't replace numeric placeholders in queries
* correctly, and this makes numeric expressions (such as COUNT(*) >= :count)
* fail. We replace numeric placeholders in the query ourselves to work
* around this bug.
*
* See http://bugs.php.net/bug.php?id=45259 for more details.
*/
protected function getStatement($query, &$args = array()) {
if (count($args)) {
// Check if $args is a simple numeric array.
if (range(0, count($args) - 1) === array_keys($args)) {
// In that case, we have unnamed placeholders.
$count = 0;
$new_args = array();
foreach ($args as $value) {
if (is_float($value) || is_int($value)) {
if (is_float($value)) {
// Force the conversion to float so as not to loose precision
// in the automatic cast.
$value = sprintf('%F', $value);
}
$query = substr_replace($query, $value, strpos($query, '?'), 1);
}
else {
$placeholder = ':db_statement_placeholder_' . $count++;
$query = substr_replace($query, $placeholder, strpos($query, '?'), 1);
$new_args[$placeholder] = $value;
}
}
$args = $new_args;
}
else {
// Else, this is using named placeholders.
foreach ($args as $placeholder => $value) {
if (is_float($value) || is_int($value)) {
if (is_float($value)) {
// Force the conversion to float so as not to loose precision
// in the automatic cast.
$value = sprintf('%F', $value);
}
// We will remove this placeholder from the query as PDO throws an
// exception if the number of placeholders in the query and the
// arguments does not match.
unset($args[$placeholder]);
// PDO allows placeholders to not be prefixed by a colon. See
// http://marc.info/?l=php-internals&m=111234321827149&w=2 for
// more.
if ($placeholder[0] != ':') {
$placeholder = ":{$placeholder}";
}
// When replacing the placeholders, make sure we search for the
// exact placeholder. For example, if searching for
// ':db_placeholder_1', do not replace ':db_placeholder_11'.
$query = preg_replace('/' . preg_quote($placeholder) . '\\b/', $value, $query);
}
}
}
}
return $this->dbh
->PDOPrepare($query);
}
public function execute($args = array(), $options = array()) {
try {
$return = parent::execute($args, $options);
} catch (PDOException $e) {
if (!empty($e->errorInfo[1]) && $e->errorInfo[1] === 17) {
// The schema has changed. SQLite specifies that we must resend the query.
$return = parent::execute($args, $options);
}
else {
// Rethrow the exception.
throw $e;
}
}
// In some weird cases, SQLite will prefix some column names by the name
// of the table. We post-process the data, by renaming the column names
// using the same convention as MySQL and PostgreSQL.
$rename_columns = array();
foreach ($this->columnNames as $k => $column) {
// In some SQLite versions, SELECT DISTINCT(field) will return "(field)"
// instead of "field".
if (preg_match("/^\\((.*)\\)\$/", $column, $matches)) {
$rename_columns[$column] = $matches[1];
$this->columnNames[$k] = $matches[1];
$column = $matches[1];
}
// Remove "table." prefixes.
if (preg_match("/^.*\\.(.*)\$/", $column, $matches)) {
$rename_columns[$column] = $matches[1];
$this->columnNames[$k] = $matches[1];
}
}
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]);
}
}
// Finally, extract the first row again.
$this->currentRow = $this->data[0];
unset($this->data[0]);
}
return $return;
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DatabaseStatementPrefetch:: |
protected | property | The list of column names in this result set. | |
DatabaseStatementPrefetch:: |
protected | property | The key of the current row. | |
DatabaseStatementPrefetch:: |
protected | property | The current row, retrieved in PDO::FETCH_ASSOC format. | |
DatabaseStatementPrefetch:: |
protected | property | Main data store. | |
DatabaseStatementPrefetch:: |
public | property | Reference to the database connection object for this statement. | |
DatabaseStatementPrefetch:: |
protected | property | Holds supplementary default fetch options. | |
DatabaseStatementPrefetch:: |
protected | property | Holds the default fetch style. | |
DatabaseStatementPrefetch:: |
protected | property | Driver-specific options. Can be used by child classes. | |
DatabaseStatementPrefetch:: |
protected | property | Holds supplementary current fetch options (which will be used by the next fetch). | |
DatabaseStatementPrefetch:: |
protected | property | Holds the current fetch style (which will be used by the next fetch). | |
DatabaseStatementPrefetch:: |
protected | property | The query string. | |
DatabaseStatementPrefetch:: |
protected | property | The number of rows in this result set. | |
DatabaseStatementPrefetch:: |
protected | property | The number of rows affected by the last query. | |
DatabaseStatementPrefetch:: |
public | function | Return the current row formatted according to the current fetch style. | |
DatabaseStatementPrefetch:: |
public | function | ||
DatabaseStatementPrefetch:: |
public | function | ||
DatabaseStatementPrefetch:: |
public | function |
Returns the result set as an associative array keyed by the given field. Overrides DatabaseStatementInterface:: |
|
DatabaseStatementPrefetch:: |
public | function |
Returns the entire result set as a single associative array. Overrides DatabaseStatementInterface:: |
|
DatabaseStatementPrefetch:: |
public | function |
Fetches the next row and returns it as an associative array. Overrides DatabaseStatementInterface:: |
|
DatabaseStatementPrefetch:: |
public | function |
Returns an entire single column of a result set as an indexed array. Overrides DatabaseStatementInterface:: |
|
DatabaseStatementPrefetch:: |
public | function | ||
DatabaseStatementPrefetch:: |
public | function |
Returns a single field from the next record of a result set. Overrides DatabaseStatementInterface:: |
|
DatabaseStatementPrefetch:: |
public | function | ||
DatabaseStatementPrefetch:: |
public | function |
Return the object's SQL query string. Overrides DatabaseStatementInterface:: |
|
DatabaseStatementPrefetch:: |
public | function | ||
DatabaseStatementPrefetch:: |
public | function | ||
DatabaseStatementPrefetch:: |
public | function | ||
DatabaseStatementPrefetch:: |
public | function |
Returns the number of rows affected by the last SQL statement. Overrides DatabaseStatementInterface:: |
|
DatabaseStatementPrefetch:: |
public | function | ||
DatabaseStatementPrefetch:: |
protected | function | Throw a PDO Exception based on the last PDO error. | |
DatabaseStatementPrefetch:: |
public | function | ||
DatabaseStatementPrefetch:: |
public | function | ||
DatabaseStatement_sqlite:: |
public | function |
Executes a prepared statement. Overrides DatabaseStatementPrefetch:: |
|
DatabaseStatement_sqlite:: |
protected | function |
SQLite specific implementation of getStatement(). Overrides DatabaseStatementPrefetch:: |