class Statement

Same name in other branches
  1. 9 core/modules/sqlite/src/Driver/Database/sqlite/Statement.php \Drupal\sqlite\Driver\Database\sqlite\Statement
  2. 9 core/lib/Drupal/Core/Database/Driver/sqlite/Statement.php \Drupal\Core\Database\Driver\sqlite\Statement
  3. 9 core/lib/Drupal/Core/Database/Statement.php \Drupal\Core\Database\Statement
  4. 8.9.x core/lib/Drupal/Core/Database/Driver/sqlite/Statement.php \Drupal\Core\Database\Driver\sqlite\Statement
  5. 8.9.x core/lib/Drupal/Core/Database/Statement.php \Drupal\Core\Database\Statement
  6. 10 core/modules/sqlite/src/Driver/Database/sqlite/Statement.php \Drupal\sqlite\Driver\Database\sqlite\Statement
  7. 10 core/lib/Drupal/Core/Database/Driver/sqlite/Statement.php \Drupal\Core\Database\Driver\sqlite\Statement

SQLite implementation of \Drupal\Core\Database\Statement.

The PDO SQLite driver only closes SELECT statements when the PDOStatement destructor is called and SQLite does not allow data change (INSERT, UPDATE etc) on a table which has open SELECT statements. This is a user-space mock of PDOStatement that buffers all the data and doesn't have those limitations.

Hierarchy

Expanded class hierarchy of Statement

File

core/modules/sqlite/src/Driver/Database/sqlite/Statement.php, line 17

Namespace

Drupal\sqlite\Driver\Database\sqlite
View source
class Statement extends StatementPrefetchIterator implements StatementInterface {
    
    /**
     * {@inheritdoc}
     *
     * 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(string $query, ?array &$args = []) : object {
        if (is_array($args) && !empty($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 = [];
                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, NULL) . '\\b/', $value, $query);
                    }
                }
            }
        }
        return $this->clientConnection
            ->prepare($query);
    }
    
    /**
     * {@inheritdoc}
     */
    public function execute($args = [], $options = []) {
        if (isset($options['fetch']) && is_int($options['fetch'])) {
            @trigger_error("Passing the 'fetch' key as an integer to \$options in execute() is deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Use a case of \\Drupal\\Core\\Database\\FetchAs enum instead. See https://www.drupal.org/node/3488338", E_USER_DEPRECATED);
        }
        try {
            $return = parent::execute($args, $options);
        } catch (\PDOException $e) {
            // The database schema might be changed by another process in between the
            // time that the statement was prepared and the time the statement was run
            // (e.g. usually happens when running tests). In this case, we need to
            // re-run the query.
            // @see http://www.sqlite.org/faq.html#q15
            // @see http://www.sqlite.org/rescode.html#schema
            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;
            }
        }
        return $return;
    }

}

Members

Title Sort descending Deprecated Modifiers Object type Summary Overriden Title
FetchModeTrait::$fetchModeLiterals protected property Map FETCH_* modes to their literal for inclusion in messages.
FetchModeTrait::$supportedFetchModes protected property The fetch modes supported.
FetchModeTrait::assocToClass protected function Converts a row of data in FETCH_ASSOC format to FETCH_CLASS.
FetchModeTrait::assocToColumn protected function Converts a row of data in FETCH_ASSOC format to FETCH_COLUMN.
FetchModeTrait::assocToFetchMode protected function Converts a row of data in associative format to a specified format.
FetchModeTrait::assocToNum protected function Converts a row of data in FETCH_ASSOC format to FETCH_NUM.
FetchModeTrait::assocToObj protected function Converts a row of data in FETCH_ASSOC format to FETCH_OBJ.
PdoTrait::clientExecute protected function Executes the prepared PDO statement.
PdoTrait::clientFetch protected function Fetches the next row from the PDO statement.
PdoTrait::clientFetchAll protected function
PdoTrait::clientFetchColumn protected function Returns a single column from the next row of a result set.
PdoTrait::clientFetchObject protected function Fetches the next row and returns it as an object.
PdoTrait::clientQueryString protected function Returns the query string used to prepare the statement.
PdoTrait::clientRowCount protected function Returns the number of rows affected by the last SQL statement.
PdoTrait::clientSetFetchMode protected function Sets the default fetch mode for the PDO statement.
PdoTrait::fetchAsToPdo protected function Converts a FetchAs mode to a \PDO::FETCH_* constant value.
PdoTrait::getClientStatement public function Returns the client-level database PDO statement object.
PdoTrait::pdoToFetchAs protected function Converts a \PDO::FETCH_* constant value to a FetchAs mode.
Statement::execute public function Executes a prepared statement. Overrides StatementPrefetchIterator::execute
Statement::getStatement protected function 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.
Overrides StatementPrefetchIterator::getStatement
StatementBase::$clientStatement protected property The client database Statement object.
StatementBase::$fetchMode protected property Holds the default fetch mode.
StatementBase::$fetchOptions protected property Holds fetch options.
StatementBase::$result protected property The results of a data query language (DQL) statement.
StatementBase::dispatchStatementExecutionEndEvent protected function Dispatches an event informing that the statement execution succeeded.
StatementBase::dispatchStatementExecutionFailureEvent protected function Dispatches an event informing of the statement execution failure.
StatementBase::dispatchStatementExecutionStartEvent protected function Dispatches an event informing that the statement execution begins.
StatementBase::fetch public function Fetches the next row from a result set. Overrides StatementInterface::fetch
StatementBase::fetchAll public function Returns an array containing all of the result set rows. Overrides StatementInterface::fetchAll
StatementBase::fetchAllAssoc public function Returns the result set as an associative array keyed by the given field. Overrides StatementInterface::fetchAllAssoc
StatementBase::fetchAllKeyed public function Returns the entire result set as a single associative array. Overrides StatementInterface::fetchAllKeyed
StatementBase::fetchAssoc public function Fetches the next row and returns it as an associative array. Overrides StatementInterface::fetchAssoc
StatementBase::fetchCol public function Returns an entire single column of a result set as an indexed array. Overrides StatementInterface::fetchCol
StatementBase::fetchField public function Returns a single field from the next record of a result set. Overrides StatementInterface::fetchField
StatementBase::fetchObject public function Fetches the next row and returns it as an object. Overrides StatementInterface::fetchObject
StatementBase::getConnectionTarget public function Returns the target connection this statement is associated with. Overrides StatementInterface::getConnectionTarget
StatementBase::getQueryString public function Gets the query string of this statement. Overrides StatementInterface::getQueryString
StatementBase::rowCount public function Returns the number of rows matched by the last SQL statement. Overrides StatementInterface::rowCount
StatementBase::setFetchMode public function Sets the default fetch mode for this statement. Overrides StatementInterface::setFetchMode
StatementIteratorTrait::$isResultsetIterable private property Traces if rows can be fetched from the resultset.
StatementIteratorTrait::$resultsetKey private property The key of the current row.
StatementIteratorTrait::$resultsetRow private property The current row, retrieved in the current fetch format.
StatementIteratorTrait::current public function Returns the current element.
StatementIteratorTrait::getResultsetCurrentRowIndex protected function Returns the row index of the current element in the resultset.
StatementIteratorTrait::key public function Returns the key of the current element.
StatementIteratorTrait::markResultsetFetchingComplete protected function Informs the iterator that no more rows can be fetched from the resultset.
StatementIteratorTrait::markResultsetIterable protected function Informs the iterator whether rows can be fetched from the resultset.
StatementIteratorTrait::next public function Moves the current position to the next element.
StatementIteratorTrait::rewind public function Rewinds back to the first element of the Iterator.
StatementIteratorTrait::setResultsetCurrentRow protected function Sets the current resultset row for the iterator, and increments the key.
StatementIteratorTrait::valid public function Checks if current position is valid.
StatementPrefetchIterator::$columnNames Deprecated protected property The list of column names in this result set.
StatementPrefetchIterator::$data Deprecated protected property Main data store.
StatementPrefetchIterator::$defaultFetchMode Deprecated protected property Holds the default fetch mode.
StatementPrefetchIterator::$defaultFetchStyle Deprecated protected property Holds the default fetch style.
StatementPrefetchIterator::$rowCount Deprecated protected property The number of rows matched by the last query.
StatementPrefetchIterator::fetchColumn Deprecated public function
StatementPrefetchIterator::__construct public function Constructs a StatementPrefetchIterator object. Overrides StatementBase::__construct

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.