query-interface.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. 'use strict';
  2. const sequelizeErrors = require('../../errors');
  3. const { QueryInterface } = require('../abstract/query-interface');
  4. const QueryTypes = require('../../query-types');
  5. /**
  6. * The interface that Sequelize uses to talk with MySQL/MariaDB database
  7. */
  8. class MySQLQueryInterface extends QueryInterface {
  9. /**
  10. * A wrapper that fixes MySQL's inability to cleanly remove columns from existing tables if they have a foreign key constraint.
  11. *
  12. * @override
  13. */
  14. async removeColumn(tableName, columnName, options) {
  15. options = options || {};
  16. const [results] = await this.sequelize.query(
  17. this.queryGenerator.getForeignKeyQuery(tableName.tableName ? tableName : {
  18. tableName,
  19. schema: this.sequelize.config.database
  20. }, columnName),
  21. { raw: true, ...options }
  22. );
  23. //Exclude primary key constraint
  24. if (results.length && results[0].constraint_name !== 'PRIMARY') {
  25. await Promise.all(results.map(constraint => this.sequelize.query(
  26. this.queryGenerator.dropForeignKeyQuery(tableName, constraint.constraint_name),
  27. { raw: true, ...options }
  28. )));
  29. }
  30. return await this.sequelize.query(
  31. this.queryGenerator.removeColumnQuery(tableName, columnName),
  32. { raw: true, ...options }
  33. );
  34. }
  35. /**
  36. * @override
  37. */
  38. async upsert(tableName, insertValues, updateValues, where, options) {
  39. options = { ...options };
  40. options.type = QueryTypes.UPSERT;
  41. options.updateOnDuplicate = Object.keys(updateValues);
  42. const model = options.model;
  43. const sql = this.queryGenerator.insertQuery(tableName, insertValues, model.rawAttributes, options);
  44. return await this.sequelize.query(sql, options);
  45. }
  46. /**
  47. * @override
  48. */
  49. async removeConstraint(tableName, constraintName, options) {
  50. const sql = this.queryGenerator.showConstraintsQuery(
  51. tableName.tableName ? tableName : {
  52. tableName,
  53. schema: this.sequelize.config.database
  54. }, constraintName);
  55. const constraints = await this.sequelize.query(sql, { ...options,
  56. type: this.sequelize.QueryTypes.SHOWCONSTRAINTS });
  57. const constraint = constraints[0];
  58. let query;
  59. if (!constraint || !constraint.constraintType) {
  60. throw new sequelizeErrors.UnknownConstraintError(
  61. {
  62. message: `Constraint ${constraintName} on table ${tableName} does not exist`,
  63. constraint: constraintName,
  64. table: tableName
  65. });
  66. }
  67. if (constraint.constraintType === 'FOREIGN KEY') {
  68. query = this.queryGenerator.dropForeignKeyQuery(tableName, constraintName);
  69. } else {
  70. query = this.queryGenerator.removeIndexQuery(constraint.tableName, constraint.constraintName);
  71. }
  72. return await this.sequelize.query(query, options);
  73. }
  74. }
  75. exports.MySQLQueryInterface = MySQLQueryInterface;