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

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 # 2.0.0-rc1
- [BUG] Fixed an issue with foreign key object syntax for hasOne and belongsTo - [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 - [FEATURE] Added `field` and `name` to the object form of foreign key definitions
......
...@@ -1288,48 +1288,6 @@ module.exports = (function() { ...@@ -1288,48 +1288,6 @@ module.exports = (function() {
return '*'; return '*';
} }
return this.quote(smth.col, factory); 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 { } else {
result = smth.toString(this, factory); result = smth.toString(this, factory);
} }
......
...@@ -108,10 +108,12 @@ module.exports = (function() { ...@@ -108,10 +108,12 @@ module.exports = (function() {
// A recursive parser for nested where conditions // A recursive parser for nested where conditions
parseConditionObject: function(_conditions, path) { parseConditionObject: function(_conditions, path) {
var self = this;
path = path || []; path = path || [];
return Utils._.reduce(_conditions, function (r, v, k) { // result, key, value return Utils._.reduce(_conditions, function (r, v, k) { // result, key, value
if (Utils._.isObject(v)) { 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 { } else {
r.push({ path: path.concat(k), value: v }); r.push({ path: path.concat(k), value: v });
} }
...@@ -123,35 +125,37 @@ module.exports = (function() { ...@@ -123,35 +125,37 @@ module.exports = (function() {
var _ = Utils._; var _ = Utils._;
if (smth instanceof Utils.json) { if (smth instanceof Utils.json) {
// Parse nested object // Parse nested object
if (this.conditions) { if (smth.conditions) {
var conditions = _.map(this.parseConditionObject(this.conditions), function generateSql(condition) { var conditions = _.map(this.parseConditionObject(smth.conditions), function generateSql(condition) {
// TODO: Move this postgres specific logic to a more appropriate place
return util.format("%s#>>'{%s}' = '%s'", return util.format("%s#>>'{%s}' = '%s'",
_.first(condition.path), _.first(condition.path),
_.rest(condition.path).join(','), _.rest(condition.path).join(','),
condition.value); condition.value);
}); });
return conditions.join(' and '); return conditions.join(' and ');
} else if (this.path) { } else if (smth.path) {
var str; var str;
// Allow specifying conditions using the postgres json syntax // Allow specifying conditions using the postgres json syntax
if (_.any(['->', '->>', '#>'], _.partial(_.contains, this.path))) { // TODO: Move postgres stuff somewhere else if (_.any(['->', '->>', '#>'], _.partial(_.contains, smth.path))) {
str = this.path; str = smth.path;
} else { } else {
// Also support json dot notation // Also support json dot notation
var path = this.path.split('.'); var path = smth.path.split('.');
str = util.format("%s#>>'{%s}'", str = util.format("%s#>>'{%s}'",
_.first(path), _.first(path),
_.rest(path).join(',')); _.rest(path).join(','));
} }
if (this.value) { if (smth.value) {
str += util.format(" = %s", this.escape(this.value)); str += util.format(" = %s", this.escape(smth.value));
} }
return str;
} }
} else { } 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() { ...@@ -478,7 +478,7 @@ module.exports = (function() {
this.runHooks('beforeDefine', attributes, options); this.runHooks('beforeDefine', attributes, options);
modelName = options.modelName; modelName = options.modelName;
delete options.modelName; delete options.modelName;
var factory = new Model(modelName, attributes, options); var factory = new Model(modelName, attributes, options);
this.modelManager.addDAO(factory.init(this.modelManager)); this.modelManager.addDAO(factory.init(this.modelManager));
...@@ -876,7 +876,11 @@ module.exports = (function() { ...@@ -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} * @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 * @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() { ...@@ -147,37 +147,39 @@ describe(Support.getTestDialectTeaser("Utils"), function() {
}); });
}); });
describe('json', function () { if (Support.getTestDialect() === 'postgres') {
var queryGeneratorStub = { escape: function (value) { return "'" + value + "'"; } }; describe('json', function () {
var queryGenerator = require('../lib/dialects/postgres/query-generator.js');
it('successfully parses a complex nested condition hash', function() {
var conditions = { it('successfully parses a complex nested condition hash', function() {
metadata: { var conditions = {
language: 'icelandic', metadata: {
pg_rating: { 'dk': 'G' } language: 'icelandic',
}, pg_rating: { 'dk': 'G' }
another_json_field: { x: 1 } },
}; 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); 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 () { it('successfully parses a string using dot notation', function () {
var path = 'metadata.pg_rating.dk'; var path = 'metadata.pg_rating.dk';
expect((new Utils.json(path)).toString(queryGeneratorStub)).to.equal("metadata#>>'{pg_rating,dk}'"); expect(queryGenerator.handleSequelizeMethod(new Utils.json(path))).to.equal("metadata#>>'{pg_rating,dk}'");
}); });
it('allows postgres json syntax', function () { it('allows postgres json syntax', function () {
var path = 'metadata->pg_rating->>dk'; var path = 'metadata->pg_rating->>dk';
expect((new Utils.json(path)).toString(queryGeneratorStub)).to.equal(path); expect(queryGenerator.handleSequelizeMethod(new Utils.json(path))).to.equal(path);
}); });
it('can take a value to compare against', function () { it('can take a value to compare against', function () {
var path = 'metadata.pg_rating.is'; var path = 'metadata.pg_rating.is';
var value = 'U'; var value = 'U';
expect((new Utils.json(path, value)).toString(queryGeneratorStub)).to.equal("metadata#>>'{pg_rating,is}' = 'U'"); expect(queryGenerator.handleSequelizeMethod(new Utils.json(path, value))).to.equal("metadata#>>'{pg_rating,is}' = 'U'");
});
}); });
}); }
describe('inflection', function () { describe('inflection', function () {
it('works better than lingo ;)', 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!