Loading core/lib/Drupal/Core/Database/Connection.php +8 −2 Changes for core/lib/Drupal/Core/Database/Connection.php: 8 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -543,6 +543,9 @@ public function getFullQualifiedTableName($table) { * An associative array of options to control how the query is run. See * the documentation for self::defaultOptions() for details. The content of * the 'pdo' key will be passed to the prepared statement. * @param bool $allow_row_count * (optional) A flag indicating if row count is allowed on the statement * object. Defaults to FALSE. * * @return \Drupal\Core\Database\StatementInterface * A PDO prepared statement ready for its execute() method. Loading @@ -552,14 +555,14 @@ public function getFullQualifiedTableName($table) { * not allowed in the query. * @throws \Drupal\Core\Database\DatabaseExceptionWrapper */ public function prepareStatement(string $query, array $options): StatementInterface { public function prepareStatement(string $query, array $options, bool $allow_row_count = FALSE): StatementInterface { try { $query = $this->preprocessStatement($query, $options); // @todo in Drupal 10, only return the StatementWrapper. // @see https://www.drupal.org/node/3177490 $statement = $this->statementWrapperClass ? new $this->statementWrapperClass($this, $this->connection, $query, $options['pdo'] ?? []) : new $this->statementWrapperClass($this, $this->connection, $query, $options['pdo'] ?? [], $allow_row_count) : $this->connection->prepare($query, $options['pdo'] ?? []); } catch (\Exception $e) { Loading Loading @@ -887,6 +890,9 @@ public function query($query, array $args = [], $options = []) { case Database::RETURN_STATEMENT: return $stmt; // Database::RETURN_AFFECTED should not be used; enable row counting // by passing the appropriate argument to the constructor instead. // @see https://www.drupal.org/node/3186368 case Database::RETURN_AFFECTED: $stmt->allowRowCount = TRUE; return $stmt->rowCount(); Loading core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php +2 −2 Changes for core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php: 2 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -201,13 +201,13 @@ public function query($query, array $args = [], $options = []) { /** * {@inheritdoc} */ public function prepareStatement(string $query, array $options): StatementInterface { public function prepareStatement(string $query, array $options, bool $allow_row_count = FALSE): StatementInterface { // mapConditionOperator converts some operations (LIKE, REGEXP, etc.) to // PostgreSQL equivalents (ILIKE, ~*, etc.). However PostgreSQL doesn't // automatically cast the fields to the right type for these operators, // so we need to alter the query and add the type-cast. $query = preg_replace('/ ([^ ]+) +(I*LIKE|NOT +I*LIKE|~\*|!~\*) /i', ' ${1}::text ${2} ', $query); return parent::prepareStatement($query, $options); return parent::prepareStatement($query, $options, $allow_row_count); } public function queryRange($query, $from, $count, array $args = [], array $options = []) { Loading core/lib/Drupal/Core/Database/Driver/pgsql/Update.php +3 −9 Changes for core/lib/Drupal/Core/Database/Driver/pgsql/Update.php: 3 added lines, 9 removed lines. Original line number Diff line number Diff line Loading @@ -2,7 +2,6 @@ namespace Drupal\Core\Database\Driver\pgsql; use Drupal\Core\Database\Database; use Drupal\Core\Database\Query\Update as QueryUpdate; use Drupal\Core\Database\Query\SelectInterface; Loading @@ -18,7 +17,7 @@ public function execute() { // Because we filter $fields the same way here and in __toString(), the // placeholders will all match up properly. $stmt = $this->connection->prepareStatement((string) $this, $this->queryOptions); $stmt = $this->connection->prepareStatement((string) $this, $this->queryOptions, TRUE); // Fetch the list of blobs and sequences used on that table. $table_information = $this->connection->schema()->queryTableInformation($this->table); Loading Loading @@ -69,20 +68,15 @@ public function execute() { } } $options = $this->queryOptions; $options['already_prepared'] = TRUE; $options['return'] = Database::RETURN_AFFECTED; $this->connection->addSavepoint(); try { $stmt->execute(NULL, $options); $stmt->execute(NULL, $this->queryOptions); $this->connection->releaseSavepoint(); $stmt->allowRowCount = TRUE; return $stmt->rowCount(); } catch (\Exception $e) { $this->connection->rollbackSavepoint(); throw $e; $this->connection->exceptionHandler()->handleExecutionException($e, $stmt, [], $this->queryOptions); } } Loading core/lib/Drupal/Core/Database/Driver/pgsql/Upsert.php +2 −3 Changes for core/lib/Drupal/Core/Database/Driver/pgsql/Upsert.php: 2 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -19,8 +19,7 @@ public function execute() { return NULL; } $stmt = $this->connection->prepareStatement((string) $this, $this->queryOptions); $stmt->allowRowCount = TRUE; $stmt = $this->connection->prepareStatement((string) $this, $this->queryOptions, TRUE); // Fetch the list of blobs and sequences used on that table. $table_information = $this->connection->schema()->queryTableInformation($this->table); Loading Loading @@ -87,7 +86,7 @@ public function execute() { } catch (\Exception $e) { $this->connection->rollbackSavepoint(); throw $e; $this->connection->exceptionHandler()->handleExecutionException($e, $stmt, [], $options); } } Loading core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php +14 −14 Changes for core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php: 14 added lines, 14 removed lines. Original line number Diff line number Diff line Loading @@ -2,7 +2,6 @@ namespace Drupal\Core\Database\Driver\sqlite; use Drupal\Core\Database\Database; use Drupal\Core\Database\DatabaseNotFoundException; use Drupal\Core\Database\Connection as DatabaseConnection; use Drupal\Core\Database\StatementInterface; Loading Loading @@ -431,10 +430,10 @@ public function mapConditionOperator($operator) { /** * {@inheritdoc} */ public function prepareStatement(string $query, array $options): StatementInterface { public function prepareStatement(string $query, array $options, bool $allow_row_count = FALSE): StatementInterface { try { $query = $this->preprocessStatement($query, $options); $statement = new Statement($this->connection, $this, $query, $options['pdo'] ?? []); $statement = new Statement($this->connection, $this, $query, $options['pdo'] ?? [], $allow_row_count); } catch (\Exception $e) { $this->exceptionHandler()->handleStatementException($e, $query, $options); Loading @@ -449,20 +448,21 @@ public function nextId($existing_id = 0) { // override nextId. However, this is unlikely as we deal with short strings // and integers and no known databases require special handling for those // simple cases. If another transaction wants to write the same row, it will // wait until this transaction commits. Also, the return value needs to be // set to RETURN_AFFECTED as if it were a real update() query otherwise it // is not possible to get the row count properly. $affected = $this->query('UPDATE {sequences} SET value = GREATEST(value, :existing_id) + 1', [ ':existing_id' => $existing_id, ], ['return' => Database::RETURN_AFFECTED]); if (!$affected) { $this->query('INSERT INTO {sequences} (value) VALUES (:existing_id + 1)', [ ':existing_id' => $existing_id, ]); // wait until this transaction commits. $stmt = $this->prepareStatement('UPDATE {sequences} SET [value] = GREATEST([value], :existing_id) + 1', [], TRUE); $args = [':existing_id' => $existing_id]; try { $stmt->execute($args); } catch (\Exception $e) { $this->exceptionHandler()->handleExecutionException($e, $stmt, $args, []); } if ($stmt->rowCount() === 0) { $this->query('INSERT INTO {sequences} ([value]) VALUES (:existing_id + 1)', $args); } // The transaction gets committed when the transaction object gets destroyed // because it gets out of scope. return $this->query('SELECT value FROM {sequences}')->fetchField(); return $this->query('SELECT [value] FROM {sequences}')->fetchField(); } /** Loading Loading
core/lib/Drupal/Core/Database/Connection.php +8 −2 Changes for core/lib/Drupal/Core/Database/Connection.php: 8 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -543,6 +543,9 @@ public function getFullQualifiedTableName($table) { * An associative array of options to control how the query is run. See * the documentation for self::defaultOptions() for details. The content of * the 'pdo' key will be passed to the prepared statement. * @param bool $allow_row_count * (optional) A flag indicating if row count is allowed on the statement * object. Defaults to FALSE. * * @return \Drupal\Core\Database\StatementInterface * A PDO prepared statement ready for its execute() method. Loading @@ -552,14 +555,14 @@ public function getFullQualifiedTableName($table) { * not allowed in the query. * @throws \Drupal\Core\Database\DatabaseExceptionWrapper */ public function prepareStatement(string $query, array $options): StatementInterface { public function prepareStatement(string $query, array $options, bool $allow_row_count = FALSE): StatementInterface { try { $query = $this->preprocessStatement($query, $options); // @todo in Drupal 10, only return the StatementWrapper. // @see https://www.drupal.org/node/3177490 $statement = $this->statementWrapperClass ? new $this->statementWrapperClass($this, $this->connection, $query, $options['pdo'] ?? []) : new $this->statementWrapperClass($this, $this->connection, $query, $options['pdo'] ?? [], $allow_row_count) : $this->connection->prepare($query, $options['pdo'] ?? []); } catch (\Exception $e) { Loading Loading @@ -887,6 +890,9 @@ public function query($query, array $args = [], $options = []) { case Database::RETURN_STATEMENT: return $stmt; // Database::RETURN_AFFECTED should not be used; enable row counting // by passing the appropriate argument to the constructor instead. // @see https://www.drupal.org/node/3186368 case Database::RETURN_AFFECTED: $stmt->allowRowCount = TRUE; return $stmt->rowCount(); Loading
core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php +2 −2 Changes for core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php: 2 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -201,13 +201,13 @@ public function query($query, array $args = [], $options = []) { /** * {@inheritdoc} */ public function prepareStatement(string $query, array $options): StatementInterface { public function prepareStatement(string $query, array $options, bool $allow_row_count = FALSE): StatementInterface { // mapConditionOperator converts some operations (LIKE, REGEXP, etc.) to // PostgreSQL equivalents (ILIKE, ~*, etc.). However PostgreSQL doesn't // automatically cast the fields to the right type for these operators, // so we need to alter the query and add the type-cast. $query = preg_replace('/ ([^ ]+) +(I*LIKE|NOT +I*LIKE|~\*|!~\*) /i', ' ${1}::text ${2} ', $query); return parent::prepareStatement($query, $options); return parent::prepareStatement($query, $options, $allow_row_count); } public function queryRange($query, $from, $count, array $args = [], array $options = []) { Loading
core/lib/Drupal/Core/Database/Driver/pgsql/Update.php +3 −9 Changes for core/lib/Drupal/Core/Database/Driver/pgsql/Update.php: 3 added lines, 9 removed lines. Original line number Diff line number Diff line Loading @@ -2,7 +2,6 @@ namespace Drupal\Core\Database\Driver\pgsql; use Drupal\Core\Database\Database; use Drupal\Core\Database\Query\Update as QueryUpdate; use Drupal\Core\Database\Query\SelectInterface; Loading @@ -18,7 +17,7 @@ public function execute() { // Because we filter $fields the same way here and in __toString(), the // placeholders will all match up properly. $stmt = $this->connection->prepareStatement((string) $this, $this->queryOptions); $stmt = $this->connection->prepareStatement((string) $this, $this->queryOptions, TRUE); // Fetch the list of blobs and sequences used on that table. $table_information = $this->connection->schema()->queryTableInformation($this->table); Loading Loading @@ -69,20 +68,15 @@ public function execute() { } } $options = $this->queryOptions; $options['already_prepared'] = TRUE; $options['return'] = Database::RETURN_AFFECTED; $this->connection->addSavepoint(); try { $stmt->execute(NULL, $options); $stmt->execute(NULL, $this->queryOptions); $this->connection->releaseSavepoint(); $stmt->allowRowCount = TRUE; return $stmt->rowCount(); } catch (\Exception $e) { $this->connection->rollbackSavepoint(); throw $e; $this->connection->exceptionHandler()->handleExecutionException($e, $stmt, [], $this->queryOptions); } } Loading
core/lib/Drupal/Core/Database/Driver/pgsql/Upsert.php +2 −3 Changes for core/lib/Drupal/Core/Database/Driver/pgsql/Upsert.php: 2 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -19,8 +19,7 @@ public function execute() { return NULL; } $stmt = $this->connection->prepareStatement((string) $this, $this->queryOptions); $stmt->allowRowCount = TRUE; $stmt = $this->connection->prepareStatement((string) $this, $this->queryOptions, TRUE); // Fetch the list of blobs and sequences used on that table. $table_information = $this->connection->schema()->queryTableInformation($this->table); Loading Loading @@ -87,7 +86,7 @@ public function execute() { } catch (\Exception $e) { $this->connection->rollbackSavepoint(); throw $e; $this->connection->exceptionHandler()->handleExecutionException($e, $stmt, [], $options); } } Loading
core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php +14 −14 Changes for core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php: 14 added lines, 14 removed lines. Original line number Diff line number Diff line Loading @@ -2,7 +2,6 @@ namespace Drupal\Core\Database\Driver\sqlite; use Drupal\Core\Database\Database; use Drupal\Core\Database\DatabaseNotFoundException; use Drupal\Core\Database\Connection as DatabaseConnection; use Drupal\Core\Database\StatementInterface; Loading Loading @@ -431,10 +430,10 @@ public function mapConditionOperator($operator) { /** * {@inheritdoc} */ public function prepareStatement(string $query, array $options): StatementInterface { public function prepareStatement(string $query, array $options, bool $allow_row_count = FALSE): StatementInterface { try { $query = $this->preprocessStatement($query, $options); $statement = new Statement($this->connection, $this, $query, $options['pdo'] ?? []); $statement = new Statement($this->connection, $this, $query, $options['pdo'] ?? [], $allow_row_count); } catch (\Exception $e) { $this->exceptionHandler()->handleStatementException($e, $query, $options); Loading @@ -449,20 +448,21 @@ public function nextId($existing_id = 0) { // override nextId. However, this is unlikely as we deal with short strings // and integers and no known databases require special handling for those // simple cases. If another transaction wants to write the same row, it will // wait until this transaction commits. Also, the return value needs to be // set to RETURN_AFFECTED as if it were a real update() query otherwise it // is not possible to get the row count properly. $affected = $this->query('UPDATE {sequences} SET value = GREATEST(value, :existing_id) + 1', [ ':existing_id' => $existing_id, ], ['return' => Database::RETURN_AFFECTED]); if (!$affected) { $this->query('INSERT INTO {sequences} (value) VALUES (:existing_id + 1)', [ ':existing_id' => $existing_id, ]); // wait until this transaction commits. $stmt = $this->prepareStatement('UPDATE {sequences} SET [value] = GREATEST([value], :existing_id) + 1', [], TRUE); $args = [':existing_id' => $existing_id]; try { $stmt->execute($args); } catch (\Exception $e) { $this->exceptionHandler()->handleExecutionException($e, $stmt, $args, []); } if ($stmt->rowCount() === 0) { $this->query('INSERT INTO {sequences} ([value]) VALUES (:existing_id + 1)', $args); } // The transaction gets committed when the transaction object gets destroyed // because it gets out of scope. return $this->query('SELECT value FROM {sequences}')->fetchField(); return $this->query('SELECT [value] FROM {sequences}')->fetchField(); } /** Loading