Skip to content

Commit

Permalink
feat: migrate removeColumn to typescript (#16476)
Browse files Browse the repository at this point in the history
  • Loading branch information
lohart13 committed Sep 11, 2023
1 parent db7fe12 commit bc35a52
Show file tree
Hide file tree
Showing 29 changed files with 386 additions and 490 deletions.
8 changes: 8 additions & 0 deletions packages/core/src/dialects/abstract/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ export type DialectSupports = {
truncate: {
cascade: boolean,
},
removeColumn: {
cascade: boolean,
ifExists: boolean,
},
};

type TypeParser = (...params: any[]) => unknown;
Expand Down Expand Up @@ -366,6 +370,10 @@ export abstract class AbstractDialect {
truncate: {
cascade: false,
},
removeColumn: {
cascade: false,
ifExists: false,
},
};

protected static extendSupport(supportsOverwrite: DeepPartial<DialectSupports>): DialectSupports {
Expand Down
33 changes: 33 additions & 0 deletions packages/core/src/dialects/abstract/query-generator-typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import type {
ListSchemasQueryOptions,
ListTablesQueryOptions,
QuoteTableOptions,
RemoveColumnQueryOptions,
RemoveConstraintQueryOptions,
ShowConstraintsQueryOptions,
} from './query-generator.types.js';
Expand All @@ -59,6 +60,7 @@ export interface RemoveIndexQueryOptions {
export const DROP_TABLE_QUERY_SUPPORTABLE_OPTIONS = new Set<keyof DropTableQueryOptions>(['cascade']);
export const LIST_TABLES_QUERY_SUPPORTABLE_OPTIONS = new Set<keyof ListTablesQueryOptions>(['schema']);
export const QUOTE_TABLE_SUPPORTABLE_OPTIONS = new Set<keyof QuoteTableOptions>(['indexHints', 'tableHints']);
export const REMOVE_COLUMN_QUERY_SUPPORTABLE_OPTIONS = new Set<keyof RemoveColumnQueryOptions>(['ifExists', 'cascade']);
export const REMOVE_CONSTRAINT_QUERY_SUPPORTABLE_OPTIONS = new Set<keyof RemoveConstraintQueryOptions>(['ifExists', 'cascade']);
export const REMOVE_INDEX_QUERY_SUPPORTABLE_OPTIONS = new Set<keyof RemoveIndexQueryOptions>(['concurrently', 'ifExists', 'cascade']);
export const SHOW_CONSTRAINTS_QUERY_SUPPORTABLE_OPTIONS = new Set<keyof ShowConstraintsQueryOptions>(['columnName', 'constraintName', 'constraintType']);
Expand Down Expand Up @@ -186,6 +188,37 @@ export class AbstractQueryGeneratorTypeScript {
throw new Error(`listTablesQuery has not been implemented in ${this.dialect.name}.`);
}

removeColumnQuery(tableName: TableNameOrModel, attributeName: string, options?: RemoveColumnQueryOptions): string {
const REMOVE_COLUMN_QUERY_SUPPORTED_OPTIONS = new Set<keyof RemoveColumnQueryOptions>();

if (this.dialect.supports.removeColumn.cascade) {
REMOVE_COLUMN_QUERY_SUPPORTED_OPTIONS.add('cascade');
}

if (this.dialect.supports.removeColumn.ifExists) {
REMOVE_COLUMN_QUERY_SUPPORTED_OPTIONS.add('ifExists');
}

if (options) {
rejectInvalidOptions(
'removeColumnQuery',
this.dialect.name,
REMOVE_COLUMN_QUERY_SUPPORTABLE_OPTIONS,
REMOVE_COLUMN_QUERY_SUPPORTED_OPTIONS,
options,
);
}

return joinSQLFragments([
'ALTER TABLE',
this.quoteTable(tableName),
'DROP COLUMN',
options?.ifExists ? 'IF EXISTS' : '',
this.quoteIdentifier(attributeName),
options?.cascade ? 'CASCADE' : '',
]);
}

addConstraintQuery(tableName: TableNameOrModel, options: AddConstraintQueryOptions): string {
if (!this.dialect.supports.constraints.add) {
throw new Error(`Add constraint queries are not supported by ${this.dialect.name} dialect`);
Expand Down
11 changes: 0 additions & 11 deletions packages/core/src/dialects/abstract/query-generator.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,6 @@ export interface AddColumnQueryOptions {
ifNotExists?: boolean;
}

// keep REMOVE_COLUMN_QUERY_SUPPORTABLE_OPTIONS updated when modifying this
export interface RemoveColumnQueryOptions {
ifExists?: boolean;
}

/**
* The base class for all query generators, used to generate all SQL queries.
*
Expand Down Expand Up @@ -131,12 +126,6 @@ export class AbstractQueryGenerator extends AbstractQueryGeneratorTypeScript {
options?: AddColumnQueryOptions,
): string;

removeColumnQuery(
table: TableNameOrModel,
attributeName: string,
options?: RemoveColumnQueryOptions,
): string;

updateQuery(
tableName: TableName,
attrValueHash: object,
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/dialects/abstract/query-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export const CREATE_DATABASE_QUERY_SUPPORTABLE_OPTIONS = new Set(['collate', 'ch
export const CREATE_SCHEMA_QUERY_SUPPORTABLE_OPTIONS = new Set(['collate', 'charset']);
export const CREATE_TABLE_QUERY_SUPPORTABLE_OPTIONS = new Set(['collate', 'charset', 'engine', 'rowFormat', 'comment', 'initialAutoIncrement', 'uniqueKeys']);
export const ADD_COLUMN_QUERY_SUPPORTABLE_OPTIONS = new Set(['ifNotExists']);
export const REMOVE_COLUMN_QUERY_SUPPORTABLE_OPTIONS = new Set(['ifExists']);

/**
* Abstract Query Generator
Expand Down
6 changes: 6 additions & 0 deletions packages/core/src/dialects/abstract/query-generator.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ export interface ListTablesQueryOptions {
schema?: string;
}

// keep REMOVE_COLUMN_QUERY_SUPPORTABLE_OPTIONS updated when modifying this
export interface RemoveColumnQueryOptions {
cascade?: boolean;
ifExists?: boolean;
}

export interface BaseConstraintQueryOptions {
name?: string;
type: ConstraintType;
Expand Down
19 changes: 19 additions & 0 deletions packages/core/src/dialects/abstract/query-interface-typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import type {
QiDropAllTablesOptions,
QiDropTableOptions,
QiShowAllTablesOptions,
RemoveColumnOptions,
RemoveConstraintOptions,
ShowAllSchemasOptions,
ShowConstraintsOptions,
Expand Down Expand Up @@ -265,6 +266,24 @@ export class AbstractQueryInterfaceTypeScript {
}
}

/**
* Removes a column from a table
*
* @param tableName
* @param attributeName
* @param options
*/
async removeColumn(
tableName: TableNameOrModel,
attributeName: string,
options?: RemoveColumnOptions,
): Promise<void> {
const queryOptions = { ...options, raw: true };
const sql = this.queryGenerator.removeColumnQuery(tableName, attributeName, queryOptions);

await this.sequelize.queryRaw(sql, queryOptions);
}

/**
* Add a constraint to a table
*
Expand Down
13 changes: 1 addition & 12 deletions packages/core/src/dialects/abstract/query-interface.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type { IsolationLevel, Transaction } from '../../transaction';
import type { AllowLowercase } from '../../utils/types.js';
import type { DataType } from './data-types.js';
import type { RemoveIndexQueryOptions, TableNameOrModel } from './query-generator-typescript';
import type { AbstractQueryGenerator, AddColumnQueryOptions, RemoveColumnQueryOptions } from './query-generator.js';
import type { AbstractQueryGenerator, AddColumnQueryOptions } from './query-generator.js';
import { AbstractQueryInterfaceTypeScript } from './query-interface-typescript';
import type { QiDropAllSchemasOptions } from './query-interface.types.js';
import type { WhereOptions } from './where-sql-builder-types.js';
Expand Down Expand Up @@ -213,8 +213,6 @@ export interface IndexDescription {

export interface AddColumnOptions extends AddColumnQueryOptions, QueryRawOptions, Replaceable { }

export interface RemoveColumnOptions extends RemoveColumnQueryOptions, QueryRawOptions, Replaceable { }

export interface CreateTableAttributeOptions<M extends Model = Model>
extends AttributeOptions<M> {
/**
Expand Down Expand Up @@ -295,15 +293,6 @@ export class AbstractQueryInterface extends AbstractQueryInterfaceTypeScript {
options?: AddColumnOptions
): Promise<void>;

/**
* Removes a column from a table
*/
removeColumn(
table: TableName,
attribute: string,
options?: RemoveColumnOptions,
): Promise<void>;

/**
* Changes a column
*/
Expand Down
8 changes: 0 additions & 8 deletions packages/core/src/dialects/abstract/query-interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,14 +235,6 @@ export class AbstractQueryInterface extends AbstractQueryInterfaceTypeScript {
* @param {string} attributeName Column name to remove
* @param {object} [options] Query options
*/
async removeColumn(tableName, attributeName, options) {
options = options || {};

const { ifExists, ...rawQueryOptions } = options;
const removeColumnQueryOptions = ifExists ? { ifExists } : undefined;

return this.sequelize.queryRaw(this.queryGenerator.removeColumnQuery(tableName, attributeName, removeColumnQueryOptions), rawQueryOptions);
}

normalizeAttribute(dataTypeOrOptions) {
let attribute;
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/dialects/abstract/query-interface.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type {
DropTableQueryOptions,
ListSchemasQueryOptions,
ListTablesQueryOptions,
RemoveColumnQueryOptions,
RemoveConstraintQueryOptions,
ShowConstraintsQueryOptions,
} from './query-generator.types';
Expand Down Expand Up @@ -99,6 +100,9 @@ export interface QiDropAllTablesOptions extends QiDropTableOptions {

export interface FetchDatabaseVersionOptions extends Omit<QueryRawOptions, 'type' | 'plain'> {}

/** Options accepted by {@link AbstractQueryInterface#removeColumn} */
export interface RemoveColumnOptions extends RemoveColumnQueryOptions, QueryRawOptions { }

/** Options accepted by {@link AbstractQueryInterface#addConstraint} */
export type AddConstraintOptions = AddConstraintQueryOptions & QueryRawOptions;

Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/dialects/db2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ export class Db2Dialect extends AbstractDialect {
precision: false,
},
},
removeColumn: {
cascade: true,
},
});

readonly defaultVersion = '1.0.0';
Expand Down
19 changes: 0 additions & 19 deletions packages/core/src/dialects/db2/query-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -227,25 +227,6 @@ export class Db2QueryGenerator extends Db2QueryGeneratorTypeScript {
});
}

removeColumnQuery(tableName, attributeName, options) {
if (options) {
rejectInvalidOptions(
'removeColumnQuery',
this.dialect.name,
REMOVE_COLUMN_QUERY_SUPPORTABLE_OPTIONS,
REMOVE_COLUMN_QUERY_SUPPORTED_OPTIONS,
options,
);
}

const query = 'ALTER TABLE <%= tableName %> DROP COLUMN <%= attributeName %>;';

return template(query, this._templateSettings)({
tableName: this.quoteTable(tableName),
attributeName: this.quoteIdentifier(attributeName),
});
}

changeColumnQuery(tableName, attributes) {
const query = 'ALTER TABLE <%= tableName %> <%= query %>;';
const attrString = [];
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/dialects/ibmi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ export class IBMiDialect extends AbstractDialect {
dataTypes: {
COLLATE_BINARY: true,
},
removeColumn: {
cascade: true,
},
},
);

Expand Down
14 changes: 0 additions & 14 deletions packages/core/src/dialects/ibmi/query-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,20 +158,6 @@ export class IBMiQueryGenerator extends IBMiQueryGeneratorTypeScript {
return `ALTER TABLE ${this.quoteTable(table)} ADD ${this.quoteIdentifier(key)} ${definition}`;
}

removeColumnQuery(tableName, attributeName, options) {
if (options) {
rejectInvalidOptions(
'removeColumnQuery',
this.dialect.name,
REMOVE_COLUMN_QUERY_SUPPORTABLE_OPTIONS,
REMOVE_COLUMN_QUERY_SUPPORTED_OPTIONS,
options,
);
}

return `ALTER TABLE ${this.quoteTable(tableName)} DROP COLUMN ${this.quoteIdentifier(attributeName)}`;
}

changeColumnQuery(tableName, attributes) {
const attrString = [];
const constraintString = [];
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/dialects/mariadb/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ export class MariaDbDialect extends AbstractDialect {
quoted: true,
},
globalTimeZoneConfig: true,
removeColumn: {
ifExists: true,
},
},
);

Expand Down
13 changes: 0 additions & 13 deletions packages/core/src/dialects/mariadb/query-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,6 @@ export class MariaDbQueryGenerator extends MariaDbQueryGeneratorTypeScript {
]);
}

removeColumnQuery(tableName, attributeName, options = {}) {
const ifExists = options.ifExists ? 'IF EXISTS' : '';

return joinSQLFragments([
'ALTER TABLE',
this.quoteTable(tableName),
'DROP',
ifExists,
this.quoteIdentifier(attributeName),
';',
]);
}

changeColumnQuery(tableName, attributes) {
const attrString = [];
const constraintString = [];
Expand Down
9 changes: 3 additions & 6 deletions packages/core/src/dialects/mariadb/query-interface.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use strict';

import { EMPTY_OBJECT, getObjectFromMap } from '../../utils/object';
import { getObjectFromMap } from '../../utils/object';
import { assertNoReservedBind, combineBinds } from '../../utils/sql';

const { AbstractQueryInterface } = require('../abstract/query-interface');
Expand All @@ -15,14 +15,11 @@ export class MariaDbQueryInterface extends AbstractQueryInterface {
*
* @override
*/
async removeColumn(tableName, columnName, options = EMPTY_OBJECT) {
async removeColumn(tableName, columnName, options) {
const foreignKeys = await this.showConstraints(tableName, { ...options, columnName, constraintType: 'FOREIGN KEY' });
await Promise.all(foreignKeys.map(constraint => this.removeConstraint(tableName, constraint.constraintName, options)));

return this.sequelize.queryRaw(
this.queryGenerator.removeColumnQuery(tableName, columnName),
{ raw: true, ...options },
);
await super.removeColumn(tableName, columnName, options);
}

/**
Expand Down
3 changes: 3 additions & 0 deletions packages/core/src/dialects/mssql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ export class MssqlDialect extends AbstractDialect {
quoted: false,
},
tableHints: true,
removeColumn: {
ifExists: true,
},
});

readonly connectionManager: MsSqlConnectionManager;
Expand Down
13 changes: 0 additions & 13 deletions packages/core/src/dialects/mssql/query-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,19 +271,6 @@ export class MsSqlQueryGenerator extends MsSqlQueryGeneratorTypeScript {
+ `@level2type = N'Column', @level2name = ${this.quoteIdentifier(column)};`;
}

removeColumnQuery(tableName, attributeName, options = {}) {
const ifExists = options.ifExists ? 'IF EXISTS' : '';

return joinSQLFragments([
'ALTER TABLE',
this.quoteTable(tableName),
'DROP COLUMN',
ifExists,
this.quoteIdentifier(attributeName),
';',
]);
}

changeColumnQuery(tableName, attributes) {
const attrString = [];
const constraintString = [];
Expand Down
15 changes: 4 additions & 11 deletions packages/core/src/dialects/mssql/query-interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,11 @@ export class MsSqlQueryInterface extends AbstractQueryInterface {
* @override
*/
async removeColumn(tableName, columnName, options) {
options = { raw: true, ...options };
const allConstraints = await this.showConstraints(tableName, { ...options, columnName });
const constraints = allConstraints.filter(constraint => ['DEFAULT', 'FOREIGN KEY', 'PRIMARY KEY'].includes(constraint.constraintType));
await Promise.all(constraints.map(constraint => this.removeConstraint(tableName, constraint.constraintName, options)));

const constraints = await this.showConstraints(tableName, { ...options, columnName });
for (const constraint of constraints) {
if (['DEFAULT', 'FOREIGN KEY', 'PRIMARY KEY'].includes(constraint.constraintType)) {
await this.removeConstraint(tableName, constraint.constraintName, options);
}
}

const removeSql = this.queryGenerator.removeColumnQuery(tableName, columnName);

return this.sequelize.queryRaw(removeSql, options);
await super.removeColumn(tableName, columnName, options);
}

/**
Expand Down

0 comments on commit bc35a52

Please sign in to comment.