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

Commit 23f0460a by Jan Aagaard Meier

Fix use of sequelize.fn etc in date and boolean fields. Closes #1471

1 parent bb40f280
...@@ -437,7 +437,7 @@ module.exports = (function() { ...@@ -437,7 +437,7 @@ module.exports = (function() {
, len = obj.length , len = obj.length
for (var i = 0; i < len - 1; i++) { for (var i = 0; i < len - 1; i++) {
var item = obj[i] var item = obj[i]
if (item._modelAttribute || Utils._.isString(item) || item instanceof Utils.fn || item instanceof Utils.col || item instanceof Utils.literal || item instanceof Utils.cast || 'raw' in item) { if (item._modelAttribute || Utils._.isString(item) || item._isSequelizeMethod || 'raw' in item) {
break break
} }
...@@ -476,7 +476,7 @@ module.exports = (function() { ...@@ -476,7 +476,7 @@ module.exports = (function() {
return sql return sql
} else if (obj._modelAttribute) { } else if (obj._modelAttribute) {
return this.quoteTable(obj.Model.name)+'.'+obj.fieldName return this.quoteTable(obj.Model.name)+'.'+obj.fieldName
} else if (obj instanceof Utils.fn || obj instanceof Utils.col || obj instanceof Utils.literal || obj instanceof Utils.cast) { } else if (obj._isSequelizeMethod) {
return obj.toString(this) return obj.toString(this)
} else if (Utils._.isObject(obj) && 'raw' in obj) { } else if (Utils._.isObject(obj) && 'raw' in obj) {
return obj.raw return obj.raw
...@@ -551,7 +551,7 @@ module.exports = (function() { ...@@ -551,7 +551,7 @@ module.exports = (function() {
Escape a value (e.g. a string, number or date) Escape a value (e.g. a string, number or date)
*/ */
escape: function(value, field) { escape: function(value, field) {
if (value instanceof Utils.fn || value instanceof Utils.col || value instanceof Utils.literal || value instanceof Utils.cast) { if (value && value._isSequelizeMethod) {
return value.toString(this) return value.toString(this)
} else { } else {
return SqlString.escape(value, false, null, this.dialect, field) return SqlString.escape(value, false, null, this.dialect, field)
......
...@@ -807,7 +807,7 @@ module.exports = (function() { ...@@ -807,7 +807,7 @@ module.exports = (function() {
Escape a value (e.g. a string, number or date) Escape a value (e.g. a string, number or date)
*/ */
escape: function(value, field) { escape: function(value, field) {
if (value instanceof Utils.fn || value instanceof Utils.col || value instanceof Utils.literal || value instanceof Utils.cast) { if (value && value._isSequelizeMethod) {
return value.toString(this) return value.toString(this)
} else { } else {
if (field && field.type && field.type.toString() === DataTypes.HSTORE.type && Utils._.isObject(value)) { if (field && field.type && field.type.toString() === DataTypes.HSTORE.type && Utils._.isObject(value)) {
......
...@@ -295,13 +295,13 @@ module.exports = (function() { ...@@ -295,13 +295,13 @@ module.exports = (function() {
} }
// Convert date fields to real date objects // Convert date fields to real date objects
if (this.Model._hasDateAttributes && this.Model._isDateAttribute(key) && value !== null && !(value instanceof Date)) { if (this.Model._hasDateAttributes && this.Model._isDateAttribute(key) && value !== null && !(value instanceof Date) && !value._isSequelizeMethod) {
value = new Date(value) value = new Date(value)
} }
} }
// Convert boolean-ish values to booleans // Convert boolean-ish values to booleans
if (this.Model._hasBooleanAttributes && this.Model._isBooleanAttribute(key) && value !== null && value !== undefined) { if (this.Model._hasBooleanAttributes && this.Model._isBooleanAttribute(key) && value !== null && value !== undefined && !value._isSequelizeMethod) {
value = !!value value = !!value
} }
......
...@@ -1921,14 +1921,12 @@ module.exports = (function() { ...@@ -1921,14 +1921,12 @@ module.exports = (function() {
var optClone = function (options) { var optClone = function (options) {
return Utils._.cloneDeep(options, function (elem) { return Utils._.cloneDeep(options, function (elem) {
// The InstanceFactories used for include are pass by ref, so don't clone them. // The InstanceFactories used for include are pass by ref, so don't clone them.
if (elem instanceof Model || if (elem &&
elem instanceof Utils.col || (
elem instanceof Utils.literal || elem._isSequelizeMethod ||
elem instanceof Utils.cast || elem instanceof Model ||
elem instanceof Utils.fn ||
elem instanceof Utils.and ||
elem instanceof Utils.or ||
elem instanceof Transaction elem instanceof Transaction
)
) { ) {
return elem return elem
} }
......
...@@ -557,6 +557,8 @@ var Utils = module.exports = { ...@@ -557,6 +557,8 @@ var Utils = module.exports = {
Utils.condition = Utils.where Utils.condition = Utils.where
Utils.and.prototype._isSequelizeMethod =
Utils.or.prototype._isSequelizeMethod =
Utils.where.prototype._isSequelizeMethod = Utils.where.prototype._isSequelizeMethod =
Utils.literal.prototype._isSequelizeMethod = Utils.literal.prototype._isSequelizeMethod =
Utils.cast.prototype._isSequelizeMethod = Utils.cast.prototype._isSequelizeMethod =
......
...@@ -3,6 +3,7 @@ var chai = require('chai') ...@@ -3,6 +3,7 @@ var chai = require('chai')
, Sequelize = require('../../index') , Sequelize = require('../../index')
, expect = chai.expect , expect = chai.expect
, Support = require(__dirname + '/../support') , Support = require(__dirname + '/../support')
, dialect = Support.getTestDialect()
, DataTypes = require(__dirname + "/../../lib/data-types") , DataTypes = require(__dirname + "/../../lib/data-types")
, datetime = require('chai-datetime') , datetime = require('chai-datetime')
...@@ -103,6 +104,41 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -103,6 +104,41 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
expect(user.dataValues.email).not.to.be.ok expect(user.dataValues.email).not.to.be.ok
}) })
it('allows use of sequelize.fn and sequelize.col in date and bool fields', function () {
var self = this
, User = this.sequelize.define('User', {
d: DataTypes.DATE,
b: DataTypes.BOOLEAN,
always_false: {
type: DataTypes.BOOLEAN,
defaultValue: false
}
}, {timestamps: false})
return User.sync({ force: true }).then(function () {
return User.create({}).then(function (user) {
// Create the user first to set the proper default values. PG does not support column references in insert,
// so we must create a record with the right value for always_false, then reference it in an update
var now = dialect === 'sqlite' ? self.sequelize.fn('', self.sequelize.fn('date', 'now')) : self.sequelize.fn('NOW')
user.set({
d: now,
b: self.sequelize.col('always_false')
})
expect(user.get('d')).to.be.instanceof(self.sequelize.Utils.fn)
expect(user.get('b')).to.be.instanceof(self.sequelize.Utils.col)
return user.save().then(function () {
return user.reload().then(function () {
expect(user.d).to.equalDate(new Date())
expect(user.b).to.equal(false)
})
})
})
})
})
describe('includes', function () { describe('includes', function () {
it('should support basic includes', function () { it('should support basic includes', function () {
var Product = this.sequelize.define('Product', { var Product = this.sequelize.define('Product', {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!