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

Commit 1149f3ea by Daniel Durante

Merge pull request #980 from sequelize/chore/remove_FOREIGN_KEY_CHECKS

Removed disabling of foreign keys while dropping tables for pg and mysql.
2 parents 858a3874 204e4cfa
...@@ -261,27 +261,13 @@ module.exports = (function() { ...@@ -261,27 +261,13 @@ module.exports = (function() {
}, },
/* /*
Globally enable foreign key constraints
*/
enableForeignKeyConstraintsQuery: function() {
throwMethodUndefined('enableForeignKeyConstraintsQuery')
},
/*
Globally disable foreign key constraints
*/
disableForeignKeyConstraintsQuery: function() {
throwMethodUndefined('disableForeignKeyConstraintsQuery')
},
/*
Quote an object based on its type. This is a more general version of quoteIdentifiers Quote an object based on its type. This is a more general version of quoteIdentifiers
Strings: should proxy to quoteIdentifiers Strings: should proxy to quoteIdentifiers
Arrays: First argument should be qouted, second argument should be append without quoting Arrays: First argument should be qouted, second argument should be append without quoting
Objects: Objects:
* If raw is set, that value should be returned verbatim, without quoting * If raw is set, that value should be returned verbatim, without quoting
* If fn is set, the string should start with the value of fn, starting paren, followed by * If fn is set, the string should start with the value of fn, starting paren, followed by
the values of cols (which is assumed to be an array), quoted and joined with ', ', the values of cols (which is assumed to be an array), quoted and joined with ', ',
unless they are themselves objects unless they are themselves objects
* If direction is set, should be prepended * If direction is set, should be prepended
...@@ -366,10 +352,31 @@ module.exports = (function() { ...@@ -366,10 +352,31 @@ module.exports = (function() {
if (value instanceof Utils.fn || value instanceof Utils.col) { if (value instanceof Utils.fn || value instanceof Utils.col) {
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)
} }
} },
/**
* Generates an SQL query that returns all foreign keys of a table.
*
* @param {String} tableName The name of the table.
* @param {String} schemaName The name of the schema.
* @return {String} The generated sql query.
*/
getForeignKeysQuery: function(tableName, schemaName) {
throwMethodUndefined('getForeignKeysQuery')
},
/**
* Generates an SQL query that removes a foreign key from a table.
*
* @param {String} tableName The name of the table.
* @param {String} foreignKey The name of the foreign key constraint.
* @return {String} The generated sql query.
*/
dropForeignKeyQuery: function(tableName, foreignKey) {
throwMethodUndefined('dropForeignKeyQuery')
}
} }
var throwMethodUndefined = function(methodName) { var throwMethodUndefined = function(methodName) {
......
...@@ -404,10 +404,10 @@ module.exports = (function() { ...@@ -404,10 +404,10 @@ module.exports = (function() {
}, },
showIndexQuery: function(tableName, options) { showIndexQuery: function(tableName, options) {
var sql = "SHOW INDEX FROM <%= tableName %><%= options %>" var sql = "SHOW INDEX FROM `<%= tableName %>`<%= options %>"
return Utils._.template(sql)({ return Utils._.template(sql)({
tableName: tableName, tableName: tableName,
options: (options || {}).database ? ' FROM ' + options.database : '' options: (options || {}).database ? ' FROM `' + options.database + '`' : ''
}) })
}, },
...@@ -589,22 +589,34 @@ module.exports = (function() { ...@@ -589,22 +589,34 @@ module.exports = (function() {
return fields return fields
}, },
enableForeignKeyConstraintsQuery: function() {
var sql = "SET FOREIGN_KEY_CHECKS = 1;"
return Utils._.template(sql, {})
},
disableForeignKeyConstraintsQuery: function() {
var sql = "SET FOREIGN_KEY_CHECKS = 0;"
return Utils._.template(sql, {})
},
quoteIdentifier: function(identifier, force) { quoteIdentifier: function(identifier, force) {
return Utils.addTicks(identifier, "`") return Utils.addTicks(identifier, "`")
}, },
quoteIdentifiers: function(identifiers, force) { quoteIdentifiers: function(identifiers, force) {
return identifiers.split('.').map(function(v) { return this.quoteIdentifier(v, force) }.bind(this)).join('.') return identifiers.split('.').map(function(v) { return this.quoteIdentifier(v, force) }.bind(this)).join('.')
},
/**
* Generates an SQL query that returns all foreign keys of a table.
*
* @param {String} tableName The name of the table.
* @param {String} schemaName The name of the schema.
* @return {String} The generated sql query.
*/
getForeignKeysQuery: function(tableName, schemaName) {
return "SELECT CONSTRAINT_NAME as constraint_name FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = '" + tableName + "' AND CONSTRAINT_NAME!='PRIMARY' AND CONSTRAINT_SCHEMA='" + schemaName + "' AND REFERENCED_TABLE_NAME IS NOT NULL;"
},
/**
* Generates an SQL query that removes a foreign key from a table.
*
* @param {String} tableName The name of the table.
* @param {String} foreignKey The name of the foreign key constraint.
* @return {String} The generated sql query.
*/
dropForeignKeyQuery: function(tableName, foreignKey) {
return 'ALTER TABLE ' + this.quoteIdentifier(tableName) + ' DROP FOREIGN KEY ' + this.quoteIdentifier(foreignKey) + ';'
} }
} }
......
...@@ -714,14 +714,6 @@ module.exports = (function() { ...@@ -714,14 +714,6 @@ module.exports = (function() {
return fields return fields
}, },
enableForeignKeyConstraintsQuery: function() {
return false // not supported by dialect
},
disableForeignKeyConstraintsQuery: function() {
return false // not supported by dialect
},
createTrigger: function(tableName, triggerName, eventType, fireOnSpec, functionName, functionParams, optionsArray) { createTrigger: function(tableName, triggerName, eventType, fireOnSpec, functionName, functionParams, optionsArray) {
var sql = [ var sql = [
'CREATE <%= constraintVal %>TRIGGER <%= triggerName %>' 'CREATE <%= constraintVal %>TRIGGER <%= triggerName %>'
...@@ -1004,6 +996,28 @@ module.exports = (function() { ...@@ -1004,6 +996,28 @@ module.exports = (function() {
quoteIdentifiers: function(identifiers, force) { quoteIdentifiers: function(identifiers, force) {
return identifiers.split('.').map(function(t) { return this.quoteIdentifier(t, force) }.bind(this)).join('.') return identifiers.split('.').map(function(t) { return this.quoteIdentifier(t, force) }.bind(this)).join('.')
},
/**
* Generates an SQL query that returns all foreign keys of a table.
*
* @param {String} tableName The name of the table.
* @param {String} schemaName The name of the schema.
* @return {String} The generated sql query.
*/
getForeignKeysQuery: function(tableName, schemaName) {
return "SELECT conname as constraint_name, pg_catalog.pg_get_constraintdef(r.oid, true) as condef FROM pg_catalog.pg_constraint r WHERE r.conrelid = (SELECT oid FROM pg_class WHERE relname = '" + tableName + "' LIMIT 1) AND r.contype = 'f' ORDER BY 1;"
},
/**
* Generates an SQL query that removes a foreign key from a table.
*
* @param {String} tableName The name of the table.
* @param {String} foreignKey The name of the foreign key constraint.
* @return {String} The generated sql query.
*/
dropForeignKeyQuery: function(tableName, foreignKey) {
return 'ALTER TABLE ' + this.quoteIdentifier(tableName) + ' DROP CONSTRAINT ' + this.quoteIdentifier(foreignKey) + ';'
} }
} }
......
...@@ -179,7 +179,7 @@ module.exports = (function() { ...@@ -179,7 +179,7 @@ module.exports = (function() {
, attrLeft = ((primaryKeysLeft.length !== 1) ? 'id' : primaryKeysLeft[0]) , attrLeft = ((primaryKeysLeft.length !== 1) ? 'id' : primaryKeysLeft[0])
, tableRight = ((include.association.associationType === 'BelongsTo') ? tableName : include.as) , tableRight = ((include.association.associationType === 'BelongsTo') ? tableName : include.as)
, attrRight = include.association.identifier , attrRight = include.association.identifier
joinQuery += " LEFT OUTER JOIN " + this.quoteIdentifier(table) + " AS " + this.quoteIdentifier(as) + " ON " + this.quoteIdentifier(tableLeft) + "." + this.quoteIdentifier(attrLeft) + " = " + this.quoteIdentifier(tableRight) + "." + this.quoteIdentifier(attrRight) joinQuery += " LEFT OUTER JOIN " + this.quoteIdentifier(table) + " AS " + this.quoteIdentifier(as) + " ON " + this.quoteIdentifier(tableLeft) + "." + this.quoteIdentifier(attrLeft) + " = " + this.quoteIdentifier(tableRight) + "." + this.quoteIdentifier(attrRight)
} else { } else {
var primaryKeysSource = Object.keys(include.association.source.primaryKeys) var primaryKeysSource = Object.keys(include.association.source.primaryKeys)
...@@ -377,16 +377,6 @@ module.exports = (function() { ...@@ -377,16 +377,6 @@ module.exports = (function() {
return fields return fields
}, },
enableForeignKeyConstraintsQuery: function() {
var sql = "PRAGMA foreign_keys = ON;"
return Utils._.template(sql, {})
},
disableForeignKeyConstraintsQuery: function() {
var sql = "PRAGMA foreign_keys = OFF;"
return Utils._.template(sql, {})
},
hashToWhereConditions: function(hash) { hashToWhereConditions: function(hash) {
for (var key in hash) { for (var key in hash) {
if (hash.hasOwnProperty(key)) { if (hash.hasOwnProperty(key)) {
...@@ -486,6 +476,17 @@ module.exports = (function() { ...@@ -486,6 +476,17 @@ module.exports = (function() {
quoteIdentifiers: function(identifiers, force) { quoteIdentifiers: function(identifiers, force) {
return identifiers.split('.').map(function(v) { return this.quoteIdentifier(v, force) }.bind(this)).join('.') return identifiers.split('.').map(function(v) { return this.quoteIdentifier(v, force) }.bind(this)).join('.')
},
/**
* Generates an SQL query that returns all foreign keys of a table.
*
* @param {String} tableName The name of the table.
* @param {String} schemaName The name of the schema.
* @return {String} The generated sql query.
*/
getForeignKeysQuery: function(tableName, schemaName) {
return "PRAGMA foreign_key_list(\"" + tableName + "\")"
} }
} }
......
...@@ -118,5 +118,60 @@ var QueryInterface = module.exports = { ...@@ -118,5 +118,60 @@ var QueryInterface = module.exports = {
queryAndEmit.call(this, queries.splice(queries.length - 1)[0], methodName, {}, emitter) queryAndEmit.call(this, queries.splice(queries.length - 1)[0], methodName, {}, emitter)
} }
}.bind(this)) }.bind(this))
},
dropAllTables: function() {
var self = this
return new Utils.CustomEventEmitter(function(dropAllTablesEmitter) {
var events = []
, chainer = new Utils.QueryChainer()
, onError = function(err) {
self.emit('dropAllTables', err)
dropAllTablesEmitter.emit('error', err)
}
self
.showAllTables()
.error(onError)
.success(function(tableNames) {
self
.sequelize
.query('PRAGMA foreign_keys;')
.proxy(dropAllTablesEmitter, { events: ['sql'] })
.error(onError)
.success(function(result) {
var foreignKeysAreEnabled = result.foreign_keys === 1
if (foreignKeysAreEnabled) {
var queries = []
queries.push('PRAGMA foreign_keys = OFF')
tableNames.forEach(function(tableName) {
queries.push(self.QueryGenerator.dropTableQuery(tableName).replace(';', ''))
})
queries.push('PRAGMA foreign_keys = ON')
QueryInterface.execMultiQuery.call(self, queries, 'dropAllTables', dropAllTablesEmitter, self.queryAndEmit)
} else {
// add the table removal query to the chainer
tableNames.forEach(function(tableName) {
chainer.add(self, 'dropTable', [ tableName, { cascade: true } ])
})
chainer
.runSerially()
.proxy(dropAllTablesEmitter, { events: ['sql'] })
.error(onError)
.success(function() {
self.emit('dropAllTables', null)
dropAllTablesEmitter.emit('success', null)
})
}
})
})
}).run()
} }
} }
...@@ -139,6 +139,10 @@ module.exports = (function() { ...@@ -139,6 +139,10 @@ module.exports = (function() {
result[_result.name].defaultValue = result[_result.name].defaultValue.replace(/'/g, "") result[_result.name].defaultValue = result[_result.name].defaultValue.replace(/'/g, "")
} }
}) })
} else if (this.sql.indexOf('PRAGMA foreign_keys;') !== -1) {
result = results[0]
} else if (this.sql.indexOf('PRAGMA foreign_keys') !== -1) {
result = results
} }
this.emit('success', result) this.emit('success', result)
......
...@@ -3,20 +3,19 @@ var util = require("util") ...@@ -3,20 +3,19 @@ var util = require("util")
, Promise = require("promise") , Promise = require("promise")
, proxyEventKeys = ['success', 'error', 'sql'] , proxyEventKeys = ['success', 'error', 'sql']
, tick = (typeof setImmediate !== "undefined" ? setImmediate : process.nextTick) , tick = (typeof setImmediate !== "undefined" ? setImmediate : process.nextTick)
, Utils = require('../utils')
var bindToProcess = function(fct) { var bindToProcess = function(fct) {
if (fct) { if (fct && process.domain) {
if (process.domain) { return process.domain.bind(fct)
return process.domain.bind(fct);
}
} }
return fct; return fct
}; };
module.exports = (function() { module.exports = (function() {
var CustomEventEmitter = function(fct) { var CustomEventEmitter = function(fct) {
this.fct = bindToProcess(fct); this.fct = bindToProcess(fct)
} }
util.inherits(CustomEventEmitter, EventEmitter) util.inherits(CustomEventEmitter, EventEmitter)
...@@ -54,25 +53,40 @@ module.exports = (function() { ...@@ -54,25 +53,40 @@ module.exports = (function() {
return this return this
} }
CustomEventEmitter.prototype.sql = CustomEventEmitter.prototype.sql = function(fct) {
function(fct) {
this.on('sql', bindToProcess(fct)) this.on('sql', bindToProcess(fct))
return this; return this;
} }
CustomEventEmitter.prototype.proxy = function(emitter) { /**
proxyEventKeys.forEach(function (eventKey) { * Proxy every event of this custom event emitter to another one.
*
* @param {CustomEventEmitter} emitter The event emitter that should receive the events.
* @return {void}
*/
CustomEventEmitter.prototype.proxy = function(emitter, options) {
options = Utils._.extend({
events: proxyEventKeys,
skipEvents: []
}, options || {})
options.events = Utils._.difference(options.events, options.skipEvents)
options.events.forEach(function (eventKey) {
this.on(eventKey, function (result) { this.on(eventKey, function (result) {
emitter.emit(eventKey, result) emitter.emit(eventKey, result)
}) })
}.bind(this)) }.bind(this))
return this
} }
CustomEventEmitter.prototype.then = CustomEventEmitter.prototype.then = function(onFulfilled, onRejected) {
function (onFulfilled, onRejected) {
var self = this var self = this
onFulfilled = bindToProcess(onFulfilled) onFulfilled = bindToProcess(onFulfilled)
onRejected = bindToProcess(onRejected) onRejected = bindToProcess(onRejected)
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
self.on('error', reject) self.on('error', reject)
.on('success', resolve); .on('success', resolve);
......
...@@ -223,34 +223,45 @@ module.exports = (function() { ...@@ -223,34 +223,45 @@ module.exports = (function() {
QueryInterface.prototype.dropAllTables = function() { QueryInterface.prototype.dropAllTables = function() {
var self = this var self = this
return new Utils.CustomEventEmitter(function(emitter) { if (this.sequelize.options.dialect === 'sqlite') {
var chainer = new Utils.QueryChainer() // sqlite needs some special treatment as it cannot drop a column
return SQLiteQueryInterface.dropAllTables.call(this)
self.showAllTables().success(function(tableNames) { } else {
chainer.add(self, 'disableForeignKeyConstraints', []) return new Utils.CustomEventEmitter(function(dropAllTablesEmitter) {
var events = []
tableNames.forEach(function(tableName) { , chainer = new Utils.QueryChainer()
chainer.add(self, 'dropTable', [tableName, {cascade: true}]) , onError = function(err) {
}) self.emit('dropAllTables', err)
dropAllTablesEmitter.emit('error', err)
}
chainer.add(self, 'enableForeignKeyConstraints', []) self.showAllTables().success(function(tableNames) {
self.getForeignKeysForTables(tableNames).success(function(foreignKeys) {
chainer // add the foreign key removal query to the chainer
.runSerially() Object.keys(foreignKeys).forEach(function(tableName) {
.success(function() { foreignKeys[tableName].forEach(function(foreignKey) {
self.emit('dropAllTables', null) var sql = self.QueryGenerator.dropForeignKeyQuery(tableName, foreignKey)
emitter.emit('success', null) chainer.add(self.sequelize, 'query', [ sql ])
})
}) })
.error(function(err) {
self.emit('dropAllTables', err) // add the table removal query to the chainer
emitter.emit('error', err) tableNames.forEach(function(tableName) {
chainer.add(self, 'dropTable', [ tableName, { cascade: true } ])
}) })
}).error(function(err) { chainer
self.emit('dropAllTables', err) .runSerially()
emitter.emit('error', err) .success(function() {
}) self.emit('dropAllTables', null)
}).run() dropAllTablesEmitter.emit('success', null)
})
.error(onError)
}).error(onError)
}).error(onError)
}).run()
}
} }
QueryInterface.prototype.renameTable = function(before, after) { QueryInterface.prototype.renameTable = function(before, after) {
...@@ -263,6 +274,7 @@ module.exports = (function() { ...@@ -263,6 +274,7 @@ module.exports = (function() {
return new Utils.CustomEventEmitter(function(emitter) { return new Utils.CustomEventEmitter(function(emitter) {
var showTablesSql = self.QueryGenerator.showTablesQuery() var showTablesSql = self.QueryGenerator.showTablesQuery()
self.sequelize.query(showTablesSql, null, { raw: true }).success(function(tableNames) { self.sequelize.query(showTablesSql, null, { raw: true }).success(function(tableNames) {
self.emit('showAllTables', null) self.emit('showAllTables', null)
emitter.emit('success', Utils._.flatten(tableNames)) emitter.emit('success', Utils._.flatten(tableNames))
...@@ -397,6 +409,35 @@ module.exports = (function() { ...@@ -397,6 +409,35 @@ module.exports = (function() {
return queryAndEmit.call(this, sql, 'showIndex') return queryAndEmit.call(this, sql, 'showIndex')
} }
QueryInterface.prototype.getForeignKeysForTables = function(tableNames) {
var self = this
return new Utils.CustomEventEmitter(function(emitter) {
if (tableNames.length === 0) {
emitter.emit('success', {})
} else {
var chainer = new Utils.QueryChainer()
tableNames.forEach(function(tableName) {
var sql = self.QueryGenerator.getForeignKeysQuery(tableName, self.sequelize.config.database)
chainer.add(self.sequelize, 'query', [sql])
})
chainer.runSerially().proxy(emitter, {
skipEvents: ['success']
}).success(function(results) {
var result = {}
tableNames.forEach(function(tableName, i) {
result[tableName] = Utils._.compact(results[i]).map(function(r) { return r.constraint_name })
})
emitter.emit('success', result)
})
}
}).run()
}
QueryInterface.prototype.removeIndex = function(tableName, indexNameOrAttributes) { QueryInterface.prototype.removeIndex = function(tableName, indexNameOrAttributes) {
var sql = this.QueryGenerator.removeIndexQuery(tableName, indexNameOrAttributes) var sql = this.QueryGenerator.removeIndexQuery(tableName, indexNameOrAttributes)
return queryAndEmit.call(this, sql, "removeIndex") return queryAndEmit.call(this, sql, "removeIndex")
...@@ -434,13 +475,12 @@ module.exports = (function() { ...@@ -434,13 +475,12 @@ module.exports = (function() {
return new Utils.CustomEventEmitter(function(emitter) { return new Utils.CustomEventEmitter(function(emitter) {
var chainer = new Utils.QueryChainer() var chainer = new Utils.QueryChainer()
chainer.add(self, 'enableForeignKeyConstraints', [])
chainer.add(self, 'queryAndEmit', [[sql, dao], 'delete']) chainer.add(self, 'queryAndEmit', [[sql, dao], 'delete'])
chainer.runSerially() chainer.runSerially()
.success(function(results){ .success(function(results){
emitter.query = { sql: sql } emitter.query = { sql: sql }
emitter.emit('success', results[1]) emitter.emit('success', results[0])
emitter.emit('sql', sql) emitter.emit('sql', sql)
}) })
.error(function(err) { .error(function(err) {
...@@ -461,7 +501,6 @@ module.exports = (function() { ...@@ -461,7 +501,6 @@ module.exports = (function() {
return new Utils.CustomEventEmitter(function(emitter) { return new Utils.CustomEventEmitter(function(emitter) {
var chainer = new Utils.QueryChainer() var chainer = new Utils.QueryChainer()
chainer.add(self, 'enableForeignKeyConstraints', [])
chainer.add(self, 'queryAndEmit', [sql, 'bulkUpdate']) chainer.add(self, 'queryAndEmit', [sql, 'bulkUpdate'])
return chainer.runSerially() return chainer.runSerially()
...@@ -547,7 +586,6 @@ module.exports = (function() { ...@@ -547,7 +586,6 @@ module.exports = (function() {
var chainer = new Utils.QueryChainer() var chainer = new Utils.QueryChainer()
chainer.add(self, 'enableForeignKeyConstraints', [])
chainer.add(self, 'queryAndEmit', [[sql, dao], 'delete']) chainer.add(self, 'queryAndEmit', [[sql, dao], 'delete'])
chainer.runSerially() chainer.runSerially()
...@@ -578,7 +616,6 @@ module.exports = (function() { ...@@ -578,7 +616,6 @@ module.exports = (function() {
return new Utils.CustomEventEmitter(function(emitter) { return new Utils.CustomEventEmitter(function(emitter) {
var chainer = new Utils.QueryChainer() var chainer = new Utils.QueryChainer()
chainer.add(self, 'enableForeignKeyConstraints', [])
chainer.add(self, 'queryAndEmit', [sql, 'bulkDelete', options]) chainer.add(self, 'queryAndEmit', [sql, 'bulkDelete', options])
chainer.runSerially() chainer.runSerially()
...@@ -660,30 +697,6 @@ module.exports = (function() { ...@@ -660,30 +697,6 @@ module.exports = (function() {
}).run() }).run()
} }
QueryInterface.prototype.enableForeignKeyConstraints = function() {
var sql = this.QueryGenerator.enableForeignKeyConstraintsQuery()
if(sql) {
return queryAndEmit.call(this, sql, 'enableForeignKeyConstraints')
} else {
return new Utils.CustomEventEmitter(function(emitter) {
this.emit('enableForeignKeyConstraints', null)
emitter.emit('success')
}).run()
}
}
QueryInterface.prototype.disableForeignKeyConstraints = function() {
var sql = this.QueryGenerator.disableForeignKeyConstraintsQuery()
if(sql){
return queryAndEmit.call(this, sql, 'disableForeignKeyConstraints')
} else {
return new Utils.CustomEventEmitter(function(emitter) {
this.emit('disableForeignKeyConstraints', null)
emitter.emit('success')
}).run()
}
}
QueryInterface.prototype.createTrigger = function(tableName, triggerName, timingType, fireOnArray, QueryInterface.prototype.createTrigger = function(tableName, triggerName, timingType, fireOnArray,
functionName, functionParams, optionsArray) { functionName, functionParams, optionsArray) {
var sql = this.QueryGenerator.createTrigger(tableName, triggerName, timingType, fireOnArray, functionName var sql = this.QueryGenerator.createTrigger(tableName, triggerName, timingType, fireOnArray, functionName
......
...@@ -28,12 +28,9 @@ describe(Support.getTestDialectTeaser("HasMany"), function() { ...@@ -28,12 +28,9 @@ describe(Support.getTestDialectTeaser("HasMany"), function() {
describe('hasSingle', function() { describe('hasSingle', function() {
beforeEach(function(done) { beforeEach(function(done) {
var self = this var self = this
this.Article = this.sequelize.define('Article', {
'title': DataTypes.STRING this.Article = this.sequelize.define('Article', { 'title': DataTypes.STRING })
}) this.Label = this.sequelize.define('Label', { 'text': DataTypes.STRING })
this.Label = this.sequelize.define('Label', {
'text': DataTypes.STRING
})
this.Article.hasMany(this.Label) this.Article.hasMany(this.Label)
......
...@@ -182,8 +182,8 @@ if (dialect.match(/^mysql/)) { ...@@ -182,8 +182,8 @@ if (dialect.match(/^mysql/)) {
}, { }, {
title: 'functions can take functions as arguments', title: 'functions can take functions as arguments',
arguments: ['myTable', function (sequelize) { arguments: ['myTable', function (sequelize) {
return { return {
order: [[sequelize.fn('f1', sequelize.fn('f2', sequelize.col('id'))), 'DESC']] order: [[sequelize.fn('f1', sequelize.fn('f2', sequelize.col('id'))), 'DESC']]
} }
}], }],
expectation: "SELECT * FROM `myTable` ORDER BY f1(f2(`id`)) DESC;", expectation: "SELECT * FROM `myTable` ORDER BY f1(f2(`id`)) DESC;",
...@@ -194,7 +194,7 @@ if (dialect.match(/^mysql/)) { ...@@ -194,7 +194,7 @@ if (dialect.match(/^mysql/)) {
arguments: ['myTable', function (sequelize) { arguments: ['myTable', function (sequelize) {
return { return {
order: [ order: [
[sequelize.fn('f1', sequelize.col('myTable.id')), 'DESC'], [sequelize.fn('f1', sequelize.col('myTable.id')), 'DESC'],
[sequelize.fn('f2', 12, 'lalala', new Date(Date.UTC(2011, 2, 27, 10, 1, 55))), 'ASC'] [sequelize.fn('f2', 12, 'lalala', new Date(Date.UTC(2011, 2, 27, 10, 1, 55))), 'ASC']
] ]
} }
...@@ -450,10 +450,10 @@ if (dialect.match(/^mysql/)) { ...@@ -450,10 +450,10 @@ if (dialect.match(/^mysql/)) {
showIndexQuery: [ showIndexQuery: [
{ {
arguments: ['User'], arguments: ['User'],
expectation: 'SHOW INDEX FROM User' expectation: 'SHOW INDEX FROM `User`'
}, { }, {
arguments: ['User', { database: 'sequelize' }], arguments: ['User', { database: 'sequelize' }],
expectation: "SHOW INDEX FROM User FROM sequelize" expectation: "SHOW INDEX FROM `User` FROM `sequelize`"
} }
], ],
...@@ -504,7 +504,7 @@ if (dialect.match(/^mysql/)) { ...@@ -504,7 +504,7 @@ if (dialect.match(/^mysql/)) {
describe(suiteTitle, function() { describe(suiteTitle, function() {
tests.forEach(function(test) { tests.forEach(function(test) {
var title = test.title || 'MySQL correctly returns ' + test.expectation + ' for ' + util.inspect(test.arguments) var title = test.title || 'MySQL correctly returns ' + test.expectation + ' for ' + util.inspect(test.arguments)
it(title, function(done) { it(title, function(done) {
// Options would normally be set by the query interface that instantiates the query-generator, but here we specify it explicitly // Options would normally be set by the query interface that instantiates the query-generator, but here we specify it explicitly
var context = test.context || {options: {}}; var context = test.context || {options: {}};
if (test.needsSequelize) { if (test.needsSequelize) {
......
...@@ -57,7 +57,7 @@ var Support = { ...@@ -57,7 +57,7 @@ var Support = {
}, },
getSequelizeInstance: function(db, user, pass, options) { getSequelizeInstance: function(db, user, pass, options) {
options = options || {}; options = options || {}
options.dialect = options.dialect || this.getTestDialect() options.dialect = options.dialect || this.getTestDialect()
return new Sequelize(db, user, pass, options) return new Sequelize(db, user, pass, options)
}, },
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!