diff --git a/packages/cubejs-base-driver/src/BaseDriver.ts b/packages/cubejs-base-driver/src/BaseDriver.ts index 1db5b97c98f0d..242fc50fb1452 100644 --- a/packages/cubejs-base-driver/src/BaseDriver.ts +++ b/packages/cubejs-base-driver/src/BaseDriver.ts @@ -164,27 +164,6 @@ export abstract class BaseDriver implements DriverInterface { `; } - protected informationSchemaGetSchemasQuery() { - return ` - SELECT table_schema as ${this.quoteIdentifier('schema_name')} - FROM information_schema.tables - WHERE table_schema NOT IN (${this.getIgnoredSchemas()}) - GROUP BY table_schema - ORDER BY table_schema - `; - } - - protected informationSchemaGetTablesQuery(schemaNames: string[]) { - const schemas = schemaNames.map(s => this.singleQuoteIdentifier(s)).join(', '); - return ` - SELECT table_schema as ${this.quoteIdentifier('schema_name')}, - table_name as ${this.quoteIdentifier('table_name')} - FROM information_schema.tables - WHERE table_schema IN (${schemas}) - ORDER BY table_schema, table_name - `; - } - protected getSslOptions(dataSource: string): TLSConnectionOptions | undefined { if ( getEnv('dbSsl', { dataSource }) || @@ -334,21 +313,43 @@ export abstract class BaseDriver implements DriverInterface { } public getSchemas() { - const query = this.informationSchemaGetSchemasQuery(); + const query = ` + SELECT table_schema as ${this.quoteIdentifier('schema_name')} + FROM information_schema.tables + WHERE table_schema NOT IN (${this.getIgnoredSchemas()}) + GROUP BY table_schema + `; return this.query(query); } - public getTables(schemaNames?: string[]) { + public getTablesForSpecificSchemas(schemaNames?: string[]) { if (!schemaNames) { throw new Error('getTables without schemaNames is not supported'); } - const query = this.informationSchemaGetTablesQuery(schemaNames); - return this.query(query); + const schemas = schemaNames.map((_, idx) => `$${idx + 1}`).join(', '); + + const query = ` + SELECT table_schema as ${this.quoteIdentifier('schema_name')}, + table_name as ${this.quoteIdentifier('table_name')} + FROM information_schema.tables + WHERE table_schema IN (${schemas}) + `; + return this.query(query, schemaNames); } - public getColumns(tables: QueryTablesResult[]) { - const conditions = tables.map(t => `(table_schema='${t.schema_name}' AND table_name='${t.table_name}')`).join(' OR '); + public getColumnsForSpecificTables(tables: QueryTablesResult[]) { + const conditions: string[] = []; + const parameters: string[] = []; + + tables.forEach((t, idx) => { + const schemaPlaceholder = `$${2 * idx + 1}`; + const tablePlaceholder = `$${2 * idx + 2}`; + conditions.push(`(table_schema=${schemaPlaceholder} AND table_name=${tablePlaceholder})`); + parameters.push(t.schema_name, t.table_name); + }); + + const conditionString = conditions.join(' OR '); const query = ` SELECT columns.column_name as ${this.quoteIdentifier('column_name')}, @@ -356,10 +357,10 @@ export abstract class BaseDriver implements DriverInterface { columns.table_schema as ${this.quoteIdentifier('table_schema')}, columns.data_type as ${this.quoteIdentifier('data_type')} FROM information_schema.columns - WHERE ${conditions} + WHERE ${conditionString} `; - return this.query(query); + return this.query(query, parameters); } public getTablesQuery(schemaName: string) { diff --git a/packages/cubejs-base-driver/src/driver.interface.ts b/packages/cubejs-base-driver/src/driver.interface.ts index 0583a2a155610..297e0ba27a14a 100644 --- a/packages/cubejs-base-driver/src/driver.interface.ts +++ b/packages/cubejs-base-driver/src/driver.interface.ts @@ -186,10 +186,10 @@ export interface DriverInterface { // tableColumnTypes: (table: string) => Promise; queryColumnTypes: (sql: string, params?: unknown[]) => Promise<{ name: any; type: string; }[]>; - // Returns all schemas for current database + // getSchemas: () => Promise; - // Returns all tables for defined schemas - getTables: (schemaNames: string[]) => Promise; + getTablesForSpecificSchemas: (schemaNames: string[]) => Promise; + getColumnsForSpecificTables: (tables: QueryTablesResult[]) => Promise; // eslint-disable-next-line camelcase getTablesQuery: (schemaName: string) => Promise; // Remove table from database diff --git a/packages/cubejs-server-core/src/core/DevServer.ts b/packages/cubejs-server-core/src/core/DevServer.ts index b824931b4699d..410497d7caaec 100644 --- a/packages/cubejs-server-core/src/core/DevServer.ts +++ b/packages/cubejs-server-core/src/core/DevServer.ts @@ -131,7 +131,7 @@ export class DevServer { requestId: getRequestIdFromRequest(req), }); - const tables = await driver.getTables(req.body.schemaNames); + const tables = await driver.getTablesForSpecificSchemas(req.body.schemaNames); res.json({ tables }); })); @@ -149,7 +149,7 @@ export class DevServer { requestId: getRequestIdFromRequest(req), }); - const columns = await driver.getColumns(req.body.tables); + const columns = await driver.getColumnsForSpecificTables(req.body.tables); res.json({ columns }); }));