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

Commit c2d05d09 by Mick Hansen

[merge]

2 parents 449625f4 7a7f3ddf
...@@ -229,27 +229,31 @@ if (program.migrate || program.undo) { ...@@ -229,27 +229,31 @@ if (program.migrate || program.undo) {
migratorOptions = _.merge(migratorOptions, { filesFilter: /\.js$|\.coffee$/ }) migratorOptions = _.merge(migratorOptions, { filesFilter: /\.js$|\.coffee$/ })
} }
var migrator = sequelize.getMigrator(migratorOptions) sequelize.authenticate().success(function () {
var migrator = sequelize.getMigrator(migratorOptions)
if (program.undo) {
migrator.findOrCreateSequelizeMetaDAO().success(function(Meta) { if (program.undo) {
Meta.find({ order: 'id DESC' }).success(function(meta) { migrator.findOrCreateSequelizeMetaDAO().success(function(Meta) {
if (meta) { Meta.find({ order: 'id DESC' }).success(function(meta) {
migrator = sequelize.getMigrator(_.extend(migratorOptions, meta.values), true) if (meta) {
migrator.migrate({ method: 'down' }).success(function() { migrator = sequelize.getMigrator(_.extend(migratorOptions, meta.values), true)
migrator.migrate({ method: 'down' }).success(function() {
process.exit(0)
})
} else {
console.log("There are no pending migrations.")
process.exit(0) process.exit(0)
}) }
} else { })
console.log("There are no pending migrations.")
process.exit(0)
}
}) })
}) } else {
} else { sequelize.migrate().success(function() {
sequelize.migrate().success(function() { process.exit(0)
process.exit(0) })
}) }
} }).error(function (err) {
console.error("Unable to connect to database: "+err)
})
} else { } else {
console.log('Cannot find "' + configuration.configFile + '". Have you run "sequelize --init"?') console.log('Cannot find "' + configuration.configFile + '". Have you run "sequelize --init"?')
process.exit(1) process.exit(1)
......
Notice: All 1.7.x changes are present in 2.0.x aswell Notice: All 1.7.x changes are present in 2.0.x aswell
# v1.7.0-rc7 (next)
- [BUG] ORDER BY statements when using includes should now be places in the appropriate sub/main query more intelligently.
- [BUG] using include.attributes with primary key attributes specified should no longer result in multiple primary key attributes being selected [#1410](https://github.com/sequelize/sequelize/pull/1410)
- [DEPENDENCIES] all dependencies, including Validator have been updated to the latest versions.
#### Backwards compatability changes
- .set() will no longer set values that are not a dynamic setter or defined in the model. This only breaks BC since .set() was introduced but restores original .updateAttributes functionality where it was possible to 'trust' user input.
# v1.7.0-rc6 # v1.7.0-rc6
- [BUG] Encode binary strings as bytea in postgres, and fix a case where using a binary as key in an association would produce an error [1364](https://github.com/sequelize/sequelize/pull/1364). Thanks to @SohumB - [BUG] Encode binary strings as bytea in postgres, and fix a case where using a binary as key in an association would produce an error [1364](https://github.com/sequelize/sequelize/pull/1364). Thanks to @SohumB
......
...@@ -613,7 +613,7 @@ module.exports = (function() { ...@@ -613,7 +613,7 @@ module.exports = (function() {
DAOFactory.prototype.findAndCountAll = function(findOptions, queryOptions) { DAOFactory.prototype.findAndCountAll = function(findOptions, queryOptions) {
var self = this var self = this
// no limit, offset, order, attributes for the options given to count() // no limit, offset, order, attributes for the options given to count()
, countOptions = Utils._.omit(findOptions || {}, ['offset', 'limit', 'order', 'attributes']) , countOptions = Utils._.omit(findOptions ? Utils._.merge({}, findOptions) : {}, ['offset', 'limit', 'order', 'attributes'])
return new Utils.CustomEventEmitter(function (emitter) { return new Utils.CustomEventEmitter(function (emitter) {
var emit = { var emit = {
......
...@@ -157,6 +157,11 @@ module.exports = (function() { ...@@ -157,6 +157,11 @@ module.exports = (function() {
this._setInclude(key, value, options) this._setInclude(key, value, options)
return return
} else { } else {
// If not raw, and attribute is not in model definition
if (!options.raw && Object.keys(this.Model.attributes).indexOf(key) === -1) {
return;
}
// If attempting to set primary key and primary key is already defined, return // If attempting to set primary key and primary key is already defined, return
if (this.Model._hasPrimaryKeys && originalValue && this.Model._isPrimaryKey(key)) { if (this.Model._hasPrimaryKeys && originalValue && this.Model._isPrimaryKey(key)) {
return return
...@@ -262,7 +267,7 @@ module.exports = (function() { ...@@ -262,7 +267,7 @@ module.exports = (function() {
options = Utils._.extend({}, options, fieldsOrOptions) options = Utils._.extend({}, options, fieldsOrOptions)
if (!options.fields) { if (!options.fields) {
options.fields = this.attributes options.fields = Object.keys(this.Model.attributes)
} }
if (options.returning === undefined) { if (options.returning === undefined) {
......
...@@ -536,7 +536,15 @@ module.exports = (function() { ...@@ -536,7 +536,15 @@ module.exports = (function() {
}.bind(this)).join(", ") }.bind(this)).join(", ")
if (subQuery && mainAttributes) { if (subQuery && mainAttributes) {
mainAttributes = mainAttributes.concat(Model.primaryKeyAttributes) if (Model.hasPrimaryKeys) {
Model.primaryKeyAttributes.forEach(function(keyAtt){
if(mainAttributes.indexOf(keyAtt) == -1){
mainAttributes.push(keyAtt)
}
})
} else {
mainAttributes.push("id")
}
} }
// Escape attributes // Escape attributes
...@@ -767,12 +775,25 @@ module.exports = (function() { ...@@ -767,12 +775,25 @@ module.exports = (function() {
// Add ORDER to sub or main query // Add ORDER to sub or main query
if (options.order) { if (options.order) {
options.order = Array.isArray(options.order) ? options.order.map(function (t) { return this.quote(t, Model) }.bind(this)).join(', ') : options.order var mainQueryOrder = [];
var subQueryOrder = [];
if (subQuery) { if (Array.isArray(options.order)) {
subQueryItems.push(" ORDER BY " + options.order) options.order.forEach(function (t) {
if (subQuery && !(t[0] instanceof daoFactory)) {
subQueryOrder.push(this.quote(t, Model))
}
mainQueryOrder.push(this.quote(t, Model))
}.bind(this))
} else { } else {
mainQueryItems.push(" ORDER BY " + options.order) mainQueryOrder.push(options.order)
}
if (mainQueryOrder.length) {
mainQueryItems.push(" ORDER BY " + mainQueryOrder.join(', '))
}
if (subQueryOrder.length) {
subQueryItems.push(" ORDER BY " + subQueryOrder.join(', '))
} }
} }
...@@ -793,6 +814,7 @@ module.exports = (function() { ...@@ -793,6 +814,7 @@ module.exports = (function() {
query += subQueryItems.join('') query += subQueryItems.join('')
query += ") AS "+options.table query += ") AS "+options.table
query += mainJoinQueries.join('') query += mainJoinQueries.join('')
query += mainQueryItems.join('')
} else { } else {
query = mainQueryItems.join('') query = mainQueryItems.join('')
} }
...@@ -908,7 +930,7 @@ module.exports = (function() { ...@@ -908,7 +930,7 @@ module.exports = (function() {
if (treatAsAnd) { if (treatAsAnd) {
return treatAsAnd return treatAsAnd
} else { } else {
return !(arg instanceof Date) && ((arg instanceof Utils.and) || (arg instanceof Utils.or) || Utils.isHash(arg) || Array.isArray(arg)) return !(arg instanceof Date) && ((arg instanceof Utils.and) || (arg instanceof Utils.or) || Utils.isHash(arg))
} }
}, false) }, false)
......
...@@ -60,8 +60,8 @@ module.exports = (function() { ...@@ -60,8 +60,8 @@ module.exports = (function() {
urlParts = url.parse(arguments[0]) urlParts = url.parse(arguments[0])
// SQLite don't have DB in connection url // SQLite don't have DB in connection url
if (urlParts.path) { if (urlParts.pathname) {
database = urlParts.path.replace(/^\//, '') database = urlParts.pathname.replace(/^\//, '')
} }
dialect = urlParts.protocol dialect = urlParts.protocol
...@@ -140,6 +140,8 @@ module.exports = (function() { ...@@ -140,6 +140,8 @@ module.exports = (function() {
Sequelize.DAOValidator = DAOValidator Sequelize.DAOValidator = DAOValidator
Sequelize.DAOFactory = Sequelize.Model = DAOFactory
for (var dataType in DataTypes) { for (var dataType in DataTypes) {
Sequelize[dataType] = DataTypes[dataType] Sequelize[dataType] = DataTypes[dataType]
} }
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
"lingo": "~0.0.5", "lingo": "~0.0.5",
"validator": "~3.2.0", "validator": "~3.2.0",
"moment": "~2.5.0", "moment": "~2.5.0",
"dottie": "0.0.9-0", "dottie": "0.1.0",
"toposort-class": "~0.3.0", "toposort-class": "~0.3.0",
"generic-pool": "2.0.4", "generic-pool": "2.0.4",
"sql": "~0.35.0", "sql": "~0.35.0",
......
...@@ -119,6 +119,17 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -119,6 +119,17 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
}) })
}) })
if (dialect !== 'postgres') {
it('still allows simple arrays lookups', function (done) {
this.User.find({
where: ["id IN (?) OR id IN (?)", [1, 2], [3, 4]]
}).on('sql', function(sql) {
expect(sql).to.contain("id IN (1, 2) OR id IN (3, 4)")
done()
})
})
}
;(['find', 'findAll']).forEach(function(finderMethod) { ;(['find', 'findAll']).forEach(function(finderMethod) {
it('correctly handles complex combinations', function(done) { it('correctly handles complex combinations', function(done) {
this.User[finderMethod]({ this.User[finderMethod]({
......
...@@ -1029,6 +1029,28 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () { ...@@ -1029,6 +1029,28 @@ describe(Support.getTestDialectTeaser("DAOFactory"), function () {
}, function() {done()}) }, function() {done()})
}) })
it('sorts by 1st degree association while using limit', function(done) {
var self = this
async.forEach([ [ 'ASC', 'England', 'Energy' ], [ 'DESC', 'Korea', 'Tech' ] ], function(params, callback) {
self.Country.findAll({
include: [ self.Industry ],
order: [
[ self.Industry, 'name', params[0] ]
],
limit: 3
}).done(function(err, countries) {
expect(err).not.to.be.ok
expect(countries).to.exist
expect(countries[0]).to.exist
expect(countries[0].name).to.equal(params[1])
expect(countries[0].industries).to.exist
expect(countries[0].industries[0]).to.exist
expect(countries[0].industries[0].name).to.equal(params[2])
callback()
})
}, function() {done()})
})
it('sorts by through table attribute', function(done) { it('sorts by through table attribute', function(done) {
var self = this var self = this
async.forEach([ [ 'ASC', 'England', 'Energy' ], [ 'DESC', 'France', 'Media' ] ], function(params, callback) { async.forEach([ [ 'ASC', 'England', 'Energy' ], [ 'DESC', 'France', 'Media' ] ], function(params, callback) {
......
...@@ -62,6 +62,34 @@ describe(Support.getTestDialectTeaser("DAO"), function () { ...@@ -62,6 +62,34 @@ describe(Support.getTestDialectTeaser("DAO"), function () {
expect(user.get('updatedAt')).not.to.be.ok expect(user.get('updatedAt')).not.to.be.ok
}) })
it('doesn\'t set value if not a dynamic setter or a model attribute', function() {
var User = this.sequelize.define('User', {
name: {type: DataTypes.STRING},
email_hidden: {type: DataTypes.STRING}
}, {
setterMethods: {
email_secret: function (value) {
this.set('email_hidden', value)
}
}
})
var user = User.build()
user.set({
name: 'antonio banderaz',
email: 'antonio@banderaz.com',
email_secret: 'foo@bar.com'
})
user.set('email', 'antonio@banderaz.com')
expect(user.get('name')).to.equal('antonio banderaz')
expect(user.get('email_hidden')).to.equal('foo@bar.com')
expect(user.get('email')).not.to.be.ok
expect(user.dataValues.email).not.to.be.ok
})
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', {
......
...@@ -22,6 +22,42 @@ var sortById = function(a, b) { ...@@ -22,6 +22,42 @@ var sortById = function(a, b) {
describe(Support.getTestDialectTeaser("Include"), function () { describe(Support.getTestDialectTeaser("Include"), function () {
describe('find', function () { describe('find', function () {
it('should support a empty belongsTo include', function (done) {
var Company = this.sequelize.define('Company', {})
, User = this.sequelize.define('User', {})
User.belongsTo(Company, {as: 'Employer'})
this.sequelize.sync({force: true}).done(function () {
User.create().then(function () {
User.find({
include: [{model: Company, as: 'Employer'}]
}).done(function (err, user) {
expect(err).not.to.be.ok
expect(user).to.be.ok
done()
})
}, done)
})
})
it('should support a empty hasOne include', function (done) {
var Company = this.sequelize.define('Company', {})
, Person = this.sequelize.define('Person', {})
Company.hasOne(Person, {as: 'CEO'})
this.sequelize.sync({force: true}).done(function () {
Company.create().then(function () {
Company.find({
include: [{model: Person, as: 'CEO'}]
}).done(function (err, company) {
expect(err).not.to.be.ok
expect(company).to.be.ok
done()
})
}, done)
})
})
it('should support a simple nested belongsTo -> belongsTo include', function (done) { it('should support a simple nested belongsTo -> belongsTo include', function (done) {
var Task = this.sequelize.define('Task', {}) var Task = this.sequelize.define('Task', {})
, User = this.sequelize.define('User', {}) , User = this.sequelize.define('User', {})
......
...@@ -48,6 +48,9 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () { ...@@ -48,6 +48,9 @@ describe(Support.getTestDialectTeaser("Sequelize"), function () {
it('should work with connection strings (2)', function () { it('should work with connection strings (2)', function () {
var sequelize = new Sequelize('sqlite://test.sqlite/') var sequelize = new Sequelize('sqlite://test.sqlite/')
}) })
it('should work with connection strings (3)', function () {
var sequelize = new Sequelize('sqlite://test.sqlite/lol?reconnect=true')
})
} }
}) })
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!