sequelize/sequelize — pull request #1024 by durango (2013-10-30 02:19:02+00:00)
Title: New way to declare indices

There's now a new way to declare indices within DAOFactories.. as per the example...

```js
it('allows multiple column unique keys to be defined', function(done) {
var User = this.sequelize.define('UserWithUniqueUsername', {
username: { type: Sequelize.STRING, unique: 'user_and_email' },
email: { type: Sequelize.STRING, unique: 'user_and_email' },
aCol: { type: Sequelize.STRING, unique: 'a_and_b' },
bCol: { type: Sequelize.STRING, unique: 'a_and_b' }
})

User.sync({ force: true }).on('sql', function(sql) {
expect(sql).to.match(/UNIQUE\s*(uniq_UserWithUniqueUsernames_username_email)?\s*\([`"]?username[`"]?, [`"]?email[`"]?\)/)
expect(sql).to.match(/UNIQUE\s*(uniq_UserWithUniqueUsernames_aCol_bCol)?\s*\([`"]?aCol[`"]?, [`"]?bCol[`"]?\)/)
done()
})
})

it('allows us to customize the error message for unique constraint', function(done) {
var User = this.sequelize.define('UserWithUniqueUsername', {
username: { type: Sequelize.STRING, unique: { name: 'user_and_email', msg: 'User and email must be unique' }},
email: { type: Sequelize.STRING, unique: 'user_and_email' },
aCol: { type: Sequelize.STRING, unique: 'a_and_b' },
bCol: { type: Sequelize.STRING, unique: 'a_and_b' }
})

User.sync({ force: true }).success(function() {
User.create({username: 'tobi', email: 'tobi@tobi.me'}).success(function() {
User.create({username: 'tobi', email: 'tobi@tobi.me'}).error(function(err) {
expect(err).to.equal('User and email must be unique')
done()
})
})
})
})

it("doesn't allow duplicated records with unique:true", function(done) {
var User = this.sequelize.define('UserWithUniqueUsername', {
username: { type: Sequelize.STRING, unique: true }
})

User.sync({ force: true }).success(function() {
User.create({ username:'foo' }).success(function() {
User.create({ username: 'foo' }).error(function(err) {
expect(err).to.exist

if (dialect === "sqlite") {
expect(err.message).to.match(/.*SQLITE_CONSTRAINT.*/)
}
else if (Support.dialectIsMySQL()) {
expect(err.message).to.match(/.*Duplicate\ entry.*/)
} else {
expect(err.message).to.match(/.*duplicate\ key\ value.*/)
}

done()
})
})
})
})

it("raises an error if created object breaks definition contraints", function(done) {
var UserNull = this.sequelize.define('UserWithNonNullSmth', {
username: { type: Sequelize.STRING, unique: true },
smth: { type: Sequelize.STRING, allowNull: false }
})

this.sequelize.options.omitNull = false

UserNull.sync({ force: true }).success(function() {
UserNull.create({ username: 'foo2', smth: null }).error(function(err) {
expect(err).to.exist

if (Support.dialectIsMySQL()) {
// We need to allow two different errors for MySQL, see:
// http://dev.mysql.com/doc/refman/5.0/en/server-sql-mode.html#sqlmode_strict_trans_tables
expect(err.message).to.match(/(Column 'smth' cannot be null|Field 'smth' doesn't have a default value)/)
}
else if (dialect === "sqlite") {
expect(err.message).to.match(/.*SQLITE_CONSTRAINT.*/)
} else {
expect(err.message).to.match(/.*column "smth" violates not-null.*/)
}

UserNull.create({ username: 'foo', smth: 'foo' }).success(function() {
UserNull.create({ username: 'foo', smth: 'bar' }).error(function(err) {
expect(err).to.exist

if (dialect === "sqlite") {
expect(err.message).to.match(/.*SQLITE_CONSTRAINT.*/)
}
else if (Support.dialectIsMySQL()) {
expect(err.message).to.match(/Duplicate entry 'foo' for key 'username'/)
} else {
expect(err.message).to.match(/.*duplicate key value violates unique constraint.*/)
}

done()
})
})
})
})
})
```

Closes https://github.com/sequelize/sequelize/issues/653
Closes https://github.com/sequelize/sequelize/issues/32