mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-22 23:56:00 +00:00
schemaList moved from dbinfo to separate request
This commit is contained in:
@@ -23,17 +23,16 @@ describe('Schema tests', () => {
|
|||||||
testWrapper(async (conn, driver, engine) => {
|
testWrapper(async (conn, driver, engine) => {
|
||||||
await baseStructure(conn, driver);
|
await baseStructure(conn, driver);
|
||||||
const structure1 = await driver.analyseFull(conn);
|
const structure1 = await driver.analyseFull(conn);
|
||||||
expect(structure1.schemas.find(x => x.schemaName == 'myschema')).toBeFalsy();
|
const schemas1 = await driver.listSchemas(conn);
|
||||||
const count = structure1.schemas.length;
|
expect(schemas1.find(x => x.schemaName == 'myschema')).toBeFalsy();
|
||||||
|
const count = schemas1.length;
|
||||||
expect(structure1.tables.length).toEqual(2);
|
expect(structure1.tables.length).toEqual(2);
|
||||||
await runCommandOnDriver(conn, driver, dmp => dmp.createSchema('myschema'));
|
await runCommandOnDriver(conn, driver, dmp => dmp.createSchema('myschema'));
|
||||||
const structure2 = await driver.analyseIncremental(conn, structure1);
|
const structure2 = await driver.analyseIncremental(conn, structure1);
|
||||||
expect(structure2.schemas.find(x => x.schemaName == 'myschema')).toBeTruthy();
|
const schemas2 = await driver.listSchemas(conn);
|
||||||
expect(structure2.tables.length).toEqual(2);
|
expect(schemas2.find(x => x.schemaName == 'myschema')).toBeTruthy();
|
||||||
expect(structure2.schemas.length).toEqual(count + 1);
|
expect(schemas2.length).toEqual(count + 1);
|
||||||
|
expect(structure2).toBeNull();
|
||||||
const structure3 = await driver.analyseIncremental(conn, structure2);
|
|
||||||
expect(structure3).toBeNull();
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -44,29 +43,14 @@ describe('Schema tests', () => {
|
|||||||
await runCommandOnDriver(conn, driver, dmp => dmp.createSchema('myschema'));
|
await runCommandOnDriver(conn, driver, dmp => dmp.createSchema('myschema'));
|
||||||
|
|
||||||
const structure1 = await driver.analyseFull(conn);
|
const structure1 = await driver.analyseFull(conn);
|
||||||
expect(structure1.schemas.find(x => x.schemaName == 'myschema')).toBeTruthy();
|
const schemas1 = await driver.listSchemas(conn);
|
||||||
|
expect(schemas1.find(x => x.schemaName == 'myschema')).toBeTruthy();
|
||||||
expect(structure1.tables.length).toEqual(2);
|
expect(structure1.tables.length).toEqual(2);
|
||||||
await runCommandOnDriver(conn, driver, dmp => dmp.dropSchema('myschema'));
|
await runCommandOnDriver(conn, driver, dmp => dmp.dropSchema('myschema'));
|
||||||
const structure2 = await driver.analyseIncremental(conn, structure1);
|
const structure2 = await driver.analyseIncremental(conn, structure1);
|
||||||
expect(structure2.schemas.find(x => x.schemaName == 'myschema')).toBeFalsy();
|
const schemas2 = await driver.listSchemas(conn);
|
||||||
expect(structure2.tables.length).toEqual(2);
|
expect(schemas2.find(x => x.schemaName == 'myschema')).toBeFalsy();
|
||||||
|
expect(structure2).toBeNull();
|
||||||
const structure3 = await driver.analyseIncremental(conn, structure2);
|
|
||||||
expect(structure3).toBeNull();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
test.each(engines.filter(x => x.supportSchemas).map(engine => [engine.label, engine]))(
|
|
||||||
'Create table - keep schemas - %s',
|
|
||||||
testWrapper(async (conn, driver, engine) => {
|
|
||||||
await baseStructure(conn, driver);
|
|
||||||
const structure1 = await driver.analyseFull(conn);
|
|
||||||
const count = structure1.schemas.length;
|
|
||||||
expect(structure1.tables.length).toEqual(2);
|
|
||||||
await driver.query(conn, `create table t3 (id int not null primary key)`);
|
|
||||||
const structure2 = await driver.analyseIncremental(conn, structure1);
|
|
||||||
expect(structure2.tables.length).toEqual(3);
|
|
||||||
expect(structure2.schemas.length).toEqual(count);
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ module.exports = {
|
|||||||
return res.result || null;
|
return res.result || null;
|
||||||
},
|
},
|
||||||
|
|
||||||
async loadDataCore(msgtype, { conid, database, ...args }, req) {
|
async loadDataCore(msgtype, { conid, database, ...args }, req) {
|
||||||
testConnectionPermission(conid, req);
|
testConnectionPermission(conid, req);
|
||||||
const opened = await this.ensureOpened(conid, database);
|
const opened = await this.ensureOpened(conid, database);
|
||||||
const res = await this.sendRequest(opened, { msgtype, ...args });
|
const res = await this.sendRequest(opened, { msgtype, ...args });
|
||||||
@@ -213,6 +213,12 @@ module.exports = {
|
|||||||
return res.result || null;
|
return res.result || null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
schemaList_meta: true,
|
||||||
|
async schemaList({ conid, database }, req) {
|
||||||
|
testConnectionPermission(conid, req);
|
||||||
|
return this.loadDataCore('schemaList', { conid, database });
|
||||||
|
},
|
||||||
|
|
||||||
loadKeys_meta: true,
|
loadKeys_meta: true,
|
||||||
async loadKeys({ conid, database, root, filter }, req) {
|
async loadKeys({ conid, database, root, filter }, req) {
|
||||||
testConnectionPermission(conid, req);
|
testConnectionPermission(conid, req);
|
||||||
|
|||||||
@@ -213,6 +213,10 @@ async function handleDriverDataCore(msgid, callMethod) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleSchemaList({ msgid }) {
|
||||||
|
return handleDriverDataCore(msgid, driver => driver.listSchemas(systemConnection));
|
||||||
|
}
|
||||||
|
|
||||||
async function handleCollectionData({ msgid, options }) {
|
async function handleCollectionData({ msgid, options }) {
|
||||||
return handleDriverDataCore(msgid, driver => driver.readCollection(systemConnection, options));
|
return handleDriverDataCore(msgid, driver => driver.readCollection(systemConnection, options));
|
||||||
}
|
}
|
||||||
@@ -337,6 +341,7 @@ const messageHandlers = {
|
|||||||
loadFieldValues: handleLoadFieldValues,
|
loadFieldValues: handleLoadFieldValues,
|
||||||
sqlSelect: handleSqlSelect,
|
sqlSelect: handleSqlSelect,
|
||||||
exportKeys: handleExportKeys,
|
exportKeys: handleExportKeys,
|
||||||
|
schemaList: handleSchemaList,
|
||||||
// runCommand: handleRunCommand,
|
// runCommand: handleRunCommand,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import _pick from 'lodash/pick';
|
|||||||
import _compact from 'lodash/compact';
|
import _compact from 'lodash/compact';
|
||||||
import { getLogger } from './getLogger';
|
import { getLogger } from './getLogger';
|
||||||
import { type Logger } from 'pinomin';
|
import { type Logger } from 'pinomin';
|
||||||
import stableStringify from 'json-stable-stringify';
|
|
||||||
|
|
||||||
const logger = getLogger('dbAnalyser');
|
const logger = getLogger('dbAnalyser');
|
||||||
|
|
||||||
@@ -71,10 +70,7 @@ export class DatabaseAnalyser {
|
|||||||
async fullAnalysis() {
|
async fullAnalysis() {
|
||||||
const res = this.addEngineField(await this._runAnalysis());
|
const res = this.addEngineField(await this._runAnalysis());
|
||||||
// console.log('FULL ANALYSIS', res);
|
// console.log('FULL ANALYSIS', res);
|
||||||
return {
|
return res;
|
||||||
...res,
|
|
||||||
schemas: await this.readSchemaList(),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async singleObjectAnalysis(name, typeField) {
|
async singleObjectAnalysis(name, typeField) {
|
||||||
@@ -91,10 +87,6 @@ export class DatabaseAnalyser {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
async readSchemaList() {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
async incrementalAnalysis(structure) {
|
async incrementalAnalysis(structure) {
|
||||||
this.structure = structure;
|
this.structure = structure;
|
||||||
|
|
||||||
@@ -107,35 +99,22 @@ export class DatabaseAnalyser {
|
|||||||
const structureModifications = modifications.filter(x => x.action != 'setTableRowCounts');
|
const structureModifications = modifications.filter(x => x.action != 'setTableRowCounts');
|
||||||
const setTableRowCounts = modifications.find(x => x.action == 'setTableRowCounts');
|
const setTableRowCounts = modifications.find(x => x.action == 'setTableRowCounts');
|
||||||
|
|
||||||
let structureUpdated = null;
|
let structureWithRowCounts = null;
|
||||||
if (setTableRowCounts) {
|
if (setTableRowCounts) {
|
||||||
const newStructure = mergeTableRowCounts(structure, setTableRowCounts.rowCounts);
|
const newStructure = mergeTableRowCounts(structure, setTableRowCounts.rowCounts);
|
||||||
if (areDifferentRowCounts(structure, newStructure)) {
|
if (areDifferentRowCounts(structure, newStructure)) {
|
||||||
structureUpdated = newStructure;
|
structureWithRowCounts = newStructure;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const schemas = await this.readSchemaList();
|
|
||||||
const areSchemasDifferent = stableStringify(schemas) != stableStringify(this.structure.schemas);
|
|
||||||
if (areSchemasDifferent) {
|
|
||||||
structureUpdated = {
|
|
||||||
...structure,
|
|
||||||
...structureUpdated,
|
|
||||||
schemas,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (structureModifications.length == 0) {
|
if (structureModifications.length == 0) {
|
||||||
return structureUpdated ? this.addEngineField(structureUpdated) : null;
|
return structureWithRowCounts ? this.addEngineField(structureWithRowCounts) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.modifications = structureModifications;
|
this.modifications = structureModifications;
|
||||||
if (structureUpdated) this.structure = structureUpdated;
|
if (structureWithRowCounts) this.structure = structureWithRowCounts;
|
||||||
logger.info({ modifications: this.modifications }, 'DB modifications detected:');
|
logger.info({ modifications: this.modifications }, 'DB modifications detected:');
|
||||||
return {
|
return this.addEngineField(this.mergeAnalyseResult(await this._runAnalysis()));
|
||||||
...this.addEngineField(this.mergeAnalyseResult(await this._runAnalysis())),
|
|
||||||
schemas,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mergeAnalyseResult(newlyAnalysed) {
|
mergeAnalyseResult(newlyAnalysed) {
|
||||||
@@ -359,7 +338,6 @@ export class DatabaseAnalyser {
|
|||||||
functions: [],
|
functions: [],
|
||||||
procedures: [],
|
procedures: [],
|
||||||
triggers: [],
|
triggers: [],
|
||||||
schemas: [],
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
packages/types/dbinfo.d.ts
vendored
1
packages/types/dbinfo.d.ts
vendored
@@ -139,7 +139,6 @@ export interface DatabaseInfoObjects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface DatabaseInfo extends DatabaseInfoObjects {
|
export interface DatabaseInfo extends DatabaseInfoObjects {
|
||||||
schemas?: SchemaInfo[];
|
|
||||||
engine?: string;
|
engine?: string;
|
||||||
defaultSchema?: string;
|
defaultSchema?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
2
packages/types/engines.d.ts
vendored
2
packages/types/engines.d.ts
vendored
@@ -11,6 +11,7 @@ import {
|
|||||||
FunctionInfo,
|
FunctionInfo,
|
||||||
TriggerInfo,
|
TriggerInfo,
|
||||||
CollectionInfo,
|
CollectionInfo,
|
||||||
|
SchemaInfo,
|
||||||
} from './dbinfo';
|
} from './dbinfo';
|
||||||
import { FilterBehaviour } from './filter-type';
|
import { FilterBehaviour } from './filter-type';
|
||||||
|
|
||||||
@@ -230,6 +231,7 @@ export interface EngineDriver extends FilterBehaviourProvider {
|
|||||||
): any[];
|
): any[];
|
||||||
// adapts table info from different source (import, other database) to be suitable for this database
|
// adapts table info from different source (import, other database) to be suitable for this database
|
||||||
adaptTableInfo(table: TableInfo): TableInfo;
|
adaptTableInfo(table: TableInfo): TableInfo;
|
||||||
|
async listSchemas(pool): SchemaInfo[];
|
||||||
|
|
||||||
analyserClass?: any;
|
analyserClass?: any;
|
||||||
dumperClass?: any;
|
dumperClass?: any;
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getFormContext } from '../forms/FormProviderCore.svelte';
|
import { getFormContext } from '../forms/FormProviderCore.svelte';
|
||||||
import FormSelectField from '../forms/FormSelectField.svelte';
|
import FormSelectField from '../forms/FormSelectField.svelte';
|
||||||
import { useDatabaseInfo, useDatabaseList } from '../utility/metadataLoaders';
|
import { useSchemaList } from '../utility/metadataLoaders';
|
||||||
|
|
||||||
export let conidName;
|
export let conidName;
|
||||||
export let databaseName;
|
export let databaseName;
|
||||||
|
|
||||||
const { values } = getFormContext();
|
const { values } = getFormContext();
|
||||||
$: dbinfo = useDatabaseInfo({ conid: $values[conidName], database: values[databaseName] });
|
$: schemaList = useSchemaList({ conid: $values[conidName], database: values[databaseName] });
|
||||||
|
|
||||||
$: schemaOptions = (($dbinfo && $dbinfo.schemas) || []).map(schema => ({
|
$: schemaOptions = ($schemaList || []).map(schema => ({
|
||||||
value: schema.schemaName,
|
value: schema.schemaName,
|
||||||
label: schema.schemaName,
|
label: schema.schemaName,
|
||||||
}));
|
}));
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { addCompleter, setCompleters } from 'ace-builds/src-noconflict/ext-language_tools';
|
import { addCompleter, setCompleters } from 'ace-builds/src-noconflict/ext-language_tools';
|
||||||
import { getDatabaseInfo } from '../utility/metadataLoaders';
|
import { getDatabaseInfo, getSchemaList } from '../utility/metadataLoaders';
|
||||||
import analyseQuerySources from './analyseQuerySources';
|
import analyseQuerySources from './analyseQuerySources';
|
||||||
import { getStringSettingsValue } from '../settings/settingsTools';
|
import { getStringSettingsValue } from '../settings/settingsTools';
|
||||||
|
|
||||||
@@ -24,9 +24,9 @@ const COMMON_KEYWORDS = [
|
|||||||
'go',
|
'go',
|
||||||
];
|
];
|
||||||
|
|
||||||
function createTableLikeList(dbinfo, schemaCondition) {
|
function createTableLikeList(schemaList, dbinfo, schemaCondition) {
|
||||||
return [
|
return [
|
||||||
...(dbinfo.schemas?.map(x => ({
|
...(schemaList?.map(x => ({
|
||||||
name: x.schemaName,
|
name: x.schemaName,
|
||||||
value: x.schemaName,
|
value: x.schemaName,
|
||||||
caption: x.schemaName,
|
caption: x.schemaName,
|
||||||
@@ -78,6 +78,7 @@ export function mountCodeCompletion({ conid, database, editor, getText }) {
|
|||||||
const cursor = session.selection.cursor;
|
const cursor = session.selection.cursor;
|
||||||
const line = session.getLine(cursor.row).slice(0, cursor.column);
|
const line = session.getLine(cursor.row).slice(0, cursor.column);
|
||||||
const dbinfo = await getDatabaseInfo({ conid, database });
|
const dbinfo = await getDatabaseInfo({ conid, database });
|
||||||
|
const schemaList = await getSchemaList({ conid, database });
|
||||||
|
|
||||||
const convertUpper = getStringSettingsValue('sqlEditor.sqlCommandsCase', 'upperCase') == 'upperCase';
|
const convertUpper = getStringSettingsValue('sqlEditor.sqlCommandsCase', 'upperCase') == 'upperCase';
|
||||||
|
|
||||||
@@ -147,9 +148,9 @@ export function mountCodeCompletion({ conid, database, editor, getText }) {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const schema = (dbinfo.schemas || []).find(x => x.schemaName == colMatch[1]);
|
const schema = (schemaList || []).find(x => x.schemaName == colMatch[1]);
|
||||||
if (schema) {
|
if (schema) {
|
||||||
list = createTableLikeList(dbinfo, x => x.schemaName == schema.schemaName);
|
list = createTableLikeList(schemaList, dbinfo, x => x.schemaName == schema.schemaName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -167,7 +168,11 @@ export function mountCodeCompletion({ conid, database, editor, getText }) {
|
|||||||
} else {
|
} else {
|
||||||
list = [
|
list = [
|
||||||
...(onlyTables ? [] : list),
|
...(onlyTables ? [] : list),
|
||||||
...createTableLikeList(dbinfo, x => !dbinfo.defaultSchema || dbinfo.defaultSchema == x.schemaName),
|
...createTableLikeList(
|
||||||
|
schemaList,
|
||||||
|
dbinfo,
|
||||||
|
x => !dbinfo.defaultSchema || dbinfo.defaultSchema == x.schemaName
|
||||||
|
),
|
||||||
|
|
||||||
...(onlyTables
|
...(onlyTables
|
||||||
? []
|
? []
|
||||||
|
|||||||
@@ -249,6 +249,10 @@
|
|||||||
<FormCheckboxField label={`Use only database ${defaultDatabase}`} name="singleDatabase" disabled={isConnected} />
|
<FormCheckboxField label={`Use only database ${defaultDatabase}`} name="singleDatabase" disabled={isConnected} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#if driver?.showConnectionField('useSeparateSchemas', $values, showConnectionFieldArgs)}
|
||||||
|
<FormCheckboxField label={`Use schemas separately (use this if you have many large schemas)`} name="useSeparateSchemas" disabled={isConnected} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#if driver}
|
{#if driver}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-6 mr-1">
|
<div class="col-6 mr-1">
|
||||||
|
|||||||
@@ -92,6 +92,7 @@
|
|||||||
export let driver;
|
export let driver;
|
||||||
export let resetCounter;
|
export let resetCounter;
|
||||||
export let isCreateTable;
|
export let isCreateTable;
|
||||||
|
export let schemaList;
|
||||||
|
|
||||||
$: isWritable = !!setTableInfo;
|
$: isWritable = !!setTableInfo;
|
||||||
|
|
||||||
@@ -172,7 +173,7 @@
|
|||||||
title="Table properties"
|
title="Table properties"
|
||||||
fieldDefinitions={tableFormOptions ?? []}
|
fieldDefinitions={tableFormOptions ?? []}
|
||||||
pureNameTitle={isCreateTable ? 'Table name' : null}
|
pureNameTitle={isCreateTable ? 'Table name' : null}
|
||||||
schemaList={isCreateTable && dbInfo?.schemas?.length >= 0 ? dbInfo?.schemas : null}
|
schemaList={isCreateTable && schemaList?.length >= 0 ? schemaList : null}
|
||||||
values={_.pick(tableInfo, ['schemaName', 'pureName', ...(tableFormOptions ?? []).map(x => x.name)])}
|
values={_.pick(tableInfo, ['schemaName', 'pureName', ...(tableFormOptions ?? []).map(x => x.name)])}
|
||||||
onChangeValues={vals => {
|
onChangeValues={vals => {
|
||||||
if (!_.isEmpty(vals)) {
|
if (!_.isEmpty(vals)) {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
import TableEditor from '../tableeditor/TableEditor.svelte';
|
import TableEditor from '../tableeditor/TableEditor.svelte';
|
||||||
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
||||||
|
|
||||||
import { useConnectionInfo, useDatabaseInfo, useDbCore } from '../utility/metadataLoaders';
|
import { useConnectionInfo, useDatabaseInfo, useDbCore, useSchemaList } from '../utility/metadataLoaders';
|
||||||
import { showModal } from '../modals/modalTools';
|
import { showModal } from '../modals/modalTools';
|
||||||
import ConfirmSqlModal from '../modals/ConfirmSqlModal.svelte';
|
import ConfirmSqlModal from '../modals/ConfirmSqlModal.svelte';
|
||||||
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
|
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
|
||||||
@@ -75,6 +75,7 @@
|
|||||||
$: tableInfoWithPairingId = $tableInfo ? generateTablePairingId($tableInfo) : null;
|
$: tableInfoWithPairingId = $tableInfo ? generateTablePairingId($tableInfo) : null;
|
||||||
$: connection = useConnectionInfo({ conid });
|
$: connection = useConnectionInfo({ conid });
|
||||||
$: driver = findEngineDriver($connection, $extensions);
|
$: driver = findEngineDriver($connection, $extensions);
|
||||||
|
$: schemaList = useSchemaList({ conid, database });
|
||||||
|
|
||||||
const { editorState, editorValue, setEditorData, clearEditorData } = useEditorData({ tabid });
|
const { editorState, editorValue, setEditorData, clearEditorData } = useEditorData({ tabid });
|
||||||
|
|
||||||
@@ -146,6 +147,7 @@
|
|||||||
bind:this={domEditor}
|
bind:this={domEditor}
|
||||||
tableInfo={showTable}
|
tableInfo={showTable}
|
||||||
dbInfo={$dbInfo}
|
dbInfo={$dbInfo}
|
||||||
|
schemaList={$schemaList}
|
||||||
{driver}
|
{driver}
|
||||||
{resetCounter}
|
{resetCounter}
|
||||||
isCreateTable={objectTypeField == 'tables' && !$editorValue?.base}
|
isCreateTable={objectTypeField == 'tables' && !$editorValue?.base}
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ const databaseInfoLoader = ({ conid, database }) => ({
|
|||||||
transform: extendDatabaseInfo,
|
transform: extendDatabaseInfo,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const schemaListLoader = ({ conid, database }) => ({
|
||||||
|
url: 'database-connections/schema-list',
|
||||||
|
params: { conid, database },
|
||||||
|
reloadTrigger: { key: `schema-list-changed`, conid, database },
|
||||||
|
});
|
||||||
|
|
||||||
// const tableInfoLoader = ({ conid, database, schemaName, pureName }) => ({
|
// const tableInfoLoader = ({ conid, database, schemaName, pureName }) => ({
|
||||||
// url: 'metadata/table-info',
|
// url: 'metadata/table-info',
|
||||||
// params: { conid, database, schemaName, pureName },
|
// params: { conid, database, schemaName, pureName },
|
||||||
@@ -449,3 +455,9 @@ export function useAuthTypes(args) {
|
|||||||
// export function useDatabaseKeys(args) {
|
// export function useDatabaseKeys(args) {
|
||||||
// return useCore(databaseKeysLoader, args);
|
// return useCore(databaseKeysLoader, args);
|
||||||
// }
|
// }
|
||||||
|
export function getSchemaList(args) {
|
||||||
|
return getCore(schemaListLoader, args);
|
||||||
|
}
|
||||||
|
export function useSchemaList(args) {
|
||||||
|
return useCore(schemaListLoader, args);
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,14 +4,13 @@
|
|||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import FontIcon from '../icons/FontIcon.svelte';
|
import FontIcon from '../icons/FontIcon.svelte';
|
||||||
import { DatabaseInfo } from 'dbgate-types';
|
|
||||||
import { showModal } from '../modals/modalTools';
|
import { showModal } from '../modals/modalTools';
|
||||||
import ConfirmModal from '../modals/ConfirmModal.svelte';
|
import ConfirmModal from '../modals/ConfirmModal.svelte';
|
||||||
import { runOperationOnDatabase } from '../modals/ConfirmSqlModal.svelte';
|
import { runOperationOnDatabase } from '../modals/ConfirmSqlModal.svelte';
|
||||||
import InputTextModal from '../modals/InputTextModal.svelte';
|
import InputTextModal from '../modals/InputTextModal.svelte';
|
||||||
import { appliedCurrentSchema } from '../stores';
|
import { appliedCurrentSchema } from '../stores';
|
||||||
|
|
||||||
export let dbinfo: DatabaseInfo;
|
export let schemaList;
|
||||||
export let selectedSchema;
|
export let selectedSchema;
|
||||||
export let objectList;
|
export let objectList;
|
||||||
|
|
||||||
@@ -44,7 +43,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$: schemaList = _.uniq(
|
$: schemaList = _.uniq(
|
||||||
_.compact([selectedSchema, ...Object.keys(countBySchema), ...(dbinfo?.schemas?.map(x => x.schemaName) ?? [])])
|
_.compact([selectedSchema, ...Object.keys(countBySchema), ...(schemaList?.map(x => x.schemaName) ?? [])])
|
||||||
);
|
);
|
||||||
$: countBySchema = computeCountBySchema(objectList ?? []);
|
$: countBySchema = computeCountBySchema(objectList ?? []);
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
import InlineButton from '../buttons/InlineButton.svelte';
|
import InlineButton from '../buttons/InlineButton.svelte';
|
||||||
import SearchInput from '../elements/SearchInput.svelte';
|
import SearchInput from '../elements/SearchInput.svelte';
|
||||||
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
|
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
|
||||||
import { useConnectionInfo, useDatabaseInfo, useDatabaseStatus, useUsedApps } from '../utility/metadataLoaders';
|
import { useConnectionInfo, useDatabaseInfo, useDatabaseStatus, useSchemaList, useUsedApps } from '../utility/metadataLoaders';
|
||||||
import SearchBoxWrapper from '../elements/SearchBoxWrapper.svelte';
|
import SearchBoxWrapper from '../elements/SearchBoxWrapper.svelte';
|
||||||
import AppObjectList from '../appobj/AppObjectList.svelte';
|
import AppObjectList from '../appobj/AppObjectList.svelte';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
@@ -46,6 +46,7 @@
|
|||||||
|
|
||||||
$: objects = useDatabaseInfo({ conid, database });
|
$: objects = useDatabaseInfo({ conid, database });
|
||||||
$: status = useDatabaseStatus({ conid, database });
|
$: status = useDatabaseStatus({ conid, database });
|
||||||
|
$: schemaList = useSchemaList({ conid, database });
|
||||||
|
|
||||||
$: connection = useConnectionInfo({ conid });
|
$: connection = useConnectionInfo({ conid });
|
||||||
$: driver = findEngineDriver($connection, $extensions);
|
$: driver = findEngineDriver($connection, $extensions);
|
||||||
@@ -144,7 +145,7 @@
|
|||||||
</InlineButton>
|
</InlineButton>
|
||||||
</SearchBoxWrapper>
|
</SearchBoxWrapper>
|
||||||
<SchemaSelector
|
<SchemaSelector
|
||||||
dbinfo={$objects}
|
schemaList={$schemaList}
|
||||||
bind:selectedSchema
|
bind:selectedSchema
|
||||||
objectList={flatFilteredList}
|
objectList={flatFilteredList}
|
||||||
valueStorageKey={`sql-object-list-schema-${conid}-${database}`}
|
valueStorageKey={`sql-object-list-schema-${conid}-${database}`}
|
||||||
|
|||||||
@@ -79,12 +79,6 @@ class MsSqlAnalyser extends DatabaseAnalyser {
|
|||||||
this.singleObjectId = resId.rows[0].id;
|
this.singleObjectId = resId.rows[0].id;
|
||||||
}
|
}
|
||||||
|
|
||||||
async readSchemaList() {
|
|
||||||
const schemaRows = await this.analyserQuery('getSchemas');
|
|
||||||
const schemas = schemaRows.rows;
|
|
||||||
return schemas;
|
|
||||||
}
|
|
||||||
|
|
||||||
async _runAnalysis() {
|
async _runAnalysis() {
|
||||||
this.feedback({ analysingMessage: 'Loading tables' });
|
this.feedback({ analysingMessage: 'Loading tables' });
|
||||||
const tablesRows = await this.analyserQuery('tables', ['tables']);
|
const tablesRows = await this.analyserQuery('tables', ['tables']);
|
||||||
|
|||||||
@@ -150,6 +150,10 @@ const driver = {
|
|||||||
getAccessTokenFromAuth: (connection, req) => {
|
getAccessTokenFromAuth: (connection, req) => {
|
||||||
return req?.user?.msentraToken;
|
return req?.user?.msentraToken;
|
||||||
},
|
},
|
||||||
|
async listSchemas(pool) {
|
||||||
|
const { rows } = await this.query(pool, 'select schema_id as objectId, name as schemaName from sys.schemas');
|
||||||
|
return rows;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
driver.initialize = dbgateEnv => {
|
driver.initialize = dbgateEnv => {
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
module.exports = `select schema_id as objectId, name as schemaName from sys.schemas`;
|
|
||||||
@@ -8,7 +8,6 @@ const loadSqlCode = require('./loadSqlCode');
|
|||||||
const views = require('./views');
|
const views = require('./views');
|
||||||
const programmables = require('./programmables');
|
const programmables = require('./programmables');
|
||||||
const viewColumns = require('./viewColumns');
|
const viewColumns = require('./viewColumns');
|
||||||
const getSchemas = require('./getSchemas');
|
|
||||||
const indexes = require('./indexes');
|
const indexes = require('./indexes');
|
||||||
const indexcols = require('./indexcols');
|
const indexcols = require('./indexcols');
|
||||||
|
|
||||||
@@ -22,7 +21,6 @@ module.exports = {
|
|||||||
views,
|
views,
|
||||||
programmables,
|
programmables,
|
||||||
viewColumns,
|
viewColumns,
|
||||||
getSchemas,
|
|
||||||
indexes,
|
indexes,
|
||||||
indexcols,
|
indexcols,
|
||||||
tableSizes,
|
tableSizes,
|
||||||
|
|||||||
@@ -312,17 +312,6 @@ class Analyser extends DatabaseAnalyser {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
async readSchemaList() {
|
|
||||||
const schemaRows = await this.analyserQuery('getSchemas');
|
|
||||||
|
|
||||||
const schemas = schemaRows.rows.map(x => ({
|
|
||||||
schemaName: x.schema_name,
|
|
||||||
objectId: `schemas:${x.schema_name}`,
|
|
||||||
}));
|
|
||||||
|
|
||||||
return schemas;
|
|
||||||
}
|
|
||||||
|
|
||||||
async _getFastSnapshot() {
|
async _getFastSnapshot() {
|
||||||
const tableModificationsQueryData = this.driver.dialect.stringAgg
|
const tableModificationsQueryData = this.driver.dialect.stringAgg
|
||||||
? await this.analyserQuery('tableModifications')
|
? await this.analyserQuery('tableModifications')
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const stream = require('stream');
|
|||||||
const driverBases = require('../frontend/drivers');
|
const driverBases = require('../frontend/drivers');
|
||||||
const Analyser = require('./Analyser');
|
const Analyser = require('./Analyser');
|
||||||
const pg = require('pg');
|
const pg = require('pg');
|
||||||
const { getLogger, createBulkInsertStreamBase, makeUniqueColumnNames } = global.DBGATE_PACKAGES['dbgate-tools'];;
|
const { getLogger, createBulkInsertStreamBase, makeUniqueColumnNames } = global.DBGATE_PACKAGES['dbgate-tools'];
|
||||||
|
|
||||||
const logger = getLogger('postreDriver');
|
const logger = getLogger('postreDriver');
|
||||||
|
|
||||||
@@ -267,6 +267,20 @@ const drivers = driverBases.map(driverBase => ({
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async listSchemas(pool) {
|
||||||
|
const schemaRows = await this.query(
|
||||||
|
pool,
|
||||||
|
'select oid as "object_id", nspname as "schema_name" from pg_catalog.pg_namespace'
|
||||||
|
);
|
||||||
|
|
||||||
|
const schemas = schemaRows.rows.map(x => ({
|
||||||
|
schemaName: x.schema_name,
|
||||||
|
objectId: x.object_id,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return schemas;
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
module.exports = drivers;
|
module.exports = drivers;
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
module.exports = `select oid as "object_id", nspname as "schema_name" from pg_catalog.pg_namespace`;
|
|
||||||
@@ -12,7 +12,6 @@ const matviewColumns = require('./matviewColumns');
|
|||||||
const indexes = require('./indexes');
|
const indexes = require('./indexes');
|
||||||
const indexcols = require('./indexcols');
|
const indexcols = require('./indexcols');
|
||||||
const uniqueNames = require('./uniqueNames');
|
const uniqueNames = require('./uniqueNames');
|
||||||
const getSchemas = require('./getSchemas');
|
|
||||||
const geometryColumns = require('./geometryColumns');
|
const geometryColumns = require('./geometryColumns');
|
||||||
const geographyColumns = require('./geographyColumns');
|
const geographyColumns = require('./geographyColumns');
|
||||||
|
|
||||||
@@ -40,5 +39,4 @@ module.exports = {
|
|||||||
uniqueNames,
|
uniqueNames,
|
||||||
geometryColumns,
|
geometryColumns,
|
||||||
geographyColumns,
|
geographyColumns,
|
||||||
getSchemas,
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -136,7 +136,9 @@ const postgresDriverBase = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
['authType', 'user', 'password', 'defaultDatabase', 'singleDatabase', 'isReadOnly'].includes(field) ||
|
['authType', 'user', 'password', 'defaultDatabase', 'singleDatabase', 'isReadOnly', 'useSeparateSchemas'].includes(
|
||||||
|
field
|
||||||
|
) ||
|
||||||
(values.authType == 'socket' && ['socketPath'].includes(field)) ||
|
(values.authType == 'socket' && ['socketPath'].includes(field)) ||
|
||||||
(values.authType != 'socket' && ['server', 'port'].includes(field))
|
(values.authType != 'socket' && ['server', 'port'].includes(field))
|
||||||
);
|
);
|
||||||
@@ -242,7 +244,8 @@ const redshiftDriver = {
|
|||||||
title: 'Amazon Redshift',
|
title: 'Amazon Redshift',
|
||||||
defaultPort: 5439,
|
defaultPort: 5439,
|
||||||
databaseUrlPlaceholder: 'e.g. redshift-cluster-1.xxxx.redshift.amazonaws.com:5439/dev',
|
databaseUrlPlaceholder: 'e.g. redshift-cluster-1.xxxx.redshift.amazonaws.com:5439/dev',
|
||||||
showConnectionField: (field, values) => ['databaseUrl', 'user', 'password', 'isReadOnly'].includes(field),
|
showConnectionField: (field, values) =>
|
||||||
|
['databaseUrl', 'user', 'password', 'isReadOnly', 'useSeparateSchemas'].includes(field),
|
||||||
beforeConnectionSave: connection => {
|
beforeConnectionSave: connection => {
|
||||||
const { databaseUrl } = connection;
|
const { databaseUrl } = connection;
|
||||||
if (databaseUrl) {
|
if (databaseUrl) {
|
||||||
|
|||||||
Reference in New Issue
Block a user