alter plan

This commit is contained in:
Jan Prochazka 2021-06-25 17:04:01 +02:00
parent 0d61e43431
commit 05a65dab3c
2 changed files with 181 additions and 1 deletions

View File

@ -0,0 +1,117 @@
import { ColumnInfo, ConstraintInfo, DatabaseInfo, TableInfo } from '../../types';
interface AlterOperation_CreateTable {
operationType: 'createTable';
newObject: TableInfo;
}
interface AlterOperation_DropTable {
operationType: 'dropTable';
oldObject: TableInfo;
}
interface AlterOperation_CreateColumn {
operationType: 'createColumn';
newObject: ColumnInfo;
}
interface AlterOperation_ChangeColumn {
operationType: 'changeColumn';
oldObject: ColumnInfo;
newObject: ColumnInfo;
}
interface AlterOperation_DropColumn {
operationType: 'dropColumn';
oldObject: ColumnInfo;
}
interface AlterOperation_CreateConstraint {
operationType: 'createConstraint';
newObject: ConstraintInfo;
}
interface AlterOperation_ChangeConstraint {
operationType: 'changeConstraint';
oldObject: ConstraintInfo;
newObject: ConstraintInfo;
}
interface AlterOperation_DropConstraint {
operationType: 'dropConstraint';
oldObject: ConstraintInfo;
}
type AlterOperation =
| AlterOperation_CreateColumn
| AlterOperation_ChangeColumn
| AlterOperation_DropColumn
| AlterOperation_CreateConstraint
| AlterOperation_ChangeConstraint
| AlterOperation_DropConstraint
| AlterOperation_CreateTable
| AlterOperation_DropTable;
export class AlterPlan {
operations: AlterOperation[] = [];
constructor(public db: DatabaseInfo) {}
createTable(table: TableInfo) {
this.operations.push({
operationType: 'createTable',
newObject: table,
});
}
dropTable(table: TableInfo) {
this.operations.push({
operationType: 'dropTable',
oldObject: table,
});
}
createColumn(column: ColumnInfo) {
this.operations.push({
operationType: 'createColumn',
newObject: column,
});
}
changeColumn(oldColumn: ColumnInfo, newColumn: ColumnInfo) {
this.operations.push({
operationType: 'changeColumn',
oldObject: oldColumn,
newObject: newColumn,
});
}
dropColumn(column: ColumnInfo) {
this.operations.push({
operationType: 'dropColumn',
oldObject: column,
});
}
createConstraint(constraint: ConstraintInfo) {
this.operations.push({
operationType: 'createConstraint',
newObject: constraint,
});
}
changeConstraint(oldConstraint: ConstraintInfo, newConstraint: ConstraintInfo) {
this.operations.push({
operationType: 'changeConstraint',
oldObject: oldConstraint,
newObject: newConstraint,
});
}
dropConstraint(constraint: ConstraintInfo) {
this.operations.push({
operationType: 'dropConstraint',
oldObject: constraint,
});
}
}

View File

@ -1,5 +1,13 @@
import { ColumnInfo, TableInfo } from 'dbgate-types';
import { ColumnInfo, DatabaseInfo, TableInfo } from 'dbgate-types';
import uuidv1 from 'uuid/v1';
import { AlterPlan } from './alterPlan';
export interface DbDiffOptions {
allowRecreateTable: boolean;
allowRecreateConstraint: boolean;
allowRecreateSpecificObject: boolean;
allowPairRenamedTables: boolean;
}
export function generateTablePairingId(table: TableInfo): TableInfo {
if (!table) return table;
@ -27,3 +35,58 @@ export function generateTablePairingId(table: TableInfo): TableInfo {
}
return table;
}
function getTableConstraints(table: TableInfo) {
const res = [];
if (table.primaryKey) res.push(table.primaryKey);
if (table.foreignKeys) res.push(...table.foreignKeys);
if (table.indexes) res.push(...table.indexes);
if (table.checks) res.push(...table.checks);
return res;
}
function createPairs(oldList, newList, additionalCondition = null) {
const res = [];
for (const a of oldList) {
const b = newList.find(x => x.pairingId == a.pairingId || (additionalCondition && additionalCondition(a, b)));
if (b) {
res.push([a, b]);
} else {
res.push([a, null]);
}
}
for (const b of newList) {
if (!res.find(x => x[1] == b)) {
res.push([null, b]);
}
}
return res;
}
function planAlterTable(plan: AlterPlan, oldTable: TableInfo, newTable: TableInfo, options: DbDiffOptions) {
// if (oldTable.primaryKey)
const constraintPairs = createPairs(
getTableConstraints(oldTable),
getTableConstraints(newTable),
(a, b) => a.constraintType == 'primaryKey' && b.constraintType == 'primaryKey'
);
const columnPairs = createPairs(oldTable.columns, newTable.columns);
constraintPairs.filter(x => x[1] == null).forEach(x => plan.dropConstraint(x));
}
export function createAlterTablePlan(
oldTable: TableInfo,
newTable: TableInfo,
options: DbDiffOptions,
db: DatabaseInfo
): AlterPlan {
const plan = new AlterPlan(db);
if (oldTable == null) {
plan.createTable(newTable);
} else {
planAlterTable(plan, oldTable, newTable, options);
}
return plan;
}