Skip to content

Commit

Permalink
feat(sqlite): split SQLite from MySQL (#16201)
Browse files Browse the repository at this point in the history
  • Loading branch information
lohart13 committed Jul 1, 2023
1 parent be5161b commit 789b690
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 53 deletions.
13 changes: 11 additions & 2 deletions packages/core/src/dialects/sqlite/query-generator-typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ import { randomBytes } from 'node:crypto';
import { rejectInvalidOptions } from '../../utils/check';
import { joinSQLFragments } from '../../utils/join-sql-fragments';
import { generateIndexName } from '../../utils/string';
import { AbstractQueryGenerator } from '../abstract/query-generator';
import type { RemoveColumnQueryOptions } from '../abstract/query-generator';
import { REMOVE_INDEX_QUERY_SUPPORTABLE_OPTIONS } from '../abstract/query-generator-typescript';
import type { RemoveIndexQueryOptions, TableNameOrModel } from '../abstract/query-generator-typescript';
import type { ShowConstraintsQueryOptions } from '../abstract/query-generator.types';
import type { ColumnsDescription } from '../abstract/query-interface.types';
import { MySqlQueryGenerator } from '../mysql/query-generator';

const REMOVE_INDEX_QUERY_SUPPORTED_OPTIONS = new Set<keyof RemoveIndexQueryOptions>(['ifExists']);

/**
* Temporary class to ease the TypeScript migration
*/
export class SqliteQueryGeneratorTypeScript extends MySqlQueryGenerator {
export class SqliteQueryGeneratorTypeScript extends AbstractQueryGenerator {
createSchemaQuery(): string {
throw new Error(`Schemas are not supported in ${this.dialect.name}.`);
}
Expand Down Expand Up @@ -49,6 +50,14 @@ export class SqliteQueryGeneratorTypeScript extends MySqlQueryGenerator {
return `PRAGMA foreign_keys = ${enable ? 'ON' : 'OFF'}`;
}

dropForeignKeyQuery(_tableName: TableNameOrModel, _foreignKey: string): string {
throw new Error(`dropForeignKeyQuery is not supported in ${this.dialect.name}.`);
}

removeColumnQuery(_table: TableNameOrModel, _attributeName: string, _options?: RemoveColumnQueryOptions): string {
throw new Error(`removeColumnQuery is not supported in ${this.dialect.name}.`);
}

removeIndexQuery(
tableName: TableNameOrModel,
indexNameOrAttributes: string | string[],
Expand Down
40 changes: 1 addition & 39 deletions packages/core/src/dialects/sqlite/query-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,13 @@ import { removeNullishValuesFromHash } from '../../utils/format';
import { EMPTY_OBJECT } from '../../utils/object.js';
import { defaultValueSchemable } from '../../utils/query-builder-utils';
import { rejectInvalidOptions } from '../../utils/check';
import {
ADD_COLUMN_QUERY_SUPPORTABLE_OPTIONS,
CREATE_TABLE_QUERY_SUPPORTABLE_OPTIONS,
REMOVE_COLUMN_QUERY_SUPPORTABLE_OPTIONS,
} from '../abstract/query-generator';
import { ADD_COLUMN_QUERY_SUPPORTABLE_OPTIONS, CREATE_TABLE_QUERY_SUPPORTABLE_OPTIONS } from '../abstract/query-generator';

const { Transaction } = require('../../transaction');
const _ = require('lodash');
const { SqliteQueryGeneratorTypeScript } = require('./query-generator-typescript');

const ADD_COLUMN_QUERY_SUPPORTED_OPTIONS = new Set();
const REMOVE_COLUMN_QUERY_SUPPORTED_OPTIONS = new Set();
// TODO: add support for 'uniqueKeys' by improving the createTableQuery implementation so it also generates a CREATE UNIQUE INDEX query
const CREATE_TABLE_QUERY_SUPPORTED_OPTIONS = new Set();

Expand Down Expand Up @@ -276,39 +271,6 @@ export class SqliteQueryGenerator extends SqliteQueryGeneratorTypeScript {
return result;
}

// TODO: this should not implement `removeColumnQuery` but a new sqlite specific function possibly called `replaceTableQuery`
removeColumnQuery(tableName, attributes, options) {
if (options) {
rejectInvalidOptions(
'removeColumnQuery',
this.dialect.name,
REMOVE_COLUMN_QUERY_SUPPORTABLE_OPTIONS,
REMOVE_COLUMN_QUERY_SUPPORTED_OPTIONS,
options,
);
}

attributes = this.attributesToSQL(attributes);

const table = this.extractTableDetails(tableName);

// TODO: this is unsafe, this table could already exist
const backupTableName = {
tableName: `${table.tableName}_backup`,
schema: table.schema,
delimiter: table.delimiter,
};

const quotedTableName = this.quoteTable(tableName);
const quotedBackupTableName = this.quoteTable(backupTableName);
const attributeNames = Object.keys(attributes).map(attr => this.quoteIdentifier(attr)).join(', ');

return `${this.createTableQuery(backupTableName, attributes)}`
+ `INSERT INTO ${quotedBackupTableName} SELECT ${attributeNames} FROM ${quotedTableName};`
+ `DROP TABLE ${quotedTableName};`
+ `ALTER TABLE ${quotedBackupTableName} RENAME TO ${quotedTableName};`;
}

renameColumnQuery(tableName, attrNameBefore, attrNameAfter, attributes) {

let backupTableName;
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/dialects/sqlite/query-interface.d.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Sequelize } from '../../sequelize.js';
import { AbstractQueryInterface } from '../abstract/query-interface.js';
import type { SqliteQueryGenerator } from './query-generator.js';
import { SqliteQueryInterfaceTypeScript } from './query-interface-typescript.js';

export class SqliteQueryInterface extends AbstractQueryInterface {
export class SqliteQueryInterface extends SqliteQueryInterfaceTypeScript {
queryGenerator: SqliteQueryGenerator;

constructor(sequelize: Sequelize, queryGenerator: SqliteQueryGenerator);
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/dialects/sqlite/query-interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ export class SqliteQueryInterface extends SqliteQueryInterfaceTypeScript {
}
}

const sql = this.queryGenerator.removeColumnQuery(tableName, columns);
const sql = this.queryGenerator._replaceTableQuery(tableName, columns);
const subQueries = sql.split(';').filter(q => q !== '');

for (const subQuery of subQueries) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createSequelizeInstance, expectsql, sequelize } from '../../support';

const dialect = sequelize.dialect;
const notSupportedError = new Error(`dropForeignKeyQuery is not supported in ${dialect.name}.`);

describe('QueryGenerator#dropForeignKeyQuery', () => {
const queryGenerator = sequelize.getQueryInterface().queryGenerator;
Expand All @@ -10,6 +11,7 @@ describe('QueryGenerator#dropForeignKeyQuery', () => {
default: 'ALTER TABLE [myTable] DROP FOREIGN KEY [myColumnKey];',
postgres: 'ALTER TABLE "myTable" DROP CONSTRAINT "myColumnKey";',
mssql: 'ALTER TABLE [myTable] DROP [myColumnKey]',
sqlite: notSupportedError,
});
});

Expand All @@ -20,6 +22,7 @@ describe('QueryGenerator#dropForeignKeyQuery', () => {
default: 'ALTER TABLE [MyModels] DROP FOREIGN KEY [myColumnKey];',
postgres: 'ALTER TABLE "MyModels" DROP CONSTRAINT "myColumnKey";',
mssql: 'ALTER TABLE [MyModels] DROP [myColumnKey]',
sqlite: notSupportedError,
});
});

Expand All @@ -28,7 +31,7 @@ describe('QueryGenerator#dropForeignKeyQuery', () => {
default: 'ALTER TABLE [mySchema].[myTable] DROP FOREIGN KEY [myColumnKey];',
postgres: 'ALTER TABLE "mySchema"."myTable" DROP CONSTRAINT "myColumnKey";',
mssql: 'ALTER TABLE [mySchema].[myTable] DROP [myColumnKey]',
sqlite: 'ALTER TABLE `mySchema.myTable` DROP FOREIGN KEY `myColumnKey`;',
sqlite: notSupportedError,
});
});

Expand All @@ -37,6 +40,7 @@ describe('QueryGenerator#dropForeignKeyQuery', () => {
default: 'ALTER TABLE [myTable] DROP FOREIGN KEY [myColumnKey];',
postgres: 'ALTER TABLE "myTable" DROP CONSTRAINT "myColumnKey";',
mssql: 'ALTER TABLE [myTable] DROP [myColumnKey]',
sqlite: notSupportedError,
});
});

Expand All @@ -48,7 +52,7 @@ describe('QueryGenerator#dropForeignKeyQuery', () => {
default: 'ALTER TABLE [mySchema].[myTable] DROP FOREIGN KEY [myColumnKey];',
postgres: 'ALTER TABLE "mySchema"."myTable" DROP CONSTRAINT "myColumnKey";',
mssql: 'ALTER TABLE [mySchema].[myTable] DROP [myColumnKey]',
sqlite: 'ALTER TABLE `mySchema.myTable` DROP FOREIGN KEY `myColumnKey`;',
sqlite: notSupportedError,
});
});

Expand All @@ -59,7 +63,7 @@ describe('QueryGenerator#dropForeignKeyQuery', () => {
}

expectsql(() => queryGenerator.dropForeignKeyQuery({ tableName: 'myTable', schema: 'mySchema', delimiter: 'custom' }, 'myColumnKey'), {
sqlite: 'ALTER TABLE `mySchemacustommyTable` DROP FOREIGN KEY `myColumnKey`;',
sqlite: notSupportedError,
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { createSequelizeInstance, expectsql, getTestDialect, sequelize } from '.

const dialect = sequelize.dialect;
const dialectName = getTestDialect();
const notSupportedError = new Error(`removeColumnQuery is not supported in ${dialectName}.`);

describe('QueryGenerator#removeColumnQuery', () => {
const queryGenerator = sequelize.getQueryInterface().queryGenerator;
Expand All @@ -11,7 +12,7 @@ describe('QueryGenerator#removeColumnQuery', () => {
expectsql(() => queryGenerator.removeColumnQuery('myTable', 'myColumn'), {
default: 'ALTER TABLE [myTable] DROP COLUMN [myColumn];',
'mariadb mysql snowflake': 'ALTER TABLE [myTable] DROP [myColumn];',
sqlite: 'CREATE TABLE IF NOT EXISTS `myTable_backup` (`0` m, `1` y, `2` C, `3` o, `4` l, `5` u, `6` m, `7` n);INSERT INTO `myTable_backup` SELECT `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7` FROM `myTable`;DROP TABLE `myTable`;ALTER TABLE `myTable_backup` RENAME TO `myTable`;',
sqlite: notSupportedError,
});
});

Expand All @@ -20,6 +21,7 @@ describe('QueryGenerator#removeColumnQuery', () => {
default: buildInvalidOptionReceivedError('removeColumnQuery', dialectName, ['ifExists']),
mariadb: 'ALTER TABLE `myTable` DROP IF EXISTS `myColumn`;',
'postgres mssql': 'ALTER TABLE [myTable] DROP COLUMN IF EXISTS [myColumn];',
sqlite: notSupportedError,
});
});

Expand All @@ -29,23 +31,23 @@ describe('QueryGenerator#removeColumnQuery', () => {
expectsql(() => queryGenerator.removeColumnQuery(MyModel, 'myColumn'), {
default: 'ALTER TABLE [MyModels] DROP COLUMN [myColumn];',
'mariadb mysql snowflake': 'ALTER TABLE [MyModels] DROP [myColumn];',
sqlite: 'CREATE TABLE IF NOT EXISTS `MyModels_backup` (`0` m, `1` y, `2` C, `3` o, `4` l, `5` u, `6` m, `7` n);INSERT INTO `MyModels_backup` SELECT `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7` FROM `MyModels`;DROP TABLE `MyModels`;ALTER TABLE `MyModels_backup` RENAME TO `MyModels`;',
sqlite: notSupportedError,
});
});

it('generates a query that drops a column with schema', () => {
expectsql(() => queryGenerator.removeColumnQuery({ tableName: 'myTable', schema: 'mySchema' }, 'myColumn'), {
default: 'ALTER TABLE [mySchema].[myTable] DROP COLUMN [myColumn];',
'mariadb mysql snowflake': 'ALTER TABLE [mySchema].[myTable] DROP [myColumn];',
sqlite: 'CREATE TABLE IF NOT EXISTS `mySchema.myTable_backup` (`0` m, `1` y, `2` C, `3` o, `4` l, `5` u, `6` m, `7` n);INSERT INTO `mySchema.myTable_backup` SELECT `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7` FROM `mySchema.myTable`;DROP TABLE `mySchema.myTable`;ALTER TABLE `mySchema.myTable_backup` RENAME TO `mySchema.myTable`;',
sqlite: notSupportedError,
});
});

it('generates a query that drops a column with default schema', () => {
expectsql(() => queryGenerator.removeColumnQuery({ tableName: 'myTable', schema: dialect.getDefaultSchema() }, 'myColumn'), {
default: 'ALTER TABLE [myTable] DROP COLUMN [myColumn];',
'mariadb mysql snowflake': 'ALTER TABLE [myTable] DROP [myColumn];',
sqlite: 'CREATE TABLE IF NOT EXISTS `myTable_backup` (`0` m, `1` y, `2` C, `3` o, `4` l, `5` u, `6` m, `7` n);INSERT INTO `myTable_backup` SELECT `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7` FROM `myTable`;DROP TABLE `myTable`;ALTER TABLE `myTable_backup` RENAME TO `myTable`;',
sqlite: notSupportedError,
});
});

Expand All @@ -56,7 +58,7 @@ describe('QueryGenerator#removeColumnQuery', () => {
expectsql(() => queryGeneratorSchema.removeColumnQuery('myTable', 'myColumn'), {
default: 'ALTER TABLE [mySchema].[myTable] DROP COLUMN [myColumn];',
'mariadb mysql snowflake': 'ALTER TABLE [mySchema].[myTable] DROP [myColumn];',
sqlite: 'CREATE TABLE IF NOT EXISTS `mySchema.myTable_backup` (`0` m, `1` y, `2` C, `3` o, `4` l, `5` u, `6` m, `7` n);INSERT INTO `mySchema.myTable_backup` SELECT `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7` FROM `mySchema.myTable`;DROP TABLE `mySchema.myTable`;ALTER TABLE `mySchema.myTable_backup` RENAME TO `mySchema.myTable`;',
sqlite: notSupportedError,
});
});

Expand All @@ -67,7 +69,7 @@ describe('QueryGenerator#removeColumnQuery', () => {
}

expectsql(() => queryGenerator.removeColumnQuery({ tableName: 'myTable', schema: 'mySchema', delimiter: 'custom' }, 'myColumn'), {
sqlite: 'CREATE TABLE IF NOT EXISTS `mySchemacustommyTable_backup` (`0` m, `1` y, `2` C, `3` o, `4` l, `5` u, `6` m, `7` n);INSERT INTO `mySchemacustommyTable_backup` SELECT `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7` FROM `mySchemacustommyTable`;DROP TABLE `mySchemacustommyTable`;ALTER TABLE `mySchemacustommyTable_backup` RENAME TO `mySchemacustommyTable`;',
sqlite: notSupportedError,
});
});
});

0 comments on commit 789b690

Please sign in to comment.