Update to Drupal 8.0.0 beta 14. For more information, see https://drupal.org/node/2544542

This commit is contained in:
Pantheon Automation 2015-08-27 12:03:05 -07:00 committed by Greg Anderson
parent 3b2511d96d
commit 81ccda77eb
2155 changed files with 54307 additions and 46870 deletions

View file

@ -24,7 +24,7 @@ abstract class Connection {
*
* We need this information for later auditing and logging.
*
* @var string
* @var string|null
*/
protected $target = NULL;
@ -35,14 +35,14 @@ abstract class Connection {
* connection can be a single server or a cluster of primary and replicas
* (use target to pick between primary and replica).
*
* @var string
* @var string|null
*/
protected $key = NULL;
/**
* The current database logging object for this connection.
*
* @var Log
* @var \Drupal\Core\Database\Log|null
*/
protected $logger = NULL;
@ -111,7 +111,9 @@ abstract class Connection {
/**
* The schema object for this connection.
*
* @var object
* Set to NULL when the schema is destroyed.
*
* @var \Drupal\Core\Database\Schema|null
*/
protected $schema = NULL;
@ -138,6 +140,14 @@ abstract class Connection {
/**
* Constructs a Connection object.
*
* @param \PDO $connection
* An object of the PDO class representing a database connection.
* @param array $connection_options
* An array of options for the connection. May include the following:
* - prefix
* - namespace
* - Other driver-specific options.
*/
public function __construct(\PDO $connection, array $connection_options) {
// Initialize and prepare the connection prefix.
@ -221,7 +231,7 @@ abstract class Connection {
* that behavior and simply return NULL on failure, set this option to
* FALSE.
*
* @return
* @return array
* An array of default query options.
*/
protected function defaultOptions() {
@ -241,7 +251,7 @@ abstract class Connection {
* is for requesting the connection information of this specific
* open connection object.
*
* @return
* @return array
* An array of the connection information. The exact list of
* properties is driver-dependent.
*/
@ -252,9 +262,9 @@ abstract class Connection {
/**
* Set the list of prefixes used by this database connection.
*
* @param $prefix
* The prefixes, in any of the multiple forms documented in
* default.settings.php.
* @param array|string $prefix
* Either a single prefix, or an array of prefixes, in any of the multiple
* forms documented in default.settings.php.
*/
protected function setPrefix($prefix) {
if (is_array($prefix)) {
@ -289,10 +299,10 @@ abstract class Connection {
* tables, allowing Drupal to coexist with other systems in the same database
* and/or schema if necessary.
*
* @param $sql
* @param string $sql
* A string containing a partial or entire SQL query.
*
* @return
* @return string
* The properly-prefixed string.
*/
public function prefixTables($sql) {
@ -304,6 +314,9 @@ abstract class Connection {
*
* This function is for when you want to know the prefix of a table. This
* is not used in prefixTables due to performance reasons.
*
* @param string $table
* (optional) The table to find the prefix for.
*/
public function tablePrefix($table = 'default') {
if (isset($this->prefixes[$table])) {
@ -355,9 +368,8 @@ abstract class Connection {
* signature. We therefore also ensure that this function is only ever
* called once.
*
* @param $target
* The target this connection is for. Set to NULL (default) to disable
* logging entirely.
* @param string $target
* (optional) The target this connection is for.
*/
public function setTarget($target = NULL) {
if (!isset($this->target)) {
@ -368,8 +380,8 @@ abstract class Connection {
/**
* Returns the target this connection is associated with.
*
* @return
* The target string of this connection.
* @return string|null
* The target string of this connection, or NULL if no target is set.
*/
public function getTarget() {
return $this->target;
@ -378,7 +390,7 @@ abstract class Connection {
/**
* Tells this connection object what its key is.
*
* @param $target
* @param string $key
* The key this connection is for.
*/
public function setKey($key) {
@ -390,8 +402,8 @@ abstract class Connection {
/**
* Returns the key this connection is associated with.
*
* @return
* The key of this connection.
* @return string|null
* The key of this connection, or NULL if no key is set.
*/
public function getKey() {
return $this->key;
@ -400,7 +412,7 @@ abstract class Connection {
/**
* Associates a logging object with this connection.
*
* @param $logger
* @param \Drupal\Core\Database\Log $logger
* The logging object we want to use.
*/
public function setLogger(Log $logger) {
@ -410,7 +422,7 @@ abstract class Connection {
/**
* Gets the current logging object for this connection.
*
* @return \Drupal\Core\Database\Log
* @return \Drupal\Core\Database\Log|null
* The current logging object for this connection. If there isn't one,
* NULL is returned.
*/
@ -424,12 +436,12 @@ abstract class Connection {
* This information is exposed to all database drivers, although it is only
* useful on some of them. This method is table prefix-aware.
*
* @param $table
* @param string $table
* The table name to use for the sequence.
* @param $field
* @param string $field
* The field name to use for the sequence.
*
* @return
* @return string
* A table prefix-parsed string for the sequence name.
*/
public function makeSequenceName($table, $field) {
@ -441,10 +453,10 @@ abstract class Connection {
*
* The comment string will be sanitized to avoid SQL injection attacks.
*
* @param $comments
* @param string[] $comments
* An array of query comment strings.
*
* @return
* @return string
* A sanitized comment string.
*/
public function makeComment($comments) {
@ -483,10 +495,10 @@ abstract class Connection {
* Unless the comment is sanitised first, the SQL server would drop the
* node table and ignore the rest of the SQL statement.
*
* @param $comment
* @param string $comment
* A query comment string.
*
* @return
* @return string
* A sanitized version of the query comment string.
*/
protected function filterComment($comment = '') {
@ -500,7 +512,7 @@ abstract class Connection {
* query. All queries executed by Drupal are executed as PDO prepared
* statements.
*
* @param $query
* @param string|\Drupal\Core\Database\StatementInterface $query
* The query to execute. In most cases this will be a string containing
* an SQL query with placeholders. An already-prepared instance of
* StatementInterface may also be passed in order to allow calling
@ -509,26 +521,36 @@ abstract class Connection {
* It is extremely rare that module code will need to pass a statement
* object to this method. It is used primarily for database drivers for
* databases that require special LOB field handling.
* @param $args
* @param array $args
* An array of arguments for the prepared statement. If the prepared
* statement uses ? placeholders, this array must be an indexed array.
* If it contains named placeholders, it must be an associative array.
* @param $options
* An associative array of options to control how the query is run. See
* the documentation for DatabaseConnection::defaultOptions() for details.
* @param array $options
* An associative array of options to control how the query is run. The
* given options will be merged with self::defaultOptions(). See the
* documentation for self::defaultOptions() for details.
* Typically, $options['return'] will be set by a default or by a query
* builder, and should not be set by a user.
*
* @return \Drupal\Core\Database\StatementInterface|int|null
* This method will return one of: the executed statement, the number of
* rows affected by the query (not the number matched), or the generated
* insert ID of the last query, depending on the value of
* $options['return']. Typically that value will be set by default or a
* query builder and should not be set by a user. If there is an error,
* this method will return NULL and may throw an exception if
* $options['throw_exception'] is TRUE.
* This method will return one of the following:
* - If either $options['return'] === self::RETURN_STATEMENT, or
* $options['return'] is not set (due to self::defaultOptions()),
* returns the executed statement.
* - If $options['return'] === self::RETURN_AFFECTED,
* returns the number of rows affected by the query
* (not the number matched).
* - If $options['return'] === self::RETURN_INSERT_ID,
* returns the generated insert ID of the last query.
* - If either $options['return'] === self::RETURN_NULL, or
* an exception occurs and $options['throw_exception'] evaluates to FALSE,
* returns NULL.
*
* @throws \Drupal\Core\Database\DatabaseExceptionWrapper
* @throws \Drupal\Core\Database\IntegrityConstraintViolationException
* @throws \InvalidArgumentException
*
* @see \Drupal\Core\Database\Connection::defaultOptions()
*/
public function query($query, array $args = array(), $options = array()) {
// Use default values if not already set.
@ -628,6 +650,13 @@ abstract class Connection {
*
* @return bool
* TRUE if the query was modified, FALSE otherwise.
*
* @throws \InvalidArgumentException
* This exception is thrown when:
* - A placeholder that ends in [] is supplied, and the supplied value is
* not an array.
* - A placeholder that does not end in [] is supplied, and the supplied
* value is an array.
*/
protected function expandArguments(&$query, &$args) {
$modified = FALSE;
@ -700,12 +729,12 @@ abstract class Connection {
/**
* Prepares and returns a SELECT query object.
*
* @param $table
* @param string $table
* The base table for this query, that is, the first table in the FROM
* clause. This table will also be used as the "base" table for query_alter
* hook implementations.
* @param $alias
* The alias of the base table of this query.
* @param string $alias
* (optional) The alias of the base table of this query.
* @param $options
* An array of options on the query.
*
@ -724,8 +753,10 @@ abstract class Connection {
/**
* Prepares and returns an INSERT query object.
*
* @param $options
* An array of options on the query.
* @param string $table
* The table to use for the insert statement.
* @param array $options
* (optional) An array of options on the query.
*
* @return \Drupal\Core\Database\Query\Insert
* A new Insert query object.
@ -740,8 +771,10 @@ abstract class Connection {
/**
* Prepares and returns a MERGE query object.
*
* @param $options
* An array of options on the query.
* @param string $table
* The table to use for the merge statement.
* @param array $options
* (optional) An array of options on the query.
*
* @return \Drupal\Core\Database\Query\Merge
* A new Merge query object.
@ -757,8 +790,10 @@ abstract class Connection {
/**
* Prepares and returns an UPDATE query object.
*
* @param $options
* An array of options on the query.
* @param string $table
* The table to use for the update statement.
* @param array $options
* (optional) An array of options on the query.
*
* @return \Drupal\Core\Database\Query\Update
* A new Update query object.
@ -773,8 +808,10 @@ abstract class Connection {
/**
* Prepares and returns a DELETE query object.
*
* @param $options
* An array of options on the query.
* @param string $table
* The table to use for the delete statement.
* @param array $options
* (optional) An array of options on the query.
*
* @return \Drupal\Core\Database\Query\Delete
* A new Delete query object.
@ -789,8 +826,10 @@ abstract class Connection {
/**
* Prepares and returns a TRUNCATE query object.
*
* @param $options
* An array of options on the query.
* @param string $table
* The table to use for the truncate statement.
* @param array $options
* (optional) An array of options on the query.
*
* @return \Drupal\Core\Database\Query\Truncate
* A new Truncate query object.
@ -825,8 +864,11 @@ abstract class Connection {
* For some database drivers, it may also wrap the database name in
* database-specific escape characters.
*
* @param string $database
* An unsanitized database name.
*
* @return string
* The sanitized database name string.
* The sanitized database name.
*/
public function escapeDatabase($database) {
return preg_replace('/[^A-Za-z0-9_.]+/', '', $database);
@ -839,8 +881,11 @@ abstract class Connection {
* For some database drivers, it may also wrap the table name in
* database-specific escape characters.
*
* @return
* The sanitized table name string.
* @param string $table
* An unsanitized table name.
*
* @return string
* The sanitized table name.
*/
public function escapeTable($table) {
return preg_replace('/[^A-Za-z0-9_.]+/', '', $table);
@ -853,8 +898,11 @@ abstract class Connection {
* For some database drivers, it may also wrap the field name in
* database-specific escape characters.
*
* @return
* The sanitized field name string.
* @param string $field
* An unsanitized field name.
*
* @return string
* The sanitized field name.
*/
public function escapeField($field) {
return preg_replace('/[^A-Za-z0-9_.]+/', '', $field);
@ -868,8 +916,11 @@ abstract class Connection {
* DatabaseConnection::escapeTable(), this doesn't allow the period (".")
* because that is not allowed in aliases.
*
* @return
* The sanitized field name string.
* @param string $field
* An unsanitized alias name.
*
* @return string
* The sanitized alias name.
*/
public function escapeAlias($field) {
return preg_replace('/[^A-Za-z0-9_]+/', '', $field);
@ -894,10 +945,10 @@ abstract class Connection {
* Backslash is defined as escape character for LIKE patterns in
* Drupal\Core\Database\Query\Condition::mapConditionOperator().
*
* @param $string
* @param string $string
* The string to escape.
*
* @return
* @return string
* The escaped string.
*/
public function escapeLike($string) {
@ -907,7 +958,7 @@ abstract class Connection {
/**
* Determines if there is an active transaction open.
*
* @return
* @return bool
* TRUE if we're currently in a transaction, FALSE otherwise.
*/
public function inTransaction() {
@ -915,7 +966,10 @@ abstract class Connection {
}
/**
* Determines current transaction depth.
* Determines the current transaction depth.
*
* @return int
* The current transaction depth.
*/
public function transactionDepth() {
return count($this->transactionLayers);
@ -924,8 +978,8 @@ abstract class Connection {
/**
* Returns a new DatabaseTransaction object on this connection.
*
* @param $name
* Optional name of the savepoint.
* @param string $name
* (optional) The name of the savepoint.
*
* @return \Drupal\Core\Database\Transaction
* A Transaction object.
@ -942,10 +996,11 @@ abstract class Connection {
*
* This method throws an exception if no transaction is active.
*
* @param $savepoint_name
* The name of the savepoint. The default, 'drupal_transaction', will roll
* the entire transaction back.
* @param string $savepoint_name
* (optional) The name of the savepoint. The default, 'drupal_transaction',
* will roll the entire transaction back.
*
* @throws \Drupal\Core\Database\TransactionOutOfOrderException
* @throws \Drupal\Core\Database\TransactionNoActiveException
*
* @see \Drupal\Core\Database\Transaction::rollback()
@ -997,6 +1052,9 @@ abstract class Connection {
*
* If no transaction is already active, we begin a new transaction.
*
* @param string $name
* The name of the transaction.
*
* @throws \Drupal\Core\Database\TransactionNameNonUniqueException
*
* @see \Drupal\Core\Database\Transaction
@ -1026,8 +1084,8 @@ abstract class Connection {
* back the transaction as necessary. If no transaction is active, we return
* because the transaction may have manually been rolled back.
*
* @param $name
* The name of the savepoint
* @param string $name
* The name of the savepoint.
*
* @throws \Drupal\Core\Database\TransactionNoActiveException
* @throws \Drupal\Core\Database\TransactionCommitFailedException
@ -1083,16 +1141,17 @@ abstract class Connection {
* separate parameters so that they can be properly escaped to avoid SQL
* injection attacks.
*
* @param $query
* @param string $query
* A string containing an SQL query.
* @param $args
* An array of values to substitute into the query at placeholder markers.
* @param $from
* @param int $from
* The first result row to return.
* @param $count
* @param int $count
* The maximum number of result rows to return.
* @param $options
* An array of options on the query.
* @param array $args
* (optional) An array of values to substitute into the query at placeholder
* markers.
* @param array $options
* (optional) An array of options on the query.
*
* @return \Drupal\Core\Database\StatementInterface
* A database query result resource, or NULL if the query was not executed
@ -1103,7 +1162,7 @@ abstract class Connection {
/**
* Generates a temporary table name.
*
* @return
* @return string
* A table name.
*/
protected function generateTemporaryTableName() {
@ -1122,15 +1181,17 @@ abstract class Connection {
* Note that if you need to know how many results were returned, you should do
* a SELECT COUNT(*) on the temporary table afterwards.
*
* @param $query
* @param string $query
* A string containing a normal SELECT SQL query.
* @param $args
* An array of values to substitute into the query at placeholder markers.
* @param $options
* An associative array of options to control how the query is run. See
* the documentation for DatabaseConnection::defaultOptions() for details.
* @param array $args
* (optional) An array of values to substitute into the query at placeholder
* markers.
* @param array $options
* (optional) An associative array of options to control how the query is
* run. See the documentation for DatabaseConnection::defaultOptions() for
* details.
*
* @return
* @return string
* The name of the temporary table.
*/
abstract function queryTemporary($query, array $args = array(), array $options = array());
@ -1142,6 +1203,9 @@ abstract class Connection {
* instance, there could be two MySQL drivers, mysql and mysql_mock. This
* function would return different values for each, but both would return
* "mysql" for databaseType().
*
* @return string
* The type of database driver.
*/
abstract public function driver();
@ -1155,7 +1219,7 @@ abstract class Connection {
/**
* Determines if this driver supports transactions.
*
* @return
* @return bool
* TRUE if this connection supports transactions, FALSE otherwise.
*/
public function supportsTransactions() {
@ -1167,7 +1231,7 @@ abstract class Connection {
*
* DDL queries are those that change the schema, such as ALTER queries.
*
* @return
* @return bool
* TRUE if this connection supports transactions for DDL queries, FALSE
* otherwise.
*/
@ -1199,7 +1263,7 @@ abstract class Connection {
* overridable lookup function. Database connections should define only
* those operators they wish to be handled differently than the default.
*
* @param $operator
* @param string $operator
* The condition operator, such as "IN", "BETWEEN", etc. Case-sensitive.
*
* @return
@ -1226,7 +1290,7 @@ abstract class Connection {
}
/**
* Retrieves an unique id from a given sequence.
* Retrieves an unique ID from a given sequence.
*
* Use this function if for some reason you can't use a serial field. For
* example, MySQL has no ways of reading of the current value of a sequence
@ -1234,9 +1298,9 @@ abstract class Connection {
* value. Or sometimes you just need a unique integer.
*
* @param $existing_id
* After a database import, it might be that the sequences table is behind,
* so by passing in the maximum existing id, it can be assured that we
* never issue the same id.
* (optional) After a database import, it might be that the sequences table
* is behind, so by passing in the maximum existing ID, it can be assured
* that we never issue the same ID.
*
* @return
* An integer number larger than any number returned by earlier calls and

View file

@ -14,6 +14,7 @@ use Drupal\Core\Database\DatabaseNotFoundException;
use Drupal\Core\Database\TransactionCommitFailedException;
use Drupal\Core\Database\DatabaseException;
use Drupal\Core\Database\Connection as DatabaseConnection;
use Drupal\Component\Utility\Unicode;
/**
* @addtogroup database
@ -34,6 +35,16 @@ class Connection extends DatabaseConnection {
*/
protected $needsCleanup = FALSE;
/**
* The minimal possible value for the max_allowed_packet setting of MySQL.
*
* @link https://mariadb.com/kb/en/mariadb/server-system-variables/#max_allowed_packet
* @link https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_max_allowed_packet
*
* @var int
*/
const MIN_MAX_ALLOWED_PACKET = 1024;
/**
* Constructs a Connection object.
*/
@ -49,6 +60,24 @@ class Connection extends DatabaseConnection {
$this->connectionOptions = $connection_options;
}
/**
* {@inheritdoc}
*/
public function query($query, array $args = array(), $options = array()) {
try {
return parent::query($query, $args, $options);
} catch (DatabaseException $e) {
if ($e->getPrevious()->errorInfo[1] == 1153) {
// If a max_allowed_packet error occurs the message length is truncated.
// This should prevent the error from recurring if the exception is
// logged to the database using dblog or the like.
$message = Unicode::truncateBytes($e->getMessage(), self::MIN_MAX_ALLOWED_PACKET);
$e = new DatabaseExceptionWrapper($message, $e->getCode(), $e->getPrevious());
}
throw $e;
}
}
/**
* {@inheritdoc}
*/
@ -278,6 +307,7 @@ class Connection extends DatabaseConnection {
}
}
}
}

View file

@ -31,6 +31,27 @@ class Connection extends DatabaseConnection {
*/
const DATABASE_NOT_FOUND = 7;
/**
* The list of PostgreSQL reserved key words.
*
* @see http://www.postgresql.org/docs/9.4/static/sql-keywords-appendix.html
*/
protected $postgresqlReservedKeyWords = ['all', 'analyse', 'analyze', 'and',
'any', 'array', 'as', 'asc', 'asymmetric', 'authorization', 'binary', 'both',
'case', 'cast', 'check', 'collate', 'collation', 'column', 'concurrently',
'constraint', 'create', 'cross', 'current_catalog', 'current_date',
'current_role', 'current_schema', 'current_time', 'current_timestamp',
'current_user', 'default', 'deferrable', 'desc', 'distinct', 'do', 'else',
'end', 'except', 'false', 'fetch', 'for', 'foreign', 'freeze', 'from', 'full',
'grant', 'group', 'having', 'ilike', 'in', 'initially', 'inner', 'intersect',
'into', 'is', 'isnull', 'join', 'lateral', 'leading', 'left', 'like', 'limit',
'localtime', 'localtimestamp', 'natural', 'not', 'notnull', 'null', 'offset',
'on', 'only', 'or', 'order', 'outer', 'over', 'overlaps', 'placing',
'primary', 'references', 'returning', 'right', 'select', 'session_user',
'similar', 'some', 'symmetric', 'table', 'then', 'to', 'trailing', 'true',
'union', 'unique', 'user', 'using', 'variadic', 'verbose', 'when', 'where',
'window', 'with'];
/**
* Constructs a connection object.
*/
@ -167,6 +188,10 @@ class Connection extends DatabaseConnection {
// Quote the field name for case-sensitivity.
$escaped = '"' . $escaped . '"';
}
elseif (in_array(strtolower($escaped), $this->postgresqlReservedKeyWords)) {
// Quote the field name for PostgreSQL reserved key words.
$escaped = '"' . $escaped . '"';
}
return $escaped;
}
@ -181,6 +206,10 @@ class Connection extends DatabaseConnection {
if (preg_match('/[A-Z]/', $escaped)) {
$escaped = '"' . $escaped . '"';
}
elseif (in_array(strtolower($escaped), $this->postgresqlReservedKeyWords)) {
// Quote the alias name for PostgreSQL reserved key words.
$escaped = '"' . $escaped . '"';
}
return $escaped;
}
@ -195,6 +224,10 @@ class Connection extends DatabaseConnection {
if (preg_match('/[A-Z]/', $escaped)) {
$escaped = '"' . $escaped . '"';
}
elseif (in_array(strtolower($escaped), $this->postgresqlReservedKeyWords)) {
// Quote the table name for PostgreSQL reserved key words.
$escaped = '"' . $escaped . '"';
}
return $escaped;
}

View file

@ -117,6 +117,8 @@ class Insert extends QueryInsert {
// Default fields are always placed first for consistency.
$insert_fields = array_merge($this->defaultFields, $this->insertFields);
$insert_fields = array_map(function($f) { return $this->connection->escapeField($f); }, $insert_fields);
// If we're selecting from a SelectQuery, finish building the query and
// pass it back, as any remaining options are irrelevant.
if (!empty($this->fromQuery)) {
@ -154,4 +156,5 @@ class Insert extends QueryInsert {
return $query;
}
}

View file

@ -51,7 +51,7 @@ class Tasks extends InstallTasks {
* {@inheritdoc}
*/
public function minimumVersion() {
return '8.3';
return '9.1.2';
}
/**

View file

@ -329,7 +329,7 @@ class Schema extends DatabaseSchema {
}
if (!empty($field['unsigned'])) {
// Unsigned datatypes are not supported in PostgreSQL 8.3. In MySQL,
// Unsigned datatypes are not supported in PostgreSQL 9.1. In MySQL,
// they are used to ensure a positive number is inserted and it also
// doubles the maximum integer size that can be stored in a field.
// The PostgreSQL schema in Drupal creates a check constraint
@ -569,7 +569,7 @@ class Schema extends DatabaseSchema {
}
public function indexExists($table, $name) {
// Details http://www.postgresql.org/docs/8.3/interactive/view-pg-indexes.html
// Details http://www.postgresql.org/docs/9.1/interactive/view-pg-indexes.html
$index_name = $this->ensureIdentifiersLength($table, $name, 'idx');
// Remove leading and trailing quotes because the index name is in a WHERE
// clause and not used as an identifier.

View file

@ -22,7 +22,7 @@ use Drupal\Core\Database\StatementInterface;
class Statement extends StatementPrefetch implements StatementInterface {
/**
* SQLite specific implementation of getStatement().
* {@inheritdoc}
*
* The PDO SQLite layer doesn't replace numeric placeholders in queries
* correctly, and this makes numeric expressions (such as COUNT(*) >= :count)
@ -87,6 +87,9 @@ class Statement extends StatementPrefetch implements StatementInterface {
return $this->pdoConnection->prepare($query);
}
/**
* {@inheritdoc}
*/
public function execute($args = array(), $options = array()) {
try {
$return = parent::execute($args, $options);

View file

@ -17,6 +17,8 @@ use Drupal\Core\Database\Connection;
*/
class Delete extends Query implements ConditionInterface {
use QueryConditionTrait;
/**
* The table from which to delete.
*
@ -24,15 +26,6 @@ class Delete extends Query implements ConditionInterface {
*/
protected $table;
/**
* The condition object for this query.
*
* Condition handling is handled via composition.
*
* @var Condition
*/
protected $condition;
/**
* Constructs a Delete object.
*
@ -51,82 +44,6 @@ class Delete extends Query implements ConditionInterface {
$this->condition = new Condition('AND');
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::condition().
*/
public function condition($field, $value = NULL, $operator = '=') {
$this->condition->condition($field, $value, $operator);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::isNull().
*/
public function isNull($field) {
$this->condition->isNull($field);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::isNotNull().
*/
public function isNotNull($field) {
$this->condition->isNotNull($field);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::exists().
*/
public function exists(SelectInterface $select) {
$this->condition->exists($select);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::notExists().
*/
public function notExists(SelectInterface $select) {
$this->condition->notExists($select);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::conditions().
*/
public function &conditions() {
return $this->condition->conditions();
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::arguments().
*/
public function arguments() {
return $this->condition->arguments();
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::where().
*/
public function where($snippet, $args = array()) {
$this->condition->where($snippet, $args);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::compile().
*/
public function compile(Connection $connection, PlaceholderInterface $queryPlaceholder) {
return $this->condition->compile($connection, $queryPlaceholder);
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::compiled().
*/
public function compiled() {
return $this->condition->compiled();
}
/**
* Executes the DELETE query.
*

View file

@ -49,6 +49,9 @@ use Drupal\Core\Database\IntegrityConstraintViolationException;
* fields() and updateFields().
*/
class Merge extends Query implements ConditionInterface {
use QueryConditionTrait;
/**
* Returned by execute() if an INSERT query has been executed.
*/
@ -339,82 +342,6 @@ class Merge extends Query implements ConditionInterface {
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::condition().
*/
public function condition($field, $value = NULL, $operator = '=') {
$this->condition->condition($field, $value, $operator);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::isNull().
*/
public function isNull($field) {
$this->condition->isNull($field);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::isNotNull().
*/
public function isNotNull($field) {
$this->condition->isNotNull($field);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::exists().
*/
public function exists(SelectInterface $select) {
$this->condition->exists($select);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::notExists().
*/
public function notExists(SelectInterface $select) {
$this->condition->notExists($select);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::conditions().
*/
public function &conditions() {
return $this->condition->conditions();
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::arguments().
*/
public function arguments() {
return $this->condition->arguments();
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::where().
*/
public function where($snippet, $args = array()) {
$this->condition->where($snippet, $args);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::compile().
*/
public function compile(Connection $connection, PlaceholderInterface $queryPlaceholder) {
return $this->condition->compile($connection, $queryPlaceholder);
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::compiled().
*/
public function compiled() {
return $this->condition->compiled();
}
/**
* Implements PHP magic __toString method to convert the query to a string.
*

View file

@ -180,25 +180,4 @@ abstract class Query implements PlaceholderInterface {
return $this->comments;
}
/**
* {@inheritdoc}
*/
public function conditionGroupFactory($conjunction = 'AND') {
return new Condition($conjunction);
}
/**
* {@inheritdoc}
*/
public function andConditionGroup() {
return $this->conditionGroupFactory('AND');
}
/**
* {@inheritdoc}
*/
public function orConditionGroup() {
return $this->conditionGroupFactory('OR');
}
}

View file

@ -0,0 +1,125 @@
<?php
/**
* @file
* Contains \Drupal\Core\Database\Query\QueryConditionTrait.
*/
namespace Drupal\Core\Database\Query;
use Drupal\Core\Database\Connection;
/**
* Provides an implementation of ConditionInterface.
*
* @see \Drupal\Core\Database\Query\ConditionInterface
*/
trait QueryConditionTrait {
/**
* The condition object for this query.
*
* Condition handling is handled via composition.
*
* @var \Drupal\Core\Database\Query\Condition
*/
protected $condition;
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::condition().
*/
public function condition($field, $value = NULL, $operator = '=') {
$this->condition->condition($field, $value, $operator);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::isNull().
*/
public function isNull($field) {
$this->condition->isNull($field);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::isNotNull().
*/
public function isNotNull($field) {
$this->condition->isNotNull($field);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::exists().
*/
public function exists(SelectInterface $select) {
$this->condition->exists($select);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::notExists().
*/
public function notExists(SelectInterface $select) {
$this->condition->notExists($select);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::conditions().
*/
public function &conditions() {
return $this->condition->conditions();
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::arguments().
*/
public function arguments() {
return $this->condition->arguments();
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::where().
*/
public function where($snippet, $args = array()) {
$this->condition->where($snippet, $args);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::compile().
*/
public function compile(Connection $connection, PlaceholderInterface $queryPlaceholder) {
$this->condition->compile($connection, $queryPlaceholder);
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::compiled().
*/
public function compiled() {
return $this->condition->compiled();
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::conditionGroupFactory().
*/
public function conditionGroupFactory($conjunction = 'AND') {
return new Condition($conjunction);
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::andConditionGroup().
*/
public function andConditionGroup() {
return $this->conditionGroupFactory('AND');
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::orConditionGroup().
*/
public function orConditionGroup() {
return $this->conditionGroupFactory('OR');
}
}

View file

@ -18,6 +18,8 @@ use Drupal\Core\Database\Connection;
*/
class Select extends Query implements SelectInterface {
use QueryConditionTrait;
/**
* The fields to SELECT.
*
@ -71,13 +73,6 @@ class Select extends Query implements SelectInterface {
*/
protected $group = array();
/**
* The conditional object for the WHERE clause.
*
* @var \Drupal\Core\Database\Query\Condition
*/
protected $where;
/**
* The conditional object for the HAVING clause.
*
@ -139,7 +134,7 @@ class Select extends Query implements SelectInterface {
$options['return'] = Database::RETURN_STATEMENT;
parent::__construct($connection, $options);
$conjunction = isset($options['conjunction']) ? $options['conjunction'] : 'AND';
$this->where = new Condition($conjunction);
$this->condition = new Condition($conjunction);
$this->having = new Condition($conjunction);
$this->addJoin(NULL, $table, $alias);
}
@ -188,21 +183,6 @@ class Select extends Query implements SelectInterface {
return isset($this->alterMetaData[$key]) ? $this->alterMetaData[$key] : NULL;
}
/**
* {@inheritdoc}
*/
public function condition($field, $value = NULL, $operator = '=') {
$this->where->condition($field, $value, $operator);
return $this;
}
/**
* {@inheritdoc}
*/
public function &conditions() {
return $this->where->conditions();
}
/**
* {@inheritdoc}
*/
@ -211,7 +191,7 @@ class Select extends Query implements SelectInterface {
return NULL;
}
$args = $this->where->arguments() + $this->having->arguments();
$args = $this->condition->arguments() + $this->having->arguments();
foreach ($this->tables as $table) {
if ($table['arguments']) {
@ -238,51 +218,11 @@ class Select extends Query implements SelectInterface {
return $args;
}
/**
* {@inheritdoc}
*/
public function where($snippet, $args = array()) {
$this->where->where($snippet, $args);
return $this;
}
/**
* {@inheritdoc}
*/
public function isNull($field) {
$this->where->isNull($field);
return $this;
}
/**
* {@inheritdoc}
*/
public function isNotNull($field) {
$this->where->isNotNull($field);
return $this;
}
/**
* {@inheritdoc}
*/
public function exists(SelectInterface $select) {
$this->where->exists($select);
return $this;
}
/**
* {@inheritdoc}
*/
public function notExists(SelectInterface $select) {
$this->where->notExists($select);
return $this;
}
/**
* {@inheritdoc}
*/
public function compile(Connection $connection, PlaceholderInterface $queryPlaceholder) {
$this->where->compile($connection, $queryPlaceholder);
$this->condition->compile($connection, $queryPlaceholder);
$this->having->compile($connection, $queryPlaceholder);
foreach ($this->tables as $table) {
@ -302,7 +242,7 @@ class Select extends Query implements SelectInterface {
* {@inheritdoc}
*/
public function compiled() {
if (!$this->where->compiled() || !$this->having->compiled()) {
if (!$this->condition->compiled() || !$this->having->compiled()) {
return FALSE;
}
@ -463,6 +403,13 @@ class Select extends Query implements SelectInterface {
return $this->connection->escapeLike($string);
}
/**
* {@inheritdoc}
*/
public function escapeField($string) {
return $this->connection->escapeField($string);
}
/**
* {@inheritdoc}
*/
@ -885,9 +832,9 @@ class Select extends Query implements SelectInterface {
}
// WHERE
if (count($this->where)) {
if (count($this->condition)) {
// There is an implicit string cast on $this->condition.
$query .= "\nWHERE " . $this->where;
$query .= "\nWHERE " . $this->condition;
}
// GROUP BY
@ -943,7 +890,7 @@ class Select extends Query implements SelectInterface {
// want to clone the database connection object as that would duplicate the
// connection itself.
$this->where = clone($this->where);
$this->condition = clone($this->condition);
$this->having = clone($this->having);
foreach ($this->union as $key => $aggregate) {
$this->union[$key]['query'] = clone($aggregate['query']);

View file

@ -210,6 +210,14 @@ class SelectExtender implements SelectInterface {
return $this->query->escapeLike($string);
}
/**
* {@inheritdoc}
*/
public function escapeField($string) {
$this->query->escapeField($string);
return $this;
}
public function getArguments(PlaceholderInterface $queryPlaceholder = NULL) {
return $this->query->getArguments($queryPlaceholder);
}

View file

@ -140,6 +140,18 @@ interface SelectInterface extends ConditionInterface, AlterableInterface, Extend
*/
public function escapeLike($string);
/**
* Escapes a field name string.
*
* Force all field names to be strictly alphanumeric-plus-underscore.
* For some database drivers, it may also wrap the field name in
* database-specific escape characters.
*
* @return
* The sanitized field name string.
*/
public function escapeField($string);
/**
* Compiles and returns an associative array of the arguments for this prepared statement.
*
@ -632,4 +644,5 @@ interface SelectInterface extends ConditionInterface, AlterableInterface, Extend
* The called object.
*/
public function forUpdate($set = TRUE);
}

View file

@ -17,6 +17,8 @@ use Drupal\Core\Database\Connection;
*/
class Update extends Query implements ConditionInterface {
use QueryConditionTrait;
/**
* The table to update.
*
@ -38,15 +40,6 @@ class Update extends Query implements ConditionInterface {
*/
protected $arguments = array();
/**
* The condition object for this query.
*
* Condition handling is handled via composition.
*
* @var \Drupal\Core\Database\Query\Condition
*/
protected $condition;
/**
* Array of fields to update to an expression in case of a duplicate record.
*
@ -80,82 +73,6 @@ class Update extends Query implements ConditionInterface {
$this->condition = new Condition('AND');
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::condition().
*/
public function condition($field, $value = NULL, $operator = '=') {
$this->condition->condition($field, $value, $operator);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::isNull().
*/
public function isNull($field) {
$this->condition->isNull($field);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::isNotNull().
*/
public function isNotNull($field) {
$this->condition->isNotNull($field);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::exists().
*/
public function exists(SelectInterface $select) {
$this->condition->exists($select);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::notExists().
*/
public function notExists(SelectInterface $select) {
$this->condition->notExists($select);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::conditions().
*/
public function &conditions() {
return $this->condition->conditions();
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::arguments().
*/
public function arguments() {
return $this->condition->arguments();
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::where().
*/
public function where($snippet, $args = array()) {
$this->condition->where($snippet, $args);
return $this;
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::compile().
*/
public function compile(Connection $connection, PlaceholderInterface $queryPlaceholder) {
return $this->condition->compile($connection, $queryPlaceholder);
}
/**
* Implements Drupal\Core\Database\Query\ConditionInterface::compiled().
*/
public function compiled() {
return $this->condition->compiled();
}
/**
* Adds a set of field->value pairs to be updated.
*
@ -256,13 +173,13 @@ class Update extends Query implements ConditionInterface {
$data['expression']->compile($this->connection, $this);
$data['expression'] = ' (' . $data['expression'] . ')';
}
$update_fields[] = $field . '=' . $data['expression'];
$update_fields[] = $this->connection->escapeField($field) . '=' . $data['expression'];
unset($fields[$field]);
}
$max_placeholder = 0;
foreach ($fields as $field => $value) {
$update_fields[] = $field . '=:db_update_placeholder_' . ($max_placeholder++);
$update_fields[] = $this->connection->escapeField($field) . '=:db_update_placeholder_' . ($max_placeholder++);
}
$query = $comments . 'UPDATE {' . $this->connection->escapeTable($this->table) . '} SET ' . implode(', ', $update_fields);

View file

@ -41,6 +41,9 @@ class Statement extends \PDOStatement implements StatementInterface {
$this->setFetchMode(\PDO::FETCH_OBJ);
}
/**
* {@inheritdoc}
*/
public function execute($args = array(), $options = array()) {
if (isset($options['fetch'])) {
if (is_string($options['fetch'])) {
@ -68,14 +71,23 @@ class Statement extends \PDOStatement implements StatementInterface {
return $return;
}
/**
* {@inheritdoc}
*/
public function getQueryString() {
return $this->queryString;
}
/**
* {@inheritdoc}
*/
public function fetchCol($index = 0) {
return $this->fetchAll(\PDO::FETCH_COLUMN, $index);
}
/**
* {@inheritdoc}
*/
public function fetchAllAssoc($key, $fetch = NULL) {
$return = array();
if (isset($fetch)) {
@ -95,6 +107,9 @@ class Statement extends \PDOStatement implements StatementInterface {
return $return;
}
/**
* {@inheritdoc}
*/
public function fetchAllKeyed($key_index = 0, $value_index = 1) {
$return = array();
$this->setFetchMode(\PDO::FETCH_NUM);
@ -104,11 +119,17 @@ class Statement extends \PDOStatement implements StatementInterface {
return $return;
}
/**
* {@inheritdoc}
*/
public function fetchField($index = 0) {
// Call \PDOStatement::fetchColumn to fetch the field.
return $this->fetchColumn($index);
}
/**
* {@inheritdoc}
*/
public function fetchAssoc() {
// Call \PDOStatement::fetch to fetch the row.
return $this->fetch(\PDO::FETCH_ASSOC);
@ -127,4 +148,42 @@ class Statement extends \PDOStatement implements StatementInterface {
}
}
/**
* {@inheritdoc}
*/
public function setFetchMode($mode, $a1 = NULL, $a2 = array()) {
// Call \PDOStatement::setFetchMode to set fetch mode.
// \PDOStatement is picky about the number of arguments in some cases so we
// need to be pass the exact number of arguments we where given.
switch (func_num_args()) {
case 1:
return parent::setFetchMode($mode);
case 2:
return parent::setFetchMode($mode, $a1);
case 3:
default:
return parent::setFetchMode($mode, $a1, $a2);
}
}
/**
* {@inheritdoc}
*/
public function fetchAll($mode = NULL, $column_index = NULL, $constructor_arguments = NULL) {
// Call \PDOStatement::fetchAll to fetch all rows.
// \PDOStatement is picky about the number of arguments in some cases so we
// need to be pass the exact number of arguments we where given.
switch (func_num_args()) {
case 0:
return parent::fetchAll();
case 1:
return parent::fetchAll($mode);
case 2:
return parent::fetchAll($mode, $column_index);
case 3:
default:
return parent::fetchAll($mode, $column_index, $constructor_arguments);
}
}
}

View file

@ -28,14 +28,23 @@ class StatementEmpty implements \Iterator, StatementInterface {
*/
public $allowRowCount = FALSE;
/**
* {@inheritdoc}
*/
public function execute($args = array(), $options = array()) {
return FALSE;
}
/**
* {@inheritdoc}
*/
public function getQueryString() {
return '';
}
/**
* {@inheritdoc}
*/
public function rowCount() {
if ($this->allowRowCount) {
return 0;
@ -43,61 +52,102 @@ class StatementEmpty implements \Iterator, StatementInterface {
throw new RowCountException();
}
/**
* {@inheritdoc}
*/
public function setFetchMode($mode, $a1 = NULL, $a2 = array()) {
return;
}
/**
* {@inheritdoc}
*/
public function fetch($mode = NULL, $cursor_orientation = NULL, $cursor_offset = NULL) {
return NULL;
}
/**
* {@inheritdoc}
*/
public function fetchField($index = 0) {
return NULL;
}
/**
* {@inheritdoc}
*/
public function fetchObject() {
return NULL;
}
/**
* {@inheritdoc}
*/
public function fetchAssoc() {
return NULL;
}
function fetchAll($mode = NULL, $column_index = NULL, array $constructor_arguments = array()) {
/**
* {@inheritdoc}
*/
public function fetchAll($mode = NULL, $column_index = NULL, $constructor_arguments = NULL) {
return array();
}
/**
* {@inheritdoc}
*/
public function fetchCol($index = 0) {
return array();
}
/**
* {@inheritdoc}
*/
public function fetchAllKeyed($key_index = 0, $value_index = 1) {
return array();
}
/**
* {@inheritdoc}
*/
public function fetchAllAssoc($key, $fetch = NULL) {
return array();
}
/* Implementations of Iterator. */
/**
* {@inheritdoc}
*/
public function current() {
return NULL;
}
/**
* {@inheritdoc}
*/
public function key() {
return NULL;
}
/**
* {@inheritdoc}
*/
public function rewind() {
// Nothing to do: our DatabaseStatement can't be rewound.
}
/**
* {@inheritdoc}
*/
public function next() {
// Do nothing, since this is an always-empty implementation.
}
/**
* {@inheritdoc}
*/
public function valid() {
return FALSE;
}
}

View file

@ -10,11 +10,6 @@ namespace Drupal\Core\Database;
/**
* Represents a prepared statement.
*
* Some methods in that class are purposefully commented out. Due to a change in
* how PHP defines PDOStatement, we can't define a signature for those methods
* that will work the same way between versions older than 5.2.6 and later
* versions. See http://bugs.php.net/bug.php?id=42452 for more details.
*
* Child implementations should either extend PDOStatement:
* @code
* class Drupal\Core\Database\Driver\oracle\Statement extends PDOStatement implements Drupal\Core\Database\StatementInterface {}
@ -100,7 +95,7 @@ interface StatementInterface extends \Traversable {
* If $mode is PDO::FETCH_CLASS, the optional arguments to pass to the
* constructor.
*/
// public function setFetchMode($mode, $a1 = NULL, $a2 = array());
public function setFetchMode($mode, $a1 = NULL, $a2 = array());
/**
* Fetches the next row from a result set.
@ -119,7 +114,7 @@ interface StatementInterface extends \Traversable {
* @return
* A result, formatted according to $mode.
*/
// public function fetch($mode = NULL, $cursor_orientation = NULL, $cursor_offset = NULL);
public function fetch($mode = NULL, $cursor_orientation = NULL, $cursor_offset = NULL);
/**
* Returns a single field from the next record of a result set.
@ -138,7 +133,7 @@ interface StatementInterface extends \Traversable {
* The object will be of the class specified by StatementInterface::setFetchMode()
* or stdClass if not specified.
*/
// public function fetchObject();
public function fetchObject();
/**
* Fetches the next row and returns it as an associative array.
@ -165,7 +160,7 @@ interface StatementInterface extends \Traversable {
* @return
* An array of results.
*/
// function fetchAll($mode = NULL, $column_index = NULL, array $constructor_arguments);
function fetchAll($mode = NULL, $column_index = NULL, $constructor_arguments = NULL);
/**
* Returns an entire single column of a result set as an indexed array.

View file

@ -139,14 +139,7 @@ class StatementPrefetch implements \Iterator, StatementInterface {
}
/**
* Executes a prepared statement.
*
* @param $args
* An array of values with as many elements as there are bound parameters in the SQL statement being executed.
* @param $options
* An array of options for this query.
* @return
* TRUE on success, or FALSE on failure.
* {@inheritdoc}
*/
public function execute($args = array(), $options = array()) {
if (isset($options['fetch'])) {
@ -236,29 +229,29 @@ class StatementPrefetch implements \Iterator, StatementInterface {
}
/**
* Return the object's SQL query string.
* {@inheritdoc}
*/
public function getQueryString() {
return $this->queryString;
}
/**
* @see \PDOStatement::setFetchMode()
* {@inheritdoc}
*/
public function setFetchMode($fetchStyle, $a2 = NULL, $a3 = NULL) {
$this->defaultFetchStyle = $fetchStyle;
switch ($fetchStyle) {
public function setFetchMode($mode, $a1 = NULL, $a2 = array()) {
$this->defaultFetchStyle = $mode;
switch ($mode) {
case \PDO::FETCH_CLASS:
$this->defaultFetchOptions['class'] = $a2;
if ($a3) {
$this->defaultFetchOptions['constructor_args'] = $a3;
$this->defaultFetchOptions['class'] = $a1;
if ($a2) {
$this->defaultFetchOptions['constructor_args'] = $a2;
}
break;
case \PDO::FETCH_COLUMN:
$this->defaultFetchOptions['column'] = $a2;
$this->defaultFetchOptions['column'] = $a1;
break;
case \PDO::FETCH_INTO:
$this->defaultFetchOptions['object'] = $a2;
$this->defaultFetchOptions['object'] = $a1;
break;
}
@ -274,8 +267,8 @@ class StatementPrefetch implements \Iterator, StatementInterface {
* array position in $this->data and format it according to $this->fetchStyle
* and $this->fetchMode.
*
* @return
* The current row formatted as requested.
* @return mixed
* The current row formatted as requested.
*/
public function current() {
if (isset($this->currentRow)) {
@ -327,16 +320,23 @@ class StatementPrefetch implements \Iterator, StatementInterface {
}
}
/* Implementations of Iterator. */
/**
* {@inheritdoc}
*/
public function key() {
return $this->currentKey;
}
/**
* {@inheritdoc}
*/
public function rewind() {
// Nothing to do: our DatabaseStatement can't be rewound.
}
/**
* {@inheritdoc}
*/
public function next() {
if (!empty($this->data)) {
$this->currentRow = reset($this->data);
@ -348,6 +348,9 @@ class StatementPrefetch implements \Iterator, StatementInterface {
}
}
/**
* {@inheritdoc}
*/
public function valid() {
return isset($this->currentRow);
}
@ -365,6 +368,9 @@ class StatementPrefetch implements \Iterator, StatementInterface {
}
}
/**
* {@inheritdoc}
*/
public function fetch($fetch_style = NULL, $cursor_orientation = \PDO::FETCH_ORI_NEXT, $cursor_offset = NULL) {
if (isset($this->currentRow)) {
// Set the fetch parameter.
@ -398,10 +404,16 @@ class StatementPrefetch implements \Iterator, StatementInterface {
}
}
/**
* {@inheritdoc}
*/
public function fetchField($index = 0) {
return $this->fetchColumn($index);
}
/**
* {@inheritdoc}
*/
public function fetchObject($class_name = NULL, $constructor_args = array()) {
if (isset($this->currentRow)) {
if (!isset($class_name)) {
@ -427,6 +439,9 @@ class StatementPrefetch implements \Iterator, StatementInterface {
}
}
/**
* {@inheritdoc}
*/
public function fetchAssoc() {
if (isset($this->currentRow)) {
$result = $this->currentRow;
@ -438,14 +453,17 @@ class StatementPrefetch implements \Iterator, StatementInterface {
}
}
public function fetchAll($fetch_style = NULL, $fetch_column = NULL, $constructor_args = NULL) {
$this->fetchStyle = isset($fetch_style) ? $fetch_style : $this->defaultFetchStyle;
/**
* {@inheritdoc}
*/
public function fetchAll($mode = NULL, $column_index = NULL, $constructor_arguments = NULL) {
$this->fetchStyle = isset($mode) ? $mode : $this->defaultFetchStyle;
$this->fetchOptions = $this->defaultFetchOptions;
if (isset($fetch_column)) {
$this->fetchOptions['column'] = $fetch_column;
if (isset($column_index)) {
$this->fetchOptions['column'] = $column_index;
}
if (isset($constructor_args)) {
$this->fetchOptions['constructor_args'] = $constructor_args;
if (isset($constructor_arguments)) {
$this->fetchOptions['constructor_args'] = $constructor_arguments;
}
$result = array();
@ -462,6 +480,9 @@ class StatementPrefetch implements \Iterator, StatementInterface {
return $result;
}
/**
* {@inheritdoc}
*/
public function fetchCol($index = 0) {
if (isset($this->columnNames[$index])) {
$result = array();
@ -477,6 +498,9 @@ class StatementPrefetch implements \Iterator, StatementInterface {
}
}
/**
* {@inheritdoc}
*/
public function fetchAllKeyed($key_index = 0, $value_index = 1) {
if (!isset($this->columnNames[$key_index]) || !isset($this->columnNames[$value_index]))
return array();
@ -493,6 +517,9 @@ class StatementPrefetch implements \Iterator, StatementInterface {
return $result;
}
/**
* {@inheritdoc}
*/
public function fetchAllAssoc($key, $fetch_style = NULL) {
$this->fetchStyle = isset($fetch_style) ? $fetch_style : $this->defaultFetchStyle;
$this->fetchOptions = $this->defaultFetchOptions;

View file

@ -307,7 +307,8 @@
* specification). Each specification is an array containing the name of
* the referenced table ('table'), and an array of column mappings
* ('columns'). Column mappings are defined by key pairs ('source_column' =>
* 'referenced_column').
* 'referenced_column'). This key is for documentation purposes only; foreign
* keys are not created in the database, nor are they enforced by Drupal.
* - 'indexes': An associative array of indexes ('indexname' =>
* specification). Each specification is an array of one or more
* key column specifiers (see below) that form an index on the
@ -357,6 +358,8 @@
* 'unique keys' => array(
* 'vid' => array('vid'),
* ),
* // For documentation purposes only; foreign keys are not created in the
* // database.
* 'foreign keys' => array(
* 'node_revision' => array(
* 'table' => 'node_field_revision',
@ -467,7 +470,9 @@ function hook_query_TAG_alter(Drupal\Core\Database\Query\AlterableInterface $que
* creation and alteration of the supported database engines.
*
* See the Schema API Handbook at https://www.drupal.org/node/146843 for details
* on schema definition structures.
* on schema definition structures. Note that foreign key definitions are for
* documentation purposes only; foreign keys are not created in the database,
* nor are they enforced by Drupal.
*
* @return array
* A schema definition structure array. For each element of the
@ -517,6 +522,8 @@ function hook_schema() {
'nid_vid' => array('nid', 'vid'),
'vid' => array('vid'),
),
// For documentation purposes only; foreign keys are not created in the
// database.
'foreign keys' => array(
'node_revision' => array(
'table' => 'node_field_revision',