query-interface.js 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. 'use strict';
  2. /**
  3. Returns an object that treats MySQL's inabilities to do certain queries.
  4. @class QueryInterface
  5. @static
  6. @private
  7. */
  8. const Promise = require('../../promise');
  9. const sequelizeErrors = require('../../errors');
  10. /**
  11. A wrapper that fixes MySQL's inability to cleanly remove columns from existing tables if they have a foreign key constraint.
  12. @param {QueryInterface} qi
  13. @param {string} tableName The name of the table.
  14. @param {string} columnName The name of the attribute that we want to remove.
  15. @param {Object} options
  16. @private
  17. */
  18. function removeColumn(qi, tableName, columnName, options) {
  19. options = options || {};
  20. return qi.sequelize.query(
  21. qi.QueryGenerator.getForeignKeyQuery(tableName.tableName ? tableName : {
  22. tableName,
  23. schema: qi.sequelize.config.database
  24. }, columnName),
  25. Object.assign({ raw: true }, options)
  26. )
  27. .then(([results]) => {
  28. //Exclude primary key constraint
  29. if (!results.length || results[0].constraint_name === 'PRIMARY') {
  30. // No foreign key constraints found, so we can remove the column
  31. return;
  32. }
  33. return Promise.map(results, constraint => qi.sequelize.query(
  34. qi.QueryGenerator.dropForeignKeyQuery(tableName, constraint.constraint_name),
  35. Object.assign({ raw: true }, options)
  36. ));
  37. })
  38. .then(() => qi.sequelize.query(
  39. qi.QueryGenerator.removeColumnQuery(tableName, columnName),
  40. Object.assign({ raw: true }, options)
  41. ));
  42. }
  43. /**
  44. * @param {QueryInterface} qi
  45. * @param {string} tableName
  46. * @param {string} constraintName
  47. * @param {Object} options
  48. *
  49. * @private
  50. */
  51. function removeConstraint(qi, tableName, constraintName, options) {
  52. const sql = qi.QueryGenerator.showConstraintsQuery(
  53. tableName.tableName ? tableName : {
  54. tableName,
  55. schema: qi.sequelize.config.database
  56. }, constraintName);
  57. return qi.sequelize.query(sql, Object.assign({}, options,
  58. { type: qi.sequelize.QueryTypes.SHOWCONSTRAINTS }))
  59. .then(constraints => {
  60. const constraint = constraints[0];
  61. let query;
  62. if (!constraint || !constraint.constraintType) {
  63. throw new sequelizeErrors.UnknownConstraintError(
  64. {
  65. message: `Constraint ${constraintName} on table ${tableName} does not exist`,
  66. constraint: constraintName,
  67. table: tableName
  68. });
  69. }
  70. if (constraint.constraintType === 'FOREIGN KEY') {
  71. query = qi.QueryGenerator.dropForeignKeyQuery(tableName, constraintName);
  72. } else {
  73. query = qi.QueryGenerator.removeIndexQuery(constraint.tableName, constraint.constraintName);
  74. }
  75. return qi.sequelize.query(query, options);
  76. });
  77. }
  78. exports.removeConstraint = removeConstraint;
  79. exports.removeColumn = removeColumn;