diff --git a/lib/term.js b/lib/term.js index 180659d..39792fc 100644 --- a/lib/term.js +++ b/lib/term.js @@ -1,3 +1,4 @@ +var Reflect = require('harmony-reflect'); // ES6 Proxy var Promise = require('bluebird'); var protodef = require(__dirname+'/protodef.js'); var termTypes = protodef.Term.TermType; @@ -9,30 +10,48 @@ var WritableStream = require(__dirname+'/writable_stream.js'); var TransformStream = require(__dirname+'/transform_stream.js'); function Term(r, value, error) { - var self = this; var term = function(field) { if (Term.prototype._fastArity(arguments.length, 1) === false) { var _len = arguments.length;var _args = new Array(_len); for(var _i = 0; _i < _len; _i++) {_args[_i] = arguments[_i];} - Term.prototype._arity(_args, 1, '(...)', self); + Term.prototype._arity(_args, 1, '(...)', term); } - return term.bracket(field); + return term._self.bracket(field); } - helper.changeProto(term, self); + + term._self = this; if (value === undefined) { - term._query = []; + term._self._query = []; } else { - term._query = value; + term._self._query = value; } - term._r = r; // Keep a reference to r for global settings + term._self._r = r; // Keep a reference to r for global settings - if (error !== undefined) { - term._error = error; - term._frames = []; - } + term._self._error = error || null; + term._self._frames = []; - return term; + return new Proxy(term, { + apply: function (target, reciever, args) { + return target.apply(target, args); + }, + get: function (target, prop, receiver) { + if (target._self[prop] !== undefined) { + return Reflect.get(target._self, prop, receiver); + } + if (target[prop] !== undefined) { + return Reflect.get(target, prop, receiver); + } + return target._self.bracket(prop); + }, + set: function (target, prop, receiver) { + return Reflect.set(target._self, prop, receiver); + } + }); +} + +Term.isTerm = function (term) { + return (term && term._self || term) instanceof Term; } // run([connection][, options][, callback]) @@ -890,7 +909,7 @@ Term.prototype.orderBy = function() { var args = [this]; for(var i=0; i<_args.length-1; i++) { - if ((_args[i] instanceof Term) && + if ((Term.isTerm(_args[i])) && ((_args[i]._query[0] === termTypes.DESC) || (_args[i]._query[0] === termTypes.ASC))) { args.push(new Term(this._r).expr(_args[i])) } @@ -904,7 +923,7 @@ Term.prototype.orderBy = function() { term._query.push(new Term(this._r).expr(translateOptions(_args[_args.length-1]))._query); } else { - if ((_args[_args.length-1] instanceof Term) && + if ((Term.isTerm(_args[_args.length-1])) && ((_args[_args.length-1]._query[0] === termTypes.DESC) || (_args[_args.length-1]._query[0] === termTypes.ASC))) { args.push(new Term(this._r).expr(_args[_args.length-1])) } @@ -1853,7 +1872,7 @@ Term.prototype.time = function() { // Special check for arity var foundArgs = false; for(var i=0; i<_args.length; i++) { - if ((_args[i] instanceof Term) && (_args[i]._query[0] === termTypes.ARGS)) { + if ((Term.isTerm(_args[i])) && (_args[i]._query[0] === termTypes.ARGS)) { foundArgs = true; break; } @@ -2282,7 +2301,7 @@ Term.prototype.expr = function(expression, nestingLevel) { //if (nestingLevel == null) nestingLevel = self._r.nestingLevel; if (_nestingLevel < 0) throw new Error.ReqlDriverError('Nesting depth limit exceeded.\nYou probably have a circular reference somewhere') - if (expression instanceof Term) { + if (Term.isTerm(expression)) { return expression; } else if (expression instanceof Function) { @@ -2312,7 +2331,7 @@ Term.prototype.expr = function(expression, nestingLevel) { helper.loopKeys(expression, function(expression, key) { if (expression[key] !== undefined) { var optArg = new Term(self._r).expr(expression[key], _nestingLevel-1); - if (optArg instanceof Term && !foundError && optArg._error != null) { + if (Term.isTerm(optArg) && !foundError && optArg._error != null) { foundError = true; term._error = optArg._error; term._frames = [key].concat(optArg._frames); @@ -2325,7 +2344,7 @@ Term.prototype.expr = function(expression, nestingLevel) { } else { // Primitive if (expression === null) { - return new Term(self._r, null, expression); + return new Term(self._r, null); } else if (typeof expression === 'string') { return new Term(self._r, expression); @@ -2852,7 +2871,7 @@ Term.prototype._fillArgs = function(args) { var foundError = false; var internalArgs = []; for(var i=0; i max) { for(var i=0; i= 3.0.1" + "dependencies": { + "bluebird": ">= 3.0.1", + "harmony-reflect": "^1.4.2" }, "devDependencies": { "mocha": ">= 1.20.0", diff --git a/test/document-manipulation.js b/test/document-manipulation.js index 136e937..0885fef 100644 --- a/test/document-manipulation.js +++ b/test/document-manipulation.js @@ -89,6 +89,18 @@ It('`r.row` should work - 5', function* (done) { } }) +It('`r.row` Proxy should work - 1', function* (done) { + try { + var result = yield r.expr({ foo: { bar: 'baz' } }).foo.bar.run(); + assert.equal(result, 'baz'); + + done(); + } + catch(e) { + done(e); + } +}) + It('`pluck` should work', function* (done) { try { var result = yield r.expr({a: 0, b: 1, c: 2}).pluck("a", "b").run();