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

Commit 23cc2178 by Jan Aagaard Meier

Add changelog entry and clean up code for sequelize.where

1 parent ba31b20f
# Next
- [FEATURE] Added to posibility of using a sequelize object as key in `sequelize.where`. Also added the option of specifying a comparator
# 2.0.0-rc1
- [BUG] Fixed an issue with foreign key object syntax for hasOne and belongsTo
- [FEATURE] Added `field` and `name` to the object form of foreign key definitions
......
......@@ -1288,48 +1288,6 @@ module.exports = (function() {
return '*';
}
return this.quote(smth.col, factory);
} else if (smth instanceof Utils.json) {
// A recursive parser for nested where conditions
function parseConditionObject(_conditions, path) {
path = path || [];
return _.reduce(_conditions, function (r, v, k) { // result, key, value
if (_.isObject(v)) {
r = r.concat(parseConditionObject(v, path.concat(k))); // Recursively parse objects
} else {
r.push({ path: path.concat(k), value: v });
}
return r;
}, []);
}
// Parse nested object
if (this.conditions) {
var conditions = _.map(parseConditionObject(this.conditions), function generateSql(condition) {
// TODO: Move this postgres specific logic to a more appropriate place
return util.format("%s#>>'{%s}' = '%s'",
_.first(condition.path),
_.rest(condition.path).join(','),
condition.value);
});
result = conditions.join(' and ');
} else if (this.path) {
var str;
// Allow specifying conditions using the postgres json syntax
if (_.any(['->', '->>', '#>'], _.partial(_.contains, this.path))) { // TODO: Move postgres stuff somewhere else
result = this.path;
} else {
// Also support json dot notation
var path = this.path.split('.');
result = util.format("%s#>>'{%s}'",
_.first(path),
_.rest(path).join(','));
}
if (this.value) {
result += util.format(" = %s", this.escape(this.value));
}
}
} else {
result = smth.toString(this, factory);
}
......
......@@ -108,10 +108,12 @@ module.exports = (function() {
// A recursive parser for nested where conditions
parseConditionObject: function(_conditions, path) {
var self = this;
path = path || [];
return Utils._.reduce(_conditions, function (r, v, k) { // result, key, value
if (Utils._.isObject(v)) {
r = r.concat(this.parseConditionObject(v, path.concat(k))); // Recursively parse objects
r = r.concat(self.parseConditionObject(v, path.concat(k))); // Recursively parse objects
} else {
r.push({ path: path.concat(k), value: v });
}
......@@ -123,35 +125,37 @@ module.exports = (function() {
var _ = Utils._;
if (smth instanceof Utils.json) {
// Parse nested object
if (this.conditions) {
var conditions = _.map(this.parseConditionObject(this.conditions), function generateSql(condition) {
// TODO: Move this postgres specific logic to a more appropriate place
if (smth.conditions) {
var conditions = _.map(this.parseConditionObject(smth.conditions), function generateSql(condition) {
return util.format("%s#>>'{%s}' = '%s'",
_.first(condition.path),
_.rest(condition.path).join(','),
condition.value);
});
return conditions.join(' and ');
} else if (this.path) {
} else if (smth.path) {
var str;
// Allow specifying conditions using the postgres json syntax
if (_.any(['->', '->>', '#>'], _.partial(_.contains, this.path))) { // TODO: Move postgres stuff somewhere else
str = this.path;
if (_.any(['->', '->>', '#>'], _.partial(_.contains, smth.path))) {
str = smth.path;
} else {
// Also support json dot notation
var path = this.path.split('.');
var path = smth.path.split('.');
str = util.format("%s#>>'{%s}'",
_.first(path),
_.rest(path).join(','));
}
if (this.value) {
str += util.format(" = %s", this.escape(this.value));
if (smth.value) {
str += util.format(" = %s", this.escape(smth.value));
}
return str;
}
} else {
return AbstractQueryGenerator.call(this, smth, tableName, factory, options, prepend);
return AbstractQueryGenerator.handleSequelizeMethod.call(this, smth, tableName, factory, options, prepend);
}
},
......
......@@ -478,7 +478,7 @@ module.exports = (function() {
this.runHooks('beforeDefine', attributes, options);
modelName = options.modelName;
delete options.modelName;
var factory = new Model(modelName, attributes, options);
this.modelManager.addDAO(factory.init(this.modelManager));
......@@ -876,7 +876,11 @@ module.exports = (function() {
};
/*
* A way of specifying attr = condition. Mostly used internally
* A way of specifying attr = condition.
*
* The attr can either be an object taken from `Model.rawAttributes` (for example `Model.rawAttributes.id` or `Model.rawAttributes.name`). The
* attribute should be defined in your model definition. The attribute can also be an object from one of the sequelize utility functions (`sequelize.fn`, `sequelize.col` et.c).
*
* @see {Model#find}
*
* @param {Object} attr The attribute, which can be either an attribute object from `Model.rawAttributes` or a sequelize object, for example an instance of `sequelize.fn`. For simple string attributes, use the POJO syntax
......
......@@ -147,37 +147,39 @@ describe(Support.getTestDialectTeaser("Utils"), function() {
});
});
describe('json', function () {
var queryGeneratorStub = { escape: function (value) { return "'" + value + "'"; } };
it('successfully parses a complex nested condition hash', function() {
var conditions = {
metadata: {
language: 'icelandic',
pg_rating: { 'dk': 'G' }
},
another_json_field: { x: 1 }
};
var expected = "metadata#>>'{language}' = 'icelandic' and metadata#>>'{pg_rating,dk}' = 'G' and another_json_field#>>'{x}' = '1'";
expect((new Utils.json(conditions)).toString(queryGeneratorStub)).to.deep.equal(expected);
});
if (Support.getTestDialect() === 'postgres') {
describe('json', function () {
var queryGenerator = require('../lib/dialects/postgres/query-generator.js');
it('successfully parses a complex nested condition hash', function() {
var conditions = {
metadata: {
language: 'icelandic',
pg_rating: { 'dk': 'G' }
},
another_json_field: { x: 1 }
};
var expected = "metadata#>>'{language}' = 'icelandic' and metadata#>>'{pg_rating,dk}' = 'G' and another_json_field#>>'{x}' = '1'";
expect(queryGenerator.handleSequelizeMethod(new Utils.json(conditions))).to.deep.equal(expected);
});
it('successfully parses a string using dot notation', function () {
var path = 'metadata.pg_rating.dk';
expect((new Utils.json(path)).toString(queryGeneratorStub)).to.equal("metadata#>>'{pg_rating,dk}'");
});
it('successfully parses a string using dot notation', function () {
var path = 'metadata.pg_rating.dk';
expect(queryGenerator.handleSequelizeMethod(new Utils.json(path))).to.equal("metadata#>>'{pg_rating,dk}'");
});
it('allows postgres json syntax', function () {
var path = 'metadata->pg_rating->>dk';
expect((new Utils.json(path)).toString(queryGeneratorStub)).to.equal(path);
});
it('allows postgres json syntax', function () {
var path = 'metadata->pg_rating->>dk';
expect(queryGenerator.handleSequelizeMethod(new Utils.json(path))).to.equal(path);
});
it('can take a value to compare against', function () {
var path = 'metadata.pg_rating.is';
var value = 'U';
expect((new Utils.json(path, value)).toString(queryGeneratorStub)).to.equal("metadata#>>'{pg_rating,is}' = 'U'");
it('can take a value to compare against', function () {
var path = 'metadata.pg_rating.is';
var value = 'U';
expect(queryGenerator.handleSequelizeMethod(new Utils.json(path, value))).to.equal("metadata#>>'{pg_rating,is}' = 'U'");
});
});
});
}
describe('inflection', function () {
it('works better than lingo ;)', function () {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!