From db75a12118bdd6a92d9e2709c382bd7a120d8ee4 Mon Sep 17 00:00:00 2001 From: mamobyz Date: Thu, 5 Mar 2015 15:13:35 +0100 Subject: [PATCH 1/6] Added strategy clause required for traverse queries which fixes the issue #279 --- lib/db/statement.js | 54 +++++++++++++++++++++++++-------------- test/db/statement-test.js | 20 +++++++++++++++ 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/lib/db/statement.js b/lib/db/statement.js index 1e53a53..c213c16 100644 --- a/lib/db/statement.js +++ b/lib/db/statement.js @@ -1,9 +1,9 @@ "use strict"; -var RID = require('../recordid'), +var RID = require('../recordid'), utils = require('../utils'); -function Statement (db) { +function Statement(db) { this.db = db; this._state = { params: {}, @@ -31,6 +31,16 @@ Statement.prototype.select = clause('select', '*'); */ Statement.prototype.traverse = clause('traverse', '*'); +/** + * A 'strategy' clause for traverse query + * @param {String} args The strategy how traverse should go in deep, either 'DEPTH_FIRST'|'BREADTH_FIRST', the first one is default + * @return {Statement} The statement object + */ +Statement.prototype.strategy = function (s) { + if (typeof s === 'string' && s.toUpperCase() === 'DEPTH_FIRST' || s.toUpperCase() === 'BREADTH_FIRST') + this._state.strategy = s.toUpperCase(); + return this; +}; /** * Insert expression. @@ -431,7 +441,7 @@ Statement.prototype.near = function (latitudeProperty, longitudeProperty, longit values.push(JSON.stringify({maxDistance: maxDistanceInKms})); } return this.where( - '['+properties.join(',')+'] NEAR ['+values.join(',')+']' + '[' + properties.join(',') + '] NEAR [' + values.join(',') + ']' ); }; @@ -448,12 +458,11 @@ Statement.prototype.near = function (latitudeProperty, longitudeProperty, longit */ Statement.prototype.within = function (latitudeProperty, longitudeProperty, box) { return this.where( - '['+latitudeProperty+','+longitudeProperty+'] WITHIN '+JSON.stringify(box) + '[' + latitudeProperty + ',' + longitudeProperty + '] WITHIN ' + JSON.stringify(box) ); }; - /** * Add the given parameter to the query. * @@ -575,7 +584,7 @@ Statement.prototype.buildStatement = function () { } } else { - return ''+item; + return '' + item; } }).join(', ')); } @@ -621,7 +630,7 @@ Statement.prototype.buildStatement = function () { } } else { - return ''+item; + return '' + item; } }).join(', ')); } @@ -638,7 +647,7 @@ Statement.prototype.buildStatement = function () { } } else { - return ''+item; + return '' + item; } }).join(', ')); } @@ -653,7 +662,9 @@ Statement.prototype.buildStatement = function () { else { return this._objectToSet(item); } - }, this).filter(function (item) { return item; }).join(', ')); + }, this).filter(function (item) { + return item; + }).join(', ')); } if (state.increment && state.increment.length) { @@ -711,7 +722,7 @@ Statement.prototype.buildStatement = function () { if ((state.update || state.insert || state.delete) && state.return) { statement.push('RETURN'); if (Array.isArray(state.return)) { - statement.push('['+state.return.join(',')+']'); + statement.push('[' + state.return.join(',') + ']'); } else if (typeof state.return === 'object') { statement.push(encodeReturnObject(state.return)); @@ -777,7 +788,7 @@ Statement.prototype.buildStatement = function () { } } else { - return ''+item; + return '' + item; } }).join(', ')); } @@ -805,7 +816,7 @@ Statement.prototype.buildStatement = function () { return parts.join(' '); } else { - return ''+item; + return '' + item; } }).join(', ')); } @@ -813,6 +824,11 @@ Statement.prototype.buildStatement = function () { if (state.limit) { statement.push('LIMIT ' + (+state.limit)); } + + if (state.strategy && state.traverse) { + statement.push('STRATEGY ' + state.strategy) + } + if (state.skip) { statement.push('SKIP ' + (+state.skip)); } @@ -836,13 +852,13 @@ Statement.prototype.buildStatement = function () { } if (state.wait) { - statement.push('WAIT ' + (+state.wait)); + statement.push('WAIT ' + (+state.wait)); } if (!(state.update || state.insert || state.delete) && state.return) { statement.push('RETURN'); if (Array.isArray(state.return)) { - statement.push('['+state.return.join(',')+']'); + statement.push('[' + state.return.join(',') + ']'); } else if (typeof state.return === 'object') { statement.push(encodeReturnObject(state.return)); @@ -973,11 +989,11 @@ Statement.prototype._objectToSet = function (obj) { } }; -function paramify (key) { +function paramify(key) { return key.replace(/([^A-Za-z0-9])/g, ''); } -function clause (name) { +function clause(name) { var defaults = Array.prototype.slice.call(arguments, 1); return function (args) { if (args === undefined) { @@ -992,7 +1008,7 @@ function clause (name) { }; } -function whereClause (operator, comparisonOperator) { +function whereClause(operator, comparisonOperator) { comparisonOperator = comparisonOperator || '='; return function (condition, params) { this._state.where = this._state.where || []; @@ -1005,7 +1021,7 @@ function whereClause (operator, comparisonOperator) { } -function encodeReturnObject (obj) { +function encodeReturnObject(obj) { var keys = Object.keys(obj), length = keys.length, parts = new Array(length), @@ -1014,5 +1030,5 @@ function encodeReturnObject (obj) { key = keys[i]; parts[i] = utils.encode(key) + ":" + obj[key]; } - return '{'+parts.join(',')+'}'; + return '{' + parts.join(',') + '}'; } \ No newline at end of file diff --git a/test/db/statement-test.js b/test/db/statement-test.js index 3b4e09e..9c20088 100644 --- a/test/db/statement-test.js +++ b/test/db/statement-test.js @@ -178,6 +178,26 @@ COMMIT \n\ this.statement.traverse('in("Thing")', 'out("Thing")'); this.statement.buildStatement().should.equal('TRAVERSE in("Thing"), out("Thing")'); }); + + it('should traverse in depth first', function () { + this.statement.traverse().strategy('DEPTH_FIRST').from('Abc'); + this.statement.buildStatement().should.equal('TRAVERSE * FROM Abc STRATEGY DEPTH_FIRST'); + }); + + it('should traverse in breadth first', function () { + this.statement.traverse().strategy('BREADTH_FIRST').from('#23:4'); + this.statement.buildStatement().should.equal('TRAVERSE * FROM #23:4 STRATEGY BREADTH_FIRST'); + }); + + it('should traverse with no strategy spec', function () { + this.statement.traverse().strategy('XYZ'); + this.statement.buildStatement().should.equal('TRAVERSE *'); + }); + + it('should traverse in breadth first and with limit', function () { + this.statement.traverse().strategy('BREADTH_FIRST').limit(2).from('Xyz'); + this.statement.buildStatement().should.equal('TRAVERSE * FROM Xyz LIMIT 2 STRATEGY BREADTH_FIRST'); + }); }); describe('Statement::while()', function () { From fa8b2228f9d5fa5804e229d883008342f109e8de Mon Sep 17 00:00:00 2001 From: mamobyz Date: Thu, 5 Mar 2015 15:13:35 +0100 Subject: [PATCH 2/6] Added strategy clause required for traverse queries which fixes the issue #279 Style improvements according to JSLint --- lib/db/statement.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/db/statement.js b/lib/db/statement.js index c213c16..6bff1ea 100644 --- a/lib/db/statement.js +++ b/lib/db/statement.js @@ -33,12 +33,14 @@ Statement.prototype.traverse = clause('traverse', '*'); /** * A 'strategy' clause for traverse query - * @param {String} args The strategy how traverse should go in deep, either 'DEPTH_FIRST'|'BREADTH_FIRST', the first one is default - * @return {Statement} The statement object + * @param {String} args The strategy how traverse should go in deep, + * either 'DEPTH_FIRST'|'BREADTH_FIRST', the first one is default + * @return {Statement} The statement object */ Statement.prototype.strategy = function (s) { - if (typeof s === 'string' && s.toUpperCase() === 'DEPTH_FIRST' || s.toUpperCase() === 'BREADTH_FIRST') + if (typeof s === 'string' && s.toUpperCase() === 'DEPTH_FIRST' || s.toUpperCase() === 'BREADTH_FIRST') { this._state.strategy = s.toUpperCase(); + } return this; }; @@ -826,7 +828,7 @@ Statement.prototype.buildStatement = function () { } if (state.strategy && state.traverse) { - statement.push('STRATEGY ' + state.strategy) + statement.push('STRATEGY ' + state.strategy); } if (state.skip) { From 1fce765123111c1dba042cea0df90f646c0113ca Mon Sep 17 00:00:00 2001 From: Zlatko Fedor Date: Sun, 15 Mar 2015 15:55:08 +1300 Subject: [PATCH 3/6] added support for abstract classes --- lib/db/class/index.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/db/class/index.js b/lib/db/class/index.js index e42d89d..25d86db 100644 --- a/lib/db/class/index.js +++ b/lib/db/class/index.js @@ -204,9 +204,10 @@ exports.list = function (refresh) { * @param {String} name The name of the class to create. * @param {String} parentName The name of the parent to extend, if any. * @param {String|Integer} cluster The cluster name or id. + * @param {Boolean} isAbstract The flag for the abstract class * @promise {Object} The created class object */ -exports.create = function (name, parentName, cluster) { +exports.create = function (name, parentName, cluster, isAbstract) { var query = 'CREATE CLASS ' + name; if (parentName) { @@ -216,6 +217,10 @@ exports.create = function (name, parentName, cluster) { if (cluster) { query += ' CLUSTER ' + cluster; } + + if(isAbstract) { + query += ' ABSTRACT'; + } return this.query(query) .bind(this) @@ -296,4 +301,4 @@ exports.cacheData = function (classes) { } return this; -}; \ No newline at end of file +}; From f054e1035cb417675c1f94e8b3c31ae3e0ecc56d Mon Sep 17 00:00:00 2001 From: Zlatko Fedor Date: Sun, 15 Mar 2015 16:00:43 +1300 Subject: [PATCH 4/6] Bad default config for class properties Your current implementation for default value will replace valid number 0 to null because 0 || null => null --- lib/db/class/property.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/db/class/property.js b/lib/db/class/property.js index 9db2bcf..b512d56 100644 --- a/lib/db/class/property.js +++ b/lib/db/class/property.js @@ -35,8 +35,8 @@ Property.prototype.configure = function (config) { this.readonly = config.readonly || false; this.notNull = config.notNull || false; this.collate = config.collate || 'default'; - this.min = config.min || null; - this.max = config.max || null; + this.min = typeof config.min !== 'undefined' ? config.min : null; + this.max = typeof config.max !== 'undefined' ? config.max : null; this.regexp = config.regexp || null; this.linkedClass = config.linkedClass || null; if (config.custom && config.custom.fields) { From 7e403cac52aed8b409709076e57f2e9ed949aeb1 Mon Sep 17 00:00:00 2001 From: Charles Pick Date: Sun, 15 Mar 2015 20:00:14 +0000 Subject: [PATCH 5/6] disable 2.1-SNAPSHOT tests in travis for now --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f3cf06e..7b188f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,4 +6,3 @@ before_script: env: - ORIENTDB_VERSION=1.7.10 - ORIENTDB_VERSION=2.0.2 - - ORIENTDB_VERSION=2.1-SNAPSHOT From dd9aeee8fdff6aaba127b44b1fab2edc90c155ef Mon Sep 17 00:00:00 2001 From: mamobyz Date: Mon, 16 Mar 2015 08:45:25 +0100 Subject: [PATCH 6/6] Undo formatting caused by the last changes --- lib/db/statement.js | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/lib/db/statement.js b/lib/db/statement.js index 6bff1ea..a76697e 100644 --- a/lib/db/statement.js +++ b/lib/db/statement.js @@ -1,9 +1,9 @@ "use strict"; -var RID = require('../recordid'), +var RID = require('../recordid'), utils = require('../utils'); -function Statement(db) { +function Statement (db) { this.db = db; this._state = { params: {}, @@ -443,7 +443,7 @@ Statement.prototype.near = function (latitudeProperty, longitudeProperty, longit values.push(JSON.stringify({maxDistance: maxDistanceInKms})); } return this.where( - '[' + properties.join(',') + '] NEAR [' + values.join(',') + ']' + '['+properties.join(',')+'] NEAR ['+values.join(',')+']' ); }; @@ -460,11 +460,12 @@ Statement.prototype.near = function (latitudeProperty, longitudeProperty, longit */ Statement.prototype.within = function (latitudeProperty, longitudeProperty, box) { return this.where( - '[' + latitudeProperty + ',' + longitudeProperty + '] WITHIN ' + JSON.stringify(box) + '['+latitudeProperty+','+longitudeProperty+'] WITHIN '+JSON.stringify(box) ); }; + /** * Add the given parameter to the query. * @@ -586,7 +587,7 @@ Statement.prototype.buildStatement = function () { } } else { - return '' + item; + return ''+item; } }).join(', ')); } @@ -632,7 +633,7 @@ Statement.prototype.buildStatement = function () { } } else { - return '' + item; + return ''+item; } }).join(', ')); } @@ -649,7 +650,7 @@ Statement.prototype.buildStatement = function () { } } else { - return '' + item; + return ''+item; } }).join(', ')); } @@ -664,9 +665,7 @@ Statement.prototype.buildStatement = function () { else { return this._objectToSet(item); } - }, this).filter(function (item) { - return item; - }).join(', ')); + }, this).filter(function (item) { return item; }).join(', ')); } if (state.increment && state.increment.length) { @@ -724,7 +723,7 @@ Statement.prototype.buildStatement = function () { if ((state.update || state.insert || state.delete) && state.return) { statement.push('RETURN'); if (Array.isArray(state.return)) { - statement.push('[' + state.return.join(',') + ']'); + statement.push('['+state.return.join(',')+']'); } else if (typeof state.return === 'object') { statement.push(encodeReturnObject(state.return)); @@ -790,7 +789,7 @@ Statement.prototype.buildStatement = function () { } } else { - return '' + item; + return ''+item; } }).join(', ')); } @@ -818,7 +817,7 @@ Statement.prototype.buildStatement = function () { return parts.join(' '); } else { - return '' + item; + return ''+item; } }).join(', ')); } @@ -854,13 +853,13 @@ Statement.prototype.buildStatement = function () { } if (state.wait) { - statement.push('WAIT ' + (+state.wait)); + statement.push('WAIT ' + (+state.wait)); } if (!(state.update || state.insert || state.delete) && state.return) { statement.push('RETURN'); if (Array.isArray(state.return)) { - statement.push('[' + state.return.join(',') + ']'); + statement.push('['+state.return.join(',')+']'); } else if (typeof state.return === 'object') { statement.push(encodeReturnObject(state.return)); @@ -991,11 +990,11 @@ Statement.prototype._objectToSet = function (obj) { } }; -function paramify(key) { +function paramify (key) { return key.replace(/([^A-Za-z0-9])/g, ''); } -function clause(name) { +function clause (name) { var defaults = Array.prototype.slice.call(arguments, 1); return function (args) { if (args === undefined) { @@ -1010,7 +1009,7 @@ function clause(name) { }; } -function whereClause(operator, comparisonOperator) { +function whereClause (operator, comparisonOperator) { comparisonOperator = comparisonOperator || '='; return function (condition, params) { this._state.where = this._state.where || []; @@ -1023,7 +1022,7 @@ function whereClause(operator, comparisonOperator) { } -function encodeReturnObject(obj) { +function encodeReturnObject (obj) { var keys = Object.keys(obj), length = keys.length, parts = new Array(length), @@ -1032,5 +1031,5 @@ function encodeReturnObject(obj) { key = keys[i]; parts[i] = utils.encode(key) + ":" + obj[key]; } - return '{' + parts.join(',') + '}'; -} \ No newline at end of file + return '{'+parts.join(',')+'}'; +}