Clone shared methods so that they can be customized per model
This commit is contained in:
parent
9a5241e8e8
commit
a953ba13de
|
@ -90,14 +90,14 @@ function DataSource(name, settings, modelBuilder) {
|
|||
var connector = this.connector;
|
||||
|
||||
// DataAccessObject - connector defined or supply the default
|
||||
this.DataAccessObject = (connector && connector.DataAccessObject) ? connector.DataAccessObject : this.constructor.DataAccessObject;
|
||||
this.DataAccessObject.apply(this, arguments);
|
||||
|
||||
var dao = (connector && connector.DataAccessObject) || this.constructor.DataAccessObject;
|
||||
this.DataAccessObject = function() {};
|
||||
|
||||
// define DataAccessObject methods
|
||||
Object.keys(this.DataAccessObject).forEach(function (name) {
|
||||
var fn = this.DataAccessObject[name];
|
||||
|
||||
Object.keys(dao).forEach(function (name) {
|
||||
var fn = dao[name];
|
||||
this.DataAccessObject[name] = fn;
|
||||
|
||||
if(typeof fn === 'function') {
|
||||
this.defineOperation(name, {
|
||||
accepts: fn.accepts,
|
||||
|
@ -111,11 +111,10 @@ function DataSource(name, settings, modelBuilder) {
|
|||
}.bind(this));
|
||||
|
||||
// define DataAccessObject.prototype methods
|
||||
Object.keys(this.DataAccessObject.prototype).forEach(function (name) {
|
||||
var fn = this.DataAccessObject.prototype[name];
|
||||
|
||||
Object.keys(dao.prototype).forEach(function (name) {
|
||||
var fn = dao.prototype[name];
|
||||
this.DataAccessObject.prototype[name] = fn;
|
||||
if(typeof fn === 'function') {
|
||||
|
||||
this.defineOperation(name, {
|
||||
prototype: true,
|
||||
accepts: fn.accepts,
|
||||
|
@ -127,8 +126,11 @@ function DataSource(name, settings, modelBuilder) {
|
|||
});
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
util.inherits(DataSource, EventEmitter);
|
||||
|
||||
// allow child classes to supply a data access object
|
||||
|
|
16
lib/jutil.js
16
lib/jutil.js
|
@ -49,6 +49,9 @@ exports.mixin = function (newClass, mixinClass, options) {
|
|||
Object.keys(mixinClass).forEach(function (classProp) {
|
||||
if (classProp !== 'super_' && classProp !== '_mixins' && (!newClass.hasOwnProperty(classProp) || options.override)) {
|
||||
var pd = Object.getOwnPropertyDescriptor(mixinClass, classProp);
|
||||
if(pd.writable && typeof pd.value === 'function' && pd.value.shared) {
|
||||
pd.value = exports.proxy(pd.value);
|
||||
}
|
||||
Object.defineProperty(newClass, classProp, pd);
|
||||
}
|
||||
});
|
||||
|
@ -59,6 +62,9 @@ exports.mixin = function (newClass, mixinClass, options) {
|
|||
Object.keys(mixinClass.prototype).forEach(function (instanceProp) {
|
||||
if (!newClass.prototype.hasOwnProperty(instanceProp) || options.override) {
|
||||
var pd = Object.getOwnPropertyDescriptor(mixinClass.prototype, instanceProp);
|
||||
if(pd.writable && typeof pd.value === 'function' && pd.value.shared) {
|
||||
pd.value = exports.proxy(pd.value);
|
||||
}
|
||||
Object.defineProperty(newClass.prototype, instanceProp, pd);
|
||||
}
|
||||
});
|
||||
|
@ -68,3 +74,13 @@ exports.mixin = function (newClass, mixinClass, options) {
|
|||
return newClass;
|
||||
};
|
||||
|
||||
exports.proxy = function(fn) {
|
||||
var f = function() {
|
||||
return fn.apply(this, arguments);
|
||||
};
|
||||
Object.keys(fn).forEach(function(x) {
|
||||
f[x] = fn[x];
|
||||
});
|
||||
return f;
|
||||
};
|
||||
|
||||
|
|
|
@ -673,3 +673,23 @@ describe('DataSource constructor', function(){
|
|||
});
|
||||
});
|
||||
|
||||
|
||||
describe('Injected remotable methods', function(){
|
||||
it('are not shared across models', function() {
|
||||
var ds = new DataSource('memory');
|
||||
var M1 = ds.createModel('M1');
|
||||
var M2 = ds.createModel('M2');
|
||||
// Remotable methods are not shared across models
|
||||
assert.notEqual(M1.create, M2.create, 'Remotable methods are not shared');
|
||||
assert.equal(M1.create.shared, true, 'M1.create is remotable');
|
||||
assert.equal(M2.create.shared, true, 'M2.create is remotable');
|
||||
M1.create.shared = false;
|
||||
assert.equal(M1.create.shared, false, 'M1.create should be local now');
|
||||
assert.equal(M2.create.shared, true, 'M2.create should stay remotable');
|
||||
// Non-shared method should be same
|
||||
assert.equal(M1.prototype.save, M2.prototype.save,
|
||||
'Local methods should be the same');
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue