From 35fc2e0f5bc0d1e6ea1c8969c3043d992a955de2 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sun, 30 May 2021 10:13:38 +0200 Subject: [PATCH] Materialized views #123 --- packages/tools/src/SqlDumper.ts | 14 ++++++++++++++ packages/tools/src/SqlGenerator.ts | 10 ++++++++++ packages/web/src/impexp/FormTablesSelect.svelte | 12 ++++++++++-- packages/web/src/modals/SqlGeneratorModal.svelte | 9 ++++----- packages/web/src/utility/common.ts | 6 ++++++ packages/web/src/widgets/SqlObjectList.svelte | 5 ++--- 6 files changed, 46 insertions(+), 10 deletions(-) diff --git a/packages/tools/src/SqlDumper.ts b/packages/tools/src/SqlDumper.ts index 8ddc9616..385bf9e1 100644 --- a/packages/tools/src/SqlDumper.ts +++ b/packages/tools/src/SqlDumper.ts @@ -293,6 +293,20 @@ export class SqlDumper { changeViewSchema(obj: ViewInfo, newSchema: string) {} renameView(obj: ViewInfo, newSchema: string) {} + createMatview(obj: ViewInfo) { + this.putRaw(obj.createSql); + this.endCommand(); + } + dropMatview(obj: ViewInfo, { testIfExists = false }) { + this.putCmd('^drop ^materialized ^view %f', obj); + } + alterMatview(obj: ViewInfo) { + this.putRaw(obj.createSql.replace(/create\s+view/i, 'ALTER VIEW')); + this.endCommand(); + } + changeMatviewSchema(obj: ViewInfo, newSchema: string) {} + renameMatview(obj: ViewInfo, newSchema: string) {} + createProcedure(obj: ProcedureInfo) { this.putRaw(obj.createSql); this.endCommand(); diff --git a/packages/tools/src/SqlGenerator.ts b/packages/tools/src/SqlGenerator.ts index 9d7ecfe1..48b0d103 100644 --- a/packages/tools/src/SqlGenerator.ts +++ b/packages/tools/src/SqlGenerator.ts @@ -30,6 +30,10 @@ interface SqlGeneratorOptions { checkIfViewExists: boolean; createViews: boolean; + dropMatviews: boolean; + checkIfMatviewExists: boolean; + createMatviews: boolean; + dropProcedures: boolean; checkIfProcedureExists: boolean; createProcedures: boolean; @@ -52,6 +56,7 @@ interface SqlGeneratorObject { export class SqlGenerator { private tables: TableInfo[]; private views: ViewInfo[]; + private matviews: ViewInfo[]; private procedures: ProcedureInfo[]; private functions: FunctionInfo[]; private triggers: TriggerInfo[]; @@ -70,6 +75,7 @@ export class SqlGenerator { this.dbinfo = extendDatabaseInfo(dbinfo); this.tables = this.extract('tables'); this.views = this.extract('views'); + this.matviews = this.extract('matviews'); this.procedures = this.extract('procedures'); this.functions = this.extract('functions'); this.triggers = this.extract('triggers'); @@ -90,6 +96,8 @@ export class SqlGenerator { if (this.checkDumper()) return; this.dropObjects(this.views, 'View'); if (this.checkDumper()) return; + this.dropObjects(this.matviews, 'Matview'); + if (this.checkDumper()) return; this.dropObjects(this.triggers, 'Trigger'); if (this.checkDumper()) return; @@ -114,6 +122,8 @@ export class SqlGenerator { if (this.checkDumper()) return; this.createObjects(this.views, 'View'); if (this.checkDumper()) return; + this.createObjects(this.matviews, 'Matview'); + if (this.checkDumper()) return; this.createObjects(this.triggers, 'Trigger'); if (this.checkDumper()) return; } finally { diff --git a/packages/web/src/impexp/FormTablesSelect.svelte b/packages/web/src/impexp/FormTablesSelect.svelte index 12c3004c..b8e4c16a 100644 --- a/packages/web/src/impexp/FormTablesSelect.svelte +++ b/packages/web/src/impexp/FormTablesSelect.svelte @@ -5,6 +5,7 @@ import { getFormContext } from '../forms/FormProviderCore.svelte'; import FormSelectField from '../forms/FormSelectField.svelte'; +import { getObjectTypeFieldLabel } from '../utility/common'; import { useDatabaseInfo, useDatabaseList } from '../utility/metadataLoaders'; export let conidName; @@ -15,19 +16,25 @@ const { values, setFieldValue } = getFormContext(); $: dbinfo = useDatabaseInfo({ conid: $values[conidName], database: $values[databaseName] }); - $: tablesOptions = _.compact([...($dbinfo?.tables || []), ...($dbinfo?.views || []), ...($dbinfo?.collections || [])]) + $: tablesOptions = _.compact([ + ...($dbinfo?.tables || []), + ...($dbinfo?.views || []), + ...($dbinfo?.matviews || []), + ...($dbinfo?.collections || []), + ]) .filter(x => !$values[schemaName] || x.schemaName == $values[schemaName]) .map(x => ({ value: x.pureName, label: x.pureName, })); +
- {#each ['tables', 'views', 'collections'] as field} + {#each ['tables', 'views', 'matviews', 'collections'] as field} {#if $dbinfo && $dbinfo[field]?.length > 0} diff --git a/packages/web/src/modals/SqlGeneratorModal.svelte b/packages/web/src/modals/SqlGeneratorModal.svelte index 9504963a..5d500fc0 100644 --- a/packages/web/src/modals/SqlGeneratorModal.svelte +++ b/packages/web/src/modals/SqlGeneratorModal.svelte @@ -31,6 +31,7 @@ import openNewTab from '../utility/openNewTab'; import ErrorInfo from '../elements/ErrorInfo.svelte'; import LoadingInfo from '../elements/LoadingInfo.svelte'; + import { getObjectTypeFieldLabel } from '../utility/common'; export let conid; export let database; @@ -49,8 +50,6 @@ export let initialObjects = null; - const OBJ_TYPE_LABELS = { Matview: 'Materialized view' }; - let busy = false; let managerSize; let objectsFilter = ''; @@ -156,7 +155,7 @@ ({ ...x, conid, database }))} module={databaseObjectAppObject} - groupFunc={data => _.startCase(data.objectTypeField)} + groupFunc={data => getObjectTypeFieldLabel(data.objectTypeField)} isExpandable={data => data.objectTypeField == 'tables' || data.objectTypeField == 'views'} filter={objectsFilter} disableContextMenu @@ -215,8 +214,8 @@ - {#each ['View', 'MatView', 'Procedure', 'Function', 'Trigger'] as objtype} -
{OBJ_TYPE_LABELS[objtype] || objtype}s
+ {#each ['View', 'Matview', 'Procedure', 'Function', 'Trigger'] as objtype} +
{getObjectTypeFieldLabel(objtype.toLowerCase() + 's')}s
{#if values[`drop${objtype}s`]} diff --git a/packages/web/src/utility/common.ts b/packages/web/src/utility/common.ts index f8df2a33..a0e24eb2 100644 --- a/packages/web/src/utility/common.ts +++ b/packages/web/src/utility/common.ts @@ -1,4 +1,5 @@ import { openedTabs } from '../stores'; +import _ from 'lodash'; export class LoadingToken { isCanceled = false; @@ -26,3 +27,8 @@ export function setSelectedTabFunc(files, tabid) { export function setSelectedTab(tabid) { openedTabs.update(tabs => setSelectedTabFunc(tabs, tabid)); } + +export function getObjectTypeFieldLabel(objectTypeField) { + if (objectTypeField == 'matviews') return 'Materialized Views'; + return _.startCase(objectTypeField); +} diff --git a/packages/web/src/widgets/SqlObjectList.svelte b/packages/web/src/widgets/SqlObjectList.svelte index f252d000..aeccb9e0 100644 --- a/packages/web/src/widgets/SqlObjectList.svelte +++ b/packages/web/src/widgets/SqlObjectList.svelte @@ -12,6 +12,7 @@ import ErrorInfo from '../elements/ErrorInfo.svelte'; import axiosInstance from '../utility/axiosInstance'; import LoadingInfo from '../elements/LoadingInfo.svelte'; +import { getObjectTypeFieldLabel } from '../utility/common'; export let conid; export let database; @@ -36,8 +37,6 @@ axiosInstance.post('database-connections/refresh', { conid, database }); }; - const OBJECT_TYPE_LABELS = { matviews: 'Materialized views' }; - {#if $status && $status.name == 'error'} @@ -65,7 +64,7 @@ ({ ...x, conid, database }))} module={databaseObjectAppObject} - groupFunc={data => OBJECT_TYPE_LABELS[data.objectTypeField] || _.startCase(data.objectTypeField)} + groupFunc={data => getObjectTypeFieldLabel(data.objectTypeField)} subItemsComponent={SubColumnParamList} isExpandable={data => data.objectTypeField == 'tables' || data.objectTypeField == 'views' || data.objectTypeField == 'matviews'}