From 3628bd5be86718c3d257152c15910499bd9ba409 Mon Sep 17 00:00:00 2001 From: Ritchie Date: Tue, 11 Jun 2013 11:11:10 -0700 Subject: [PATCH 1/2] Fix remoteEnabled bug --- lib/datasource.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/datasource.js b/lib/datasource.js index 062a4a61..4d37590a 100644 --- a/lib/datasource.js +++ b/lib/datasource.js @@ -73,7 +73,7 @@ function DataSource(name, settings) { accepts: fn.accepts, returns: fn.returns, http: fn.http, - remoteEnabled: fn.share, + remoteEnabled: fn.shared || false, fn: fn }); } @@ -282,8 +282,6 @@ DataSource.prototype.mixin = function (ModelCtor) { // mixin enabled operations as alias functions Object.keys(ops).forEach(function (name) { - console.log(name); - var op = ops[name]; var fn = op.fn; var scope; @@ -1177,9 +1175,10 @@ DataSource.prototype.enableRemote = function (operation) { DataSource.prototype.disable = function (operation) { var op = this.getOperation(operation); if(op) { - op.enabled = false; + op.enabled = + op.remoteEnabled = false; } else { - throw new Error(operation + ' is provided by the attached connector'); + throw new Error(operation + ' is not provided by the attached connector'); } } @@ -1192,7 +1191,7 @@ DataSource.prototype.disableRemote = function (operation) { if(op) { op.remoteEnabled = false; } else { - throw new Error(operation + ' is provided by the attached connector'); + throw new Error(operation + ' is not provided by the attached connector'); } } @@ -1202,9 +1201,10 @@ DataSource.prototype.disableRemote = function (operation) { DataSource.prototype.getOperation = function (operation) { var ops = this.operations(); + var opKeys = Object.keys(ops); - for(var i = 0; i < ops.length; i++) { - var op = ops[i]; + for(var i = 0; i < opKeys.length; i++) { + var op = ops[opKeys[i]]; if(op.name === operation) { return op; @@ -1226,6 +1226,7 @@ DataSource.prototype.operations = function () { DataSource.prototype.defineOperation = function (name, options, fn) { options.fn = fn; + options.name = name; options.enabled = true; this._operations[name] = options; } From 7e23393e9990d2ce33cec258cd5b86a2b4fc4789 Mon Sep 17 00:00:00 2001 From: Ritchie Martori Date: Wed, 12 Jun 2013 15:45:31 -0700 Subject: [PATCH 2/2] Fixed memory adapter filtering + asteroid compatibility upddates --- lib/adapters/memory.js | 22 +++++++----- lib/dao.js | 18 ++++++++++ lib/datasource.js | 80 ++++++++++++++++++------------------------ lib/model-builder.js | 4 +++ 4 files changed, 70 insertions(+), 54 deletions(-) diff --git a/lib/adapters/memory.js b/lib/adapters/memory.js index ff68e337..f40d1753 100644 --- a/lib/adapters/memory.js +++ b/lib/adapters/memory.js @@ -191,10 +191,18 @@ function applyFilter(filter) { } return false; } + if(isNum(example.gt) && example.gt < value) return true; + if(isNum(example.gte) && example.gte <= value) return true; + if(isNum(example.lt) && example.lt > value) return true; + if(isNum(example.lte) && example.lte >= value) return true; } // not strict equality return (example !== null ? example.toString() : example) == (value !== null ? value.toString() : value); } + + function isNum(n) { + return typeof n === 'number'; + } } Memory.prototype.destroyAll = function destroyAll(model, callback) { @@ -209,15 +217,11 @@ Memory.prototype.count = function count(model, callback, where) { var cache = this.cache[model]; var data = Object.keys(cache) if (where) { - data = data.filter(function (id) { - var ok = true; - Object.keys(where).forEach(function (key) { - if (JSON.parse(cache[id])[key] != where[key]) { - ok = false; - } - }); - return ok; - }); + var filter = {where: where}; + data = data.map(function (id) { + return this.fromDb(model, cache[id]); + }.bind(this)); + data = data.filter(applyFilter(filter)); } process.nextTick(function () { callback(null, data.length); diff --git a/lib/dao.js b/lib/dao.js index 87a8e70d..1a64a6e5 100644 --- a/lib/dao.js +++ b/lib/dao.js @@ -157,6 +157,10 @@ DataAccessObject.create = function (data, callback) { return obj; }; +DataAccessObject.create.shared = true; +DataAccessObject.create.accepts = {arg: 'data', type: 'object'}; +DataAccessObject.create.returns = {arg: 'data', type: 'object'}; + function stillConnecting(schema, obj, args) { if (schema.connected) return false; // Connected @@ -358,6 +362,10 @@ DataAccessObject.findOne = function findOne(params, cb) { }); }; +DataAccessObject.findOne.shared = true; +DataAccessObject.findOne.accepts = {arg: 'filter', type: 'object'}; +DataAccessObject.findOne.returns = {arg: 'data', type: 'object'}; + /** * Destroy all records * @param {Function} cb - callback called with (err) @@ -529,6 +537,13 @@ DataAccessObject.prototype.updateAttribute = function updateAttribute(name, valu this.updateAttributes(data, callback); }; +DataAccessObject.prototype.updateAttribute.shared = true; +DataAccessObject.prototype.updateAttribute.accepts = [ + {arg: 'name', type: 'string', required: true}, + {arg: 'value', type: 'any', required: true} +]; +DataAccessObject.prototype.updateAttribute.returns = {arg: 'data', type: 'object'}; + /** * Update set of attributes * @@ -609,6 +624,9 @@ DataAccessObject.prototype.reload = function reload(callback) { this.constructor.find(this.id, callback); }; +DataAccessObject.prototype.reload.shared = true; +DataAccessObject.prototype.reload.returns = {arg: 'data', type: 'object'}; + /** * Define readonly property on object * diff --git a/lib/datasource.js b/lib/datasource.js index 4d37590a..5d7a14ae 100644 --- a/lib/datasource.js +++ b/lib/datasource.js @@ -57,8 +57,11 @@ function DataSource(name, settings) { ModelBuilder.call(this, arguments); this.setup(name, settings); - // default DataAccessObject - this.DataAccessObject = this.constructor.DataAccessObject; + // connector + var connector = this.connector(); + + // DataAccessObject - connector defined or supply the default + this.DataAccessObject = connector.DataAccessObject || this.constructor.DataAccessObject; this.DataAccessObject.call(this, arguments); // operation metadata @@ -73,8 +76,9 @@ function DataSource(name, settings) { accepts: fn.accepts, returns: fn.returns, http: fn.http, - remoteEnabled: fn.shared || false, - fn: fn + remoteEnabled: fn.shared ? true : false, + scope: this.DataAccessObject, + fnName: name }); } }.bind(this)); @@ -89,8 +93,9 @@ function DataSource(name, settings) { accepts: fn.accepts, returns: fn.returns, http: fn.http, - remoteEnabled: fn.share, - fn: fn + remoteEnabled: fn.shared ? true : false, + scope: this.DataAccessObject.prototype, + fnName: name }); } }.bind(this)); @@ -279,27 +284,39 @@ DataSource.prototype.createModel = DataSource.prototype.define; DataSource.prototype.mixin = function (ModelCtor) { var ops = this.operations(); + var self = this; + var DAO = this.DataAccessObject; - // mixin enabled operations as alias functions + // mixin DAO + jutil.mixin(ModelCtor, DAO); + + // decorate operations as alias functions Object.keys(ops).forEach(function (name) { var op = ops[name]; - var fn = op.fn; + var fn = op.scope[op.fnName]; var scope; if(op.enabled) { scope = op.prototype ? ModelCtor.prototype : ModelCtor; - var sfn = scope[name] = function () { - fn.apply(this, arguments); - } - Object.keys(op).forEach(function (key) { - if(key !== 'fn' && key !== 'prototype') { + // var sfn = scope[name] = function () { + // op.scope[op.fnName].apply(self, arguments); + // } + Object.keys(op) + .filter(function (key) { + // filter out the following keys + return ~ [ + 'scope', + 'fnName', + 'prototype' + ].indexOf(key) + }) + .forEach(function (key) { if(typeof op[key] !== 'undefined') { - sfn[key] = op[key]; + op.scope[op.fnName][key] = op[key]; } - } - }); + }); } - }.bind(this)); + }); } /** @@ -324,6 +341,7 @@ DataSource.prototype.attach = function (ModelCtor) { // redefine the schema hiddenProperty(ModelCtor, 'schema', this); + ModelCtor.dataSource = this; // add to def this.definitions[className] = { @@ -1142,19 +1160,6 @@ DataSource.prototype.transaction = function() { return transaction; }; -/** - * Enable a data source operation. - */ - -DataSource.prototype.enable = function (operation) { - var op = this.getOperation(operation); - if(op) { - op.enabled = true; - } else { - throw new Error(operation + ' is provided by the attached connector'); - } -} - /** * Enable a data source operation remotely. */ @@ -1163,20 +1168,6 @@ DataSource.prototype.enableRemote = function (operation) { var op = this.getOperation(operation); if(op) { op.remoteEnabled = true; - } else { - throw new Error(operation + ' is provided by the attached connector'); - } -} - -/** - * Disable a data source operation. - */ - -DataSource.prototype.disable = function (operation) { - var op = this.getOperation(operation); - if(op) { - op.enabled = - op.remoteEnabled = false; } else { throw new Error(operation + ' is not provided by the attached connector'); } @@ -1227,7 +1218,6 @@ DataSource.prototype.operations = function () { DataSource.prototype.defineOperation = function (name, options, fn) { options.fn = fn; options.name = name; - options.enabled = true; this._operations[name] = options; } diff --git a/lib/model-builder.js b/lib/model-builder.js index 8f288b32..295b119d 100644 --- a/lib/model-builder.js +++ b/lib/model-builder.js @@ -167,6 +167,10 @@ ModelBuilder.prototype.define = function defineClass(className, properties, sett Object.keys(properties).forEach(cb); }; + ModelClass.attachTo = function (dataSource) { + dataSource.attach(this); + } + ModelClass.registerProperty = function (attr) { var DataType = properties[attr].type; if(!DataType) {