Commit 454174a6 by Carsten Brandt

added NOT operator for db, elasticsearch, redis

issue #1523
parent d076da69
...@@ -139,6 +139,7 @@ class QueryBuilder extends \yii\base\Object ...@@ -139,6 +139,7 @@ class QueryBuilder extends \yii\base\Object
public function buildCondition($condition) public function buildCondition($condition)
{ {
static $builders = array( static $builders = array(
'not' => 'buildNotCondition',
'and' => 'buildAndCondition', 'and' => 'buildAndCondition',
'or' => 'buildAndCondition', 'or' => 'buildAndCondition',
'between' => 'buildBetweenCondition', 'between' => 'buildBetweenCondition',
...@@ -196,6 +197,19 @@ class QueryBuilder extends \yii\base\Object ...@@ -196,6 +197,19 @@ class QueryBuilder extends \yii\base\Object
return count($parts) === 1 ? $parts[0] : ['and' => $parts]; return count($parts) === 1 ? $parts[0] : ['and' => $parts];
} }
private function buildNotCondition($operator, $operands, &$params)
{
if (count($operands) != 1) {
throw new InvalidParamException("Operator '$operator' requires exactly one operand.");
}
$operand = reset($operands);
if (is_array($operand)) {
$operand = $this->buildCondition($operand, $params);
}
return [$operator => $operand];
}
private function buildAndCondition($operator, $operands) private function buildAndCondition($operator, $operands)
{ {
$parts = []; $parts = [];
......
...@@ -219,6 +219,7 @@ EOF; ...@@ -219,6 +219,7 @@ EOF;
public function buildCondition($condition, &$columns) public function buildCondition($condition, &$columns)
{ {
static $builders = [ static $builders = [
'not' => 'buildNotCondition',
'and' => 'buildAndCondition', 'and' => 'buildAndCondition',
'or' => 'buildAndCondition', 'or' => 'buildAndCondition',
'between' => 'buildBetweenCondition', 'between' => 'buildBetweenCondition',
...@@ -269,6 +270,19 @@ EOF; ...@@ -269,6 +270,19 @@ EOF;
return count($parts) === 1 ? $parts[0] : '(' . implode(') and (', $parts) . ')'; return count($parts) === 1 ? $parts[0] : '(' . implode(') and (', $parts) . ')';
} }
private function buildNotCondition($operator, $operands, &$params)
{
if (count($operands) != 1) {
throw new InvalidParamException("Operator '$operator' requires exactly one operand.");
}
$operand = reset($operands);
if (is_array($operand)) {
$operand = $this->buildCondition($operand, $params);
}
return "!($operand)";
}
private function buildAndCondition($operator, $operands, &$columns) private function buildAndCondition($operator, $operands, &$columns)
{ {
$parts = []; $parts = [];
......
...@@ -14,6 +14,7 @@ Yii Framework 2 Change Log ...@@ -14,6 +14,7 @@ Yii Framework 2 Change Log
- Enh #1406: DB Schema support for Oracle Database (p0larbeer, qiangxue) - Enh #1406: DB Schema support for Oracle Database (p0larbeer, qiangxue)
- Enh #1437: Added ListView::viewParams (qiangxue) - Enh #1437: Added ListView::viewParams (qiangxue)
- Enh #1469: ActiveRecord::find() now works with default conditions (default scope) applied by createQuery (cebe) - Enh #1469: ActiveRecord::find() now works with default conditions (default scope) applied by createQuery (cebe)
- Enh #1523: Query conditions now allow to use the NOT operator (cebe)
- Enh #1552: It is now possible to use multiple bootstrap NavBar in a single page (Alex-Code) - Enh #1552: It is now possible to use multiple bootstrap NavBar in a single page (Alex-Code)
- Enh: Added `favicon.ico` and `robots.txt` to defauly application templates (samdark) - Enh: Added `favicon.ico` and `robots.txt` to defauly application templates (samdark)
- Enh: Added `Widget::autoIdPrefix` to support prefixing automatically generated widget IDs (qiangxue) - Enh: Added `Widget::autoIdPrefix` to support prefixing automatically generated widget IDs (qiangxue)
......
...@@ -788,6 +788,7 @@ class QueryBuilder extends \yii\base\Object ...@@ -788,6 +788,7 @@ class QueryBuilder extends \yii\base\Object
public function buildCondition($condition, &$params) public function buildCondition($condition, &$params)
{ {
static $builders = [ static $builders = [
'NOT' => 'buildNotCondition',
'AND' => 'buildAndCondition', 'AND' => 'buildAndCondition',
'OR' => 'buildAndCondition', 'OR' => 'buildAndCondition',
'BETWEEN' => 'buildBetweenCondition', 'BETWEEN' => 'buildBetweenCondition',
...@@ -878,6 +879,30 @@ class QueryBuilder extends \yii\base\Object ...@@ -878,6 +879,30 @@ class QueryBuilder extends \yii\base\Object
} }
/** /**
* Inverts an SQL expressions with `NOT` operator.
* @param string $operator the operator to use for connecting the given operands
* @param array $operands the SQL expressions to connect.
* @param array $params the binding parameters to be populated
* @return string the generated SQL expression
* @throws InvalidParamException if wrong number of operands have been given.
*/
public function buildNotCondition($operator, $operands, &$params)
{
if (count($operands) != 1) {
throw new InvalidParamException("Operator '$operator' requires exactly one operand.");
}
$operand = reset($operands);
if (is_array($operand)) {
$operand = $this->buildCondition($operand, $params);
}
if ($operand === '') {
return '';
}
return "$operator ($operand)";
}
/**
* Creates an SQL expressions with the `BETWEEN` operator. * Creates an SQL expressions with the `BETWEEN` operator.
* @param string $operator the operator to use (e.g. `BETWEEN` or `NOT BETWEEN`) * @param string $operator the operator to use (e.g. `BETWEEN` or `NOT BETWEEN`)
* @param array $operands the first operand is the column name. The second and third operands * @param array $operands the first operand is the column name. The second and third operands
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment