Subclass of patio.sql.ComplexExpression where the expression results in a boolean value in SQL.
ExtendsDataset._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)Arguments
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).
ExampleBooleanExpression.invert(sql.a) //=> NOT "a"Arguments
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); } }