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

Recursive condition parser for nested json conditions

1 parent 80b9887b
...@@ -1267,6 +1267,8 @@ module.exports = (function() { ...@@ -1267,6 +1267,8 @@ module.exports = (function() {
result = (value === 'NULL') ? key + ' IS NULL' : [key, value].join('='); result = (value === 'NULL') ? key + ' IS NULL' : [key, value].join('=');
} }
} else if (smth instanceof Utils.json) {
result = smth.toString();
} else if (Utils._.isPlainObject(smth)) { } else if (Utils._.isPlainObject(smth)) {
if (prepend) { if (prepend) {
if (tableName) options.keysEscaped = true; if (tableName) options.keysEscaped = true;
......
...@@ -831,6 +831,18 @@ module.exports = (function() { ...@@ -831,6 +831,18 @@ module.exports = (function() {
return new Utils.or(Array.prototype.slice.call(arguments)); return new Utils.or(Array.prototype.slice.call(arguments));
}; };
/**
* Creates an object representing nested where conditions for postgres's json data-type.
* @see {Model#find}
*
* @method json
* @param {Object} conditions A hash containing strings/numbers or other nested hashes
* @return {Sequelize.json}
*/
Sequelize.json = Sequelize.prototype.json = function (conditions) {
return new Utils.json(conditions);
};
/* /*
* A way of specifying attr = condition. Mostly used internally * A way of specifying attr = condition. Mostly used internally
* @see {Model#find} * @see {Model#find}
......
...@@ -547,6 +547,10 @@ var Utils = module.exports = { ...@@ -547,6 +547,10 @@ var Utils = module.exports = {
this.args = args; this.args = args;
}, },
json: function(conditions) {
this.conditions = conditions;
},
where: function(attribute, logic) { where: function(attribute, logic) {
this.attribute = attribute; this.attribute = attribute;
this.logic = logic; this.logic = logic;
...@@ -572,7 +576,8 @@ Utils.where.prototype._isSequelizeMethod = ...@@ -572,7 +576,8 @@ Utils.where.prototype._isSequelizeMethod =
Utils.literal.prototype._isSequelizeMethod = Utils.literal.prototype._isSequelizeMethod =
Utils.cast.prototype._isSequelizeMethod = Utils.cast.prototype._isSequelizeMethod =
Utils.fn.prototype._isSequelizeMethod = Utils.fn.prototype._isSequelizeMethod =
Utils.col.prototype._isSequelizeMethod = true; Utils.col.prototype._isSequelizeMethod =
Utils.json.prototype._isSequelizeMethod = true;
// I know this may seem silly, but this gives us the ability to recognize whether // I know this may seem silly, but this gives us the ability to recognize whether
// or not we should be escaping or if we should trust the user. Basically, it // or not we should be escaping or if we should trust the user. Basically, it
...@@ -613,6 +618,34 @@ Utils.col.prototype.toString = function(queryGenerator, parentModel) { ...@@ -613,6 +618,34 @@ Utils.col.prototype.toString = function(queryGenerator, parentModel) {
return queryGenerator.quote(this.col, parentModel); return queryGenerator.quote(this.col, parentModel);
}; };
Utils.json.prototype.toString = function () {
var _ = Utils._;
// A recursive parser for nested where conditions
function parse(_conditions, path) {
path = path || [];
return _.reduce(_conditions, function (r, v, k) { // result, key, value
if (_.isObject(v)) {
r = r.concat(parse(v, path.concat(k))); // Recursively parse objects
} else {
r.push({ path: path.concat(k), value: v });
}
return r;
}, []);
}
// TODO: Move this postgres specific logic to a more appropriate place
function generateSql(condition) {
return util.format("%s#>>'{%s}' = '%s'",
_.first(condition.path),
_.rest(condition.path).join(','),
condition.value);
}
var conditions = _.map(parse(this.conditions), generateSql);
return conditions.join(' and ');
};
Utils.CustomEventEmitter = require(__dirname + '/emitters/custom-event-emitter'); Utils.CustomEventEmitter = require(__dirname + '/emitters/custom-event-emitter');
Utils.Promise = require(__dirname + '/promise'); Utils.Promise = require(__dirname + '/promise');
Utils.QueryChainer = require(__dirname + '/query-chainer'); Utils.QueryChainer = require(__dirname + '/query-chainer');
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!