From 4d09f4a07ea7d05535cb2bbb408f4c5cd66248ee Mon Sep 17 00:00:00 2001 From: rijkvanzanten Date: Mon, 9 Nov 2020 18:50:08 -0500 Subject: [PATCH] Add oracle/mssql --- api/src/middleware/schema.ts | 3 -- packages/schema/src/dialects/mssql.ts | 55 +++++++++++++++++++++--- packages/schema/src/dialects/oracledb.ts | 43 +++++++++++++++++- 3 files changed, 91 insertions(+), 10 deletions(-) diff --git a/api/src/middleware/schema.ts b/api/src/middleware/schema.ts index 62a4d450f6..863db1c76b 100644 --- a/api/src/middleware/schema.ts +++ b/api/src/middleware/schema.ts @@ -9,9 +9,6 @@ import { schemaInspector } from '../database'; const sanitizeQueryMiddleware: RequestHandler = asyncHandler(async (req, res, next) => { const schemaOverview = await schemaInspector.overview(); - - console.log(schemaOverview); - req.schema = schemaOverview; return next(); diff --git a/packages/schema/src/dialects/mssql.ts b/packages/schema/src/dialects/mssql.ts index f8a1c75c6b..a7603b5bdb 100644 --- a/packages/schema/src/dialects/mssql.ts +++ b/packages/schema/src/dialects/mssql.ts @@ -2,6 +2,7 @@ import Knex from 'knex'; import { Schema } from '../types/schema'; import { Table } from '../types/table'; import { Column } from '../types/column'; +import { SchemaOverview } from '../types/overview'; type RawTable = { TABLE_NAME: string; @@ -40,8 +41,52 @@ export default class MSSQL implements Schema { // Overview // =============================================================================================== async overview() { - /** @TODO */ - return {}; + const columns = await this.knex.raw( + ` + SELECT + c.TABLE_NAME as table_name, + c.COLUMN_NAME as column_name, + c.COLUMN_DEFAULT as default_value, + c.IS_NULLABLE as is_nullable, + c.DATA_TYPE as data_type, + pk.PK_SET as column_key + FROM + ${this.knex.client.database()}.INFORMATION_SCHEMA.COLUMNS as c + LEFT JOIN ( + SELECT + PK_SET = CASE WHEN CONSTRAINT_NAME LIKE '%pk%' THEN 'PRIMARY' ELSE NULL END + FROM ${this.knex.client.database()}.INFORMATION_SCHEMA.KEY_COLUMN_USAGE + ) as pk + ON [c].[TABLE_NAME] = [pk].[CONSTRAINT_TABLE_NAME] + AND [c].[TABLE_CATALOG] = [pk].[CONSTRAINT_CATALOG] + AND [c].[COLUMN_NAME] = [pk].[CONSTRAINT_COLUMN_NAME] + ` + ); + + const overview: SchemaOverview = {}; + + for (const column of columns[0]) { + if (column.table_name in overview === false) { + overview[column.table_name] = { + primary: columns[0].find( + (nested: { column_key: string; table_name: string }) => { + return ( + nested.table_name === column.table_name && + nested.column_key === 'PRIMARY' + ); + } + )?.column_name, + columns: {}, + }; + } + + overview[column.table_name].columns[column.column_name] = { + ...column, + is_nullable: column.is_nullable === 'YES', + }; + } + + return overview; } // Tables @@ -166,8 +211,8 @@ export default class MSSQL implements Schema { .joinRaw( `left join ( select CONSTRAINT_NAME AS CONSTRAINT_NAME, TABLE_NAME as CONSTRAINT_TABLE_NAME, COLUMN_NAME AS CONSTRAINT_COLUMN_NAME, CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, PK_SET = CASE - WHEN CONSTRAINT_NAME like '%pk%' THEN 'PRIMARY' - ELSE NULL + WHEN CONSTRAINT_NAME like '%pk%' THEN 'PRIMARY' + ELSE NULL END from ${dbName}.INFORMATION_SCHEMA.KEY_COLUMN_USAGE ) as pk ON [c].[TABLE_NAME] = [pk].[CONSTRAINT_TABLE_NAME] @@ -178,7 +223,7 @@ export default class MSSQL implements Schema { .joinRaw( `left join ( select CONSTRAINT_NAME,CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, MATCH_OPTION, DELETE_RULE, UPDATE_RULE from ${dbName}.INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS - + ) as rc ON [pk].[CONSTRAINT_NAME] = [rc].[CONSTRAINT_NAME] AND [pk].[CONSTRAINT_CATALOG] = [rc].[CONSTRAINT_CATALOG] diff --git a/packages/schema/src/dialects/oracledb.ts b/packages/schema/src/dialects/oracledb.ts index 69cf43a934..e94a854ff1 100644 --- a/packages/schema/src/dialects/oracledb.ts +++ b/packages/schema/src/dialects/oracledb.ts @@ -2,6 +2,7 @@ import Knex from 'knex'; import { Schema } from '../types/schema'; import { Table } from '../types/table'; import { Column } from '../types/column'; +import { SchemaOverview } from '../types/overview'; type RawTable = { TABLE_NAME: string; @@ -39,8 +40,46 @@ export default class oracleDB implements Schema { // Overview // =============================================================================================== async overview() { - /** @TODO */ - return {}; + const columns = await this.knex.raw( + ` + SELECT + c.TABLE_NAME as table_name, + c.COLUMN_NAME as column_name, + c.DATA_DEFAULT as default_value, + c.NULLABLE as is_nullable, + c.DATA_TYPE as data_type, + pk.CONSTRAINT_TYPE as column_key + FROM DBA_TAB_COLUMNS as c + LEFT JOIN all_constraints as pk + ON c.TABLE_NAME = pk.TABLE_NAME + AND c.CONSTRAINT_NAME = pk.CONSTRAINT_NAME + AND c.OWNER = pk.OWNER + ` + ); + + const overview: SchemaOverview = {}; + + for (const column of columns[0]) { + if (column.table_name in overview === false) { + overview[column.table_name] = { + primary: columns[0].find( + (nested: { column_key: string; table_name: string }) => { + return ( + nested.table_name === column.table_name && nested.column_key === 'P' + ); + } + )?.column_name, + columns: {}, + }; + } + + overview[column.table_name].columns[column.column_name] = { + ...column, + is_nullable: column.is_nullable === 'YES', + }; + } + + return overview; } // Tables