mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
db diff supports views, procedures, functions
This commit is contained in:
parent
1765ab4118
commit
73b338d38a
@ -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 || '';
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
@ -141,7 +155,8 @@
|
||||
driver
|
||||
);
|
||||
|
||||
$: sqlPreview = getAlterTableScript(
|
||||
$: sqlPreview = getAlterObjectScript(
|
||||
diffRows[pairIndex]?.objectTypeField,
|
||||
diffRows[pairIndex]?.target,
|
||||
diffRows[pairIndex]?.source,
|
||||
dbDiffOptions,
|
||||
@ -329,7 +344,7 @@
|
||||
disableFocusOutline
|
||||
columns={[
|
||||
{ fieldName: 'isChecked', header: '', width: '50px', slot: 1, headerSlot: 2 },
|
||||
{ fieldName: 'type', header: 'Type', width: '100px' },
|
||||
{ fieldName: 'type', header: 'Type', width: '100px', slot: 3 },
|
||||
{ fieldName: 'sourceSchemaName', header: 'Schema' },
|
||||
{ fieldName: 'sourcePureName', header: 'Name' },
|
||||
{ fieldName: 'state', header: 'Action', width: '100px' },
|
||||
@ -353,6 +368,10 @@
|
||||
<FontIcon icon="icon check-all" />
|
||||
</InlineButton>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="3" let:row>
|
||||
<FontIcon icon={row.typeIcon} />
|
||||
{row.typeName}
|
||||
</svelte:fragment>
|
||||
</ScrollableTableControl>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user