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

Commit a06a92d5 by Trey Thomas

MySQL: drop foreign key before dropping column

1 parent 489099fc
......@@ -332,6 +332,26 @@ var QueryGenerator = {
},
/**
* Generates an SQL query that returns the foreign key constraint of a given column.
*
* @param {String} tableName The name of the table.
* @param {String} columnName The name of the column.
* @return {String} The generated sql query.
*/
getForeignKeyQuery: function(table, columnName) {
var tableName = table.tableName || table;
if (table.schema) {
tableName = table.schema + '.' + tableName;
}
return [
'SELECT CONSTRAINT_NAME as constraint_name',
'FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE',
'WHERE TABLE_NAME = ' + wrapSingleQuote(tableName),
'AND COLUMN_NAME = ' + wrapSingleQuote(columnName),
].join(' ');
},
/**
* Generates an SQL query that removes a foreign key from a table.
*
* @param {String} tableName The name of the table.
......@@ -343,4 +363,9 @@ var QueryGenerator = {
}
};
// private methods
function wrapSingleQuote(identifier){
return Utils.addTicks(identifier, '\'');
}
module.exports = Utils._.extend(Utils._.clone(require('../abstract/query-generator')), QueryGenerator);
'use strict';
/**
Returns an object that treats MySQL's inabilities to do certain queries.
@class QueryInterface
@static
*/
var _ = require('lodash');
/**
A wrapper that fixes MySQL's inability to cleanly remove columns from existing tables if they have a foreign key constraint.
@method removeColumn
@for QueryInterface
@param {String} tableName The name of the table.
@param {String} columnName The name of the attribute that we want to remove.
@param {Object} options
*/
var removeColumn = function (tableName, columnName, options) {
var self = this;
options = options || {};
return self.sequelize.query(
self.QueryGenerator.getForeignKeyQuery(tableName, columnName),
_.assign({ raw: true }, options)
)
.spread(function (results) {
if (!results.length) {
// No foreign key constraints found, so we can remove the column
return;
}
return self.sequelize.query(
self.QueryGenerator.dropForeignKeyQuery(tableName, results[0].constraint_name),
_.assign({ raw: true }, options)
);
})
.then(function () {
return self.sequelize.query(
self.QueryGenerator.removeColumnQuery(tableName, columnName),
_.assign({ raw: true }, options)
);
});
};
module.exports = {
removeColumn: removeColumn
};
......@@ -5,6 +5,7 @@ var Utils = require('./utils')
, DataTypes = require('./data-types')
, SQLiteQueryInterface = require('./dialects/sqlite/query-interface')
, MSSSQLQueryInterface = require('./dialects/mssql/query-interface')
, MySQLQueryInterface = require('./dialects/mysql/query-interface')
, Transaction = require('./transaction')
, Promise = require('./promise')
, QueryTypes = require('./query-types');
......@@ -360,8 +361,11 @@ QueryInterface.prototype.removeColumn = function(tableName, attributeName, optio
// sqlite needs some special treatment as it cannot drop a column
return SQLiteQueryInterface.removeColumn.call(this, tableName, attributeName, options);
case 'mssql':
// mssql needs special treatment as it cannot drop a column with a default constraint
// mssql needs special treatment as it cannot drop a column with a default or foreign key constraint
return MSSSQLQueryInterface.removeColumn.call(this, tableName, attributeName, options);
case 'mysql':
// mysql needs special treatment as it cannot drop a column with a foreign key constraint
return MySQLQueryInterface.removeColumn.call(this, tableName, attributeName, options);
default:
var sql = this.QueryGenerator.removeColumnQuery(tableName, attributeName);
return this.sequelize.query(sql, options);
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!