Skip to content

Commit aaa0a30

Browse files
committed
feat(lib/columns): support cascade on drop
1 parent 3c30ef3 commit aaa0a30

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

src/lib/PostgresMetaColumns.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,14 +342,14 @@ COMMIT;`
342342
return await this.retrieve({ id })
343343
}
344344

345-
async remove(id: string): Promise<PostgresMetaResult<PostgresColumn>> {
345+
async remove(id: string, { cascade = false } = {}): Promise<PostgresMetaResult<PostgresColumn>> {
346346
const { data: column, error } = await this.retrieve({ id })
347347
if (error) {
348348
return { data: null, error }
349349
}
350350
const sql = `ALTER TABLE ${ident(column!.schema)}.${ident(column!.table)} DROP COLUMN ${ident(
351351
column!.name
352-
)};`
352+
)} ${cascade ? 'CASCADE' : 'RESTRICT'};`
353353
{
354354
const { error } = await this.query(sql)
355355
if (error) {

src/server/routes/columns.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,10 @@ export default async (fastify: FastifyInstance) => {
142142
}
143143
}>('/:id(\\d+\\.\\d+)', async (request, reply) => {
144144
const connectionString = request.headers.pg
145+
const cascade = request.query.cascade === 'true'
145146

146147
const pgMeta = new PostgresMeta({ ...DEFAULT_POOL_CONFIG, connectionString })
147-
const { data, error } = await pgMeta.columns.remove(request.params.id)
148+
const { data, error } = await pgMeta.columns.remove(request.params.id, { cascade })
148149
await pgMeta.end()
149150
if (error) {
150151
request.log.error({ error, request: extractRequestForLogging(request) })

test/lib/columns.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,3 +781,67 @@ test('enums are populated in enum array columns', async () => {
781781
await pgMeta.tables.remove(testTable!.id)
782782
await pgMeta.query(`drop type test_enum`)
783783
})
784+
785+
test('drop with cascade', async () => {
786+
await pgMeta.query(`
787+
create table public.t (
788+
id int8 primary key,
789+
t_id int8 generated always as (id) stored
790+
);
791+
`)
792+
793+
let res = await pgMeta.columns.retrieve({
794+
schema: 'public',
795+
table: 't',
796+
name: 'id',
797+
})
798+
res = await pgMeta.columns.remove(res.data!.id, { cascade: true })
799+
expect(res).toMatchInlineSnapshot(
800+
{
801+
data: {
802+
id: expect.stringMatching(/^\d+\.1$/),
803+
table_id: expect.any(Number),
804+
},
805+
},
806+
`
807+
Object {
808+
"data": Object {
809+
"comment": null,
810+
"data_type": "bigint",
811+
"default_value": null,
812+
"enums": Array [],
813+
"format": "int8",
814+
"id": StringMatching /\\^\\\\d\\+\\\\\\.1\\$/,
815+
"identity_generation": null,
816+
"is_generated": false,
817+
"is_identity": false,
818+
"is_nullable": false,
819+
"is_unique": false,
820+
"is_updatable": true,
821+
"name": "id",
822+
"ordinal_position": 1,
823+
"schema": "public",
824+
"table": "t",
825+
"table_id": Any<Number>,
826+
},
827+
"error": null,
828+
}
829+
`
830+
)
831+
832+
res = await pgMeta.columns.retrieve({
833+
schema: 'public',
834+
table: 't',
835+
name: 't_id',
836+
})
837+
expect(res).toMatchInlineSnapshot(`
838+
Object {
839+
"data": null,
840+
"error": Object {
841+
"message": "Cannot find a column named t_id in table public.t",
842+
},
843+
}
844+
`)
845+
846+
await pgMeta.query(`drop table public.t;`)
847+
})

0 commit comments

Comments
 (0)