Skip to content
Permalink
Browse files

Implemented support for in and not in

  • Loading branch information...
lorenzo committed Jan 1, 2013
1 parent 2d0182f commit 8a44c0590e457387936953f0e065f16ff52eccad
@@ -13,6 +13,11 @@ class QueryExpression implements Countable {
protected $_identifier;
protected $_bindingsCount = 0;
protected $_replaceArrayParams = false;
public function __construct($conditions = [], $types = [], $conjunction = 'AND') {
$this->_conjunction = strtoupper($conjunction);
$this->_identifier = substr(spl_object_hash($this), 7, 9);
@@ -89,6 +94,10 @@ public function in($field, $values, $type = null) {
return $this->add([$field . ' IN' => $values], $type ? [$field => $type] : []);
}
public function notIn($field, $values, $type = null) {
return $this->add([$field . ' NOT IN' => $values], $type ? [$field => $type] : []);
}
/**
* Associates a query placeholder to a value and a type for next execution
*
@@ -101,15 +110,20 @@ public function in($field, $values, $type = null) {
*/
public function bind($token, $value, $type) {
$param = $token;
$number = count($this->_bindings);
$number = $this->_bindingsCount++;
if (is_numeric($token)) {
$param = '?';
} else if ($param[0] !== ':') {
$param = sprintf(':c%s%s', $this->_identifier, $number);
}
$this->_bindings[$number] = compact('value', 'type') + [
if (strpos($type, '[]') !== false) {
$param = sprintf(':array%d', $number);
$type = str_replace('[]', '', $type);
}
$this->_bindings[$number] = compact('value', 'type', 'token') + [
'placeholder' => substr($param, 1)
];
return $param;
@@ -134,6 +148,9 @@ public function __toString() {
}
public function sql() {
if ($this->_replaceArrayParams) {
$this->_replaceArrays();
}
$conjunction = $this->_conjunction;
return '(' . implode(" $conjunction ", $this->_conditions) . ')';
}
@@ -188,7 +205,34 @@ protected function _parseCondition($field, $value, $types) {
}
$type = isset($types[$expression]) ? $types[$expression] : null;
return sprintf('%s %s %s', $expression, $operator, $this->bind($field, $value, $type));
$template = '%s %s %s';
if (in_array(strtolower(trim($operator)), ['in', 'not in'])) {
$type = $type ?: 'string';
$type .= strpos($type, '[]') === false ? '[]' : null;
$template = '%s %s (%s)';
$this->_replaceArrayParams = true;
}
return sprintf($template, $expression, $operator, $this->bind($field, $value, $type));
}
protected function _replaceArrays() {
foreach ($this->_conditions as $k => $condition) {
if (!is_string($condition)) {
continue;
}
$condition = preg_replace_callback('/(:array(\d+))/', function($match) {
$params = [];
$binding = $this->_bindings[$match[2]];
foreach ($this->_bindings[$match[2]]['value'] as $value) {
$params[] = $this->bind($binding['token'], $value, $binding['type']);
}
unset($this->_bindings[$match[2]]);
return implode(', ', $params);
}, $condition);
$this->_conditions[$k] = $condition;
}
}
}
@@ -692,6 +692,47 @@ public function testSelectWhereOperatorMethods() {
->where(function($exp) { return $exp->isNotNull('visible'); })
->execute();
$this->assertCount(2, $result);
$query = new Query($this->connection);
$result = $query
->select(['id'])
->from('dates')
->where(function($exp) {
return $exp->in('visible', ['Y', 'N']);
})
->execute();
$this->assertCount(2, $result);
$query = new Query($this->connection);
$result = $query
->select(['id'])
->from('dates')
->where(function($exp) {
return $exp->in(
'posted',
[new \DateTime('2012-12-21 12:00'), new \DateTime('2012-12-22 12:00')],
'datetime'
);
})
->execute();
$this->assertCount(2, $result);
$this->assertEquals(['id' => 1], $result->fetch('assoc'));
$this->assertEquals(['id' => 2], $result->fetch('assoc'));
$query = new Query($this->connection);
$result = $query
->select(['id'])
->from('dates')
->where(function($exp) {
return $exp->notIn(
'posted',
[new \DateTime('2012-12-21 12:00'), new \DateTime('2012-12-22 12:00')],
'datetime'
);
})
->execute();
$this->assertCount(1, $result);
$this->assertEquals(['id' => 3], $result->fetch('assoc'));
}
}

0 comments on commit 8a44c05

Please sign in to comment.
You can’t perform that action at this time.