diff options
author | Dries Buytaert <dries@buytaert.net> | 2009-08-29 05:43:35 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2009-08-29 05:43:35 +0000 |
commit | fb0275fa6a7d67f80bb865deb25f66707082eb34 (patch) | |
tree | b1888f9cd6d1cae22f4e4ad9646b92c2d3bd6c68 /includes | |
parent | eca9c6cc165dea9f01f1b74869e20a921b80086e (diff) | |
download | brdo-fb0275fa6a7d67f80bb865deb25f66707082eb34.tar.gz brdo-fb0275fa6a7d67f80bb865deb25f66707082eb34.tar.bz2 |
- Patch #496500 by chx: remove global placeholder counter.
Diffstat (limited to 'includes')
-rw-r--r-- | includes/database/mysql/schema.inc | 4 | ||||
-rw-r--r-- | includes/database/query.inc | 71 | ||||
-rw-r--r-- | includes/database/schema.inc | 18 | ||||
-rw-r--r-- | includes/database/select.inc | 49 |
4 files changed, 94 insertions, 48 deletions
diff --git a/includes/database/mysql/schema.inc b/includes/database/mysql/schema.inc index edf86458c..99df5e70e 100644 --- a/includes/database/mysql/schema.inc +++ b/includes/database/mysql/schema.inc @@ -372,11 +372,11 @@ class DatabaseSchema_mysql extends DatabaseSchema { $condition = $this->buildTableNameCondition($this->connection->prefixTables('{' . $table . '}')); if (isset($column)) { $condition->condition('column_name', $column); - $condition->compile($this->connection); + $condition->compile($this->connection, $this); // Don't use {} around information_schema.columns table. return db_query("SELECT column_comment FROM information_schema.columns WHERE " . (string) $condition, $condition->arguments())->fetchField(); } - $condition->compile($this->connection); + $condition->compile($this->connection, $this); // Don't use {} around information_schema.tables table. $comment = db_query("SELECT table_comment FROM information_schema.tables WHERE " . (string) $condition, $condition->arguments())->fetchField(); // Work-around for MySQL 5.0 bug http://bugs.mysql.com/bug.php?id=11379 diff --git a/includes/database/query.inc b/includes/database/query.inc index 729b8a739..87b903d96 100644 --- a/includes/database/query.inc +++ b/includes/database/query.inc @@ -111,8 +111,11 @@ interface QueryConditionInterface { * * @param $connection * The database connection for which to compile the conditionals. + * @param $query + * The query this condition belongs to. If not given, the current query is + * used. */ - public function compile(DatabaseConnection $connection); + public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $queryPlaceholder = NULL); } @@ -197,11 +200,21 @@ interface QueryAlterableInterface { } /** + * Interface for a query that accepts placeholders. + */ +interface QueryPlaceholderInterface { + /** + * Returns the next placeholder for the query. + */ + function nextPlaceholder(); +} + +/** * Base class for the query builders. * * All query builders inherit from a common base class. */ -abstract class Query { +abstract class Query implements QueryPlaceholderInterface { /** * The connection object on which to run this query. @@ -217,6 +230,11 @@ abstract class Query { */ protected $queryOptions; + /** + * The placeholder counter. + */ + protected $nextPlaceholder = 0; + public function __construct(DatabaseConnection $connection, $options) { $this->connection = $connection; $this->queryOptions = $options; @@ -236,6 +254,10 @@ abstract class Query { * A prepared statement query string for this object. */ abstract public function __toString(); + + public function nextPlaceholder() { + return $this->nextPlaceholder++; + } } /** @@ -866,14 +888,14 @@ class DeleteQuery extends Query implements QueryConditionInterface { return $this; } - public function compile(DatabaseConnection $connection) { - return $this->condition->compile($connection); + public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $queryPlaceholder = NULL) { + return $this->condition->compile($connection, isset($queryPlaceholder) ? $queryPlaceholder : $this); } public function execute() { $values = array(); if (count($this->condition)) { - $this->condition->compile($this->connection); + $this->condition->compile($this->connection, $this); $values = $this->condition->arguments(); } @@ -884,7 +906,7 @@ class DeleteQuery extends Query implements QueryConditionInterface { $query = 'DELETE FROM {' . $this->connection->escapeTable($this->table) . '} '; if (count($this->condition)) { - $this->condition->compile($this->connection); + $this->condition->compile($this->connection, $this); $query .= "\nWHERE " . $this->condition; } @@ -911,8 +933,8 @@ class TruncateQuery extends Query { $this->table = $table; } - public function compile(DatabaseConnection $connection) { - return $this->condition->compile($connection); + public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $queryPlaceholder = NULL) { + return $this->condition->compile($connection, isset($queryPlaceholder) ? $queryPlaceholder : $this); } public function execute() { @@ -971,7 +993,6 @@ class UpdateQuery extends Query implements QueryConditionInterface { */ protected $expressionFields = array(); - public function __construct(DatabaseConnection $connection, $table, array $options = array()) { $options['return'] = Database::RETURN_AFFECTED; parent::__construct($connection, $options); @@ -1008,8 +1029,8 @@ class UpdateQuery extends Query implements QueryConditionInterface { return $this; } - public function compile(DatabaseConnection $connection) { - return $this->condition->compile($connection); + public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $queryPlaceholder = NULL) { + return $this->condition->compile($connection, isset($queryPlaceholder) ? $queryPlaceholder : $this); } /** @@ -1073,7 +1094,7 @@ class UpdateQuery extends Query implements QueryConditionInterface { } if (count($this->condition)) { - $this->condition->compile($this->connection); + $this->condition->compile($this->connection, $this); $update_values = array_merge($update_values, $this->condition->arguments()); } @@ -1098,7 +1119,7 @@ class UpdateQuery extends Query implements QueryConditionInterface { $query = 'UPDATE {' . $this->connection->escapeTable($this->table) . '} SET ' . implode(', ', $update_fields); if (count($this->condition)) { - $this->condition->compile($this->connection); + $this->condition->compile($this->connection, $this); // There is an implicit string cast on $this->condition. $query .= "\nWHERE " . $this->condition; } @@ -1178,17 +1199,8 @@ class DatabaseCondition implements QueryConditionInterface, Countable { return $this->arguments; } - public function compile(DatabaseConnection $connection) { - // This value is static, so it will increment across the entire request - // rather than just this query. That is OK, because we only need definitive - // placeholder names if we're going to use them for _alter hooks, which we - // are not. The alter hook would intervene before compilation. - // $next_placeholder does not use drupal_static as it increments and should - // never be reset during a request. - static $next_placeholder = 1; - + public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $queryPlaceholder = NULL) { if ($this->changed) { - $condition_fragments = array(); $arguments = array(); @@ -1205,7 +1217,7 @@ class DatabaseCondition implements QueryConditionInterface, Countable { // It's a structured condition, so parse it out accordingly. if ($condition['field'] instanceof QueryConditionInterface) { // Compile the sub-condition recursively and add it to the list. - $condition['field']->compile($connection); + $condition['field']->compile($connection, $queryPlaceholder); $condition_fragments[] = '(' . (string)$condition['field'] . ')'; $arguments += $condition['field']->arguments(); } @@ -1238,7 +1250,7 @@ class DatabaseCondition implements QueryConditionInterface, Countable { } if ($operator['use_value']) { foreach ($condition['value'] as $value) { - $placeholder = ':db_condition_placeholder_' . $next_placeholder++; + $placeholder = ':db_condition_placeholder_' . $queryPlaceholder->nextPlaceholder(); $arguments[$placeholder] = $value; $placeholders[] = $placeholder; } @@ -1263,6 +1275,15 @@ class DatabaseCondition implements QueryConditionInterface, Countable { return $this->stringVersion; } + function __clone() { + $this->changed = TRUE; + foreach ($this->conditions as $key => $condition) { + if ($condition['field'] instanceOf QueryConditionInterface) { + $this->conditions[$key]['field'] = clone($condition['field']); + } + } + } + /** * Gets any special processing requirements for the condition operator. * diff --git a/includes/database/schema.inc b/includes/database/schema.inc index 442fedd69..f8fd12ede 100644 --- a/includes/database/schema.inc +++ b/includes/database/schema.inc @@ -146,14 +146,24 @@ * @see drupal_install_schema() */ -abstract class DatabaseSchema { +abstract class DatabaseSchema implements QueryPlaceholderInterface { protected $connection; + /** + * The placeholder counter. + */ + protected $placeholder = 0; + + public function __construct($connection) { $this->connection = $connection; } + public function nextPlaceholder() { + return $this->placeholder++; + } + /** * Build a condition to match a table name against a standard information_schema. * @@ -204,7 +214,7 @@ abstract class DatabaseSchema { */ public function tableExists($table) { $condition = $this->buildTableNameCondition($this->connection->prefixTables('{' . $table . '}')); - $condition->compile($this->connection); + $condition->compile($this->connection, $this); // Normally, we would heartily discourage the use of string // concatination for conditionals like this however, we // couldn't use db_select() here because it would prefix @@ -224,7 +234,7 @@ abstract class DatabaseSchema { */ public function findTables($table_expression) { $condition = $this->buildTableNameCondition($table_expression, 'LIKE'); - $condition->compile($this->connection); + $condition->compile($this->connection, $this); // Normally, we would heartily discourage the use of string // concatination for conditionals like this however, we // couldn't use db_select() here because it would prefix @@ -239,7 +249,7 @@ abstract class DatabaseSchema { public function columnExists($table, $column) { $condition = $this->buildTableNameCondition($this->connection->prefixTables('{' . $table . '}')); $condition->condition('column_name', $column); - $condition->compile($this->connection); + $condition->compile($this->connection, $this); // Normally, we would heartily discourage the use of string // concatination for conditionals like this however, we // couldn't use db_select() here because it would prefix diff --git a/includes/database/select.inc b/includes/database/select.inc index 073f82c88..e8d418ea7 100644 --- a/includes/database/select.inc +++ b/includes/database/select.inc @@ -35,7 +35,7 @@ interface QueryExtendableInterface { /** * Interface definition for a Select Query object. */ -interface SelectQueryInterface extends QueryConditionInterface, QueryAlterableInterface, QueryExtendableInterface { +interface SelectQueryInterface extends QueryConditionInterface, QueryAlterableInterface, QueryExtendableInterface, QueryPlaceholderInterface { /* Alter accessors to expose the query data to alter hooks. */ @@ -114,10 +114,14 @@ interface SelectQueryInterface extends QueryConditionInterface, QueryAlterableIn /** * Compiles and returns an associative array of the arguments for this prepared statement. * + * @param $queryPlaceholder + * When collecting the arguments of a subquery, the main placeholder + * object should be passed as this parameter. + * * @return * An associative array of all placeholder arguments for this query. */ - public function getArguments(); + public function getArguments(QueryPlaceholderInterface $queryPlaceholder = NULL); /* Query building operations */ @@ -400,12 +404,22 @@ class SelectQueryExtender implements SelectQueryInterface { */ protected $connection; + /** + * The placeholder counter. + */ + protected $placeholder = 0; public function __construct(SelectQueryInterface $query, DatabaseConnection $connection) { $this->query = $query; $this->connection = $connection; } + /* Implementations of QueryPlaceholderInterface. */ + + public function nextPlaceholder() { + return $this->placeholder++; + } + /* Implementations of QueryAlterableInterface. */ public function addTag($tag) { @@ -454,8 +468,8 @@ class SelectQueryExtender implements SelectQueryInterface { return $this; } - public function compile(DatabaseConnection $connection) { - return $this->query->compile($connection); + public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $queryPlaceholder = NULL) { + return $this->condition->compile($connection, isset($queryPlaceholder) ? $queryPlaceholder : $this); } /* Implmeentations of QueryConditionInterface for the HAVING clause. */ @@ -510,8 +524,8 @@ class SelectQueryExtender implements SelectQueryInterface { return $this->query->getTables(); } - public function getArguments() { - return $this->query->getArguments(); + public function getArguments(QueryPlaceholderInterface $queryPlaceholder = NULL) { + return $this->query->getArguments($queryPlaceholder); } public function isPrepared() { @@ -826,9 +840,8 @@ class SelectQuery extends Query implements SelectQueryInterface { return $this; } - - public function compile(DatabaseConnection $connection) { - return $this->where->compile($connection); + public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $queryPlaceholder = NULL) { + return $this->where->compile($connection, isset($queryPlaceholder) ? $queryPlaceholder : $this); } /* Implmeentations of QueryConditionInterface for the HAVING clause. */ @@ -855,7 +868,7 @@ class SelectQuery extends Query implements SelectQueryInterface { } public function havingCompile(DatabaseConnection $connection) { - return $this->having->compile($connection); + return $this->having->compile($connection, $this); } /* Implementations of QueryExtendableInterface. */ @@ -897,9 +910,12 @@ class SelectQuery extends Query implements SelectQueryInterface { return $this->tables; } - public function getArguments() { - $this->where->compile($this->connection); - $this->having->compile($this->connection); + public function getArguments(QueryPlaceholderInterface $queryPlaceholder = NULL) { + if (!isset($queryPlaceholder)) { + $queryPlaceholder = $this; + } + $this->where->compile($this->connection, $queryPlaceholder); + $this->having->compile($this->connection, $queryPlaceholder); $args = $this->where->arguments() + $this->having->arguments(); foreach ($this->tables as $table) { if ($table['arguments']) { @@ -907,7 +923,7 @@ class SelectQuery extends Query implements SelectQueryInterface { } // If this table is a subquery, grab its arguments recursively. if ($table['table'] instanceof SelectQueryInterface) { - $args += $table['table']->getArguments(); + $args += $table['table']->getArguments($queryPlaceholder); } } foreach ($this->expressions as $expression) { @@ -1179,7 +1195,7 @@ class SelectQuery extends Query implements SelectQueryInterface { // WHERE if (count($this->where)) { - $this->where->compile($this->connection); + $this->where->compile($this->connection, $this); // There is an implicit string cast on $this->condition. $query .= "\nWHERE " . $this->where; } @@ -1191,7 +1207,7 @@ class SelectQuery extends Query implements SelectQueryInterface { // HAVING if (count($this->having)) { - $this->having->compile($this->connection); + $this->having->compile($this->connection, $this); // There is an implicit string cast on $this->having. $query .= "\nHAVING " . $this->having; } @@ -1207,7 +1223,6 @@ class SelectQuery extends Query implements SelectQueryInterface { } // RANGE is database specific, so we can't do it here. - return $query; } |