Mercurial > hg > isophonics-drupal-site
diff core/lib/Drupal/Core/Database/database.api.php @ 17:129ea1e6d783
Update, including to Drupal core 8.6.10
author | Chris Cannam |
---|---|
date | Thu, 28 Feb 2019 13:21:36 +0000 |
parents | c2387f117808 |
children |
line wrap: on
line diff
--- a/core/lib/Drupal/Core/Database/database.api.php Tue Jul 10 15:07:59 2018 +0100 +++ b/core/lib/Drupal/Core/Database/database.api.php Thu Feb 28 13:21:36 2019 +0000 @@ -22,7 +22,7 @@ * practices. * * For more detailed information on the database abstraction layer, see - * https://www.drupal.org/developing/api/database. + * https://www.drupal.org/docs/8/api/database-api/database-api-overview. * * @section sec_entity Querying entities * Any query on Drupal entities or fields should use the Entity Query API. See @@ -30,19 +30,20 @@ * * @section sec_simple Simple SELECT database queries * For simple SELECT queries that do not involve entities, the Drupal database - * abstraction layer provides the functions db_query() and db_query_range(), - * which execute SELECT queries (optionally with range limits) and return result - * sets that you can iterate over using foreach loops. (The result sets are - * objects implementing the \Drupal\Core\Database\StatementInterface interface.) + * abstraction layer provides the functions \Drupal::database()->query() and + * \Drupal::database()->queryRange(), which execute SELECT queries (optionally + * with range limits) and return result sets that you can iterate over using + * foreach loops. (The result sets are objects implementing the + * \Drupal\Core\Database\StatementInterface interface.) * You can use the simple query functions for query strings that are not * dynamic (except for placeholders, see below), and that you are certain will * work in any database engine. See @ref sec_dynamic below if you have a more * complex query, or a query whose syntax would be different in some databases. * - * As a note, db_query() and similar functions are wrappers on connection object - * methods. In most classes, you should use dependency injection and the - * database connection object instead of these wrappers; See @ref sec_connection - * below for details. + * Note: \Drupal::database() is used here as a shorthand way to get a reference + * to the database connection object. In most classes, you should use dependency + * injection and inject the 'database' service to perform queries. See + * @ref sec_connection below for details. * * To use the simple database query functions, you will need to make a couple of * modifications to your bare SQL query: @@ -55,7 +56,8 @@ * putting variables directly into the query, to protect against SQL * injection attacks. * - LIMIT syntax differs between databases, so if you have a ranged query, - * use db_query_range() instead of db_query(). + * use \Drupal::database()->queryRange() instead of + * \Drupal::database()->query(). * * For example, if the query you want to run is: * @code @@ -64,7 +66,7 @@ * @endcode * you would do it like this: * @code - * $result = db_query_range('SELECT e.id, e.title, e.created + * $result = \Drupal::database()->queryRange('SELECT e.id, e.title, e.created * FROM {example} e * WHERE e.uid = :uid * ORDER BY e.created DESC', @@ -91,16 +93,11 @@ * fields (see the @link entity_api Entity API topic @endlink for more on * entity queries). * - * As a note, db_select() and similar functions are wrappers on connection - * object methods. In most classes, you should use dependency injection and the - * database connection object instead of these wrappers; See @ref sec_connection - * below for details. - * * The dynamic query API lets you build up a query dynamically using method * calls. As an illustration, the query example from @ref sec_simple above * would be: * @code - * $result = db_select('example', 'e') + * $result = \Drupal::database()->select('example', 'e') * ->fields('e', array('id', 'title', 'created')) * ->condition('e.uid', $uid) * ->orderBy('e.created', 'DESC') @@ -109,7 +106,7 @@ * @endcode * * There are also methods to join to other tables, add fields with aliases, - * isNull() to have a @code WHERE e.foo IS NULL @endcode condition, etc. See + * isNull() to query for NULL values, etc. See * https://www.drupal.org/developing/api/database for many more details. * * One note on chaining: It is common in the dynamic database API to chain @@ -123,17 +120,19 @@ * returns the query or something else, and only chain methods that return the * query. * - * @section_insert INSERT, UPDATE, and DELETE queries + * @section sec_insert INSERT, UPDATE, and DELETE queries * INSERT, UPDATE, and DELETE queries need special care in order to behave - * consistently across databases; you should never use db_query() to run - * an INSERT, UPDATE, or DELETE query. Instead, use functions db_insert(), - * db_update(), and db_delete() to obtain a base query on your table, and then - * add dynamic conditions (as illustrated in @ref sec_dynamic above). + * consistently across databases; you should never use + * \Drupal::database()->query() to run an INSERT, UPDATE, or DELETE query. + * Instead, use functions \Drupal::database()->insert(), + * \Drupal::database()->update(), and \Drupal::database()->delete() to obtain + * a base query on your table, and then add dynamic conditions (as illustrated + * in @ref sec_dynamic above). * - * As a note, db_insert() and similar functions are wrappers on connection - * object methods. In most classes, you should use dependency injection and the - * database connection object instead of these wrappers; See @ref sec_connection - * below for details. + * Note: \Drupal::database() is used here as a shorthand way to get a reference + * to the database connection object. In most classes, you should use dependency + * injection and inject the 'database' service to perform queries. See + * @ref sec_connection below for details. * * For example, if your query is: * @code @@ -142,7 +141,7 @@ * You can execute it via: * @code * $fields = array('id' => 1, 'uid' => 2, 'path' => 'path', 'name' => 'Name'); - * db_insert('example') + * \Drupal::database()->insert('example') * ->fields($fields) * ->execute(); * @endcode @@ -150,21 +149,26 @@ * @section sec_transaction Transactions * Drupal supports transactions, including a transparent fallback for * databases that do not support transactions. To start a new transaction, - * call @code $txn = db_transaction(); @endcode 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 (when all relevant queries have completed successfully). + * call startTransaction(), like this: + * @code + * $transaction = \Drupal::database()->startTransaction(); + * @endcode + * The transaction will remain open for as long as the variable $transaction + * remains in scope; when $transaction 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 (when all relevant queries have + * completed successfully). * * Example: * @code * function my_transaction_function() { + * $connection = \Drupal::database(); * // The transaction opens here. - * $txn = db_transaction(); + * $transaction = $connection->startTransaction(); * * try { - * $id = db_insert('example') + * $id = $connection->insert('example') * ->fields(array( * 'field1' => 'mystring', * 'field2' => 5, @@ -177,20 +181,21 @@ * } * catch (Exception $e) { * // Something went wrong somewhere, so roll back now. - * $txn->rollBack(); + * $transaction->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. + * // $transaction goes out of scope here. Unless the transaction was rolled + * // back, it gets automatically committed here. * } * * function my_other_function($id) { + * $connection = \Drupal::database(); * // The transaction is still open here. * * if ($id % 2 == 0) { - * db_update('example') + * $connection->update('example') * ->condition('id', $id) * ->fields(array('field2' => 10)) * ->execute(); @@ -199,18 +204,19 @@ * @endcode * * @section sec_connection Database connection objects - * The examples here all use functions like db_select() and db_query(), which - * can be called from any Drupal method or function code. In some classes, you - * may already have a database connection object in a member variable, or it may - * be passed into a class constructor via dependency injection. If that is the - * case, you can look at the code for db_select() and the other functions to see - * how to get a query object from your connection variable. For example: + * The examples here all use functions like \Drupal::database()->select() and + * \Drupal::database()->query(), which can be called from any Drupal method or + * function code. In some classes, you may already have a database connection + * object in a member variable, or it may be passed into a class constructor + * via dependency injection. If that is the case, you can look at the code for + * \Drupal::database()->select() and the other functions to see how to get a + * query object from your connection variable. For example: * @code * $query = $connection->select('example', 'e'); * @endcode * would be the equivalent of * @code - * $query = db_select('example', 'e'); + * $query = \Drupal::database()->select('example', 'e'); * @endcode * if you had a connection object variable $connection available to use. See * also the @link container Services and Dependency Injection topic. @endlink @@ -242,18 +248,15 @@ * * The following keys are defined: * - 'description': A string in non-markup plain text describing this table - * and its purpose. References to other tables should be enclosed in - * curly-brackets. For example, the node_field_revision table - * description field might contain "Stores per-revision title and - * body data for each {node}." + * and its purpose. References to other tables should be enclosed in curly + * brackets. * - 'fields': An associative array ('fieldname' => specification) * that describes the table's database columns. The specification * is also an array. The following specification parameters are defined: * - 'description': A string in non-markup plain text describing this field - * and its purpose. References to other tables should be enclosed in - * curly-brackets. For example, the node table vid field - * description might contain "Always holds the largest (most - * recent) {node_field_revision}.vid value for this nid." + * and its purpose. References to other tables should be enclosed in curly + * brackets. For example, the users_data table 'uid' field description + * might contain "The {users}.uid this record affects." * - 'type': The generic datatype: 'char', 'varchar', 'text', 'blob', 'int', * 'float', 'numeric', or 'serial'. Most types just map to the according * database engine specific data types. Use 'serial' for auto incrementing @@ -316,64 +319,70 @@ * key column specifiers (see below) that form an index on the * table. * - * A key column specifier is either a string naming a column or an - * array of two elements, column name and length, specifying a prefix - * of the named column. + * A key column specifier is either a string naming a column or an array of two + * elements, column name and length, specifying a prefix of the named column. * - * As an example, here is a SUBSET of the schema definition for - * Drupal's 'node' table. It show four fields (nid, vid, type, and - * title), the primary key on field 'nid', a unique key named 'vid' on - * field 'vid', and two indexes, one named 'nid' on field 'nid' and - * one named 'node_title_type' on the field 'title' and the first four - * bytes of the field 'type': + * As an example, this is the schema definition for the 'users_data' table. It + * shows five fields ('uid', 'module', 'name', 'value', and 'serialized'), the + * primary key (on the 'uid', 'module', and 'name' fields), and two indexes (the + * 'module' index on the 'module' field and the 'name' index on the 'name' + * field). * * @code - * $schema['node'] = array( - * 'description' => 'The base table for nodes.', - * 'fields' => array( - * 'nid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), - * 'vid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE,'default' => 0), - * 'type' => array('type' => 'varchar','length' => 32,'not null' => TRUE, 'default' => ''), - * 'language' => array('type' => 'varchar','length' => 12,'not null' => TRUE,'default' => ''), - * 'title' => array('type' => 'varchar','length' => 255,'not null' => TRUE, 'default' => ''), - * 'uid' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), - * 'status' => array('type' => 'int', 'not null' => TRUE, 'default' => 1), - * 'created' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), - * 'changed' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), - * 'comment' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), - * 'promote' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), - * 'moderate' => array('type' => 'int', 'not null' => TRUE,'default' => 0), - * 'sticky' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), - * 'translate' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), - * ), - * 'indexes' => array( - * 'node_changed' => array('changed'), - * 'node_created' => array('created'), - * 'node_moderate' => array('moderate'), - * 'node_frontpage' => array('promote', 'status', 'sticky', 'created'), - * 'node_status_type' => array('status', 'type', 'nid'), - * 'node_title_type' => array('title', array('type', 4)), - * 'node_type' => array(array('type', 4)), - * 'uid' => array('uid'), - * 'translate' => array('translate'), - * ), - * 'unique keys' => array( - * 'vid' => array('vid'), - * ), + * $schema['users_data'] = [ + * 'description' => 'Stores module data as key/value pairs per user.', + * 'fields' => [ + * 'uid' => [ + * 'description' => 'The {users}.uid this record affects.', + * 'type' => 'int', + * 'unsigned' => TRUE, + * 'not null' => TRUE, + * 'default' => 0, + * ], + * 'module' => [ + * 'description' => 'The name of the module declaring the variable.', + * 'type' => 'varchar_ascii', + * 'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH, + * 'not null' => TRUE, + * 'default' => '', + * ], + * 'name' => [ + * 'description' => 'The identifier of the data.', + * 'type' => 'varchar_ascii', + * 'length' => 128, + * 'not null' => TRUE, + * 'default' => '', + * ], + * 'value' => [ + * 'description' => 'The value.', + * 'type' => 'blob', + * 'not null' => FALSE, + * 'size' => 'big', + * ], + * 'serialized' => [ + * 'description' => 'Whether value is serialized.', + * 'type' => 'int', + * 'size' => 'tiny', + * 'unsigned' => TRUE, + * 'default' => 0, + * ], + * ], + * 'primary key' => ['uid', 'module', 'name'], + * 'indexes' => [ + * 'module' => ['module'], + * 'name' => ['name'], + * ], * // For documentation purposes only; foreign keys are not created in the * // database. - * 'foreign keys' => array( - * 'node_revision' => array( - * 'table' => 'node_field_revision', - * 'columns' => array('vid' => 'vid'), - * ), - * 'node_author' => array( + * 'foreign keys' => [ + * 'data_user' => [ * 'table' => 'users', - * 'columns' => array('uid' => 'uid'), - * ), - * ), - * 'primary key' => array('nid'), - * ); + * 'columns' => [ + * 'uid' => 'uid', + * ], + * ], + * ], + * ]; * @endcode * * @see drupal_install_schema() @@ -484,60 +493,61 @@ * @ingroup schemaapi */ function hook_schema() { - $schema['node'] = [ - // Example (partial) specification for table "node". - 'description' => 'The base table for nodes.', + $schema['users_data'] = [ + 'description' => 'Stores module data as key/value pairs per user.', 'fields' => [ - 'nid' => [ - 'description' => 'The primary identifier for a node.', - 'type' => 'serial', - 'unsigned' => TRUE, - 'not null' => TRUE, - ], - 'vid' => [ - 'description' => 'The current {node_field_revision}.vid version identifier.', + 'uid' => [ + 'description' => 'The {users}.uid this record affects.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, ], - 'type' => [ - 'description' => 'The type of this node.', - 'type' => 'varchar', - 'length' => 32, + 'module' => [ + 'description' => 'The name of the module declaring the variable.', + 'type' => 'varchar_ascii', + 'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH, 'not null' => TRUE, 'default' => '', ], - 'title' => [ - 'description' => 'The node title.', - 'type' => 'varchar', - 'length' => 255, + 'name' => [ + 'description' => 'The identifier of the data.', + 'type' => 'varchar_ascii', + 'length' => 128, 'not null' => TRUE, 'default' => '', ], + 'value' => [ + 'description' => 'The value.', + 'type' => 'blob', + 'not null' => FALSE, + 'size' => 'big', + ], + 'serialized' => [ + 'description' => 'Whether value is serialized.', + 'type' => 'int', + 'size' => 'tiny', + 'unsigned' => TRUE, + 'default' => 0, + ], ], + 'primary key' => ['uid', 'module', 'name'], 'indexes' => [ - 'node_changed' => ['changed'], - 'node_created' => ['created'], - ], - 'unique keys' => [ - 'nid_vid' => ['nid', 'vid'], - 'vid' => ['vid'], + 'module' => ['module'], + 'name' => ['name'], ], // For documentation purposes only; foreign keys are not created in the // database. 'foreign keys' => [ - 'node_revision' => [ - 'table' => 'node_field_revision', - 'columns' => ['vid' => 'vid'], - ], - 'node_author' => [ + 'data_user' => [ 'table' => 'users', - 'columns' => ['uid' => 'uid'], + 'columns' => [ + 'uid' => 'uid', + ], ], ], - 'primary key' => ['nid'], ]; + return $schema; }