diff --git a/lib/queryTransform.js b/lib/queryTransform.js index 571a352..0c3cbcb 100644 --- a/lib/queryTransform.js +++ b/lib/queryTransform.js @@ -51,6 +51,10 @@ Node.prototype.transform = function () { result[this.left.name] = this.right.value } + if (this.type === 'ne' && this.right.type === 'literal') { + result[this.left.name] = { '$ne': this.right.value } + } + if (this.type === 'lt' && this.right.type === 'literal') { result[this.left.name] = { '$lt': this.right.value } } @@ -61,28 +65,68 @@ Node.prototype.transform = function () { if (this.type === 'and') { result['$and'] = result['$and'] || [] - result['$and'].push(new Node(this.left.type, this.left.left, this.left.right, this.func, this.args).transform()) - result['$and'].push(new Node(this.right.type, this.right.left, this.right.right, this.func, this.args).transform()) + if (this.left.type !== 'functioncall') { + result['$and'].push(new Node(this.left.type, this.left.left, this.left.right, this.func, this.args).transform()) + } else { + result['$and'].push(new Node(this.left.type, this.left.left, this.left.right, this.left.func, this.left.args).transform()) + } + + if (this.right.type !== 'functioncall') { + result['$and'].push(new Node(this.right.type, this.right.left, this.right.right, this.func, this.args).transform()) + } else { + result['$and'].push(new Node(this.right.type, this.right.left, this.right.right, this.right.func, this.right.args).transform()) + } } if (this.type === 'or') { result['$or'] = result['$or'] || [] - result['$or'].push(new Node(this.left.type, this.left.left, this.left.right, this.func, this.args).transform()) - result['$or'].push(new Node(this.right.type, this.right.left, this.right.right, this.func, this.args).transform()) + if (this.left.type !== 'functioncall') { + result['$or'].push(new Node(this.left.type, this.left.left, this.left.right, this.func, this.args).transform()) + } else { + result['$or'].push(new Node(this.left.type, this.left.left, this.left.right, this.left.func, this.left.args).transform()) + } + + if (this.right.type !== 'functioncall') { + result['$or'].push(new Node(this.right.type, this.right.left, this.right.right, this.func, this.args).transform()) + } else { + result['$or'].push(new Node(this.right.type, this.right.left, this.right.right, this.right.func, this.right.args).transform()) + } } if (this.type === 'functioncall') { switch (this.func) { - case 'substringof': substringof(this, result) + case 'endswith': + endswith(this, result) + break + case 'substringof': + substringof(this, result) + break + case 'startswith': + startswith(this, result) + break } } return result } +function endswith (node, result) { + var prop = node.args[0].type === 'property' ? node.args[0] : node.args[1] + var lit = node.args[0].type === 'literal' ? node.args[0] : node.args[1] + + result[prop.name] = {'$regex': new RegExp(lit.value + '$'), '$options': 'i'} +} + function substringof (node, result) { var prop = node.args[0].type === 'property' ? node.args[0] : node.args[1] var lit = node.args[0].type === 'literal' ? node.args[0] : node.args[1] - result[prop.name] = new RegExp(lit.value) + result[prop.name] = {'$regex': new RegExp(lit.value), '$options': 'i'} } + +function startswith (node, result) { + var prop = node.args[0].type === 'property' ? node.args[0] : node.args[1] + var lit = node.args[0].type === 'literal' ? node.args[0] : node.args[1] + + result[prop.name] = {'$regex': new RegExp('^' + lit.value), '$options': 'i'} +} \ No newline at end of file