Skip to content

Commit

Permalink
Support new query language: gizmo according to Caylye's Merge:513(cay…
Browse files Browse the repository at this point in the history
…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
Show file tree
Hide file tree
Showing 3 changed files with 201 additions and 0 deletions.
70 changes: 70 additions & 0 deletions lib/v1/gizmo/Gizmo.js
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;


38 changes: 38 additions & 0 deletions lib/v1/gizmo/Path.js
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;


93 changes: 93 additions & 0 deletions lib/v1/gizmo/Query.js
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;


0 comments on commit 3ab8740

Please sign in to comment.