added caching functionnality

This commit is contained in:
Sébastien Drouyer 2012-10-30 00:37:19 +01:00
parent 4c95f1dcad
commit 0633737ac7
1 changed files with 51 additions and 11 deletions

View File

@ -37,6 +37,13 @@ AbstractClass.prototype._initProperties = function (data, applySetters) {
var properties = ds.properties; var properties = ds.properties;
data = data || {}; data = data || {};
Object.defineProperty(this, '__cachedRelations', {
writable: true,
enumerable: false,
configurable: true,
value: {}
});
Object.defineProperty(this, '__data', { Object.defineProperty(this, '__data', {
writable: true, writable: true,
enumerable: false, enumerable: false,
@ -723,15 +730,32 @@ AbstractClass.belongsTo = function (anotherClass, params) {
}; };
this.prototype[methodName] = function (p) { this.prototype[methodName] = function (p) {
var self = this;
var cachedValue = null;
if (this.__cachedRelations && this.__cachedRelations[methodName]) {
cachedValue = this.__cachedRelations[methodName];
}
if (p instanceof AbstractClass) { // acts as setter if (p instanceof AbstractClass) { // acts as setter
this[fk] = p.id; this[fk] = p.id;
this.__cachedRelations[methodName] = p;
} else if (typeof p === 'function') { // acts as async getter } else if (typeof p === 'function') { // acts as async getter
this.__finders__[methodName](this[fk], p); if (cachedValue === null) {
this.__finders__[methodName](this[fk], function(err, inst) {
if (!err) {
self.__cachedRelations[methodName] = inst;
}
p(err, inst);
});
return this[fk]; return this[fk];
} else {
p(null, cachedValue);
return cachedValue;
}
} else if (typeof p === 'undefined') { // acts as sync getter } else if (typeof p === 'undefined') { // acts as sync getter
return this[fk]; return cachedValue || this[fk];
} else { // setter } else { // setter
this[fk] = p; this[fk] = p;
this.__cachedRelations[methodName] = p;
} }
}; };
@ -766,18 +790,34 @@ function defineScope(cls, targetClass, name, params, methods) {
enumerable: false, enumerable: false,
configurable: true, configurable: true,
get: function () { get: function () {
var f = function caller(cond, cb) { var f = function caller(condOrRefresh, cb) {
var actualCond; var actualCond = {};
var actualRefresh = false;
if (arguments.length === 1) { if (arguments.length === 1) {
actualCond = {}; cb = condOrRefresh;
cb = cond;
} else if (arguments.length === 2) { } else if (arguments.length === 2) {
actualCond = cond; if (typeof condOrRefresh === 'boolean') {
actualRefresh = condOrRefresh;
} else { } else {
throw new Error('Method only can be called with one or two arguments'); actualCond = condOrRefresh;
}
} else if (arguments.length > 2) {
throw new Error('Method only can\'t be called with more than two arguments');
} }
return targetClass.all(mergeParams(actualCond, caller._scope), cb); if (!this.__cachedRelations || !this.__cachedRelations[name] || actualRefresh) {
var self = this;
return targetClass.all(mergeParams(actualCond, caller._scope), function(err, data) {
self.__cachedRelations[name] = data;
cb(err, data);
});
} else {
if (cb) {
cb(null, this.__cachedRelations);
} else {
return this.__cachedRelations[name];
}
}
}; };
f._scope = typeof params === 'function' ? params.call(this) : params; f._scope = typeof params === 'function' ? params.call(this) : params;
f.build = build; f.build = build;