-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support new query language: gizmo according to Caylye's Merge:513(cay…
…leygraph/cayley#513) and Issue:519(cayleygraph/cayley#519), old 'gremlin' will still be supported through the configuration 'queryLang'.
- Loading branch information
Leonard Shi
committed
Jan 14, 2017
1 parent
251c599
commit 3ab8740
Showing
3 changed files
with
201 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
'use strict'; | ||
|
||
const CommonImport = require('../../util/CommonImport'); | ||
|
||
const types = ['query', 'shape']; | ||
|
||
const Path = require('./Path'); | ||
const Query = require('./Query'); | ||
|
||
class Gizmo { | ||
|
||
constructor(promisify, requestWithDefaultOpts, queryLang) { | ||
this._promisify = promisify; | ||
this._request = requestWithDefaultOpts; | ||
this._queryLang = queryLang; | ||
} | ||
|
||
type(type) { | ||
if (!type || types.indexOf(type) === -1) { | ||
throw new Error("Please pass in valid type, can be: 'query' or 'shape'."); | ||
} | ||
const gizmo = new this.constructor(this._promisify, this._request); | ||
gizmo._query = gizmo._query.bind(gizmo, type); | ||
return gizmo; | ||
} | ||
|
||
V() { | ||
return this._v(Array.prototype.slice.call(arguments)); | ||
} | ||
|
||
Vertex() { | ||
return this._v(Array.prototype.slice.call(arguments)); | ||
} | ||
|
||
M() { | ||
return this.Morphism(); | ||
} | ||
|
||
Morphism() { | ||
const path = new Path(['M', []]); | ||
return path; | ||
} | ||
|
||
_v() { | ||
const query = new Query(['V', arguments[0]], this._promisify); | ||
query._query = this._query; | ||
return query; | ||
} | ||
|
||
_query(type, gizmoText, callback) { | ||
if (types.indexOf(type) === -1) { | ||
type = types[0]; | ||
} | ||
this._request.post({ | ||
uri: '/' + type + '/' + this._queryLang, | ||
body: gizmoText | ||
}, (err, res, resBody) => { | ||
if (err) { | ||
callback(err); | ||
} else { | ||
callback(null, JSON.parse(resBody)); | ||
} | ||
}); | ||
} | ||
|
||
} | ||
|
||
module.exports = Gizmo; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
'use strict'; | ||
|
||
const CommonImport = require('../../util/CommonImport'); | ||
|
||
class Path { | ||
|
||
constructor(calls) { | ||
this._calls = calls; | ||
this.constructor._generateFuncs4Path.apply(this); | ||
} | ||
|
||
static _generateFuncs4Path() { | ||
|
||
const generator = (funcName) => { | ||
this[funcName] = (...args) => { | ||
this._calls.push(funcName, args); | ||
return this; | ||
}; | ||
}; | ||
|
||
// Basic Traversals | ||
['Out', 'In', 'Both', 'Is', 'Has', 'LabelContext', 'Limit', 'Skip', 'InPredicates', 'OutPredicates'].forEach(generator); | ||
|
||
// Tagging | ||
['Tag', 'As', 'Back', 'Save'].forEach(generator); | ||
|
||
//Joining | ||
['Intersect', 'And', 'Union', 'Or', 'Except', 'Difference'].forEach(generator); | ||
|
||
//Using Morphisms | ||
['Follow', 'FollowR'].forEach(generator); | ||
} | ||
|
||
} | ||
|
||
module.exports = Path; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
'use strict'; | ||
|
||
const CommonImport = require('../../util/CommonImport'); | ||
|
||
const Path = require('./Path'); | ||
|
||
class Query extends Path { | ||
|
||
constructor(calls, promisify) { | ||
super(calls); | ||
this._promisify = promisify; | ||
this.constructor._generateFuncs4Query.apply(this); | ||
} | ||
|
||
static _getGizmoText() { | ||
if (!this._calls.length) { | ||
return ''; | ||
} | ||
let gizmoText = 'g.'; | ||
this._calls.forEach((item, idx, array) => { | ||
if (Array.isArray(item)) { | ||
const params = item.reduce((acc, curr, innerIdx) => { | ||
if (Number.isInteger(curr)) { | ||
acc += curr; | ||
} else if (typeof curr === 'function') { | ||
acc += curr.toString(); | ||
} else { | ||
acc += ('"' + curr + '"'); | ||
} | ||
if (innerIdx !== item.length - 1) { | ||
acc += ',' | ||
} | ||
return acc; | ||
}, ''); | ||
if (params) { | ||
gizmoText += (array[idx - 1] + '(' + params + ').'); | ||
} else { | ||
gizmoText += (array[idx - 1] + '().'); | ||
} | ||
} | ||
}); | ||
return gizmoText.slice(0, -1); | ||
} | ||
|
||
static _generateFuncs4Query() { | ||
|
||
const generator = (funcName) => { | ||
this[funcName] = (...args) => { | ||
const lastArg = args[args.length - 1]; | ||
if (typeof lastArg === 'function') { | ||
if (this._promisify) { | ||
CommonImport.logger.warn("'promisify' was set to true and 'callback' provided, 'callback' will be ignored."); | ||
} | ||
args.pop(); | ||
} else { | ||
if (!this._promisify) { | ||
throw new Error("'promisify' was set to false, but no 'callback' provided."); | ||
} | ||
} | ||
/* | ||
* Special check for: | ||
* - query.ForEach(callback), query.ForEach(limit, callback) | ||
* - query.Map(callback), query.Map(limit, callback) <- alias of 'query.ForEach' | ||
*/ | ||
if (funcName === 'ForEach' || funcName === 'Map') { | ||
if (typeof args[args.length - 1] !== 'function') { | ||
throw new Error("Missed 'gizmoCallback' function for 'query." | ||
+ funcName + "(gizmoCallback, callback)', or 'query." | ||
+ funcName + "(limit, gizmoCallback, callback)."); | ||
} | ||
} | ||
this._calls.push(funcName, args); | ||
const gizmoText = this.constructor._getGizmoText.apply(this); | ||
if (!gizmoText) { | ||
throw new Error('Invalid gizmo text.'); | ||
} | ||
if (this._promisify) { | ||
return CommonImport.Promise.promisify(this._query)(gizmoText); | ||
} else { | ||
this._query(gizmoText, lastArg); | ||
} | ||
}; | ||
}; | ||
|
||
['All', 'GetLimit', 'ToArray', 'ToValue', 'TagArray', 'TagValue', 'ForEach', 'Map'].forEach(generator); | ||
|
||
} | ||
|
||
} | ||
|
||
module.exports = Query; | ||
|
||
|