commit
b78050410d
|
@ -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);
|
||||
|
|
18
lib/dao.js
18
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
|
||||
*
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var ModelBuilder = require('./model-builder.js').ModelBuilder;
|
||||
var jutil = require('./jutil');
|
||||
var ModelBaseClass = require('./model.js');
|
||||
|
@ -57,9 +58,48 @@ 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
|
||||
this._operations = {};
|
||||
|
||||
// define DataAccessObject methods
|
||||
Object.keys(this.DataAccessObject).forEach(function (name) {
|
||||
var fn = this.DataAccessObject[name];
|
||||
|
||||
if(typeof fn === 'function') {
|
||||
this.defineOperation(name, {
|
||||
accepts: fn.accepts,
|
||||
returns: fn.returns,
|
||||
http: fn.http,
|
||||
remoteEnabled: fn.shared ? true : false,
|
||||
scope: this.DataAccessObject,
|
||||
fnName: name
|
||||
});
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
// define DataAccessObject.prototype methods
|
||||
Object.keys(this.DataAccessObject.prototype).forEach(function (name) {
|
||||
var fn = this.DataAccessObject.prototype[name];
|
||||
|
||||
if(typeof fn === 'function') {
|
||||
this.defineOperation(name, {
|
||||
prototype: true,
|
||||
accepts: fn.accepts,
|
||||
returns: fn.returns,
|
||||
http: fn.http,
|
||||
remoteEnabled: fn.shared ? true : false,
|
||||
scope: this.DataAccessObject.prototype,
|
||||
fnName: name
|
||||
});
|
||||
}
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
util.inherits(DataSource, ModelBuilder);
|
||||
|
@ -225,10 +265,40 @@ DataSource.prototype.define = function defineClass(className, properties, settin
|
|||
*/
|
||||
|
||||
DataSource.prototype.mixin = function (ModelCtor) {
|
||||
var ops = this.operations();
|
||||
var self = this;
|
||||
var DAO = this.DataAccessObject;
|
||||
|
||||
// inherit DataAccessObject methods
|
||||
jutil.mixin(ModelCtor, this.DataAccessObject);
|
||||
// mixin DAO
|
||||
jutil.mixin(ModelCtor, DAO);
|
||||
|
||||
// decorate operations as alias functions
|
||||
Object.keys(ops).forEach(function (name) {
|
||||
var op = ops[name];
|
||||
var fn = op.scope[op.fnName];
|
||||
var scope;
|
||||
|
||||
if(op.enabled) {
|
||||
scope = op.prototype ? ModelCtor.prototype : ModelCtor;
|
||||
// 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') {
|
||||
op.scope[op.fnName][key] = op[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -253,6 +323,7 @@ DataSource.prototype.attach = function (ModelCtor) {
|
|||
|
||||
// redefine the schema
|
||||
hiddenProperty(ModelCtor, 'schema', this);
|
||||
ModelCtor.dataSource = this;
|
||||
|
||||
// add to def
|
||||
this.definitions[className] = {
|
||||
|
@ -1072,6 +1143,67 @@ DataSource.prototype.transaction = function() {
|
|||
return transaction;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable a data source operation remotely.
|
||||
*/
|
||||
|
||||
DataSource.prototype.enableRemote = function (operation) {
|
||||
var op = this.getOperation(operation);
|
||||
if(op) {
|
||||
op.remoteEnabled = true;
|
||||
} else {
|
||||
throw new Error(operation + ' is not provided by the attached connector');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a data source operation remotely.
|
||||
*/
|
||||
|
||||
DataSource.prototype.disableRemote = function (operation) {
|
||||
var op = this.getOperation(operation);
|
||||
if(op) {
|
||||
op.remoteEnabled = false;
|
||||
} else {
|
||||
throw new Error(operation + ' is not provided by the attached connector');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an operation's metadata.
|
||||
*/
|
||||
|
||||
DataSource.prototype.getOperation = function (operation) {
|
||||
var ops = this.operations();
|
||||
var opKeys = Object.keys(ops);
|
||||
|
||||
for(var i = 0; i < opKeys.length; i++) {
|
||||
var op = ops[opKeys[i]];
|
||||
|
||||
if(op.name === operation) {
|
||||
return op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all operations.
|
||||
*/
|
||||
|
||||
DataSource.prototype.operations = function () {
|
||||
return this._operations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define an operation.
|
||||
*/
|
||||
|
||||
DataSource.prototype.defineOperation = function (name, options, fn) {
|
||||
options.fn = fn;
|
||||
options.name = name;
|
||||
this._operations[name] = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define hidden property
|
||||
*/
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue