From 73b338d38a3cf101f44b443daf28414e5a2007c1 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sun, 7 Nov 2021 11:18:21 +0100 Subject: [PATCH] db diff supports views, procedures, functions --- packages/tools/src/computeDiffRows.ts | 80 +++++++++++++++----- packages/tools/src/diffTools.ts | 7 +- packages/web/src/tabs/CompareModelTab.svelte | 23 +++++- 3 files changed, 88 insertions(+), 22 deletions(-) diff --git a/packages/tools/src/computeDiffRows.ts b/packages/tools/src/computeDiffRows.ts index 772d3cf0..4e48c084 100644 --- a/packages/tools/src/computeDiffRows.ts +++ b/packages/tools/src/computeDiffRows.ts @@ -1,5 +1,5 @@ -import { DbDiffOptions, testEqualColumns, testEqualTables } from './diffTools'; -import { DatabaseInfo, EngineDriver, TableInfo } from 'dbgate-types'; +import { DbDiffOptions, testEqualColumns, testEqualTables, testEqualSqlObjects } from './diffTools'; +import { DatabaseInfo, EngineDriver, SqlObjectInfo, TableInfo } from 'dbgate-types'; export function computeDiffRowsCore(sourceList, targetList, testEqual) { const res = []; @@ -35,6 +35,34 @@ export function computeDiffRowsCore(sourceList, targetList, testEqual) { return res; } +const COMPARE_DEFS = { + tables: { + test: testEqualTables, + name: 'Table', + icon: 'img table', + }, + views: { + test: testEqualSqlObjects, + name: 'View', + icon: 'img view', + }, + matviews: { + test: testEqualSqlObjects, + name: 'Materialized view', + icon: 'img view', + }, + procedures: { + test: testEqualSqlObjects, + name: 'Procedure', + icon: 'img procedure', + }, + functions: { + test: testEqualSqlObjects, + name: 'Function', + icon: 'img function', + }, +}; + export function computeDbDiffRows( sourceDb: DatabaseInfo, targetDb: DatabaseInfo, @@ -42,18 +70,29 @@ export function computeDbDiffRows( driver: EngineDriver ) { if (!sourceDb || !targetDb || !driver) return []; - return computeDiffRowsCore(sourceDb.tables, targetDb.tables, (a, b) => - testEqualTables(a, b, opts, targetDb, driver) - ).map(row => ({ - ...row, - sourceSchemaName: row?.source?.schemaName, - sourcePureName: row?.source?.pureName, - targetSchemaName: row?.target?.schemaName, - targetPureName: row?.target?.pureName, - identifier: `${row?.source?.schemaName || row?.target?.schemaName}.${ - row?.source?.pureName || row?.target?.pureName - }`, - })); + + const res = []; + for (const objectTypeField of ['tables', 'views', 'procedures', 'matviews', 'functions']) { + const defs = COMPARE_DEFS[objectTypeField]; + res.push( + ...computeDiffRowsCore(sourceDb[objectTypeField], targetDb[objectTypeField], (a, b) => + defs.test(a, b, opts, targetDb, driver) + ).map(row => ({ + ...row, + sourceSchemaName: row?.source?.schemaName, + sourcePureName: row?.source?.pureName, + targetSchemaName: row?.target?.schemaName, + targetPureName: row?.target?.pureName, + typeName: defs.name, + typeIcon: defs.icon, + identifier: `${row?.source?.schemaName || row?.target?.schemaName}.${ + row?.source?.pureName || row?.target?.pureName + }`, + objectTypeField, + })) + ); + } + return res; } export function computeTableDiffColumns( @@ -76,9 +115,12 @@ export function computeTableDiffColumns( })); } -export function getCreateObjectScript(table: TableInfo, driver: EngineDriver) { - if (!table || !driver) return ''; - const dmp = driver.createDumper(); - dmp.createTable(table); - return dmp.s; +export function getCreateObjectScript(obj: TableInfo | SqlObjectInfo, driver: EngineDriver) { + if (!obj || !driver) return ''; + if (obj.objectTypeField == 'tables') { + const dmp = driver.createDumper(); + dmp.createTable(obj as TableInfo); + return dmp.s; + } + return (obj as SqlObjectInfo).createSql || ''; } diff --git a/packages/tools/src/diffTools.ts b/packages/tools/src/diffTools.ts index 7a013617..4afd75ef 100644 --- a/packages/tools/src/diffTools.ts +++ b/packages/tools/src/diffTools.ts @@ -5,6 +5,7 @@ import { EngineDriver, NamedObjectInfo, SqlDialect, + SqlObjectInfo, TableInfo, } from 'dbgate-types'; import uuidv1 from 'uuid/v1'; @@ -381,6 +382,10 @@ export function testEqualTables( return plan.operations.length == 0; } +export function testEqualSqlObjects(a: SqlObjectInfo, b: SqlObjectInfo, opts: DbDiffOptions) { + return a.createSql == b.createSql; +} + export function createAlterTablePlan( oldTable: TableInfo, newTable: TableInfo, @@ -425,7 +430,7 @@ export function createAlterDatabasePlan( if (!opts.noDropSqlObject) { plan.dropSqlObject(oldobj); } - } else if (newobj.createSql != oldobj.createSql) { + } else if (!testEqualSqlObjects(oldobj.createSql, newobj.createSql, opts)) { plan.recreates.sqlObjects += 1; if (!opts.noDropSqlObject) { plan.dropSqlObject(oldobj); diff --git a/packages/web/src/tabs/CompareModelTab.svelte b/packages/web/src/tabs/CompareModelTab.svelte index 8242e976..56b9673c 100644 --- a/packages/web/src/tabs/CompareModelTab.svelte +++ b/packages/web/src/tabs/CompareModelTab.svelte @@ -65,6 +65,20 @@ } return 5; } + + function getAlterObjectScript(objectTypeField, oldObject, newObject, opts, db, driver) { + if ((!oldObject && !newObject) || !driver) { + return { sql: '' }; + } + + if (objectTypeField == 'tables') { + return getAlterTableScript(oldObject, newObject, opts, db, driver); + } + const dmp = driver.createDumper(); + if (oldObject) dmp.dropSqlObject(oldObject); + if (newObject) dmp.createSqlObject(newObject); + return { sql: dmp.s }; + }