mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-02 19:33:59 +00:00
alter processor
This commit is contained in:
33
integration-tests/__tests__/alter-processor.spec.js
Normal file
33
integration-tests/__tests__/alter-processor.spec.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
const engines = require('../engines');
|
||||||
|
const uuidv1 = require('uuid/v1');
|
||||||
|
const { testWrapper } = require('../tools');
|
||||||
|
|
||||||
|
async function testTableDiff(conn, driver, mangle) {
|
||||||
|
await driver.query(conn, 'create table t1 (col1 int not null)');
|
||||||
|
|
||||||
|
const structure1 = await driver.analyseFull(conn);
|
||||||
|
mangle(structure1.tables[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('Alter processor', () => {
|
||||||
|
test.each(engines.map(engine => [engine.label, engine]))(
|
||||||
|
'Add column - %s',
|
||||||
|
testWrapper(async (conn, driver, engine) => {
|
||||||
|
testTableDiff(conn, driver, tbl =>
|
||||||
|
tbl.columns.push({
|
||||||
|
columnName: 'added',
|
||||||
|
dataType: 'int',
|
||||||
|
pairingId: uuidv1(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
// console.log('ENGINE', engine);
|
||||||
|
// for (const sql of initSql) await driver.query(conn, sql);
|
||||||
|
|
||||||
|
// await driver.query(conn, object.create1);
|
||||||
|
// const structure = await driver.analyseFull(conn);
|
||||||
|
|
||||||
|
// expect(structure[type].length).toEqual(1);
|
||||||
|
// expect(structure[type][0]).toEqual(type.includes('views') ? view1Match : obj1Match);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -15,12 +15,13 @@ import {
|
|||||||
IndexInfo,
|
IndexInfo,
|
||||||
UniqueInfo,
|
UniqueInfo,
|
||||||
CheckInfo,
|
CheckInfo,
|
||||||
|
AlterProcessor,
|
||||||
} from 'dbgate-types';
|
} from 'dbgate-types';
|
||||||
import _isString from 'lodash/isString';
|
import _isString from 'lodash/isString';
|
||||||
import _isNumber from 'lodash/isNumber';
|
import _isNumber from 'lodash/isNumber';
|
||||||
import _isDate from 'lodash/isDate';
|
import _isDate from 'lodash/isDate';
|
||||||
|
|
||||||
export class SqlDumper {
|
export class SqlDumper implements AlterProcessor {
|
||||||
s = '';
|
s = '';
|
||||||
driver: EngineDriver;
|
driver: EngineDriver;
|
||||||
dialect: SqlDialect;
|
dialect: SqlDialect;
|
||||||
@@ -416,8 +417,8 @@ export class SqlDumper {
|
|||||||
|
|
||||||
renameConstraint(constraint: ConstraintInfo, newName: string) {}
|
renameConstraint(constraint: ConstraintInfo, newName: string) {}
|
||||||
|
|
||||||
createColumn(table: TableInfo, column: ColumnInfo, constraints: ConstraintInfo[]) {
|
createColumn(column: ColumnInfo, constraints: ConstraintInfo[]) {
|
||||||
this.put('^alter ^table %f ^add %i ', table, column.columnName);
|
this.put('^alter ^table %f ^add %i ', column, column.columnName);
|
||||||
this.columnDefinition(column);
|
this.columnDefinition(column);
|
||||||
this.inlineConstraints(constraints);
|
this.inlineConstraints(constraints);
|
||||||
this.endCommand();
|
this.endCommand();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ColumnInfo, ConstraintInfo, DatabaseInfo, TableInfo } from '../../types';
|
import { AlterProcessor, ColumnInfo, ConstraintInfo, DatabaseInfo, NamedObjectInfo, TableInfo } from '../../types';
|
||||||
|
|
||||||
interface AlterOperation_CreateTable {
|
interface AlterOperation_CreateTable {
|
||||||
operationType: 'createTable';
|
operationType: 'createTable';
|
||||||
@@ -10,6 +10,12 @@ interface AlterOperation_DropTable {
|
|||||||
oldObject: TableInfo;
|
oldObject: TableInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface AlterOperation_RenameTable {
|
||||||
|
operationType: 'renameTable';
|
||||||
|
object: TableInfo;
|
||||||
|
newName: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface AlterOperation_CreateColumn {
|
interface AlterOperation_CreateColumn {
|
||||||
operationType: 'createColumn';
|
operationType: 'createColumn';
|
||||||
newObject: ColumnInfo;
|
newObject: ColumnInfo;
|
||||||
@@ -21,6 +27,12 @@ interface AlterOperation_ChangeColumn {
|
|||||||
newObject: ColumnInfo;
|
newObject: ColumnInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface AlterOperation_RenameColumn {
|
||||||
|
operationType: 'renameColumn';
|
||||||
|
object: ColumnInfo;
|
||||||
|
newName: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface AlterOperation_DropColumn {
|
interface AlterOperation_DropColumn {
|
||||||
operationType: 'dropColumn';
|
operationType: 'dropColumn';
|
||||||
oldObject: ColumnInfo;
|
oldObject: ColumnInfo;
|
||||||
@@ -42,6 +54,12 @@ interface AlterOperation_DropConstraint {
|
|||||||
oldObject: ConstraintInfo;
|
oldObject: ConstraintInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface AlterOperation_RenameConstraint {
|
||||||
|
operationType: 'renameConstraint';
|
||||||
|
object: ConstraintInfo;
|
||||||
|
newName: string;
|
||||||
|
}
|
||||||
|
|
||||||
type AlterOperation =
|
type AlterOperation =
|
||||||
| AlterOperation_CreateColumn
|
| AlterOperation_CreateColumn
|
||||||
| AlterOperation_ChangeColumn
|
| AlterOperation_ChangeColumn
|
||||||
@@ -50,7 +68,10 @@ type AlterOperation =
|
|||||||
| AlterOperation_ChangeConstraint
|
| AlterOperation_ChangeConstraint
|
||||||
| AlterOperation_DropConstraint
|
| AlterOperation_DropConstraint
|
||||||
| AlterOperation_CreateTable
|
| AlterOperation_CreateTable
|
||||||
| AlterOperation_DropTable;
|
| AlterOperation_DropTable
|
||||||
|
| AlterOperation_RenameTable
|
||||||
|
| AlterOperation_RenameColumn
|
||||||
|
| AlterOperation_RenameConstraint;
|
||||||
|
|
||||||
export class AlterPlan {
|
export class AlterPlan {
|
||||||
operations: AlterOperation[] = [];
|
operations: AlterOperation[] = [];
|
||||||
@@ -114,4 +135,53 @@ export class AlterPlan {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renameTable(table: TableInfo, newName: string) {
|
||||||
|
this.operations.push({
|
||||||
|
operationType: 'renameTable',
|
||||||
|
object: table,
|
||||||
|
newName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renameColumn(column: ColumnInfo, newName: string) {
|
||||||
|
this.operations.push({
|
||||||
|
operationType: 'renameColumn',
|
||||||
|
object: column,
|
||||||
|
newName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renameConstraint(constraint: ConstraintInfo, newName: string) {
|
||||||
|
this.operations.push({
|
||||||
|
operationType: 'renameConstraint',
|
||||||
|
object: constraint,
|
||||||
|
newName,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function runAlterOperation(op: AlterOperation, processor: AlterProcessor) {
|
||||||
|
switch (op.operationType) {
|
||||||
|
case 'createTable':
|
||||||
|
processor.createTable(op.newObject);
|
||||||
|
break;
|
||||||
|
case 'changeColumn':
|
||||||
|
processor.changeColumn(op.oldObject, op.newObject);
|
||||||
|
break;
|
||||||
|
case 'createColumn':
|
||||||
|
processor.createColumn(op.newObject, []);
|
||||||
|
break;
|
||||||
|
case 'dropColumn':
|
||||||
|
processor.dropColumn(op.oldObject);
|
||||||
|
break;
|
||||||
|
case 'changeConstraint':
|
||||||
|
processor.changeConstraint(op.oldObject, op.newObject);
|
||||||
|
break;
|
||||||
|
case 'createConstraint':
|
||||||
|
processor.createConstraint(op.newObject);
|
||||||
|
break;
|
||||||
|
case 'dropConstraint':
|
||||||
|
processor.dropConstraint(op.oldObject);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
69
packages/tools/src/database-info-alter-processor.ts
Normal file
69
packages/tools/src/database-info-alter-processor.ts
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
import { ColumnInfo, ConstraintInfo, DatabaseInfo, ForeignKeyInfo, PrimaryKeyInfo, TableInfo } from '../../types';
|
||||||
|
|
||||||
|
export class DatabaseInfoAlterProcessor {
|
||||||
|
constructor(public db: DatabaseInfo) {}
|
||||||
|
|
||||||
|
createTable(table: TableInfo) {
|
||||||
|
this.db.tables.push(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
dropTable(table: TableInfo) {
|
||||||
|
this.db.tables = this.db.tables.filter(x => x.pureName != table.pureName && x.schemaName != table.schemaName);
|
||||||
|
}
|
||||||
|
|
||||||
|
createColumn(column: ColumnInfo) {
|
||||||
|
const table = this.db.tables.find(x => x.pureName == column.pureName && x.schemaName == column.schemaName);
|
||||||
|
table.columns.push(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
changeColumn(oldColumn: ColumnInfo, newColumn: ColumnInfo) {
|
||||||
|
const table = this.db.tables.find(x => x.pureName == oldColumn.pureName && x.schemaName == oldColumn.schemaName);
|
||||||
|
table.columns = table.columns.map(x => (x.columnName == oldColumn.columnName ? newColumn : x));
|
||||||
|
}
|
||||||
|
|
||||||
|
dropColumn(column: ColumnInfo) {
|
||||||
|
const table = this.db.tables.find(x => x.pureName == column.pureName && x.schemaName == column.schemaName);
|
||||||
|
table.columns = table.columns.filter(x => x.columnName != column.columnName);
|
||||||
|
}
|
||||||
|
|
||||||
|
createConstraint(constraint: ConstraintInfo) {
|
||||||
|
const table = this.db.tables.find(x => x.pureName == constraint.pureName && x.schemaName == constraint.schemaName);
|
||||||
|
switch (constraint.constraintType) {
|
||||||
|
case 'primaryKey':
|
||||||
|
table.primaryKey = constraint as PrimaryKeyInfo;
|
||||||
|
break;
|
||||||
|
case 'foreignKey':
|
||||||
|
table.foreignKeys.push(constraint as ForeignKeyInfo);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changeConstraint(oldConstraint: ConstraintInfo, newConstraint: ConstraintInfo) {
|
||||||
|
const table = this.db.tables.find(
|
||||||
|
x => x.pureName == oldConstraint.pureName && x.schemaName == oldConstraint.schemaName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
dropConstraint(constraint: ConstraintInfo) {
|
||||||
|
const table = this.db.tables.find(x => x.pureName == constraint.pureName && x.schemaName == constraint.schemaName);
|
||||||
|
switch (constraint.constraintType) {
|
||||||
|
case 'primaryKey':
|
||||||
|
table.primaryKey = null;
|
||||||
|
break;
|
||||||
|
case 'foreignKey':
|
||||||
|
table.foreignKeys = table.foreignKeys.filter(x => x.constraintName != constraint.constraintName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renameTable(table: TableInfo, newName: string) {
|
||||||
|
this.db.tables.find(x => x.pureName == table.pureName && x.schemaName == table.schemaName).pureName = newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
renameColumn(column: ColumnInfo, newName: string) {
|
||||||
|
const table = this.db.tables.find(x => x.pureName == column.pureName && x.schemaName == column.schemaName);
|
||||||
|
table.columns.find(x => x.columnName == column.columnName).columnName = newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
renameConstraint(constraint: ConstraintInfo, newName: string) {}
|
||||||
|
}
|
||||||
@@ -1,12 +1,19 @@
|
|||||||
import { ColumnInfo, DatabaseInfo, TableInfo } from 'dbgate-types';
|
import { ColumnInfo, DatabaseInfo, EngineDriver, NamedObjectInfo, TableInfo } from 'dbgate-types';
|
||||||
import uuidv1 from 'uuid/v1';
|
import uuidv1 from 'uuid/v1';
|
||||||
import { AlterPlan } from './alterPlan';
|
import { AlterPlan } from './alterPlan';
|
||||||
|
|
||||||
|
type DbDiffSchemaMode = 'strict' | 'ignore' | 'ignoreImplicit';
|
||||||
|
|
||||||
export interface DbDiffOptions {
|
export interface DbDiffOptions {
|
||||||
allowRecreateTable: boolean;
|
allowRecreateTable: boolean;
|
||||||
allowRecreateConstraint: boolean;
|
allowRecreateConstraint: boolean;
|
||||||
allowRecreateSpecificObject: boolean;
|
allowRecreateSpecificObject: boolean;
|
||||||
allowPairRenamedTables: boolean;
|
allowPairRenamedTables: boolean;
|
||||||
|
|
||||||
|
ignoreCase: boolean;
|
||||||
|
schemaMode: DbDiffSchemaMode;
|
||||||
|
leftImplicitSchema: string;
|
||||||
|
rightImplicitSchema: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateTablePairingId(table: TableInfo): TableInfo {
|
export function generateTablePairingId(table: TableInfo): TableInfo {
|
||||||
@@ -36,6 +43,160 @@ export function generateTablePairingId(table: TableInfo): TableInfo {
|
|||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testEqualNames(a: string, b: string, opts: DbDiffOptions) {
|
||||||
|
if (opts.ignoreCase) return a.toLowerCase() == b.toLowerCase();
|
||||||
|
return a == b;
|
||||||
|
}
|
||||||
|
|
||||||
|
function testEqualSchemas(lschema: string, rschema: string, opts: DbDiffOptions) {
|
||||||
|
if (opts.schemaMode == 'ignore') lschema = null;
|
||||||
|
if (opts.schemaMode == 'ignoreImplicit' && lschema == opts.leftImplicitSchema) lschema = null;
|
||||||
|
if (opts.schemaMode == 'ignore') rschema = null;
|
||||||
|
if (opts.schemaMode == 'ignoreImplicit' && rschema == opts.rightImplicitSchema) rschema = null;
|
||||||
|
return testEqualNames(lschema, rschema, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testEqualFullNames(lft: NamedObjectInfo, rgt: NamedObjectInfo, opts: DbDiffOptions) {
|
||||||
|
if (lft == null || rgt == null) return lft == rgt;
|
||||||
|
return testEqualSchemas(lft.schemaName, rgt.schemaName, opts) && testEqualNames(lft.pureName, rgt.pureName, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testEqualsColumns(
|
||||||
|
a: ColumnInfo,
|
||||||
|
b: ColumnInfo,
|
||||||
|
checkName: boolean,
|
||||||
|
checkDefault: boolean,
|
||||||
|
opts: DbDiffOptions
|
||||||
|
) {
|
||||||
|
if (checkName && !testEqualNames(a.columnName, b.columnName, opts)) {
|
||||||
|
// opts.DiffLogger.Trace("Column, different name: {0}; {1}", a, b);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//if (!DbDiffTool.EqualFullNames(a.Domain, b.Domain, opts))
|
||||||
|
//{
|
||||||
|
// opts.DiffLogger.Trace("Column {0}, {1}: different domain: {2}; {3}", a, b, a.Domain, b.Domain);
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
if (a.computedExpression != b.computedExpression) {
|
||||||
|
// opts.DiffLogger.Trace(
|
||||||
|
// 'Column {0}, {1}: different computed expression: {2}; {3}',
|
||||||
|
// a,
|
||||||
|
// b,
|
||||||
|
// a.ComputedExpression,
|
||||||
|
// b.ComputedExpression
|
||||||
|
// );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (a.computedExpression != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (checkDefault) {
|
||||||
|
if (a.defaultValue == null) {
|
||||||
|
if (a.defaultValue != b.defaultValue) {
|
||||||
|
// opts.DiffLogger.Trace(
|
||||||
|
// 'Column {0}, {1}: different default values: {2}; {3}',
|
||||||
|
// a,
|
||||||
|
// b,
|
||||||
|
// a.DefaultValue,
|
||||||
|
// b.DefaultValue
|
||||||
|
// );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (a.defaultValue != b.defaultValue) {
|
||||||
|
// opts.DiffLogger.Trace(
|
||||||
|
// 'Column {0}, {1}: different default values: {2}; {3}',
|
||||||
|
// a,
|
||||||
|
// b,
|
||||||
|
// a.DefaultValue,
|
||||||
|
// b.DefaultValue
|
||||||
|
// );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (a.defaultConstraint != b.defaultConstraint) {
|
||||||
|
// opts.DiffLogger.Trace(
|
||||||
|
// 'Column {0}, {1}: different default constraint names: {2}; {3}',
|
||||||
|
// a,
|
||||||
|
// b,
|
||||||
|
// a.DefaultConstraint,
|
||||||
|
// b.DefaultConstraint
|
||||||
|
// );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (a.notNull != b.notNull) {
|
||||||
|
// opts.DiffLogger.Trace('Column {0}, {1}: different nullable: {2}; {3}', a, b, a.NotNull, b.NotNull);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (a.autoIncrement != b.autoIncrement) {
|
||||||
|
// opts.DiffLogger.Trace('Column {0}, {1}: different autoincrement: {2}; {3}', a, b, a.AutoIncrement, b.AutoIncrement);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (a.isSparse != b.isSparse) {
|
||||||
|
// opts.DiffLogger.Trace('Column {0}, {1}: different is_sparse: {2}; {3}', a, b, a.IsSparse, b.IsSparse);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!testEqualTypes(a, b, opts)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//var btype = b.DataType;
|
||||||
|
//var atype = a.DataType;
|
||||||
|
//if (pairing != null && pairing.Target != null && pairing.Source.Dialect != null)
|
||||||
|
//{
|
||||||
|
// btype = pairing.Source.Dialect.MigrateDataType(b, btype, pairing.Source.Dialect.GetDefaultMigrationProfile(), null);
|
||||||
|
// btype = pairing.Source.Dialect.GenericTypeToSpecific(btype).ToGenericType();
|
||||||
|
|
||||||
|
// // normalize type
|
||||||
|
// atype = pairing.Source.Dialect.GenericTypeToSpecific(atype).ToGenericType();
|
||||||
|
//}
|
||||||
|
//if (!EqualTypes(atype, btype, opts))
|
||||||
|
//{
|
||||||
|
// opts.DiffLogger.Trace("Column {0}, {1}: different types: {2}; {3}", a, b, a.DataType, b.DataType);
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
//if (!opts.IgnoreColumnCollation && a.Collation != b.Collation)
|
||||||
|
//{
|
||||||
|
// opts.DiffLogger.Trace("Column {0}, {1}: different collations: {2}; {3}", a, b, a.Collation, b.Collation);
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
//if (!opts.IgnoreColumnCharacterSet && a.CharacterSet != b.CharacterSet)
|
||||||
|
//{
|
||||||
|
// opts.DiffLogger.Trace("Column {0}, {1}: different character sets: {2}; {3}", a, b, a.CharacterSet, b.CharacterSet);
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function testEqualTypes(a: ColumnInfo, b: ColumnInfo, opts: DbDiffOptions) {
|
||||||
|
if (a.dataType != b.dataType) {
|
||||||
|
// opts.DiffLogger.Trace("Column {0}, {1}: different types: {2}; {3}", a, b, a.DataType, b.DataType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (a.Length != b.Length)
|
||||||
|
//{
|
||||||
|
// opts.DiffLogger.Trace("Column {0}, {1}: different lengths: {2}; {3}", a, b, a.Length, b.Length);
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (a.Precision != b.Precision)
|
||||||
|
//{
|
||||||
|
// opts.DiffLogger.Trace("Column {0}, {1}: different lengths: {2}; {3}", a, b, a.Precision, b.Precision);
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (a.Scale != b.Scale)
|
||||||
|
//{
|
||||||
|
// opts.DiffLogger.Trace("Column {0}, {1}: different scale: {2}; {3}", a, b, a.Scale, b.Scale);
|
||||||
|
// return false;
|
||||||
|
//}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function getTableConstraints(table: TableInfo) {
|
function getTableConstraints(table: TableInfo) {
|
||||||
const res = [];
|
const res = [];
|
||||||
if (table.primaryKey) res.push(table.primaryKey);
|
if (table.primaryKey) res.push(table.primaryKey);
|
||||||
@@ -63,30 +224,61 @@ function createPairs(oldList, newList, additionalCondition = null) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
function planAlterTable(plan: AlterPlan, oldTable: TableInfo, newTable: TableInfo, options: DbDiffOptions) {
|
function planAlterTable(plan: AlterPlan, oldTable: TableInfo, newTable: TableInfo, opts: DbDiffOptions) {
|
||||||
// if (oldTable.primaryKey)
|
// if (oldTable.primaryKey)
|
||||||
|
|
||||||
|
const columnPairs = createPairs(oldTable.columns, newTable.columns);
|
||||||
const constraintPairs = createPairs(
|
const constraintPairs = createPairs(
|
||||||
getTableConstraints(oldTable),
|
getTableConstraints(oldTable),
|
||||||
getTableConstraints(newTable),
|
getTableConstraints(newTable),
|
||||||
(a, b) => a.constraintType == 'primaryKey' && b.constraintType == 'primaryKey'
|
(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));
|
constraintPairs.filter(x => x[1] == null).forEach(x => plan.dropConstraint(x[0]));
|
||||||
|
columnPairs.filter(x => x[1] == null).forEach(x => plan.dropColumn(x[0]));
|
||||||
|
|
||||||
|
if (!testEqualFullNames(oldTable, newTable, opts)) {
|
||||||
|
plan.renameTable(oldTable, newTable.pureName);
|
||||||
|
}
|
||||||
|
|
||||||
|
columnPairs.filter(x => x[0] == null).forEach(x => plan.createColumn(x[1]));
|
||||||
|
|
||||||
|
columnPairs
|
||||||
|
.filter(x => x[0] && x[1])
|
||||||
|
.forEach(x => {
|
||||||
|
if (!testEqualsColumns(x[0], x[1], true, true, opts)) {
|
||||||
|
if (!testEqualsColumns(x[0], x[1], false, true, opts)) {
|
||||||
|
plan.renameColumn(x[0], x[1].columnName);
|
||||||
|
} else {
|
||||||
|
plan.changeColumn(x[0], x[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
constraintPairs.filter(x => x[0] == null).forEach(x => plan.createConstraint(x[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createAlterTablePlan(
|
export function createAlterTablePlan(
|
||||||
oldTable: TableInfo,
|
oldTable: TableInfo,
|
||||||
newTable: TableInfo,
|
newTable: TableInfo,
|
||||||
options: DbDiffOptions,
|
opts: DbDiffOptions,
|
||||||
db: DatabaseInfo
|
db: DatabaseInfo
|
||||||
): AlterPlan {
|
): AlterPlan {
|
||||||
const plan = new AlterPlan(db);
|
const plan = new AlterPlan(db);
|
||||||
if (oldTable == null) {
|
if (oldTable == null) {
|
||||||
plan.createTable(newTable);
|
plan.createTable(newTable);
|
||||||
} else {
|
} else {
|
||||||
planAlterTable(plan, oldTable, newTable, options);
|
planAlterTable(plan, oldTable, newTable, opts);
|
||||||
}
|
}
|
||||||
return plan;
|
return plan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getAlterTableScript(
|
||||||
|
oldTable: TableInfo,
|
||||||
|
newTable: TableInfo,
|
||||||
|
opts: DbDiffOptions,
|
||||||
|
db: DatabaseInfo,
|
||||||
|
driver: EngineDriver
|
||||||
|
): string {
|
||||||
|
const plan = createAlterTablePlan(oldTable, newTable, opts, db);
|
||||||
|
}
|
||||||
|
|||||||
15
packages/types/alter-processor.d.ts
vendored
Normal file
15
packages/types/alter-processor.d.ts
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { ColumnInfo, ConstraintInfo, TableInfo } from './dbinfo';
|
||||||
|
|
||||||
|
export interface AlterProcessor {
|
||||||
|
createTable(table: TableInfo);
|
||||||
|
dropTable(table: TableInfo);
|
||||||
|
createColumn(column: ColumnInfo, constraints: ConstraintInfo[]);
|
||||||
|
changeColumn(oldColumn: ColumnInfo, newColumn: ColumnInfo);
|
||||||
|
dropColumn(column: ColumnInfo);
|
||||||
|
createConstraint(constraint: ConstraintInfo);
|
||||||
|
changeConstraint(oldConstraint: ConstraintInfo, newConstraint: ConstraintInfo);
|
||||||
|
dropConstraint(constraint: ConstraintInfo);
|
||||||
|
renameTable(table: TableInfo, newName: string);
|
||||||
|
renameColumn(column: ColumnInfo, newName: string);
|
||||||
|
renameConstraint(constraint: ConstraintInfo, newName: string);
|
||||||
|
}
|
||||||
1
packages/types/index.d.ts
vendored
1
packages/types/index.d.ts
vendored
@@ -42,3 +42,4 @@ export * from './dialect';
|
|||||||
export * from './dumper';
|
export * from './dumper';
|
||||||
export * from './dbtypes';
|
export * from './dbtypes';
|
||||||
export * from './extensions';
|
export * from './extensions';
|
||||||
|
export * from './alter-processor';
|
||||||
|
|||||||
Reference in New Issue
Block a user