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

Commit 0e5bbe88 by Mick Hansen

Merge branch 'master' of github.com:sequelize/sequelize

2 parents 713b42f2 ddf86f46
# Next
- [FEATURE] Throw an error if no where clause is given to `Model.destroy()`.
- [BUG] Fixed issue with `order: sequelize.literal('string')`
- [FEATURE] add `clone: true` support to `.get()`. Is needed when using `delete` on values from a `.get()` (`toJSON()`, `this.values`). (.get() is just a reference to the values for performance reasons when there's no custom getters or includes)
- [FEATURE] add `sequelize.escape(value)` convenience method
......@@ -11,7 +12,7 @@
#### Backwards compatability changes
- `instance.update()` using default fields will now automatically also save and validate values provided via `beforeUpdate` hooks
- Sequelize no longer supports case insensitive mysql enums
# 2.0.0-rc6
- [BUG] Fixed issue with including by association reference and where
......
......@@ -8,6 +8,8 @@ In order to use the CLI you need to install the respective package:
$ npm install --save sequelize-cli
```
As with any npm package, you can use the global flag (`-g`) to install the CLI globally. If you have installed the CLI without the global flag, use `node_modules/.bin/sequelize [command]` instead of `sequelize [command]`.
The CLI currently supports the following commands:
```bash
......
......@@ -589,8 +589,8 @@ Let's assume we have an empty database with a `User` model which has a `username
```js
User
.findOrCreate({ username: 'sdepold' }, { job: 'Technical Lead JavaScript' })
.then(function(user, created) {
.findOrCreate({where: {username: 'sdepold'}, defaults: {job: 'Technical Lead JavaScript'}})
.spread(function(user, created) {
console.log(user.values)
console.log(created)
 
......@@ -613,8 +613,8 @@ User
.create({ username: 'fnord', job: 'omnomnom' })
.then(function() {
User
.findOrCreate({ username: 'fnord' }, { job: 'something else' })
.then(function(user, created) {
.findOrCreate({where: {username: 'fnord'}, defaults: {job: 'something else'}})
.spread(function(user, created) {
console.log(user.values)
console.log(created)
 
......@@ -634,8 +634,6 @@ User
... the existing entry will not be changed. See the `job` of the second user, and the fact that created was false.
Notice that the success callback has two arguments. When using [promises][5] you should call `spread` [(API ref)][6] instead of `then`, since `then` will only recieve the first argument (the DAO), while `spread` will recieve both the DAO, and the `created` boolean.
### findAndCountAll - Search for multiple elements in the database, returns both data and total count
This is a convienience method that combines`findAll()`and`count()`(see below), this is useful when dealing with queries related to pagination where you want to retrieve data with a`limit`and`offset`but also need to know the total number of records that match the query.
......@@ -835,7 +833,7 @@ Project.count({ where: ["id > ?", 25] }).then(function(c) {
### max - Get the greatest value of a specific attribute within a specific table
And here is a method for getting the max value of an attribute:
And here is a method for getting the max value of an attribute:f
```js
/*
......
......@@ -264,7 +264,7 @@ module.exports = (function() {
var table = this.quoteTable(tableName);
if (options.truncate === true) {
// Truncate does not allow LIMIT and WHERE
return 'TRUNCATE ' + table;
return 'TRUNCATE TABLE ' + table;
}
where = this.getWhereConditions(where);
......
......@@ -149,7 +149,7 @@ module.exports = (function() {
} else if (this.isBulkUpdateQuery()) {
result = data.length;
} else if (this.isBulkDeleteQuery()){
result = data[0].AFFECTEDROWS;
result = data[0] && data[0].AFFECTEDROWS;
} else if (this.isVersionQuery()) {
result = data[0].version;
}
......
......@@ -518,27 +518,6 @@ module.exports = (function() {
}
});
for (var attrName in this.Model.rawAttributes) {
if (self.Model.rawAttributes.hasOwnProperty(attrName)) {
var definition = this.Model.rawAttributes[attrName]
, isEnum = definition.type.toString() === DataTypes.ENUM.toString()
, isMySQL = ['mysql', 'mariadb'].indexOf(this.Model.modelManager.sequelize.options.dialect) !== -1
, ciCollation = !!this.Model.options.collate && this.Model.options.collate.match(/_ci$/i)
, valueOutOfScope;
// Unfortunately for MySQL CI collation we need to map/lowercase values again
if (isEnum && isMySQL && ciCollation && (attrName in values) && values[attrName]) {
var scopeIndex = (definition.values || []).map(function(d) { return d.toLowerCase(); }).indexOf(values[attrName].toLowerCase());
valueOutOfScope = scopeIndex === -1;
// We'll return what the actual case will be, since a simple SELECT query would do the same...
if (!valueOutOfScope) {
values[attrName] = definition.values[scopeIndex];
}
}
}
}
if (updatedAtAttr && !options.silent) {
values[updatedAtAttr] = self.Model.__getTimestamp(updatedAtAttr);
}
......@@ -559,7 +538,7 @@ module.exports = (function() {
var identifier = self.primaryKeyValues;
if (identifier) {
for (attrName in identifier) {
for (var attrName in identifier) {
// Field name mapping
var rawAttribute = self.Model.rawAttributes[attrName];
if (rawAttribute.field && rawAttribute.field !== rawAttribute.fieldName) {
......
......@@ -1412,6 +1412,13 @@ module.exports = (function() {
* @return {Promise<undefined>}
*/
Model.prototype.destroy = function(options) {
var self = this
, instances;
if (!options || !(options.where || options.truncate)) {
throw new Error('Missing where or truncate attribute in the options parameter passed to destroy.');
}
options = Utils._.extend({
hooks: true,
individualHooks: false,
......@@ -1421,8 +1428,6 @@ module.exports = (function() {
options.type = QueryTypes.BULKDELETE;
var self = this
, instances;
mapFieldNames.call(this, options, this);
......
......@@ -78,58 +78,6 @@ if (Support.dialectIsMySQL()) {
});
});
describe('validations', function() {
describe('enums', function() {
it('enum data type should be case insensitive if my collation allows it', function(done) {
var User = this.sequelize.define('User' + config.rand(), {
mood: {
type: DataTypes.ENUM,
values: ['HAPPY', 'sad', 'WhatEver']
}
}, {
collate: 'utf8_general_ci'
});
User.sync({ force: true }).success(function() {
User.create({mood: 'happy'}).success(function(user) {
expect(user).to.exist;
expect(user.mood).to.equal('HAPPY');
var u = User.build({mood: 'SAD'});
u.save().success(function(_user) {
expect(_user).to.exist;
expect(_user.mood).to.equal('sad');
done();
});
});
});
});
it('enum data type should be case sensitive if my collation enforces it', function(done) {
var User = this.sequelize.define('User' + config.rand(), {
mood: {
type: DataTypes.ENUM,
values: ['HAPPY', 'sad', 'WhatEver']
}
}, {
collate: 'latin1_bin'
});
User.sync({ force: true }).success(function() {
User.create({mood: 'happy'}).error(function(err) {
expect(err).to.be.instanceOf(Error);
expect(err.get('mood')[0].message).to.equal('Value "happy" for ENUM mood is out of allowed scope. Allowed values: HAPPY, sad, WhatEver');
var u = User.build({mood: 'SAD'});
u.save().error(function(err) {
expect(err).to.be.instanceOf(Error);
expect(err.get('mood')[0].message).to.equal('Value "SAD" for ENUM mood is out of allowed scope. Allowed values: HAPPY, sad, WhatEver');
done();
});
});
});
});
});
});
describe('primaryKeys', function() {
it('determines the correct primaryKeys', function(done) {
var User = this.sequelize.define('User' + config.rand(), {
......
......@@ -857,6 +857,19 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
describe('update', function() {
it('throws an error if no where clause is given', function() {
var User = this.sequelize.define('User', { username: DataTypes.STRING });
return this.sequelize.sync({ force: true }).then(function() {
return User.update();
}).then(function() {
throw new Error('Update should throw an error if no where clause is given.');
}, function(err) {
expect(err).to.be.an.instanceof(Error);
expect(err.message).to.equal('Missing where attribute in the options parameter passed to update.');
});
});
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
......@@ -1081,6 +1094,54 @@ describe(Support.getTestDialectTeaser('Model'), function() {
});
describe('destroy', function() {
it('truncate should clear the table', function() {
var User = this.sequelize.define('User', { username: DataTypes.STRING }),
data = [
{ username: 'user1' },
{ username: 'user2' }
];
return this.sequelize.sync({ force: true }).then(function() {
return User.bulkCreate(data);
}).then(function() {
return User.destroy({ truncate: true });
}).then(function() {
return expect(User.findAll()).to.eventually.have.length(0);
});
});
it('throws an error if no where clause is given', function() {
var User = this.sequelize.define('User', { username: DataTypes.STRING });
return this.sequelize.sync({ force: true }).then(function() {
return User.destroy();
}).then(function() {
throw new Error('Destroy should throw an error if no where clause is given.');
}, function(err) {
expect(err).to.be.an.instanceof(Error);
expect(err.message).to.equal('Missing where or truncate attribute in the options parameter passed to destroy.');
});
});
it('deletes all instances when given an empty where object', function() {
var User = this.sequelize.define('User', { username: DataTypes.STRING }),
data = [
{ username: 'user1' },
{ username: 'user2' }
];
return this.sequelize.sync({ force: true }).then(function() {
return User.bulkCreate(data);
}).then(function() {
return User.destroy({ where: {} });
}).then(function(affectedRows) {
expect(affectedRows).to.equal(2);
return User.findAll();
}).then(function(users) {
expect(users).to.have.length(0);
});
});
if (current.dialect.supports.transactions) {
it('supports transactions', function(done) {
Support.prepareTransactionTest(this.sequelize, function(sequelize) {
......@@ -1089,7 +1150,10 @@ describe(Support.getTestDialectTeaser('Model'), function() {
User.sync({ force: true }).success(function() {
User.create({ username: 'foo' }).success(function() {
sequelize.transaction().then(function(t) {
User.destroy({transaction: t }).success(function() {
User.destroy({
where: {},
transaction: t
}).success(function() {
User.count().success(function(count1) {
User.count({ transaction: t }).success(function(count2) {
expect(count1).to.equal(1);
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!