From ca31c699afcc46b408c71f2bb81c88bf3ddc9180 Mon Sep 17 00:00:00 2001 From: Julien Ripouteau Date: Fri, 16 Feb 2024 14:42:49 +0100 Subject: [PATCH] refactor: handle pragma foreign_keys --- src/dialects/base_sqlite.ts | 20 ++++++++++++++++++++ test/database/drop_tables.spec.ts | 30 +++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/dialects/base_sqlite.ts b/src/dialects/base_sqlite.ts index f9709067..d1dbf32a 100644 --- a/src/dialects/base_sqlite.ts +++ b/src/dialects/base_sqlite.ts @@ -84,11 +84,31 @@ export abstract class BaseSqliteDialect implements DialectContract { */ async dropAllTables() { const tables = await this.getAllTables() + + /** + * Check for foreign key pragma and turn it off if enabled + * so that we can drop tables without any issues + */ + const pragma = await this.client.rawQuery('PRAGMA foreign_keys;') + if (pragma[0].foreign_keys === 1) { + await this.client.rawQuery('PRAGMA foreign_keys = OFF;') + } + + /** + * Drop all tables + */ const promises = tables .filter((table) => !this.config.wipe?.ignoreTables?.includes(table)) .map((table) => this.client.rawQuery(`DROP TABLE ${table};`)) await Promise.all(promises) + + /** + * Restore foreign key pragma to it's original value + */ + if (pragma[0].foreign_keys === 1) { + await this.client.rawQuery('PRAGMA foreign_keys = ON;') + } } /** diff --git a/test/database/drop_tables.spec.ts b/test/database/drop_tables.spec.ts index 98e4ba52..5b143d63 100644 --- a/test/database/drop_tables.spec.ts +++ b/test/database/drop_tables.spec.ts @@ -121,7 +121,6 @@ test.group('Query client | drop tables', (group) => { table.integer('temp_users_id').unsigned().references('id').inTable('temp_users') }) - await connection.client?.table('temp_users').insert({ id: 1 }) await connection.client?.table('temp_posts').insert({ id: 1, temp_users_id: 1 }) @@ -133,4 +132,33 @@ test.group('Query client | drop tables', (group) => { await connection.disconnect() }) + + if (['better-sqlite', 'sqlite'].includes(process.env.DB!)) { + test('drop tables when PRAGMA foreign_keys is enabled', async ({ assert }) => { + const connection = new Connection('primary', getConfig(), logger) + connection.connect() + + await connection.client!.schema.createTable('temp_posts', (table) => { + table.increments('id') + }) + + await connection.client!.schema.createTableIfNotExists('temp_users', (table) => { + table.increments('id') + table.integer('temp_posts_id').unsigned().references('id').inTable('temp_posts') + }) + + await connection.client?.table('temp_posts').insert({ id: 1 }) + await connection.client?.table('temp_users').insert({ id: 1, temp_posts_id: 1 }) + + const client = new QueryClient('dual', connection, createEmitter()) + + await client.rawQuery('PRAGMA foreign_keys = ON;') + await client.dialect.dropAllTables(['public']) + + assert.isFalse(await connection.client!.schema.hasTable('temp_users')) + assert.isFalse(await connection.client!.schema.hasTable('temp_posts')) + + await connection.disconnect() + }) + } })