From b4134bdc790a5026a0d93d0850b2efb817c40789 Mon Sep 17 00:00:00 2001 From: "Visal .In" Date: Sat, 19 Oct 2024 15:56:56 +0700 Subject: [PATCH] add drop column test --- src/client.ts | 9 ++++++ src/connections/index.ts | 6 ++++ src/connections/mongodb.ts | 4 +++ src/connections/sql-base.ts | 17 ++++++++++ src/query-builder/index.ts | 21 ++++++++++++ tests/connections/connection.test.ts | 48 +++++++++++++++------------- 6 files changed, 83 insertions(+), 22 deletions(-) diff --git a/src/client.ts b/src/client.ts index 1a131ce..79bc197 100644 --- a/src/client.ts +++ b/src/client.ts @@ -62,6 +62,7 @@ export interface QueryBuilderInternal { // ------------------------------------------ // This is use for alter or create schema // ------------------------------------------ + dropColumn?: string; columns: { name: string; definition?: TableColumnDefinition; // For alter or create column @@ -345,6 +346,12 @@ class QueryBuilderAlterTable extends IQueryBuilder { return this; } + dropColumn(name: string) { + this.state.action = QueryBuilderAction.DROP_COLUMNS; + this.state.dropColumn = name; + return this; + } + renameTable(newTableName: string) { this.state.action = QueryBuilderAction.RENAME_TABLE; this.state.newTableName = newTableName; @@ -463,6 +470,8 @@ function buildQueryString( return dialect.alterColumn(queryBuilder); case QueryBuilderAction.RENAME_COLUMNS: return dialect.renameColumn(queryBuilder); + case QueryBuilderAction.DROP_COLUMNS: + return dialect.dropColumn(queryBuilder); default: throw new Error('Invalid action'); } diff --git a/src/connections/index.ts b/src/connections/index.ts index 404cb96..d9b593a 100644 --- a/src/connections/index.ts +++ b/src/connections/index.ts @@ -108,4 +108,10 @@ export abstract class Connection { columnName: string, defintion: TableColumnDefinition ): Promise; + + abstract dropColumn( + schemaName: string | undefined, + tableName: string, + columnName: string + ): Promise; } diff --git a/src/connections/mongodb.ts b/src/connections/mongodb.ts index e7f8245..b8914ae 100644 --- a/src/connections/mongodb.ts +++ b/src/connections/mongodb.ts @@ -165,6 +165,10 @@ export class MongoDBConnection implements Connection { return createOkResult(); } + async dropColumn(): Promise { + return createOkResult(); + } + async select( schemaName: string, tableName: string, diff --git a/src/connections/sql-base.ts b/src/connections/sql-base.ts index 54a9c74..7836be3 100644 --- a/src/connections/sql-base.ts +++ b/src/connections/sql-base.ts @@ -240,6 +240,23 @@ export abstract class SqlConnection extends Connection { ); } + async dropColumn( + schemaName: string | undefined, + tableName: string, + columnName: string + ): Promise { + const qb = Outerbase(this); + + return await this.query( + qb + .alterTable( + schemaName ? `${schemaName}.${tableName}` : tableName + ) + .dropColumn(columnName) + .toQuery() + ); + } + async testConnection(): Promise { try { await this.connect(); diff --git a/src/query-builder/index.ts b/src/query-builder/index.ts index a2fb92b..65d6be9 100644 --- a/src/query-builder/index.ts +++ b/src/query-builder/index.ts @@ -21,6 +21,7 @@ interface Dialect { renameTable(builder: QueryBuilderInternal): Query; renameColumn(builder: QueryBuilderInternal): Query; alterColumn(builder: QueryBuilderInternal): Query; + dropColumn(builder: QueryBuilderInternal): Query; addColumn(builder: QueryBuilderInternal): Query; } @@ -394,6 +395,26 @@ export abstract class AbstractDialect implements Dialect { }; } + dropColumn(builder: QueryBuilderInternal): Query { + const tableName = builder.table; + const columnName = builder.dropColumn; + + if (!tableName) { + throw new Error( + 'Table name is required to build a DROP COLUMN query.' + ); + } + + if (!columnName) { + throw new Error('Column name is required to drop.'); + } + + return { + query: `ALTER TABLE ${this.escapeId(tableName)} DROP COLUMN ${this.escapeId(columnName)}`, + parameters: [], + }; + } + renameColumn(builder: QueryBuilderInternal): Query { const tableName = builder.table; diff --git a/tests/connections/connection.test.ts b/tests/connections/connection.test.ts index 235d3fd..30dc8dc 100644 --- a/tests/connections/connection.test.ts +++ b/tests/connections/connection.test.ts @@ -179,7 +179,10 @@ describe('Database Connection', () => { ]); }); - test('Add table column', async () => { + test('Add and drop table column', async () => { + // Skip Mongodb because it does not have schema + if (process.env.CONNECTION_TYPE === 'mongodb') return; + const { error } = await db.addColumn( DEFAULT_SCHEMA, 'persons', @@ -194,26 +197,8 @@ describe('Database Connection', () => { expect(error).not.toBeTruthy(); - // Need to update email because MongoDB does not have schema - if (process.env.CONNECTION_TYPE === 'bigquery') { - await db.raw( - `UPDATE \`${DEFAULT_SCHEMA}.persons\` SET email = 'test@outerbase.com' WHERE TRUE;` - ); - } else { - await db.update( - DEFAULT_SCHEMA, - 'persons', - { - email: 'test@outerbase.com', - }, - {} - ); - } - const { data } = await db.select(DEFAULT_SCHEMA, 'persons', { orderBy: ['id'], - limit: 1000, - offset: 0, }); expect(cleanup(data)).toEqual([ @@ -221,13 +206,33 @@ describe('Database Connection', () => { id: 1, full_name: 'Visal In', age: 25, - email: 'test@outerbase.com', + email: null, + }, + { + id: 2, + full_name: 'Outerbase', + age: 30, + email: null, + }, + ]); + + // Remove the column + await db.dropColumn(DEFAULT_SCHEMA, 'persons', 'email'); + + const { data: data2 } = await db.select(DEFAULT_SCHEMA, 'persons', { + orderBy: ['id'], + }); + + expect(cleanup(data2)).toEqual([ + { + id: 1, + full_name: 'Visal In', + age: 25, }, { id: 2, full_name: 'Outerbase', age: 30, - email: 'test@outerbase.com', }, ]); }); @@ -264,7 +269,6 @@ describe('Database Connection', () => { id: 2, full_name: 'Outerbase', age: 30, - email: 'test@outerbase.com', }, ]); });