Refactor more functions into mixins
This commit is contained in:
parent
50b2036511
commit
dd8512bc1f
15
lib/dao.js
15
lib/dao.js
|
@ -7,13 +7,12 @@ module.exports = DataAccessObject;
|
||||||
* Module dependencies
|
* Module dependencies
|
||||||
*/
|
*/
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
|
var jutil = require('./jutil');
|
||||||
var validations = require('./validations.js');
|
var validations = require('./validations.js');
|
||||||
var ValidationError = validations.ValidationError;
|
var ValidationError = validations.ValidationError;
|
||||||
var List = require('./list.js');
|
var List = require('./list.js');
|
||||||
require('./hooks.js');
|
|
||||||
require('./relations.js');
|
require('./relations.js');
|
||||||
require('./include.js');
|
var Inclusion = require('./include.js');
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DAO class - base class for all persist objects
|
* DAO class - base class for all persist objects
|
||||||
|
@ -27,6 +26,13 @@ require('./include.js');
|
||||||
* @param {Object} data - initial object data
|
* @param {Object} data - initial object data
|
||||||
*/
|
*/
|
||||||
function DataAccessObject() {
|
function DataAccessObject() {
|
||||||
|
if(DataAccessObject._mixins) {
|
||||||
|
var self = this;
|
||||||
|
var args = arguments;
|
||||||
|
DataAccessObject._mixins.forEach(function(m) {
|
||||||
|
m.call(self, args);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -616,3 +622,6 @@ function defineReadonlyProp(obj, key, value) {
|
||||||
value: value
|
value: value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jutil.mixin(DataAccessObject, validations.Validatable);
|
||||||
|
jutil.mixin(DataAccessObject, Inclusion);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
* Module dependencies
|
* Module dependencies
|
||||||
*/
|
*/
|
||||||
var ModelBuilder = require('./model-builder.js').ModelBuilder;
|
var ModelBuilder = require('./model-builder.js').ModelBuilder;
|
||||||
|
var jutil = require('./jutil');
|
||||||
var ModelBaseClass = require('./model.js');
|
var ModelBaseClass = require('./model.js');
|
||||||
var DataAccessObject = require('./dao.js');
|
var DataAccessObject = require('./dao.js');
|
||||||
var List = require('./list.js');
|
var List = require('./list.js');
|
||||||
|
@ -53,11 +54,12 @@ function DataSource(name, settings) {
|
||||||
if (!(this instanceof DataSource)) {
|
if (!(this instanceof DataSource)) {
|
||||||
return new DataSource(name, settings);
|
return new DataSource(name, settings);
|
||||||
}
|
}
|
||||||
ModelBuilder.call(this);
|
ModelBuilder.call(this, arguments);
|
||||||
this.setup(name, settings);
|
this.setup(name, settings);
|
||||||
|
|
||||||
// default DataAccessObject
|
// default DataAccessObject
|
||||||
this.DataAccessObject = this.constructor.DataAccessObject;
|
this.DataAccessObject = this.constructor.DataAccessObject;
|
||||||
|
this.DataAccessObject.call(this, arguments);
|
||||||
};
|
};
|
||||||
|
|
||||||
util.inherits(DataSource, ModelBuilder);
|
util.inherits(DataSource, ModelBuilder);
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
/**
|
/**
|
||||||
* Module exports
|
* Module exports
|
||||||
*/
|
*/
|
||||||
exports.Hookable = Hookable;
|
module.exports = Hookable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hooks mixins for ./model.js
|
* Hooks mixins
|
||||||
*/
|
*/
|
||||||
var Hookable = require('./model.js');
|
|
||||||
|
function Hookable() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of hooks available
|
* List of hooks available
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
/**
|
/**
|
||||||
* Include mixin for ./model.js
|
* Include mixin for ./model.js
|
||||||
*/
|
*/
|
||||||
var DataAccessObject = require('./dao.js');
|
module.exports = Inclusion;
|
||||||
|
|
||||||
|
function Inclusion() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows you to load relations of several objects and optimize numbers of requests.
|
* Allows you to load relations of several objects and optimize numbers of requests.
|
||||||
|
@ -22,7 +25,7 @@ var DataAccessObject = require('./dao.js');
|
||||||
* - Passport.include(passports, {owner: [{posts: 'images'}, 'passports']}); // ...
|
* - Passport.include(passports, {owner: [{posts: 'images'}, 'passports']}); // ...
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
DataAccessObject.include = function (objects, include, cb) {
|
Inclusion.include = function (objects, include, cb) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
50
lib/jutil.js
50
lib/jutil.js
|
@ -1,9 +1,51 @@
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param newClass
|
||||||
|
* @param baseClass
|
||||||
|
*/
|
||||||
exports.inherits = function (newClass, baseClass) {
|
exports.inherits = function (newClass, baseClass) {
|
||||||
Object.keys(baseClass).forEach(function (classMethod) {
|
Object.keys(baseClass).forEach(function (classProp) {
|
||||||
newClass[classMethod] = baseClass[classMethod];
|
newClass[classProp] = baseClass[classProp];
|
||||||
});
|
});
|
||||||
Object.keys(baseClass.prototype).forEach(function (instanceMethod) {
|
Object.keys(baseClass.prototype).forEach(function (instanceProp) {
|
||||||
newClass.prototype[instanceMethod] = baseClass.prototype[instanceMethod];
|
newClass.prototype[instanceProp] = baseClass.prototype[instanceProp];
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mix in the base class into the new class
|
||||||
|
* @param newClass
|
||||||
|
* @param baseClass
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
exports.mixin = function (newClass, baseClass, options) {
|
||||||
|
options = options || {
|
||||||
|
staticProperties: true,
|
||||||
|
instanceProperties: true,
|
||||||
|
override: true
|
||||||
|
};
|
||||||
|
|
||||||
|
if (options.staticProperties) {
|
||||||
|
Object.keys(baseClass).forEach(function (classProp) {
|
||||||
|
if (classProp !== 'super_' && (!newClass.hasOwnProperty(classProp) || options.override)) {
|
||||||
|
newClass[classProp] = baseClass[classProp];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.instanceProperties) {
|
||||||
|
if (baseClass.prototype) {
|
||||||
|
Object.keys(baseClass.prototype).forEach(function (instanceProp) {
|
||||||
|
newClass.prototype[instanceProp] = baseClass.prototype[instanceProp];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(newClass._mixins)) {
|
||||||
|
newClass._mixins.push(baseClass);
|
||||||
|
} else {
|
||||||
|
newClass._mixins = [baseClass];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,9 @@ module.exports = ModelBaseClass;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
var List = require('./list.js');
|
var jutil = require('./jutil');
|
||||||
require('./hooks.js');
|
var List = require('./list');
|
||||||
|
var Hookable = require('./hooks');
|
||||||
|
|
||||||
var BASE_TYPES = ['String', 'Boolean', 'Number', 'Date', 'Text'];
|
var BASE_TYPES = ['String', 'Boolean', 'Number', 'Date', 'Text'];
|
||||||
|
|
||||||
|
@ -242,3 +243,5 @@ function isdef(s) {
|
||||||
return s !== undef;
|
return s !== undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jutil.mixin(ModelBaseClass, Hookable);
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ var defineScope = require('./scope.js').defineScope;
|
||||||
/**
|
/**
|
||||||
* Relations mixins for ./dao.js
|
* Relations mixins for ./dao.js
|
||||||
*/
|
*/
|
||||||
var Model = require('./dao.js');
|
var DataAccessObject = require('./dao.js');
|
||||||
|
|
||||||
Model.relationNameFor = function relationNameFor(foreignKey) {
|
DataAccessObject.relationNameFor = function relationNameFor(foreignKey) {
|
||||||
for (var rel in this.relations) {
|
for (var rel in this.relations) {
|
||||||
if (this.relations[rel].type === 'belongsTo' && this.relations[rel].keyFrom === foreignKey) {
|
if (this.relations[rel].type === 'belongsTo' && this.relations[rel].keyFrom === foreignKey) {
|
||||||
return rel;
|
return rel;
|
||||||
|
@ -20,11 +20,11 @@ Model.relationNameFor = function relationNameFor(foreignKey) {
|
||||||
/**
|
/**
|
||||||
* Declare hasMany relation
|
* Declare hasMany relation
|
||||||
*
|
*
|
||||||
* @param {Model} anotherClass - class to has many
|
* @param {DataAccessObject} anotherClass - class to has many
|
||||||
* @param {Object} params - configuration {as:, foreignKey:}
|
* @param {Object} params - configuration {as:, foreignKey:}
|
||||||
* @example `User.hasMany(Post, {as: 'posts', foreignKey: 'authorId'});`
|
* @example `User.hasMany(Post, {as: 'posts', foreignKey: 'authorId'});`
|
||||||
*/
|
*/
|
||||||
Model.hasMany = function hasMany(anotherClass, params) {
|
DataAccessObject.hasMany = function hasMany(anotherClass, params) {
|
||||||
var thisClass = this, thisClassName = this.modelName;
|
var thisClass = this, thisClassName = this.modelName;
|
||||||
params = params || {};
|
params = params || {};
|
||||||
if (typeof anotherClass === 'string') {
|
if (typeof anotherClass === 'string') {
|
||||||
|
@ -175,7 +175,7 @@ Model.hasMany = function hasMany(anotherClass, params) {
|
||||||
*
|
*
|
||||||
* This optional parameter default value is false, so the related object will be loaded from cache if available.
|
* This optional parameter default value is false, so the related object will be loaded from cache if available.
|
||||||
*/
|
*/
|
||||||
Model.belongsTo = function (anotherClass, params) {
|
DataAccessObject.belongsTo = function (anotherClass, params) {
|
||||||
params = params || {};
|
params = params || {};
|
||||||
if ('string' === typeof anotherClass) {
|
if ('string' === typeof anotherClass) {
|
||||||
params.as = anotherClass;
|
params.as = anotherClass;
|
||||||
|
@ -232,7 +232,7 @@ Model.belongsTo = function (anotherClass, params) {
|
||||||
if (!refresh && this.__cachedRelations && (typeof this.__cachedRelations[methodName] !== 'undefined')) {
|
if (!refresh && this.__cachedRelations && (typeof this.__cachedRelations[methodName] !== 'undefined')) {
|
||||||
cachedValue = this.__cachedRelations[methodName];
|
cachedValue = this.__cachedRelations[methodName];
|
||||||
}
|
}
|
||||||
if (p instanceof Model) { // acts as setter
|
if (p instanceof DataAccessObject) { // acts as setter
|
||||||
this[fk] = p.id;
|
this[fk] = p.id;
|
||||||
this.__cachedRelations[methodName] = p;
|
this.__cachedRelations[methodName] = p;
|
||||||
} else if (typeof p === 'function') { // acts as async getter
|
} else if (typeof p === 'function') { // acts as async getter
|
||||||
|
@ -263,7 +263,7 @@ Model.belongsTo = function (anotherClass, params) {
|
||||||
*
|
*
|
||||||
* Post.hasAndBelongsToMany('tags'); creates connection model 'PostTag'
|
* Post.hasAndBelongsToMany('tags'); creates connection model 'PostTag'
|
||||||
*/
|
*/
|
||||||
Model.hasAndBelongsToMany = function hasAndBelongsToMany(anotherClass, params) {
|
DataAccessObject.hasAndBelongsToMany = function hasAndBelongsToMany(anotherClass, params) {
|
||||||
params = params || {};
|
params = params || {};
|
||||||
var models = this.schema.models;
|
var models = this.schema.models;
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,13 @@ exports.defineScope = defineScope;
|
||||||
/**
|
/**
|
||||||
* Scope mixin for ./model.js
|
* Scope mixin for ./model.js
|
||||||
*/
|
*/
|
||||||
var Model = require('./dao.js');
|
var DataAccessObject = require('./dao.js');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define scope
|
* Define scope
|
||||||
* TODO: describe behavior and usage examples
|
* TODO: describe behavior and usage examples
|
||||||
*/
|
*/
|
||||||
Model.scope = function (name, params) {
|
DataAccessObject.scope = function (name, params) {
|
||||||
defineScope(this, this, name, params);
|
defineScope(this, this, name, params);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,10 @@ exports.ValidationError = ValidationError;
|
||||||
* In more complicated cases it can be {Hash} of messages (for each case):
|
* In more complicated cases it can be {Hash} of messages (for each case):
|
||||||
* `User.validatesLengthOf('password', { min: 6, max: 20, message: {min: 'too short', max: 'too long'}});`
|
* `User.validatesLengthOf('password', { min: 6, max: 20, message: {min: 'too short', max: 'too long'}});`
|
||||||
*/
|
*/
|
||||||
var Validatable = require('./dao.js');
|
exports.Validatable = Validatable;
|
||||||
|
|
||||||
|
function Validatable() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate presence. This validation fails when validated field is blank.
|
* Validate presence. This validation fails when validated field is blank.
|
||||||
|
|
Loading…
Reference in New Issue