Subclass of patio.sql.ComplexExpression where the expression results in a boolean value in SQL.
ExtendsArguments
- Dataset._filterObject({a : 1}) //=> WHERE (a = 1)
- Dataset._filterObject({x : {gt : 1}}) //=> WHERE (x > 1)
- Dataset._filterObject({x : {gt : 1}, a : 1}) //=> WHERE ((x > 1) AND (a = 1))
- Dataset._filterObject({x : {like : "name"}}) //=> WHERE (x LIKE 'name')
- Dataset._filterObject({x : {iLike : "name"}}) //=> WHERE (x LIKE 'name')
- Dataset._filterObject({x : {between : [1,10]}}) //=> WHERE ((x >= 1) AND (x <= 10))
- Dataset._filterObject({x : {notBetween : [1,10]}}) //=> WHERE ((x < 1) OR (x > 10))
- Dataset._filterObject({x : {neq : 1}}) //=> WHERE (x != 1)
the expression we need to create an expression out of
null
] : the key that the hash corresponds to
patio.sql.Expression
an expression to use in the filter
- function (expr,key,op){
- /*jshint loopfunc:true*/
- var pairs = [], opts, newKey;
- var twoArityOperators = this.TWO_ARITY_OPERATORS;
- for (var k in expr) {
- var v = expr[k];
- if (isHash(v)) { //its a hash too filter it too!
- pairs.push(this.__filterObject(v, k, op));
- } else if (key && (twoArityOperators[k.toUpperCase()] || k.match(/between/i))) {
- //its a two arrity operator (e.g. '=', '>')
- newKey = isString(key) ? key.split(",") : [key];
- if (newKey.length > 1) {
- //this represents a hash where the key represents two columns
- //(e.g. {"col1,col2" : 1}) => WHERE (col1 = 1 AND col2 = 1)
- pairs = pairs.concat(newKey.map(function (k) {
- //filter each column with the expression
- return this.__filterObject(expr, k, op);
- }, this));
- } else {
- newKey = [sql.stringToIdentifier(newKey[0])];
- if (k.match(/^like$/)) {
- //its a like clause {col : {like : "hello"}}
- pairs.push(StringExpression.like.apply(StringExpression, (newKey.concat(isArray(v) ? v : [v]))));
- } else if (k.match(/^iLike$/)) {
- //its a like clause {col : {iLike : "hello"}}
- pairs.push(StringExpression.like.apply(StringExpression, (newKey.concat(isArray(v) ? v : [v]).concat({caseInsensitive: true}))));
- } else if (k.match(/between/i)) {
- //its a like clause {col : {between : [1,10]}}
- var between = sql.stringToIdentifier(newKey[0]).between(v);
- k === "notBetween" && (between = between.not());
- pairs.push(between);
- } else {
- //otherwise is just a boolean expressio
- //it its not a valid operator then we
- //BooleanExpression with throw an error
- pairs.push(new BooleanExpression(k, newKey[0], v));
- }
- }
- } else {
- //we're not a twoarity operator
- //so we create a boolean expression out of it
- newKey = k.split(",");
- if (newKey.length === 1) {
- newKey = sql.stringToIdentifier(newKey[0]);
- }
- opts = [
- [newKey, v]
- ];
- pairs.push(BooleanExpression.fromValuePairs(opts));
- }
- }
- //if the total of pairs is one then we just return the first element
- //otherwise we join them all with an AND
- return pairs.length === 1 ? pairs[0] : BooleanExpression.fromArgs([op || "AND"].concat(pairs));
- }
Take pairs of values (e.g. a hash or array of two element arrays) and converts it to a patio.sql.BooleanExpression. The operator and args used depends on the case of the right (2nd) argument:
BooleanExpression.fromValuePairs({a : [1,2,3]}) //=> a IN (1,2,3) BooleanExpression.fromValuePairs({a : true}); // a IS TRUE; BooleanExpression.fromValuePairs({a : /^A/i}); // a *~ '^A'
If multiple arguments are given, they are joined with the op given (AND by default, OR possible). If negate is set to true, all subexpressions are inverted before used.
BooleanExpression.fromValuePairs({a : [1,2,3], b : true}) //=> a IN (1,2,3) AND b IS TRUE BooleanExpression.fromValuePairs({a : [1,2,3], b : true}, "OR") //=> a IN (1,2,3) OR b IS TRUE BooleanExpression.fromValuePairs({a : [1,2,3], b : true}, "OR", true) //=> a NOT IN (1,2,3) AND b IS NOT TRUEArguments
object to convert to a patio.sql.BooleanExpression
"AND"
] : Boolean operator to join each subexpression with.
BooleanExpression.fromValuePairs({a : [1,2,3], b : true}, "OR") //=> a IN (1,2,3) OR b IS TRUE
false
] : set to try to invert the patio.sql.BooleanExpression.
BooleanExpression.fromValuePairs({a : [1,2,3], b : true}, "OR", true) //=> a NOT IN (1,2,3) AND b IS NOT TRUE
patio.sql.BooleanExpression
expression composed of sub expressions built from the hash.
- function (a,op,negate){
- !Dataset && (Dataset = require("./dataset"));
- op = op || "AND", negate = negate || false;
- var pairArr = [];
- var isArr = isArray(a) && Expression.isConditionSpecifier(a);
- if (isHash(a)) {
- pairArr.push(this.__filterObject(a, null, op));
- } else {
- for (var k in a) {
- var v = isArr ? a[k][1] : a[k], ret;
- k = isArr ? a[k][0] : k;
- if (isArray(v) || isInstanceOf(v, Dataset)) {
- k = isArray(k) ? k.map(sql.stringToIdentifier) : sql.stringToIdentifier(k);
- ret = new BooleanExpression("IN", k, v);
- } else if (isInstanceOf(v, NegativeBooleanConstant)) {
- ret = new BooleanExpression("ISNOT", k, v.constant);
- } else if (isInstanceOf(v, BooleanConstant)) {
- ret = new BooleanExpression("IS", k, v.constant);
- } else if (isNull(v) || isBoolean(v)) {
- ret = new BooleanExpression("IS", k, v);
- } else if (isHash(v)) {
- ret = BooleanExpression.__filterObject(v, k, op);
- } else if (isRegExp(v)) {
- ret = StringExpression.like(sql.stringToIdentifier(k), v);
- } else {
- ret = new BooleanExpression("EQ", sql.stringToIdentifier(k), v);
- }
- negate && (ret = BooleanExpression.invert(ret));
- pairArr.push(ret);
- }
- }
- //if We just have one then return the first otherwise create a new Boolean expression
- return pairArr.length === 1 ? pairArr[0] : BooleanExpression.fromArgs([op].concat(pairArr));
- }
Invert the expression, if possible. If the expression cannot be inverted, it throws an patio.error.ExpressionError. An inverted expression should match everything that the uninverted expression did not match, and vice-versa, except for possible issues with SQL NULL (i.e. 1 == NULL is NULL and 1 != NULL is also NULL).
ExampleArguments
- BooleanExpression.invert(sql.a) //=> NOT "a"
the expression to invert.
patio.sql.BooleanExpression
the inverted expression.
- function (expression){
- if (isInstanceOf(expression, BooleanExpression)) {
- var op = expression.op, newArgs;
- if (op === "AND" || op === "OR") {
- newArgs = [OPERTATOR_INVERSIONS[op]].concat(expression.args.map(function (arg) {
- return BooleanExpression.invert(arg);
- }));
- return BooleanExpression.fromArgs(newArgs);
- } else {
- newArgs = [OPERTATOR_INVERSIONS[op]].concat(expression.args);
- return BooleanExpression.fromArgs(newArgs);
- }
- } else if (isInstanceOf(expression, StringExpression) || isInstanceOf(expression, NumericExpression)) {
- throw new ExpressionError(format("Cannot invert %4j", [expression]));
- } else {
- return new BooleanExpression("NOT", expression);
- }
- }