fixed query runner small issues, and added renameColumn method

This commit is contained in:
Umed Khudoiberdiev 2016-12-12 13:57:54 +05:00
parent 7c3abca2f8
commit 502c30e61e
9 changed files with 503 additions and 26 deletions

View File

@ -5,11 +5,15 @@ import {QueryRunner} from "../../../src/query-runner/QueryRunner";
export class FirstReleaseMigration1481283582 implements MigrationInterface {
async up(queryRunner: QueryRunner, connection: Connection): Promise<any> {
await queryRunner.query("ALTER TABLE `post` CHANGE `title` `name` VARCHAR(255)");
await queryRunner.renameColumn("post", "title", "name");
// alternatively you can do:
// await queryRunner.query("ALTER TABLE `post` CHANGE `title` `name` VARCHAR(255)");
}
async down(queryRunner: QueryRunner, connection: Connection): Promise<any> {
await queryRunner.query("ALTER TABLE `post` CHANGE `name` `title` VARCHAR(255)");
await queryRunner.renameColumn("post", "name", "title");
// alternatively you can do:
// await queryRunner.query("ALTER TABLE `post` CHANGE `name` `title` VARCHAR(255)");
}
}

View File

@ -257,7 +257,8 @@ export class MysqlQueryRunner implements QueryRunner {
return [];
// load tables, columns, indices and foreign keys
const tablesSql = `SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '${this.dbName}'`;
const tableNamesString = tableNames.map(tableName => `'${tableName}'`).join(", ");
const tablesSql = `SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '${this.dbName}' AND TABLE_NAME IN (${tableNamesString})`;
const columnsSql = `SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '${this.dbName}'`;
const indicesSql = `SELECT * FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = '${this.dbName}' AND INDEX_NAME != 'PRIMARY'`;
const foreignKeysSql = `SELECT * FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA = '${this.dbName}' AND REFERENCED_COLUMN_NAME IS NOT NULL`;
@ -411,13 +412,89 @@ export class MysqlQueryRunner implements QueryRunner {
await Promise.all(queries);
}
/**
* Renames column in the given table.
*/
renameColumn(table: TableSchema, oldColumn: ColumnSchema, newColumn: ColumnSchema): Promise<void>;
/**
* Renames column in the given table.
*/
renameColumn(tableName: string, oldColumnName: string, newColumnName: string): Promise<void>;
/**
* Renames column in the given table.
*/
async renameColumn(tableSchemaOrName: TableSchema|string, oldColumnSchemaOrName: ColumnSchema|string, newColumnSchemaOrName: ColumnSchema|string): Promise<void> {
let tableSchema: TableSchema|undefined = undefined;
if (tableSchemaOrName instanceof TableSchema) {
tableSchema = tableSchemaOrName;
} else {
tableSchema = await this.loadTableSchema(tableSchemaOrName);
}
if (!tableSchema)
throw new Error(`Table ${tableSchemaOrName} was not found.`);
let oldColumn: ColumnSchema|undefined = undefined;
if (oldColumnSchemaOrName instanceof ColumnSchema) {
oldColumn = oldColumnSchemaOrName;
} else {
oldColumn = tableSchema.columns.find(column => column.name === oldColumnSchemaOrName);
}
if (!oldColumn)
throw new Error(`Column "${oldColumnSchemaOrName}" was not found in the "${tableSchemaOrName}" table.`);
let newColumn: ColumnSchema|undefined = undefined;
if (newColumnSchemaOrName instanceof ColumnSchema) {
newColumn = newColumnSchemaOrName;
} else {
newColumn = oldColumn.clone();
newColumn.name = newColumnSchemaOrName;
}
return this.changeColumn(tableSchema, newColumn, oldColumn);
}
/**
* Changes a column in the table.
*/
async changeColumn(tableSchema: TableSchema, newColumn: ColumnSchema, oldColumn: ColumnSchema): Promise<void> {
changeColumn(tableSchema: TableSchema, oldColumn: ColumnSchema, newColumn: ColumnSchema): Promise<void>;
/**
* Changes a column in the table.
*/
changeColumn(tableSchema: string, oldColumn: string, newColumn: ColumnSchema): Promise<void>;
/**
* Changes a column in the table.
*/
async changeColumn(tableSchemaOrName: TableSchema|string, oldColumnSchemaOrName: ColumnSchema|string, newColumn: ColumnSchema): Promise<void> {
if (this.isReleased)
throw new QueryRunnerAlreadyReleasedError();
let tableSchema: TableSchema|undefined = undefined;
if (tableSchemaOrName instanceof TableSchema) {
tableSchema = tableSchemaOrName;
} else {
tableSchema = await this.loadTableSchema(tableSchemaOrName);
}
if (!tableSchema)
throw new Error(`Table ${tableSchemaOrName} was not found.`);
let oldColumn: ColumnSchema|undefined = undefined;
if (oldColumnSchemaOrName instanceof ColumnSchema) {
oldColumn = oldColumnSchemaOrName;
} else {
oldColumn = tableSchema.columns.find(column => column.name === oldColumnSchemaOrName);
}
if (!oldColumn)
throw new Error(`Column "${oldColumnSchemaOrName}" was not found in the "${tableSchemaOrName}" table.`);
if (newColumn.isUnique === false && oldColumn.isUnique === true)
await this.query(`ALTER TABLE \`${tableSchema.name}\` DROP INDEX \`${oldColumn.name}\``);
@ -432,7 +509,7 @@ export class MysqlQueryRunner implements QueryRunner {
throw new QueryRunnerAlreadyReleasedError();
const updatePromises = changedColumns.map(async changedColumn => {
return this.changeColumn(tableSchema, changedColumn.newColumn, changedColumn.oldColumn);
return this.changeColumn(tableSchema, changedColumn.oldColumn, changedColumn.newColumn);
});
await Promise.all(updatePromises);

View File

@ -442,13 +442,89 @@ AND cons.constraint_name = cols.constraint_name AND cons.owner = cols.owner ORDE
await Promise.all(queries);
}
/**
* Renames column in the given table.
*/
renameColumn(table: TableSchema, oldColumn: ColumnSchema, newColumn: ColumnSchema): Promise<void>;
/**
* Renames column in the given table.
*/
renameColumn(tableName: string, oldColumnName: string, newColumnName: string): Promise<void>;
/**
* Renames column in the given table.
*/
async renameColumn(tableSchemaOrName: TableSchema|string, oldColumnSchemaOrName: ColumnSchema|string, newColumnSchemaOrName: ColumnSchema|string): Promise<void> {
let tableSchema: TableSchema|undefined = undefined;
if (tableSchemaOrName instanceof TableSchema) {
tableSchema = tableSchemaOrName;
} else {
tableSchema = await this.loadTableSchema(tableSchemaOrName);
}
if (!tableSchema)
throw new Error(`Table ${tableSchemaOrName} was not found.`);
let oldColumn: ColumnSchema|undefined = undefined;
if (oldColumnSchemaOrName instanceof ColumnSchema) {
oldColumn = oldColumnSchemaOrName;
} else {
oldColumn = tableSchema.columns.find(column => column.name === oldColumnSchemaOrName);
}
if (!oldColumn)
throw new Error(`Column "${oldColumnSchemaOrName}" was not found in the "${tableSchemaOrName}" table.`);
let newColumn: ColumnSchema|undefined = undefined;
if (newColumnSchemaOrName instanceof ColumnSchema) {
newColumn = newColumnSchemaOrName;
} else {
newColumn = oldColumn.clone();
newColumn.name = newColumnSchemaOrName;
}
return this.changeColumn(tableSchema, newColumn, oldColumn);
}
/**
* Changes a column in the table.
*/
async changeColumn(tableSchema: TableSchema, newColumn: ColumnSchema, oldColumn: ColumnSchema): Promise<void> {
changeColumn(tableSchema: TableSchema, oldColumn: ColumnSchema, newColumn: ColumnSchema): Promise<void>;
/**
* Changes a column in the table.
*/
changeColumn(tableSchema: string, oldColumn: string, newColumn: ColumnSchema): Promise<void>;
/**
* Changes a column in the table.
*/
async changeColumn(tableSchemaOrName: TableSchema|string, oldColumnSchemaOrName: ColumnSchema|string, newColumn: ColumnSchema): Promise<void> {
if (this.isReleased)
throw new QueryRunnerAlreadyReleasedError();
let tableSchema: TableSchema|undefined = undefined;
if (tableSchemaOrName instanceof TableSchema) {
tableSchema = tableSchemaOrName;
} else {
tableSchema = await this.loadTableSchema(tableSchemaOrName);
}
if (!tableSchema)
throw new Error(`Table ${tableSchemaOrName} was not found.`);
let oldColumn: ColumnSchema|undefined = undefined;
if (oldColumnSchemaOrName instanceof ColumnSchema) {
oldColumn = oldColumnSchemaOrName;
} else {
oldColumn = tableSchema.columns.find(column => column.name === oldColumnSchemaOrName);
}
if (!oldColumn)
throw new Error(`Column "${oldColumnSchemaOrName}" was not found in the "${tableSchemaOrName}" table.`);
if (newColumn.isGenerated !== oldColumn.isGenerated) {
if (newColumn.isGenerated) {
@ -489,7 +565,7 @@ AND cons.constraint_name = cols.constraint_name AND cons.owner = cols.owner ORDE
if (this.isReleased)
throw new QueryRunnerAlreadyReleasedError();
const updatePromises = changedColumns.map(async changedColumn => this.changeColumn(tableSchema, changedColumn.newColumn, changedColumn.oldColumn));
const updatePromises = changedColumns.map(async changedColumn => this.changeColumn(tableSchema, changedColumn.oldColumn, changedColumn.newColumn));
await Promise.all(updatePromises);
}

View File

@ -254,7 +254,7 @@ export class PostgresQueryRunner implements QueryRunner {
// load tables, columns, indices and foreign keys
const tableNamesString = tableNames.map(name => "'" + name + "'").join(", ");
const tablesSql = `SELECT * FROM information_schema.tables WHERE table_catalog = '${this.dbName}' AND table_schema = 'public'`;
const tablesSql = `SELECT * FROM information_schema.tables WHERE table_catalog = '${this.dbName}' AND table_schema = 'public' AND table_name IN (${tableNamesString})`;
const columnsSql = `SELECT * FROM information_schema.columns WHERE table_catalog = '${this.dbName}' AND table_schema = 'public'`;
const indicesSql = `SELECT t.relname AS table_name, i.relname AS index_name, a.attname AS column_name FROM pg_class t, pg_class i, pg_index ix, pg_attribute a
WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid
@ -421,13 +421,89 @@ where constraint_type = 'PRIMARY KEY' and tc.table_catalog = '${this.dbName}'`;
await Promise.all(queries);
}
/**
* Renames column in the given table.
*/
renameColumn(table: TableSchema, oldColumn: ColumnSchema, newColumn: ColumnSchema): Promise<void>;
/**
* Renames column in the given table.
*/
renameColumn(tableName: string, oldColumnName: string, newColumnName: string): Promise<void>;
/**
* Renames column in the given table.
*/
async renameColumn(tableSchemaOrName: TableSchema|string, oldColumnSchemaOrName: ColumnSchema|string, newColumnSchemaOrName: ColumnSchema|string): Promise<void> {
let tableSchema: TableSchema|undefined = undefined;
if (tableSchemaOrName instanceof TableSchema) {
tableSchema = tableSchemaOrName;
} else {
tableSchema = await this.loadTableSchema(tableSchemaOrName);
}
if (!tableSchema)
throw new Error(`Table ${tableSchemaOrName} was not found.`);
let oldColumn: ColumnSchema|undefined = undefined;
if (oldColumnSchemaOrName instanceof ColumnSchema) {
oldColumn = oldColumnSchemaOrName;
} else {
oldColumn = tableSchema.columns.find(column => column.name === oldColumnSchemaOrName);
}
if (!oldColumn)
throw new Error(`Column "${oldColumnSchemaOrName}" was not found in the "${tableSchemaOrName}" table.`);
let newColumn: ColumnSchema|undefined = undefined;
if (newColumnSchemaOrName instanceof ColumnSchema) {
newColumn = newColumnSchemaOrName;
} else {
newColumn = oldColumn.clone();
newColumn.name = newColumnSchemaOrName;
}
return this.changeColumn(tableSchema, newColumn, oldColumn);
}
/**
* Changes a column in the table.
*/
async changeColumn(tableSchema: TableSchema, newColumn: ColumnSchema, oldColumn: ColumnSchema): Promise<void> {
changeColumn(tableSchema: TableSchema, oldColumn: ColumnSchema, newColumn: ColumnSchema): Promise<void>;
/**
* Changes a column in the table.
*/
changeColumn(tableSchema: string, oldColumn: string, newColumn: ColumnSchema): Promise<void>;
/**
* Changes a column in the table.
*/
async changeColumn(tableSchemaOrName: TableSchema|string, oldColumnSchemaOrName: ColumnSchema|string, newColumn: ColumnSchema): Promise<void> {
if (this.isReleased)
throw new QueryRunnerAlreadyReleasedError();
let tableSchema: TableSchema|undefined = undefined;
if (tableSchemaOrName instanceof TableSchema) {
tableSchema = tableSchemaOrName;
} else {
tableSchema = await this.loadTableSchema(tableSchemaOrName);
}
if (!tableSchema)
throw new Error(`Table ${tableSchemaOrName} was not found.`);
let oldColumn: ColumnSchema|undefined = undefined;
if (oldColumnSchemaOrName instanceof ColumnSchema) {
oldColumn = oldColumnSchemaOrName;
} else {
oldColumn = tableSchema.columns.find(column => column.name === oldColumnSchemaOrName);
}
if (!oldColumn)
throw new Error(`Column "${oldColumnSchemaOrName}" was not found in the "${tableSchemaOrName}" table.`);
if (oldColumn.type !== newColumn.type ||
oldColumn.name !== newColumn.name) {
@ -485,7 +561,7 @@ where constraint_type = 'PRIMARY KEY' and tc.table_catalog = '${this.dbName}'`;
throw new QueryRunnerAlreadyReleasedError();
const updatePromises = changedColumns.map(async changedColumn => {
return this.changeColumn(tableSchema, changedColumn.newColumn, changedColumn.oldColumn);
return this.changeColumn(tableSchema, changedColumn.oldColumn, changedColumn.newColumn);
});
await Promise.all(updatePromises);

View File

@ -92,7 +92,7 @@ export class SqliteDriver implements Driver {
// we need to enable foreign keys in sqlite to make sure all foreign key related features
// working properly. this also makes onDelete to work with sqlite.
connection.executePendingMigrations(`PRAGMA foreign_keys = ON;`, (err: any, result: any) => {
connection.run(`PRAGMA foreign_keys = ON;`, (err: any, result: any) => {
ok();
});
});

View File

@ -168,7 +168,7 @@ export class SqliteQueryRunner implements QueryRunner {
this.logger.logQuery(sql, parameters);
return new Promise<any[]>((ok, fail) => {
const __this = this;
this.databaseConnection.connection.executePendingMigrations(sql, parameters, function (err: any): void {
this.databaseConnection.connection.run(sql, parameters, function (err: any): void {
if (err) {
__this.logger.logFailedQuery(sql, parameters);
__this.logger.logQueryError(err);
@ -265,8 +265,10 @@ export class SqliteQueryRunner implements QueryRunner {
if (!tableNames || !tableNames.length)
return [];
const tableNamesString = tableNames.map(tableName => `'${tableName}'`).join(", ");
// load tables, columns, indices and foreign keys
const dbTables: ObjectLiteral[] = await this.query(`SELECT * FROM sqlite_master WHERE type = 'table' AND name != 'sqlite_sequence'`);
const dbTables: ObjectLiteral[] = await this.query(`SELECT * FROM sqlite_master WHERE type = 'table' AND name IN (${tableNamesString})`);
// if tables were not found in the db, no need to proceed
if (!dbTables || !dbTables.length)
@ -454,13 +456,88 @@ export class SqliteQueryRunner implements QueryRunner {
}
/**
* Changes a column in the table.
* Changed column looses all its keys in the db.
* Renames column in the given table.
*/
async changeColumn(tableSchema: TableSchema, newColumn: ColumnSchema, oldColumn: ColumnSchema): Promise<void> {
renameColumn(table: TableSchema, oldColumn: ColumnSchema, newColumn: ColumnSchema): Promise<void>;
/**
* Renames column in the given table.
*/
renameColumn(tableName: string, oldColumnName: string, newColumnName: string): Promise<void>;
/**
* Renames column in the given table.
*/
async renameColumn(tableSchemaOrName: TableSchema|string, oldColumnSchemaOrName: ColumnSchema|string, newColumnSchemaOrName: ColumnSchema|string): Promise<void> {
let tableSchema: TableSchema|undefined = undefined;
if (tableSchemaOrName instanceof TableSchema) {
tableSchema = tableSchemaOrName;
} else {
tableSchema = await this.loadTableSchema(tableSchemaOrName);
}
if (!tableSchema)
throw new Error(`Table ${tableSchemaOrName} was not found.`);
let oldColumn: ColumnSchema|undefined = undefined;
if (oldColumnSchemaOrName instanceof ColumnSchema) {
oldColumn = oldColumnSchemaOrName;
} else {
oldColumn = tableSchema.columns.find(column => column.name === oldColumnSchemaOrName);
}
if (!oldColumn)
throw new Error(`Column "${oldColumnSchemaOrName}" was not found in the "${tableSchemaOrName}" table.`);
let newColumn: ColumnSchema|undefined = undefined;
if (newColumnSchemaOrName instanceof ColumnSchema) {
newColumn = newColumnSchemaOrName;
} else {
newColumn = oldColumn.clone();
newColumn.name = newColumnSchemaOrName;
}
return this.changeColumn(tableSchema, newColumn, oldColumn);
}
/**
* Changes a column in the table.
*/
changeColumn(tableSchema: TableSchema, oldColumn: ColumnSchema, newColumn: ColumnSchema): Promise<void>;
/**
* Changes a column in the table.
*/
changeColumn(tableSchema: string, oldColumn: string, newColumn: ColumnSchema): Promise<void>;
/**
* Changes a column in the table.
*/
async changeColumn(tableSchemaOrName: TableSchema|string, oldColumnSchemaOrName: ColumnSchema|string, newColumn: ColumnSchema): Promise<void> {
if (this.isReleased)
throw new QueryRunnerAlreadyReleasedError();
let tableSchema: TableSchema|undefined = undefined;
if (tableSchemaOrName instanceof TableSchema) {
tableSchema = tableSchemaOrName;
} else {
tableSchema = await this.loadTableSchema(tableSchemaOrName);
}
if (!tableSchema)
throw new Error(`Table ${tableSchemaOrName} was not found.`);
let oldColumn: ColumnSchema|undefined = undefined;
if (oldColumnSchemaOrName instanceof ColumnSchema) {
oldColumn = oldColumnSchemaOrName;
} else {
oldColumn = tableSchema.columns.find(column => column.name === oldColumnSchemaOrName);
}
if (!oldColumn)
throw new Error(`Column "${oldColumnSchemaOrName}" was not found in the "${tableSchemaOrName}" table.`);
// todo: fix it. it should not depend on tableSchema
return this.recreateTable(tableSchema);
}

View File

@ -319,7 +319,8 @@ export class SqlServerQueryRunner implements QueryRunner {
return [];
// load tables, columns, indices and foreign keys
const tablesSql = `SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_CATALOG = '${this.dbName}'`;
const tableNamesString = tableNames.map(tableName => `'${tableName}'`).join(", ");
const tablesSql = `SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_CATALOG = '${this.dbName}' AND TABLE_NAME IN (${tableNamesString})`;
const columnsSql = `SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_CATALOG = '${this.dbName}'`;
const constraintsSql = `SELECT columnUsages.*, tableConstraints.CONSTRAINT_TYPE FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE columnUsages ` +
`LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tableConstraints ON tableConstraints.CONSTRAINT_NAME = columnUsages.CONSTRAINT_NAME ` +
@ -496,13 +497,89 @@ export class SqlServerQueryRunner implements QueryRunner {
await Promise.all(queries);
}
/**
* Renames column in the given table.
*/
renameColumn(table: TableSchema, oldColumn: ColumnSchema, newColumn: ColumnSchema): Promise<void>;
/**
* Renames column in the given table.
*/
renameColumn(tableName: string, oldColumnName: string, newColumnName: string): Promise<void>;
/**
* Renames column in the given table.
*/
async renameColumn(tableSchemaOrName: TableSchema|string, oldColumnSchemaOrName: ColumnSchema|string, newColumnSchemaOrName: ColumnSchema|string): Promise<void> {
let tableSchema: TableSchema|undefined = undefined;
if (tableSchemaOrName instanceof TableSchema) {
tableSchema = tableSchemaOrName;
} else {
tableSchema = await this.loadTableSchema(tableSchemaOrName);
}
if (!tableSchema)
throw new Error(`Table ${tableSchemaOrName} was not found.`);
let oldColumn: ColumnSchema|undefined = undefined;
if (oldColumnSchemaOrName instanceof ColumnSchema) {
oldColumn = oldColumnSchemaOrName;
} else {
oldColumn = tableSchema.columns.find(column => column.name === oldColumnSchemaOrName);
}
if (!oldColumn)
throw new Error(`Column "${oldColumnSchemaOrName}" was not found in the "${tableSchemaOrName}" table.`);
let newColumn: ColumnSchema|undefined = undefined;
if (newColumnSchemaOrName instanceof ColumnSchema) {
newColumn = newColumnSchemaOrName;
} else {
newColumn = oldColumn.clone();
newColumn.name = newColumnSchemaOrName;
}
return this.changeColumn(tableSchema, newColumn, oldColumn);
}
/**
* Changes a column in the table.
*/
async changeColumn(tableSchema: TableSchema, newColumn: ColumnSchema, oldColumn: ColumnSchema): Promise<void> {
changeColumn(tableSchema: TableSchema, oldColumn: ColumnSchema, newColumn: ColumnSchema): Promise<void>;
/**
* Changes a column in the table.
*/
changeColumn(tableSchema: string, oldColumn: string, newColumn: ColumnSchema): Promise<void>;
/**
* Changes a column in the table.
*/
async changeColumn(tableSchemaOrName: TableSchema|string, oldColumnSchemaOrName: ColumnSchema|string, newColumn: ColumnSchema): Promise<void> {
if (this.isReleased)
throw new QueryRunnerAlreadyReleasedError();
let tableSchema: TableSchema|undefined = undefined;
if (tableSchemaOrName instanceof TableSchema) {
tableSchema = tableSchemaOrName;
} else {
tableSchema = await this.loadTableSchema(tableSchemaOrName);
}
if (!tableSchema)
throw new Error(`Table ${tableSchemaOrName} was not found.`);
let oldColumn: ColumnSchema|undefined = undefined;
if (oldColumnSchemaOrName instanceof ColumnSchema) {
oldColumn = oldColumnSchemaOrName;
} else {
oldColumn = tableSchema.columns.find(column => column.name === oldColumnSchemaOrName);
}
if (!oldColumn)
throw new Error(`Column "${oldColumnSchemaOrName}" was not found in the "${tableSchemaOrName}" table.`);
// to update an identy column we have to drop column and recreate it again
if (newColumn.isGenerated !== oldColumn.isGenerated) {
await this.query(`ALTER TABLE "${tableSchema.name}" DROP COLUMN "${newColumn.name}"`);
@ -531,7 +608,7 @@ export class SqlServerQueryRunner implements QueryRunner {
throw new QueryRunnerAlreadyReleasedError();
const updatePromises = changedColumns.map(async changedColumn => {
return this.changeColumn(tableSchema, changedColumn.newColumn, changedColumn.oldColumn);
return this.changeColumn(tableSchema, changedColumn.oldColumn, changedColumn.newColumn);
});
await Promise.all(updatePromises);

View File

@ -274,8 +274,10 @@ export class WebsqlQueryRunner implements QueryRunner {
if (!tableNames || !tableNames.length)
return [];
const tableNamesString = tableNames.map(tableName => `'${tableName}'`).join(", ");
// load tables, columns, indices and foreign keys
const dbTables: ObjectLiteral[] = await this.query(`SELECT * FROM sqlite_master WHERE type = 'table' AND name != 'sqlite_sequence'`);
const dbTables: ObjectLiteral[] = await this.query(`SELECT * FROM sqlite_master WHERE type = 'table' AND name IN (${tableNamesString})`);
// if tables were not found in the db, no need to proceed
if (!dbTables || !dbTables.length)
@ -463,13 +465,88 @@ export class WebsqlQueryRunner implements QueryRunner {
}
/**
* Changes a column in the table.
* Changed column looses all its keys in the db.
* Renames column in the given table.
*/
async changeColumn(tableSchema: TableSchema, newColumn: ColumnSchema, oldColumn: ColumnSchema): Promise<void> {
renameColumn(table: TableSchema, oldColumn: ColumnSchema, newColumn: ColumnSchema): Promise<void>;
/**
* Renames column in the given table.
*/
renameColumn(tableName: string, oldColumnName: string, newColumnName: string): Promise<void>;
/**
* Renames column in the given table.
*/
async renameColumn(tableSchemaOrName: TableSchema|string, oldColumnSchemaOrName: ColumnSchema|string, newColumnSchemaOrName: ColumnSchema|string): Promise<void> {
let tableSchema: TableSchema|undefined = undefined;
if (tableSchemaOrName instanceof TableSchema) {
tableSchema = tableSchemaOrName;
} else {
tableSchema = await this.loadTableSchema(tableSchemaOrName);
}
if (!tableSchema)
throw new Error(`Table ${tableSchemaOrName} was not found.`);
let oldColumn: ColumnSchema|undefined = undefined;
if (oldColumnSchemaOrName instanceof ColumnSchema) {
oldColumn = oldColumnSchemaOrName;
} else {
oldColumn = tableSchema.columns.find(column => column.name === oldColumnSchemaOrName);
}
if (!oldColumn)
throw new Error(`Column "${oldColumnSchemaOrName}" was not found in the "${tableSchemaOrName}" table.`);
let newColumn: ColumnSchema|undefined = undefined;
if (newColumnSchemaOrName instanceof ColumnSchema) {
newColumn = newColumnSchemaOrName;
} else {
newColumn = oldColumn.clone();
newColumn.name = newColumnSchemaOrName;
}
return this.changeColumn(tableSchema, newColumn, oldColumn);
}
/**
* Changes a column in the table.
*/
changeColumn(tableSchema: TableSchema, oldColumn: ColumnSchema, newColumn: ColumnSchema): Promise<void>;
/**
* Changes a column in the table.
*/
changeColumn(tableSchema: string, oldColumn: string, newColumn: ColumnSchema): Promise<void>;
/**
* Changes a column in the table.
*/
async changeColumn(tableSchemaOrName: TableSchema|string, oldColumnSchemaOrName: ColumnSchema|string, newColumn: ColumnSchema): Promise<void> {
if (this.isReleased)
throw new QueryRunnerAlreadyReleasedError();
let tableSchema: TableSchema|undefined = undefined;
if (tableSchemaOrName instanceof TableSchema) {
tableSchema = tableSchemaOrName;
} else {
tableSchema = await this.loadTableSchema(tableSchemaOrName);
}
if (!tableSchema)
throw new Error(`Table ${tableSchemaOrName} was not found.`);
let oldColumn: ColumnSchema|undefined = undefined;
if (oldColumnSchemaOrName instanceof ColumnSchema) {
oldColumn = oldColumnSchemaOrName;
} else {
oldColumn = tableSchema.columns.find(column => column.name === oldColumnSchemaOrName);
}
if (!oldColumn)
throw new Error(`Column "${oldColumnSchemaOrName}" was not found in the "${tableSchemaOrName}" table.`);
// todo: fix it. it should not depend on tableSchema
return this.recreateTable(tableSchema);
}

View File

@ -124,17 +124,30 @@ export interface QueryRunner {
*/
addColumns(table: TableSchema, columns: ColumnSchema[]): Promise<void>;
// todo: renameColumn ?
/**
* Renames column in the given table.
*/
renameColumn(table: TableSchema, oldColumn: ColumnSchema, newColumn: ColumnSchema): Promise<void>;
/**
* Renames column in the given table.
*/
renameColumn(tableName: string, oldColumnName: string, newColumnName: string): Promise<void>;
/**
* Changes a column in the table.
*/
changeColumn(table: TableSchema, newColumn: ColumnSchema, oldColumn: ColumnSchema): Promise<void>;
changeColumn(table: TableSchema, oldColumn: ColumnSchema, newColumn: ColumnSchema): Promise<void>;
/**
* Changes a column in the table.
*/
changeColumn(table: string, oldColumn: string, newColumn: ColumnSchema): Promise<void>;
/**
* Changes a columns in the table.
*/
changeColumns(table: TableSchema, changedColumns: { newColumn: ColumnSchema, oldColumn: ColumnSchema }[]): Promise<void>;
changeColumns(table: TableSchema, changedColumns: { oldColumn: ColumnSchema, newColumn: ColumnSchema }[]): Promise<void>;
/**
* Drops the column in the table.