不要怂,就是干,撸起袖子干!

Commit 8813622a by Mick Hansen

refactor: introduce Utils.mapFinderOptions

1 parent b7c8e85a
......@@ -676,10 +676,11 @@ UUIDV4.prototype.validate = function(value) {
* @property VIRTUAL
* @alias NONE
*/
var VIRTUAL = function(returnType, fields) {
if (!(this instanceof VIRTUAL)) return new VIRTUAL(returnType, fields);
this.returnType = returnType;
var VIRTUAL = function(ReturnType, fields) {
if (!(this instanceof VIRTUAL)) return new VIRTUAL(ReturnType, fields);
if (typeof ReturnType === 'function') ReturnType = new ReturnType();
this.returnType = ReturnType;
this.fields = fields;
};
util.inherits(VIRTUAL, ABSTRACT);
......
......@@ -538,7 +538,7 @@ validateIncludedElement = function(include, tableNames, options) {
// pseudo include just needed the attribute logic, return
if (include._pseudo) {
return Utils.mapOptionFieldNames(include, include.model);
return Utils.mapFinderOptions(include, include.model);
}
// check if the current Model is actually associated with the passed Model - or it's a pseudo include
......@@ -595,7 +595,7 @@ validateIncludedElement = function(include, tableNames, options) {
Model.$injectScope(model.$scope, include);
include = Utils.mapOptionFieldNames(include, include.model);
include = Utils.mapFinderOptions(include, include.model);
if (include.required === undefined) {
include.required = !!include.where;
......@@ -1326,17 +1326,9 @@ Model.prototype.findAll = function(options) {
if (options.attributes === undefined) {
options.attributes = Object.keys(this.tableAttributes);
} else if (this._hasVirtualAttributes) {
options.attributes.forEach(function (attribute) {
if (this._isVirtualAttribute(attribute) && this.rawAttributes[attribute].type.fields) {
options.attributes = options.attributes.concat(this.rawAttributes[attribute].type.fields);
}
}.bind(this));
options.attributes = _.without.apply(this, [options.attributes].concat(this._virtualAttributes));
options.attributes = _.unique(options.attributes);
}
Utils.mapOptionFieldNames(options, this);
Utils.mapFinderOptions(options, this);
options = paranoidClause(this, options);
......
......@@ -76,6 +76,23 @@ var Utils = module.exports = {
});
},
/* Expand and normalize finder options */
mapFinderOptions: function(options, Model) {
if (Model._hasVirtualAttributes) {
options.attributes.forEach(function (attribute) {
if (Model._isVirtualAttribute(attribute) && Model.rawAttributes[attribute].type.fields) {
options.attributes = options.attributes.concat(Model.rawAttributes[attribute].type.fields);
}
}.bind(Model));
options.attributes = _.without.apply(_, [options.attributes].concat(Model._virtualAttributes));
options.attributes = _.unique(options.attributes);
}
Utils.mapOptionFieldNames(options, Model);
return options;
},
/* Used to map field names in attributes and where conditions */
mapOptionFieldNames: function(options, Model) {
if (options.attributes) {
......
'use strict';
var chai = require('chai')
, expect = chai.expect
, Support = require(__dirname + '/support')
, DataTypes = require(__dirname + '/../../lib/data-types')
, Utils = require(__dirname + '/../../lib/utils');
// Notice: [] will be replaced by dialect specific tick/quote character when there is not dialect specific expectation but only a default expectation
suite(Support.getTestDialectTeaser('Utils'), function() {
suite('toDefaultValue', function () {
test('return plain data types', function () {
expect(Utils.toDefaultValue(DataTypes.UUIDV4)).to.equal('UUIDV4');
});
test('return uuid v1', function () {
expect(/^[a-z0-9\-]{36}$/.test(Utils.toDefaultValue(DataTypes.UUIDV1()))).to.be.equal(true);
});
test('return uuid v4', function () {
expect(/^[a-z0-9\-]{36}/.test(Utils.toDefaultValue(DataTypes.UUIDV4()))).to.be.equal(true);
});
test('return now', function () {
expect(Object.prototype.toString.call(Utils.toDefaultValue(DataTypes.NOW()))).to.be.equal('[object Date]');
});
test('return plain string', function () {
expect(Utils.toDefaultValue('Test')).to.equal('Test');
});
test('return plain object', function () {
chai.assert.deepEqual({}, Utils.toDefaultValue({}));
});
});
suite('mapOptionFieldNames', function () {
test('plain where', function () {
expect(Utils.mapOptionFieldNames({
where: {
firstName: 'Paul',
lastName: 'Atreides'
}
}, this.sequelize.define('User', {
firstName: {
type: DataTypes.STRING,
field: 'first_name'
},
lastName: {
type: DataTypes.STRING,
field: 'last_name'
}
}))).to.eql({
where: {
first_name: 'Paul',
last_name: 'Atreides'
}
});
});
test('$or where', function () {
expect(Utils.mapOptionFieldNames({
where: {
$or: {
firstName: 'Paul',
lastName: 'Atreides'
}
}
}, this.sequelize.define('User', {
firstName: {
type: DataTypes.STRING,
field: 'first_name'
},
lastName: {
type: DataTypes.STRING,
field: 'last_name'
}
}))).to.eql({
where: {
$or: {
first_name: 'Paul',
last_name: 'Atreides'
}
}
});
});
test('$or[] where', function () {
expect(Utils.mapOptionFieldNames({
where: {
$or: [
{firstName: 'Paul'},
{lastName: 'Atreides'}
]
}
}, this.sequelize.define('User', {
firstName: {
type: DataTypes.STRING,
field: 'first_name'
},
lastName: {
type: DataTypes.STRING,
field: 'last_name'
}
}))).to.eql({
where: {
$or: [
{first_name: 'Paul'},
{last_name: 'Atreides'}
]
}
});
});
test('$and where', function () {
expect(Utils.mapOptionFieldNames({
where: {
$and: {
firstName: 'Paul',
lastName: 'Atreides'
}
}
}, this.sequelize.define('User', {
firstName: {
type: DataTypes.STRING,
field: 'first_name'
},
lastName: {
type: DataTypes.STRING,
field: 'last_name'
}
}))).to.eql({
where: {
$and: {
first_name: 'Paul',
last_name: 'Atreides'
}
}
});
});
});
suite('stack', function() {
test('stack trace starts after call to Util.stack()', function this_here_test() {
function a() {
return b();
}
function b() {
return c();
}
function c() {
return Utils.stack();
}
var stack = a();
expect(stack[0].getFunctionName()).to.eql('c');
expect(stack[1].getFunctionName()).to.eql('b');
expect(stack[2].getFunctionName()).to.eql('a');
expect(stack[3].getFunctionName()).to.eql('this_here_test');
});
});
});
\ No newline at end of file
'use strict';
/* jshint -W030 */
/* jshint -W110 */
var chai = require('chai')
, expect = chai.expect
, Utils = require(__dirname + '/../../lib/utils')
, Support = require(__dirname + '/support');
, Support = require(__dirname + '/support')
, DataTypes = require(__dirname + '/../../lib/data-types')
, Utils = require(__dirname + '/../../lib/utils');
describe(Support.getTestDialectTeaser('Utils'), function() {
describe('formatReferences', function () {
// Notice: [] will be replaced by dialect specific tick/quote character when there is not dialect specific expectation but only a default expectation
suite(Support.getTestDialectTeaser('Utils'), function() {
suite('toDefaultValue', function () {
test('return plain data types', function () {
expect(Utils.toDefaultValue(DataTypes.UUIDV4)).to.equal('UUIDV4');
});
test('return uuid v1', function () {
expect(/^[a-z0-9\-]{36}$/.test(Utils.toDefaultValue(DataTypes.UUIDV1()))).to.be.equal(true);
});
test('return uuid v4', function () {
expect(/^[a-z0-9\-]{36}/.test(Utils.toDefaultValue(DataTypes.UUIDV4()))).to.be.equal(true);
});
test('return now', function () {
expect(Object.prototype.toString.call(Utils.toDefaultValue(DataTypes.NOW()))).to.be.equal('[object Date]');
});
test('return plain string', function () {
expect(Utils.toDefaultValue('Test')).to.equal('Test');
});
test('return plain object', function () {
chai.assert.deepEqual({}, Utils.toDefaultValue({}));
});
});
suite('mapFinderOptions', function () {
test('virtual attribute dependencies', function () {
expect(Utils.mapFinderOptions({
attributes: [
'active'
]
}, this.sequelize.define('User', {
createdAt: {
type: DataTypes.DATE,
field: 'created_at'
},
active: {
type: new DataTypes.VIRTUAL(DataTypes.BOOLEAN, ['createdAt'])
}
})).attributes).to.eql([
[
'created_at',
'createdAt'
]
]);
});
});
suite('mapOptionFieldNames', function () {
test('plain where', function () {
expect(Utils.mapOptionFieldNames({
where: {
firstName: 'Paul',
lastName: 'Atreides'
}
}, this.sequelize.define('User', {
firstName: {
type: DataTypes.STRING,
field: 'first_name'
},
lastName: {
type: DataTypes.STRING,
field: 'last_name'
}
}))).to.eql({
where: {
first_name: 'Paul',
last_name: 'Atreides'
}
});
});
test('$or where', function () {
expect(Utils.mapOptionFieldNames({
where: {
$or: {
firstName: 'Paul',
lastName: 'Atreides'
}
}
}, this.sequelize.define('User', {
firstName: {
type: DataTypes.STRING,
field: 'first_name'
},
lastName: {
type: DataTypes.STRING,
field: 'last_name'
}
}))).to.eql({
where: {
$or: {
first_name: 'Paul',
last_name: 'Atreides'
}
}
});
});
test('$or[] where', function () {
expect(Utils.mapOptionFieldNames({
where: {
$or: [
{firstName: 'Paul'},
{lastName: 'Atreides'}
]
}
}, this.sequelize.define('User', {
firstName: {
type: DataTypes.STRING,
field: 'first_name'
},
lastName: {
type: DataTypes.STRING,
field: 'last_name'
}
}))).to.eql({
where: {
$or: [
{first_name: 'Paul'},
{last_name: 'Atreides'}
]
}
});
});
test('$and where', function () {
expect(Utils.mapOptionFieldNames({
where: {
$and: {
firstName: 'Paul',
lastName: 'Atreides'
}
}
}, this.sequelize.define('User', {
firstName: {
type: DataTypes.STRING,
field: 'first_name'
},
lastName: {
type: DataTypes.STRING,
field: 'last_name'
}
}))).to.eql({
where: {
$and: {
first_name: 'Paul',
last_name: 'Atreides'
}
}
});
});
});
suite('stack', function() {
test('stack trace starts after call to Util.stack()', function this_here_test() {
function a() {
return b();
}
function b() {
return c();
}
function c() {
return Utils.stack();
}
var stack = a();
expect(stack[0].getFunctionName()).to.eql('c');
expect(stack[1].getFunctionName()).to.eql('b');
expect(stack[2].getFunctionName()).to.eql('a');
expect(stack[3].getFunctionName()).to.eql('this_here_test');
});
});
suite('formatReferences', function () {
([
[{referencesKey: 1}, {references: {model: undefined, key: 1, deferrable: undefined}, referencesKey: undefined, referencesDeferrable: undefined}],
[{references: 'a'}, {references: {model: 'a', key: undefined, deferrable: undefined}, referencesKey: undefined, referencesDeferrable: undefined}],
......@@ -19,9 +195,9 @@ describe(Support.getTestDialectTeaser('Utils'), function() {
var input = test[0];
var output = test[1];
it('converts ' + JSON.stringify(input) + ' to ' + JSON.stringify(output), function () {
it(JSON.stringify(input) + ' to ' + JSON.stringify(output), function () {
expect(Utils.formatReferences(input)).to.deep.equal(output);
});
});
});
});
});
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!