summaryrefslogtreecommitdiff
path: root/includes/database/query.inc
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2009-08-29 05:43:35 +0000
committerDries Buytaert <dries@buytaert.net>2009-08-29 05:43:35 +0000
commitfb0275fa6a7d67f80bb865deb25f66707082eb34 (patch)
treeb1888f9cd6d1cae22f4e4ad9646b92c2d3bd6c68 /includes/database/query.inc
parenteca9c6cc165dea9f01f1b74869e20a921b80086e (diff)
downloadbrdo-fb0275fa6a7d67f80bb865deb25f66707082eb34.tar.gz
brdo-fb0275fa6a7d67f80bb865deb25f66707082eb34.tar.bz2
- Patch #496500 by chx: remove global placeholder counter.
Diffstat (limited to 'includes/database/query.inc')
-rw-r--r--includes/database/query.inc71
1 files changed, 46 insertions, 25 deletions
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.
*