From 8c3c32aeba287f56fc8128907e39481a58ec3ac8 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 19 Sep 2024 13:41:49 +0200 Subject: [PATCH] default schema refactor --- integration-tests/__tests__/schema-tests.spec.js | 1 + integration-tests/engines.js | 2 ++ packages/tools/src/index.ts | 1 + packages/tools/src/schemaInfoTools.ts | 15 +++++++++++++++ packages/types/dbinfo.d.ts | 2 +- packages/web/src/query/codeCompletion.ts | 13 +++++++------ .../src/backend/MsSqlAnalyser.js | 3 --- plugins/dbgate-plugin-mssql/src/backend/driver.js | 9 ++++++++- .../dbgate-plugin-postgres/src/backend/drivers.js | 3 +++ 9 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 packages/tools/src/schemaInfoTools.ts diff --git a/integration-tests/__tests__/schema-tests.spec.js b/integration-tests/__tests__/schema-tests.spec.js index 38dbed4e..cb823d09 100644 --- a/integration-tests/__tests__/schema-tests.spec.js +++ b/integration-tests/__tests__/schema-tests.spec.js @@ -32,6 +32,7 @@ describe('Schema tests', () => { const schemas2 = await driver.listSchemas(conn); expect(schemas2.find(x => x.schemaName == 'myschema')).toBeTruthy(); expect(schemas2.length).toEqual(count + 1); + expect(schemas2.find(x => x.isDefault).schemaName).toEqual(engine.defaultSchemaName); expect(structure2).toBeNull(); }) ); diff --git a/integration-tests/engines.js b/integration-tests/engines.js index 380e8c3f..a0c25388 100644 --- a/integration-tests/engines.js +++ b/integration-tests/engines.js @@ -82,6 +82,7 @@ const engines = [ }, ], supportSchemas: true, + defaultSchemaName: 'public', }, { label: 'SQL Server', @@ -107,6 +108,7 @@ const engines = [ }, ], supportSchemas: true, + defaultSchemaName: 'dbo', }, { label: 'SQLite', diff --git a/packages/tools/src/index.ts b/packages/tools/src/index.ts index 900f7aeb..46b6c36f 100644 --- a/packages/tools/src/index.ts +++ b/packages/tools/src/index.ts @@ -23,3 +23,4 @@ export * from './getLogger'; export * from './getConnectionLabel'; export * from './detectSqlFilterBehaviour'; export * from './filterBehaviours'; +export * from './schemaInfoTools'; diff --git a/packages/tools/src/schemaInfoTools.ts b/packages/tools/src/schemaInfoTools.ts new file mode 100644 index 00000000..298b4cac --- /dev/null +++ b/packages/tools/src/schemaInfoTools.ts @@ -0,0 +1,15 @@ +import { SchemaInfo, SqlDialect } from 'dbgate-types'; + +export function findDefaultSchema(schemaList: SchemaInfo[], dialect: SqlDialect) { + if (!schemaList) { + return null; + } + const dynamicDefaultSchema = schemaList.find(x => x.isDefault); + if (dynamicDefaultSchema) { + return dynamicDefaultSchema.schemaName; + } + if (dialect.defaultSchemaName && schemaList.find(x => x.schemaName == dialect.defaultSchemaName)) { + return dialect.defaultSchemaName; + } + return schemaList[0]?.schemaName; +} diff --git a/packages/types/dbinfo.d.ts b/packages/types/dbinfo.d.ts index fcf0866d..dc41dfa2 100644 --- a/packages/types/dbinfo.d.ts +++ b/packages/types/dbinfo.d.ts @@ -126,6 +126,7 @@ export interface TriggerInfo extends SqlObjectInfo {} export interface SchemaInfo { objectId?: string; schemaName: string; + isDefault?: boolean; } export interface DatabaseInfoObjects { @@ -140,5 +141,4 @@ export interface DatabaseInfoObjects { export interface DatabaseInfo extends DatabaseInfoObjects { engine?: string; - defaultSchema?: string; } diff --git a/packages/web/src/query/codeCompletion.ts b/packages/web/src/query/codeCompletion.ts index 184a86a0..27754ab4 100644 --- a/packages/web/src/query/codeCompletion.ts +++ b/packages/web/src/query/codeCompletion.ts @@ -1,8 +1,10 @@ import _ from 'lodash'; import { addCompleter, setCompleters } from 'ace-builds/src-noconflict/ext-language_tools'; -import { getDatabaseInfo, getSchemaList } from '../utility/metadataLoaders'; +import { getConnectionInfo, getDatabaseInfo, getSchemaList } from '../utility/metadataLoaders'; import analyseQuerySources from './analyseQuerySources'; import { getStringSettingsValue } from '../settings/settingsTools'; +import { findEngineDriver, findDefaultSchema } from 'dbgate-tools'; +import { getExtensions } from '../stores'; const COMMON_KEYWORDS = [ 'select', @@ -79,6 +81,9 @@ export function mountCodeCompletion({ conid, database, editor, getText }) { const line = session.getLine(cursor.row).slice(0, cursor.column); const dbinfo = await getDatabaseInfo({ conid, database }); const schemaList = await getSchemaList({ conid, database }); + const connection = await getConnectionInfo(conid); + const driver = findEngineDriver(connection, getExtensions()); + const defaultSchema = findDefaultSchema(schemaList, driver.dialect); const convertUpper = getStringSettingsValue('sqlEditor.sqlCommandsCase', 'upperCase') == 'upperCase'; @@ -168,11 +173,7 @@ export function mountCodeCompletion({ conid, database, editor, getText }) { } else { list = [ ...(onlyTables ? [] : list), - ...createTableLikeList( - schemaList, - dbinfo, - x => !dbinfo.defaultSchema || dbinfo.defaultSchema == x.schemaName - ), + ...createTableLikeList(schemaList, dbinfo, x => !defaultSchema || defaultSchema == x.schemaName), ...(onlyTables ? [] diff --git a/plugins/dbgate-plugin-mssql/src/backend/MsSqlAnalyser.js b/plugins/dbgate-plugin-mssql/src/backend/MsSqlAnalyser.js index 7c34e19e..592bef7b 100644 --- a/plugins/dbgate-plugin-mssql/src/backend/MsSqlAnalyser.js +++ b/plugins/dbgate-plugin-mssql/src/backend/MsSqlAnalyser.js @@ -92,8 +92,6 @@ class MsSqlAnalyser extends DatabaseAnalyser { const indexesRows = await this.analyserQuery('indexes', ['tables']); this.feedback({ analysingMessage: 'Loading index columns' }); const indexcolsRows = await this.analyserQuery('indexcols', ['tables']); - this.feedback({ analysingMessage: 'Loading default schema' }); - const defaultSchemaRows = await this.driver.query(this.pool, 'SELECT SCHEMA_NAME() as name'); this.feedback({ analysingMessage: 'Loading table sizes' }); const tableSizes = await this.analyserQuery('tableSizes'); @@ -173,7 +171,6 @@ class MsSqlAnalyser extends DatabaseAnalyser { views, procedures, functions, - defaultSchema: defaultSchemaRows.rows[0] ? defaultSchemaRows.rows[0].name : undefined, }; } diff --git a/plugins/dbgate-plugin-mssql/src/backend/driver.js b/plugins/dbgate-plugin-mssql/src/backend/driver.js index f7fdcca1..eddc2a97 100644 --- a/plugins/dbgate-plugin-mssql/src/backend/driver.js +++ b/plugins/dbgate-plugin-mssql/src/backend/driver.js @@ -152,7 +152,14 @@ const driver = { }, async listSchemas(pool) { const { rows } = await this.query(pool, 'select schema_id as objectId, name as schemaName from sys.schemas'); - return rows; + + const defaultSchemaRows = await this.query(pool, 'SELECT SCHEMA_NAME() as name'); + const defaultSchema = defaultSchemaRows.rows[0]?.name; + + return rows.map(x => ({ + ...x, + isDefault: x.schemaName == defaultSchema, + })); }, }; diff --git a/plugins/dbgate-plugin-postgres/src/backend/drivers.js b/plugins/dbgate-plugin-postgres/src/backend/drivers.js index 8019cb6d..d93e7ab6 100644 --- a/plugins/dbgate-plugin-postgres/src/backend/drivers.js +++ b/plugins/dbgate-plugin-postgres/src/backend/drivers.js @@ -273,10 +273,13 @@ const drivers = driverBases.map(driverBase => ({ pool, 'select oid as "object_id", nspname as "schema_name" from pg_catalog.pg_namespace' ); + const defaultSchemaRows = await this.query(pool, 'SHOW SEARCH_PATH;'); + const searchPath = defaultSchemaRows.rows[0]?.search_path?.replace('"$user",', '')?.trim(); const schemas = schemaRows.rows.map(x => ({ schemaName: x.schema_name, objectId: x.object_id, + isDefault: x.schema_name == searchPath, })); return schemas;