Commit 1627fdf7 authored by Crell's avatar Crell
Browse files

Revert "Remove empty files from old database structure."

This reverts commit d3cf8901.
parent a731ac1d
<?php
use Drupal\Core\Database\Database;
use Drupal\Core\Database\Query\Condition;
/**
* @file
* Core systems for the database layer.
*
* Classes required for basic functioning of the database system should be
* placed in this file. All utility functions should also be placed in this
* file only, as they cannot auto-load the way classes can.
*/
/**
* @defgroup database Database abstraction layer
* @{
* Allow the use of different database servers using the same code base.
*
* Drupal provides a database abstraction layer to provide developers with
* the ability to support multiple database servers easily. The intent of
* this layer is to preserve the syntax and power of SQL as much as possible,
* but also allow developers a way to leverage more complex functionality in
* a unified way. It also provides a structured interface for dynamically
* constructing queries when appropriate, and enforcing security checks and
* similar good practices.
*
* The system is built atop PHP's PDO (PHP Data Objects) database API and
* inherits much of its syntax and semantics.
*
* Most Drupal database SELECT queries are performed by a call to db_query() or
* db_query_range(). Module authors should also consider using the PagerDefault
* Extender for queries that return results that need to be presented on
* multiple pages, and the Tablesort Extender for generating appropriate queries
* for sortable tables.
*
* For example, one might wish to return a list of the most recent 10 nodes
* authored by a given user. Instead of directly issuing the SQL query
* @code
* SELECT n.nid, n.title, n.created FROM node n WHERE n.uid = $uid LIMIT 0, 10;
* @endcode
* one would instead call the Drupal functions:
* @code
* $result = db_query_range('SELECT n.nid, n.title, n.created
* FROM {node} n WHERE n.uid = :uid', 0, 10, array(':uid' => $uid));
* foreach ($result as $record) {
* // Perform operations on $node->title, etc. here.
* }
* @endcode
* Curly braces are used around "node" to provide table prefixing via
* DatabaseConnection::prefixTables(). The explicit use of a user ID is pulled
* out into an argument passed to db_query() so that SQL injection attacks
* from user input can be caught and nullified. The LIMIT syntax varies between
* database servers, so that is abstracted into db_query_range() arguments.
* Finally, note the PDO-based ability to iterate over the result set using
* foreach ().
*
* All queries are passed as a prepared statement string. A
* prepared statement is a "template" of a query that omits literal or variable
* values in favor of placeholders. The values to place into those
* placeholders are passed separately, and the database driver handles
* inserting the values into the query in a secure fashion. That means you
* should never quote or string-escape a value to be inserted into the query.
*
* There are two formats for placeholders: named and unnamed. Named placeholders
* are strongly preferred in all cases as they are more flexible and
* self-documenting. Named placeholders should start with a colon ":" and can be
* followed by one or more letters, numbers or underscores.
*
* Named placeholders begin with a colon followed by a unique string. Example:
* @code
* SELECT nid, title FROM {node} WHERE uid=:uid;
* @endcode
*
* ":uid" is a placeholder that will be replaced with a literal value when
* the query is executed. A given placeholder label cannot be repeated in a
* given query, even if the value should be the same. When using named
* placeholders, the array of arguments to the query must be an associative
* array where keys are a placeholder label (e.g., :uid) and the value is the
* corresponding value to use. The array may be in any order.
*
* Unnamed placeholders are simply a question mark. Example:
* @code
* SELECT nid, title FROM {node} WHERE uid=?;
* @endcode
*
* In this case, the array of arguments must be an indexed array of values to
* use in the exact same order as the placeholders in the query.
*
* Note that placeholders should be a "complete" value. For example, when
* running a LIKE query the SQL wildcard character, %, should be part of the
* value, not the query itself. Thus, the following is incorrect:
* @code
* SELECT nid, title FROM {node} WHERE title LIKE :title%;
* @endcode
* It should instead read:
* @code
* SELECT nid, title FROM {node} WHERE title LIKE :title;
* @endcode
* and the value for :title should include a % as appropriate. Again, note the
* lack of quotation marks around :title. Because the value is not inserted
* into the query as one big string but as an explicitly separate value, the
* database server knows where the query ends and a value begins. That is
* considerably more secure against SQL injection than trying to remember
* which values need quotation marks and string escaping and which don't.
*
* INSERT, UPDATE, and DELETE queries need special care in order to behave
* consistently across all different databases. Therefore, they use a special
* object-oriented API for defining a query structurally. For example, rather
* than:
* @code
* INSERT INTO node (nid, title, body) VALUES (1, 'my title', 'my body');
* @endcode
* one would instead write:
* @code
* $fields = array('nid' => 1, 'title' => 'my title', 'body' => 'my body');
* db_insert('node')->fields($fields)->execute();
* @endcode
* This method allows databases that need special data type handling to do so,
* while also allowing optimizations such as multi-insert queries. UPDATE and
* DELETE queries have a similar pattern.
*
* Drupal also supports transactions, including a transparent fallback for
* databases that do not support transactions. To start a new transaction,
* simply call $txn = db_transaction(); in your own code. The transaction will
* remain open for as long as the variable $txn remains in scope. When $txn is
* destroyed, the transaction will be committed. If your transaction is nested
* inside of another then Drupal will track each transaction and only commit
* the outer-most transaction when the last transaction object goes out out of
* scope, that is, all relevant queries completed successfully.
*
* Example:
* @code
* function my_transaction_function() {
* // The transaction opens here.
* $txn = db_transaction();
*
* try {
* $id = db_insert('example')
* ->fields(array(
* 'field1' => 'mystring',
* 'field2' => 5,
* ))
* ->execute();
*
* my_other_function($id);
*
* return $id;
* }
* catch (Exception $e) {
* // Something went wrong somewhere, so roll back now.
* $txn->rollback();
* // Log the exception to watchdog.
* watchdog_exception('type', $e);
* }
*
* // $txn goes out of scope here. Unless the transaction was rolled back, it
* // gets automatically committed here.
* }
*
* function my_other_function($id) {
* // The transaction is still open here.
*
* if ($id % 2 == 0) {
* db_update('example')
* ->condition('id', $id)
* ->fields(array('field2' => 10))
* ->execute();
* }
* }
* @endcode
*
* @link http://drupal.org/developing/api/database
*/
/**
* The following utility functions are simply convenience wrappers.
*
* They should never, ever have any database-specific code in them.
*/
/**
* Executes an arbitrary query string against the active database.
*
* Use this function for SELECT queries if it is just a simple query string.
* If the caller or other modules need to change the query, use db_select()
* instead.
*
* Do not use this function for INSERT, UPDATE, or DELETE queries. Those should
* be handled via db_insert(), db_update() and db_delete() respectively.
*
* @param $query
* The prepared statement query to run. Although it will accept both named and
* unnamed placeholders, named placeholders are strongly preferred as they are
* more self-documenting.
* @param $args
* An array of values to substitute into the query. If the query uses named
* placeholders, this is an associative array in any order. If the query uses
* unnamed placeholders (?), this is an indexed array and the order must match
* the order of placeholders in the query string.
* @param $options
* An array of options to control how the query operates.
*
* @return DatabaseStatementInterface
* A prepared statement object, already executed.
*
* @see DatabaseConnection::defaultOptions()
*/
function db_query($query, array $args = array(), array $options = array()) {
if (empty($options['target'])) {
$options['target'] = 'default';
}
return Database::getConnection($options['target'])->query($query, $args, $options);
}
/**
* Executes a query against the active database, restricted to a range.
*
* @param $query
* The prepared statement query to run. Although it will accept both named and
* unnamed placeholders, named placeholders are strongly preferred as they are
* more self-documenting.
* @param $from
* The first record from the result set to return.
* @param $count
* The number of records to return from the result set.
* @param $args
* An array of values to substitute into the query. If the query uses named
* placeholders, this is an associative array in any order. If the query uses
* unnamed placeholders (?), this is an indexed array and the order must match
* the order of placeholders in the query string.
* @param $options
* An array of options to control how the query operates.
*
* @return DatabaseStatementInterface
* A prepared statement object, already executed.
*
* @see DatabaseConnection::defaultOptions()
*/
function db_query_range($query, $from, $count, array $args = array(), array $options = array()) {
if (empty($options['target'])) {
$options['target'] = 'default';
}
return Database::getConnection($options['target'])->queryRange($query, $from, $count, $args, $options);
}
/**
* Executes a query string and saves the result set to a temporary table.
*
* The execution of the query string happens against the active database.
*
* @param $query
* The prepared statement query to run. Although it will accept both named and
* unnamed placeholders, named placeholders are strongly preferred as they are
* more self-documenting.
* @param $args
* An array of values to substitute into the query. If the query uses named
* placeholders, this is an associative array in any order. If the query uses
* unnamed placeholders (?), this is an indexed array and the order must match
* the order of placeholders in the query string.
* @param $options
* An array of options to control how the query operates.
*
* @return
* The name of the temporary table.
*
* @see DatabaseConnection::defaultOptions()
*/
function db_query_temporary($query, array $args = array(), array $options = array()) {
if (empty($options['target'])) {
$options['target'] = 'default';
}
return Database::getConnection($options['target'])->queryTemporary($query, $args, $options);
}
/**
* Returns a new InsertQuery object for the active database.
*
* @param $table
* The table into which to insert.
* @param $options
* An array of options to control how the query operates.
*
* @return InsertQuery
* A new InsertQuery object for this connection.
*/
function db_insert($table, array $options = array()) {
if (empty($options['target']) || $options['target'] == 'slave') {
$options['target'] = 'default';
}
return Database::getConnection($options['target'])->insert($table, $options);
}
/**
* Returns a new MergeQuery object for the active database.
*
* @param $table
* The table into which to merge.
* @param $options
* An array of options to control how the query operates.
*
* @return MergeQuery
* A new MergeQuery object for this connection.
*/
function db_merge($table, array $options = array()) {
if (empty($options['target']) || $options['target'] == 'slave') {
$options['target'] = 'default';
}
return Database::getConnection($options['target'])->merge($table, $options);
}
/**
* Returns a new UpdateQuery object for the active database.
*
* @param $table
* The table to update.
* @param $options
* An array of options to control how the query operates.
*
* @return UpdateQuery
* A new UpdateQuery object for this connection.
*/
function db_update($table, array $options = array()) {
if (empty($options['target']) || $options['target'] == 'slave') {
$options['target'] = 'default';
}
return Database::getConnection($options['target'])->update($table, $options);
}
/**
* Returns a new DeleteQuery object for the active database.
*
* @param $table
* The table from which to delete.
* @param $options
* An array of options to control how the query operates.
*
* @return DeleteQuery
* A new DeleteQuery object for this connection.
*/
function db_delete($table, array $options = array()) {
if (empty($options['target']) || $options['target'] == 'slave') {
$options['target'] = 'default';
}
return Database::getConnection($options['target'])->delete($table, $options);
}
/**
* Returns a new TruncateQuery object for the active database.
*
* @param $table
* The table from which to delete.
* @param $options
* An array of options to control how the query operates.
*
* @return TruncateQuery
* A new TruncateQuery object for this connection.
*/
function db_truncate($table, array $options = array()) {
if (empty($options['target']) || $options['target'] == 'slave') {
$options['target'] = 'default';
}
return Database::getConnection($options['target'])->truncate($table, $options);
}
/**
* Returns a new SelectQuery object for the active database.
*
* @param $table
* The base table for this query. May be a string or another SelectQuery
* object. If a query object is passed, it will be used as a subselect.
* @param $alias
* The alias for the base table of this query.
* @param $options
* An array of options to control how the query operates.
*
* @return SelectQuery
* A new SelectQuery object for this connection.
*/
function db_select($table, $alias = NULL, array $options = array()) {
if (empty($options['target'])) {
$options['target'] = 'default';
}
return Database::getConnection($options['target'])->select($table, $alias, $options);
}
/**
* Returns a new transaction object for the active database.
*
* @param string $name
* Optional name of the transaction.
* @param array $options
* An array of options to control how the transaction operates:
* - target: The database target name.
*
* @return DatabaseTransaction
* A new DatabaseTransaction object for this connection.
*/
function db_transaction($name = NULL, array $options = array()) {
if (empty($options['target'])) {
$options['target'] = 'default';
}
return Database::getConnection($options['target'])->startTransaction($name);
}
/**
* Sets a new active database.
*
* @param $key
* The key in the $databases array to set as the default database.
*
* @return
* The key of the formerly active database.
*/
function db_set_active($key = 'default') {
return Database::setActiveConnection($key);
}
/**
* Restricts a dynamic table name to safe characters.
*
* Only keeps alphanumeric and underscores.
*
* @param $table
* The table name to escape.
*
* @return
* The escaped table name as a string.
*/
function db_escape_table($table) {
return Database::getConnection()->escapeTable($table);
}
/**
* Restricts a dynamic column or constraint name to safe characters.
*
* Only keeps alphanumeric and underscores.
*
* @param $field
* The field name to escape.
*
* @return
* The escaped field name as a string.
*/
function db_escape_field($field) {
return Database::getConnection()->escapeField($field);
}
/**
* Escapes characters that work as wildcard characters in a LIKE pattern.
*
* The wildcard characters "%" and "_" as well as backslash are prefixed with
* a backslash. Use this to do a search for a verbatim string without any
* wildcard behavior.
*
* You must use a query builder like db_select() in order to use db_like() on
* all supported database systems. Using db_like() with db_query() or
* db_query_range() is not supported.
*
* For example, the following does a case-insensitive query for all rows whose
* name starts with $prefix:
* @code
* $result = db_select('person', 'p')
* ->fields('p')
* ->condition('name', db_like($prefix) . '%', 'LIKE')
* ->execute()
* ->fetchAll();
* @endcode
*
* Backslash is defined as escape character for LIKE patterns in
* DatabaseCondition::mapConditionOperator().
*
* @param $string
* The string to escape.
*
* @return
* The escaped string.
*/
function db_like($string) {
return Database::getConnection()->escapeLike($string);
}
/**
* Retrieves the name of the currently active database driver.
*
* @return
* The name of the currently active database driver.
*/
function db_driver() {
return Database::getConnection()->driver();
}
/**
* Closes the active database connection.
*
* @param $options
* An array of options to control which connection is closed. Only the target
* key has any meaning in this case.
*/
function db_close(array $options = array()) {
if (empty($options['target'])) {
$options['target'] = NULL;
}
Database::closeConnection($options['target']);
}
/**
* Retrieves a unique id.
*
* Use this function if for some reason you can't use a serial field. Using a
* serial field is preferred, and InsertQuery::execute() returns the value of
* the last ID inserted.
*
* @param $existing_id
* After a database import, it might be that the sequences table is behind, so
* by passing in a minimum ID, it can be assured that we never issue the same
* ID.
*
* @return
* An integer number larger than any number returned before for this sequence.
*/
function db_next_id($existing_id = 0) {
return Database::getConnection()->nextId($existing_id);
}
/**
* Returns a new DatabaseCondition, set to "OR" all conditions together.
*
* @return Condition
*/
function db_or() {
return new Condition('OR');
}
/**
* Returns a new DatabaseCondition, set to "AND" all conditions together.
*
* @return Condition
*/
function db_and() {
return new Condition('AND');
}
/**
* Returns a new DatabaseCondition, set to "XOR" all conditions together.
*
* @return Condition
*/
function db_xor() {
return new Condition('XOR');
}
/**
* Returns a new DatabaseCondition, set to the specified conjunction.
*
* Internal API function call. The db_and(), db_or(), and db_xor()
* functions are preferred.
*
* @param $conjunction
* The conjunction to use for query conditions (AND, OR or XOR).
* @return Condition
*/
function db_condition($conjunction) {
return new Condition($conjunction);
}
/**
* @} End of "defgroup database".
*/
/**
* @ingroup schemaapi
* @{
*/
/**
* Creates a new table from a Drupal table definition.
*
* @param $name
* The name of the table to create.
* @param $table
* A Schema API table definition array.
*/
function db_create_table($name, $table) {
return Database::getConnection()->schema()->createTable($name, $table);
}
/**
* Returns an array of field names from an array of key/index column specifiers.
*
* This is usually an identity function but if a key/index uses a column prefix
* specification, this function extracts just the name.
*
* @param $fields
* An array of key/index column specifiers.
*
* @return
* An array of field names.
*/
function db_field_names($fields) {
return Database::getConnection()->schema()->fieldNames($fields);
}
/**
* Checks if an index exists in the given table.
*
* @param $table
* The name of the table in drupal (no prefixing).
* @param $name
* The name of the index in drupal (no prefixing).
*
* @return
* TRUE if the given index exists, otherwise FALSE.
*/
function db_index_exists($table, $name) {
return Database::getConnection()->schema()->indexExists($table, $name);
}
/**
* Checks if a table exists.
*
* @param $table
* The name of the table in drupal (no prefixing).
*
* @return
* TRUE if the given table exists, otherwise FALSE.
*/
function db_table_exists($table) {
return Database::getConnection()->schema()->tableExists($table);