Code coverage for /20081101/includes/database/database.inc

Line #Times calledCode
1
<?php
2
// $Id: database.inc,v 1.20 2008/11/01 21:21:35 dries Exp $
3
4
/**
5
 * @file
6
 * Base classes for the database layer.
7
 */
8
9
/**
10
 * @defgroup database Database abstraction layer
11
 * @{
12
 * Allow the use of different database servers using the same code base.
13
 *
14
 * Drupal provides a database abstraction layer to provide developers with
15
 * the ability to support multiple database servers easily.  The intent of
16
 * this layer is to preserve the syntax and power of SQL as much as
possible,
17
 * but also allow developers a way to leverage more complex functionality
in
18
 * a unified way.  It also provides a structured interface for dynamically
19
 * constructing queries when appropriate, and enforcing security checks and
20
 * similar good practices.
21
 *
22
 * The system is built atop PHP's PDO (PHP Data Objects) database API and
23
 * inherits much of its syntax and semantics.
24
 *
25
 * Most Drupal database SELECT queries are performed by a call to
db_query() or
26
 * db_query_range(). Module authors should also consider using
pager_query() for
27
 * queries that return results that need to be presented on multiple pages,
and
28
 * tablesort_sql() for generating appropriate queries for sortable tables.
29
 *
30
 * For example, one might wish to return a list of the most recent 10 nodes
31
 * authored by a given user. Instead of directly issuing the SQL query
32
 * @code
33
 *   SELECT n.nid, n.title, n.created FROM node n WHERE n.uid = $uid LIMIT
0, 10;
34
 * @endcode
35
 * one would instead call the Drupal functions:
36
 * @code
37
 *   $result = db_query_range('SELECT n.nid, n.title, n.created
38
 *     FROM {node} n WHERE n.uid = :uid', array(':uid' => $uid), 0, 10);
39
 *   foreach($result as $record) {
40
 *     // Perform operations on $node->title, etc. here.
41
 *   }
42
 * @endcode
43
 * Curly braces are used around "node" to provide table prefixing via
44
 * DatabaseConnection::prefixTables(). The explicit use of a user ID is
pulled
45
 * out into an argument passed to db_query() so that SQL injection attacks
46
 * from user input can be caught and nullified. The LIMIT syntax varies
between
47
 * database servers, so that is abstracted into db_query_range() arguments.
48
 * Finally, note the PDO-based ability to foreach() over the result set.
49
 *
50
 *
51
 * All queries are passed as a prepared statement string.  A
52
 * prepared statement is a "template" of a query that omits literal or
variable
53
 * values in favor of placeholders.  The values to place into those
54
 * placeholders are passed separately, and the database driver handles
55
 * inserting the values into the query in a secure fashion.  That means you
56
 * should never quote or string-escape a value to be inserted into the
query.
57
 *
58
 * There are two formats for placeholders: named and unnamed.  Named
placeholders
59
 * are strongly preferred in all cases as they are more flexible and
60
 * self-documenting.
61
 *
62
 * Named placeholders begin with a colon followed by a unique string.
Example:
63
 * @code
64
 * SELECT nid, title FROM {node} WHERE uid=:uid
65
 * @endcode
66
 *
67
 * ":uid" is a placeholder that will be replaced with a literal value when
68
 * the query is executed.  A given placeholder label cannot be repeated in
a
69
 * given query, even if the value should be the same.  When using named
70
 * placeholders, the array of arguments to the query must be an associative
71
 * array where keys are a placeholder label (e.g., :uid) and the value is
the
72
 * corresponding value to use.  The array may be in any order.
73
 *
74
 * Unnamed placeholders are simply a question mark.  Example:
75
 * @code
76
 * SELECT nid, title FROM {node} WHERE uid=?
77
 * @endcode
78
 *
79
 * In this case, the array of arguments must be an indexed array of values
to
80
 * use in the exact same order as the placeholders in the query.
81
 *
82
 * Note that placeholders should be a "complete" value.  For example, when
83
 * running a LIKE query the SQL wildcard character, %, should be part of
the
84
 * value, not the query itself.  Thus, the following is incorrect:
85
 *
86
 * @code
87
 * SELECT nid, title FROM {node} WHERE title LIKE :title%
88
 * @endcode
89
 *
90
 * It should instead read:
91
 *
92
 * @code
93
 * SELECT nid, title FROM {node} WHERE title LIKE :title
94
 * @endcode
95
 *
96
 * and the value for :title should include a % as appropriate.  Again, note
the
97
 * lack of quotation marks around :title.  Because the value is not
inserted
98
 * into the query as one big string but as an explicitly separate value,
the
99
 * database server knows where the query ends and a value begins.  That is
100
 * considerably more secure against SQL injection than trying to remember
101
 * which values need quotation marks and string escaping and which don't.
102
 *
103
 *
104
 * INSERT, UPDATE, and DELETE queries need special care in order to behave
105
 * consistently across all different databases.  Therefore, they use a
special
106
 * object-oriented API for defining a query structurally.  For example,
rather than
107
 * @code
108
 * INSERT INTO node (nid, title, body) VALUES (1, 'my title', 'my body')
109
 * @endcode
110
 * one would instead write:
111
 * @code
112
 * $fields = array('nid' => 1, 'title' => 'my title', 'body' => 'my body');
113
 * db_insert('my_table')->fields($fields)->execute();
114
 * @endcode
115
 * This method allows databases that need special data type handling to do
so,
116
 * while also allowing optimizations such as multi-insert queries.  UPDATE
and
117
 * DELETE queries have a similar pattern.
118
 */
119
120
121
/**
122
 * Base Database API class.
123
 *
124
 * This class provides a Drupal-specific extension of the PDO database
abstraction class in PHP.
125
 * Every database driver implementation must provide a concrete
implementation of it to support
126
 * special handling required by that database.
127
 *
128
 * @link http://us.php.net/manual/en/ref.pdo.php
129
 */
1302367
abstract class DatabaseConnection extends PDO {
131
132
  /**
133
   * Reference to the last statement that was executed.
134
   *
135
   * We only need this for the legacy db_affected_rows() call, which will
be removed.
136
   *
137
   * @var DatabaseStatement
138
   * @todo Remove this variable.
139
   */
140
  public $lastStatement;
141
142
  /**
143
   * The database target this connection is for.
144
   *
145
   * We need this information for later auditing and logging.
146
   *
147
   * @var string
148
   */
149
  protected $target = NULL;
150
151
  /**
152
   * The current database logging object for this connection.
153
   *
154
   * @var DatabaseLog
155
   */
156
  protected $logger = NULL;
157
158
  function __construct($dsn, $username, $password, $driver_options =
array()) {
159
    // Because the other methods don't seem to work right.
1602369
    $driver_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
161
    // Call PDO::__construct and PDO::setAttribute.
1622369
    parent::__construct($dsn, $username, $password, $driver_options);
1632369
    $this->setAttribute(PDO::ATTR_STATEMENT_CLASS,
array('DatabaseStatement', array($this)));
1642369
  }
165
166
  /**
167
   * Return the default query options for any given query.
168
   *
169
   * A given query can be customized with a number of option flags in an
170
   * associative array.
171
   *
172
   *   target - The database "target" against which to execute a query. 
Valid
173
   *   values are "default" or "slave".  The system will first try to open
a
174
   *   connection to a database specified with the user-supplied key.  If
one
175
   *   is not available, it will silently fall back to the "default"
target.
176
   *   If multiple databases connections are specified with the same
target,
177
   *   one will be selected at random for the duration of the request.
178
   *
179
   *   fetch - This element controls how rows from a result set will be
returned.
180
   *   legal values include PDO::FETCH_ASSOC, PDO::FETCH_BOTH,
PDO::FETCH_OBJ,
181
   *   PDO::FETCH_NUM, or a string representing the name of a class.  If a
string
182
   *   is specified, each record will be fetched into a new object of that
class.
183
   *   The behavior of all other values is defined by PDO.  See
184
   *   http://www.php.net/PDOStatement-fetch
185
   *
186
   *   return - Depending on the type of query, different return values may
be
187
   *   meaningful.  This directive instructs the system which type of
return
188
   *   value is desired.  The system will generally set the correct value
189
   *   automatically, so it is extremely rare that a module developer will
ever
190
   *   need to specify this value.  Setting it incorrectly will likely lead
to
191
   *   unpredictable results or fatal errors.  Legal values include:
192
   *
193
   *     Database::RETURN_STATEMENT - Return the prepared statement object
for the
194
   *     query.  This is usually only meaningful for SELECT queries, where
the
195
   *     statement object is how one accesses the result set returned by
the query.
196
   *
197
   *     Database::RETURN_AFFECTED - Return the number of rows affected by
an
198
   *     UPDATE or DELETE query.  Be aware that means the number of rows
199
   *     actually changed, not the number of rows matched by the WHERE
clause.
200
   *
201
   *     Database::RETURN_INSERT_ID - Return the sequence ID (primary key)
202
   *     created by an INSERT statement on a table that contains a serial
column.
203
   *
204
   *     Database::RETURN_NULL - Do not return anything, as there is no
205
   *     meaningful value to return.  That is the case for INSERT queries
on
206
   *     tables that do not contain a serial column.
207
   *
208
   *   throw_exception - By default, the database system will catch any
errors
209
   *   on a query as an Exception, log it, and then rethrow it so that code
210
   *   further up the call chain can take an appropriate action.  To
supress
211
   *   that behavior and simply return NULL on failure, set this option to
FALSE.
212
   *
213
   * @return
214
   *   An array of default query options.
215
   */
216
  protected function defaultOptions() {
217
    return array(
2182498
      'target' => 'default',
2192498
      'fetch' => PDO::FETCH_OBJ,
2202498
      'return' => Database::RETURN_STATEMENT,
2212498
      'throw_exception' => TRUE,
2222498
    );
2230
  }
224
225
  /**
226
   * Append a database prefix to all tables in a query.
227
   *
228
   * Queries sent to Drupal should wrap all table names in curly brackets.
This
229
   * function searches for this syntax and adds Drupal's table prefix to
all
230
   * tables, allowing Drupal to coexist with other systems in the same
database
231
   * if necessary.
232
   *
233
   * @param $sql
234
   *   A string containing a partial or entire SQL query.
235
   * @return
236
   *   The properly-prefixed string.
237
   */
238
  protected function prefixTables($sql) {
2392498
    global $db_prefix;
240
2412498
    if (is_array($db_prefix)) {
2420
      if (array_key_exists('default', $db_prefix)) {
2430
        $tmp = $db_prefix;
2440
        unset($tmp['default']);
2450
        foreach ($tmp as $key => $val) {
2460
          $sql = strtr($sql, array('{' . $key . '}' => $val . $key));
2470
        }
2480
        return strtr($sql, array('{' => $db_prefix['default'] , '}' =>
''));
2490
      }
250
      else {
2510
        foreach ($db_prefix as $key => $val) {
2520
          $sql = strtr($sql, array('{' . $key . '}' => $val . $key));
2530
        }
2540
        return strtr($sql, array('{' => '' , '}' => ''));
255
      }
2560
    }
257
    else {
2582498
      return strtr($sql, array('{' => $db_prefix , '}' => ''));
259
    }
2600
  }
261
262
  /**
263
   * Prepare a query string and return the prepared statement.
264
   *
265
   * This method statically caches prepared statements, reusing them when
266
   * possible.  It also prefixes tables names enclosed in curly-braces.
267
   *
268
   * @param $query
269
   *   The query string as SQL, with curly-braces surrounding the
270
   *   table names.
271
   * @return
272
   *   A PDO prepared statement ready for its execute() method.
273
   */
274
  protected function prepareQuery($query) {
2752498
    static $statements = array();
2762498
    $query = self::prefixTables($query);
2772498
    if (empty($statements[$query])) {
278
      // Call PDO::prepare.
2792498
      $statements[$query] = parent::prepare($query);
2802498
    }
2812498
    return $statements[$query];
2820
  }
283
284
  /**
285
   * Tell this connection object what its target value is.
286
   *
287
   * This is needed for logging and auditing.  It's sloppy to do in the
288
   * constructor because the constructor for child classes has a different
289
   * signature.  We therefore also ensure that this function is only ever
290
   * called once.
291
   *
292
   * @param $target
293
   *   The target this connection is for.  Set to NULL (default) to disable
294
   *   logging entirely.
295
   */
296
  public function setTarget($target = NULL) {
2972369
    if (!isset($this->target)) {
2982369
      $this->target = $target;
2992369
    }
3002369
  }
301
302
  /**
303
   * Returns the target this connection is associated with.
304
   *
305
   * @return
306
   *   The target string of this connection.
307
   */
308
  public function getTarget() {
3091
    return $this->target;
3100
  }
311
312
  /**
313
   * Associate a logging object with this connection.
314
   *
315
   * @param $logger
316
   *   The logging object we want to use.
317
   */
318
  public function setLogger(DatabaseLog $logger) {
3191
    $this->logger = $logger;
3201
  }
321
322
  /**
323
   * Get the current logging object for this connection.
324
   *
325
   * @return
326
   *   The current logging object for this connection.  If there isn't one,
327
   *   NULL is returned.
328
   */
329
  public function getLogger() {
3302498
    return $this->logger;
3310
  }
332
333
  /**
334
   * Create the appropriate sequence name for a given table and serial
field.
335
   *
336
   * This information is exposed to all database drivers, although it is
only
337
   * useful on some of them.  This method is table prefix-aware.
338
   *
339
   * @param $table
340
   *   The table name to use for the sequence.
341
   * @param $field
342
   *   The field name to use for the sequence.
343
   * @return
344
   *   A table prefix-parsed string for the sequence name.
345
   */
346
  public function makeSequenceName($table, $field) {
347162
    return $this->prefixTables('{'. $table .'}_'. $field .'_seq');
3480
  }
349
350
  /**
351
   * Executes a query string against the database.
352
   *
353
   * This method provides a central handler for the actual execution
354
   * of every query.  All queries executed by Drupal are executed as
355
   * PDO prepared statements.  This method statically caches those
356
   * prepared statements, reusing them when possible.
357
   *
358
   * @param $query
359
   *   The query to execute.  In most cases this will be a string
containing
360
   *   an SQL query with placeholders.  An already-prepared instance of
361
   *   DatabaseStatement may also be passed in order to allow calling code
362
   *   to manually bind variables to a query.  If a DatabaseStatement
object
363
   *   is passed, the $args array will be ignored.
364
   *
365
   *   It is extremely rare that module code will need to pass a statement
366
   *   object to this method.  It is used primarily for database drivers
for
367
   *   databases that require special LOB field handling.
368
   * @param $args
369
   *   An array of arguments for the prepared statement.  If the prepared
370
   *   statement uses ? placeholders, this array must be an indexed array.
371
   *   If it contains named placeholders, it must be an associative array.
372
   * @param $options
373
   *   An associative array of options to control how the query is run. 
See
374
   *   the documentation for DatabaseConnection::defaultOptions() for
details.
375
   * @return
376
   *   This method will return one of: The executed statement, the number
of
377
   *   rows affected by the query (not the number matched), or the
generated
378
   *   insert id of the last query, depending on the value of
$options['return'].
379
   *   Typically that value will be set by default or a query builder and
should
380
   *   not be set by a user.  If there is an error, this method will return
NULL
381
   *   and may throw an exception if $options['throw_exception'] is TRUE.
382
   */
383
  public function query($query, Array $args = array(), $options = array())
{
384
385
    // Use default values if not already set.
3862498
    $options += $this->defaultOptions();
387
388
    try {
389
      // We allow either a pre-bound statement object or a literal string.
390
      // In either case, we want to end up with an executed statement
object,
391
      // which we pass to PDOStatement::execute.
3922498
      if ($query instanceof DatabaseStatement) {
3930
        $stmt = $query;
3940
        $stmt->execute(NULL, $options);
3950
      }
396
      else {
3972498
        $stmt = $this->prepareQuery($query);
3982498
        $stmt->execute($args, $options);
399
      }
400
401
      // Depending on the type of query we may need to return a different
value.
402
      // See DatabaseConnection::defaultOptions() for a description of each
value.
4032498
      switch ($options['return']) {
4042498
        case Database::RETURN_STATEMENT:
4052498
          return $stmt;
4062134
        case Database::RETURN_AFFECTED:
4072032
          return $stmt->rowCount();
408731
        case Database::RETURN_INSERT_ID:
409731
          return $this->lastInsertId();
4100
        case Database::RETURN_NULL:
4110
          return;
4120
        default:
4130
          throw new PDOException('Invalid return directive: ' .
$options['return']);
4140
      }
415
    }
4161
    catch (PDOException $e) {
4171
      if (!function_exists('module_implements')) {
4180
        _db_need_install();
4190
      }
4201
      if ($options['throw_exception']) {
4211
        if ($query instanceof DatabaseStatement) {
4220
          $query_string = $stmt->queryString;
4230
        }
424
        else {
4251
          $query_string = $query;
426
        }
4271
        throw new PDOException($query_string . " - \n" . print_r($args,1) .
$e->getMessage());
4280
      }
4290
      return NULL;
430
    }
4310
  }
432
433
  /**
434
   * Prepare and return a SELECT query object with the specified ID.
435
   *
436
   * @see SelectQuery
437
   * @param $table
438
   *   The base table for this query, that is, the first table in the FROM
439
   *   clause.  This table will also be used as the "base" table for
query_alter
440
   *   hook implementations.
441
   * @param $alias
442
   *   The alias of the base table of this query.
443
   * @param $options
444
   *   An array of options on the query.
445
   * @return
446
   *   A new SelectQuery object.
447
   */
448
  public function select($table, $alias = NULL, Array $options = array()) {
4492005
    static $class_type;
4502005
    if (empty($class_type)) {
4512005
      $class_type = 'SelectQuery_' . $this->driver();
4522005
      if (!class_exists($class_type)) {
4532005
        $class_type = 'SelectQuery';
4542005
      }
4552005
    }
4562005
    return new $class_type($table, $alias, $this, $options);
4570
  }
458
459
  /**
460
   * Prepare and return an INSERT query object with the specified ID.
461
   *
462
   * @see InsertQuery
463
   * @param $options
464
   *   An array of options on the query.
465
   * @return
466
   *   A new InsertQuery object.
467
   */
468
  public function insert($table, Array $options = array()) {
469731
    static $class_type;
470731
    if (empty($class_type)) {
471731
      $class_type = 'InsertQuery_' . $this->driver();
472731
      if (!class_exists($class_type)) {
4730
        $class_type = 'InsertQuery';
4740
      }
475731
    }
476731
    return new $class_type($this, $table, $options);
4770
  }
478
479
  /**
480
   * Prepare and return a MERGE query object with the specified ID.
481
   *
482
   * @see MergeQuery
483
   * @param $options
484
   *   An array of options on the query.
485
   * @return
486
   *   A new MergeQuery object.
487
   */
488
  public function merge($table, Array $options = array()) {
4891630
    static $class_type;
4901630
    if (empty($class_type)) {
4911502
      $class_type = 'MergeQuery_' . $this->driver();
4921502
      if (!class_exists($class_type)) {
4930
        $class_type = 'MergeQuery';
4940
      }
4951502
    }
4961630
    return new $class_type($this, $table, $options);
4970
  }
498
499
  /**
500
   * Prepare and return an UPDATE query object with the specified ID.
501
   *
502
   * @see UpdateQuery
503
   * @param $options
504
   *   An array of options on the query.
505
   * @return
506
   *   A new UpdateQuery object.
507
   */
508
  public function update($table, Array $options = array()) {
50967
    static $class_type;
51067
    if (empty($class_type)) {
51167
      $class_type = 'UpdateQuery_' . $this->driver();
51267
      if (!class_exists($class_type)) {
51367
        $class_type = 'UpdateQuery';
51467
      }
51567
    }
51667
    return new $class_type($this, $table, $options);
5170
  }
518
519
  /**
520
   * Prepare and return a DELETE query object with the specified ID.
521
   *
522
   * @see DeleteQuery
523
   * @param $options
524
   *   An array of options on the query.
525
   * @return
526
   *   A new DeleteQuery object.
527
   */
528
  public function delete($table, Array $options = array()) {
529720
    static $class_type;
530720
    if (empty($class_type)) {
531720
      $class_type = 'DeleteQuery_' . $this->driver();
532720
      if (!class_exists($class_type)) {
533720
        $class_type = 'DeleteQuery';
534720
      }
535720
    }
536720
    return new $class_type($this, $table, $options);
5370
  }
538
539
  /**
540
   * Returns a DatabaseSchema object for manipulating the schema of this
database.
541
   *
542
   * This method will lazy-load the appropriate schema library file.
543
   *
544
   * @return
545
   *   The DatabaseSchema object for this connection.
546
   */
547
  public function schema() {
548137
    static $schema;
549137
    if (empty($schema)) {
550137
      $class_type = 'DatabaseSchema_' . $this->driver();
551137
      $schema = new $class_type($this);
552137
    }
553137
    return $schema;
5540
  }
555
556
  /**
557
   * Escapes a table name string.
558
   *
559
   * Force all table names to be strictly alphanumeric-plus-underscore.
560
   * For some database drivers, it may also wrap the table name in
561
   * database-specific escape characters.
562
   *
563
   * @return
564
   *   The sanitized table name string.
565
   */
566
  public function escapeTable($table) {
5670
    return preg_replace('/[^A-Za-z0-9_]+/', '', $string);
5680
  }
569
570
  /**
571
   * Returns a new DatabaseTransaction object on this connection.
572
   *
573
   * @param $required
574
   *   If executing an operation that absolutely must use transactions,
specify
575
   *   TRUE for this parameter.  If the connection does not support
transactions,
576
   *   this method will throw an exception and the operation will not be
possible.
577
   * @see DatabaseTransaction
578
   */
579
  public function startTransaction($required = FALSE) {
5800
    static $class_type;
581
5820
    if ($required && !$this->supportsTransactions()) {
5830
      throw new TransactionsNotSupportedException();
5840
    }
585
5860
    if (empty($class_type)) {
5870
      $class_type = 'DatabaseTransaction_' . $this->driver();
5880
      if (!class_exists($class_type)) {
5890
        $class_type = 'DatabaseTransaction';
5900
      }
5910
    }
5920
    return new $class_type($this);
5930
  }
594
595
  /**
596
   * Runs a limited-range query on this database object.
597
   *
598
   * Use this as a substitute for ->query() when a subset of the query is
to be
599
   * returned.
600
   * User-supplied arguments to the query should be passed in as separate
parameters
601
   * so that they can be properly escaped to avoid SQL injection attacks.
602
   *
603
   * @param $query
604
   *   A string containing an SQL query.
605
   * @param $args
606
   *   An array of values to substitute into the query at placeholder
markers.
607
   * @param $from
608
   *   The first result row to return.
609
   * @param $count
610
   *   The maximum number of result rows to return.
611
   * @param $options
612
   *   An array of options on the query.
613
   * @return
614
   *   A database query result resource, or NULL if the query was not
executed
615
   *   correctly.
616
   */
617
   abstract public function queryRange($query, Array $args, $from, $count,
Array $options);
618
619
  /**
620
   * Runs a SELECT query and stores its results in a temporary table.
621
   *
622
   * Use this as a substitute for ->query() when the results need to stored
623
   * in a temporary table. Temporary tables exist for the duration of the
page
624
   * request.
625
   * User-supplied arguments to the query should be passed in as separate
parameters
626
   * so that they can be properly escaped to avoid SQL injection attacks.
627
   *
628
   * Note that if you need to know how many results were returned, you
should do
629
   * a SELECT COUNT(*) on the temporary table afterwards.
630
   *
631
   * @param $query
632
   *   A string containing a normal SELECT SQL query.
633
   * @param $args
634
   *   An array of values to substitute into the query at placeholder
markers.
635
   * @param $tablename
636
   *   The name of the temporary table to select into. This name will not
be
637
   *   prefixed as there is no risk of collision.
638
   * @param $options
639
   *   An associative array of options to control how the query is run. 
See
640
   *   the documentation for DatabaseConnection::defaultOptions() for
details.
641
   * @return
642
   *   A database query result resource, or FALSE if the query was not
executed
643
   *   correctly.
644
   */
645
   abstract function queryTemporary($query, Array $args, $tablename,
$options = array());
646
647
  /**
648
   * Returns the type of database driver.
649
   *
650
   * This is not necessarily the same as the type of the database itself.
651
   * For instance, there could be two MySQL drivers, mysql and mysql_mock.
652
   * This function would return different values for each, but both would
653
   * return "mysql" for databaseType().
654
   */
655
  abstract public function driver();
656
657
  /**
658
   * Determine if this driver supports transactions.
659
   */
660
  abstract public function supportsTransactions();
661
662
  /**
663
   * Returns the type of the database being accessed.
664
   */
665
  abstract public function databaseType();
666
667
668
  /**
669
   * Gets any special processing requirements for the condition operator.
670
   *
671
   * Some condition types require special processing, such as IN, because
672
   * the value data they pass in is not a simple value.  This is a simple
673
   * overridable lookup function.  Database connections should define only
674
   * those operators they wish to be handled differently than the default.
675
   *
676
   * @see DatabaseCondition::compile().
677
   * @param $operator
678
   *   The condition operator, such as "IN", "BETWEEN", etc. 
Case-sensitive.
679
   * @return
680
   *   The extra handling directives for the specified operator, or NULL.
681
   */
682
  abstract public function mapConditionOperator($operator);
683
}
684
685
/**
686
 * Primary front-controller for the database system.
687
 *
688
 * This class is uninstantiatable and un-extendable.  It acts to
encapsulate
689
 * all control and shepherding of database connections into a single
location
690
 * without the use of globals.
691
 *
692
 */
6932367
abstract class Database {
694
695
  /**
696
   * Flag to indicate a query call should simply return NULL.
697
   *
698
   * This is used for queries that have no reasonable return value
699
   * anyway, such as INSERT statements to a table without a serial
700
   * primary key.
701
   */
702
  const RETURN_NULL = 0;
703
704
  /**
705
   * Flag to indicate a query call should return the prepared statement.
706
   */
707
  const RETURN_STATEMENT = 1;
708
709
  /**
710
   * Flag to indicate a query call should return the number of affected
rows.
711
   */
712
  const RETURN_AFFECTED = 2;
713
714
  /**
715
   * Flag to indicate a query call should return the "last insert id".
716
   */
717
  const RETURN_INSERT_ID = 3;
718
719
  /**
720
   * An nested array of all active connections.  It is keyed by database
name and target.
721
   *
722
   * @var array
723
   */
724
  static protected $connections = array();
725
726
  /**
727
   * A processed copy of the database connection information from
settings.php
728
   *
729
   * @var array
730
   */
731
  static protected $databaseInfo = NULL;
732
733
  /**
734
   * A list of key/target credentials to simply ignore.
735
   *
736
   * @var array
737
   */
738
  static protected $ignoreTargets = array();
739
740
  /**
741
   * The key of the currently active database connection.
742
   *
743
   * @var string
744
   */
745
  static protected $activeKey = 'default';
746
747
  /**
748
   * An array of active query log objects.
749
   *
750
   * Every connection has one and only one logger object for all targets
751
   * and logging keys.
752
   *
753
   * array(
754
   *   '$db_key' => DatabaseLog object.
755
   * );
756
   *
757
   * @var array
758
   */
759
  static protected $logs = array();
760
761
  /**
762
   * Start logging a given logging key on the specified connection.
763
   *
764
   * @see DatabaseLog
765
   * @param $logging_key
766
   *   The logging key to log.
767
   * @param $key
768
   *   The database connection key for which we want to log.
769
   * @return
770
   *   The query log object.  Note that the log object does support richer
771
   *   methods than the few exposed through the Database class, so in some
772
   *   cases it may be desirable to access it directly.
773
   */
774
  final public static function startLog($logging_key, $key = 'default') {
7751
    if (empty(self::$logs[$key])) {
7761
      self::$logs[$key] = new DatabaseLog($key);
777
778
      // Every target already active for this connection key needs to have
779
      // the logging object associated with it.
7801
      if (!empty(self::$connections[$key])) {
7811
        foreach (self::$connections[$key] as $connection) {
7821
          $connection->setLogger(self::$logs[$key]);
7831
        }
7841
      }
7851
    }
786
7871
    self::$logs[$key]->start($logging_key);
7881
    return self::$logs[$key];
7890
  }
790
791
  /**
792
   * Retrieve the queries logged on for given logging key.
793
   *
794
   * This method also ends logging for the specified key.  To get the query
log
795
   * to date without ending the logger request the logging object by
starting
796
   * it again (which does nothing to an open log key) and call methods on
it as
797
   * desired.
798
   *
799
   * @see DatabaseLog
800
   * @param $logging_key
801
   *   The logging key to log.
802
   * @param $key
803
   *   The database connection key for which we want to log.
804
   * @return
805
   *   The query log for the specified logging key and connection.
806
   */
807
  final public static function getLog($logging_key, $key = 'default') {
8081
    if (empty(self::$logs[$key])) {
8090
      return NULL;
8100
    }
8111
    $queries = self::$logs[$key]->get($logging_key);
8121
    self::$logs[$key]->end($logging_key);
8131
    return $queries;
8140
  }
815
816
  /**
817
   * Gets the active connection object for the specified target.
818
   *
819
   * @return
820
   *   The active connection object.
821
   */
822
  final public static function getActiveConnection($target = 'default') {
823
    // This could just be a call to getConnection(), but that's an extra
824
    // method call for every single query.
8252498
    if (!empty(self::$ignoreTargets[self::$activeKey][$target])) {
8260
      $target = 'default';
8270
    }
828
8292498
    if (!isset(self::$connections[self::$activeKey][$target])) {
830
      // If we're trying to open a target that doesn't exist, we need to
know
831
      // what the actual target we got was.
8322368
      $target = self::openConnection(self::$activeKey, $target);
8332368
    }
834
8352498
    return isset(self::$connections[self::$activeKey][$target]) ?
self::$connections[self::$activeKey][$target] : NULL;
8360
  }
837
838
  /**
839
   * Gets the connection object for the specified database key and target.
840
   *
841
   * @return
842
   *   The corresponding connection object.
843
   */
844
  final public static function getConnection($key = 'default', $target =
'default') {
845704
    if (!empty(self::$ignoreTargets[$key][$target])) {
8461
      $target = 'default';
8471
    }
848
849704
    if (!isset(self::$connections[$key][$target])) {
850
      // If we're trying to open a target that doesn't exist, we need to
know
851
      // what the actual target we got was.
8521
      $target = self::openConnection(self::$activeKey, $target);
8531
    }
854
855704
    return isset(self::$connections[$key][$target]) ?
self::$connections[$key][$target] : NULL;
8560
  }
857
858
  /**
859
   * Determine if there is an active connection.
860
   *
861
   * Note that this method will return FALSE if no connection has been
established
862
   * yet, even if one could be.
863
   *
864
   * @return
865
   *   TRUE if there is at least one database connection established, FALSE
otherwise.
866
   */
867
  final public static function isActiveConnection() {
8682163
    return !empty(self::$activeKey) && !empty(self::$connections) &&
!empty(self::$connections[self::$activeKey]);
8690
  }
870
871
  /**
872
   * Set the active connection to the specified key.
873
   *
874
   * @return
875
   *   The previous database connection key.
876
   */
877
  final public static function setActiveConnection($key = 'default') {
8781
    if (empty(self::$databaseInfo)) {
8790
      self::parseConnectionInfo();
8800
    }
881
8821
    if (!empty(self::$databaseInfo[$key])) {
8831
      $old_key = self::$activeKey;
8841
      self::$activeKey = $key;
8851
      return $old_key;
8860
    }
8870
  }
888
889
  /**
890
   * Process the configuration file for database information.
891
   */
892
  final protected static function parseConnectionInfo() {
8932367
    global $databases;
894
8952367
    if (empty($databases)) {
8960
      _db_need_install();
8970
    }
8982367
    $databaseInfo = $databases;
899
9002367
    foreach ($databaseInfo as $index => $info) {
9012367
      foreach ($databaseInfo[$index] as $target => $value) {
902
        // If there is no "driver" property, then we assume it's an array
of
903
        // possible connections for this target.  Pick one at random.  That
904
        // allows us to have, for example, multiple slave servers.
9052367
        if (empty($value['driver'])) {
9060
          $databaseInfo[$index][$target] =
$databaseInfo[$index][$target][mt_rand(0,
count($databaseInfo[$index][$target]) - 1)];
9070
        }
9082367
      }
9092367
    }
910
9112367
    self::$databaseInfo = $databaseInfo;
9122367
  }
913
914
  /**
915
   * Add database connection info for a given key/target.
916
   *
917
   * This method allows the addition of new connection credentials at
runtime.
918
   * Under normal circumstances the preferred way to specify database
credentials
919
   * is via settings.php.  However, this method allows them to be added at
920
   * arbitrary times, such as during unit tests, when connecting to
admin-defined
921
   * third party databases, etc.
922
   *
923
   * If the given key/target pair already exists, this method will be
ignored.
924
   *
925
   * @param $key
926
   *   The database key.
927
   * @param $target
928
   *   The database target name.
929
   * @param $info
930
   *   The database connection information, as it would be defined in
settings.php.
931
   *   Note that the structure of this array will depend on the database
driver
932
   *   it is connecting to.
933
   */
934
  public static function addConnectionInfo($key, $target, $info) {
9352
    if (empty(self::$databaseInfo[$key][$target])) {
9362
      self::$databaseInfo[$key][$target] = $info;
9372
    }
9382
  }
939
940
  /**
941
   * Gets information on the specified database connection.
942
   *
943
   * @param $connection
944
   *   The connection key for which we want information.
945
   */
946
  final public static function getConnectionInfo($key = 'default') {
947146
    if (empty(self::$databaseInfo)) {
9480
      self::parseConnectionInfo();
9490
    }
950
951146
    if (!empty(self::$databaseInfo[$key])) {
952146
      return self::$databaseInfo[$key];
9530
    }
954
9550
  }
956
957
  /**
958
   * Open a connection to the server specified by the given key and target.
959
   *
960
   * @param $key
961
   *   The database connection key, as specified in settings.php.  The
default
962
   *   is "default".
963
   * @param $target
964
   *   The database target to open.  If the specified target does not
exist,
965
   *   the "default" target will be used instead.
966
   * @return
967
   *   The name of the target that was actually opened.
968
   */
969
  final protected static function openConnection($key, $target) {
9702369
    global $db_prefix;
971
9722369
    if (empty(self::$databaseInfo)) {
9732367
      self::parseConnectionInfo();
9742367
    }
975
    try {
976
      // If the requested database does not exist then it is an
unrecoverable error.
977
      // If the requested target does not exist, however, we fall back to
the default
978
      // target.  The target is typically either "default" or "slave",
indicating to
979
      // use a slave SQL server if one is available.  If it's not
available, then the
980
      // default/master server is the correct server to use.
9812369
      if (!isset(self::$databaseInfo[$key])) {
9820
        throw new Exception('DB does not exist');
9830
      }
9842369
      if (!isset(self::$databaseInfo[$key][$target])) {
9851
        $target = 'default';
9861
      }
987
9882369
      if (!$driver = self::$databaseInfo[$key][$target]['driver']) {
9890
        throw new Exception('Drupal is not set up');
9900
      }
991
992
      // We cannot rely on the registry yet, because the registry requires
993
      // an open database connection.
9942369
      $driver_class = 'DatabaseConnection_' . $driver;
9952369
      require_once DRUPAL_ROOT . '/includes/database/' . $driver .
'/database.inc';
9962369
      self::$connections[$key][$target] = new
$driver_class(self::$databaseInfo[$key][$target]);
9972369
      self::$connections[$key][$target]->setTarget($target);
998
999
      // If we have any active logging objects for this connection key, we
need
1000
      // to associate them with the connection we just opened.
10012369
      if (!empty(self::$logs[$key])) {
10021
        self::$connections[$key][$target]->setLogger(self::$logs[$key]);
10031
      }
1004
1005
      // We need to pass around the simpletest database prefix in the
request
1006
      // and we put that in the user_agent header.
10072369
      if (preg_match("/^simpletest\d+$/", $_SERVER['HTTP_USER_AGENT'])) {
10082367
        $db_prefix .= $_SERVER['HTTP_USER_AGENT'];
10092367
      }
1010
1011
      // Return the target that was actually opened in case the requested
one
1012
      // didn't exist.
10132369
      return $target;
1014
    }
10150
    catch (Exception $e) {
1016
      // It is extremely rare that an exception will be generated here
other
1017
      // than when installing.  We therefore intercept it and try the
installer,
1018
      // passing on the exception otherwise.
10190
      _db_need_install();
10200
      throw $e;
1021
    }
10220
  }
1023
1024
  /**
1025
   * Instruct the system to temporarily ignore a given key/target.
1026
   *
1027
   * At times we need to temporarily disable slave queries.  To do so,
1028
   * call this method with the database key and the target to disable.
1029
   * That database key will then always fall back to 'default' for that
1030
   * key, even if it's defined.
1031
   *
1032
   * @param $key
1033
   *   The database connection key.
1034
   * @param $target
1035
   *   The target of the specified key to ignore.
1036
   */
1037
  public static function ignoreTarget($key, $target) {
10381
    self::$ignoreTargets[$key][$target] = TRUE;
10391
  }
1040
1041
}
1042
1043
/**
1044
 * Exception to mark databases that do not support transations.
1045
 *
1046
 * This exception will be thrown when a transaction is started that does
not
1047
 * allow for the "silent fallback" of no transaction and the database
connection
1048
 * in use does not support transactions.  The calling code must then take
1049
 * appropriate action.
1050
 */
10512367
class TransactionsNotSupportedException extends PDOException { }
1052
1053
/**
1054
 * A wrapper class for creating and managing database transactions.
1055
 *
1056
 * Not all databases or database configurations support transactions.  For
1057
 * example, MySQL MyISAM tables do not.  It is also easy to begin a
transaction
1058
 * and then forget to commit it, which can lead to connection errors when
1059
 * another transaction is started.
1060
 *
1061
 * This class acts as a wrapper for transactions.  To begin a transaction,
1062
 * simply instantiate it.  When the object goes out of scope and is
destroyed
1063
 * it will automatically commit.  It also will check to see if the
specified
1064
 * connection supports transactions.  If not, it will simply skip any
transaction
1065
 * commands, allowing user-space code to proceed normally.  The only
difference
1066
 * is that rollbacks won't actually do anything.
1067
 *
1068
 * In the vast majority of cases, you should not instantiate this class
directly.
1069
 * Instead, call ->startTransaction() from the appropriate connection
object.
1070
 */
10712367
class DatabaseTransaction {
1072
1073
  /**
1074
   * The connection object for this transaction.
1075
   *
1076
   * @var DatabaseConnection
1077
   */
1078
  protected $connection;
1079
1080
  /**
1081
   * Whether or not this connection supports transactions.
1082
   *
1083
   * This can be derived from the connection itself with a method call,
1084
   * but is cached here for performance.
1085
   *
1086
   * @var boolean
1087
   */
1088
  protected $supportsTransactions;
1089
1090
  /**
1091
   * Whether or not this transaction has been rolled back.
1092
   *
1093
   * @var boolean
1094
   */
1095
  protected $hasRolledBack = FALSE;
1096
1097
  /**
1098
   * Whether or not this transaction has been committed.
1099
   *
1100
   * @var boolean
1101
   */
1102
  protected $hasCommitted = FALSE;
1103
1104
  /**
1105
   * Track the number of "layers" of transactions currently active.
1106
   *
1107
   * On many databases transactions cannot nest.  Instead, we track
1108
   * nested calls to transactions and collapse them into a single
1109
   * transaction.
1110
   *
1111
   * @var int
1112
   */
1113
  protected static $layers = 0;
1114
1115
  public function __construct(DatabaseConnection $connection) {
11160
    $this->connection = $connection;
11170
    $this->supportsTransactions = $connection->supportsTransactions();
1118
11190
    if (self::$layers == 0 && $this->supportsTransactions) {
11200
      $connection->beginTransaction();
11210
    }
1122
11230
    ++self::$layers;
11240
  }
1125
1126
  /**
1127
   * Commit this transaction.
1128
   */
1129
  public function commit() {
11300
    --self::$layers;
11310
    if (self::$layers == 0 && $this->supportsTransactions) {
11320
      $this->connection->commit();
11330
      $this->hasCommitted = TRUE;
11340
    }
11350
  }
1136
1137
  /**
1138
   * Roll back this transaction.
1139
   */
1140
  public function rollBack() {
11410
    if ($this->supportsTransactions) {
11420
      $this->connection->rollBack();
11430
      $this->hasRolledBack = TRUE;
11440
    }
11450
  }
1146
1147
  /**
1148
   * Determine if this transaction has already been rolled back.
1149
   *
1150
   * @return
1151
   *   TRUE if the transaction has been rolled back, FALSE otherwise.
1152
   */
1153
  public function hasRolledBack() {
11540
    return $this->hasRolledBack;
11550
  }
1156
1157
  public function __destruct() {
11580
    --self::$layers;
11590
    if (self::$layers == 0 && $this->supportsTransactions &&
!$this->hasRolledBack && !$this->hasCommitted) {
11600
      $this->connection->commit();
11610
    }
11620
  }
1163
1164
}
1165
1166
/**
1167
 * Prepared statement class.
1168
 *
1169
 * PDO allows us to extend the PDOStatement class to provide additional
1170
 * functionality beyond that offered by default.  We do need extra
1171
 * functionality.  By default, this class is not driver-specific.  If a
given
1172
 * driver needs to set a custom statement class, it may do so in its
constructor.
1173
 *
1174
 * @link http://us.php.net/pdostatement
1175
 */
11762367
class DatabaseStatement extends PDOStatement {
1177
1178
  /**
1179
   * Reference to the database connection object for this statement.
1180
   *
1181
   * The name $dbh is inherited from PDOStatement.
1182
   *
1183
   * @var DatabaseConnection
1184
   */
1185
  public $dbh;
1186
1187
  protected function __construct($dbh) {
11882498
    $this->dbh = $dbh;
11892498
    $this->setFetchMode(PDO::FETCH_OBJ);
11902498
  }
1191
1192
  /**
1193
   * Executes a prepared statement
1194
   *
1195
   * @param $args
1196
   *   An array of values with as many elements as there are bound
parameters in the SQL statement being executed.
1197
   * @param $options
1198
   *   An array of options for this query.
1199
   * @return
1200
   *   TRUE on success, or FALSE on failure.
1201
   */
1202
  public function execute($args, $options) {
12032498
    if (isset($options['fetch'])) {
12042498
      if (is_string($options['fetch'])) {
1205
        // Default to an object. Note: db fields will be added to the
object
1206
        // before the constructor is run. If you need to assign fields
after
1207
        // the constructor is run, see http://drupal.org/node/315092.
12081
        $this->setFetchMode(PDO::FETCH_CLASS, $options['fetch']);
12091
      }
1210
      else {
12112498
        $this->setFetchMode($options['fetch']);
1212
      }
12132498
    }
12142498
    $this->dbh->lastStatement = $this;
1215
12162498
    $logger = $this->dbh->getLogger();
12172498
    if (!empty($logger)) {
12181
      $query_start = microtime(TRUE);
12191
    }
1220
12212498
    $return = parent::execute($args);
1222
12232498
    if (!empty($logger)) {
12241
      $query_end = microtime(TRUE);
12251
      $logger->log($this, $args, $query_end - $query_start);
12261
    }
1227
12282498
    return $return;
12290
  }
1230
1231
  /**
1232
   * Returns an entire single column of a result set as an indexed array.
1233
   *
1234
   * Note that this method will run the result set to the end.
1235
   *
1236
   * @param $index
1237
   *   The index of the column number to fetch.
1238
   * @return
1239
   *   An indexed array.
1240
   */
1241
  public function fetchCol($index = 0) {
12422362
    return $this->fetchAll(PDO::FETCH_COLUMN, $index);
12430
  }
1244
1245
  /**
1246
   * Returns an entire result set as an associative array keyed by the
named field.
1247
   *
1248
   * If the given key appears multiple times, later records will overwrite
1249
   * earlier ones.
1250
   *
1251
   * Note that this method will run the result set to the end.
1252
   *
1253
   * @param $key
1254
   *   The name of the field on which to index the array.
1255
   * @param $fetch
1256
   *   The fetchmode to use.  If set to   PDO::FETCH_ASSOC, PDO::FETCH_NUM,
or
1257
   *   PDO::FETCH_BOTH the returned value with be an array of arrays.  For
any
1258
   *   other value it will be an array of objects.
1259
   * @return
1260
   *   An associative array.
1261
   */
1262
  public function fetchAllAssoc($key, $fetch = PDO::FETCH_OBJ) {
1263514
    $return = array();
1264514
    $this->setFetchMode($fetch);
1265514
    if (in_array($fetch, array(PDO::FETCH_ASSOC, PDO::FETCH_NUM,
PDO::FETCH_BOTH))) {
1266212
      foreach ($this as $record) {
126779
        $return[$record[$key]] = $record;
126879
      }
1269212
    }
1270
    else {
1271306
      foreach ($this as $record) {
1272306
        $return[$record->$key] = $record;
1273306
      }
1274
    }
1275514
    return $return;
12760
  }
1277
1278
  /**
1279
   * Returns the entire result set as a single associative array.
1280
   *
1281
   * This method is only useful for two-column result sets.  It will return
1282
   * an associative array where the key is one column from the result set
1283
   * and the value is another field.  In most cases, the default of the
first two
1284
   * columns is appropriate.
1285
   *
1286
   * Note that this method will run the result set to the end.
1287
   *
1288
   * @param $key_index
1289
   *   The numeric index of the field to use as the array key.
1290
   * @param $value_index
1291
   *   The numeric index of the field to use as the array value.
1292
   * @return
1293
   *   An associative array.
1294
   */
1295
  public function fetchAllKeyed($key_index = 0, $value_index = 1) {
1296484
    $return = array();
1297484
    $this->setFetchMode(PDO::FETCH_NUM);
1298484
    foreach ($this as $record) {
1299484
      $return[$record[$key_index]] = $record[$value_index];
1300484
    }
1301484
    return $return;
13020
  }
1303
1304
  /**
1305
   * Return a single field out of the current
1306
   *
1307
   * @param $index
1308
   *   The numeric index of the field to return.  Defaults to the first
field.
1309
   * @return
1310
   *   A single field from the next record.
1311
   */
1312
  public function fetchField($index = 0) {
1313
    // Call PDOStatement::fetchColumn to fetch the field.
13142497
    return $this->fetchColumn($index);
13150
  }
1316
1317
  /**
1318
   * Fetches the next row and returns it as an associative array.
1319
   *
1320
   * This method corresponds to PDOStatement::fetchObject(),
1321
   * but for associative arrays.  For some reason PDOStatement does
1322
   * not have a corresponding array helper method, so one is added.
1323
   *
1324
   * @return
1325
   *   An associative array.
1326
   */
1327
  public function fetchAssoc() {
1328
    // Call PDOStatement::fetch to fetch the row.
132926
    return $this->fetch(PDO::FETCH_ASSOC);
13300
  }
1331
}
1332
1333
/**
1334
 * The following utility functions are simply convenience wrappers.
1335
 * They should never, ever have any database-specific code in them.
1336
 */
1337
1338
/**
1339
 * Execute an arbitrary query string against the active database.
1340
 *
1341
 * Do not use this function for INSERT, UPDATE, or DELETE queries.  Those
should
1342
 * be handled via the appropriate query builder factory.  Use this function
for
1343
 * SELECT queries that do not require a query builder.
1344
 *
1345
 * @see DatabaseConnection::defaultOptions()
1346
 * @param $query
1347
 *   The prepared statement query to run.  Although it will accept both
1348
 *   named and unnamed placeholders, named placeholders are strongly
preferred
1349
 *   as they are more self-documenting.
1350
 * @param $args
1351
 *   An array of values to substitute into the query.  If the query uses
named
1352
 *   placeholders, this is an associative array in any order.  If the query
uses
1353
 *   unnamed placeholders (?), this is an indexed array and the order must
match
1354
 *   the order of placeholders in the query string.
1355
 * @param $options
1356
 *   An array of options to control how the query operates.
1357
 * @return
1358
 *   A prepared statement object, already executed.
1359
 */
13602367
function db_query($query, $args = array(), $options = array()) {
13612498
  if (!is_array($args)) {
13622485
    $args = func_get_args();
13632485
    array_shift($args);
13642485
  }
13652498
  list($query, $args, $options) = _db_query_process_args($query, $args,
$options);
1366
13672498
  return Database::getActiveConnection($options['target'])->query($query,
$args, $options);
13680
}
1369
1370
/**
1371
 * Execute an arbitrary query string against the active database,
restricted to a specified range.
1372
 *
1373
 * @see DatabaseConnection::defaultOptions()
1374
 * @param $query
1375
 *   The prepared statement query to run.  Although it will accept both
1376
 *   named and unnamed placeholders, named placeholders are strongly
preferred
1377
 *   as they are more self-documenting.
1378
 * @param $args
1379
 *   An array of values to substitute into the query.  If the query uses
named
1380
 *   placeholders, this is an associative array in any order.  If the query
uses
1381
 *   unnamed placeholders (?), this is an indexed array and the order must
match
1382
 *   the order of placeholders in the query string.
1383
 * @param $from
1384
 *   The first record from the result set to return.
1385
 * @param $limit
1386
 *   The number of records to return from the result set.
1387
 * @param $options
1388
 *   An array of options to control how the query operates.
1389
 * @return
1390
 *   A prepared statement object, already executed.
1391
 */
13922367
function db_query_range($query, $args, $from = 0, $count = 0, $options =
array()) {
13932477
  if (!is_array($args)) {
1394232
    $args = func_get_args();
1395232
    array_shift($args);
1396232
    $count = array_pop($args);
1397232
    $from = array_pop($args);
1398232
  }
13992477
  list($query, $args, $options) = _db_query_process_args($query, $args,
$options);
1400
14012477
  return
Database::getActiveConnection($options['target'])->queryRange($query,
$args, $from, $count, $options);
14020
}
1403
1404
/**
1405
 * Execute a query string against the active database and save the result
set to a temp table.
1406
 *
1407
 * @see DatabaseConnection::defaultOptions()
1408
 * @param $query
1409
 *   The prepared statement query to run.  Although it will accept both
1410
 *   named and unnamed placeholders, named placeholders are strongly
preferred
1411
 *   as they are more self-documenting.
1412
 * @param $args
1413
 *   An array of values to substitute into the query.  If the query uses
named
1414
 *   placeholders, this is an associative array in any order.  If the query
uses
1415
 *   unnamed placeholders (?), this is an indexed array and the order must
match
1416
 *   the order of placeholders in the query string.
1417
 * @param $from
1418
 *   The first record from the result set to return.
1419
 * @param $limit
1420
 *   The number of records to return from the result set.
1421
 * @param $options
1422
 *   An array of options to control how the query operates.
1423
 */
14242367
function db_query_temporary($query, $args, $tablename, $options = array())
{
14250
  if (!is_array($args)) {
14260
    $args = func_get_args();
14270
    array_shift($args);
14280
  }
14290
  list($query, $args, $options) = _db_query_process_args($query, $args,
$options);
1430
14310
  return
Database::getActiveConnection($options['target'])->queryTemporary($query,
$args, $tablename, $options);
14320
}
1433
1434
/**
1435
 * Returns a new InsertQuery object for the active database.
1436
 *
1437
 * @param $table
1438
 *   The table into which to insert.
1439
 * @param $options
1440
 *   An array of options to control how the query operates.
1441
 * @return
1442
 *   A new InsertQuery object for this connection.
1443
 */
14442367
function db_insert($table, Array $options = array()) {
1445238
  if (empty($options['target']) || $options['target'] == 'slave') {
1446238
    $options['target'] = 'default';
1447238
  }
1448238
  return Database::getActiveConnection($options['target'])->insert($table,
$options);
14490
}
1450
1451
/**
1452
 * Returns a new MergeQuery object for the active database.
1453
 *
1454
 * @param $table
1455
 *   The table into which to merge.
1456
 * @param $options
1457
 *   An array of options to control how the query operates.
1458
 * @return
1459
 *   A new MergeQuery object for this connection.
1460
 */
14612367
function db_merge($table, Array $options = array()) {
14621630
  if (empty($options['target']) || $options['target'] == 'slave') {
14631630
    $options['target'] = 'default';
14641630
  }
14651630
  return Database::getActiveConnection($options['target'])->merge($table,
$options);
14660
}
1467
1468
/**
1469
 * Returns a new UpdateQuery object for the active database.
1470
 *
1471
 * @param $table
1472
 *   The table to update.
1473
 * @param $options
1474
 *   An array of options to control how the query operates.
1475
 * @return
1476
 *   A new UpdateQuery object for this connection.
1477
 */
14782367
function db_update($table, Array $options = array()) {
147967
  if (empty($options['target']) || $options['target'] == 'slave') {
148067
    $options['target'] = 'default';
148167
  }
148267
  return Database::getActiveConnection($options['target'])->update($table,
$options);
14830
}
1484
1485
/**
1486
 * Returns a new DeleteQuery object for the active database.
1487
 *
1488
 * @param $table
1489
 *   The table from which to delete.
1490
 * @param $options
1491
 *   An array of options to control how the query operates.
1492
 * @return
1493
 *   A new DeleteQuery object for this connection.
1494
 */
14952367
function db_delete($table, Array $options = array()) {
1496720
  if (empty($options['target']) || $options['target'] == 'slave') {
1497720
    $options['target'] = 'default';
1498720
  }
1499720
  return Database::getActiveConnection($options['target'])->delete($table,
$options);
15000
}
1501
1502
/**
1503
 * Returns a new SelectQuery object for the active database.
1504
 *
1505
 * @param $table
1506
 *   The base table for this query.
1507
 * @param $alias
1508
 *   The alias for the base table of this query.
1509
 * @param $options
1510
 *   An array of options to control how the query operates.
1511
 * @return
1512
 *   A new SelectQuery object for this connection.
1513
 */
15142367
function db_select($table, $alias = NULL, Array $options = array()) {
15152005
  if (empty($options['target'])) {
15162005
    $options['target'] = 'default';
15172005
  }
15182005
  return Database::getActiveConnection($options['target'])->select($table,
$alias, $options);
15190
}
1520
1521
/**
1522
 * Sets a new active database.
1523
 *
1524
 * @param $key
1525
 *   The key in the $databases array to set as the default database.
1526
 * @returns
1527
 *   The key of the formerly active database.
1528
 */
15292367
function db_set_active($key = 'default') {
15301
  return Database::setActiveConnection($key);
15310
}
1532
1533
/**
1534
 * Determine if there is an active connection.
1535
 *
1536
 * Note that this method will return FALSE if no connection has been
established
1537
 * yet, even if one could be.
1538
 *
1539
 * @return
1540
 *   TRUE if there is at least one database connection established, FALSE
otherwise.
1541
 */
15422367
function db_is_active() {
15432163
  return Database::isActiveConnection();
15440
}
1545
1546
/**
1547
 * Restrict a dynamic table, column or constraint name to safe characters.
1548
 *
1549
 * Only keeps alphanumeric and underscores.
1550
 *
1551
 * @param $table
1552
 *   The table name to escape.
1553
 * @return
1554
 *   The escaped table name as a string.
1555
 */
15562367
function db_escape_table($table) {
155716
  return Database::getActiveConnection()->escapeTable($table);
15580
}
1559
1560
/**
1561
 * Perform an SQL query and return success or failure.
1562
 *
1563
 * @param $sql
1564
 *   A string containing a complete SQL query.  %-substitution
1565
 *   parameters are not supported.
1566
 * @return
1567
 *   An array containing the keys:
1568
 *     success: a boolean indicating whether the query succeeded
1569
 *     query: the SQL query executed, passed through check_plain()
1570
 */
15712367
function update_sql($sql) {
1572137
  $result = Database::getActiveConnection()->query($sql);
1573137
  return array('success' => $result !== FALSE, 'query' =>
check_plain($sql));
15740
}
1575
1576
/**
1577
 * Generate placeholders for an array of query arguments of a single type.
1578
 *
1579
 * Given a Schema API field type, return correct %-placeholders to
1580
 * embed in a query
1581
 *
1582
 * @todo This may be possible to remove in favor of db_select().
1583
 * @param $arguments
1584
 *   An array with at least one element.
1585
 * @param $type
1586
 *   The Schema API type of a field (e.g. 'int', 'text', or 'varchar').
1587
 */
15882367
function db_placeholders($arguments, $type = 'int') {
15892207
  $placeholder = db_type_placeholder($type);
15902207
  return implode(',', array_fill(0, count($arguments), $placeholder));
15910
}
1592
1593
/**
1594
 * Wraps the given table.field entry with a DISTINCT(). The wrapper is
added to
1595
 * the SELECT list entry of the given query and the resulting query is
returned.
1596
 * This function only applies the wrapper if a DISTINCT doesn't already
exist in
1597
 * the query.
1598
 *
1599
 * @todo Remove this.
1600
 * @param $table
1601
 *   Table containing the field to set as DISTINCT
1602
 * @param $field
1603
 *   Field to set as DISTINCT
1604
 * @param $query
1605
 *   Query to apply the wrapper to
1606
 * @return
1607
 *   SQL query with the DISTINCT wrapper surrounding the given table.field.
1608
 */
16092367
function db_distinct_field($table, $field, $query) {
16100
  return Database::getActiveConnection()->distinctField($table, $field,
$query);
16110
}
1612
1613
/**
1614
 * Retrieve the name of the currently active database driver, such as
1615
 * "mysql" or "pgsql".
1616
 *
1617
 * @return The name of the currently active database driver.
1618
 */
16192367
function db_driver() {
1620134
  return Database::getActiveConnection()->driver();
16210
}
1622
1623
/**
1624
 * @} End of "defgroup database".
1625
 */
1626
1627
1628
/**
1629
 * @ingroup schemaapi
1630
 * @{
1631
 */
1632
1633
1634
/**
1635
 * Create a new table from a Drupal table definition.
1636
 *
1637
 * @param $ret
1638
 *   Array to which query results will be added.
1639
 * @param $name
1640
 *   The name of the table to create.
1641
 * @param $table
1642
 *   A Schema API table definition array.
1643
 */
16442367
function db_create_table(&$ret, $name, $table) {
1645136
  return Database::getActiveConnection()->schema()->createTable($ret,
$name, $table);
16460
}
1647
1648
/**
1649
 * Return an array of field names from an array of key/index column
specifiers.
1650
 *
1651
 * This is usually an identity function but if a key/index uses a column
prefix
1652
 * specification, this function extracts just the name.
1653
 *
1654
 * @param $fields
1655
 *   An array of key/index column specifiers.
1656
 * @return
1657
 *   An array of field names.
1658
 */
16592367
function db_field_names($fields) {
16600
  return Database::getActiveConnection()->schema()->fieldNames($fields);
16610
}
1662
1663
/**
1664
 * Check if a table exists.
1665
 */
16662367
function db_table_exists($table) {
166721
  return Database::getActiveConnection()->schema()->tableExists($table);
16680
}
1669
1670
/**
1671
 * Check if a column exists in the given table.
1672
 */
16732367
function db_column_exists($table, $column) {
16740
  return Database::getActiveConnection()->schema()->columnExists($table,
$column);
16750
}
1676
1677
/**
1678
 * Find all tables that are like the specified base table name.
1679
 *
1680
 * @param $table_expression
1681
 *   An SQL expression, for example "simpletest%" (without the quotes).
1682
 *   BEWARE: this is not prefixed, the caller should take care of that.
1683
 * @return
1684
 *   Array, both the keys and the values are the matching tables.
1685
 */
16862367
function db_find_tables($table_expression) {
16871
  return
Database::getActiveConnection()->schema()->findTables($table_expression);
16880
}
1689
1690
/**
1691
 * Given a Schema API field type, return the correct %-placeholder.
1692
 *
1693
 * Embed the placeholder in a query to be passed to db_query and and pass
as an
1694
 * argument to db_query a value of the specified type.
1695
 *
1696
 * @todo Remove this after all queries are converted to type-agnostic form.
1697
 * @param $type
1698
 *   The Schema API type of a field.
1699
 * @return
1700
 *   The placeholder string to embed in a query for that type.
1701
 */
17022367
function db_type_placeholder($type) {
1703
  switch ($type) {
17042207
    case 'varchar':
17052207
    case 'char':
17062207
    case 'text':
17072207
    case 'datetime':
1708157
      return '\'%s\'';
1709
17102078
    case 'numeric':
1711
      // Numeric values are arbitrary precision numbers.  Syntacically,
numerics
1712
      // should be specified directly in SQL. However, without single
quotes
1713
      // the %s placeholder does not protect against non-numeric characters
such
1714
      // as spaces which would expose us to SQL injection.
17150
      return '%n';
1716
17172078
    case 'serial':
17182078
    case 'int':
17192078
      return '%d';
1720
17210
    case 'float':
17220
      return '%f';
1723
17240
    case 'blob':
17250
      return '%b';
17260
  }
1727
1728
  // There is no safe value to return here, so return something that
1729
  // will cause the query to fail.
17300
  return 'unsupported type ' . $type . 'for db_type_placeholder';
17310
}
1732
1733
17342367
function _db_create_keys_sql($spec) {
17350
  return Database::getActiveConnection()->schema()->createKeysSql($spec);
17360
}
1737
1738
/**
1739
 * This maps a generic data type in combination with its data size
1740
 * to the engine-specific data type.
1741
 */
17422367
function db_type_map() {
1743136
  return Database::getActiveConnection()->schema()->getFieldTypeMap();
17440
}
1745
1746
/**
1747
 * Rename a table.
1748
 *
1749
 * @param $ret
1750
 *   Array to which query results will be added.
1751
 * @param $table
1752
 *   The table to be renamed.
1753
 * @param $new_name
1754
 *   The new name for the table.
1755
 */
17562367
function db_rename_table(&$ret, $table, $new_name) {
17570
  return Database::getActiveConnection()->schema()->renameTable($ret,
$table, $new_name);
17580
}
1759
1760
/**
1761
 * Drop a table.
1762
 *
1763
 * @param $ret
1764
 *   Array to which query results will be added.
1765
 * @param $table
1766
 *   The table to be dropped.
1767
 */
17682367
function db_drop_table(&$ret, $table) {
1769135
  return Database::getActiveConnection()->schema()->dropTable($ret,
$table);
17700
}
1771
1772
/**
1773
 * Add a new field to a table.
1774
 *
1775
 * @param $ret
1776
 *   Array to which query results will be added.
1777
 * @param $table
1778
 *   Name of the table to be altered.
1779
 * @param $field
1780
 *   Name of the field to be added.
1781
 * @param $spec
1782
 *   The field specification array, as taken from a schema definition.
1783
 *   The specification may also contain the key 'initial', the newly
1784
 *   created field will be set to the value of the key in all rows.
1785
 *   This is most useful for creating NOT NULL columns with no default
1786
 *   value in existing tables.
1787
 * @param $keys_new
1788
 *   Optional keys and indexes specification to be created on the
1789
 *   table along with adding the field. The format is the same as a
1790
 *   table specification but without the 'fields' element.  If you are
1791
 *   adding a type 'serial' field, you MUST specify at least one key
1792
 *   or index including it in this array. @see db_change_field for more
1793
 *   explanation why.
1794
 */
17952367
function db_add_field(&$ret, $table, $field, $spec, $keys_new = array()) {
17960
  return Database::getActiveConnection()->schema()->addField($ret, $table,
$field, $spec, $keys_new);
17970
}
1798
1799
/**
1800
 * Drop a field.
1801
 *
1802
 * @param $ret
1803
 *   Array to which query results will be added.
1804
 * @param $table
1805
 *   The table to be altered.
1806
 * @param $field
1807
 *   The field to be dropped.
1808
 */
18092367
function db_drop_field(&$ret, $table, $field) {
18100
  return Database::getActiveConnection()->schema()->dropField($ret, $table,
$field);
18110
}
1812
1813
/**
1814
 * Set the default value for a field.
1815
 *
1816
 * @param $ret
1817
 *   Array to which query results will be added.
1818
 * @param $table
1819
 *   The table to be altered.
1820
 * @param $field
1821
 *   The field to be altered.
1822
 * @param $default
1823
 *   Default value to be set. NULL for 'default NULL'.
1824
 */
18252367
function db_field_set_default(&$ret, $table, $field, $default) {
18260
  return Database::getActiveConnection()->schema()->fieldSetDefault($ret,
$table, $field, $default);
18270
}
1828
1829
/**
1830
 * Set a field to have no default value.
1831
 *
1832
 * @param $ret
1833
 *   Array to which query results will be added.
1834
 * @param $table
1835
 *   The table to be altered.
1836
 * @param $field
1837
 *   The field to be altered.
1838
 */
18392367
function db_field_set_no_default(&$ret, $table, $field) {
18400
  return Database::getActiveConnection()->schema()->fieldSetNoDefault($ret,
$table, $field);
18410
}
1842
1843
/**
1844
 * Add a primary key.
1845
 *
1846
 * @param $ret
1847
 *   Array to which query results will be added.
1848
 * @param $table
1849
 *   The table to be altered.
1850
 * @param $fields
1851
 *   Fields for the primary key.
1852
 */
18532367
function db_add_primary_key(&$ret, $table, $fields) {
18540
  return Database::getActiveConnection()->schema()->addPrimaryKey($ret,
$table, $field);
18550
}
1856
1857
/**
1858
 * Drop the primary key.
1859
 *
1860
 * @param $ret
1861
 *   Array to which query results will be added.
1862
 * @param $table
1863
 *   The table to be altered.
1864
 */
18652367
function db_drop_primary_key(&$ret, $table) {
18660
  return Database::getActiveConnection()->schema()->dropPrimaryKey($ret,
$table);
18670
}
1868
1869
/**
1870
 * Add a unique key.
1871
 *
1872
 * @param $ret
1873
 *   Array to which query results will be added.
1874
 * @param $table
1875
 *   The table to be altered.
1876
 * @param $name
1877
 *   The name of the key.
1878
 * @param $fields
1879
 *   An array of field names.
1880
 */
18812367
function db_add_unique_key(&$ret, $table, $name, $fields) {
18820
  return Database::getActiveConnection()->schema()->addUniqueKey($ret,
$table, $name, $fields);
18830
}
1884
1885
/**
1886
 * Drop a unique key.
1887
 *
1888
 * @param $ret
1889
 *   Array to which query results will be added.
1890
 * @param $table
1891
 *   The table to be altered.
1892
 * @param $name
1893
 *   The name of the key.
1894
 */
18952367
function db_drop_unique_key(&$ret, $table, $name) {
18960
  return Database::getActiveConnection()->schema()->dropUniqueKey($ret,
$table, $name);
18970
}
1898
1899
/**
1900
 * Add an index.
1901
 *
1902
 * @param $ret
1903
 *   Array to which query results will be added.
1904
 * @param $table
1905
 *   The table to be altered.
1906
 * @param $name
1907
 *   The name of the index.
1908
 * @param $fields
1909
 *   An array of field names.
1910
 */
19112367
function db_add_index(&$ret, $table, $name, $fields) {
19120
  return Database::getActiveConnection()->schema()->addIndex($ret, $table,
$name, $fields);
19130
}
1914
1915
/**
1916
 * Drop an index.
1917
 *
1918
 * @param $ret
1919
 *   Array to which query results will be added.
1920
 * @param $table
1921
 *   The table to be altered.
1922
 * @param $name
1923
 *   The name of the index.
1924
 */
19252367
function db_drop_index(&$ret, $table, $name) {
19260
  return Database::getActiveConnection()->schema()->addIndex($ret, $table,
$name);
19270
}
1928
1929
/**
1930
 * Change a field definition.
1931
 *
1932
 * IMPORTANT NOTE: To maintain database portability, you have to explicitly
1933
 * recreate all indices and primary keys that are using the changed field.
1934
 *
1935
 * That means that you have to drop all affected keys and indexes with
1936
 * db_drop_{primary_key,unique_key,index}() before calling
db_change_field().
1937
 * To recreate the keys and indices, pass the key definitions as the
1938
 * optional $keys_new argument directly to db_change_field().
1939
 *
1940
 * For example, suppose you have:
1941
 * @code
1942
 * $schema['foo'] = array(
1943
 *   'fields' => array(
1944
 *     'bar' => array('type' => 'int', 'not null' => TRUE)
1945
 *   ),
1946
 *   'primary key' => array('bar')
1947
 * );
1948
 * @endcode
1949
 * and you want to change foo.bar to be type serial, leaving it as the
1950
 * primary key.  The correct sequence is:
1951
 * @code
1952
 * db_drop_primary_key($ret, 'foo');
1953
 * db_change_field($ret, 'foo', 'bar', 'bar',
1954
 *   array('type' => 'serial', 'not null' => TRUE),
1955
 *   array('primary key' => array('bar')));
1956
 * @endcode
1957
 *
1958
 * The reasons for this are due to the different database engines:
1959
 *
1960
 * On PostgreSQL, changing a field definition involves adding a new field
1961
 * and dropping an old one which* causes any indices, primary keys and
1962
 * sequences (from serial-type fields) that use the changed field to be
dropped.
1963
 *
1964
 * On MySQL, all type 'serial' fields must be part of at least one key
1965
 * or index as soon as they are created.  You cannot use
1966
 * db_add_{primary_key,unique_key,index}() for this purpose because
1967
 * the ALTER TABLE command will fail to add the column without a key
1968
 * or index specification.  The solution is to use the optional
1969
 * $keys_new argument to create the key or index at the same time as
1970
 * field.
1971
 *
1972
 * You could use db_add_{primary_key,unique_key,index}() in all cases
1973
 * unless you are converting a field to be type serial. You can use
1974
 * the $keys_new argument in all cases.
1975
 *
1976
 * @param $ret
1977
 *   Array to which query results will be added.
1978
 * @param $table
1979
 *   Name of the table.
1980
 * @param $field
1981
 *   Name of the field to change.
1982
 * @param $field_new
1983
 *   New name for the field (set to the same as $field if you don't want to
change the name).
1984
 * @param $spec
1985
 *   The field specification for the new field.
1986
 * @param $keys_new
1987
 *   Optional keys and indexes specification to be created on the
1988
 *   table along with changing the field. The format is the same as a
1989
 *   table specification but without the 'fields' element.
1990
 */
1991
19922367
function db_change_field(&$ret, $table, $field, $field_new, $spec,
$keys_new = array()) {
19930
  return Database::getActiveConnection()->schema()->changeField($ret,
$table, $field, $field_new, $spec, $keys_new);
19940
}
1995
1996
/**
1997
 * @} End of "ingroup schemaapi".
1998
 */
1999
2000
/**
2001
 * Prints a themed maintenance page with the 'Site offline' text,
2002
 * adding the provided error message in the case of 'display_errors'
2003
 * set to on. Ends the page request; no return.
2004
 */
20052367
function _db_error_page($error = '') {
20060
  global $db_type;
20070
  drupal_init_language();
20080
  drupal_maintenance_theme();
20090
  drupal_set_header($_SERVER['SERVER_PROTOCOL'] . ' 503 Service
Unavailable');
20100
  drupal_set_title('Site offline');
20110
}
2012
2013
/**
2014
 * @ingroup database-legacy
2015
 *
2016
 * These functions are no longer necessary, as the DatabaseStatement object
2017
 * offers this and much more functionality.  They are kept temporarily for
backward
2018
 * compatibility during conversion and should be removed as soon as
possible.
2019
 *
2020
 * @{
2021
 */
2022
20232367
function db_fetch_object(DatabaseStatement $statement) {
20242497
  return $statement->fetch(PDO::FETCH_OBJ);
20250
}
2026
20272367
function db_fetch_array(DatabaseStatement $statement) {
20282484
  return $statement->fetch(PDO::FETCH_ASSOC);
20290
}
2030
20312367
function db_result(DatabaseStatement $statement) {
20322496
  return $statement->fetchField();
20330
}
2034
20352367
function _db_need_install() {
20360
  if (!function_exists('install_goto')) {
20370
    include_once DRUPAL_ROOT . '/includes/install.inc';
20380
    install_goto('install.php');
20390
  }
20400
}
2041
2042
/**
2043
 * Backward-compatibility utility.
2044
 *
2045
 * This function should be removed after all queries have been converted
2046
 * to the new API.  It is temporary only.
2047
 *
2048
 * @todo Remove this once the query conversion is complete.
2049
 */
20502367
function _db_query_process_args($query, $args, $options) {
2051
20522498
  if (!is_array($options)) {
20531612
    $options = array();
20541612
  }
20552498
  if (empty($options['target'])) {
20562498
    $options['target'] = 'default';
20572498
  }
2058
2059
  // Temporary backward-compatibliity hacks.  Remove later.
20602498
  $old_query = $query;
20612498
  $query = str_replace(array('%n', '%d', '%f', '%b', "'%s'", '%s'), '?',
$old_query);
20622498
  if ($old_query !== $query) {
20632497
    $args = array_values($args);  // The old system allowed named arrays,
but PDO doesn't if you use ?.
20642497
  }
2065
2066
  // A large number of queries pass FALSE or empty-string for
2067
  // int/float fields because the previous version of db_query()
2068
  // casted them to int/float, resulting in 0.  MySQL PDO happily
2069
  // accepts these values as zero but PostgreSQL PDO does not, and I
2070
  // do not feel like tracking down and fixing every such query at
2071
  // this time.
20722498
  if (preg_match_all('/%([dsfb])/', $old_query, $m) > 0) {
20732497
    foreach ($m[1] as $idx => $char) {
2074
      switch ($char) {
20752497
        case 'd':
20762484
          $args[$idx] = (int) $args[$idx];
20772484
          break;
20782497
        case 'f':
20791
          $args[$idx] = (float) $args[$idx];
20801
          break;
20810
      }
20822497
    }
20832497
  }
2084
20852498
  return array($query, $args, $options);
20860
}
2087
2088
2089
/**
2090
 * Returns the last insert id.
2091
 *
2092
 * @todo Remove this function when all queries have been ported to
db_insert().
2093
 * @param $table
2094
 *   The name of the table you inserted into.
2095
 * @param $field
2096
 *   The name of the autoincrement field.
2097
 */
20982367
function db_last_insert_id($table, $field) {
2099162
  $sequence_name =
Database::getActiveConnection()->makeSequenceName($table, $field);
2100162
  return Database::getActiveConnection()->lastInsertId($sequence_name);
21010
}
2102
2103
/**
2104
 * Determine the number of rows changed by the preceding query.
2105
 *
2106
 * This may not work, actually, without some tricky temp code.
2107
 *
2108
 * @todo Remove this function when all queries have been ported to
db_update().
2109
 */
21102367
function db_affected_rows() {
2111482
  $statement = Database::getActiveConnection()->lastStatement;
2112482
  if (!$statement) {
21130
    return 0;
21140
  }
2115482
  return $statement->rowCount();
21160
}
2117
2118
/**
2119
 * Helper function for db_rewrite_sql.
2120
 *
2121
 * Collects JOIN and WHERE statements via hook_db_rewrite_sql()
2122
 * Decides whether to select primary_key or DISTINCT(primary_key)
2123
 *
2124
 * @todo Remove this function when all code has been converted to
query_alter.
2125
 * @param $query
2126
 *   Query to be rewritten.
2127
 * @param $primary_table
2128
 *   Name or alias of the table which has the primary key field for this
query.
2129
 *   Typical table names would be: {blocks}, {comments}, {forum}, {node},
2130
 *   {menu}, {term_data} or {vocabulary}. However, in most cases the usual
2131
 *   table alias (b, c, f, n, m, t or v) is used instead of the table name.
2132
 * @param $primary_field
2133
 *   Name of the primary field.
2134
 * @param $args
2135
 *   Array of additional arguments.
2136
 * @return
2137
 *   An array: join statements, where statements, field or DISTINCT(field).
2138
 */
21392367
function _db_rewrite_sql($query = '', $primary_table = 'n', $primary_field
= 'nid', $args = array()) {
21402063
  $where = array();
21412063
  $join = array();
21422063
  $distinct = FALSE;
21432063
  foreach (module_implements('db_rewrite_sql') as $module) {
21442063
    $result = module_invoke($module, 'db_rewrite_sql', $query,
$primary_table, $primary_field, $args);
21452063
    if (isset($result) && is_array($result)) {
21460
      if (isset($result['where'])) {
21470
        $where[] = $result['where'];
21480
      }
21490
      if (isset($result['join'])) {
21500
        $join[] = $result['join'];
21510
      }
21520
      if (isset($result['distinct']) && $result['distinct']) {
21530
        $distinct = TRUE;
21540
      }
21550
    }
21562063
    elseif (isset($result)) {
21570
      $where[] = $result;
21580
    }
21592063
  }
2160
21612063
  $where = empty($where) ? '' : '(' . implode(') AND (', $where) . ')';
21622063
  $join = empty($join) ? '' : implode(' ', $join);
2163
21642063
  return array($join, $where, $distinct);
21650
}
2166
2167
/**
2168
 * Rewrites node, taxonomy and comment queries. Use it for listing queries.
Do not
2169
 * use FROM table1, table2 syntax, use JOIN instead.
2170
 *
2171
 * @todo Remove this function when all code has been converted to
query_alter.
2172
 * @param $query
2173
 *   Query to be rewritten.
2174
 * @param $primary_table
2175
 *   Name or alias of the table which has the primary key field for this
query.
2176
 *   Typical table names would be: {blocks}, {comments}, {forum}, {node},
2177
 *   {menu}, {term_data} or {vocabulary}. However, it is more common to use
the
2178
 *   the usual table aliases: b, c, f, n, m, t or v.
2179
 * @param $primary_field
2180
 *   Name of the primary field.
2181
 * @param $args
2182
 *   An array of arguments, passed to the implementations of
hook_db_rewrite_sql.
2183
 * @return
2184
 *   The original query with JOIN and WHERE statements inserted from
2185
 *   hook_db_rewrite_sql implementations. nid is rewritten if needed.
2186
 */
21872367
function db_rewrite_sql($query, $primary_table = 'n', $primary_field =
'nid',  $args = array()) {
21882063
  list($join, $where, $distinct) = _db_rewrite_sql($query, $primary_table,
$primary_field, $args);
2189
21902063
  if ($distinct) {
21910
    $query = db_distinct_field($primary_table, $primary_field, $query);
21920
  }
2193
21942063
  if (!empty($where) || !empty($join)) {
2195
    $pattern = '{
2196
      # Beginning of the string
2197
      ^
2198
      ((?P<anonymous_view>
2199
        # Everything within this set of parentheses is named "anonymous
view"
2200
        (?:
2201
          [^()]++                   # anything not parentheses
2202
        |
2203
          \( (?P>anonymous_view) \)          # an open parenthesis, more
"anonymous view" and finally a close parenthesis.
2204
        )*
2205
      )[^()]+WHERE)
22060
    }x';
22070
    preg_match($pattern, $query, $matches);
22080
    if ($where) {
22090
      $n = strlen($matches[1]);
22100
      $second_part = substr($query, $n);
22110
      $first_part = substr($matches[1], 0, $n - 5) ." $join WHERE $where
AND ( ";
2212
      // PHP 4 does not support strrpos for strings. We emulate it.
22130
      $haystack_reverse = strrev($second_part);
2214
      // No need to use strrev on the needle, we supply GROUP, ORDER, LIMIT
2215
      // reversed.
22160
      foreach (array('PUORG', 'REDRO', 'TIMIL') as $needle_reverse) {
22170
        $pos = strpos($haystack_reverse, $needle_reverse);
22180
        if ($pos !== FALSE) {
2219
          // All needles are five characters long.
22200
          $pos += 5;
22210
          break;
22220
        }
22230
      }
22240
      if ($pos === FALSE) {
22250
        $query = $first_part . $second_part . ')';
22260
      }
2227
      else {
22280
        $query = $first_part . substr($second_part, 0, -$pos) . ')' .
substr($second_part, -$pos);
2229
      }
22300
    }
2231
    else {
22320
      $query = $matches[1] . " $join " . substr($query,
strlen($matches[1]));
2233
    }
22340
  }
2235
22362063
  return $query;
22370
}
2238
2239
2240
/**
2241
 * @} End of "ingroup database-legacy".
2242
 */
22432367