comparison 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
comparison
equal deleted inserted replaced
16:c2387f117808 17:129ea1e6d783
20 * database abstraction layer also provides a structured way to construct 20 * database abstraction layer also provides a structured way to construct
21 * complex queries, and it protects the database by using good security 21 * complex queries, and it protects the database by using good security
22 * practices. 22 * practices.
23 * 23 *
24 * For more detailed information on the database abstraction layer, see 24 * For more detailed information on the database abstraction layer, see
25 * https://www.drupal.org/developing/api/database. 25 * https://www.drupal.org/docs/8/api/database-api/database-api-overview.
26 * 26 *
27 * @section sec_entity Querying entities 27 * @section sec_entity Querying entities
28 * Any query on Drupal entities or fields should use the Entity Query API. See 28 * Any query on Drupal entities or fields should use the Entity Query API. See
29 * the @link entity_api entity API topic @endlink for more information. 29 * the @link entity_api entity API topic @endlink for more information.
30 * 30 *
31 * @section sec_simple Simple SELECT database queries 31 * @section sec_simple Simple SELECT database queries
32 * For simple SELECT queries that do not involve entities, the Drupal database 32 * For simple SELECT queries that do not involve entities, the Drupal database
33 * abstraction layer provides the functions db_query() and db_query_range(), 33 * abstraction layer provides the functions \Drupal::database()->query() and
34 * which execute SELECT queries (optionally with range limits) and return result 34 * \Drupal::database()->queryRange(), which execute SELECT queries (optionally
35 * sets that you can iterate over using foreach loops. (The result sets are 35 * with range limits) and return result sets that you can iterate over using
36 * objects implementing the \Drupal\Core\Database\StatementInterface interface.) 36 * foreach loops. (The result sets are objects implementing the
37 * \Drupal\Core\Database\StatementInterface interface.)
37 * You can use the simple query functions for query strings that are not 38 * You can use the simple query functions for query strings that are not
38 * dynamic (except for placeholders, see below), and that you are certain will 39 * dynamic (except for placeholders, see below), and that you are certain will
39 * work in any database engine. See @ref sec_dynamic below if you have a more 40 * work in any database engine. See @ref sec_dynamic below if you have a more
40 * complex query, or a query whose syntax would be different in some databases. 41 * complex query, or a query whose syntax would be different in some databases.
41 * 42 *
42 * As a note, db_query() and similar functions are wrappers on connection object 43 * Note: \Drupal::database() is used here as a shorthand way to get a reference
43 * methods. In most classes, you should use dependency injection and the 44 * to the database connection object. In most classes, you should use dependency
44 * database connection object instead of these wrappers; See @ref sec_connection 45 * injection and inject the 'database' service to perform queries. See
45 * below for details. 46 * @ref sec_connection below for details.
46 * 47 *
47 * To use the simple database query functions, you will need to make a couple of 48 * To use the simple database query functions, you will need to make a couple of
48 * modifications to your bare SQL query: 49 * modifications to your bare SQL query:
49 * - Enclose your table name in {}. Drupal allows site builders to use 50 * - Enclose your table name in {}. Drupal allows site builders to use
50 * database table name prefixes, so you cannot be sure what the actual 51 * database table name prefixes, so you cannot be sure what the actual
53 * - Instead of putting values for conditions into the query, use placeholders. 54 * - Instead of putting values for conditions into the query, use placeholders.
54 * The placeholders are named and start with :, and they take the place of 55 * The placeholders are named and start with :, and they take the place of
55 * putting variables directly into the query, to protect against SQL 56 * putting variables directly into the query, to protect against SQL
56 * injection attacks. 57 * injection attacks.
57 * - LIMIT syntax differs between databases, so if you have a ranged query, 58 * - LIMIT syntax differs between databases, so if you have a ranged query,
58 * use db_query_range() instead of db_query(). 59 * use \Drupal::database()->queryRange() instead of
60 * \Drupal::database()->query().
59 * 61 *
60 * For example, if the query you want to run is: 62 * For example, if the query you want to run is:
61 * @code 63 * @code
62 * SELECT e.id, e.title, e.created FROM example e WHERE e.uid = $uid 64 * SELECT e.id, e.title, e.created FROM example e WHERE e.uid = $uid
63 * ORDER BY e.created DESC LIMIT 0, 10; 65 * ORDER BY e.created DESC LIMIT 0, 10;
64 * @endcode 66 * @endcode
65 * you would do it like this: 67 * you would do it like this:
66 * @code 68 * @code
67 * $result = db_query_range('SELECT e.id, e.title, e.created 69 * $result = \Drupal::database()->queryRange('SELECT e.id, e.title, e.created
68 * FROM {example} e 70 * FROM {example} e
69 * WHERE e.uid = :uid 71 * WHERE e.uid = :uid
70 * ORDER BY e.created DESC', 72 * ORDER BY e.created DESC',
71 * 0, 10, array(':uid' => $uid)); 73 * 0, 10, array(':uid' => $uid));
72 * foreach ($result as $record) { 74 * foreach ($result as $record) {
89 * will not work well, you need to use the dynamic query API. However, you 91 * will not work well, you need to use the dynamic query API. However, you
90 * should still use the Entity Query API if your query involves entities or 92 * should still use the Entity Query API if your query involves entities or
91 * fields (see the @link entity_api Entity API topic @endlink for more on 93 * fields (see the @link entity_api Entity API topic @endlink for more on
92 * entity queries). 94 * entity queries).
93 * 95 *
94 * As a note, db_select() and similar functions are wrappers on connection
95 * object methods. In most classes, you should use dependency injection and the
96 * database connection object instead of these wrappers; See @ref sec_connection
97 * below for details.
98 *
99 * The dynamic query API lets you build up a query dynamically using method 96 * The dynamic query API lets you build up a query dynamically using method
100 * calls. As an illustration, the query example from @ref sec_simple above 97 * calls. As an illustration, the query example from @ref sec_simple above
101 * would be: 98 * would be:
102 * @code 99 * @code
103 * $result = db_select('example', 'e') 100 * $result = \Drupal::database()->select('example', 'e')
104 * ->fields('e', array('id', 'title', 'created')) 101 * ->fields('e', array('id', 'title', 'created'))
105 * ->condition('e.uid', $uid) 102 * ->condition('e.uid', $uid)
106 * ->orderBy('e.created', 'DESC') 103 * ->orderBy('e.created', 'DESC')
107 * ->range(0, 10) 104 * ->range(0, 10)
108 * ->execute(); 105 * ->execute();
109 * @endcode 106 * @endcode
110 * 107 *
111 * There are also methods to join to other tables, add fields with aliases, 108 * There are also methods to join to other tables, add fields with aliases,
112 * isNull() to have a @code WHERE e.foo IS NULL @endcode condition, etc. See 109 * isNull() to query for NULL values, etc. See
113 * https://www.drupal.org/developing/api/database for many more details. 110 * https://www.drupal.org/developing/api/database for many more details.
114 * 111 *
115 * One note on chaining: It is common in the dynamic database API to chain 112 * One note on chaining: It is common in the dynamic database API to chain
116 * method calls (as illustrated here), because most of the query methods modify 113 * method calls (as illustrated here), because most of the query methods modify
117 * the query object and then return the modified query as their return 114 * the query object and then return the modified query as their return
121 * - addField(): This method returns the field alias. 118 * - addField(): This method returns the field alias.
122 * Check the documentation for the query method you are using to see if it 119 * Check the documentation for the query method you are using to see if it
123 * returns the query or something else, and only chain methods that return the 120 * returns the query or something else, and only chain methods that return the
124 * query. 121 * query.
125 * 122 *
126 * @section_insert INSERT, UPDATE, and DELETE queries 123 * @section sec_insert INSERT, UPDATE, and DELETE queries
127 * INSERT, UPDATE, and DELETE queries need special care in order to behave 124 * INSERT, UPDATE, and DELETE queries need special care in order to behave
128 * consistently across databases; you should never use db_query() to run 125 * consistently across databases; you should never use
129 * an INSERT, UPDATE, or DELETE query. Instead, use functions db_insert(), 126 * \Drupal::database()->query() to run an INSERT, UPDATE, or DELETE query.
130 * db_update(), and db_delete() to obtain a base query on your table, and then 127 * Instead, use functions \Drupal::database()->insert(),
131 * add dynamic conditions (as illustrated in @ref sec_dynamic above). 128 * \Drupal::database()->update(), and \Drupal::database()->delete() to obtain
132 * 129 * a base query on your table, and then add dynamic conditions (as illustrated
133 * As a note, db_insert() and similar functions are wrappers on connection 130 * in @ref sec_dynamic above).
134 * object methods. In most classes, you should use dependency injection and the 131 *
135 * database connection object instead of these wrappers; See @ref sec_connection 132 * Note: \Drupal::database() is used here as a shorthand way to get a reference
136 * below for details. 133 * to the database connection object. In most classes, you should use dependency
134 * injection and inject the 'database' service to perform queries. See
135 * @ref sec_connection below for details.
137 * 136 *
138 * For example, if your query is: 137 * For example, if your query is:
139 * @code 138 * @code
140 * INSERT INTO example (id, uid, path, name) VALUES (1, 2, 'path', 'Name'); 139 * INSERT INTO example (id, uid, path, name) VALUES (1, 2, 'path', 'Name');
141 * @endcode 140 * @endcode
142 * You can execute it via: 141 * You can execute it via:
143 * @code 142 * @code
144 * $fields = array('id' => 1, 'uid' => 2, 'path' => 'path', 'name' => 'Name'); 143 * $fields = array('id' => 1, 'uid' => 2, 'path' => 'path', 'name' => 'Name');
145 * db_insert('example') 144 * \Drupal::database()->insert('example')
146 * ->fields($fields) 145 * ->fields($fields)
147 * ->execute(); 146 * ->execute();
148 * @endcode 147 * @endcode
149 * 148 *
150 * @section sec_transaction Transactions 149 * @section sec_transaction Transactions
151 * Drupal supports transactions, including a transparent fallback for 150 * Drupal supports transactions, including a transparent fallback for
152 * databases that do not support transactions. To start a new transaction, 151 * databases that do not support transactions. To start a new transaction,
153 * call @code $txn = db_transaction(); @endcode The transaction will 152 * call startTransaction(), like this:
154 * remain open for as long as the variable $txn remains in scope; when $txn is 153 * @code
155 * destroyed, the transaction will be committed. If your transaction is nested 154 * $transaction = \Drupal::database()->startTransaction();
156 * inside of another then Drupal will track each transaction and only commit 155 * @endcode
157 * the outer-most transaction when the last transaction object goes out out of 156 * The transaction will remain open for as long as the variable $transaction
158 * scope (when all relevant queries have completed successfully). 157 * remains in scope; when $transaction is destroyed, the transaction will be
158 * committed. If your transaction is nested inside of another then Drupal will
159 * track each transaction and only commit the outer-most transaction when the
160 * last transaction object goes out out of scope (when all relevant queries have
161 * completed successfully).
159 * 162 *
160 * Example: 163 * Example:
161 * @code 164 * @code
162 * function my_transaction_function() { 165 * function my_transaction_function() {
166 * $connection = \Drupal::database();
163 * // The transaction opens here. 167 * // The transaction opens here.
164 * $txn = db_transaction(); 168 * $transaction = $connection->startTransaction();
165 * 169 *
166 * try { 170 * try {
167 * $id = db_insert('example') 171 * $id = $connection->insert('example')
168 * ->fields(array( 172 * ->fields(array(
169 * 'field1' => 'mystring', 173 * 'field1' => 'mystring',
170 * 'field2' => 5, 174 * 'field2' => 5,
171 * )) 175 * ))
172 * ->execute(); 176 * ->execute();
175 * 179 *
176 * return $id; 180 * return $id;
177 * } 181 * }
178 * catch (Exception $e) { 182 * catch (Exception $e) {
179 * // Something went wrong somewhere, so roll back now. 183 * // Something went wrong somewhere, so roll back now.
180 * $txn->rollBack(); 184 * $transaction->rollBack();
181 * // Log the exception to watchdog. 185 * // Log the exception to watchdog.
182 * watchdog_exception('type', $e); 186 * watchdog_exception('type', $e);
183 * } 187 * }
184 * 188 *
185 * // $txn goes out of scope here. Unless the transaction was rolled back, it 189 * // $transaction goes out of scope here. Unless the transaction was rolled
186 * // gets automatically committed here. 190 * // back, it gets automatically committed here.
187 * } 191 * }
188 * 192 *
189 * function my_other_function($id) { 193 * function my_other_function($id) {
194 * $connection = \Drupal::database();
190 * // The transaction is still open here. 195 * // The transaction is still open here.
191 * 196 *
192 * if ($id % 2 == 0) { 197 * if ($id % 2 == 0) {
193 * db_update('example') 198 * $connection->update('example')
194 * ->condition('id', $id) 199 * ->condition('id', $id)
195 * ->fields(array('field2' => 10)) 200 * ->fields(array('field2' => 10))
196 * ->execute(); 201 * ->execute();
197 * } 202 * }
198 * } 203 * }
199 * @endcode 204 * @endcode
200 * 205 *
201 * @section sec_connection Database connection objects 206 * @section sec_connection Database connection objects
202 * The examples here all use functions like db_select() and db_query(), which 207 * The examples here all use functions like \Drupal::database()->select() and
203 * can be called from any Drupal method or function code. In some classes, you 208 * \Drupal::database()->query(), which can be called from any Drupal method or
204 * may already have a database connection object in a member variable, or it may 209 * function code. In some classes, you may already have a database connection
205 * be passed into a class constructor via dependency injection. If that is the 210 * object in a member variable, or it may be passed into a class constructor
206 * case, you can look at the code for db_select() and the other functions to see 211 * via dependency injection. If that is the case, you can look at the code for
207 * how to get a query object from your connection variable. For example: 212 * \Drupal::database()->select() and the other functions to see how to get a
213 * query object from your connection variable. For example:
208 * @code 214 * @code
209 * $query = $connection->select('example', 'e'); 215 * $query = $connection->select('example', 'e');
210 * @endcode 216 * @endcode
211 * would be the equivalent of 217 * would be the equivalent of
212 * @code 218 * @code
213 * $query = db_select('example', 'e'); 219 * $query = \Drupal::database()->select('example', 'e');
214 * @endcode 220 * @endcode
215 * if you had a connection object variable $connection available to use. See 221 * if you had a connection object variable $connection available to use. See
216 * also the @link container Services and Dependency Injection topic. @endlink 222 * also the @link container Services and Dependency Injection topic. @endlink
217 * 223 *
218 * @see https://www.drupal.org/developing/api/database 224 * @see https://www.drupal.org/developing/api/database
240 * hook_schema() should return an array with a key for each table that 246 * hook_schema() should return an array with a key for each table that
241 * the module defines. 247 * the module defines.
242 * 248 *
243 * The following keys are defined: 249 * The following keys are defined:
244 * - 'description': A string in non-markup plain text describing this table 250 * - 'description': A string in non-markup plain text describing this table
245 * and its purpose. References to other tables should be enclosed in 251 * and its purpose. References to other tables should be enclosed in curly
246 * curly-brackets. For example, the node_field_revision table 252 * brackets.
247 * description field might contain "Stores per-revision title and
248 * body data for each {node}."
249 * - 'fields': An associative array ('fieldname' => specification) 253 * - 'fields': An associative array ('fieldname' => specification)
250 * that describes the table's database columns. The specification 254 * that describes the table's database columns. The specification
251 * is also an array. The following specification parameters are defined: 255 * is also an array. The following specification parameters are defined:
252 * - 'description': A string in non-markup plain text describing this field 256 * - 'description': A string in non-markup plain text describing this field
253 * and its purpose. References to other tables should be enclosed in 257 * and its purpose. References to other tables should be enclosed in curly
254 * curly-brackets. For example, the node table vid field 258 * brackets. For example, the users_data table 'uid' field description
255 * description might contain "Always holds the largest (most 259 * might contain "The {users}.uid this record affects."
256 * recent) {node_field_revision}.vid value for this nid."
257 * - 'type': The generic datatype: 'char', 'varchar', 'text', 'blob', 'int', 260 * - 'type': The generic datatype: 'char', 'varchar', 'text', 'blob', 'int',
258 * 'float', 'numeric', or 'serial'. Most types just map to the according 261 * 'float', 'numeric', or 'serial'. Most types just map to the according
259 * database engine specific data types. Use 'serial' for auto incrementing 262 * database engine specific data types. Use 'serial' for auto incrementing
260 * fields. This will expand to 'INT auto_increment' on MySQL. 263 * fields. This will expand to 'INT auto_increment' on MySQL.
261 * A special 'varchar_ascii' type is also available for limiting machine 264 * A special 'varchar_ascii' type is also available for limiting machine
314 * - 'indexes': An associative array of indexes ('indexname' => 317 * - 'indexes': An associative array of indexes ('indexname' =>
315 * specification). Each specification is an array of one or more 318 * specification). Each specification is an array of one or more
316 * key column specifiers (see below) that form an index on the 319 * key column specifiers (see below) that form an index on the
317 * table. 320 * table.
318 * 321 *
319 * A key column specifier is either a string naming a column or an 322 * A key column specifier is either a string naming a column or an array of two
320 * array of two elements, column name and length, specifying a prefix 323 * elements, column name and length, specifying a prefix of the named column.
321 * of the named column. 324 *
322 * 325 * As an example, this is the schema definition for the 'users_data' table. It
323 * As an example, here is a SUBSET of the schema definition for 326 * shows five fields ('uid', 'module', 'name', 'value', and 'serialized'), the
324 * Drupal's 'node' table. It show four fields (nid, vid, type, and 327 * primary key (on the 'uid', 'module', and 'name' fields), and two indexes (the
325 * title), the primary key on field 'nid', a unique key named 'vid' on 328 * 'module' index on the 'module' field and the 'name' index on the 'name'
326 * field 'vid', and two indexes, one named 'nid' on field 'nid' and 329 * field).
327 * one named 'node_title_type' on the field 'title' and the first four 330 *
328 * bytes of the field 'type': 331 * @code
329 * 332 * $schema['users_data'] = [
330 * @code 333 * 'description' => 'Stores module data as key/value pairs per user.',
331 * $schema['node'] = array( 334 * 'fields' => [
332 * 'description' => 'The base table for nodes.', 335 * 'uid' => [
333 * 'fields' => array( 336 * 'description' => 'The {users}.uid this record affects.',
334 * 'nid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), 337 * 'type' => 'int',
335 * 'vid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE,'default' => 0), 338 * 'unsigned' => TRUE,
336 * 'type' => array('type' => 'varchar','length' => 32,'not null' => TRUE, 'default' => ''), 339 * 'not null' => TRUE,
337 * 'language' => array('type' => 'varchar','length' => 12,'not null' => TRUE,'default' => ''), 340 * 'default' => 0,
338 * 'title' => array('type' => 'varchar','length' => 255,'not null' => TRUE, 'default' => ''), 341 * ],
339 * 'uid' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), 342 * 'module' => [
340 * 'status' => array('type' => 'int', 'not null' => TRUE, 'default' => 1), 343 * 'description' => 'The name of the module declaring the variable.',
341 * 'created' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), 344 * 'type' => 'varchar_ascii',
342 * 'changed' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), 345 * 'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
343 * 'comment' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), 346 * 'not null' => TRUE,
344 * 'promote' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), 347 * 'default' => '',
345 * 'moderate' => array('type' => 'int', 'not null' => TRUE,'default' => 0), 348 * ],
346 * 'sticky' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), 349 * 'name' => [
347 * 'translate' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), 350 * 'description' => 'The identifier of the data.',
348 * ), 351 * 'type' => 'varchar_ascii',
349 * 'indexes' => array( 352 * 'length' => 128,
350 * 'node_changed' => array('changed'), 353 * 'not null' => TRUE,
351 * 'node_created' => array('created'), 354 * 'default' => '',
352 * 'node_moderate' => array('moderate'), 355 * ],
353 * 'node_frontpage' => array('promote', 'status', 'sticky', 'created'), 356 * 'value' => [
354 * 'node_status_type' => array('status', 'type', 'nid'), 357 * 'description' => 'The value.',
355 * 'node_title_type' => array('title', array('type', 4)), 358 * 'type' => 'blob',
356 * 'node_type' => array(array('type', 4)), 359 * 'not null' => FALSE,
357 * 'uid' => array('uid'), 360 * 'size' => 'big',
358 * 'translate' => array('translate'), 361 * ],
359 * ), 362 * 'serialized' => [
360 * 'unique keys' => array( 363 * 'description' => 'Whether value is serialized.',
361 * 'vid' => array('vid'), 364 * 'type' => 'int',
362 * ), 365 * 'size' => 'tiny',
366 * 'unsigned' => TRUE,
367 * 'default' => 0,
368 * ],
369 * ],
370 * 'primary key' => ['uid', 'module', 'name'],
371 * 'indexes' => [
372 * 'module' => ['module'],
373 * 'name' => ['name'],
374 * ],
363 * // For documentation purposes only; foreign keys are not created in the 375 * // For documentation purposes only; foreign keys are not created in the
364 * // database. 376 * // database.
365 * 'foreign keys' => array( 377 * 'foreign keys' => [
366 * 'node_revision' => array( 378 * 'data_user' => [
367 * 'table' => 'node_field_revision',
368 * 'columns' => array('vid' => 'vid'),
369 * ),
370 * 'node_author' => array(
371 * 'table' => 'users', 379 * 'table' => 'users',
372 * 'columns' => array('uid' => 'uid'), 380 * 'columns' => [
373 * ), 381 * 'uid' => 'uid',
374 * ), 382 * ],
375 * 'primary key' => array('nid'), 383 * ],
376 * ); 384 * ],
385 * ];
377 * @endcode 386 * @endcode
378 * 387 *
379 * @see drupal_install_schema() 388 * @see drupal_install_schema()
380 * 389 *
381 * @} 390 * @}
482 * definition. 491 * definition.
483 * 492 *
484 * @ingroup schemaapi 493 * @ingroup schemaapi
485 */ 494 */
486 function hook_schema() { 495 function hook_schema() {
487 $schema['node'] = [ 496 $schema['users_data'] = [
488 // Example (partial) specification for table "node". 497 'description' => 'Stores module data as key/value pairs per user.',
489 'description' => 'The base table for nodes.',
490 'fields' => [ 498 'fields' => [
491 'nid' => [ 499 'uid' => [
492 'description' => 'The primary identifier for a node.', 500 'description' => 'The {users}.uid this record affects.',
493 'type' => 'serial',
494 'unsigned' => TRUE,
495 'not null' => TRUE,
496 ],
497 'vid' => [
498 'description' => 'The current {node_field_revision}.vid version identifier.',
499 'type' => 'int', 501 'type' => 'int',
500 'unsigned' => TRUE, 502 'unsigned' => TRUE,
501 'not null' => TRUE, 503 'not null' => TRUE,
502 'default' => 0, 504 'default' => 0,
503 ], 505 ],
504 'type' => [ 506 'module' => [
505 'description' => 'The type of this node.', 507 'description' => 'The name of the module declaring the variable.',
506 'type' => 'varchar', 508 'type' => 'varchar_ascii',
507 'length' => 32, 509 'length' => DRUPAL_EXTENSION_NAME_MAX_LENGTH,
508 'not null' => TRUE, 510 'not null' => TRUE,
509 'default' => '', 511 'default' => '',
510 ], 512 ],
511 'title' => [ 513 'name' => [
512 'description' => 'The node title.', 514 'description' => 'The identifier of the data.',
513 'type' => 'varchar', 515 'type' => 'varchar_ascii',
514 'length' => 255, 516 'length' => 128,
515 'not null' => TRUE, 517 'not null' => TRUE,
516 'default' => '', 518 'default' => '',
517 ], 519 ],
520 'value' => [
521 'description' => 'The value.',
522 'type' => 'blob',
523 'not null' => FALSE,
524 'size' => 'big',
525 ],
526 'serialized' => [
527 'description' => 'Whether value is serialized.',
528 'type' => 'int',
529 'size' => 'tiny',
530 'unsigned' => TRUE,
531 'default' => 0,
532 ],
518 ], 533 ],
534 'primary key' => ['uid', 'module', 'name'],
519 'indexes' => [ 535 'indexes' => [
520 'node_changed' => ['changed'], 536 'module' => ['module'],
521 'node_created' => ['created'], 537 'name' => ['name'],
522 ],
523 'unique keys' => [
524 'nid_vid' => ['nid', 'vid'],
525 'vid' => ['vid'],
526 ], 538 ],
527 // For documentation purposes only; foreign keys are not created in the 539 // For documentation purposes only; foreign keys are not created in the
528 // database. 540 // database.
529 'foreign keys' => [ 541 'foreign keys' => [
530 'node_revision' => [ 542 'data_user' => [
531 'table' => 'node_field_revision',
532 'columns' => ['vid' => 'vid'],
533 ],
534 'node_author' => [
535 'table' => 'users', 543 'table' => 'users',
536 'columns' => ['uid' => 'uid'], 544 'columns' => [
545 'uid' => 'uid',
546 ],
537 ], 547 ],
538 ], 548 ],
539 'primary key' => ['nid'],
540 ]; 549 ];
550
541 return $schema; 551 return $schema;
542 } 552 }
543 553
544 /** 554 /**
545 * @} End of "addtogroup hooks". 555 * @} End of "addtogroup hooks".