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

Commit 68f920e0 by Daniel Durante

Merged master and forgot to Object.keys() for skipping validations.

2 parents 0299ce63 6815eb51
...@@ -33,7 +33,10 @@ ...@@ -33,7 +33,10 @@
- [BUG] Fixed eager loading for many-to-many associations. [#834](https://github.com/sequelize/sequelize/pull/834). thanks to lemon-tree - [BUG] Fixed eager loading for many-to-many associations. [#834](https://github.com/sequelize/sequelize/pull/834). thanks to lemon-tree
- [BUG] allowNull: true enums can now be null [#857](https://github.com/sequelize/sequelize/pull/857). thanks to durango - [BUG] allowNull: true enums can now be null [#857](https://github.com/sequelize/sequelize/pull/857). thanks to durango
- [BUG] Fixes Postgres' ability to search within arrays. [#879](https://github.com/sequelize/sequelize/pull/879). thanks to durango - [BUG] Fixes Postgres' ability to search within arrays. [#879](https://github.com/sequelize/sequelize/pull/879). thanks to durango
- [BUG] Find and finAll would modify the options objects, now the objects are cloned at the start of the method [#884](https://github.com/sequelize/sequelize/pull/884) - [BUG] Find and finAll would modify the options objects, now the objects are cloned at the start of the method [#884](https://github.com/sequelize/sequelize/pull/884) thanks to janmeier
- [BUG] Add support for typed arrays in SqlString.escape and SqlString.arrayToList [#891](https://github.com/sequelize/sequelize/pull/891). thanks to LJ1102
- [BUG] Postgres requires empty array to be explicitly cast on update [#890](https://github.com/sequelize/sequelize/pull/890). thanks to robraux
- [BUG] Added tests & bugfixes for DAO-Factory.update and array of values in where clause [#880](https://github.com/sequelize/sequelize/pull/880). thanks to domasx2
- [FEATURE] Validate a model before it gets saved. [#601](https://github.com/sequelize/sequelize/pull/601). thanks to durango - [FEATURE] Validate a model before it gets saved. [#601](https://github.com/sequelize/sequelize/pull/601). thanks to durango
- [FEATURE] Schematics. [#564](https://github.com/sequelize/sequelize/pull/564). thanks to durango - [FEATURE] Schematics. [#564](https://github.com/sequelize/sequelize/pull/564). thanks to durango
- [FEATURE] Foreign key constraints. [#595](https://github.com/sequelize/sequelize/pull/595). thanks to optilude - [FEATURE] Foreign key constraints. [#595](https://github.com/sequelize/sequelize/pull/595). thanks to optilude
......
...@@ -943,7 +943,7 @@ module.exports = (function() { ...@@ -943,7 +943,7 @@ module.exports = (function() {
if (options.validate === true) { if (options.validate === true) {
var build = self.build(attrValueHash) var build = self.build(attrValueHash)
build.hookValidate({skip: attrValueHash}).error(function(err) { build.hookValidate({skip: Object.keys(attrValueHash)}).error(function(err) {
emitter.emit('error', err) emitter.emit('error', err)
}).success(function(attributes) { }).success(function(attributes) {
if (!!attributes && !!attributes.dataValues) { if (!!attributes && !!attributes.dataValues) {
......
...@@ -67,7 +67,7 @@ var validateModel = function() { ...@@ -67,7 +67,7 @@ var validateModel = function() {
} }
var validateAttributes = function() { var validateAttributes = function() {
var self = this var self = this
, errors = {} , errors = {}
// for each field and value // for each field and value
......
...@@ -19,9 +19,9 @@ module.exports = (function() { ...@@ -19,9 +19,9 @@ module.exports = (function() {
// set pooling parameters if specified // set pooling parameters if specified
if (this.pooling) { if (this.pooling) {
this.pg.defaults.poolSize = this.config.pool.maxConnections this.pg.defaults.poolSize = this.config.pool.maxConnections || 10
this.pg.defaults.poolIdleTimeout = this.config.pool.maxIdleTime this.pg.defaults.poolIdleTimeout = this.config.pool.maxIdleTime || 30000
this.pg.defaults.reapIntervalMillis = this.config.pool.reapInterval || 1000 this.pg.defaults.reapIntervalMillis = this.config.pool.reapInterval || 1000
} }
this.disconnectTimeoutId = null this.disconnectTimeoutId = null
...@@ -142,7 +142,9 @@ module.exports = (function() { ...@@ -142,7 +142,9 @@ module.exports = (function() {
} }
if (this.client) { if (this.client) {
this.client.end.bind(this.client) // Closes a client correctly even if we have backed up queries
// https://github.com/brianc/node-postgres/pull/346
this.client.on('drain', this.client.end.bind(this.client))
} }
this.isConnecting = false this.isConnecting = false
......
...@@ -382,7 +382,7 @@ module.exports = (function() { ...@@ -382,7 +382,7 @@ module.exports = (function() {
return Utils._.template(query)(replacements) return Utils._.template(query)(replacements)
}, },
updateQuery: function(tableName, attrValueHash, where, options) { updateQuery: function(tableName, attrValueHash, where, options, attributes) {
attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, this.options.omitNull, options) attrValueHash = Utils.removeNullValuesFromHash(attrValueHash, this.options.omitNull, options)
var query = "UPDATE <%= table %> SET <%= values %> WHERE <%= where %> RETURNING *" var query = "UPDATE <%= table %> SET <%= values %> WHERE <%= where %> RETURNING *"
...@@ -390,7 +390,7 @@ module.exports = (function() { ...@@ -390,7 +390,7 @@ module.exports = (function() {
for (var key in attrValueHash) { for (var key in attrValueHash) {
var value = attrValueHash[key] var value = attrValueHash[key]
values.push(this.quoteIdentifier(key) + "=" + this.escape(value)) values.push(this.quoteIdentifier(key) + "=" + this.escape(value, (!!attributes && !!attributes[key] ? attributes[key] : undefined)))
} }
var replacements = { var replacements = {
...@@ -565,16 +565,19 @@ module.exports = (function() { ...@@ -565,16 +565,19 @@ module.exports = (function() {
if (Array.isArray(value)) { if (Array.isArray(value)) {
if (value.length === 0) { value = [null] } if (value.length === 0) { value = [null] }
var col = null, coltype = null
// Special conditions for searching within an array column type // Special conditions for searching within an array column type
var _realKey = key.split('.').pop() var _realKey = key.split('.').pop()
if (!!factory && !!factory.rawAttributes[_realKey]) { if (!!factory && !!factory.rawAttributes[_realKey]) {
var col = factory.rawAttributes[_realKey] col = factory.rawAttributes[_realKey]
coltype = col.type
if ((!!col.type && col.type.match(/\[\]$/) !== null) || (col.toString().match(/\[\]$/) !== null)) { if(coltype && !(typeof coltype == 'string')) {
_value = 'ARRAY[' + value.map(this.escape).join(',') + ']::' + (!!col.type ? col.type : col.toString()) coltype = coltype.toString();
result.push([_key, _value].join(" && "))
} }
}
if ( col && ((!!coltype && coltype.match(/\[\]$/) !== null) || (col.toString().match(/\[\]$/) !== null))) {
_value = 'ARRAY[' + value.map(this.escape).join(',') + ']::' + (!!col.type ? col.type : col.toString())
result.push([_key, _value].join(" && "))
} else { } else {
_value = "(" + value.map(this.escape).join(',') + ")" _value = "(" + value.map(this.escape).join(',') + ")"
result.push([_key, _value].join(" IN ")) result.push([_key, _value].join(" IN "))
......
...@@ -20,34 +20,34 @@ module.exports = (function() { ...@@ -20,34 +20,34 @@ module.exports = (function() {
Query.prototype.run = function(sql) { Query.prototype.run = function(sql) {
this.sql = sql this.sql = sql
var self = this var self = this
, receivedError = false
, query = this.client.query(sql)
, rows = []
if (this.options.logging !== false) { if (this.options.logging !== false) {
this.options.logging('Executing: ' + this.sql) this.options.logging('Executing: ' + this.sql)
} }
var receivedError = false
, query = this.client.query(sql)
, rows = []
query.on('row', function(row) { query.on('row', function(row) {
rows.push(row) rows.push(row)
}) })
query.on('error', function(err) { query.on('error', function(err) {
receivedError = true receivedError = true
this.emit('error', err, this.callee) self.emit('error', err, self.callee)
}.bind(this)) })
query.on('end', function() { query.on('end', function() {
this.emit('sql', this.sql) self.emit('sql', self.sql)
if (receivedError) { if (receivedError) {
return return
} }
onSuccess.call(this, rows, sql) onSuccess.call(self, rows, sql)
}.bind(this)) })
return this return this
} }
......
...@@ -417,7 +417,7 @@ module.exports = (function() { ...@@ -417,7 +417,7 @@ module.exports = (function() {
QueryInterface.prototype.update = function(dao, tableName, values, identifier, options) { QueryInterface.prototype.update = function(dao, tableName, values, identifier, options) {
var self = this var self = this
, restrict = false , restrict = false
, sql = self.QueryGenerator.updateQuery(tableName, values, identifier, options) , sql = self.QueryGenerator.updateQuery(tableName, values, identifier, options, dao.daoFactory.rawAttributes)
// Check for a restrict field // Check for a restrict field
if (!!dao.daoFactory && !!dao.daoFactory.associations) { if (!!dao.daoFactory && !!dao.daoFactory.associations) {
......
var moment = require("moment") var moment = require("moment")
, isArrayBufferView
, SqlString = exports; , SqlString = exports;
if (typeof ArrayBufferView === 'function') {
isArrayBufferView = function(object) { return object && (object instanceof ArrayBufferView) }
} else {
var arrayBufferViews = [
Int8Array, Uint8Array, Int16Array, Uint16Array,
Int32Array, Uint32Array, Float32Array, Float64Array
]
isArrayBufferView = function(object) {
for (var i=0; i<8; i++) {
if (object instanceof arrayBufferViews[i]) {
return true
}
}
return false
};
}
SqlString.escapeId = function (val, forbidQualified) { SqlString.escapeId = function (val, forbidQualified) {
if (forbidQualified) { if (forbidQualified) {
return '`' + val.replace(/`/g, '``') + '`'; return '`' + val.replace(/`/g, '``') + '`'
} }
return '`' + val.replace(/`/g, '``').replace(/\./g, '`.`') + '`'; return '`' + val.replace(/`/g, '``').replace(/\./g, '`.`') + '`'
}; }
SqlString.escape = function(val, stringifyObjects, timeZone, dialect, field) { SqlString.escape = function(val, stringifyObjects, timeZone, dialect, field) {
if (arguments.length === 1 && typeof arguments[0] === "object") { if (arguments.length === 1 && typeof arguments[0] === "object") {
...@@ -37,29 +56,28 @@ SqlString.escape = function(val, stringifyObjects, timeZone, dialect, field) { ...@@ -37,29 +56,28 @@ SqlString.escape = function(val, stringifyObjects, timeZone, dialect, field) {
} }
if (val instanceof Date) { if (val instanceof Date) {
val = SqlString.dateToString(val, timeZone || "Z", dialect); val = SqlString.dateToString(val, timeZone || "Z", dialect)
} }
if (Buffer.isBuffer(val)) { if (Buffer.isBuffer(val)) {
return SqlString.bufferToString(val, dialect); return SqlString.bufferToString(val, dialect)
} }
if (Array.isArray(val) || isArrayBufferView(val)) {
if (Array.isArray(val)) { return SqlString.arrayToList(val, timeZone, dialect, field)
return SqlString.arrayToList(val, timeZone, dialect, field);
} }
if (typeof val === 'object') { if (typeof val === 'object') {
if (stringifyObjects) { if (stringifyObjects) {
val = val.toString(); val = val.toString()
} else { } else {
return SqlString.objectToValues(val, timeZone); return SqlString.objectToValues(val, timeZone)
} }
} }
if (dialect === 'postgres' || dialect === 'sqlite') { if (dialect === 'postgres' || dialect === 'sqlite') {
// http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS // http://www.postgresql.org/docs/8.2/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS
// http://stackoverflow.com/q/603572/130598 // http://stackoverflow.com/q/603572/130598
val = val.replace(/'/g, "''"); val = val.replace(/'/g, "''")
} else { } else {
val = val.replace(/[\0\n\r\b\t\\\'\"\x1a]/g, function(s) { val = val.replace(/[\0\n\r\b\t\\\'\"\x1a]/g, function(s) {
switch(s) { switch(s) {
...@@ -71,115 +89,134 @@ SqlString.escape = function(val, stringifyObjects, timeZone, dialect, field) { ...@@ -71,115 +89,134 @@ SqlString.escape = function(val, stringifyObjects, timeZone, dialect, field) {
case "\x1a": return "\\Z"; case "\x1a": return "\\Z";
default: return "\\"+s; default: return "\\"+s;
} }
}); })
} }
return "'"+val+"'"; return "'"+val+"'"
}; }
SqlString.arrayToList = function(array, timeZone, dialect, field) { SqlString.arrayToList = function(array, timeZone, dialect, field) {
if (dialect === 'postgres') { if (dialect === 'postgres') {
var ret = 'ARRAY[' + array.map(function(v) { if (array.map) {
return SqlString.escape(v, true, timeZone, dialect, field); var valstr = array.map(function(v) {
}).join(',') + ']'; return SqlString.escape(v, true, timeZone, dialect, field)
}).join(',')
} else {
var valstr = ""
for (var i = 0; i < array.length; i++) {
valstr += SqlString.escape(array[i], true, timeZone, dialect, field) + ','
}
valstr = valstr.slice(0,-1)
}
var ret = 'ARRAY[' + valstr + ']'
if (!!field && !!field.type) { if (!!field && !!field.type) {
ret += '::' + field.type.replace(/\(\d+\)/g, ''); ret += '::' + field.type.replace(/\(\d+\)/g, '')
} }
return ret; return ret
} else { } else {
return array.map(function(v) { if (array.map) {
if (Array.isArray(v)) return array.map(function(v) {
return '(' + SqlString.arrayToList(v, timeZone, dialect) + ')'; if (Array.isArray(v)) {
return SqlString.escape(v, true, timeZone, dialect); return '(' + SqlString.arrayToList(v, timeZone, dialect) + ')'
}).join(', '); }
return SqlString.escape(v, true, timeZone, dialect)
}).join(', ')
} else {
var valstr = ""
for (var i = 0; i < array.length; i++) {
valstr += SqlString.escape(array[i], true, timeZone, dialect) + ', '
}
return valstr.slice(0, -2)
}
} }
}; }
SqlString.format = function(sql, values, timeZone, dialect) { SqlString.format = function(sql, values, timeZone, dialect) {
values = [].concat(values); values = [].concat(values);
return sql.replace(/\?/g, function(match) { return sql.replace(/\?/g, function(match) {
if (!values.length) { if (!values.length) {
return match; return match
} }
return SqlString.escape(values.shift(), false, timeZone, dialect); return SqlString.escape(values.shift(), false, timeZone, dialect)
}); })
}; }
SqlString.formatNamedParameters = function(sql, values, timeZone, dialect) { SqlString.formatNamedParameters = function(sql, values, timeZone, dialect) {
return sql.replace(/\:(\w+)/g, function (value, key) { return sql.replace(/\:(\w+)/g, function (value, key) {
if (values.hasOwnProperty(key)) { if (values.hasOwnProperty(key)) {
return SqlString.escape(values[key], false, timeZone, dialect); return SqlString.escape(values[key], false, timeZone, dialect)
} } else {
else { throw new Error('Named parameter "' + value + '" has no value in the given object.')
throw new Error('Named parameter "' + value + '" has no value in the given object.');
} }
}); })
}; }
SqlString.dateToString = function(date, timeZone, dialect) { SqlString.dateToString = function(date, timeZone, dialect) {
var dt = new Date(date); var dt = new Date(date)
// TODO: Ideally all dialects would work a bit more like this // TODO: Ideally all dialects would work a bit more like this
if (dialect === "postgres") { if (dialect === "postgres") {
return moment(dt).zone('+00:00').format("YYYY-MM-DD HH:mm:ss.SSS Z"); return moment(dt).zone('+00:00').format("YYYY-MM-DD HH:mm:ss.SSS Z")
} }
if (timeZone !== 'local') { if (timeZone !== 'local') {
var tz = convertTimezone(timeZone); var tz = convertTimezone(timeZone)
dt.setTime(dt.getTime() + (dt.getTimezoneOffset() * 60000)); dt.setTime(dt.getTime() + (dt.getTimezoneOffset() * 60000))
if (tz !== false) { if (tz !== false) {
dt.setTime(dt.getTime() + (tz * 60000)); dt.setTime(dt.getTime() + (tz * 60000))
} }
} }
return moment(dt).format("YYYY-MM-DD HH:mm:ss"); return moment(dt).format("YYYY-MM-DD HH:mm:ss")
}; }
SqlString.bufferToString = function(buffer, dialect) { SqlString.bufferToString = function(buffer, dialect) {
var hex = ''; var hex = ''
try { try {
hex = buffer.toString('hex'); hex = buffer.toString('hex')
} catch (err) { } catch (err) {
// node v0.4.x does not support hex / throws unknown encoding error // node v0.4.x does not support hex / throws unknown encoding error
for (var i = 0; i < buffer.length; i++) { for (var i = 0; i < buffer.length; i++) {
var byte = buffer[i]; var byte = buffer[i]
hex += zeroPad(byte.toString(16)); hex += zeroPad(byte.toString(16))
} }
} }
if (dialect === 'postgres') { if (dialect === 'postgres') {
// bytea hex format http://www.postgresql.org/docs/current/static/datatype-binary.html // bytea hex format http://www.postgresql.org/docs/current/static/datatype-binary.html
return "E'\\\\x" + hex+ "'"; return "E'\\\\x" + hex+ "'"
} }
return "X'" + hex+ "'"; return "X'" + hex+ "'"
}; }
SqlString.objectToValues = function(object, timeZone) { SqlString.objectToValues = function(object, timeZone) {
var values = []; var values = []
for (var key in object) { for (var key in object) {
var value = object[key]; var value = object[key]
if(typeof value === 'function') { if(typeof value === 'function') {
continue; continue;
} }
values.push(this.escapeId(key) + ' = ' + SqlString.escape(value, true, timeZone)); values.push(this.escapeId(key) + ' = ' + SqlString.escape(value, true, timeZone))
} }
return values.join(', '); return values.join(', ')
}; }
function zeroPad(number) { function zeroPad(number) {
return (number < 10) ? '0' + number : number; return (number < 10) ? '0' + number : number
} }
function convertTimezone(tz) { function convertTimezone(tz) {
if (tz == "Z") return 0; if (tz == "Z") {
return 0
}
var m = tz.match(/([\+\-\s])(\d\d):?(\d\d)?/); var m = tz.match(/([\+\-\s])(\d\d):?(\d\d)?/)
if (m) { if (m) {
return (m[1] == '-' ? -1 : 1) * (parseInt(m[2], 10) + ((m[3] ? parseInt(m[3], 10) : 0) / 60)) * 60; return (m[1] == '-' ? -1 : 1) * (parseInt(m[2], 10) + ((m[3] ? parseInt(m[3], 10) : 0) / 60)) * 60
} }
return false; return false
} }
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
"devDependencies": { "devDependencies": {
"sqlite3": "~2.1.12", "sqlite3": "~2.1.12",
"mysql": "~2.0.0-alpha8", "mysql": "~2.0.0-alpha8",
"pg": "~2.3.1", "pg": "~2.6.0",
"watchr": "~2.4.3", "watchr": "~2.4.3",
"yuidocjs": "~0.3.36", "yuidocjs": "~0.3.36",
"chai": "~1.7.2", "chai": "~1.7.2",
......
...@@ -333,7 +333,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -333,7 +333,7 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
}) })
describe('create', function() { describe('create', function() {
it("casts empty arrays correctly for postgresql", function(done) { it("casts empty arrays correctly for postgresql insert", function(done) {
if (dialect !== "postgres" && dialect !== "postgresql-native") { if (dialect !== "postgres" && dialect !== "postgresql-native") {
expect('').to.equal('') expect('').to.equal('')
return done() return done()
...@@ -352,6 +352,30 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -352,6 +352,30 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
}) })
}) })
}) })
it("casts empty array correct for postgres update", function(done) {
if (dialect !== "postgres" && dialect !== "postgresql-native") {
expect('').to.equal('')
return done()
}
var User = this.sequelize.define('UserWithArray', {
myvals: { type: Sequelize.ARRAY(Sequelize.INTEGER) },
mystr: { type: Sequelize.ARRAY(Sequelize.STRING) }
})
User.sync({force: true}).success(function() {
User.create({myvals: [1,2,3,4], mystr: ["One", "Two", "Three", "Four"]}).on('success', function(user){
user.myvals = []
user.mystr = []
user.save().on('sql', function(sql) {
expect(sql.indexOf('ARRAY[]::INTEGER[]')).to.be.above(-1)
expect(sql.indexOf('ARRAY[]::VARCHAR[]')).to.be.above(-1)
done()
})
})
})
})
it("doesn't allow duplicated records with unique:true", function(done) { it("doesn't allow duplicated records with unique:true", function(done) {
var User = this.sequelize.define('UserWithUniqueUsername', { var User = this.sequelize.define('UserWithUniqueUsername', {
...@@ -1064,6 +1088,27 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -1064,6 +1088,27 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
}) })
}) })
it('should be able to find rows where attribute is in a list of values', function (done) {
this.User.findAll({
where: {
username: ['boo', 'boo2']
}
}).success(function(users){
expect(users).to.have.length(2);
done()
});
})
it('should not break when trying to find rows using an array of primary keys', function (done) {
this.User.findAll({
where: {
id: [1, 2, 3]
}
}).success(function(users){
done();
});
})
it('should be able to find a row using like', function(done) { it('should be able to find a row using like', function(done) {
this.User.findAll({ this.User.findAll({
where: { where: {
......
...@@ -254,6 +254,34 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() { ...@@ -254,6 +254,34 @@ describe(Support.getTestDialectTeaser("DaoValidator"), function() {
} }
describe('#update', function() { describe('#update', function() {
it('should allow us to update specific columns without tripping the validations', function(done) {
var User = this.sequelize.define('model', {
username: Sequelize.STRING,
email: {
type: Sequelize.STRING,
allowNull: false,
validate: {
isEmail: {
msg: 'You must enter a valid email address'
}
}
}
})
User.sync({ force: true }).success(function() {
User.create({username: 'bob', email: 'hello@world.com'}).success(function(user) {
User.update({username: 'toni'}, {id: user.id})
.error(function(err) { console.log(err) })
.success(function() {
User.find(1).success(function(user) {
expect(user.username).to.equal('toni')
done()
})
})
})
})
})
it('should be able to emit an error upon updating when a validation has failed from an instance', function(done) { it('should be able to emit an error upon updating when a validation has failed from an instance', function(done) {
var Model = this.sequelize.define('model', { var Model = this.sequelize.define('model', {
name: { name: {
......
...@@ -17,6 +17,7 @@ if (dialect.match(/^postgres/)) { ...@@ -17,6 +17,7 @@ if (dialect.match(/^postgres/)) {
this.User = this.sequelize.define('User', { this.User = this.sequelize.define('User', {
username: DataTypes.STRING, username: DataTypes.STRING,
email: {type: DataTypes.ARRAY(DataTypes.TEXT)}, email: {type: DataTypes.ARRAY(DataTypes.TEXT)},
numbers: {type: DataTypes.ARRAY(DataTypes.FLOAT)},
document: {type: DataTypes.HSTORE, defaultValue: '"default"=>"value"'} document: {type: DataTypes.HSTORE, defaultValue: '"default"=>"value"'}
}) })
this.User.sync({ force: true }).success(function() { this.User.sync({ force: true }).success(function() {
...@@ -361,6 +362,9 @@ if (dialect.match(/^postgres/)) { ...@@ -361,6 +362,9 @@ if (dialect.match(/^postgres/)) {
arguments: ['myTable', {data: new Buffer('Sequelize') }], arguments: ['myTable', {data: new Buffer('Sequelize') }],
expectation: "INSERT INTO \"myTable\" (\"data\") VALUES (E'\\\\x53657175656c697a65') RETURNING *;" expectation: "INSERT INTO \"myTable\" (\"data\") VALUES (E'\\\\x53657175656c697a65') RETURNING *;"
}, { }, {
arguments: ['myTable', {name: 'foo', numbers: new Uint8Array([1,2,3])}],
expectation: "INSERT INTO \"myTable\" (\"name\",\"numbers\") VALUES ('foo',ARRAY[1,2,3]) RETURNING *;"
}, {
arguments: ['myTable', {name: 'foo', foo: 1}], arguments: ['myTable', {name: 'foo', foo: 1}],
expectation: "INSERT INTO \"myTable\" (\"name\",\"foo\") VALUES ('foo',1) RETURNING *;" expectation: "INSERT INTO \"myTable\" (\"name\",\"foo\") VALUES ('foo',1) RETURNING *;"
}, { }, {
...@@ -403,6 +407,10 @@ if (dialect.match(/^postgres/)) { ...@@ -403,6 +407,10 @@ if (dialect.match(/^postgres/)) {
expectation: "INSERT INTO myTable (name,birthday) VALUES ('foo','2011-03-27 10:01:55.000 +00:00') RETURNING *;", expectation: "INSERT INTO myTable (name,birthday) VALUES ('foo','2011-03-27 10:01:55.000 +00:00') RETURNING *;",
context: {options: {quoteIdentifiers: false}} context: {options: {quoteIdentifiers: false}}
}, { }, {
arguments: ['myTable', {name: 'foo', numbers: new Uint8Array([1,2,3])}],
expectation: "INSERT INTO myTable (name,numbers) VALUES ('foo',ARRAY[1,2,3]) RETURNING *;",
context: {options: {quoteIdentifiers: false}}
}, {
arguments: ['myTable', {name: 'foo', foo: 1}], arguments: ['myTable', {name: 'foo', foo: 1}],
expectation: "INSERT INTO myTable (name,foo) VALUES ('foo',1) RETURNING *;", expectation: "INSERT INTO myTable (name,foo) VALUES ('foo',1) RETURNING *;",
context: {options: {quoteIdentifiers: false}} context: {options: {quoteIdentifiers: false}}
...@@ -536,6 +544,9 @@ if (dialect.match(/^postgres/)) { ...@@ -536,6 +544,9 @@ if (dialect.match(/^postgres/)) {
arguments: ['myTable', {bar: 2}, {name: 'foo'}], arguments: ['myTable', {bar: 2}, {name: 'foo'}],
expectation: "UPDATE \"myTable\" SET \"bar\"=2 WHERE \"name\"='foo' RETURNING *" expectation: "UPDATE \"myTable\" SET \"bar\"=2 WHERE \"name\"='foo' RETURNING *"
}, { }, {
arguments: ['myTable', {numbers: new Uint8Array([1,2,3])}, {name: 'foo'}],
expectation: "UPDATE \"myTable\" SET \"numbers\"=ARRAY[1,2,3] WHERE \"name\"='foo' RETURNING *"
}, {
arguments: ['myTable', {name: "foo';DROP TABLE myTable;"}, {name: 'foo'}], arguments: ['myTable', {name: "foo';DROP TABLE myTable;"}, {name: 'foo'}],
expectation: "UPDATE \"myTable\" SET \"name\"='foo'';DROP TABLE myTable;' WHERE \"name\"='foo' RETURNING *" expectation: "UPDATE \"myTable\" SET \"name\"='foo'';DROP TABLE myTable;' WHERE \"name\"='foo' RETURNING *"
}, { }, {
...@@ -575,6 +586,10 @@ if (dialect.match(/^postgres/)) { ...@@ -575,6 +586,10 @@ if (dialect.match(/^postgres/)) {
expectation: "UPDATE myTable SET bar=2 WHERE name='foo' RETURNING *", expectation: "UPDATE myTable SET bar=2 WHERE name='foo' RETURNING *",
context: {options: {quoteIdentifiers: false}} context: {options: {quoteIdentifiers: false}}
}, { }, {
arguments: ['myTable', {numbers: new Uint8Array([1,2,3])}, {name: 'foo'}],
expectation: "UPDATE myTable SET numbers=ARRAY[1,2,3] WHERE name='foo' RETURNING *",
context: {options: {quoteIdentifiers: false}}
}, {
arguments: ['myTable', {name: "foo';DROP TABLE myTable;"}, {name: 'foo'}], arguments: ['myTable', {name: "foo';DROP TABLE myTable;"}, {name: 'foo'}],
expectation: "UPDATE myTable SET name='foo'';DROP TABLE myTable;' WHERE name='foo' RETURNING *", expectation: "UPDATE myTable SET name='foo'';DROP TABLE myTable;' WHERE name='foo' RETURNING *",
context: {options: {quoteIdentifiers: false}} context: {options: {quoteIdentifiers: false}}
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!