|
1 <?php |
|
2 |
|
3 /** |
|
4 * @file |
|
5 * Core systems for the database layer. |
|
6 * |
|
7 * Classes required for basic functioning of the database system should be |
|
8 * placed in this file. All utility functions should also be placed in this |
|
9 * file only, as they cannot auto-load the way classes can. |
|
10 */ |
|
11 |
|
12 /** |
|
13 * @defgroup database Database abstraction layer |
|
14 * @{ |
|
15 * Allow the use of different database servers using the same code base. |
|
16 * |
|
17 * Drupal provides a database abstraction layer to provide developers with |
|
18 * the ability to support multiple database servers easily. The intent of |
|
19 * this layer is to preserve the syntax and power of SQL as much as possible, |
|
20 * but also allow developers a way to leverage more complex functionality in |
|
21 * a unified way. It also provides a structured interface for dynamically |
|
22 * constructing queries when appropriate, and enforcing security checks and |
|
23 * similar good practices. |
|
24 * |
|
25 * The system is built atop PHP's PDO (PHP Data Objects) database API and |
|
26 * inherits much of its syntax and semantics. |
|
27 * |
|
28 * Most Drupal database SELECT queries are performed by a call to db_query() or |
|
29 * db_query_range(). Module authors should also consider using the PagerDefault |
|
30 * Extender for queries that return results that need to be presented on |
|
31 * multiple pages (see https://drupal.org/node/508796), and the TableSort |
|
32 * Extender for generating appropriate queries for sortable tables |
|
33 * (see https://drupal.org/node/1848372). |
|
34 * |
|
35 * For example, one might wish to return a list of the most recent 10 nodes |
|
36 * authored by a given user. Instead of directly issuing the SQL query |
|
37 * @code |
|
38 * SELECT n.nid, n.title, n.created FROM node n WHERE n.uid = $uid |
|
39 * ORDER BY n.created DESC LIMIT 0, 10; |
|
40 * @endcode |
|
41 * one would instead call the Drupal functions: |
|
42 * @code |
|
43 * $result = db_query_range('SELECT n.nid, n.title, n.created |
|
44 * FROM {node} n WHERE n.uid = :uid |
|
45 * ORDER BY n.created DESC', 0, 10, array(':uid' => $uid)); |
|
46 * foreach ($result as $record) { |
|
47 * // Perform operations on $record->title, etc. here. |
|
48 * } |
|
49 * @endcode |
|
50 * Curly braces are used around "node" to provide table prefixing via |
|
51 * DatabaseConnection::prefixTables(). The explicit use of a user ID is pulled |
|
52 * out into an argument passed to db_query() so that SQL injection attacks |
|
53 * from user input can be caught and nullified. The LIMIT syntax varies between |
|
54 * database servers, so that is abstracted into db_query_range() arguments. |
|
55 * Finally, note the PDO-based ability to iterate over the result set using |
|
56 * foreach (). |
|
57 * |
|
58 * All queries are passed as a prepared statement string. A |
|
59 * prepared statement is a "template" of a query that omits literal or variable |
|
60 * values in favor of placeholders. The values to place into those |
|
61 * placeholders are passed separately, and the database driver handles |
|
62 * inserting the values into the query in a secure fashion. That means you |
|
63 * should never quote or string-escape a value to be inserted into the query. |
|
64 * |
|
65 * There are two formats for placeholders: named and unnamed. Named placeholders |
|
66 * are strongly preferred in all cases as they are more flexible and |
|
67 * self-documenting. Named placeholders should start with a colon ":" and can be |
|
68 * followed by one or more letters, numbers or underscores. |
|
69 * |
|
70 * Named placeholders begin with a colon followed by a unique string. Example: |
|
71 * @code |
|
72 * SELECT nid, title FROM {node} WHERE uid=:uid; |
|
73 * @endcode |
|
74 * |
|
75 * ":uid" is a placeholder that will be replaced with a literal value when |
|
76 * the query is executed. A given placeholder label cannot be repeated in a |
|
77 * given query, even if the value should be the same. When using named |
|
78 * placeholders, the array of arguments to the query must be an associative |
|
79 * array where keys are a placeholder label (e.g., :uid) and the value is the |
|
80 * corresponding value to use. The array may be in any order. |
|
81 * |
|
82 * Unnamed placeholders are simply a question mark. Example: |
|
83 * @code |
|
84 * SELECT nid, title FROM {node} WHERE uid=?; |
|
85 * @endcode |
|
86 * |
|
87 * In this case, the array of arguments must be an indexed array of values to |
|
88 * use in the exact same order as the placeholders in the query. |
|
89 * |
|
90 * Note that placeholders should be a "complete" value. For example, when |
|
91 * running a LIKE query the SQL wildcard character, %, should be part of the |
|
92 * value, not the query itself. Thus, the following is incorrect: |
|
93 * @code |
|
94 * SELECT nid, title FROM {node} WHERE title LIKE :title%; |
|
95 * @endcode |
|
96 * It should instead read: |
|
97 * @code |
|
98 * SELECT nid, title FROM {node} WHERE title LIKE :title; |
|
99 * @endcode |
|
100 * and the value for :title should include a % as appropriate. Again, note the |
|
101 * lack of quotation marks around :title. Because the value is not inserted |
|
102 * into the query as one big string but as an explicitly separate value, the |
|
103 * database server knows where the query ends and a value begins. That is |
|
104 * considerably more secure against SQL injection than trying to remember |
|
105 * which values need quotation marks and string escaping and which don't. |
|
106 * |
|
107 * INSERT, UPDATE, and DELETE queries need special care in order to behave |
|
108 * consistently across all different databases. Therefore, they use a special |
|
109 * object-oriented API for defining a query structurally. For example, rather |
|
110 * than: |
|
111 * @code |
|
112 * INSERT INTO node (nid, title, body) VALUES (1, 'my title', 'my body'); |
|
113 * @endcode |
|
114 * one would instead write: |
|
115 * @code |
|
116 * $fields = array('nid' => 1, 'title' => 'my title', 'body' => 'my body'); |
|
117 * db_insert('node')->fields($fields)->execute(); |
|
118 * @endcode |
|
119 * This method allows databases that need special data type handling to do so, |
|
120 * while also allowing optimizations such as multi-insert queries. UPDATE and |
|
121 * DELETE queries have a similar pattern. |
|
122 * |
|
123 * Drupal also supports transactions, including a transparent fallback for |
|
124 * databases that do not support transactions. To start a new transaction, |
|
125 * simply call $txn = db_transaction(); in your own code. The transaction will |
|
126 * remain open for as long as the variable $txn remains in scope. When $txn is |
|
127 * destroyed, the transaction will be committed. If your transaction is nested |
|
128 * inside of another then Drupal will track each transaction and only commit |
|
129 * the outer-most transaction when the last transaction object goes out out of |
|
130 * scope, that is, all relevant queries completed successfully. |
|
131 * |
|
132 * Example: |
|
133 * @code |
|
134 * function my_transaction_function() { |
|
135 * // The transaction opens here. |
|
136 * $txn = db_transaction(); |
|
137 * |
|
138 * try { |
|
139 * $id = db_insert('example') |
|
140 * ->fields(array( |
|
141 * 'field1' => 'mystring', |
|
142 * 'field2' => 5, |
|
143 * )) |
|
144 * ->execute(); |
|
145 * |
|
146 * my_other_function($id); |
|
147 * |
|
148 * return $id; |
|
149 * } |
|
150 * catch (Exception $e) { |
|
151 * // Something went wrong somewhere, so roll back now. |
|
152 * $txn->rollback(); |
|
153 * // Log the exception to watchdog. |
|
154 * watchdog_exception('type', $e); |
|
155 * } |
|
156 * |
|
157 * // $txn goes out of scope here. Unless the transaction was rolled back, it |
|
158 * // gets automatically committed here. |
|
159 * } |
|
160 * |
|
161 * function my_other_function($id) { |
|
162 * // The transaction is still open here. |
|
163 * |
|
164 * if ($id % 2 == 0) { |
|
165 * db_update('example') |
|
166 * ->condition('id', $id) |
|
167 * ->fields(array('field2' => 10)) |
|
168 * ->execute(); |
|
169 * } |
|
170 * } |
|
171 * @endcode |
|
172 * |
|
173 * @see http://drupal.org/developing/api/database |
|
174 */ |
|
175 |
|
176 |
|
177 /** |
|
178 * Base Database API class. |
|
179 * |
|
180 * This class provides a Drupal-specific extension of the PDO database |
|
181 * abstraction class in PHP. Every database driver implementation must provide a |
|
182 * concrete implementation of it to support special handling required by that |
|
183 * database. |
|
184 * |
|
185 * @see http://php.net/manual/book.pdo.php |
|
186 */ |
|
187 abstract class DatabaseConnection extends PDO { |
|
188 |
|
189 /** |
|
190 * The database target this connection is for. |
|
191 * |
|
192 * We need this information for later auditing and logging. |
|
193 * |
|
194 * @var string |
|
195 */ |
|
196 protected $target = NULL; |
|
197 |
|
198 /** |
|
199 * The key representing this connection. |
|
200 * |
|
201 * The key is a unique string which identifies a database connection. A |
|
202 * connection can be a single server or a cluster of master and slaves (use |
|
203 * target to pick between master and slave). |
|
204 * |
|
205 * @var string |
|
206 */ |
|
207 protected $key = NULL; |
|
208 |
|
209 /** |
|
210 * The current database logging object for this connection. |
|
211 * |
|
212 * @var DatabaseLog |
|
213 */ |
|
214 protected $logger = NULL; |
|
215 |
|
216 /** |
|
217 * Tracks the number of "layers" of transactions currently active. |
|
218 * |
|
219 * On many databases transactions cannot nest. Instead, we track |
|
220 * nested calls to transactions and collapse them into a single |
|
221 * transaction. |
|
222 * |
|
223 * @var array |
|
224 */ |
|
225 protected $transactionLayers = array(); |
|
226 |
|
227 /** |
|
228 * Index of what driver-specific class to use for various operations. |
|
229 * |
|
230 * @var array |
|
231 */ |
|
232 protected $driverClasses = array(); |
|
233 |
|
234 /** |
|
235 * The name of the Statement class for this connection. |
|
236 * |
|
237 * @var string |
|
238 */ |
|
239 protected $statementClass = 'DatabaseStatementBase'; |
|
240 |
|
241 /** |
|
242 * Whether this database connection supports transactions. |
|
243 * |
|
244 * @var bool |
|
245 */ |
|
246 protected $transactionSupport = TRUE; |
|
247 |
|
248 /** |
|
249 * Whether this database connection supports transactional DDL. |
|
250 * |
|
251 * Set to FALSE by default because few databases support this feature. |
|
252 * |
|
253 * @var bool |
|
254 */ |
|
255 protected $transactionalDDLSupport = FALSE; |
|
256 |
|
257 /** |
|
258 * An index used to generate unique temporary table names. |
|
259 * |
|
260 * @var integer |
|
261 */ |
|
262 protected $temporaryNameIndex = 0; |
|
263 |
|
264 /** |
|
265 * The connection information for this connection object. |
|
266 * |
|
267 * @var array |
|
268 */ |
|
269 protected $connectionOptions = array(); |
|
270 |
|
271 /** |
|
272 * The schema object for this connection. |
|
273 * |
|
274 * @var object |
|
275 */ |
|
276 protected $schema = NULL; |
|
277 |
|
278 /** |
|
279 * The prefixes used by this database connection. |
|
280 * |
|
281 * @var array |
|
282 */ |
|
283 protected $prefixes = array(); |
|
284 |
|
285 /** |
|
286 * List of search values for use in prefixTables(). |
|
287 * |
|
288 * @var array |
|
289 */ |
|
290 protected $prefixSearch = array(); |
|
291 |
|
292 /** |
|
293 * List of replacement values for use in prefixTables(). |
|
294 * |
|
295 * @var array |
|
296 */ |
|
297 protected $prefixReplace = array(); |
|
298 |
|
299 /** |
|
300 * List of escaped database, table, and field names, keyed by unescaped names. |
|
301 * |
|
302 * @var array |
|
303 */ |
|
304 protected $escapedNames = array(); |
|
305 |
|
306 /** |
|
307 * List of escaped aliases names, keyed by unescaped aliases. |
|
308 * |
|
309 * @var array |
|
310 */ |
|
311 protected $escapedAliases = array(); |
|
312 |
|
313 function __construct($dsn, $username, $password, $driver_options = array()) { |
|
314 // Initialize and prepare the connection prefix. |
|
315 $this->setPrefix(isset($this->connectionOptions['prefix']) ? $this->connectionOptions['prefix'] : ''); |
|
316 |
|
317 // Because the other methods don't seem to work right. |
|
318 $driver_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION; |
|
319 |
|
320 // Call PDO::__construct and PDO::setAttribute. |
|
321 parent::__construct($dsn, $username, $password, $driver_options); |
|
322 |
|
323 // Set a Statement class, unless the driver opted out. |
|
324 if (!empty($this->statementClass)) { |
|
325 $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array($this->statementClass, array($this))); |
|
326 } |
|
327 } |
|
328 |
|
329 /** |
|
330 * Destroys this Connection object. |
|
331 * |
|
332 * PHP does not destruct an object if it is still referenced in other |
|
333 * variables. In case of PDO database connection objects, PHP only closes the |
|
334 * connection when the PDO object is destructed, so any references to this |
|
335 * object may cause the number of maximum allowed connections to be exceeded. |
|
336 */ |
|
337 public function destroy() { |
|
338 // Destroy all references to this connection by setting them to NULL. |
|
339 // The Statement class attribute only accepts a new value that presents a |
|
340 // proper callable, so we reset it to PDOStatement. |
|
341 $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDOStatement', array())); |
|
342 $this->schema = NULL; |
|
343 } |
|
344 |
|
345 /** |
|
346 * Returns the default query options for any given query. |
|
347 * |
|
348 * A given query can be customized with a number of option flags in an |
|
349 * associative array: |
|
350 * - target: The database "target" against which to execute a query. Valid |
|
351 * values are "default" or "slave". The system will first try to open a |
|
352 * connection to a database specified with the user-supplied key. If one |
|
353 * is not available, it will silently fall back to the "default" target. |
|
354 * If multiple databases connections are specified with the same target, |
|
355 * one will be selected at random for the duration of the request. |
|
356 * - fetch: This element controls how rows from a result set will be |
|
357 * returned. Legal values include PDO::FETCH_ASSOC, PDO::FETCH_BOTH, |
|
358 * PDO::FETCH_OBJ, PDO::FETCH_NUM, or a string representing the name of a |
|
359 * class. If a string is specified, each record will be fetched into a new |
|
360 * object of that class. The behavior of all other values is defined by PDO. |
|
361 * See http://php.net/manual/pdostatement.fetch.php |
|
362 * - return: Depending on the type of query, different return values may be |
|
363 * meaningful. This directive instructs the system which type of return |
|
364 * value is desired. The system will generally set the correct value |
|
365 * automatically, so it is extremely rare that a module developer will ever |
|
366 * need to specify this value. Setting it incorrectly will likely lead to |
|
367 * unpredictable results or fatal errors. Legal values include: |
|
368 * - Database::RETURN_STATEMENT: Return the prepared statement object for |
|
369 * the query. This is usually only meaningful for SELECT queries, where |
|
370 * the statement object is how one accesses the result set returned by the |
|
371 * query. |
|
372 * - Database::RETURN_AFFECTED: Return the number of rows affected by an |
|
373 * UPDATE or DELETE query. Be aware that means the number of rows actually |
|
374 * changed, not the number of rows matched by the WHERE clause. |
|
375 * - Database::RETURN_INSERT_ID: Return the sequence ID (primary key) |
|
376 * created by an INSERT statement on a table that contains a serial |
|
377 * column. |
|
378 * - Database::RETURN_NULL: Do not return anything, as there is no |
|
379 * meaningful value to return. That is the case for INSERT queries on |
|
380 * tables that do not contain a serial column. |
|
381 * - throw_exception: By default, the database system will catch any errors |
|
382 * on a query as an Exception, log it, and then rethrow it so that code |
|
383 * further up the call chain can take an appropriate action. To suppress |
|
384 * that behavior and simply return NULL on failure, set this option to |
|
385 * FALSE. |
|
386 * |
|
387 * @return |
|
388 * An array of default query options. |
|
389 */ |
|
390 protected function defaultOptions() { |
|
391 return array( |
|
392 'target' => 'default', |
|
393 'fetch' => PDO::FETCH_OBJ, |
|
394 'return' => Database::RETURN_STATEMENT, |
|
395 'throw_exception' => TRUE, |
|
396 ); |
|
397 } |
|
398 |
|
399 /** |
|
400 * Returns the connection information for this connection object. |
|
401 * |
|
402 * Note that Database::getConnectionInfo() is for requesting information |
|
403 * about an arbitrary database connection that is defined. This method |
|
404 * is for requesting the connection information of this specific |
|
405 * open connection object. |
|
406 * |
|
407 * @return |
|
408 * An array of the connection information. The exact list of |
|
409 * properties is driver-dependent. |
|
410 */ |
|
411 public function getConnectionOptions() { |
|
412 return $this->connectionOptions; |
|
413 } |
|
414 |
|
415 /** |
|
416 * Set the list of prefixes used by this database connection. |
|
417 * |
|
418 * @param $prefix |
|
419 * The prefixes, in any of the multiple forms documented in |
|
420 * default.settings.php. |
|
421 */ |
|
422 protected function setPrefix($prefix) { |
|
423 if (is_array($prefix)) { |
|
424 $this->prefixes = $prefix + array('default' => ''); |
|
425 } |
|
426 else { |
|
427 $this->prefixes = array('default' => $prefix); |
|
428 } |
|
429 |
|
430 // Set up variables for use in prefixTables(). Replace table-specific |
|
431 // prefixes first. |
|
432 $this->prefixSearch = array(); |
|
433 $this->prefixReplace = array(); |
|
434 foreach ($this->prefixes as $key => $val) { |
|
435 if ($key != 'default') { |
|
436 $this->prefixSearch[] = '{' . $key . '}'; |
|
437 $this->prefixReplace[] = $val . $key; |
|
438 } |
|
439 } |
|
440 // Then replace remaining tables with the default prefix. |
|
441 $this->prefixSearch[] = '{'; |
|
442 $this->prefixReplace[] = $this->prefixes['default']; |
|
443 $this->prefixSearch[] = '}'; |
|
444 $this->prefixReplace[] = ''; |
|
445 } |
|
446 |
|
447 /** |
|
448 * Appends a database prefix to all tables in a query. |
|
449 * |
|
450 * Queries sent to Drupal should wrap all table names in curly brackets. This |
|
451 * function searches for this syntax and adds Drupal's table prefix to all |
|
452 * tables, allowing Drupal to coexist with other systems in the same database |
|
453 * and/or schema if necessary. |
|
454 * |
|
455 * @param $sql |
|
456 * A string containing a partial or entire SQL query. |
|
457 * |
|
458 * @return |
|
459 * The properly-prefixed string. |
|
460 */ |
|
461 public function prefixTables($sql) { |
|
462 return str_replace($this->prefixSearch, $this->prefixReplace, $sql); |
|
463 } |
|
464 |
|
465 /** |
|
466 * Find the prefix for a table. |
|
467 * |
|
468 * This function is for when you want to know the prefix of a table. This |
|
469 * is not used in prefixTables due to performance reasons. |
|
470 */ |
|
471 public function tablePrefix($table = 'default') { |
|
472 if (isset($this->prefixes[$table])) { |
|
473 return $this->prefixes[$table]; |
|
474 } |
|
475 else { |
|
476 return $this->prefixes['default']; |
|
477 } |
|
478 } |
|
479 |
|
480 /** |
|
481 * Prepares a query string and returns the prepared statement. |
|
482 * |
|
483 * This method caches prepared statements, reusing them when |
|
484 * possible. It also prefixes tables names enclosed in curly-braces. |
|
485 * |
|
486 * @param $query |
|
487 * The query string as SQL, with curly-braces surrounding the |
|
488 * table names. |
|
489 * |
|
490 * @return DatabaseStatementInterface |
|
491 * A PDO prepared statement ready for its execute() method. |
|
492 */ |
|
493 public function prepareQuery($query) { |
|
494 $query = $this->prefixTables($query); |
|
495 |
|
496 // Call PDO::prepare. |
|
497 return parent::prepare($query); |
|
498 } |
|
499 |
|
500 /** |
|
501 * Tells this connection object what its target value is. |
|
502 * |
|
503 * This is needed for logging and auditing. It's sloppy to do in the |
|
504 * constructor because the constructor for child classes has a different |
|
505 * signature. We therefore also ensure that this function is only ever |
|
506 * called once. |
|
507 * |
|
508 * @param $target |
|
509 * The target this connection is for. Set to NULL (default) to disable |
|
510 * logging entirely. |
|
511 */ |
|
512 public function setTarget($target = NULL) { |
|
513 if (!isset($this->target)) { |
|
514 $this->target = $target; |
|
515 } |
|
516 } |
|
517 |
|
518 /** |
|
519 * Returns the target this connection is associated with. |
|
520 * |
|
521 * @return |
|
522 * The target string of this connection. |
|
523 */ |
|
524 public function getTarget() { |
|
525 return $this->target; |
|
526 } |
|
527 |
|
528 /** |
|
529 * Tells this connection object what its key is. |
|
530 * |
|
531 * @param $target |
|
532 * The key this connection is for. |
|
533 */ |
|
534 public function setKey($key) { |
|
535 if (!isset($this->key)) { |
|
536 $this->key = $key; |
|
537 } |
|
538 } |
|
539 |
|
540 /** |
|
541 * Returns the key this connection is associated with. |
|
542 * |
|
543 * @return |
|
544 * The key of this connection. |
|
545 */ |
|
546 public function getKey() { |
|
547 return $this->key; |
|
548 } |
|
549 |
|
550 /** |
|
551 * Associates a logging object with this connection. |
|
552 * |
|
553 * @param $logger |
|
554 * The logging object we want to use. |
|
555 */ |
|
556 public function setLogger(DatabaseLog $logger) { |
|
557 $this->logger = $logger; |
|
558 } |
|
559 |
|
560 /** |
|
561 * Gets the current logging object for this connection. |
|
562 * |
|
563 * @return DatabaseLog |
|
564 * The current logging object for this connection. If there isn't one, |
|
565 * NULL is returned. |
|
566 */ |
|
567 public function getLogger() { |
|
568 return $this->logger; |
|
569 } |
|
570 |
|
571 /** |
|
572 * Creates the appropriate sequence name for a given table and serial field. |
|
573 * |
|
574 * This information is exposed to all database drivers, although it is only |
|
575 * useful on some of them. This method is table prefix-aware. |
|
576 * |
|
577 * @param $table |
|
578 * The table name to use for the sequence. |
|
579 * @param $field |
|
580 * The field name to use for the sequence. |
|
581 * |
|
582 * @return |
|
583 * A table prefix-parsed string for the sequence name. |
|
584 */ |
|
585 public function makeSequenceName($table, $field) { |
|
586 return $this->prefixTables('{' . $table . '}_' . $field . '_seq'); |
|
587 } |
|
588 |
|
589 /** |
|
590 * Flatten an array of query comments into a single comment string. |
|
591 * |
|
592 * The comment string will be sanitized to avoid SQL injection attacks. |
|
593 * |
|
594 * @param $comments |
|
595 * An array of query comment strings. |
|
596 * |
|
597 * @return |
|
598 * A sanitized comment string. |
|
599 */ |
|
600 public function makeComment($comments) { |
|
601 if (empty($comments)) |
|
602 return ''; |
|
603 |
|
604 // Flatten the array of comments. |
|
605 $comment = implode('; ', $comments); |
|
606 |
|
607 // Sanitize the comment string so as to avoid SQL injection attacks. |
|
608 return '/* ' . $this->filterComment($comment) . ' */ '; |
|
609 } |
|
610 |
|
611 /** |
|
612 * Sanitize a query comment string. |
|
613 * |
|
614 * Ensure a query comment does not include strings such as "* /" that might |
|
615 * terminate the comment early. This avoids SQL injection attacks via the |
|
616 * query comment. The comment strings in this example are separated by a |
|
617 * space to avoid PHP parse errors. |
|
618 * |
|
619 * For example, the comment: |
|
620 * @code |
|
621 * db_update('example') |
|
622 * ->condition('id', $id) |
|
623 * ->fields(array('field2' => 10)) |
|
624 * ->comment('Exploit * / DROP TABLE node; --') |
|
625 * ->execute() |
|
626 * @endcode |
|
627 * |
|
628 * Would result in the following SQL statement being generated: |
|
629 * @code |
|
630 * "/ * Exploit * / DROP TABLE node; -- * / UPDATE example SET field2=..." |
|
631 * @endcode |
|
632 * |
|
633 * Unless the comment is sanitised first, the SQL server would drop the |
|
634 * node table and ignore the rest of the SQL statement. |
|
635 * |
|
636 * @param $comment |
|
637 * A query comment string. |
|
638 * |
|
639 * @return |
|
640 * A sanitized version of the query comment string. |
|
641 */ |
|
642 protected function filterComment($comment = '') { |
|
643 return strtr($comment, array('*' => ' * ')); |
|
644 } |
|
645 |
|
646 /** |
|
647 * Executes a query string against the database. |
|
648 * |
|
649 * This method provides a central handler for the actual execution of every |
|
650 * query. All queries executed by Drupal are executed as PDO prepared |
|
651 * statements. |
|
652 * |
|
653 * @param $query |
|
654 * The query to execute. In most cases this will be a string containing |
|
655 * an SQL query with placeholders. An already-prepared instance of |
|
656 * DatabaseStatementInterface may also be passed in order to allow calling |
|
657 * code to manually bind variables to a query. If a |
|
658 * DatabaseStatementInterface is passed, the $args array will be ignored. |
|
659 * It is extremely rare that module code will need to pass a statement |
|
660 * object to this method. It is used primarily for database drivers for |
|
661 * databases that require special LOB field handling. |
|
662 * @param $args |
|
663 * An array of arguments for the prepared statement. If the prepared |
|
664 * statement uses ? placeholders, this array must be an indexed array. |
|
665 * If it contains named placeholders, it must be an associative array. |
|
666 * @param $options |
|
667 * An associative array of options to control how the query is run. See |
|
668 * the documentation for DatabaseConnection::defaultOptions() for details. |
|
669 * |
|
670 * @return DatabaseStatementInterface |
|
671 * This method will return one of: the executed statement, the number of |
|
672 * rows affected by the query (not the number matched), or the generated |
|
673 * insert ID of the last query, depending on the value of |
|
674 * $options['return']. Typically that value will be set by default or a |
|
675 * query builder and should not be set by a user. If there is an error, |
|
676 * this method will return NULL and may throw an exception if |
|
677 * $options['throw_exception'] is TRUE. |
|
678 * |
|
679 * @throws PDOException |
|
680 */ |
|
681 public function query($query, array $args = array(), $options = array()) { |
|
682 |
|
683 // Use default values if not already set. |
|
684 $options += $this->defaultOptions(); |
|
685 |
|
686 try { |
|
687 // We allow either a pre-bound statement object or a literal string. |
|
688 // In either case, we want to end up with an executed statement object, |
|
689 // which we pass to PDOStatement::execute. |
|
690 if ($query instanceof DatabaseStatementInterface) { |
|
691 $stmt = $query; |
|
692 $stmt->execute(NULL, $options); |
|
693 } |
|
694 else { |
|
695 $this->expandArguments($query, $args); |
|
696 $stmt = $this->prepareQuery($query); |
|
697 $stmt->execute($args, $options); |
|
698 } |
|
699 |
|
700 // Depending on the type of query we may need to return a different value. |
|
701 // See DatabaseConnection::defaultOptions() for a description of each |
|
702 // value. |
|
703 switch ($options['return']) { |
|
704 case Database::RETURN_STATEMENT: |
|
705 return $stmt; |
|
706 case Database::RETURN_AFFECTED: |
|
707 return $stmt->rowCount(); |
|
708 case Database::RETURN_INSERT_ID: |
|
709 return $this->lastInsertId(); |
|
710 case Database::RETURN_NULL: |
|
711 return; |
|
712 default: |
|
713 throw new PDOException('Invalid return directive: ' . $options['return']); |
|
714 } |
|
715 } |
|
716 catch (PDOException $e) { |
|
717 if ($options['throw_exception']) { |
|
718 // Add additional debug information. |
|
719 if ($query instanceof DatabaseStatementInterface) { |
|
720 $e->query_string = $stmt->getQueryString(); |
|
721 } |
|
722 else { |
|
723 $e->query_string = $query; |
|
724 } |
|
725 $e->args = $args; |
|
726 throw $e; |
|
727 } |
|
728 return NULL; |
|
729 } |
|
730 } |
|
731 |
|
732 /** |
|
733 * Expands out shorthand placeholders. |
|
734 * |
|
735 * Drupal supports an alternate syntax for doing arrays of values. We |
|
736 * therefore need to expand them out into a full, executable query string. |
|
737 * |
|
738 * @param $query |
|
739 * The query string to modify. |
|
740 * @param $args |
|
741 * The arguments for the query. |
|
742 * |
|
743 * @return |
|
744 * TRUE if the query was modified, FALSE otherwise. |
|
745 */ |
|
746 protected function expandArguments(&$query, &$args) { |
|
747 $modified = FALSE; |
|
748 |
|
749 // If the placeholder value to insert is an array, assume that we need |
|
750 // to expand it out into a comma-delimited set of placeholders. |
|
751 foreach (array_filter($args, 'is_array') as $key => $data) { |
|
752 $new_keys = array(); |
|
753 foreach (array_values($data) as $i => $value) { |
|
754 // This assumes that there are no other placeholders that use the same |
|
755 // name. For example, if the array placeholder is defined as :example |
|
756 // and there is already an :example_2 placeholder, this will generate |
|
757 // a duplicate key. We do not account for that as the calling code |
|
758 // is already broken if that happens. |
|
759 $new_keys[$key . '_' . $i] = $value; |
|
760 } |
|
761 |
|
762 // Update the query with the new placeholders. |
|
763 // preg_replace is necessary to ensure the replacement does not affect |
|
764 // placeholders that start with the same exact text. For example, if the |
|
765 // query contains the placeholders :foo and :foobar, and :foo has an |
|
766 // array of values, using str_replace would affect both placeholders, |
|
767 // but using the following preg_replace would only affect :foo because |
|
768 // it is followed by a non-word character. |
|
769 $query = preg_replace('#' . $key . '\b#', implode(', ', array_keys($new_keys)), $query); |
|
770 |
|
771 // Update the args array with the new placeholders. |
|
772 unset($args[$key]); |
|
773 $args += $new_keys; |
|
774 |
|
775 $modified = TRUE; |
|
776 } |
|
777 |
|
778 return $modified; |
|
779 } |
|
780 |
|
781 /** |
|
782 * Gets the driver-specific override class if any for the specified class. |
|
783 * |
|
784 * @param string $class |
|
785 * The class for which we want the potentially driver-specific class. |
|
786 * @param array $files |
|
787 * The name of the files in which the driver-specific class can be. |
|
788 * @param $use_autoload |
|
789 * If TRUE, attempt to load classes using PHP's autoload capability |
|
790 * as well as the manual approach here. |
|
791 * @return string |
|
792 * The name of the class that should be used for this driver. |
|
793 */ |
|
794 public function getDriverClass($class, array $files = array(), $use_autoload = FALSE) { |
|
795 if (empty($this->driverClasses[$class])) { |
|
796 $driver = $this->driver(); |
|
797 $this->driverClasses[$class] = $class . '_' . $driver; |
|
798 Database::loadDriverFile($driver, $files); |
|
799 if (!class_exists($this->driverClasses[$class], $use_autoload)) { |
|
800 $this->driverClasses[$class] = $class; |
|
801 } |
|
802 } |
|
803 return $this->driverClasses[$class]; |
|
804 } |
|
805 |
|
806 /** |
|
807 * Prepares and returns a SELECT query object. |
|
808 * |
|
809 * @param $table |
|
810 * The base table for this query, that is, the first table in the FROM |
|
811 * clause. This table will also be used as the "base" table for query_alter |
|
812 * hook implementations. |
|
813 * @param $alias |
|
814 * The alias of the base table of this query. |
|
815 * @param $options |
|
816 * An array of options on the query. |
|
817 * |
|
818 * @return SelectQueryInterface |
|
819 * An appropriate SelectQuery object for this database connection. Note that |
|
820 * it may be a driver-specific subclass of SelectQuery, depending on the |
|
821 * driver. |
|
822 * |
|
823 * @see SelectQuery |
|
824 */ |
|
825 public function select($table, $alias = NULL, array $options = array()) { |
|
826 $class = $this->getDriverClass('SelectQuery', array('query.inc', 'select.inc')); |
|
827 return new $class($table, $alias, $this, $options); |
|
828 } |
|
829 |
|
830 /** |
|
831 * Prepares and returns an INSERT query object. |
|
832 * |
|
833 * @param $options |
|
834 * An array of options on the query. |
|
835 * |
|
836 * @return InsertQuery |
|
837 * A new InsertQuery object. |
|
838 * |
|
839 * @see InsertQuery |
|
840 */ |
|
841 public function insert($table, array $options = array()) { |
|
842 $class = $this->getDriverClass('InsertQuery', array('query.inc')); |
|
843 return new $class($this, $table, $options); |
|
844 } |
|
845 |
|
846 /** |
|
847 * Prepares and returns a MERGE query object. |
|
848 * |
|
849 * @param $options |
|
850 * An array of options on the query. |
|
851 * |
|
852 * @return MergeQuery |
|
853 * A new MergeQuery object. |
|
854 * |
|
855 * @see MergeQuery |
|
856 */ |
|
857 public function merge($table, array $options = array()) { |
|
858 $class = $this->getDriverClass('MergeQuery', array('query.inc')); |
|
859 return new $class($this, $table, $options); |
|
860 } |
|
861 |
|
862 |
|
863 /** |
|
864 * Prepares and returns an UPDATE query object. |
|
865 * |
|
866 * @param $options |
|
867 * An array of options on the query. |
|
868 * |
|
869 * @return UpdateQuery |
|
870 * A new UpdateQuery object. |
|
871 * |
|
872 * @see UpdateQuery |
|
873 */ |
|
874 public function update($table, array $options = array()) { |
|
875 $class = $this->getDriverClass('UpdateQuery', array('query.inc')); |
|
876 return new $class($this, $table, $options); |
|
877 } |
|
878 |
|
879 /** |
|
880 * Prepares and returns a DELETE query object. |
|
881 * |
|
882 * @param $options |
|
883 * An array of options on the query. |
|
884 * |
|
885 * @return DeleteQuery |
|
886 * A new DeleteQuery object. |
|
887 * |
|
888 * @see DeleteQuery |
|
889 */ |
|
890 public function delete($table, array $options = array()) { |
|
891 $class = $this->getDriverClass('DeleteQuery', array('query.inc')); |
|
892 return new $class($this, $table, $options); |
|
893 } |
|
894 |
|
895 /** |
|
896 * Prepares and returns a TRUNCATE query object. |
|
897 * |
|
898 * @param $options |
|
899 * An array of options on the query. |
|
900 * |
|
901 * @return TruncateQuery |
|
902 * A new TruncateQuery object. |
|
903 * |
|
904 * @see TruncateQuery |
|
905 */ |
|
906 public function truncate($table, array $options = array()) { |
|
907 $class = $this->getDriverClass('TruncateQuery', array('query.inc')); |
|
908 return new $class($this, $table, $options); |
|
909 } |
|
910 |
|
911 /** |
|
912 * Returns a DatabaseSchema object for manipulating the schema. |
|
913 * |
|
914 * This method will lazy-load the appropriate schema library file. |
|
915 * |
|
916 * @return DatabaseSchema |
|
917 * The DatabaseSchema object for this connection. |
|
918 */ |
|
919 public function schema() { |
|
920 if (empty($this->schema)) { |
|
921 $class = $this->getDriverClass('DatabaseSchema', array('schema.inc')); |
|
922 if (class_exists($class)) { |
|
923 $this->schema = new $class($this); |
|
924 } |
|
925 } |
|
926 return $this->schema; |
|
927 } |
|
928 |
|
929 /** |
|
930 * Escapes a table name string. |
|
931 * |
|
932 * Force all table names to be strictly alphanumeric-plus-underscore. |
|
933 * For some database drivers, it may also wrap the table name in |
|
934 * database-specific escape characters. |
|
935 * |
|
936 * @return string |
|
937 * The sanitized table name string. |
|
938 */ |
|
939 public function escapeTable($table) { |
|
940 if (!isset($this->escapedNames[$table])) { |
|
941 $this->escapedNames[$table] = preg_replace('/[^A-Za-z0-9_.]+/', '', $table); |
|
942 } |
|
943 return $this->escapedNames[$table]; |
|
944 } |
|
945 |
|
946 /** |
|
947 * Escapes a field name string. |
|
948 * |
|
949 * Force all field names to be strictly alphanumeric-plus-underscore. |
|
950 * For some database drivers, it may also wrap the field name in |
|
951 * database-specific escape characters. |
|
952 * |
|
953 * @return string |
|
954 * The sanitized field name string. |
|
955 */ |
|
956 public function escapeField($field) { |
|
957 if (!isset($this->escapedNames[$field])) { |
|
958 $this->escapedNames[$field] = preg_replace('/[^A-Za-z0-9_.]+/', '', $field); |
|
959 } |
|
960 return $this->escapedNames[$field]; |
|
961 } |
|
962 |
|
963 /** |
|
964 * Escapes an alias name string. |
|
965 * |
|
966 * Force all alias names to be strictly alphanumeric-plus-underscore. In |
|
967 * contrast to DatabaseConnection::escapeField() / |
|
968 * DatabaseConnection::escapeTable(), this doesn't allow the period (".") |
|
969 * because that is not allowed in aliases. |
|
970 * |
|
971 * @return string |
|
972 * The sanitized field name string. |
|
973 */ |
|
974 public function escapeAlias($field) { |
|
975 if (!isset($this->escapedAliases[$field])) { |
|
976 $this->escapedAliases[$field] = preg_replace('/[^A-Za-z0-9_]+/', '', $field); |
|
977 } |
|
978 return $this->escapedAliases[$field]; |
|
979 } |
|
980 |
|
981 /** |
|
982 * Escapes characters that work as wildcard characters in a LIKE pattern. |
|
983 * |
|
984 * The wildcard characters "%" and "_" as well as backslash are prefixed with |
|
985 * a backslash. Use this to do a search for a verbatim string without any |
|
986 * wildcard behavior. |
|
987 * |
|
988 * For example, the following does a case-insensitive query for all rows whose |
|
989 * name starts with $prefix: |
|
990 * @code |
|
991 * $result = db_query( |
|
992 * 'SELECT * FROM person WHERE name LIKE :pattern', |
|
993 * array(':pattern' => db_like($prefix) . '%') |
|
994 * ); |
|
995 * @endcode |
|
996 * |
|
997 * Backslash is defined as escape character for LIKE patterns in |
|
998 * DatabaseCondition::mapConditionOperator(). |
|
999 * |
|
1000 * @param $string |
|
1001 * The string to escape. |
|
1002 * |
|
1003 * @return |
|
1004 * The escaped string. |
|
1005 */ |
|
1006 public function escapeLike($string) { |
|
1007 return addcslashes($string, '\%_'); |
|
1008 } |
|
1009 |
|
1010 /** |
|
1011 * Determines if there is an active transaction open. |
|
1012 * |
|
1013 * @return |
|
1014 * TRUE if we're currently in a transaction, FALSE otherwise. |
|
1015 */ |
|
1016 public function inTransaction() { |
|
1017 return ($this->transactionDepth() > 0); |
|
1018 } |
|
1019 |
|
1020 /** |
|
1021 * Determines current transaction depth. |
|
1022 */ |
|
1023 public function transactionDepth() { |
|
1024 return count($this->transactionLayers); |
|
1025 } |
|
1026 |
|
1027 /** |
|
1028 * Returns a new DatabaseTransaction object on this connection. |
|
1029 * |
|
1030 * @param $name |
|
1031 * Optional name of the savepoint. |
|
1032 * |
|
1033 * @return DatabaseTransaction |
|
1034 * A DatabaseTransaction object. |
|
1035 * |
|
1036 * @see DatabaseTransaction |
|
1037 */ |
|
1038 public function startTransaction($name = '') { |
|
1039 $class = $this->getDriverClass('DatabaseTransaction'); |
|
1040 return new $class($this, $name); |
|
1041 } |
|
1042 |
|
1043 /** |
|
1044 * Rolls back the transaction entirely or to a named savepoint. |
|
1045 * |
|
1046 * This method throws an exception if no transaction is active. |
|
1047 * |
|
1048 * @param $savepoint_name |
|
1049 * The name of the savepoint. The default, 'drupal_transaction', will roll |
|
1050 * the entire transaction back. |
|
1051 * |
|
1052 * @throws DatabaseTransactionNoActiveException |
|
1053 * |
|
1054 * @see DatabaseTransaction::rollback() |
|
1055 */ |
|
1056 public function rollback($savepoint_name = 'drupal_transaction') { |
|
1057 if (!$this->supportsTransactions()) { |
|
1058 return; |
|
1059 } |
|
1060 if (!$this->inTransaction()) { |
|
1061 throw new DatabaseTransactionNoActiveException(); |
|
1062 } |
|
1063 // A previous rollback to an earlier savepoint may mean that the savepoint |
|
1064 // in question has already been accidentally committed. |
|
1065 if (!isset($this->transactionLayers[$savepoint_name])) { |
|
1066 throw new DatabaseTransactionNoActiveException(); |
|
1067 } |
|
1068 |
|
1069 // We need to find the point we're rolling back to, all other savepoints |
|
1070 // before are no longer needed. If we rolled back other active savepoints, |
|
1071 // we need to throw an exception. |
|
1072 $rolled_back_other_active_savepoints = FALSE; |
|
1073 while ($savepoint = array_pop($this->transactionLayers)) { |
|
1074 if ($savepoint == $savepoint_name) { |
|
1075 // If it is the last the transaction in the stack, then it is not a |
|
1076 // savepoint, it is the transaction itself so we will need to roll back |
|
1077 // the transaction rather than a savepoint. |
|
1078 if (empty($this->transactionLayers)) { |
|
1079 break; |
|
1080 } |
|
1081 $this->query('ROLLBACK TO SAVEPOINT ' . $savepoint); |
|
1082 $this->popCommittableTransactions(); |
|
1083 if ($rolled_back_other_active_savepoints) { |
|
1084 throw new DatabaseTransactionOutOfOrderException(); |
|
1085 } |
|
1086 return; |
|
1087 } |
|
1088 else { |
|
1089 $rolled_back_other_active_savepoints = TRUE; |
|
1090 } |
|
1091 } |
|
1092 parent::rollBack(); |
|
1093 if ($rolled_back_other_active_savepoints) { |
|
1094 throw new DatabaseTransactionOutOfOrderException(); |
|
1095 } |
|
1096 } |
|
1097 |
|
1098 /** |
|
1099 * Increases the depth of transaction nesting. |
|
1100 * |
|
1101 * If no transaction is already active, we begin a new transaction. |
|
1102 * |
|
1103 * @throws DatabaseTransactionNameNonUniqueException |
|
1104 * |
|
1105 * @see DatabaseTransaction |
|
1106 */ |
|
1107 public function pushTransaction($name) { |
|
1108 if (!$this->supportsTransactions()) { |
|
1109 return; |
|
1110 } |
|
1111 if (isset($this->transactionLayers[$name])) { |
|
1112 throw new DatabaseTransactionNameNonUniqueException($name . " is already in use."); |
|
1113 } |
|
1114 // If we're already in a transaction then we want to create a savepoint |
|
1115 // rather than try to create another transaction. |
|
1116 if ($this->inTransaction()) { |
|
1117 $this->query('SAVEPOINT ' . $name); |
|
1118 } |
|
1119 else { |
|
1120 parent::beginTransaction(); |
|
1121 } |
|
1122 $this->transactionLayers[$name] = $name; |
|
1123 } |
|
1124 |
|
1125 /** |
|
1126 * Decreases the depth of transaction nesting. |
|
1127 * |
|
1128 * If we pop off the last transaction layer, then we either commit or roll |
|
1129 * back the transaction as necessary. If no transaction is active, we return |
|
1130 * because the transaction may have manually been rolled back. |
|
1131 * |
|
1132 * @param $name |
|
1133 * The name of the savepoint |
|
1134 * |
|
1135 * @throws DatabaseTransactionNoActiveException |
|
1136 * @throws DatabaseTransactionCommitFailedException |
|
1137 * |
|
1138 * @see DatabaseTransaction |
|
1139 */ |
|
1140 public function popTransaction($name) { |
|
1141 if (!$this->supportsTransactions()) { |
|
1142 return; |
|
1143 } |
|
1144 // The transaction has already been committed earlier. There is nothing we |
|
1145 // need to do. If this transaction was part of an earlier out-of-order |
|
1146 // rollback, an exception would already have been thrown by |
|
1147 // Database::rollback(). |
|
1148 if (!isset($this->transactionLayers[$name])) { |
|
1149 return; |
|
1150 } |
|
1151 |
|
1152 // Mark this layer as committable. |
|
1153 $this->transactionLayers[$name] = FALSE; |
|
1154 $this->popCommittableTransactions(); |
|
1155 } |
|
1156 |
|
1157 /** |
|
1158 * Internal function: commit all the transaction layers that can commit. |
|
1159 */ |
|
1160 protected function popCommittableTransactions() { |
|
1161 // Commit all the committable layers. |
|
1162 foreach (array_reverse($this->transactionLayers) as $name => $active) { |
|
1163 // Stop once we found an active transaction. |
|
1164 if ($active) { |
|
1165 break; |
|
1166 } |
|
1167 |
|
1168 // If there are no more layers left then we should commit. |
|
1169 unset($this->transactionLayers[$name]); |
|
1170 if (empty($this->transactionLayers)) { |
|
1171 if (!parent::commit()) { |
|
1172 throw new DatabaseTransactionCommitFailedException(); |
|
1173 } |
|
1174 } |
|
1175 else { |
|
1176 $this->query('RELEASE SAVEPOINT ' . $name); |
|
1177 } |
|
1178 } |
|
1179 } |
|
1180 |
|
1181 /** |
|
1182 * Runs a limited-range query on this database object. |
|
1183 * |
|
1184 * Use this as a substitute for ->query() when a subset of the query is to be |
|
1185 * returned. User-supplied arguments to the query should be passed in as |
|
1186 * separate parameters so that they can be properly escaped to avoid SQL |
|
1187 * injection attacks. |
|
1188 * |
|
1189 * @param $query |
|
1190 * A string containing an SQL query. |
|
1191 * @param $args |
|
1192 * An array of values to substitute into the query at placeholder markers. |
|
1193 * @param $from |
|
1194 * The first result row to return. |
|
1195 * @param $count |
|
1196 * The maximum number of result rows to return. |
|
1197 * @param $options |
|
1198 * An array of options on the query. |
|
1199 * |
|
1200 * @return DatabaseStatementInterface |
|
1201 * A database query result resource, or NULL if the query was not executed |
|
1202 * correctly. |
|
1203 */ |
|
1204 abstract public function queryRange($query, $from, $count, array $args = array(), array $options = array()); |
|
1205 |
|
1206 /** |
|
1207 * Generates a temporary table name. |
|
1208 * |
|
1209 * @return |
|
1210 * A table name. |
|
1211 */ |
|
1212 protected function generateTemporaryTableName() { |
|
1213 return "db_temporary_" . $this->temporaryNameIndex++; |
|
1214 } |
|
1215 |
|
1216 /** |
|
1217 * Runs a SELECT query and stores its results in a temporary table. |
|
1218 * |
|
1219 * Use this as a substitute for ->query() when the results need to stored |
|
1220 * in a temporary table. Temporary tables exist for the duration of the page |
|
1221 * request. User-supplied arguments to the query should be passed in as |
|
1222 * separate parameters so that they can be properly escaped to avoid SQL |
|
1223 * injection attacks. |
|
1224 * |
|
1225 * Note that if you need to know how many results were returned, you should do |
|
1226 * a SELECT COUNT(*) on the temporary table afterwards. |
|
1227 * |
|
1228 * @param $query |
|
1229 * A string containing a normal SELECT SQL query. |
|
1230 * @param $args |
|
1231 * An array of values to substitute into the query at placeholder markers. |
|
1232 * @param $options |
|
1233 * An associative array of options to control how the query is run. See |
|
1234 * the documentation for DatabaseConnection::defaultOptions() for details. |
|
1235 * |
|
1236 * @return |
|
1237 * The name of the temporary table. |
|
1238 */ |
|
1239 abstract function queryTemporary($query, array $args = array(), array $options = array()); |
|
1240 |
|
1241 /** |
|
1242 * Returns the type of database driver. |
|
1243 * |
|
1244 * This is not necessarily the same as the type of the database itself. For |
|
1245 * instance, there could be two MySQL drivers, mysql and mysql_mock. This |
|
1246 * function would return different values for each, but both would return |
|
1247 * "mysql" for databaseType(). |
|
1248 */ |
|
1249 abstract public function driver(); |
|
1250 |
|
1251 /** |
|
1252 * Returns the version of the database server. |
|
1253 */ |
|
1254 public function version() { |
|
1255 return $this->getAttribute(PDO::ATTR_SERVER_VERSION); |
|
1256 } |
|
1257 |
|
1258 /** |
|
1259 * Determines if this driver supports transactions. |
|
1260 * |
|
1261 * @return |
|
1262 * TRUE if this connection supports transactions, FALSE otherwise. |
|
1263 */ |
|
1264 public function supportsTransactions() { |
|
1265 return $this->transactionSupport; |
|
1266 } |
|
1267 |
|
1268 /** |
|
1269 * Determines if this driver supports transactional DDL. |
|
1270 * |
|
1271 * DDL queries are those that change the schema, such as ALTER queries. |
|
1272 * |
|
1273 * @return |
|
1274 * TRUE if this connection supports transactions for DDL queries, FALSE |
|
1275 * otherwise. |
|
1276 */ |
|
1277 public function supportsTransactionalDDL() { |
|
1278 return $this->transactionalDDLSupport; |
|
1279 } |
|
1280 |
|
1281 /** |
|
1282 * Returns the name of the PDO driver for this connection. |
|
1283 */ |
|
1284 abstract public function databaseType(); |
|
1285 |
|
1286 |
|
1287 /** |
|
1288 * Gets any special processing requirements for the condition operator. |
|
1289 * |
|
1290 * Some condition types require special processing, such as IN, because |
|
1291 * the value data they pass in is not a simple value. This is a simple |
|
1292 * overridable lookup function. Database connections should define only |
|
1293 * those operators they wish to be handled differently than the default. |
|
1294 * |
|
1295 * @param $operator |
|
1296 * The condition operator, such as "IN", "BETWEEN", etc. Case-sensitive. |
|
1297 * |
|
1298 * @return |
|
1299 * The extra handling directives for the specified operator, or NULL. |
|
1300 * |
|
1301 * @see DatabaseCondition::compile() |
|
1302 */ |
|
1303 abstract public function mapConditionOperator($operator); |
|
1304 |
|
1305 /** |
|
1306 * Throws an exception to deny direct access to transaction commits. |
|
1307 * |
|
1308 * We do not want to allow users to commit transactions at any time, only |
|
1309 * by destroying the transaction object or allowing it to go out of scope. |
|
1310 * A direct commit bypasses all of the safety checks we've built on top of |
|
1311 * PDO's transaction routines. |
|
1312 * |
|
1313 * @throws DatabaseTransactionExplicitCommitNotAllowedException |
|
1314 * |
|
1315 * @see DatabaseTransaction |
|
1316 */ |
|
1317 public function commit() { |
|
1318 throw new DatabaseTransactionExplicitCommitNotAllowedException(); |
|
1319 } |
|
1320 |
|
1321 /** |
|
1322 * Retrieves an unique id from a given sequence. |
|
1323 * |
|
1324 * Use this function if for some reason you can't use a serial field. For |
|
1325 * example, MySQL has no ways of reading of the current value of a sequence |
|
1326 * and PostgreSQL can not advance the sequence to be larger than a given |
|
1327 * value. Or sometimes you just need a unique integer. |
|
1328 * |
|
1329 * @param $existing_id |
|
1330 * After a database import, it might be that the sequences table is behind, |
|
1331 * so by passing in the maximum existing id, it can be assured that we |
|
1332 * never issue the same id. |
|
1333 * |
|
1334 * @return |
|
1335 * An integer number larger than any number returned by earlier calls and |
|
1336 * also larger than the $existing_id if one was passed in. |
|
1337 */ |
|
1338 abstract public function nextId($existing_id = 0); |
|
1339 |
|
1340 /** |
|
1341 * Checks whether utf8mb4 support is configurable in settings.php. |
|
1342 * |
|
1343 * @return bool |
|
1344 */ |
|
1345 public function utf8mb4IsConfigurable() { |
|
1346 // Since 4 byte UTF-8 is not supported by default, there is nothing to |
|
1347 // configure. |
|
1348 return FALSE; |
|
1349 } |
|
1350 |
|
1351 /** |
|
1352 * Checks whether utf8mb4 support is currently active. |
|
1353 * |
|
1354 * @return bool |
|
1355 */ |
|
1356 public function utf8mb4IsActive() { |
|
1357 // Since 4 byte UTF-8 is not supported by default, there is nothing to |
|
1358 // activate. |
|
1359 return FALSE; |
|
1360 } |
|
1361 |
|
1362 /** |
|
1363 * Checks whether utf8mb4 support is available on the current database system. |
|
1364 * |
|
1365 * @return bool |
|
1366 */ |
|
1367 public function utf8mb4IsSupported() { |
|
1368 // By default we assume that the database backend may not support 4 byte |
|
1369 // UTF-8. |
|
1370 return FALSE; |
|
1371 } |
|
1372 } |
|
1373 |
|
1374 /** |
|
1375 * Primary front-controller for the database system. |
|
1376 * |
|
1377 * This class is uninstantiatable and un-extendable. It acts to encapsulate |
|
1378 * all control and shepherding of database connections into a single location |
|
1379 * without the use of globals. |
|
1380 */ |
|
1381 abstract class Database { |
|
1382 |
|
1383 /** |
|
1384 * Flag to indicate a query call should simply return NULL. |
|
1385 * |
|
1386 * This is used for queries that have no reasonable return value anyway, such |
|
1387 * as INSERT statements to a table without a serial primary key. |
|
1388 */ |
|
1389 const RETURN_NULL = 0; |
|
1390 |
|
1391 /** |
|
1392 * Flag to indicate a query call should return the prepared statement. |
|
1393 */ |
|
1394 const RETURN_STATEMENT = 1; |
|
1395 |
|
1396 /** |
|
1397 * Flag to indicate a query call should return the number of affected rows. |
|
1398 */ |
|
1399 const RETURN_AFFECTED = 2; |
|
1400 |
|
1401 /** |
|
1402 * Flag to indicate a query call should return the "last insert id". |
|
1403 */ |
|
1404 const RETURN_INSERT_ID = 3; |
|
1405 |
|
1406 /** |
|
1407 * An nested array of all active connections. It is keyed by database name |
|
1408 * and target. |
|
1409 * |
|
1410 * @var array |
|
1411 */ |
|
1412 static protected $connections = array(); |
|
1413 |
|
1414 /** |
|
1415 * A processed copy of the database connection information from settings.php. |
|
1416 * |
|
1417 * @var array |
|
1418 */ |
|
1419 static protected $databaseInfo = NULL; |
|
1420 |
|
1421 /** |
|
1422 * A list of key/target credentials to simply ignore. |
|
1423 * |
|
1424 * @var array |
|
1425 */ |
|
1426 static protected $ignoreTargets = array(); |
|
1427 |
|
1428 /** |
|
1429 * The key of the currently active database connection. |
|
1430 * |
|
1431 * @var string |
|
1432 */ |
|
1433 static protected $activeKey = 'default'; |
|
1434 |
|
1435 /** |
|
1436 * An array of active query log objects. |
|
1437 * |
|
1438 * Every connection has one and only one logger object for all targets and |
|
1439 * logging keys. |
|
1440 * |
|
1441 * array( |
|
1442 * '$db_key' => DatabaseLog object. |
|
1443 * ); |
|
1444 * |
|
1445 * @var array |
|
1446 */ |
|
1447 static protected $logs = array(); |
|
1448 |
|
1449 /** |
|
1450 * Starts logging a given logging key on the specified connection. |
|
1451 * |
|
1452 * @param $logging_key |
|
1453 * The logging key to log. |
|
1454 * @param $key |
|
1455 * The database connection key for which we want to log. |
|
1456 * |
|
1457 * @return DatabaseLog |
|
1458 * The query log object. Note that the log object does support richer |
|
1459 * methods than the few exposed through the Database class, so in some |
|
1460 * cases it may be desirable to access it directly. |
|
1461 * |
|
1462 * @see DatabaseLog |
|
1463 */ |
|
1464 final public static function startLog($logging_key, $key = 'default') { |
|
1465 if (empty(self::$logs[$key])) { |
|
1466 self::$logs[$key] = new DatabaseLog($key); |
|
1467 |
|
1468 // Every target already active for this connection key needs to have the |
|
1469 // logging object associated with it. |
|
1470 if (!empty(self::$connections[$key])) { |
|
1471 foreach (self::$connections[$key] as $connection) { |
|
1472 $connection->setLogger(self::$logs[$key]); |
|
1473 } |
|
1474 } |
|
1475 } |
|
1476 |
|
1477 self::$logs[$key]->start($logging_key); |
|
1478 return self::$logs[$key]; |
|
1479 } |
|
1480 |
|
1481 /** |
|
1482 * Retrieves the queries logged on for given logging key. |
|
1483 * |
|
1484 * This method also ends logging for the specified key. To get the query log |
|
1485 * to date without ending the logger request the logging object by starting |
|
1486 * it again (which does nothing to an open log key) and call methods on it as |
|
1487 * desired. |
|
1488 * |
|
1489 * @param $logging_key |
|
1490 * The logging key to log. |
|
1491 * @param $key |
|
1492 * The database connection key for which we want to log. |
|
1493 * |
|
1494 * @return array |
|
1495 * The query log for the specified logging key and connection. |
|
1496 * |
|
1497 * @see DatabaseLog |
|
1498 */ |
|
1499 final public static function getLog($logging_key, $key = 'default') { |
|
1500 if (empty(self::$logs[$key])) { |
|
1501 return NULL; |
|
1502 } |
|
1503 $queries = self::$logs[$key]->get($logging_key); |
|
1504 self::$logs[$key]->end($logging_key); |
|
1505 return $queries; |
|
1506 } |
|
1507 |
|
1508 /** |
|
1509 * Gets the connection object for the specified database key and target. |
|
1510 * |
|
1511 * @param $target |
|
1512 * The database target name. |
|
1513 * @param $key |
|
1514 * The database connection key. Defaults to NULL which means the active key. |
|
1515 * |
|
1516 * @return DatabaseConnection |
|
1517 * The corresponding connection object. |
|
1518 */ |
|
1519 final public static function getConnection($target = 'default', $key = NULL) { |
|
1520 if (!isset($key)) { |
|
1521 // By default, we want the active connection, set in setActiveConnection. |
|
1522 $key = self::$activeKey; |
|
1523 } |
|
1524 // If the requested target does not exist, or if it is ignored, we fall back |
|
1525 // to the default target. The target is typically either "default" or |
|
1526 // "slave", indicating to use a slave SQL server if one is available. If |
|
1527 // it's not available, then the default/master server is the correct server |
|
1528 // to use. |
|
1529 if (!empty(self::$ignoreTargets[$key][$target]) || !isset(self::$databaseInfo[$key][$target])) { |
|
1530 $target = 'default'; |
|
1531 } |
|
1532 |
|
1533 if (!isset(self::$connections[$key][$target])) { |
|
1534 // If necessary, a new connection is opened. |
|
1535 self::$connections[$key][$target] = self::openConnection($key, $target); |
|
1536 } |
|
1537 return self::$connections[$key][$target]; |
|
1538 } |
|
1539 |
|
1540 /** |
|
1541 * Determines if there is an active connection. |
|
1542 * |
|
1543 * Note that this method will return FALSE if no connection has been |
|
1544 * established yet, even if one could be. |
|
1545 * |
|
1546 * @return |
|
1547 * TRUE if there is at least one database connection established, FALSE |
|
1548 * otherwise. |
|
1549 */ |
|
1550 final public static function isActiveConnection() { |
|
1551 return !empty(self::$activeKey) && !empty(self::$connections) && !empty(self::$connections[self::$activeKey]); |
|
1552 } |
|
1553 |
|
1554 /** |
|
1555 * Sets the active connection to the specified key. |
|
1556 * |
|
1557 * @return |
|
1558 * The previous database connection key. |
|
1559 */ |
|
1560 final public static function setActiveConnection($key = 'default') { |
|
1561 if (empty(self::$databaseInfo)) { |
|
1562 self::parseConnectionInfo(); |
|
1563 } |
|
1564 |
|
1565 if (!empty(self::$databaseInfo[$key])) { |
|
1566 $old_key = self::$activeKey; |
|
1567 self::$activeKey = $key; |
|
1568 return $old_key; |
|
1569 } |
|
1570 } |
|
1571 |
|
1572 /** |
|
1573 * Process the configuration file for database information. |
|
1574 */ |
|
1575 final public static function parseConnectionInfo() { |
|
1576 global $databases; |
|
1577 |
|
1578 $database_info = is_array($databases) ? $databases : array(); |
|
1579 foreach ($database_info as $index => $info) { |
|
1580 foreach ($database_info[$index] as $target => $value) { |
|
1581 // If there is no "driver" property, then we assume it's an array of |
|
1582 // possible connections for this target. Pick one at random. That allows |
|
1583 // us to have, for example, multiple slave servers. |
|
1584 if (empty($value['driver'])) { |
|
1585 $database_info[$index][$target] = $database_info[$index][$target][mt_rand(0, count($database_info[$index][$target]) - 1)]; |
|
1586 } |
|
1587 |
|
1588 // Parse the prefix information. |
|
1589 if (!isset($database_info[$index][$target]['prefix'])) { |
|
1590 // Default to an empty prefix. |
|
1591 $database_info[$index][$target]['prefix'] = array( |
|
1592 'default' => '', |
|
1593 ); |
|
1594 } |
|
1595 elseif (!is_array($database_info[$index][$target]['prefix'])) { |
|
1596 // Transform the flat form into an array form. |
|
1597 $database_info[$index][$target]['prefix'] = array( |
|
1598 'default' => $database_info[$index][$target]['prefix'], |
|
1599 ); |
|
1600 } |
|
1601 } |
|
1602 } |
|
1603 |
|
1604 if (!is_array(self::$databaseInfo)) { |
|
1605 self::$databaseInfo = $database_info; |
|
1606 } |
|
1607 |
|
1608 // Merge the new $database_info into the existing. |
|
1609 // array_merge_recursive() cannot be used, as it would make multiple |
|
1610 // database, user, and password keys in the same database array. |
|
1611 else { |
|
1612 foreach ($database_info as $database_key => $database_values) { |
|
1613 foreach ($database_values as $target => $target_values) { |
|
1614 self::$databaseInfo[$database_key][$target] = $target_values; |
|
1615 } |
|
1616 } |
|
1617 } |
|
1618 } |
|
1619 |
|
1620 /** |
|
1621 * Adds database connection information for a given key/target. |
|
1622 * |
|
1623 * This method allows the addition of new connection credentials at runtime. |
|
1624 * Under normal circumstances the preferred way to specify database |
|
1625 * credentials is via settings.php. However, this method allows them to be |
|
1626 * added at arbitrary times, such as during unit tests, when connecting to |
|
1627 * admin-defined third party databases, etc. |
|
1628 * |
|
1629 * If the given key/target pair already exists, this method will be ignored. |
|
1630 * |
|
1631 * @param $key |
|
1632 * The database key. |
|
1633 * @param $target |
|
1634 * The database target name. |
|
1635 * @param $info |
|
1636 * The database connection information, as it would be defined in |
|
1637 * settings.php. Note that the structure of this array will depend on the |
|
1638 * database driver it is connecting to. |
|
1639 */ |
|
1640 public static function addConnectionInfo($key, $target, $info) { |
|
1641 if (empty(self::$databaseInfo[$key][$target])) { |
|
1642 self::$databaseInfo[$key][$target] = $info; |
|
1643 } |
|
1644 } |
|
1645 |
|
1646 /** |
|
1647 * Gets information on the specified database connection. |
|
1648 * |
|
1649 * @param $connection |
|
1650 * The connection key for which we want information. |
|
1651 */ |
|
1652 final public static function getConnectionInfo($key = 'default') { |
|
1653 if (empty(self::$databaseInfo)) { |
|
1654 self::parseConnectionInfo(); |
|
1655 } |
|
1656 |
|
1657 if (!empty(self::$databaseInfo[$key])) { |
|
1658 return self::$databaseInfo[$key]; |
|
1659 } |
|
1660 } |
|
1661 |
|
1662 /** |
|
1663 * Rename a connection and its corresponding connection information. |
|
1664 * |
|
1665 * @param $old_key |
|
1666 * The old connection key. |
|
1667 * @param $new_key |
|
1668 * The new connection key. |
|
1669 * @return |
|
1670 * TRUE in case of success, FALSE otherwise. |
|
1671 */ |
|
1672 final public static function renameConnection($old_key, $new_key) { |
|
1673 if (empty(self::$databaseInfo)) { |
|
1674 self::parseConnectionInfo(); |
|
1675 } |
|
1676 |
|
1677 if (!empty(self::$databaseInfo[$old_key]) && empty(self::$databaseInfo[$new_key])) { |
|
1678 // Migrate the database connection information. |
|
1679 self::$databaseInfo[$new_key] = self::$databaseInfo[$old_key]; |
|
1680 unset(self::$databaseInfo[$old_key]); |
|
1681 |
|
1682 // Migrate over the DatabaseConnection object if it exists. |
|
1683 if (isset(self::$connections[$old_key])) { |
|
1684 self::$connections[$new_key] = self::$connections[$old_key]; |
|
1685 unset(self::$connections[$old_key]); |
|
1686 } |
|
1687 |
|
1688 return TRUE; |
|
1689 } |
|
1690 else { |
|
1691 return FALSE; |
|
1692 } |
|
1693 } |
|
1694 |
|
1695 /** |
|
1696 * Remove a connection and its corresponding connection information. |
|
1697 * |
|
1698 * @param $key |
|
1699 * The connection key. |
|
1700 * @return |
|
1701 * TRUE in case of success, FALSE otherwise. |
|
1702 */ |
|
1703 final public static function removeConnection($key) { |
|
1704 if (isset(self::$databaseInfo[$key])) { |
|
1705 self::closeConnection(NULL, $key); |
|
1706 unset(self::$databaseInfo[$key]); |
|
1707 return TRUE; |
|
1708 } |
|
1709 else { |
|
1710 return FALSE; |
|
1711 } |
|
1712 } |
|
1713 |
|
1714 /** |
|
1715 * Opens a connection to the server specified by the given key and target. |
|
1716 * |
|
1717 * @param $key |
|
1718 * The database connection key, as specified in settings.php. The default is |
|
1719 * "default". |
|
1720 * @param $target |
|
1721 * The database target to open. |
|
1722 * |
|
1723 * @throws DatabaseConnectionNotDefinedException |
|
1724 * @throws DatabaseDriverNotSpecifiedException |
|
1725 */ |
|
1726 final protected static function openConnection($key, $target) { |
|
1727 if (empty(self::$databaseInfo)) { |
|
1728 self::parseConnectionInfo(); |
|
1729 } |
|
1730 |
|
1731 // If the requested database does not exist then it is an unrecoverable |
|
1732 // error. |
|
1733 if (!isset(self::$databaseInfo[$key])) { |
|
1734 throw new DatabaseConnectionNotDefinedException('The specified database connection is not defined: ' . $key); |
|
1735 } |
|
1736 |
|
1737 if (!$driver = self::$databaseInfo[$key][$target]['driver']) { |
|
1738 throw new DatabaseDriverNotSpecifiedException('Driver not specified for this database connection: ' . $key); |
|
1739 } |
|
1740 |
|
1741 // We cannot rely on the registry yet, because the registry requires an |
|
1742 // open database connection. |
|
1743 $driver_class = 'DatabaseConnection_' . $driver; |
|
1744 require_once DRUPAL_ROOT . '/includes/database/' . $driver . '/database.inc'; |
|
1745 $new_connection = new $driver_class(self::$databaseInfo[$key][$target]); |
|
1746 $new_connection->setTarget($target); |
|
1747 $new_connection->setKey($key); |
|
1748 |
|
1749 // If we have any active logging objects for this connection key, we need |
|
1750 // to associate them with the connection we just opened. |
|
1751 if (!empty(self::$logs[$key])) { |
|
1752 $new_connection->setLogger(self::$logs[$key]); |
|
1753 } |
|
1754 |
|
1755 return $new_connection; |
|
1756 } |
|
1757 |
|
1758 /** |
|
1759 * Closes a connection to the server specified by the given key and target. |
|
1760 * |
|
1761 * @param $target |
|
1762 * The database target name. Defaults to NULL meaning that all target |
|
1763 * connections will be closed. |
|
1764 * @param $key |
|
1765 * The database connection key. Defaults to NULL which means the active key. |
|
1766 */ |
|
1767 public static function closeConnection($target = NULL, $key = NULL) { |
|
1768 // Gets the active connection by default. |
|
1769 if (!isset($key)) { |
|
1770 $key = self::$activeKey; |
|
1771 } |
|
1772 // To close a connection, it needs to be set to NULL and removed from the |
|
1773 // static variable. In all cases, closeConnection() might be called for a |
|
1774 // connection that was not opened yet, in which case the key is not defined |
|
1775 // yet and we just ensure that the connection key is undefined. |
|
1776 if (isset($target)) { |
|
1777 if (isset(self::$connections[$key][$target])) { |
|
1778 self::$connections[$key][$target]->destroy(); |
|
1779 self::$connections[$key][$target] = NULL; |
|
1780 } |
|
1781 unset(self::$connections[$key][$target]); |
|
1782 } |
|
1783 else { |
|
1784 if (isset(self::$connections[$key])) { |
|
1785 foreach (self::$connections[$key] as $target => $connection) { |
|
1786 self::$connections[$key][$target]->destroy(); |
|
1787 self::$connections[$key][$target] = NULL; |
|
1788 } |
|
1789 } |
|
1790 unset(self::$connections[$key]); |
|
1791 } |
|
1792 } |
|
1793 |
|
1794 /** |
|
1795 * Instructs the system to temporarily ignore a given key/target. |
|
1796 * |
|
1797 * At times we need to temporarily disable slave queries. To do so, call this |
|
1798 * method with the database key and the target to disable. That database key |
|
1799 * will then always fall back to 'default' for that key, even if it's defined. |
|
1800 * |
|
1801 * @param $key |
|
1802 * The database connection key. |
|
1803 * @param $target |
|
1804 * The target of the specified key to ignore. |
|
1805 */ |
|
1806 public static function ignoreTarget($key, $target) { |
|
1807 self::$ignoreTargets[$key][$target] = TRUE; |
|
1808 } |
|
1809 |
|
1810 /** |
|
1811 * Load a file for the database that might hold a class. |
|
1812 * |
|
1813 * @param $driver |
|
1814 * The name of the driver. |
|
1815 * @param array $files |
|
1816 * The name of the files the driver specific class can be. |
|
1817 */ |
|
1818 public static function loadDriverFile($driver, array $files = array()) { |
|
1819 static $base_path; |
|
1820 |
|
1821 if (empty($base_path)) { |
|
1822 $base_path = dirname(realpath(__FILE__)); |
|
1823 } |
|
1824 |
|
1825 $driver_base_path = "$base_path/$driver"; |
|
1826 foreach ($files as $file) { |
|
1827 // Load the base file first so that classes extending base classes will |
|
1828 // have the base class loaded. |
|
1829 foreach (array("$base_path/$file", "$driver_base_path/$file") as $filename) { |
|
1830 // The OS caches file_exists() and PHP caches require_once(), so |
|
1831 // we'll let both of those take care of performance here. |
|
1832 if (file_exists($filename)) { |
|
1833 require_once $filename; |
|
1834 } |
|
1835 } |
|
1836 } |
|
1837 } |
|
1838 } |
|
1839 |
|
1840 /** |
|
1841 * Exception for when popTransaction() is called with no active transaction. |
|
1842 */ |
|
1843 class DatabaseTransactionNoActiveException extends Exception { } |
|
1844 |
|
1845 /** |
|
1846 * Exception thrown when a savepoint or transaction name occurs twice. |
|
1847 */ |
|
1848 class DatabaseTransactionNameNonUniqueException extends Exception { } |
|
1849 |
|
1850 /** |
|
1851 * Exception thrown when a commit() function fails. |
|
1852 */ |
|
1853 class DatabaseTransactionCommitFailedException extends Exception { } |
|
1854 |
|
1855 /** |
|
1856 * Exception to deny attempts to explicitly manage transactions. |
|
1857 * |
|
1858 * This exception will be thrown when the PDO connection commit() is called. |
|
1859 * Code should never call this method directly. |
|
1860 */ |
|
1861 class DatabaseTransactionExplicitCommitNotAllowedException extends Exception { } |
|
1862 |
|
1863 /** |
|
1864 * Exception thrown when a rollback() resulted in other active transactions being rolled-back. |
|
1865 */ |
|
1866 class DatabaseTransactionOutOfOrderException extends Exception { } |
|
1867 |
|
1868 /** |
|
1869 * Exception thrown for merge queries that do not make semantic sense. |
|
1870 * |
|
1871 * There are many ways that a merge query could be malformed. They should all |
|
1872 * throw this exception and set an appropriately descriptive message. |
|
1873 */ |
|
1874 class InvalidMergeQueryException extends Exception {} |
|
1875 |
|
1876 /** |
|
1877 * Exception thrown if an insert query specifies a field twice. |
|
1878 * |
|
1879 * It is not allowed to specify a field as default and insert field, this |
|
1880 * exception is thrown if that is the case. |
|
1881 */ |
|
1882 class FieldsOverlapException extends Exception {} |
|
1883 |
|
1884 /** |
|
1885 * Exception thrown if an insert query doesn't specify insert or default fields. |
|
1886 */ |
|
1887 class NoFieldsException extends Exception {} |
|
1888 |
|
1889 /** |
|
1890 * Exception thrown if an undefined database connection is requested. |
|
1891 */ |
|
1892 class DatabaseConnectionNotDefinedException extends Exception {} |
|
1893 |
|
1894 /** |
|
1895 * Exception thrown if no driver is specified for a database connection. |
|
1896 */ |
|
1897 class DatabaseDriverNotSpecifiedException extends Exception {} |
|
1898 |
|
1899 |
|
1900 /** |
|
1901 * A wrapper class for creating and managing database transactions. |
|
1902 * |
|
1903 * Not all databases or database configurations support transactions. For |
|
1904 * example, MySQL MyISAM tables do not. It is also easy to begin a transaction |
|
1905 * and then forget to commit it, which can lead to connection errors when |
|
1906 * another transaction is started. |
|
1907 * |
|
1908 * This class acts as a wrapper for transactions. To begin a transaction, |
|
1909 * simply instantiate it. When the object goes out of scope and is destroyed |
|
1910 * it will automatically commit. It also will check to see if the specified |
|
1911 * connection supports transactions. If not, it will simply skip any transaction |
|
1912 * commands, allowing user-space code to proceed normally. The only difference |
|
1913 * is that rollbacks won't actually do anything. |
|
1914 * |
|
1915 * In the vast majority of cases, you should not instantiate this class |
|
1916 * directly. Instead, call ->startTransaction(), from the appropriate connection |
|
1917 * object. |
|
1918 */ |
|
1919 class DatabaseTransaction { |
|
1920 |
|
1921 /** |
|
1922 * The connection object for this transaction. |
|
1923 * |
|
1924 * @var DatabaseConnection |
|
1925 */ |
|
1926 protected $connection; |
|
1927 |
|
1928 /** |
|
1929 * A boolean value to indicate whether this transaction has been rolled back. |
|
1930 * |
|
1931 * @var Boolean |
|
1932 */ |
|
1933 protected $rolledBack = FALSE; |
|
1934 |
|
1935 /** |
|
1936 * The name of the transaction. |
|
1937 * |
|
1938 * This is used to label the transaction savepoint. It will be overridden to |
|
1939 * 'drupal_transaction' if there is no transaction depth. |
|
1940 */ |
|
1941 protected $name; |
|
1942 |
|
1943 public function __construct(DatabaseConnection $connection, $name = NULL) { |
|
1944 $this->connection = $connection; |
|
1945 // If there is no transaction depth, then no transaction has started. Name |
|
1946 // the transaction 'drupal_transaction'. |
|
1947 if (!$depth = $connection->transactionDepth()) { |
|
1948 $this->name = 'drupal_transaction'; |
|
1949 } |
|
1950 // Within transactions, savepoints are used. Each savepoint requires a |
|
1951 // name. So if no name is present we need to create one. |
|
1952 elseif (!$name) { |
|
1953 $this->name = 'savepoint_' . $depth; |
|
1954 } |
|
1955 else { |
|
1956 $this->name = $name; |
|
1957 } |
|
1958 $this->connection->pushTransaction($this->name); |
|
1959 } |
|
1960 |
|
1961 public function __destruct() { |
|
1962 // If we rolled back then the transaction would have already been popped. |
|
1963 if (!$this->rolledBack) { |
|
1964 $this->connection->popTransaction($this->name); |
|
1965 } |
|
1966 } |
|
1967 |
|
1968 /** |
|
1969 * Retrieves the name of the transaction or savepoint. |
|
1970 */ |
|
1971 public function name() { |
|
1972 return $this->name; |
|
1973 } |
|
1974 |
|
1975 /** |
|
1976 * Rolls back the current transaction. |
|
1977 * |
|
1978 * This is just a wrapper method to rollback whatever transaction stack we are |
|
1979 * currently in, which is managed by the connection object itself. Note that |
|
1980 * logging (preferable with watchdog_exception()) needs to happen after a |
|
1981 * transaction has been rolled back or the log messages will be rolled back |
|
1982 * too. |
|
1983 * |
|
1984 * @see DatabaseConnection::rollback() |
|
1985 * @see watchdog_exception() |
|
1986 */ |
|
1987 public function rollback() { |
|
1988 $this->rolledBack = TRUE; |
|
1989 $this->connection->rollback($this->name); |
|
1990 } |
|
1991 } |
|
1992 |
|
1993 /** |
|
1994 * Represents a prepared statement. |
|
1995 * |
|
1996 * Some methods in that class are purposefully commented out. Due to a change in |
|
1997 * how PHP defines PDOStatement, we can't define a signature for those methods |
|
1998 * that will work the same way between versions older than 5.2.6 and later |
|
1999 * versions. See http://bugs.php.net/bug.php?id=42452 for more details. |
|
2000 * |
|
2001 * Child implementations should either extend PDOStatement: |
|
2002 * @code |
|
2003 * class DatabaseStatement_oracle extends PDOStatement implements DatabaseStatementInterface {} |
|
2004 * @endcode |
|
2005 * or define their own class. If defining their own class, they will also have |
|
2006 * to implement either the Iterator or IteratorAggregate interface before |
|
2007 * DatabaseStatementInterface: |
|
2008 * @code |
|
2009 * class DatabaseStatement_oracle implements Iterator, DatabaseStatementInterface {} |
|
2010 * @endcode |
|
2011 */ |
|
2012 interface DatabaseStatementInterface extends Traversable { |
|
2013 |
|
2014 /** |
|
2015 * Executes a prepared statement |
|
2016 * |
|
2017 * @param $args |
|
2018 * An array of values with as many elements as there are bound parameters in |
|
2019 * the SQL statement being executed. |
|
2020 * @param $options |
|
2021 * An array of options for this query. |
|
2022 * |
|
2023 * @return |
|
2024 * TRUE on success, or FALSE on failure. |
|
2025 */ |
|
2026 public function execute($args = array(), $options = array()); |
|
2027 |
|
2028 /** |
|
2029 * Gets the query string of this statement. |
|
2030 * |
|
2031 * @return |
|
2032 * The query string, in its form with placeholders. |
|
2033 */ |
|
2034 public function getQueryString(); |
|
2035 |
|
2036 /** |
|
2037 * Returns the number of rows affected by the last SQL statement. |
|
2038 * |
|
2039 * @return |
|
2040 * The number of rows affected by the last DELETE, INSERT, or UPDATE |
|
2041 * statement executed. |
|
2042 */ |
|
2043 public function rowCount(); |
|
2044 |
|
2045 /** |
|
2046 * Sets the default fetch mode for this statement. |
|
2047 * |
|
2048 * See http://php.net/manual/pdo.constants.php for the definition of the |
|
2049 * constants used. |
|
2050 * |
|
2051 * @param $mode |
|
2052 * One of the PDO::FETCH_* constants. |
|
2053 * @param $a1 |
|
2054 * An option depending of the fetch mode specified by $mode: |
|
2055 * - for PDO::FETCH_COLUMN, the index of the column to fetch |
|
2056 * - for PDO::FETCH_CLASS, the name of the class to create |
|
2057 * - for PDO::FETCH_INTO, the object to add the data to |
|
2058 * @param $a2 |
|
2059 * If $mode is PDO::FETCH_CLASS, the optional arguments to pass to the |
|
2060 * constructor. |
|
2061 */ |
|
2062 // public function setFetchMode($mode, $a1 = NULL, $a2 = array()); |
|
2063 |
|
2064 /** |
|
2065 * Fetches the next row from a result set. |
|
2066 * |
|
2067 * See http://php.net/manual/pdo.constants.php for the definition of the |
|
2068 * constants used. |
|
2069 * |
|
2070 * @param $mode |
|
2071 * One of the PDO::FETCH_* constants. |
|
2072 * Default to what was specified by setFetchMode(). |
|
2073 * @param $cursor_orientation |
|
2074 * Not implemented in all database drivers, don't use. |
|
2075 * @param $cursor_offset |
|
2076 * Not implemented in all database drivers, don't use. |
|
2077 * |
|
2078 * @return |
|
2079 * A result, formatted according to $mode. |
|
2080 */ |
|
2081 // public function fetch($mode = NULL, $cursor_orientation = NULL, $cursor_offset = NULL); |
|
2082 |
|
2083 /** |
|
2084 * Returns a single field from the next record of a result set. |
|
2085 * |
|
2086 * @param $index |
|
2087 * The numeric index of the field to return. Defaults to the first field. |
|
2088 * |
|
2089 * @return |
|
2090 * A single field from the next record, or FALSE if there is no next record. |
|
2091 */ |
|
2092 public function fetchField($index = 0); |
|
2093 |
|
2094 /** |
|
2095 * Fetches the next row and returns it as an object. |
|
2096 * |
|
2097 * The object will be of the class specified by DatabaseStatementInterface::setFetchMode() |
|
2098 * or stdClass if not specified. |
|
2099 */ |
|
2100 // public function fetchObject(); |
|
2101 |
|
2102 /** |
|
2103 * Fetches the next row and returns it as an associative array. |
|
2104 * |
|
2105 * This method corresponds to PDOStatement::fetchObject(), but for associative |
|
2106 * arrays. For some reason PDOStatement does not have a corresponding array |
|
2107 * helper method, so one is added. |
|
2108 * |
|
2109 * @return |
|
2110 * An associative array, or FALSE if there is no next row. |
|
2111 */ |
|
2112 public function fetchAssoc(); |
|
2113 |
|
2114 /** |
|
2115 * Returns an array containing all of the result set rows. |
|
2116 * |
|
2117 * @param $mode |
|
2118 * One of the PDO::FETCH_* constants. |
|
2119 * @param $column_index |
|
2120 * If $mode is PDO::FETCH_COLUMN, the index of the column to fetch. |
|
2121 * @param $constructor_arguments |
|
2122 * If $mode is PDO::FETCH_CLASS, the arguments to pass to the constructor. |
|
2123 * |
|
2124 * @return |
|
2125 * An array of results. |
|
2126 */ |
|
2127 // function fetchAll($mode = NULL, $column_index = NULL, array $constructor_arguments); |
|
2128 |
|
2129 /** |
|
2130 * Returns an entire single column of a result set as an indexed array. |
|
2131 * |
|
2132 * Note that this method will run the result set to the end. |
|
2133 * |
|
2134 * @param $index |
|
2135 * The index of the column number to fetch. |
|
2136 * |
|
2137 * @return |
|
2138 * An indexed array, or an empty array if there is no result set. |
|
2139 */ |
|
2140 public function fetchCol($index = 0); |
|
2141 |
|
2142 /** |
|
2143 * Returns the entire result set as a single associative array. |
|
2144 * |
|
2145 * This method is only useful for two-column result sets. It will return an |
|
2146 * associative array where the key is one column from the result set and the |
|
2147 * value is another field. In most cases, the default of the first two columns |
|
2148 * is appropriate. |
|
2149 * |
|
2150 * Note that this method will run the result set to the end. |
|
2151 * |
|
2152 * @param $key_index |
|
2153 * The numeric index of the field to use as the array key. |
|
2154 * @param $value_index |
|
2155 * The numeric index of the field to use as the array value. |
|
2156 * |
|
2157 * @return |
|
2158 * An associative array, or an empty array if there is no result set. |
|
2159 */ |
|
2160 public function fetchAllKeyed($key_index = 0, $value_index = 1); |
|
2161 |
|
2162 /** |
|
2163 * Returns the result set as an associative array keyed by the given field. |
|
2164 * |
|
2165 * If the given key appears multiple times, later records will overwrite |
|
2166 * earlier ones. |
|
2167 * |
|
2168 * @param $key |
|
2169 * The name of the field on which to index the array. |
|
2170 * @param $fetch |
|
2171 * The fetchmode to use. If set to PDO::FETCH_ASSOC, PDO::FETCH_NUM, or |
|
2172 * PDO::FETCH_BOTH the returned value with be an array of arrays. For any |
|
2173 * other value it will be an array of objects. By default, the fetch mode |
|
2174 * set for the query will be used. |
|
2175 * |
|
2176 * @return |
|
2177 * An associative array, or an empty array if there is no result set. |
|
2178 */ |
|
2179 public function fetchAllAssoc($key, $fetch = NULL); |
|
2180 } |
|
2181 |
|
2182 /** |
|
2183 * Default implementation of DatabaseStatementInterface. |
|
2184 * |
|
2185 * PDO allows us to extend the PDOStatement class to provide additional |
|
2186 * functionality beyond that offered by default. We do need extra |
|
2187 * functionality. By default, this class is not driver-specific. If a given |
|
2188 * driver needs to set a custom statement class, it may do so in its |
|
2189 * constructor. |
|
2190 * |
|
2191 * @see http://us.php.net/pdostatement |
|
2192 */ |
|
2193 class DatabaseStatementBase extends PDOStatement implements DatabaseStatementInterface { |
|
2194 |
|
2195 /** |
|
2196 * Reference to the database connection object for this statement. |
|
2197 * |
|
2198 * The name $dbh is inherited from PDOStatement. |
|
2199 * |
|
2200 * @var DatabaseConnection |
|
2201 */ |
|
2202 public $dbh; |
|
2203 |
|
2204 protected function __construct($dbh) { |
|
2205 $this->dbh = $dbh; |
|
2206 $this->setFetchMode(PDO::FETCH_OBJ); |
|
2207 } |
|
2208 |
|
2209 public function execute($args = array(), $options = array()) { |
|
2210 if (isset($options['fetch'])) { |
|
2211 if (is_string($options['fetch'])) { |
|
2212 // Default to an object. Note: db fields will be added to the object |
|
2213 // before the constructor is run. If you need to assign fields after |
|
2214 // the constructor is run, see http://drupal.org/node/315092. |
|
2215 $this->setFetchMode(PDO::FETCH_CLASS, $options['fetch']); |
|
2216 } |
|
2217 else { |
|
2218 $this->setFetchMode($options['fetch']); |
|
2219 } |
|
2220 } |
|
2221 |
|
2222 $logger = $this->dbh->getLogger(); |
|
2223 if (!empty($logger)) { |
|
2224 $query_start = microtime(TRUE); |
|
2225 } |
|
2226 |
|
2227 $return = parent::execute($args); |
|
2228 |
|
2229 if (!empty($logger)) { |
|
2230 $query_end = microtime(TRUE); |
|
2231 $logger->log($this, $args, $query_end - $query_start); |
|
2232 } |
|
2233 |
|
2234 return $return; |
|
2235 } |
|
2236 |
|
2237 public function getQueryString() { |
|
2238 return $this->queryString; |
|
2239 } |
|
2240 |
|
2241 public function fetchCol($index = 0) { |
|
2242 return $this->fetchAll(PDO::FETCH_COLUMN, $index); |
|
2243 } |
|
2244 |
|
2245 public function fetchAllAssoc($key, $fetch = NULL) { |
|
2246 $return = array(); |
|
2247 if (isset($fetch)) { |
|
2248 if (is_string($fetch)) { |
|
2249 $this->setFetchMode(PDO::FETCH_CLASS, $fetch); |
|
2250 } |
|
2251 else { |
|
2252 $this->setFetchMode($fetch); |
|
2253 } |
|
2254 } |
|
2255 |
|
2256 foreach ($this as $record) { |
|
2257 $record_key = is_object($record) ? $record->$key : $record[$key]; |
|
2258 $return[$record_key] = $record; |
|
2259 } |
|
2260 |
|
2261 return $return; |
|
2262 } |
|
2263 |
|
2264 public function fetchAllKeyed($key_index = 0, $value_index = 1) { |
|
2265 $return = array(); |
|
2266 $this->setFetchMode(PDO::FETCH_NUM); |
|
2267 foreach ($this as $record) { |
|
2268 $return[$record[$key_index]] = $record[$value_index]; |
|
2269 } |
|
2270 return $return; |
|
2271 } |
|
2272 |
|
2273 public function fetchField($index = 0) { |
|
2274 // Call PDOStatement::fetchColumn to fetch the field. |
|
2275 return $this->fetchColumn($index); |
|
2276 } |
|
2277 |
|
2278 public function fetchAssoc() { |
|
2279 // Call PDOStatement::fetch to fetch the row. |
|
2280 return $this->fetch(PDO::FETCH_ASSOC); |
|
2281 } |
|
2282 } |
|
2283 |
|
2284 /** |
|
2285 * Empty implementation of a database statement. |
|
2286 * |
|
2287 * This class satisfies the requirements of being a database statement/result |
|
2288 * object, but does not actually contain data. It is useful when developers |
|
2289 * need to safely return an "empty" result set without connecting to an actual |
|
2290 * database. Calling code can then treat it the same as if it were an actual |
|
2291 * result set that happens to contain no records. |
|
2292 * |
|
2293 * @see SearchQuery |
|
2294 */ |
|
2295 class DatabaseStatementEmpty implements Iterator, DatabaseStatementInterface { |
|
2296 |
|
2297 public function execute($args = array(), $options = array()) { |
|
2298 return FALSE; |
|
2299 } |
|
2300 |
|
2301 public function getQueryString() { |
|
2302 return ''; |
|
2303 } |
|
2304 |
|
2305 public function rowCount() { |
|
2306 return 0; |
|
2307 } |
|
2308 |
|
2309 public function setFetchMode($mode, $a1 = NULL, $a2 = array()) { |
|
2310 return; |
|
2311 } |
|
2312 |
|
2313 public function fetch($mode = NULL, $cursor_orientation = NULL, $cursor_offset = NULL) { |
|
2314 return NULL; |
|
2315 } |
|
2316 |
|
2317 public function fetchField($index = 0) { |
|
2318 return NULL; |
|
2319 } |
|
2320 |
|
2321 public function fetchObject() { |
|
2322 return NULL; |
|
2323 } |
|
2324 |
|
2325 public function fetchAssoc() { |
|
2326 return NULL; |
|
2327 } |
|
2328 |
|
2329 function fetchAll($mode = NULL, $column_index = NULL, array $constructor_arguments = array()) { |
|
2330 return array(); |
|
2331 } |
|
2332 |
|
2333 public function fetchCol($index = 0) { |
|
2334 return array(); |
|
2335 } |
|
2336 |
|
2337 public function fetchAllKeyed($key_index = 0, $value_index = 1) { |
|
2338 return array(); |
|
2339 } |
|
2340 |
|
2341 public function fetchAllAssoc($key, $fetch = NULL) { |
|
2342 return array(); |
|
2343 } |
|
2344 |
|
2345 /* Implementations of Iterator. */ |
|
2346 |
|
2347 public function current() { |
|
2348 return NULL; |
|
2349 } |
|
2350 |
|
2351 public function key() { |
|
2352 return NULL; |
|
2353 } |
|
2354 |
|
2355 public function rewind() { |
|
2356 // Nothing to do: our DatabaseStatement can't be rewound. |
|
2357 } |
|
2358 |
|
2359 public function next() { |
|
2360 // Do nothing, since this is an always-empty implementation. |
|
2361 } |
|
2362 |
|
2363 public function valid() { |
|
2364 return FALSE; |
|
2365 } |
|
2366 } |
|
2367 |
|
2368 /** |
|
2369 * The following utility functions are simply convenience wrappers. |
|
2370 * |
|
2371 * They should never, ever have any database-specific code in them. |
|
2372 */ |
|
2373 |
|
2374 /** |
|
2375 * Executes an arbitrary query string against the active database. |
|
2376 * |
|
2377 * Use this function for SELECT queries if it is just a simple query string. |
|
2378 * If the caller or other modules need to change the query, use db_select() |
|
2379 * instead. |
|
2380 * |
|
2381 * Do not use this function for INSERT, UPDATE, or DELETE queries. Those should |
|
2382 * be handled via db_insert(), db_update() and db_delete() respectively. |
|
2383 * |
|
2384 * @param $query |
|
2385 * The prepared statement query to run. Although it will accept both named and |
|
2386 * unnamed placeholders, named placeholders are strongly preferred as they are |
|
2387 * more self-documenting. |
|
2388 * @param $args |
|
2389 * An array of values to substitute into the query. If the query uses named |
|
2390 * placeholders, this is an associative array in any order. If the query uses |
|
2391 * unnamed placeholders (?), this is an indexed array and the order must match |
|
2392 * the order of placeholders in the query string. |
|
2393 * @param $options |
|
2394 * An array of options to control how the query operates. |
|
2395 * |
|
2396 * @return DatabaseStatementInterface |
|
2397 * A prepared statement object, already executed. |
|
2398 * |
|
2399 * @see DatabaseConnection::defaultOptions() |
|
2400 */ |
|
2401 function db_query($query, array $args = array(), array $options = array()) { |
|
2402 if (empty($options['target'])) { |
|
2403 $options['target'] = 'default'; |
|
2404 } |
|
2405 |
|
2406 return Database::getConnection($options['target'])->query($query, $args, $options); |
|
2407 } |
|
2408 |
|
2409 /** |
|
2410 * Executes a query against the active database, restricted to a range. |
|
2411 * |
|
2412 * @param $query |
|
2413 * The prepared statement query to run. Although it will accept both named and |
|
2414 * unnamed placeholders, named placeholders are strongly preferred as they are |
|
2415 * more self-documenting. |
|
2416 * @param $from |
|
2417 * The first record from the result set to return. |
|
2418 * @param $count |
|
2419 * The number of records to return from the result set. |
|
2420 * @param $args |
|
2421 * An array of values to substitute into the query. If the query uses named |
|
2422 * placeholders, this is an associative array in any order. If the query uses |
|
2423 * unnamed placeholders (?), this is an indexed array and the order must match |
|
2424 * the order of placeholders in the query string. |
|
2425 * @param $options |
|
2426 * An array of options to control how the query operates. |
|
2427 * |
|
2428 * @return DatabaseStatementInterface |
|
2429 * A prepared statement object, already executed. |
|
2430 * |
|
2431 * @see DatabaseConnection::defaultOptions() |
|
2432 */ |
|
2433 function db_query_range($query, $from, $count, array $args = array(), array $options = array()) { |
|
2434 if (empty($options['target'])) { |
|
2435 $options['target'] = 'default'; |
|
2436 } |
|
2437 |
|
2438 return Database::getConnection($options['target'])->queryRange($query, $from, $count, $args, $options); |
|
2439 } |
|
2440 |
|
2441 /** |
|
2442 * Executes a SELECT query string and saves the result set to a temporary table. |
|
2443 * |
|
2444 * The execution of the query string happens against the active database. |
|
2445 * |
|
2446 * @param $query |
|
2447 * The prepared SELECT statement query to run. Although it will accept both |
|
2448 * named and unnamed placeholders, named placeholders are strongly preferred |
|
2449 * as they are more self-documenting. |
|
2450 * @param $args |
|
2451 * An array of values to substitute into the query. If the query uses named |
|
2452 * placeholders, this is an associative array in any order. If the query uses |
|
2453 * unnamed placeholders (?), this is an indexed array and the order must match |
|
2454 * the order of placeholders in the query string. |
|
2455 * @param $options |
|
2456 * An array of options to control how the query operates. |
|
2457 * |
|
2458 * @return |
|
2459 * The name of the temporary table. |
|
2460 * |
|
2461 * @see DatabaseConnection::defaultOptions() |
|
2462 */ |
|
2463 function db_query_temporary($query, array $args = array(), array $options = array()) { |
|
2464 if (empty($options['target'])) { |
|
2465 $options['target'] = 'default'; |
|
2466 } |
|
2467 |
|
2468 return Database::getConnection($options['target'])->queryTemporary($query, $args, $options); |
|
2469 } |
|
2470 |
|
2471 /** |
|
2472 * Returns a new InsertQuery object for the active database. |
|
2473 * |
|
2474 * @param $table |
|
2475 * The table into which to insert. |
|
2476 * @param $options |
|
2477 * An array of options to control how the query operates. |
|
2478 * |
|
2479 * @return InsertQuery |
|
2480 * A new InsertQuery object for this connection. |
|
2481 */ |
|
2482 function db_insert($table, array $options = array()) { |
|
2483 if (empty($options['target']) || $options['target'] == 'slave') { |
|
2484 $options['target'] = 'default'; |
|
2485 } |
|
2486 return Database::getConnection($options['target'])->insert($table, $options); |
|
2487 } |
|
2488 |
|
2489 /** |
|
2490 * Returns a new MergeQuery object for the active database. |
|
2491 * |
|
2492 * @param $table |
|
2493 * The table into which to merge. |
|
2494 * @param $options |
|
2495 * An array of options to control how the query operates. |
|
2496 * |
|
2497 * @return MergeQuery |
|
2498 * A new MergeQuery object for this connection. |
|
2499 */ |
|
2500 function db_merge($table, array $options = array()) { |
|
2501 if (empty($options['target']) || $options['target'] == 'slave') { |
|
2502 $options['target'] = 'default'; |
|
2503 } |
|
2504 return Database::getConnection($options['target'])->merge($table, $options); |
|
2505 } |
|
2506 |
|
2507 /** |
|
2508 * Returns a new UpdateQuery object for the active database. |
|
2509 * |
|
2510 * @param $table |
|
2511 * The table to update. |
|
2512 * @param $options |
|
2513 * An array of options to control how the query operates. |
|
2514 * |
|
2515 * @return UpdateQuery |
|
2516 * A new UpdateQuery object for this connection. |
|
2517 */ |
|
2518 function db_update($table, array $options = array()) { |
|
2519 if (empty($options['target']) || $options['target'] == 'slave') { |
|
2520 $options['target'] = 'default'; |
|
2521 } |
|
2522 return Database::getConnection($options['target'])->update($table, $options); |
|
2523 } |
|
2524 |
|
2525 /** |
|
2526 * Returns a new DeleteQuery object for the active database. |
|
2527 * |
|
2528 * @param $table |
|
2529 * The table from which to delete. |
|
2530 * @param $options |
|
2531 * An array of options to control how the query operates. |
|
2532 * |
|
2533 * @return DeleteQuery |
|
2534 * A new DeleteQuery object for this connection. |
|
2535 */ |
|
2536 function db_delete($table, array $options = array()) { |
|
2537 if (empty($options['target']) || $options['target'] == 'slave') { |
|
2538 $options['target'] = 'default'; |
|
2539 } |
|
2540 return Database::getConnection($options['target'])->delete($table, $options); |
|
2541 } |
|
2542 |
|
2543 /** |
|
2544 * Returns a new TruncateQuery object for the active database. |
|
2545 * |
|
2546 * @param $table |
|
2547 * The table from which to delete. |
|
2548 * @param $options |
|
2549 * An array of options to control how the query operates. |
|
2550 * |
|
2551 * @return TruncateQuery |
|
2552 * A new TruncateQuery object for this connection. |
|
2553 */ |
|
2554 function db_truncate($table, array $options = array()) { |
|
2555 if (empty($options['target']) || $options['target'] == 'slave') { |
|
2556 $options['target'] = 'default'; |
|
2557 } |
|
2558 return Database::getConnection($options['target'])->truncate($table, $options); |
|
2559 } |
|
2560 |
|
2561 /** |
|
2562 * Returns a new SelectQuery object for the active database. |
|
2563 * |
|
2564 * @param $table |
|
2565 * The base table for this query. May be a string or another SelectQuery |
|
2566 * object. If a query object is passed, it will be used as a subselect. |
|
2567 * @param $alias |
|
2568 * The alias for the base table of this query. |
|
2569 * @param $options |
|
2570 * An array of options to control how the query operates. |
|
2571 * |
|
2572 * @return SelectQuery |
|
2573 * A new SelectQuery object for this connection. |
|
2574 */ |
|
2575 function db_select($table, $alias = NULL, array $options = array()) { |
|
2576 if (empty($options['target'])) { |
|
2577 $options['target'] = 'default'; |
|
2578 } |
|
2579 return Database::getConnection($options['target'])->select($table, $alias, $options); |
|
2580 } |
|
2581 |
|
2582 /** |
|
2583 * Returns a new transaction object for the active database. |
|
2584 * |
|
2585 * @param string $name |
|
2586 * Optional name of the transaction. |
|
2587 * @param array $options |
|
2588 * An array of options to control how the transaction operates: |
|
2589 * - target: The database target name. |
|
2590 * |
|
2591 * @return DatabaseTransaction |
|
2592 * A new DatabaseTransaction object for this connection. |
|
2593 */ |
|
2594 function db_transaction($name = NULL, array $options = array()) { |
|
2595 if (empty($options['target'])) { |
|
2596 $options['target'] = 'default'; |
|
2597 } |
|
2598 return Database::getConnection($options['target'])->startTransaction($name); |
|
2599 } |
|
2600 |
|
2601 /** |
|
2602 * Sets a new active database. |
|
2603 * |
|
2604 * @param $key |
|
2605 * The key in the $databases array to set as the default database. |
|
2606 * |
|
2607 * @return |
|
2608 * The key of the formerly active database. |
|
2609 */ |
|
2610 function db_set_active($key = 'default') { |
|
2611 return Database::setActiveConnection($key); |
|
2612 } |
|
2613 |
|
2614 /** |
|
2615 * Restricts a dynamic table name to safe characters. |
|
2616 * |
|
2617 * Only keeps alphanumeric and underscores. |
|
2618 * |
|
2619 * @param $table |
|
2620 * The table name to escape. |
|
2621 * |
|
2622 * @return |
|
2623 * The escaped table name as a string. |
|
2624 */ |
|
2625 function db_escape_table($table) { |
|
2626 return Database::getConnection()->escapeTable($table); |
|
2627 } |
|
2628 |
|
2629 /** |
|
2630 * Restricts a dynamic column or constraint name to safe characters. |
|
2631 * |
|
2632 * Only keeps alphanumeric and underscores. |
|
2633 * |
|
2634 * @param $field |
|
2635 * The field name to escape. |
|
2636 * |
|
2637 * @return |
|
2638 * The escaped field name as a string. |
|
2639 */ |
|
2640 function db_escape_field($field) { |
|
2641 return Database::getConnection()->escapeField($field); |
|
2642 } |
|
2643 |
|
2644 /** |
|
2645 * Escapes characters that work as wildcard characters in a LIKE pattern. |
|
2646 * |
|
2647 * The wildcard characters "%" and "_" as well as backslash are prefixed with |
|
2648 * a backslash. Use this to do a search for a verbatim string without any |
|
2649 * wildcard behavior. |
|
2650 * |
|
2651 * For example, the following does a case-insensitive query for all rows whose |
|
2652 * name starts with $prefix: |
|
2653 * @code |
|
2654 * $result = db_query( |
|
2655 * 'SELECT * FROM person WHERE name LIKE :pattern', |
|
2656 * array(':pattern' => db_like($prefix) . '%') |
|
2657 * ); |
|
2658 * @endcode |
|
2659 * |
|
2660 * Backslash is defined as escape character for LIKE patterns in |
|
2661 * DatabaseCondition::mapConditionOperator(). |
|
2662 * |
|
2663 * @param $string |
|
2664 * The string to escape. |
|
2665 * |
|
2666 * @return |
|
2667 * The escaped string. |
|
2668 */ |
|
2669 function db_like($string) { |
|
2670 return Database::getConnection()->escapeLike($string); |
|
2671 } |
|
2672 |
|
2673 /** |
|
2674 * Retrieves the name of the currently active database driver. |
|
2675 * |
|
2676 * @return |
|
2677 * The name of the currently active database driver. |
|
2678 */ |
|
2679 function db_driver() { |
|
2680 return Database::getConnection()->driver(); |
|
2681 } |
|
2682 |
|
2683 /** |
|
2684 * Closes the active database connection. |
|
2685 * |
|
2686 * @param $options |
|
2687 * An array of options to control which connection is closed. Only the target |
|
2688 * key has any meaning in this case. |
|
2689 */ |
|
2690 function db_close(array $options = array()) { |
|
2691 if (empty($options['target'])) { |
|
2692 $options['target'] = NULL; |
|
2693 } |
|
2694 Database::closeConnection($options['target']); |
|
2695 } |
|
2696 |
|
2697 /** |
|
2698 * Retrieves a unique id. |
|
2699 * |
|
2700 * Use this function if for some reason you can't use a serial field. Using a |
|
2701 * serial field is preferred, and InsertQuery::execute() returns the value of |
|
2702 * the last ID inserted. |
|
2703 * |
|
2704 * @param $existing_id |
|
2705 * After a database import, it might be that the sequences table is behind, so |
|
2706 * by passing in a minimum ID, it can be assured that we never issue the same |
|
2707 * ID. |
|
2708 * |
|
2709 * @return |
|
2710 * An integer number larger than any number returned before for this sequence. |
|
2711 */ |
|
2712 function db_next_id($existing_id = 0) { |
|
2713 return Database::getConnection()->nextId($existing_id); |
|
2714 } |
|
2715 |
|
2716 /** |
|
2717 * Returns a new DatabaseCondition, set to "OR" all conditions together. |
|
2718 * |
|
2719 * @return DatabaseCondition |
|
2720 */ |
|
2721 function db_or() { |
|
2722 return new DatabaseCondition('OR'); |
|
2723 } |
|
2724 |
|
2725 /** |
|
2726 * Returns a new DatabaseCondition, set to "AND" all conditions together. |
|
2727 * |
|
2728 * @return DatabaseCondition |
|
2729 */ |
|
2730 function db_and() { |
|
2731 return new DatabaseCondition('AND'); |
|
2732 } |
|
2733 |
|
2734 /** |
|
2735 * Returns a new DatabaseCondition, set to "XOR" all conditions together. |
|
2736 * |
|
2737 * @return DatabaseCondition |
|
2738 */ |
|
2739 function db_xor() { |
|
2740 return new DatabaseCondition('XOR'); |
|
2741 } |
|
2742 |
|
2743 /** |
|
2744 * Returns a new DatabaseCondition, set to the specified conjunction. |
|
2745 * |
|
2746 * Internal API function call. The db_and(), db_or(), and db_xor() |
|
2747 * functions are preferred. |
|
2748 * |
|
2749 * @param $conjunction |
|
2750 * The conjunction to use for query conditions (AND, OR or XOR). |
|
2751 * @return DatabaseCondition |
|
2752 */ |
|
2753 function db_condition($conjunction) { |
|
2754 return new DatabaseCondition($conjunction); |
|
2755 } |
|
2756 |
|
2757 /** |
|
2758 * @} End of "defgroup database". |
|
2759 */ |
|
2760 |
|
2761 |
|
2762 /** |
|
2763 * @addtogroup schemaapi |
|
2764 * @{ |
|
2765 */ |
|
2766 |
|
2767 /** |
|
2768 * Creates a new table from a Drupal table definition. |
|
2769 * |
|
2770 * @param $name |
|
2771 * The name of the table to create. |
|
2772 * @param $table |
|
2773 * A Schema API table definition array. |
|
2774 */ |
|
2775 function db_create_table($name, $table) { |
|
2776 return Database::getConnection()->schema()->createTable($name, $table); |
|
2777 } |
|
2778 |
|
2779 /** |
|
2780 * Returns an array of field names from an array of key/index column specifiers. |
|
2781 * |
|
2782 * This is usually an identity function but if a key/index uses a column prefix |
|
2783 * specification, this function extracts just the name. |
|
2784 * |
|
2785 * @param $fields |
|
2786 * An array of key/index column specifiers. |
|
2787 * |
|
2788 * @return |
|
2789 * An array of field names. |
|
2790 */ |
|
2791 function db_field_names($fields) { |
|
2792 return Database::getConnection()->schema()->fieldNames($fields); |
|
2793 } |
|
2794 |
|
2795 /** |
|
2796 * Checks if an index exists in the given table. |
|
2797 * |
|
2798 * @param $table |
|
2799 * The name of the table in drupal (no prefixing). |
|
2800 * @param $name |
|
2801 * The name of the index in drupal (no prefixing). |
|
2802 * |
|
2803 * @return |
|
2804 * TRUE if the given index exists, otherwise FALSE. |
|
2805 */ |
|
2806 function db_index_exists($table, $name) { |
|
2807 return Database::getConnection()->schema()->indexExists($table, $name); |
|
2808 } |
|
2809 |
|
2810 /** |
|
2811 * Checks if a table exists. |
|
2812 * |
|
2813 * @param $table |
|
2814 * The name of the table in drupal (no prefixing). |
|
2815 * |
|
2816 * @return |
|
2817 * TRUE if the given table exists, otherwise FALSE. |
|
2818 */ |
|
2819 function db_table_exists($table) { |
|
2820 return Database::getConnection()->schema()->tableExists($table); |
|
2821 } |
|
2822 |
|
2823 /** |
|
2824 * Checks if a column exists in the given table. |
|
2825 * |
|
2826 * @param $table |
|
2827 * The name of the table in drupal (no prefixing). |
|
2828 * @param $field |
|
2829 * The name of the field. |
|
2830 * |
|
2831 * @return |
|
2832 * TRUE if the given column exists, otherwise FALSE. |
|
2833 */ |
|
2834 function db_field_exists($table, $field) { |
|
2835 return Database::getConnection()->schema()->fieldExists($table, $field); |
|
2836 } |
|
2837 |
|
2838 /** |
|
2839 * Finds all tables that are like the specified base table name. |
|
2840 * |
|
2841 * @param $table_expression |
|
2842 * An SQL expression, for example "simpletest%" (without the quotes). |
|
2843 * BEWARE: this is not prefixed, the caller should take care of that. |
|
2844 * |
|
2845 * @return |
|
2846 * Array, both the keys and the values are the matching tables. |
|
2847 */ |
|
2848 function db_find_tables($table_expression) { |
|
2849 return Database::getConnection()->schema()->findTables($table_expression); |
|
2850 } |
|
2851 |
|
2852 function _db_create_keys_sql($spec) { |
|
2853 return Database::getConnection()->schema()->createKeysSql($spec); |
|
2854 } |
|
2855 |
|
2856 /** |
|
2857 * Renames a table. |
|
2858 * |
|
2859 * @param $table |
|
2860 * The current name of the table to be renamed. |
|
2861 * @param $new_name |
|
2862 * The new name for the table. |
|
2863 */ |
|
2864 function db_rename_table($table, $new_name) { |
|
2865 return Database::getConnection()->schema()->renameTable($table, $new_name); |
|
2866 } |
|
2867 |
|
2868 /** |
|
2869 * Drops a table. |
|
2870 * |
|
2871 * @param $table |
|
2872 * The table to be dropped. |
|
2873 */ |
|
2874 function db_drop_table($table) { |
|
2875 return Database::getConnection()->schema()->dropTable($table); |
|
2876 } |
|
2877 |
|
2878 /** |
|
2879 * Adds a new field to a table. |
|
2880 * |
|
2881 * @param $table |
|
2882 * Name of the table to be altered. |
|
2883 * @param $field |
|
2884 * Name of the field to be added. |
|
2885 * @param $spec |
|
2886 * The field specification array, as taken from a schema definition. The |
|
2887 * specification may also contain the key 'initial'; the newly-created field |
|
2888 * will be set to the value of the key in all rows. This is most useful for |
|
2889 * creating NOT NULL columns with no default value in existing tables. |
|
2890 * @param $keys_new |
|
2891 * (optional) Keys and indexes specification to be created on the table along |
|
2892 * with adding the field. The format is the same as a table specification, but |
|
2893 * without the 'fields' element. If you are adding a type 'serial' field, you |
|
2894 * MUST specify at least one key or index including it in this array. See |
|
2895 * db_change_field() for more explanation why. |
|
2896 * |
|
2897 * @see db_change_field() |
|
2898 */ |
|
2899 function db_add_field($table, $field, $spec, $keys_new = array()) { |
|
2900 return Database::getConnection()->schema()->addField($table, $field, $spec, $keys_new); |
|
2901 } |
|
2902 |
|
2903 /** |
|
2904 * Drops a field. |
|
2905 * |
|
2906 * @param $table |
|
2907 * The table to be altered. |
|
2908 * @param $field |
|
2909 * The field to be dropped. |
|
2910 */ |
|
2911 function db_drop_field($table, $field) { |
|
2912 return Database::getConnection()->schema()->dropField($table, $field); |
|
2913 } |
|
2914 |
|
2915 /** |
|
2916 * Sets the default value for a field. |
|
2917 * |
|
2918 * @param $table |
|
2919 * The table to be altered. |
|
2920 * @param $field |
|
2921 * The field to be altered. |
|
2922 * @param $default |
|
2923 * Default value to be set. NULL for 'default NULL'. |
|
2924 */ |
|
2925 function db_field_set_default($table, $field, $default) { |
|
2926 return Database::getConnection()->schema()->fieldSetDefault($table, $field, $default); |
|
2927 } |
|
2928 |
|
2929 /** |
|
2930 * Sets a field to have no default value. |
|
2931 * |
|
2932 * @param $table |
|
2933 * The table to be altered. |
|
2934 * @param $field |
|
2935 * The field to be altered. |
|
2936 */ |
|
2937 function db_field_set_no_default($table, $field) { |
|
2938 return Database::getConnection()->schema()->fieldSetNoDefault($table, $field); |
|
2939 } |
|
2940 |
|
2941 /** |
|
2942 * Adds a primary key to a database table. |
|
2943 * |
|
2944 * @param $table |
|
2945 * Name of the table to be altered. |
|
2946 * @param $fields |
|
2947 * Array of fields for the primary key. |
|
2948 */ |
|
2949 function db_add_primary_key($table, $fields) { |
|
2950 return Database::getConnection()->schema()->addPrimaryKey($table, $fields); |
|
2951 } |
|
2952 |
|
2953 /** |
|
2954 * Drops the primary key of a database table. |
|
2955 * |
|
2956 * @param $table |
|
2957 * Name of the table to be altered. |
|
2958 */ |
|
2959 function db_drop_primary_key($table) { |
|
2960 return Database::getConnection()->schema()->dropPrimaryKey($table); |
|
2961 } |
|
2962 |
|
2963 /** |
|
2964 * Adds a unique key. |
|
2965 * |
|
2966 * @param $table |
|
2967 * The table to be altered. |
|
2968 * @param $name |
|
2969 * The name of the key. |
|
2970 * @param $fields |
|
2971 * An array of field names. |
|
2972 */ |
|
2973 function db_add_unique_key($table, $name, $fields) { |
|
2974 return Database::getConnection()->schema()->addUniqueKey($table, $name, $fields); |
|
2975 } |
|
2976 |
|
2977 /** |
|
2978 * Drops a unique key. |
|
2979 * |
|
2980 * @param $table |
|
2981 * The table to be altered. |
|
2982 * @param $name |
|
2983 * The name of the key. |
|
2984 */ |
|
2985 function db_drop_unique_key($table, $name) { |
|
2986 return Database::getConnection()->schema()->dropUniqueKey($table, $name); |
|
2987 } |
|
2988 |
|
2989 /** |
|
2990 * Adds an index. |
|
2991 * |
|
2992 * @param $table |
|
2993 * The table to be altered. |
|
2994 * @param $name |
|
2995 * The name of the index. |
|
2996 * @param $fields |
|
2997 * An array of field names. |
|
2998 */ |
|
2999 function db_add_index($table, $name, $fields) { |
|
3000 return Database::getConnection()->schema()->addIndex($table, $name, $fields); |
|
3001 } |
|
3002 |
|
3003 /** |
|
3004 * Drops an index. |
|
3005 * |
|
3006 * @param $table |
|
3007 * The table to be altered. |
|
3008 * @param $name |
|
3009 * The name of the index. |
|
3010 */ |
|
3011 function db_drop_index($table, $name) { |
|
3012 return Database::getConnection()->schema()->dropIndex($table, $name); |
|
3013 } |
|
3014 |
|
3015 /** |
|
3016 * Changes a field definition. |
|
3017 * |
|
3018 * IMPORTANT NOTE: To maintain database portability, you have to explicitly |
|
3019 * recreate all indices and primary keys that are using the changed field. |
|
3020 * |
|
3021 * That means that you have to drop all affected keys and indexes with |
|
3022 * db_drop_{primary_key,unique_key,index}() before calling db_change_field(). |
|
3023 * To recreate the keys and indices, pass the key definitions as the optional |
|
3024 * $keys_new argument directly to db_change_field(). |
|
3025 * |
|
3026 * For example, suppose you have: |
|
3027 * @code |
|
3028 * $schema['foo'] = array( |
|
3029 * 'fields' => array( |
|
3030 * 'bar' => array('type' => 'int', 'not null' => TRUE) |
|
3031 * ), |
|
3032 * 'primary key' => array('bar') |
|
3033 * ); |
|
3034 * @endcode |
|
3035 * and you want to change foo.bar to be type serial, leaving it as the primary |
|
3036 * key. The correct sequence is: |
|
3037 * @code |
|
3038 * db_drop_primary_key('foo'); |
|
3039 * db_change_field('foo', 'bar', 'bar', |
|
3040 * array('type' => 'serial', 'not null' => TRUE), |
|
3041 * array('primary key' => array('bar'))); |
|
3042 * @endcode |
|
3043 * |
|
3044 * The reasons for this are due to the different database engines: |
|
3045 * |
|
3046 * On PostgreSQL, changing a field definition involves adding a new field and |
|
3047 * dropping an old one which causes any indices, primary keys and sequences |
|
3048 * (from serial-type fields) that use the changed field to be dropped. |
|
3049 * |
|
3050 * On MySQL, all type 'serial' fields must be part of at least one key or index |
|
3051 * as soon as they are created. You cannot use |
|
3052 * db_add_{primary_key,unique_key,index}() for this purpose because the ALTER |
|
3053 * TABLE command will fail to add the column without a key or index |
|
3054 * specification. The solution is to use the optional $keys_new argument to |
|
3055 * create the key or index at the same time as field. |
|
3056 * |
|
3057 * You could use db_add_{primary_key,unique_key,index}() in all cases unless you |
|
3058 * are converting a field to be type serial. You can use the $keys_new argument |
|
3059 * in all cases. |
|
3060 * |
|
3061 * @param $table |
|
3062 * Name of the table. |
|
3063 * @param $field |
|
3064 * Name of the field to change. |
|
3065 * @param $field_new |
|
3066 * New name for the field (set to the same as $field if you don't want to |
|
3067 * change the name). |
|
3068 * @param $spec |
|
3069 * The field specification for the new field. |
|
3070 * @param $keys_new |
|
3071 * (optional) Keys and indexes specification to be created on the table along |
|
3072 * with changing the field. The format is the same as a table specification |
|
3073 * but without the 'fields' element. |
|
3074 */ |
|
3075 function db_change_field($table, $field, $field_new, $spec, $keys_new = array()) { |
|
3076 return Database::getConnection()->schema()->changeField($table, $field, $field_new, $spec, $keys_new); |
|
3077 } |
|
3078 |
|
3079 /** |
|
3080 * @} End of "addtogroup schemaapi". |
|
3081 */ |
|
3082 |
|
3083 /** |
|
3084 * Sets a session variable specifying the lag time for ignoring a slave server. |
|
3085 */ |
|
3086 function db_ignore_slave() { |
|
3087 $connection_info = Database::getConnectionInfo(); |
|
3088 // Only set ignore_slave_server if there are slave servers being used, which |
|
3089 // is assumed if there are more than one. |
|
3090 if (count($connection_info) > 1) { |
|
3091 // Five minutes is long enough to allow the slave to break and resume |
|
3092 // interrupted replication without causing problems on the Drupal site from |
|
3093 // the old data. |
|
3094 $duration = variable_get('maximum_replication_lag', 300); |
|
3095 // Set session variable with amount of time to delay before using slave. |
|
3096 $_SESSION['ignore_slave_server'] = REQUEST_TIME + $duration; |
|
3097 } |
|
3098 } |