Comparing version 0.0.2 to 0.0.3
@@ -22,2 +22,3 @@ var parser = require('../dist/parser').parser; | ||
var knexify = exports.knexify = require('./knexify'); | ||
exports.knexify = require('./knexify'); | ||
exports.json = require('./lodash-stmt'); |
@@ -10,27 +10,12 @@ /** | ||
var _ = require('lodash'), | ||
resourceContext = require('./context'), | ||
// local functions | ||
processFilter, | ||
buildWhere, | ||
knexify, | ||
whereType; | ||
// contextual information we need to do the next stage of processing | ||
resourceContext = { | ||
posts: { | ||
name: 'posts', | ||
propAliases: {author: 'author.slug', tags: 'tags.slug', tag: 'tags.slug'}, | ||
relations: [] | ||
}, | ||
tags: { | ||
name: 'tags', | ||
propAliases: {}, | ||
relations: [] | ||
}, | ||
users: { | ||
name: 'users', | ||
propAliases: {role: 'roles.name'}, | ||
relations: [] | ||
} | ||
}; | ||
_.mixin(require('./lodash-stmt')); | ||
// @TODO: remove this function | ||
processFilter = function processFilter(filter, context) { | ||
@@ -40,4 +25,3 @@ var joins = [], | ||
expandAlias, | ||
processProperty, | ||
processProperties; | ||
processProperty; | ||
@@ -85,14 +69,7 @@ addJoin = function addJoin(join) { | ||
processProperties = function processProperties(statements) { | ||
_.each(statements, function (statement) { | ||
if (statement.group) { | ||
processProperties(statement.group); | ||
} else { | ||
statement.prop = processProperty(statement.prop) | ||
} | ||
}); | ||
}; | ||
// Loop through and process all the properties, really should be elsewhere | ||
_.eachStatement(filter.statements, function (statement) { | ||
statement.prop = processProperty(statement.prop); | ||
}); | ||
processProperties(filter.statements); | ||
filter.joins = joins; | ||
@@ -104,2 +81,28 @@ | ||
/** | ||
* Detect Where Type | ||
* @param statement | ||
* @param index | ||
* @returns {string} | ||
*/ | ||
whereType = function whereType(statement, index) { | ||
var whereFunc = 'andWhere'; | ||
if (index === 0) { | ||
whereFunc = 'where'; | ||
} else if (statement.func === 'or') { | ||
whereFunc = 'orWhere'; | ||
} | ||
if (statement.value === null) { | ||
if (statement.func === 'or') { | ||
whereFunc = statement.op === 'IS NOT' ? 'orWhereNotNull' : 'orWhereNull'; | ||
} else { | ||
whereFunc = statement.op === 'IS NOT' ? 'whereNotNull' : 'whereNull'; | ||
} | ||
} | ||
return whereFunc; | ||
}; | ||
/** | ||
* Build Where | ||
@@ -112,50 +115,33 @@ * | ||
buildWhere = function buildWhere(qb, statements) { | ||
if (statements.length === 0) { | ||
return qb; | ||
} | ||
_.each(statements, function(statement, index) { | ||
var whereFunc = 'andWhere'; | ||
if (index === 0) { | ||
whereFunc = 'where'; | ||
} else if (statement.func === 'or') { | ||
whereFunc = 'orWhere'; | ||
} | ||
if (statement.value === null) { | ||
if (statement.func === 'or') { | ||
whereFunc = statement.op === 'IS NOT' ? 'orWhereNotNull' : 'orWhereNull'; | ||
delete statement.op; | ||
delete statement.value; | ||
} else { | ||
whereFunc = statement.op === 'IS NOT' ? 'whereNotNull' : 'whereNull'; | ||
delete statement.op; | ||
delete statement.value; | ||
} | ||
} | ||
// Is this a Group? | ||
if (statement.group) { | ||
qb[whereFunc](function () { | ||
buildWhere(this, statement.group); | ||
_.eachStatement( | ||
statements, | ||
function single(statement, index) { | ||
// @TODO - validate value vs id here, to ensure we only pass valid things into where | ||
qb[whereType(statement, index)](statement.prop, statement.op, statement.value); | ||
}, | ||
function group(statement, index) { | ||
qb[whereType(statement, index)](function (_qb) { | ||
buildWhere(_qb, statement.group); | ||
}); | ||
} else { | ||
// @TODO - validate value vs id here, to ensure we only pass valid things into where | ||
qb[whereFunc](statement.prop, statement.op, statement.value); | ||
} | ||
}); | ||
return qb; | ||
); | ||
}; | ||
knexify = function knexify(qb, filter) { | ||
/** | ||
* Knexify | ||
* Converts a 'filter' from a set of statements in JSON form, into a set of `where` calls on a queryBuilder object | ||
* This wrapping call to buildWhere should eventually be removed | ||
* | ||
* @param qb | ||
* @param filter | ||
* @returns {object} queryBuilder | ||
*/ | ||
module.exports = function knexify(qb, filter) { | ||
filter = processFilter(filter, resourceContext[qb._single.table]); | ||
return buildWhere(qb, filter.statements); | ||
buildWhere(qb, filter.statements); | ||
// return modified queryBuilder object for chaining | ||
return qb; | ||
}; | ||
module.exports = knexify; | ||
// For testing only | ||
module.exports._buildWhere = buildWhere; |
{ | ||
"name": "ghost-gql", | ||
"version": "0.0.2", | ||
"version": "0.0.3", | ||
"description": "Filter query language for Ghost", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -27,4 +27,14 @@ var should = require('should'), | ||
statements: [] | ||
}).toQuery().should.eql('select * from "posts"'); | ||
}); | ||
// Check the output from both toSQL and toQuery - this emulates calling the query twice for pagination | ||
postKnex.toSQL().should.eql({ | ||
bindings: [], | ||
method: 'select', | ||
options: {}, | ||
sql: 'select * from "posts"' | ||
}); | ||
postKnex.toQuery().should.eql('select * from "posts"'); | ||
postKnex.where.calledOnce.should.eql(false); | ||
@@ -44,4 +54,14 @@ postKnex.orWhere.calledOnce.should.eql(false); | ||
] | ||
}).toQuery().should.eql('select * from "posts" where "posts"."id" = 5'); | ||
}); | ||
// Check the output from both toSQL and toQuery - this emulates calling the query twice for pagination | ||
postKnex.toSQL().should.eql({ | ||
bindings: [5], | ||
method: 'select', | ||
options: {}, | ||
sql: 'select * from "posts" where "posts"."id" = ?' | ||
}); | ||
postKnex.toQuery().should.eql('select * from "posts" where "posts"."id" = 5'); | ||
postKnex.where.calledOnce.should.eql(true); | ||
@@ -63,3 +83,13 @@ | ||
] | ||
}).toQuery().should.eql( | ||
}); | ||
// Check the output from both toSQL and toQuery - this emulates calling the query twice for pagination | ||
postKnex.toSQL().should.eql({ | ||
bindings: [5, 'welcome-to-ghost'], | ||
method: 'select', | ||
options: {}, | ||
sql: 'select * from "posts" where "posts"."id" = ? and "posts"."slug" = ?' | ||
}); | ||
postKnex.toQuery().should.eql( | ||
'select * from "posts" where "posts"."id" = 5 and "posts"."slug" = \'welcome-to-ghost\'' | ||
@@ -84,3 +114,13 @@ ); | ||
] | ||
}).toQuery().should.eql( | ||
}); | ||
// Check the output from both toSQL and toQuery - this emulates calling the query twice for pagination | ||
postKnex.toSQL().should.eql({ | ||
bindings: [5, 'welcome-to-ghost'], | ||
method: 'select', | ||
options: {}, | ||
sql: 'select * from "posts" where "posts"."id" = ? or "posts"."slug" = ?' | ||
}); | ||
postKnex.toQuery().should.eql( | ||
'select * from "posts" where "posts"."id" = 5 or "posts"."slug" = \'welcome-to-ghost\'' | ||
@@ -106,3 +146,13 @@ ); | ||
] | ||
}).toQuery().should.eql( | ||
}); | ||
// Check the output from both toSQL and toQuery - this emulates calling the query twice for pagination | ||
postKnex.toSQL().should.eql({ | ||
bindings: [], | ||
method: 'select', | ||
options: {}, | ||
sql: 'select * from "posts" where "posts"."image" is null' | ||
}); | ||
postKnex.toQuery().should.eql( | ||
'select * from "posts" where "posts"."image" is null' | ||
@@ -126,3 +176,13 @@ ); | ||
] | ||
}).toQuery().should.eql( | ||
}); | ||
// Check the output from both toSQL and toQuery - this emulates calling the query twice for pagination | ||
postKnex.toSQL().should.eql({ | ||
bindings: [], | ||
method: 'select', | ||
options: {}, | ||
sql: 'select * from "posts" where "posts"."image" is not null' | ||
}); | ||
postKnex.toQuery().should.eql( | ||
'select * from "posts" where "posts"."image" is not null' | ||
@@ -148,3 +208,13 @@ ); | ||
] | ||
}).toQuery().should.eql( | ||
}); | ||
// Check the output from both toSQL and toQuery - this emulates calling the query twice for pagination | ||
postKnex.toSQL().should.eql({ | ||
bindings: [5], | ||
method: 'select', | ||
options: {}, | ||
sql: 'select * from "posts" where "posts"."id" = ? or "posts"."image" is null' | ||
}); | ||
postKnex.toQuery().should.eql( | ||
'select * from "posts" where "posts"."id" = 5 or "posts"."image" is null' | ||
@@ -170,3 +240,13 @@ ); | ||
] | ||
}).toQuery().should.eql( | ||
}); | ||
// Check the output from both toSQL and toQuery - this emulates calling the query twice for pagination | ||
postKnex.toSQL().should.eql({ | ||
bindings: [5], | ||
method: 'select', | ||
options: {}, | ||
sql: 'select * from "posts" where "posts"."id" = ? or "posts"."image" is not null' | ||
}); | ||
postKnex.toQuery().should.eql( | ||
'select * from "posts" where "posts"."id" = 5 or "posts"."image" is not null' | ||
@@ -188,28 +268,74 @@ ); | ||
describe('group special cases', function () { | ||
it('should correctly build a group query', function () { | ||
knexify(postKnex, { | ||
statements: [ | ||
{op: "!=", value: "joe", prop: "author"}, | ||
{ | ||
group: [ | ||
{op: "=", value: "photo", prop: "tag"}, | ||
{op: "=", value: "video", prop: "tag", func: "or"} | ||
], func: "and" | ||
} | ||
] | ||
}).toQuery().should.eql( | ||
'select * from "posts" where "author"."slug" != \'joe\' and ("tags"."slug" = \'photo\' or "tags"."slug" = \'video\')' | ||
); | ||
it('should correctly build a group query', function () { | ||
knexify(postKnex, { | ||
statements: [ | ||
{op: "!=", value: "joe", prop: "author"}, | ||
{ | ||
group: [ | ||
{op: "=", value: "photo", prop: "tag"}, | ||
{op: "=", value: "video", prop: "tag", func: "or"} | ||
], func: "and" | ||
} | ||
] | ||
}); | ||
postKnex.where.calledOnce.should.eql(true); | ||
postKnex.andWhere.calledOnce.should.eql(true); | ||
// Check the output from both toSQL and toQuery - this emulates calling the query twice for pagination | ||
postKnex.toSQL().should.eql({ | ||
bindings: ['joe', 'photo', 'video'], | ||
method: 'select', | ||
options: {}, | ||
sql: 'select * from "posts" where "author"."slug" != ? and ("tags"."slug" = ? or "tags"."slug" = ?)' | ||
}); | ||
// can't stub out the sub-query-builder functions | ||
postKnex.orWhere.calledOnce.should.eql(false); | ||
postKnex.whereNull.calledOnce.should.eql(false); | ||
postKnex.whereNotNull.calledOnce.should.eql(false); | ||
postKnex.orWhereNull.calledOnce.should.eql(false); | ||
postKnex.orWhereNotNull.calledOnce.should.eql(false); | ||
}); | ||
postKnex.toQuery().should.eql( | ||
'select * from "posts" where "author"."slug" != \'joe\' and ("tags"."slug" = \'photo\' or "tags"."slug" = \'video\')' | ||
); | ||
postKnex.where.calledOnce.should.eql(true); | ||
postKnex.andWhere.calledOnce.should.eql(true); | ||
// can't stub out the sub-query-builder functions | ||
postKnex.orWhere.calledOnce.should.eql(false); | ||
postKnex.whereNull.calledOnce.should.eql(false); | ||
postKnex.whereNotNull.calledOnce.should.eql(false); | ||
postKnex.orWhereNull.calledOnce.should.eql(false); | ||
postKnex.orWhereNotNull.calledOnce.should.eql(false); | ||
}); | ||
it('should correctly build a group query with a not null caluse', function () { | ||
knexify(postKnex, { | ||
statements: [ | ||
{op: "!=", value: "joe", prop: "author"}, | ||
{ | ||
group: [ | ||
{op: "=", value: "true", prop: "featured"}, | ||
{prop: 'image', op: 'IS NOT', value: null, func: 'or'} | ||
], func: "and" | ||
} | ||
] | ||
}); | ||
// Check the output from both toSQL and toQuery - this emulates calling the query twice for pagination | ||
postKnex.toSQL().should.eql({ | ||
bindings: ['joe', 'true'], | ||
method: 'select', | ||
options: {}, | ||
sql: 'select * from "posts" where "author"."slug" != ? and ("posts"."featured" = ? or "posts"."image" is not null)' | ||
}); | ||
postKnex.toQuery().should.eql( | ||
'select * from "posts" where "author"."slug" != \'joe\' and ("posts"."featured" = \'true\' or "posts"."image" is not null)' | ||
); | ||
postKnex.where.calledOnce.should.eql(true); | ||
postKnex.andWhere.calledOnce.should.eql(true); | ||
// can't stub out the sub-query-builder functions | ||
postKnex.orWhere.calledOnce.should.eql(false); | ||
postKnex.whereNull.calledOnce.should.eql(false); | ||
postKnex.whereNotNull.calledOnce.should.eql(false); | ||
postKnex.orWhereNull.calledOnce.should.eql(false); | ||
postKnex.orWhereNotNull.calledOnce.should.eql(false); | ||
}); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
119208
21
2667