Skip to content

Commit

Permalink
refactor: change sqlite dropAllTables implementation (#1001)
Browse files Browse the repository at this point in the history
* refactor: change dropAllTables implementation

* test: add test for dropTables with foreign keys constraint

* refactor: handle pragma foreign_keys

* fix: test for mssql

* test: fix for mssql
  • Loading branch information
Julien-R44 committed Feb 23, 2024
1 parent 7b981e7 commit 5c18c76
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 16 deletions.
36 changes: 26 additions & 10 deletions src/dialects/base_sqlite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,32 @@ export abstract class BaseSqliteDialect implements DialectContract {
* Drop all tables inside the database
*/
async dropAllTables() {
await this.client.rawQuery('PRAGMA writable_schema = 1;')
await this.client
.knexQuery()
.delete()
.from('sqlite_master')
.whereIn('type', ['table', 'index', 'trigger'])
.whereNotIn('name', this.config.wipe?.ignoreTables || [])

await this.client.rawQuery('PRAGMA writable_schema = 0;')
await this.client.rawQuery('VACUUM;')
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;')
}
}

/**
Expand Down
6 changes: 0 additions & 6 deletions test-helpers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,6 @@ export function getConfig(): ConnectionConfig {
},
useNullAsDefault: true,
debug: !!process.env.DEBUG,
pool: {
afterCreate(connection, done) {
connection.unsafeMode(true)
done()
},
},
}
case 'mysql':
return {
Expand Down
55 changes: 55 additions & 0 deletions test/database/drop_tables.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,59 @@ test.group('Query client | drop tables', (group) => {

await connection.disconnect()
})

test('drop tables with foreign keys constraint', async ({ assert }) => {
const connection = new Connection('primary', getConfig(), logger)
connection.connect()

await connection.client!.schema.createTableIfNotExists('temp_users', (table) => {
table.increments('id')
})

await connection.client!.schema.createTableIfNotExists('temp_posts', (table) => {
table.increments('id')
table.integer('temp_users_id').unsigned().references('id').inTable('temp_users')
})

await connection.client?.table('temp_users').insert({})
const user = await connection.client?.table('temp_users').select('id').first()
await connection.client?.table('temp_posts').insert({ temp_users_id: user!.id })

const client = new QueryClient('dual', connection, createEmitter())
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()
})

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()
})
}
})

0 comments on commit 5c18c76

Please sign in to comment.