mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-28 19:56:00 +00:00
alter plan
This commit is contained in:
117
packages/tools/src/alterPlan.ts
Normal file
117
packages/tools/src/alterPlan.ts
Normal 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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,13 @@
|
|||||||
import { ColumnInfo, TableInfo } from 'dbgate-types';
|
import { ColumnInfo, DatabaseInfo, TableInfo } from 'dbgate-types';
|
||||||
import uuidv1 from 'uuid/v1';
|
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 {
|
export function generateTablePairingId(table: TableInfo): TableInfo {
|
||||||
if (!table) return table;
|
if (!table) return table;
|
||||||
@@ -27,3 +35,58 @@ export function generateTablePairingId(table: TableInfo): TableInfo {
|
|||||||
}
|
}
|
||||||
return table;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user