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

Commit 3d1a9ff0 by Nuno Sousa

Escape hstore values in all query types

1 parent 9885aca4
......@@ -1163,7 +1163,7 @@ module.exports = (function() {
return emitter.emit('error', err)
}
query = self.QueryInterface.bulkUpdate(self.getTableName(), attrValueHash, where, options)
query = self.QueryInterface.bulkUpdate(self.getTableName(), attrValueHash, where, options, self.rawAttributes)
query.on('sql', function(sql) {
emitter.emit('sql', sql)
})
......
......@@ -2,7 +2,6 @@ var Utils = require("./utils")
, Mixin = require("./associations/mixin")
, DaoValidator = require("./dao-validator")
, DataTypes = require("./data-types")
, hstore = require('./dialects/postgres/hstore')
, _ = require('lodash')
, defaultsOptions = { raw: true }
......@@ -318,7 +317,6 @@ module.exports = (function() {
for (var attrName in self.Model.rawAttributes) {
if (self.Model.rawAttributes.hasOwnProperty(attrName)) {
var definition = self.Model.rawAttributes[attrName]
, isHstore = !!definition.type && (definition.type.toString() === DataTypes.HSTORE.toString())
, isEnum = !!definition.type && (definition.type.toString() === DataTypes.ENUM.toString())
, isMySQL = ['mysql', 'mariadb'].indexOf(self.Model.daoFactoryManager.sequelize.options.dialect) !== -1
, ciCollation = !!self.Model.options.collate && self.Model.options.collate.match(/_ci$/i)
......@@ -334,12 +332,6 @@ module.exports = (function() {
values[attrName] = definition.values[scopeIndex]
}
}
if (isHstore) {
if (typeof values[attrName] === "object") {
values[attrName] = hstore.stringify(values[attrName])
}
}
}
}
......
var Utils = require("../../utils")
, hstore = require('./hstore')
, util = require("util")
, DataTypes = require("../../data-types")
, SqlString = require("../../sql-string")
......@@ -273,7 +274,7 @@ module.exports = (function() {
if (serials.indexOf(key) !== -1) {
return attrValueHash[key] || 'DEFAULT';
}
return this.escape(attrValueHash[key])
return this.escape(attrValueHash[key], modelAttributes && modelAttributes[key])
}.bind(this)).join(",") +
")")
}.bind(this))
......@@ -445,7 +446,7 @@ module.exports = (function() {
// get populated on all databases as DEFAULT value
// i.e. mysql requires: DEFAULT CURRENT_TIMESTAMP
template += " DEFAULT <%= defaultValue %>"
replacements.defaultValue = this.escape(dataType.defaultValue)
replacements.defaultValue = this.escape(dataType.defaultValue, dataType)
}
if (dataType.unique === true) {
......@@ -796,6 +797,21 @@ module.exports = (function() {
}
},
/*
Escape a value (e.g. a string, number or date)
*/
escape: function(value, field) {
if (value instanceof Utils.fn || value instanceof Utils.col || value instanceof Utils.literal || value instanceof Utils.cast) {
return value.toString(this)
} else {
if (field && field.type && field.type.toString() === DataTypes.HSTORE.type && Utils._.isObject(value)) {
value = hstore.stringify(value);
}
return SqlString.escape(value, false, null, this.dialect, field)
}
},
/**
* Generates an SQL query that returns all foreign keys of a table.
*
......
......@@ -499,8 +499,8 @@ module.exports = (function() {
return this.queryAndEmit([sql, dao, options], 'update')
}
QueryInterface.prototype.bulkUpdate = function(tableName, values, identifier, options) {
var sql = this.QueryGenerator.updateQuery(tableName, values, identifier, options)
QueryInterface.prototype.bulkUpdate = function(tableName, values, identifier, options, attributes) {
var sql = this.QueryGenerator.updateQuery(tableName, values, identifier, options, attributes)
return this.queryAndEmit([sql, null, options], 'bulkUpdate')
}
......
......@@ -13,9 +13,9 @@ if (dialect.match(/^postgres/)) {
this.sequelize.options.quoteIdentifiers = true
this.User = this.sequelize.define('User', {
username: DataTypes.STRING,
email: {type: DataTypes.ARRAY(DataTypes.TEXT)},
email: { type: DataTypes.ARRAY(DataTypes.TEXT) },
settings: DataTypes.HSTORE,
document: {type: DataTypes.HSTORE, defaultValue: '"default"=>"value"'}
document: { type: DataTypes.HSTORE, defaultValue: { default: 'value' } }
})
this.User.sync({ force: true }).success(function() {
done()
......@@ -272,6 +272,28 @@ if (dialect.match(/^postgres/)) {
.error(console.log)
})
it("should update hstore correctly", function(done) {
var self = this
this.User
.create({ username: 'user', email: ['foo@bar.com'], settings: { created: { test: '"value"' }}})
.success(function(newUser) {
// Check to see if the default value for an hstore field works
expect(newUser.document).to.deep.equal({default: 'value'})
expect(newUser.settings).to.deep.equal({ created: { test: '"value"' }})
// Check to see if updating an hstore field works
self.User.update({settings: {should: 'update', to: 'this', first: 'place'}}, newUser.identifiers).success(function() {
newUser.reload().success(function() {
// Postgres always returns keys in alphabetical order (ascending)
expect(newUser.settings).to.deep.equal({first: 'place', should: 'update', to: 'this'})
done()
});
})
})
.error(console.log)
})
it("should read hstore correctly", function(done) {
var self = this
var data = { username: 'user', email: ['foo@bar.com'], settings: { created: { test: '"value"' }}}
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!