mirror of
https://github.com/typeorm/typeorm.git
synced 2025-12-08 21:26:23 +00:00
fixed issue when sqllite database does not take in count foreign keys + fixed all tests for sqlite + moved logic of creation transaction during database drop to its method because its driver-specific (issue when sqlite needs to execute queries of disabling foreign key checks before transaction start)
This commit is contained in:
parent
ae511bbe9c
commit
92d37d39de
@ -201,17 +201,7 @@ export class Connection {
|
||||
*/
|
||||
async dropDatabase(): Promise<void> {
|
||||
const queryRunner = await this.driver.createQueryRunner();
|
||||
await queryRunner.beginTransaction();
|
||||
try {
|
||||
await queryRunner.clearDatabase();
|
||||
await queryRunner.commitTransaction();
|
||||
await queryRunner.release();
|
||||
|
||||
} catch (error) {
|
||||
await queryRunner.rollbackTransaction();
|
||||
await queryRunner.release();
|
||||
throw error;
|
||||
}
|
||||
await queryRunner.clearDatabase();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -64,14 +64,26 @@ export class MysqlQueryRunner implements QueryRunner {
|
||||
if (this.isReleased)
|
||||
throw new QueryRunnerAlreadyReleasedError();
|
||||
|
||||
const disableForeignKeysCheckQuery = `SET FOREIGN_KEY_CHECKS = 0;`;
|
||||
const dropTablesQuery = `SELECT concat('DROP TABLE IF EXISTS ', table_name, ';') AS query FROM information_schema.tables WHERE table_schema = '${this.dbName}'`;
|
||||
const enableForeignKeysCheckQuery = `SET FOREIGN_KEY_CHECKS = 1;`;
|
||||
await this.beginTransaction();
|
||||
try {
|
||||
const disableForeignKeysCheckQuery = `SET FOREIGN_KEY_CHECKS = 0;`;
|
||||
const dropTablesQuery = `SELECT concat('DROP TABLE IF EXISTS ', table_name, ';') AS query FROM information_schema.tables WHERE table_schema = '${this.dbName}'`;
|
||||
const enableForeignKeysCheckQuery = `SET FOREIGN_KEY_CHECKS = 1;`;
|
||||
|
||||
await this.query(disableForeignKeysCheckQuery);
|
||||
const dropQueries: ObjectLiteral[] = await this.query(dropTablesQuery);
|
||||
await Promise.all(dropQueries.map(query => this.query(query["query"])));
|
||||
await this.query(enableForeignKeysCheckQuery);
|
||||
await this.query(disableForeignKeysCheckQuery);
|
||||
const dropQueries: ObjectLiteral[] = await this.query(dropTablesQuery);
|
||||
await Promise.all(dropQueries.map(query => this.query(query["query"])));
|
||||
await this.query(enableForeignKeysCheckQuery);
|
||||
|
||||
await this.commitTransaction();
|
||||
|
||||
} catch (error) {
|
||||
await this.rollbackTransaction();
|
||||
throw error;
|
||||
|
||||
} finally {
|
||||
await this.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -64,14 +64,27 @@ export class OracleQueryRunner implements QueryRunner {
|
||||
if (this.isReleased)
|
||||
throw new QueryRunnerAlreadyReleasedError();
|
||||
|
||||
const disableForeignKeysCheckQuery = `SET FOREIGN_KEY_CHECKS = 0;`;
|
||||
const dropTablesQuery = `SELECT concat('DROP TABLE IF EXISTS ', table_name, ';') AS query FROM information_schema.tables WHERE table_schema = '${this.dbName}'`;
|
||||
const enableForeignKeysCheckQuery = `SET FOREIGN_KEY_CHECKS = 1;`;
|
||||
await this.beginTransaction();
|
||||
try {
|
||||
const disableForeignKeysCheckQuery = `SET FOREIGN_KEY_CHECKS = 0;`;
|
||||
const dropTablesQuery = `SELECT concat('DROP TABLE IF EXISTS ', table_name, ';') AS query FROM information_schema.tables WHERE table_schema = '${this.dbName}'`;
|
||||
const enableForeignKeysCheckQuery = `SET FOREIGN_KEY_CHECKS = 1;`;
|
||||
|
||||
await this.query(disableForeignKeysCheckQuery);
|
||||
const dropQueries: ObjectLiteral[] = await this.query(dropTablesQuery);
|
||||
await Promise.all(dropQueries.map(query => this.query(query["query"])));
|
||||
await this.query(enableForeignKeysCheckQuery);
|
||||
|
||||
await this.commitTransaction();
|
||||
|
||||
} catch (error) {
|
||||
await this.rollbackTransaction();
|
||||
throw error;
|
||||
|
||||
} finally {
|
||||
await this.release();
|
||||
}
|
||||
|
||||
await this.query(disableForeignKeysCheckQuery);
|
||||
const dropQueries: ObjectLiteral[] = await this.query(dropTablesQuery);
|
||||
await Promise.all(dropQueries.map(query => this.query(query["query"])));
|
||||
await this.query(enableForeignKeysCheckQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -63,9 +63,21 @@ export class PostgresQueryRunner implements QueryRunner {
|
||||
if (this.isReleased)
|
||||
throw new QueryRunnerAlreadyReleasedError();
|
||||
|
||||
const selectDropsQuery = `SELECT 'DROP TABLE IF EXISTS "' || tablename || '" CASCADE;' as query FROM pg_tables WHERE schemaname = 'public'`;
|
||||
const dropQueries: ObjectLiteral[] = await this.query(selectDropsQuery);
|
||||
await Promise.all(dropQueries.map(q => this.query(q["query"])));
|
||||
await this.beginTransaction();
|
||||
try {
|
||||
const selectDropsQuery = `SELECT 'DROP TABLE IF EXISTS "' || tablename || '" CASCADE;' as query FROM pg_tables WHERE schemaname = 'public'`;
|
||||
const dropQueries: ObjectLiteral[] = await this.query(selectDropsQuery);
|
||||
await Promise.all(dropQueries.map(q => this.query(q["query"])));
|
||||
|
||||
await this.commitTransaction();
|
||||
|
||||
} catch (error) {
|
||||
await this.rollbackTransaction();
|
||||
throw error;
|
||||
|
||||
} finally {
|
||||
await this.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -86,8 +86,9 @@ 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.run(`PRAGMA foreign_keys = ON`);
|
||||
ok();
|
||||
connection.run(`PRAGMA foreign_keys = ON;`, (err: any, result: any) => {
|
||||
ok();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -66,9 +66,22 @@ export class SqliteQueryRunner implements QueryRunner {
|
||||
if (this.isReleased)
|
||||
throw new QueryRunnerAlreadyReleasedError();
|
||||
|
||||
const selectDropsQuery = `select 'drop table ' || name || ';' as query from sqlite_master where type = 'table' and name != 'sqlite_sequence'`;
|
||||
const dropQueries: ObjectLiteral[] = await this.query(selectDropsQuery);
|
||||
await Promise.all(dropQueries.map(q => this.query(q["query"])));
|
||||
await this.query(`PRAGMA foreign_keys = OFF;`);
|
||||
await this.beginTransaction();
|
||||
try {
|
||||
const selectDropsQuery = `select 'drop table ' || name || ';' as query from sqlite_master where type = 'table' and name != 'sqlite_sequence'`;
|
||||
const dropQueries: ObjectLiteral[] = await this.query(selectDropsQuery);
|
||||
await Promise.all(dropQueries.map(q => this.query(q["query"])));
|
||||
await this.commitTransaction();
|
||||
|
||||
} catch (error) {
|
||||
await this.rollbackTransaction();
|
||||
throw error;
|
||||
|
||||
} finally {
|
||||
await this.release();
|
||||
await this.query(`PRAGMA foreign_keys = ON;`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -64,20 +64,32 @@ export class SqlServerQueryRunner implements QueryRunner {
|
||||
if (this.isReleased)
|
||||
throw new QueryRunnerAlreadyReleasedError();
|
||||
|
||||
const allTablesSql = `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'`;
|
||||
const allTablesResults: ObjectLiteral[] = await this.query(allTablesSql);
|
||||
const tableNames = allTablesResults.map(result => result["TABLE_NAME"]);
|
||||
await Promise.all(tableNames.map(async tableName => {
|
||||
const dropForeignKeySql = `SELECT 'ALTER TABLE ' + OBJECT_SCHEMA_NAME(parent_object_id) + '.[' + OBJECT_NAME(parent_object_id) + '] DROP CONSTRAINT ' + name as query FROM sys.foreign_keys WHERE referenced_object_id = object_id('${tableName}')`;
|
||||
const dropFkQueries: ObjectLiteral[] = await this.query(dropForeignKeySql);
|
||||
return Promise.all(dropFkQueries.map(result => result["query"]).map(dropQuery => {
|
||||
return this.query(dropQuery);
|
||||
await this.beginTransaction();
|
||||
try {
|
||||
const allTablesSql = `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'`;
|
||||
const allTablesResults: ObjectLiteral[] = await this.query(allTablesSql);
|
||||
const tableNames = allTablesResults.map(result => result["TABLE_NAME"]);
|
||||
await Promise.all(tableNames.map(async tableName => {
|
||||
const dropForeignKeySql = `SELECT 'ALTER TABLE ' + OBJECT_SCHEMA_NAME(parent_object_id) + '.[' + OBJECT_NAME(parent_object_id) + '] DROP CONSTRAINT ' + name as query FROM sys.foreign_keys WHERE referenced_object_id = object_id('${tableName}')`;
|
||||
const dropFkQueries: ObjectLiteral[] = await this.query(dropForeignKeySql);
|
||||
return Promise.all(dropFkQueries.map(result => result["query"]).map(dropQuery => {
|
||||
return this.query(dropQuery);
|
||||
}));
|
||||
}));
|
||||
}));
|
||||
await Promise.all(tableNames.map(tableName => {
|
||||
const dropTableSql = `DROP TABLE "${tableName}"`;
|
||||
return this.query(dropTableSql);
|
||||
}));
|
||||
await Promise.all(tableNames.map(tableName => {
|
||||
const dropTableSql = `DROP TABLE "${tableName}"`;
|
||||
return this.query(dropTableSql);
|
||||
}));
|
||||
|
||||
await this.commitTransaction();
|
||||
|
||||
} catch (error) {
|
||||
await this.rollbackTransaction();
|
||||
throw error;
|
||||
|
||||
} finally {
|
||||
await this.release();
|
||||
}
|
||||
|
||||
// const selectDropsQuery = `SELECT 'DROP TABLE "' + TABLE_NAME + '"' as query FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE';`;
|
||||
// const dropQueries: ObjectLiteral[] = await this.query(selectDropsQuery);
|
||||
|
||||
@ -10,7 +10,11 @@ describe("QueryBuilder > relation-count", () => {
|
||||
// const resourceDir = __dirname + "/../../../../../../test/functional/query-builder/join-relation-ids/";
|
||||
|
||||
let connections: Connection[];
|
||||
before(() => setupTestingConnections({ entities: [Post, Category, Tag], schemaCreate: true }).then(all => connections = all));
|
||||
before(() => setupTestingConnections({
|
||||
entities: [Post, Category, Tag],
|
||||
schemaCreate: true,
|
||||
dropSchemaOnConnection: true
|
||||
}).then(all => connections = all));
|
||||
beforeEach(() => reloadDatabases(connections));
|
||||
after(() => closeConnections(connections));
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ describe("QueryBuilder > relation-id", () => {
|
||||
// todo: also make sure all new qb features to work with FindOptions
|
||||
|
||||
let connections: Connection[];
|
||||
before(() => setupTestingConnections({ entities: [Post, Category, Tag], schemaCreate: true }).then(all => connections = all));
|
||||
before(() => setupTestingConnections({ entities: [Post, Category, Tag], schemaCreate: true, dropSchemaOnConnection: true }).then(all => connections = all));
|
||||
beforeEach(() => reloadDatabases(connections));
|
||||
after(() => closeConnections(connections));
|
||||
|
||||
|
||||
@ -34,8 +34,8 @@ describe("insertion", function() {
|
||||
savedPost.should.be.equal(newPost);
|
||||
expect(savedPost.id).not.to.be.empty;
|
||||
|
||||
const insertedPost = (await postRepository.findOneById(savedPost.id))!;
|
||||
insertedPost.should.be.eql({
|
||||
const insertedPost = await postRepository.findOneById(savedPost.id);
|
||||
insertedPost!.should.be.eql({
|
||||
id: savedPost.id,
|
||||
text: "Hello post",
|
||||
title: "this is post title",
|
||||
|
||||
@ -219,7 +219,7 @@ export async function setupTestingConnections(options?: TestingConnectionOptions
|
||||
const mysql = true; // !options || !options.skipMysql;
|
||||
const mariadb = false; // !options || !options.skipMariadb;
|
||||
const postgres = false; // !options || !options.skipPostgres;
|
||||
const sqlite = false; // !options || !options.skipSqlite;
|
||||
const sqlite = true; // !options || !options.skipSqlite;
|
||||
const mssql = false; // !options || !options.skipSqlserver;
|
||||
|
||||
const allParameters: ConnectionOptions[] = [];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user