diff --git a/src/connections/bigquery.ts b/src/connections/bigquery.ts index fadcb25..8667da8 100644 --- a/src/connections/bigquery.ts +++ b/src/connections/bigquery.ts @@ -9,6 +9,7 @@ import { transformObjectBasedResultFirstRow, } from './../utils/transformer'; import { SqlConnection } from './sql-base'; +import { ColumnDataType } from 'src/query-builder'; export class BigQueryConnection extends SqlConnection { bigQuery: BigQuery; diff --git a/src/connections/mysql.ts b/src/connections/mysql.ts index 5088d11..61b5958 100644 --- a/src/connections/mysql.ts +++ b/src/connections/mysql.ts @@ -20,6 +20,7 @@ import { transformArrayBasedResult, } from './../utils/transformer'; import { QueryResult } from '.'; +import { ColumnDataType } from 'src/query-builder'; interface MySQLSchemaResult { SCHEMA_NAME: string; @@ -210,6 +211,14 @@ export class MySQLConnection extends SqlConnection { this.conn = conn; } + mapDataType(dataType: string): string { + if (dataType === ColumnDataType.STRING) return 'TEXT'; + if (dataType === ColumnDataType.NUMBER) return 'INT'; + if (dataType === ColumnDataType.ARRAY) return 'JSON'; + if (dataType === ColumnDataType.UUID) return 'TEXT'; + return super.mapDataType(dataType); + } + async query>( query: Query ): Promise> { diff --git a/src/connections/postgre/base.ts b/src/connections/postgre/base.ts index ac8194a..ac38926 100644 --- a/src/connections/postgre/base.ts +++ b/src/connections/postgre/base.ts @@ -1,4 +1,4 @@ -import { AbstractDialect } from './../../query-builder'; +import { AbstractDialect, ColumnDataType } from './../../query-builder'; import { PostgresDialect } from './../../query-builder/dialects/postgres'; import { Database } from './../../models/database'; import { buildMySQLDatabaseSchmea } from './../mysql'; @@ -7,6 +7,13 @@ import { SqlConnection } from '../sql-base'; export abstract class PostgreBaseConnection extends SqlConnection { dialect: AbstractDialect = new PostgresDialect(); + mapDataType(dataType: string): string { + if (dataType === ColumnDataType.ID) return 'SERIAL'; + if (dataType === ColumnDataType.STRING) return 'TEXT'; + if (dataType === ColumnDataType.NUMBER) return 'INTEGER'; + return super.mapDataType(dataType); + } + async fetchDatabaseSchema(): Promise { // Get the list of schema first const { data: schemaList } = await this.query<{ schema_name: string }>({ diff --git a/src/connections/sql-base.ts b/src/connections/sql-base.ts index 38527bd..16757e1 100644 --- a/src/connections/sql-base.ts +++ b/src/connections/sql-base.ts @@ -5,7 +5,7 @@ import { Outerbase, QueryResult, } from '..'; -import { AbstractDialect } from './../query-builder'; +import { AbstractDialect, ColumnDataType } from './../query-builder'; import { TableColumn, TableColumnDefinition } from './../models/database'; export abstract class SqlConnection extends Connection { @@ -15,6 +15,11 @@ export abstract class SqlConnection extends Connection { query: Query ): Promise>; + mapDataType(dataType: string): string { + if (dataType === ColumnDataType.ID) return 'INTEGER'; + return dataType; + } + async raw(query: string): Promise { return await this.query({ query }); } @@ -148,7 +153,10 @@ export abstract class SqlConnection extends Connection { ); for (const column of columns) { - qb.column(column.name, column.definition); + qb.column(column.name, { + ...column.definition, + type: this.mapDataType(column.definition.type), + }); } return this.query(qb.toQuery()); @@ -217,7 +225,10 @@ export abstract class SqlConnection extends Connection { .alterTable( schemaName ? `${schemaName}.${tableName}` : tableName ) - .alterColumn(columnName, defintion) + .alterColumn(columnName, { + ...defintion, + type: this.mapDataType(defintion.type), + }) .toQuery() ); } diff --git a/src/query-builder/index.ts b/src/query-builder/index.ts index 8161425..ef45648 100644 --- a/src/query-builder/index.ts +++ b/src/query-builder/index.ts @@ -26,6 +26,7 @@ interface Dialect { } export enum ColumnDataType { + ID = 'id', STRING = 'string', NUMBER = 'number', BOOLEAN = 'boolean', diff --git a/tests/connections/connection.test.ts b/tests/connections/connection.test.ts index 0464b50..51894ab 100644 --- a/tests/connections/connection.test.ts +++ b/tests/connections/connection.test.ts @@ -1,6 +1,10 @@ +import { ColumnDataType } from '../../src/query-builder'; import createTestClient from './create-test-connection'; const { client: db, defaultSchema: DEFAULT_SCHEMA } = createTestClient(); +// Some drivers are just too slow such as Cloudflare and BigQuery +jest.setTimeout(10000); + beforeAll(async () => { await db.connect(); @@ -39,15 +43,15 @@ describe('Database Connection', () => { [ { name: 'id', - definition: { type: 'INTEGER', primaryKey: true }, + definition: { + type: ColumnDataType.NUMBER, + primaryKey: true, + }, }, { name: 'name', definition: { - type: - process.env.CONNECTION_TYPE === 'bigquery' - ? 'STRING' - : 'VARCHAR(255)', + type: ColumnDataType.STRING, }, }, ] @@ -59,22 +63,22 @@ describe('Database Connection', () => { [ { name: 'id', - definition: { type: 'INTEGER', primaryKey: true }, + definition: { + type: ColumnDataType.NUMBER, + primaryKey: true, + }, }, { name: 'name', definition: { - type: - process.env.CONNECTION_TYPE === 'bigquery' - ? 'STRING' - : 'VARCHAR(255)', + type: ColumnDataType.STRING, }, }, - { name: 'age', definition: { type: 'INTEGER' } }, + { name: 'age', definition: { type: ColumnDataType.NUMBER } }, { name: 'team_id', definition: { - type: 'INTEGER', + type: ColumnDataType.NUMBER, references: { column: ['id'], table: 'teams', @@ -236,7 +240,7 @@ describe('Database Connection', () => { includeCounting: true, }); expect(count).toEqual(2); - }); + }, 10000); test('Select from non-existing table should return error', async () => { // MongoDB does not show error when selecting from non-existing collection @@ -306,10 +310,7 @@ describe('Database Connection', () => { 'persons', 'email', { - type: - process.env.CONNECTION_TYPE === 'bigquery' - ? 'STRING' - : 'VARCHAR(255)', + type: ColumnDataType.STRING, } );