mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
alter plan
This commit is contained in:
parent
0d61e43431
commit
05a65dab3c
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 { 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user