diff --git a/lib/dialects/postgres/schema/pg-compiler.js b/lib/dialects/postgres/schema/pg-compiler.js index 5968d24ef4..63214b47c3 100644 --- a/lib/dialects/postgres/schema/pg-compiler.js +++ b/lib/dialects/postgres/schema/pg-compiler.js @@ -75,12 +75,20 @@ class SchemaCompiler_PG extends SchemaCompiler { ); } - dropSchema(schemaName) { - this.pushQuery(`drop schema ${this.formatter.wrap(schemaName)}`); + dropSchema(schemaName, cascade = false) { + this.pushQuery( + `drop schema ${this.formatter.wrap(schemaName)}${ + cascade ? ' cascade' : '' + }` + ); } - dropSchemaIfExists(schemaName) { - this.pushQuery(`drop schema if exists ${this.formatter.wrap(schemaName)}`); + dropSchemaIfExists(schemaName, cascade = false) { + this.pushQuery( + `drop schema if exists ${this.formatter.wrap(schemaName)}${ + cascade ? ' cascade' : '' + }` + ); } dropExtension(extensionName) { diff --git a/test/integration2/schema/misc.spec.js b/test/integration2/schema/misc.spec.js index 92436d84d1..18401a453f 100644 --- a/test/integration2/schema/misc.spec.js +++ b/test/integration2/schema/misc.spec.js @@ -121,6 +121,96 @@ describe('Schema (misc)', () => { }); }); + describe('dropSchema', () => { + it('has a dropSchema/dropSchemaIfExists method', async function () { + if (!isPgBased(knex)) { + return this.skip(); + } + + this.timeout(process.env.KNEX_TEST_TIMEOUT || 30000); + const dbDropSchema = ['pg', 'cockroachdb']; + + function checkSchemaNotExists(schemaName) { + knex + .raw( + 'SELECT schema_name FROM information_schema.schemata WHERE schema_name = ?', + [schemaName] + ) + .then((res) => { + expect(res[0]).to.not.equal(schemaName); + }); + } + + // Drop schema cascade = false tests. + await knex.schema.createSchema('schema').then(() => { + knex.schema + .dropSchema('schema') + .testSql((tester) => { + tester(dbDropSchema, ['drop schema "schema"']); + }) + .then(() => { + checkSchemaNotExists('schema'); + }); + }); + + await knex.schema.createSchema('schema_2').then(() => { + knex.schema + .dropSchemaIfExists('schema_2') + .testSql((tester) => { + tester(dbDropSchema, ['drop schema if exists "schema_2"']); + }) + .then(() => { + checkSchemaNotExists('schema_2'); + }); + }); + + // Drop schema cascade = true tests + await knex.schema.createSchema('schema_cascade_1').then(() => { + knex.schema + .withSchema('schema_cascade_1') + .createTable('table_cascade_1', () => {}) // created to check if cascade works. + .then(() => { + knex.schema + .dropSchema('schema_cascade_1', true) + .testSql((tester) => { + tester(dbDropSchema, [ + 'drop schema "schema_cascade_1" cascade', + ]); + }) + .then(() => { + checkSchemaNotExists('schema_cascade_1'); + knex.schema + .withSchema('schema_cascade_1') + .hasTable('table_cascade_1') + .then((exists) => expect(exists).to.equal(false)); + }); + }); + }); + + await knex.schema.createSchema('schema_cascade_2').then(() => { + knex.schema + .withSchema('schema_cascade_2') + .createTable('table_cascade_2', () => {}) // created to check if cascade works. + .then(() => { + knex.schema + .dropSchemaIfExists('schema_cascade_2', true) + .testSql((tester) => { + tester(dbDropSchema, [ + 'drop schema if exists "schema_cascade_2" cascade', + ]); + }) + .then(() => { + checkSchemaNotExists('schema_cascade_2'); + knex.schema + .withSchema('schema_cascade_2') + .hasTable('table_cascade_2') + .then((exists) => expect(exists).to.equal(false)); + }); + }); + }); + }); + }); + describe('dropTable', () => { it('has a dropTableIfExists method', function () { this.timeout(process.env.KNEX_TEST_TIMEOUT || 30000); diff --git a/types/index.d.ts b/types/index.d.ts index c3897e2c14..a7b2a499b6 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1851,8 +1851,8 @@ export declare namespace Knex { callback: (tableBuilder: AlterTableBuilder) => any ): Promise; dropTableIfExists(tableName: string): SchemaBuilder; - dropSchema(schemaName: string): SchemaBuilder; - dropSchemaIfExists(schemaName: string): SchemaBuilder; + dropSchema(schemaName: string, cascade?: boolean): SchemaBuilder; + dropSchemaIfExists(schemaName: string, cascade?: boolean): SchemaBuilder; raw(statement: string): SchemaBuilder; withSchema(schemaName: string): SchemaBuilder; queryContext(context: any): SchemaBuilder;