class DatabaseCondition implements QueryConditionInterface, Countable {
protected $conditions = array();
protected $arguments = array();
protected $changed = TRUE;
protected $queryPlaceholderIdentifier;
protected $stringVersion;
public function __construct($conjunction) {
$this->conditions['#conjunction'] = $conjunction;
}
public function count() {
return count($this->conditions) - 1;
}
public function condition($field, $value = NULL, $operator = NULL) {
if (!isset($operator)) {
if (is_array($value)) {
$operator = 'IN';
}
else {
$operator = '=';
}
}
$this->conditions[] = array(
'field' => $field,
'value' => $value,
'operator' => $operator,
);
$this->changed = TRUE;
return $this;
}
public function where($snippet, $args = array()) {
$this->conditions[] = array(
'field' => $snippet,
'value' => $args,
'operator' => NULL,
);
$this->changed = TRUE;
return $this;
}
public function isNull($field) {
return $this->condition($field, NULL, 'IS NULL');
}
public function isNotNull($field) {
return $this->condition($field, NULL, 'IS NOT NULL');
}
public function exists(SelectQueryInterface $select) {
return $this->condition('', $select, 'EXISTS');
}
public function notExists(SelectQueryInterface $select) {
return $this->condition('', $select, 'NOT EXISTS');
}
public function &conditions() {
return $this->conditions;
}
public function arguments() {
if ($this->changed) {
return NULL;
}
return $this->arguments;
}
public function compile(DatabaseConnection $connection, QueryPlaceholderInterface $queryPlaceholder) {
if ($this->changed || isset($this->queryPlaceholderIdentifier) && ($this->queryPlaceholderIdentifier != $queryPlaceholder->uniqueIdentifier())) {
$this->queryPlaceholderIdentifier = $queryPlaceholder->uniqueIdentifier();
$condition_fragments = array();
$arguments = array();
$conditions = $this->conditions;
$conjunction = $conditions['#conjunction'];
unset($conditions['#conjunction']);
foreach ($conditions as $condition) {
if (empty($condition['operator'])) {
$condition_fragments[] = ' (' . $condition['field'] . ') ';
$arguments += $condition['value'];
}
else {
if ($condition['field'] instanceof QueryConditionInterface) {
$condition['field']->compile($connection, $queryPlaceholder);
$condition_fragments[] = '(' . (string) $condition['field'] . ')';
$arguments += $condition['field']->arguments();
}
else {
$operator_defaults = array(
'prefix' => '',
'postfix' => '',
'delimiter' => '',
'operator' => $condition['operator'],
'use_value' => TRUE,
);
$operator = $connection->mapConditionOperator($condition['operator']);
if (!isset($operator)) {
$operator = $this->mapConditionOperator($condition['operator']);
}
$operator += $operator_defaults;
$placeholders = array();
if ($condition['value'] instanceof SelectQueryInterface) {
$operator = $this->ensureBrackets($operator);
$condition['value']->compile($connection, $queryPlaceholder);
$placeholders[] = (string) $condition['value'];
$arguments += $condition['value']->arguments();
$operator['use_value'] = FALSE;
}
elseif (!$operator['delimiter']) {
$condition['value'] = array($condition['value']);
}
if ($operator['use_value']) {
foreach ($condition['value'] as $value) {
$placeholder = ':db_condition_placeholder_' . $queryPlaceholder->nextPlaceholder();
$arguments[$placeholder] = $value;
$placeholders[] = $placeholder;
}
}
$condition_fragments[] = ' (' . $connection->escapeField($condition['field']) . ' ' . $operator['operator'] . ' ' . $operator['prefix'] . implode($operator['delimiter'], $placeholders) . $operator['postfix'] . ') ';
}
}
}
$this->changed = FALSE;
$this->stringVersion = implode($conjunction, $condition_fragments);
$this->arguments = $arguments;
}
}
public function compiled() {
return !$this->changed;
}
public function __toString() {
if ($this->changed) {
return '';
}
return $this->stringVersion;
}
function __clone() {
$this->changed = TRUE;
foreach ($this->conditions as $key => $condition) {
if ($key !== '#conjunction') {
if ($condition['field'] instanceOf QueryConditionInterface) {
$this->conditions[$key]['field'] = clone($condition['field']);
}
if ($condition['value'] instanceOf SelectQueryInterface) {
$this->conditions[$key]['value'] = clone($condition['value']);
}
}
}
}
protected function mapConditionOperator($operator) {
static $specials = array(
'BETWEEN' => array('delimiter' => ' AND '),
'IN' => array('delimiter' => ', ', 'prefix' => ' (', 'postfix' => ')'),
'NOT IN' => array('delimiter' => ', ', 'prefix' => ' (', 'postfix' => ')'),
'EXISTS' => array('prefix' => ' (', 'postfix' => ')'),
'NOT EXISTS' => array('prefix' => ' (', 'postfix' => ')'),
'IS NULL' => array('use_value' => FALSE),
'IS NOT NULL' => array('use_value' => FALSE),
'LIKE' => array('postfix' => " ESCAPE '\\\\'"),
'NOT LIKE' => array('postfix' => " ESCAPE '\\\\'"),
'=' => array(),
'<' => array(),
'>' => array(),
'>=' => array(),
'<=' => array(),
);
if (isset($specials[$operator])) {
$return = $specials[$operator];
}
else {
$operator = strtoupper($operator);
$return = isset($specials[$operator]) ? $specials[$operator] : array();
}
$return += array('operator' => $operator);
return $return;
}
protected function ensureBrackets($operator) {
if (strpos($operator['prefix'], '(') === FALSE) {
$operator['prefix'] .= ' (';
}
if (strpos($operator['postfix'], ')') === FALSE) {
$operator['postfix'] = ')' . $operator['postfix'];
}
return $operator;
}
}