dbgate-tools 4.4.0-alpha.2 → 4.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/SqlDumper.d.ts +1 -0
- package/lib/SqlDumper.js +34 -0
- package/lib/alterPlan.d.ts +13 -4
- package/lib/alterPlan.js +19 -4
- package/lib/computeDiffRows.d.ts +38 -0
- package/lib/computeDiffRows.js +108 -0
- package/lib/database-info-alter-processor.d.ts +2 -1
- package/lib/database-info-alter-processor.js +5 -0
- package/lib/diffTools.d.ts +8 -6
- package/lib/diffTools.js +53 -15
- package/lib/driverBase.d.ts +1 -1
- package/lib/driverBase.js +2 -2
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/preloadedRowsTools.d.ts +2 -0
- package/lib/preloadedRowsTools.js +50 -0
- package/lib/yamlModelConv.d.ts +2 -0
- package/lib/yamlModelConv.js +2 -0
- package/package.json +3 -2
package/lib/SqlDumper.d.ts
CHANGED
|
@@ -101,4 +101,5 @@ export declare class SqlDumper implements AlterProcessor {
|
|
|
101
101
|
createSqlObject(obj: SqlObjectInfo): void;
|
|
102
102
|
getSqlObjectSqlName(ojectTypeField: string): "PROCEDURE" | "VIEW" | "FUNCTION" | "TRIGGER" | "MATERIALIZED VIEW";
|
|
103
103
|
dropSqlObject(obj: SqlObjectInfo): void;
|
|
104
|
+
fillPreloadedRows(table: NamedObjectInfo, oldRows: any[], newRows: any[], key: string[]): void;
|
|
104
105
|
}
|
package/lib/SqlDumper.js
CHANGED
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.SqlDumper = void 0;
|
|
7
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
7
8
|
const isString_1 = __importDefault(require("lodash/isString"));
|
|
8
9
|
const isNumber_1 = __importDefault(require("lodash/isNumber"));
|
|
9
10
|
const isDate_1 = __importDefault(require("lodash/isDate"));
|
|
@@ -531,5 +532,38 @@ class SqlDumper {
|
|
|
531
532
|
dropSqlObject(obj) {
|
|
532
533
|
this.putCmd('^drop %s %f', this.getSqlObjectSqlName(obj.objectTypeField), obj);
|
|
533
534
|
}
|
|
535
|
+
fillPreloadedRows(table, oldRows, newRows, key) {
|
|
536
|
+
let was = false;
|
|
537
|
+
for (const row of newRows) {
|
|
538
|
+
const old = oldRows === null || oldRows === void 0 ? void 0 : oldRows.find(r => key.every(col => r[col] == row[col]));
|
|
539
|
+
const rowKeys = lodash_1.default.keys(row);
|
|
540
|
+
if (old) {
|
|
541
|
+
const updated = [];
|
|
542
|
+
for (const col of rowKeys) {
|
|
543
|
+
if (row[col] != old[col]) {
|
|
544
|
+
updated.push(col);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
if (updated.length > 0) {
|
|
548
|
+
if (was)
|
|
549
|
+
this.put(';\n');
|
|
550
|
+
was = true;
|
|
551
|
+
this.put('^update %f ^set ', table);
|
|
552
|
+
this.putCollection(', ', updated, col => this.put('%i=%v', col, row[col]));
|
|
553
|
+
this.put(' ^where ');
|
|
554
|
+
this.putCollection(' ^and ', key, col => this.put('%i=%v', col, row[col]));
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
if (was)
|
|
559
|
+
this.put(';\n');
|
|
560
|
+
was = true;
|
|
561
|
+
this.put('^insert ^into %f (%,i) ^values (%,v)', table, rowKeys, rowKeys.map(x => row[x]));
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
if (was) {
|
|
565
|
+
this.endCommand();
|
|
566
|
+
}
|
|
567
|
+
}
|
|
534
568
|
}
|
|
535
569
|
exports.SqlDumper = SqlDumper;
|
package/lib/alterPlan.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DbDiffOptions } from './diffTools';
|
|
2
|
-
import { AlterProcessor, ColumnInfo, ConstraintInfo, DatabaseInfo, SqlObjectInfo, SqlDialect, TableInfo } from '../../types';
|
|
2
|
+
import { AlterProcessor, ColumnInfo, ConstraintInfo, DatabaseInfo, SqlObjectInfo, SqlDialect, TableInfo, NamedObjectInfo } from '../../types';
|
|
3
3
|
interface AlterOperation_CreateTable {
|
|
4
4
|
operationType: 'createTable';
|
|
5
5
|
newObject: TableInfo;
|
|
@@ -62,9 +62,17 @@ interface AlterOperation_RecreateTable {
|
|
|
62
62
|
table: TableInfo;
|
|
63
63
|
operations: AlterOperation[];
|
|
64
64
|
}
|
|
65
|
-
|
|
65
|
+
interface AlterOperation_FillPreloadedRows {
|
|
66
|
+
operationType: 'fillPreloadedRows';
|
|
67
|
+
table: NamedObjectInfo;
|
|
68
|
+
oldRows: any[];
|
|
69
|
+
newRows: any[];
|
|
70
|
+
key: string[];
|
|
71
|
+
}
|
|
72
|
+
declare type AlterOperation = AlterOperation_CreateColumn | AlterOperation_ChangeColumn | AlterOperation_DropColumn | AlterOperation_CreateConstraint | AlterOperation_ChangeConstraint | AlterOperation_DropConstraint | AlterOperation_CreateTable | AlterOperation_DropTable | AlterOperation_RenameTable | AlterOperation_RenameColumn | AlterOperation_RenameConstraint | AlterOperation_CreateSqlObject | AlterOperation_DropSqlObject | AlterOperation_RecreateTable | AlterOperation_FillPreloadedRows;
|
|
66
73
|
export declare class AlterPlan {
|
|
67
|
-
|
|
74
|
+
wholeOldDb: DatabaseInfo;
|
|
75
|
+
wholeNewDb: DatabaseInfo;
|
|
68
76
|
dialect: SqlDialect;
|
|
69
77
|
opts: DbDiffOptions;
|
|
70
78
|
recreates: {
|
|
@@ -73,7 +81,7 @@ export declare class AlterPlan {
|
|
|
73
81
|
sqlObjects: number;
|
|
74
82
|
};
|
|
75
83
|
operations: AlterOperation[];
|
|
76
|
-
constructor(
|
|
84
|
+
constructor(wholeOldDb: DatabaseInfo, wholeNewDb: DatabaseInfo, dialect: SqlDialect, opts: DbDiffOptions);
|
|
77
85
|
createTable(table: TableInfo): void;
|
|
78
86
|
dropTable(table: TableInfo): void;
|
|
79
87
|
createSqlObject(obj: SqlObjectInfo): void;
|
|
@@ -88,6 +96,7 @@ export declare class AlterPlan {
|
|
|
88
96
|
renameColumn(column: ColumnInfo, newName: string): void;
|
|
89
97
|
renameConstraint(constraint: ConstraintInfo, newName: string): void;
|
|
90
98
|
recreateTable(table: TableInfo, operations: AlterOperation[]): void;
|
|
99
|
+
fillPreloadedRows(table: NamedObjectInfo, oldRows: any[], newRows: any[], key: string[]): void;
|
|
91
100
|
run(processor: AlterProcessor): void;
|
|
92
101
|
_getDependendColumnConstraints(column: ColumnInfo, dependencyDefinition: any): import("dbgate-types/dbinfo").PrimaryKeyInfo[];
|
|
93
102
|
_addLogicalDependencies(): AlterOperation[];
|
package/lib/alterPlan.js
CHANGED
|
@@ -9,8 +9,9 @@ const diffTools_1 = require("./diffTools");
|
|
|
9
9
|
const database_info_alter_processor_1 = require("./database-info-alter-processor");
|
|
10
10
|
const DatabaseAnalyser_1 = require("./DatabaseAnalyser");
|
|
11
11
|
class AlterPlan {
|
|
12
|
-
constructor(
|
|
13
|
-
this.
|
|
12
|
+
constructor(wholeOldDb, wholeNewDb, dialect, opts) {
|
|
13
|
+
this.wholeOldDb = wholeOldDb;
|
|
14
|
+
this.wholeNewDb = wholeNewDb;
|
|
14
15
|
this.dialect = dialect;
|
|
15
16
|
this.opts = opts;
|
|
16
17
|
this.recreates = {
|
|
@@ -111,13 +112,24 @@ class AlterPlan {
|
|
|
111
112
|
});
|
|
112
113
|
this.recreates.tables += 1;
|
|
113
114
|
}
|
|
115
|
+
fillPreloadedRows(table, oldRows, newRows, key) {
|
|
116
|
+
this.operations.push({
|
|
117
|
+
operationType: 'fillPreloadedRows',
|
|
118
|
+
table,
|
|
119
|
+
oldRows,
|
|
120
|
+
newRows,
|
|
121
|
+
key,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
114
124
|
run(processor) {
|
|
115
125
|
for (const op of this.operations) {
|
|
116
126
|
runAlterOperation(op, processor);
|
|
117
127
|
}
|
|
118
128
|
}
|
|
119
129
|
_getDependendColumnConstraints(column, dependencyDefinition) {
|
|
120
|
-
const table = this.
|
|
130
|
+
const table = this.wholeOldDb.tables.find(x => x.pureName == column.pureName && x.schemaName == column.schemaName);
|
|
131
|
+
if (!table)
|
|
132
|
+
return [];
|
|
121
133
|
const fks = (dependencyDefinition === null || dependencyDefinition === void 0 ? void 0 : dependencyDefinition.includes('dependencies'))
|
|
122
134
|
? table.dependencies.filter(fk => fk.columns.find(col => col.refColumnName == column.columnName))
|
|
123
135
|
: [];
|
|
@@ -261,7 +273,7 @@ class AlterPlan {
|
|
|
261
273
|
// skip this operation, as it cannot be achieved
|
|
262
274
|
return [];
|
|
263
275
|
}
|
|
264
|
-
const table = this.
|
|
276
|
+
const table = this.wholeNewDb.tables.find(x => x.pureName == op[objectField].pureName && x.schemaName == op[objectField].schemaName);
|
|
265
277
|
this.recreates.tables += 1;
|
|
266
278
|
return [
|
|
267
279
|
{
|
|
@@ -394,6 +406,9 @@ function runAlterOperation(op, processor) {
|
|
|
394
406
|
case 'dropSqlObject':
|
|
395
407
|
processor.dropSqlObject(op.oldObject);
|
|
396
408
|
break;
|
|
409
|
+
case 'fillPreloadedRows':
|
|
410
|
+
processor.fillPreloadedRows(op.table, op.oldRows, op.newRows, op.key);
|
|
411
|
+
break;
|
|
397
412
|
case 'recreateTable':
|
|
398
413
|
{
|
|
399
414
|
const oldTable = (0, diffTools_1.generateTablePairingId)(op.table);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { DbDiffOptions, testEqualTables, testEqualSqlObjects } from './diffTools';
|
|
2
|
+
import { DatabaseInfo, EngineDriver, SqlObjectInfo, TableInfo } from 'dbgate-types';
|
|
3
|
+
export declare function computeDiffRowsCore(sourceList: any, targetList: any, testEqual: any): any[];
|
|
4
|
+
export declare const DbDiffCompareDefs: {
|
|
5
|
+
tables: {
|
|
6
|
+
test: typeof testEqualTables;
|
|
7
|
+
name: string;
|
|
8
|
+
plural: string;
|
|
9
|
+
icon: string;
|
|
10
|
+
};
|
|
11
|
+
views: {
|
|
12
|
+
test: typeof testEqualSqlObjects;
|
|
13
|
+
name: string;
|
|
14
|
+
plural: string;
|
|
15
|
+
icon: string;
|
|
16
|
+
};
|
|
17
|
+
matviews: {
|
|
18
|
+
test: typeof testEqualSqlObjects;
|
|
19
|
+
name: string;
|
|
20
|
+
plural: string;
|
|
21
|
+
icon: string;
|
|
22
|
+
};
|
|
23
|
+
procedures: {
|
|
24
|
+
test: typeof testEqualSqlObjects;
|
|
25
|
+
name: string;
|
|
26
|
+
plural: string;
|
|
27
|
+
icon: string;
|
|
28
|
+
};
|
|
29
|
+
functions: {
|
|
30
|
+
test: typeof testEqualSqlObjects;
|
|
31
|
+
name: string;
|
|
32
|
+
plural: string;
|
|
33
|
+
icon: string;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
export declare function computeDbDiffRows(sourceDb: DatabaseInfo, targetDb: DatabaseInfo, opts: DbDiffOptions, driver: EngineDriver): any[];
|
|
37
|
+
export declare function computeTableDiffColumns(sourceTable: TableInfo, targetTable: TableInfo, opts: DbDiffOptions, driver: EngineDriver): any[];
|
|
38
|
+
export declare function getCreateObjectScript(obj: TableInfo | SqlObjectInfo, driver: EngineDriver): string;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getCreateObjectScript = exports.computeTableDiffColumns = exports.computeDbDiffRows = exports.DbDiffCompareDefs = exports.computeDiffRowsCore = void 0;
|
|
7
|
+
const diffTools_1 = require("./diffTools");
|
|
8
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
9
|
+
function computeDiffRowsCore(sourceList, targetList, testEqual) {
|
|
10
|
+
const res = [];
|
|
11
|
+
for (const obj of sourceList) {
|
|
12
|
+
const paired = targetList.find(x => x.pairingId == obj.pairingId);
|
|
13
|
+
if (paired) {
|
|
14
|
+
const isEqual = testEqual(obj, paired);
|
|
15
|
+
res.push({
|
|
16
|
+
source: obj,
|
|
17
|
+
target: paired,
|
|
18
|
+
state: isEqual ? 'equal' : 'changed',
|
|
19
|
+
__isChanged: !isEqual,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
res.push({
|
|
24
|
+
source: obj,
|
|
25
|
+
state: 'added',
|
|
26
|
+
__isAdded: true,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
for (const obj of targetList) {
|
|
31
|
+
const paired = sourceList.find(x => x.pairingId == obj.pairingId);
|
|
32
|
+
if (!paired) {
|
|
33
|
+
res.push({
|
|
34
|
+
target: obj,
|
|
35
|
+
state: 'removed',
|
|
36
|
+
__isDeleted: true,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return res;
|
|
41
|
+
}
|
|
42
|
+
exports.computeDiffRowsCore = computeDiffRowsCore;
|
|
43
|
+
exports.DbDiffCompareDefs = {
|
|
44
|
+
tables: {
|
|
45
|
+
test: diffTools_1.testEqualTables,
|
|
46
|
+
name: 'Table',
|
|
47
|
+
plural: 'Tables',
|
|
48
|
+
icon: 'img table',
|
|
49
|
+
},
|
|
50
|
+
views: {
|
|
51
|
+
test: diffTools_1.testEqualSqlObjects,
|
|
52
|
+
name: 'View',
|
|
53
|
+
plural: 'Views',
|
|
54
|
+
icon: 'img view',
|
|
55
|
+
},
|
|
56
|
+
matviews: {
|
|
57
|
+
test: diffTools_1.testEqualSqlObjects,
|
|
58
|
+
name: 'Materialized view',
|
|
59
|
+
plural: 'Materialized views',
|
|
60
|
+
icon: 'img view',
|
|
61
|
+
},
|
|
62
|
+
procedures: {
|
|
63
|
+
test: diffTools_1.testEqualSqlObjects,
|
|
64
|
+
name: 'Procedure',
|
|
65
|
+
plural: 'Procedures',
|
|
66
|
+
icon: 'img procedure',
|
|
67
|
+
},
|
|
68
|
+
functions: {
|
|
69
|
+
test: diffTools_1.testEqualSqlObjects,
|
|
70
|
+
name: 'Function',
|
|
71
|
+
plural: 'Functions',
|
|
72
|
+
icon: 'img function',
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
function computeDbDiffRows(sourceDb, targetDb, opts, driver) {
|
|
76
|
+
if (!sourceDb || !targetDb || !driver)
|
|
77
|
+
return [];
|
|
78
|
+
const res = [];
|
|
79
|
+
for (const objectTypeField of ['tables', 'views', 'procedures', 'matviews', 'functions']) {
|
|
80
|
+
const defs = exports.DbDiffCompareDefs[objectTypeField];
|
|
81
|
+
res.push(...lodash_1.default.sortBy(computeDiffRowsCore(sourceDb[objectTypeField], targetDb[objectTypeField], (a, b) => defs.test(a, b, opts, sourceDb, targetDb, driver)).map(row => {
|
|
82
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
83
|
+
return (Object.assign(Object.assign({}, row), { sourceSchemaName: (_a = row === null || row === void 0 ? void 0 : row.source) === null || _a === void 0 ? void 0 : _a.schemaName, sourcePureName: (_b = row === null || row === void 0 ? void 0 : row.source) === null || _b === void 0 ? void 0 : _b.pureName, targetSchemaName: (_c = row === null || row === void 0 ? void 0 : row.target) === null || _c === void 0 ? void 0 : _c.schemaName, targetPureName: (_d = row === null || row === void 0 ? void 0 : row.target) === null || _d === void 0 ? void 0 : _d.pureName, typeName: defs.name, typeIcon: defs.icon, identifier: `${((_e = row === null || row === void 0 ? void 0 : row.source) === null || _e === void 0 ? void 0 : _e.schemaName) || ((_f = row === null || row === void 0 ? void 0 : row.target) === null || _f === void 0 ? void 0 : _f.schemaName)}.${((_g = row === null || row === void 0 ? void 0 : row.source) === null || _g === void 0 ? void 0 : _g.pureName) || ((_h = row === null || row === void 0 ? void 0 : row.target) === null || _h === void 0 ? void 0 : _h.pureName)}`, objectTypeField }));
|
|
84
|
+
}), 'identifier'));
|
|
85
|
+
}
|
|
86
|
+
return res;
|
|
87
|
+
}
|
|
88
|
+
exports.computeDbDiffRows = computeDbDiffRows;
|
|
89
|
+
function computeTableDiffColumns(sourceTable, targetTable, opts, driver) {
|
|
90
|
+
if (!driver)
|
|
91
|
+
return [];
|
|
92
|
+
return computeDiffRowsCore((sourceTable === null || sourceTable === void 0 ? void 0 : sourceTable.columns) || [], (targetTable === null || targetTable === void 0 ? void 0 : targetTable.columns) || [], (a, b) => (0, diffTools_1.testEqualColumns)(a, b, true, true, opts)).map(row => {
|
|
93
|
+
var _a, _b, _c, _d, _e, _f;
|
|
94
|
+
return (Object.assign(Object.assign({}, row), { sourceColumnName: (_a = row === null || row === void 0 ? void 0 : row.source) === null || _a === void 0 ? void 0 : _a.columnName, targetColumnName: (_b = row === null || row === void 0 ? void 0 : row.target) === null || _b === void 0 ? void 0 : _b.columnName, sourceDataType: (_c = row === null || row === void 0 ? void 0 : row.source) === null || _c === void 0 ? void 0 : _c.dataType, targetDataType: (_d = row === null || row === void 0 ? void 0 : row.target) === null || _d === void 0 ? void 0 : _d.dataType, sourceNotNull: (_e = row === null || row === void 0 ? void 0 : row.source) === null || _e === void 0 ? void 0 : _e.notNull, targetNotNull: (_f = row === null || row === void 0 ? void 0 : row.target) === null || _f === void 0 ? void 0 : _f.notNull }));
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
exports.computeTableDiffColumns = computeTableDiffColumns;
|
|
98
|
+
function getCreateObjectScript(obj, driver) {
|
|
99
|
+
if (!obj || !driver)
|
|
100
|
+
return '';
|
|
101
|
+
if (obj.objectTypeField == 'tables') {
|
|
102
|
+
const dmp = driver.createDumper();
|
|
103
|
+
dmp.createTable(obj);
|
|
104
|
+
return dmp.s;
|
|
105
|
+
}
|
|
106
|
+
return obj.createSql || '';
|
|
107
|
+
}
|
|
108
|
+
exports.getCreateObjectScript = getCreateObjectScript;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ColumnInfo, ConstraintInfo, DatabaseInfo, TableInfo, SqlObjectInfo } from '../../types';
|
|
1
|
+
import { ColumnInfo, ConstraintInfo, DatabaseInfo, TableInfo, SqlObjectInfo, NamedObjectInfo } from '../../types';
|
|
2
2
|
export declare class DatabaseInfoAlterProcessor {
|
|
3
3
|
db: DatabaseInfo;
|
|
4
4
|
constructor(db: DatabaseInfo);
|
|
@@ -16,4 +16,5 @@ export declare class DatabaseInfoAlterProcessor {
|
|
|
16
16
|
renameColumn(column: ColumnInfo, newName: string): void;
|
|
17
17
|
renameConstraint(constraint: ConstraintInfo, newName: string): void;
|
|
18
18
|
recreateTable(oldTable: TableInfo, newTable: TableInfo): void;
|
|
19
|
+
fillPreloadedRows(table: NamedObjectInfo, oldRows: any[], newRows: any[], key: string[]): void;
|
|
19
20
|
}
|
|
@@ -93,5 +93,10 @@ class DatabaseInfoAlterProcessor {
|
|
|
93
93
|
recreateTable(oldTable, newTable) {
|
|
94
94
|
throw new Error('recreateTable not implemented for DatabaseInfoAlterProcessor');
|
|
95
95
|
}
|
|
96
|
+
fillPreloadedRows(table, oldRows, newRows, key) {
|
|
97
|
+
const tableInfo = this.db.tables.find(x => x.pureName == table.pureName && x.schemaName == table.schemaName);
|
|
98
|
+
tableInfo.preloadedRows = newRows;
|
|
99
|
+
tableInfo.preloadedRowsKey = key;
|
|
100
|
+
}
|
|
96
101
|
}
|
|
97
102
|
exports.DatabaseInfoAlterProcessor = DatabaseInfoAlterProcessor;
|
package/lib/diffTools.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ColumnInfo, DatabaseInfo, EngineDriver, TableInfo } from 'dbgate-types';
|
|
1
|
+
import { ColumnInfo, DatabaseInfo, EngineDriver, SqlObjectInfo, TableInfo } from 'dbgate-types';
|
|
2
2
|
import { AlterPlan } from './alterPlan';
|
|
3
3
|
declare type DbDiffSchemaMode = 'strict' | 'ignore' | 'ignoreImplicit';
|
|
4
4
|
export interface DbDiffOptions {
|
|
@@ -20,10 +20,11 @@ export declare function generateTablePairingId(table: TableInfo): TableInfo;
|
|
|
20
20
|
export declare function generateDbPairingId(db: DatabaseInfo): DatabaseInfo;
|
|
21
21
|
export declare function testEqualColumns(a: ColumnInfo, b: ColumnInfo, checkName: boolean, checkDefault: boolean, opts?: DbDiffOptions): boolean;
|
|
22
22
|
export declare function testEqualTypes(a: ColumnInfo, b: ColumnInfo, opts?: DbDiffOptions): boolean;
|
|
23
|
-
export declare function testEqualTables(a: TableInfo, b: TableInfo, opts: DbDiffOptions,
|
|
24
|
-
export declare function
|
|
25
|
-
export declare function
|
|
26
|
-
export declare function
|
|
23
|
+
export declare function testEqualTables(a: TableInfo, b: TableInfo, opts: DbDiffOptions, wholeOldDb: DatabaseInfo, wholeNewDb: DatabaseInfo, driver: EngineDriver): boolean;
|
|
24
|
+
export declare function testEqualSqlObjects(a: SqlObjectInfo, b: SqlObjectInfo, opts: DbDiffOptions): boolean;
|
|
25
|
+
export declare function createAlterTablePlan(oldTable: TableInfo, newTable: TableInfo, opts: DbDiffOptions, wholeOldDb: DatabaseInfo, wholeNewDb: DatabaseInfo, driver: EngineDriver): AlterPlan;
|
|
26
|
+
export declare function createAlterDatabasePlan(oldDb: DatabaseInfo, newDb: DatabaseInfo, opts: DbDiffOptions, wholeOldDb: DatabaseInfo, wholeNewDb: DatabaseInfo, driver: EngineDriver): AlterPlan;
|
|
27
|
+
export declare function getAlterTableScript(oldTable: TableInfo, newTable: TableInfo, opts: DbDiffOptions, wholeOldDb: DatabaseInfo, wholeNewDb: DatabaseInfo, driver: EngineDriver): {
|
|
27
28
|
sql: string;
|
|
28
29
|
recreates: any[];
|
|
29
30
|
} | {
|
|
@@ -34,7 +35,7 @@ export declare function getAlterTableScript(oldTable: TableInfo, newTable: Table
|
|
|
34
35
|
sqlObjects: number;
|
|
35
36
|
};
|
|
36
37
|
};
|
|
37
|
-
export declare function getAlterDatabaseScript(oldDb: DatabaseInfo, newDb: DatabaseInfo, opts: DbDiffOptions,
|
|
38
|
+
export declare function getAlterDatabaseScript(oldDb: DatabaseInfo, newDb: DatabaseInfo, opts: DbDiffOptions, wholeOldDb: DatabaseInfo, wholeNewDb: DatabaseInfo, driver: EngineDriver): {
|
|
38
39
|
sql: string;
|
|
39
40
|
recreates: {
|
|
40
41
|
tables: number;
|
|
@@ -44,4 +45,5 @@ export declare function getAlterDatabaseScript(oldDb: DatabaseInfo, newDb: Datab
|
|
|
44
45
|
isEmpty: boolean;
|
|
45
46
|
};
|
|
46
47
|
export declare function matchPairedObjects(db1: DatabaseInfo, db2: DatabaseInfo, opts: DbDiffOptions): DatabaseInfo;
|
|
48
|
+
export declare const modelCompareDbDiffOptions: DbDiffOptions;
|
|
47
49
|
export {};
|
package/lib/diffTools.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.matchPairedObjects = exports.getAlterDatabaseScript = exports.getAlterTableScript = exports.createAlterDatabasePlan = exports.createAlterTablePlan = exports.testEqualTables = exports.testEqualTypes = exports.testEqualColumns = exports.generateDbPairingId = exports.generateTablePairingId = void 0;
|
|
6
|
+
exports.modelCompareDbDiffOptions = exports.matchPairedObjects = exports.getAlterDatabaseScript = exports.getAlterTableScript = exports.createAlterDatabasePlan = exports.createAlterTablePlan = exports.testEqualSqlObjects = exports.testEqualTables = exports.testEqualTypes = exports.testEqualColumns = exports.generateDbPairingId = exports.generateTablePairingId = void 0;
|
|
7
7
|
const v1_1 = __importDefault(require("uuid/v1"));
|
|
8
8
|
const alterPlan_1 = require("./alterPlan");
|
|
9
9
|
const json_stable_stringify_1 = __importDefault(require("json-stable-stringify"));
|
|
@@ -185,6 +185,10 @@ function testEqualConstraints(a, b, opts = {}) {
|
|
|
185
185
|
// console.log('FK1', stableStringify(_omit(a, omitList)));
|
|
186
186
|
// console.log('FK2', stableStringify(_omit(b, omitList)));
|
|
187
187
|
// }
|
|
188
|
+
// if (a.constraintType == 'index' && b.constraintType == 'index') {
|
|
189
|
+
// console.log('IX1', stableStringify(_omit(a, omitList)));
|
|
190
|
+
// console.log('IX2', stableStringify(_omit(b, omitList)));
|
|
191
|
+
// }
|
|
188
192
|
return (0, json_stable_stringify_1.default)((0, omit_1.default)(a, omitList)) == (0, json_stable_stringify_1.default)((0, omit_1.default)(b, omitList));
|
|
189
193
|
}
|
|
190
194
|
function testEqualTypes(a, b, opts = {}) {
|
|
@@ -230,10 +234,19 @@ function createPairs(oldList, newList, additionalCondition = null) {
|
|
|
230
234
|
}
|
|
231
235
|
return res;
|
|
232
236
|
}
|
|
237
|
+
function planTablePreload(plan, oldTable, newTable) {
|
|
238
|
+
var _a, _b, _c;
|
|
239
|
+
const key = newTable.preloadedRowsKey || ((_b = (_a = newTable.primaryKey) === null || _a === void 0 ? void 0 : _a.columns) === null || _b === void 0 ? void 0 : _b.map(x => x.columnName));
|
|
240
|
+
if (((_c = newTable.preloadedRows) === null || _c === void 0 ? void 0 : _c.length) > 0 && (key === null || key === void 0 ? void 0 : key.length) > 0) {
|
|
241
|
+
plan.fillPreloadedRows(newTable, oldTable === null || oldTable === void 0 ? void 0 : oldTable.preloadedRows, newTable.preloadedRows, key);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
233
244
|
function planAlterTable(plan, oldTable, newTable, opts) {
|
|
234
245
|
// if (oldTable.primaryKey)
|
|
235
246
|
const columnPairs = createPairs(oldTable.columns, newTable.columns);
|
|
236
247
|
const constraintPairs = createPairs(getTableConstraints(oldTable), getTableConstraints(newTable), (a, b) => a.constraintType == 'primaryKey' && b.constraintType == 'primaryKey');
|
|
248
|
+
// console.log('constraintPairs SOURCE', getTableConstraints(oldTable), getTableConstraints(newTable));
|
|
249
|
+
// console.log('constraintPairs', constraintPairs);
|
|
237
250
|
if (!opts.noDropConstraint) {
|
|
238
251
|
constraintPairs.filter(x => x[1] == null).forEach(x => plan.dropConstraint(x[0]));
|
|
239
252
|
}
|
|
@@ -267,18 +280,24 @@ function planAlterTable(plan, oldTable, newTable, opts) {
|
|
|
267
280
|
}
|
|
268
281
|
});
|
|
269
282
|
constraintPairs.filter(x => x[0] == null).forEach(x => plan.createConstraint(x[1]));
|
|
283
|
+
planTablePreload(plan, oldTable, newTable);
|
|
270
284
|
}
|
|
271
|
-
function testEqualTables(a, b, opts,
|
|
272
|
-
const plan = new alterPlan_1.AlterPlan(
|
|
285
|
+
function testEqualTables(a, b, opts, wholeOldDb, wholeNewDb, driver) {
|
|
286
|
+
const plan = new alterPlan_1.AlterPlan(wholeOldDb, wholeNewDb, driver.dialect, opts);
|
|
273
287
|
planAlterTable(plan, a, b, opts);
|
|
274
288
|
// console.log('plan.operations', a, b, plan.operations);
|
|
275
289
|
return plan.operations.length == 0;
|
|
276
290
|
}
|
|
277
291
|
exports.testEqualTables = testEqualTables;
|
|
278
|
-
function
|
|
279
|
-
|
|
292
|
+
function testEqualSqlObjects(a, b, opts) {
|
|
293
|
+
return a.createSql == b.createSql;
|
|
294
|
+
}
|
|
295
|
+
exports.testEqualSqlObjects = testEqualSqlObjects;
|
|
296
|
+
function createAlterTablePlan(oldTable, newTable, opts, wholeOldDb, wholeNewDb, driver) {
|
|
297
|
+
const plan = new alterPlan_1.AlterPlan(wholeOldDb, wholeNewDb, driver.dialect, opts);
|
|
280
298
|
if (oldTable == null) {
|
|
281
299
|
plan.createTable(newTable);
|
|
300
|
+
planTablePreload(plan, null, newTable);
|
|
282
301
|
}
|
|
283
302
|
else if (newTable == null) {
|
|
284
303
|
plan.dropTable(oldTable);
|
|
@@ -290,8 +309,8 @@ function createAlterTablePlan(oldTable, newTable, opts, db, driver) {
|
|
|
290
309
|
return plan;
|
|
291
310
|
}
|
|
292
311
|
exports.createAlterTablePlan = createAlterTablePlan;
|
|
293
|
-
function createAlterDatabasePlan(oldDb, newDb, opts,
|
|
294
|
-
const plan = new alterPlan_1.AlterPlan(
|
|
312
|
+
function createAlterDatabasePlan(oldDb, newDb, opts, wholeOldDb, wholeNewDb, driver) {
|
|
313
|
+
const plan = new alterPlan_1.AlterPlan(wholeOldDb, wholeNewDb, driver.dialect, opts);
|
|
295
314
|
for (const objectTypeField of ['tables', 'views', 'procedures', 'matviews', 'functions']) {
|
|
296
315
|
for (const oldobj of oldDb[objectTypeField] || []) {
|
|
297
316
|
const newobj = (newDb[objectTypeField] || []).find(x => x.pairingId == oldobj.pairingId);
|
|
@@ -311,7 +330,7 @@ function createAlterDatabasePlan(oldDb, newDb, opts, db, driver) {
|
|
|
311
330
|
plan.dropSqlObject(oldobj);
|
|
312
331
|
}
|
|
313
332
|
}
|
|
314
|
-
else if (
|
|
333
|
+
else if (!testEqualSqlObjects(oldobj.createSql, newobj.createSql, opts)) {
|
|
315
334
|
plan.recreates.sqlObjects += 1;
|
|
316
335
|
if (!opts.noDropSqlObject) {
|
|
317
336
|
plan.dropSqlObject(oldobj);
|
|
@@ -323,8 +342,10 @@ function createAlterDatabasePlan(oldDb, newDb, opts, db, driver) {
|
|
|
323
342
|
for (const newobj of newDb[objectTypeField] || []) {
|
|
324
343
|
const oldobj = (oldDb[objectTypeField] || []).find(x => x.pairingId == newobj.pairingId);
|
|
325
344
|
if (objectTypeField == 'tables') {
|
|
326
|
-
if (oldobj == null)
|
|
345
|
+
if (oldobj == null) {
|
|
327
346
|
plan.createTable(newobj);
|
|
347
|
+
planTablePreload(plan, null, newobj);
|
|
348
|
+
}
|
|
328
349
|
}
|
|
329
350
|
else {
|
|
330
351
|
if (oldobj == null)
|
|
@@ -336,12 +357,12 @@ function createAlterDatabasePlan(oldDb, newDb, opts, db, driver) {
|
|
|
336
357
|
return plan;
|
|
337
358
|
}
|
|
338
359
|
exports.createAlterDatabasePlan = createAlterDatabasePlan;
|
|
339
|
-
function getAlterTableScript(oldTable, newTable, opts,
|
|
360
|
+
function getAlterTableScript(oldTable, newTable, opts, wholeOldDb, wholeNewDb, driver) {
|
|
340
361
|
if ((!oldTable && !newTable) || !driver) {
|
|
341
362
|
return { sql: '', recreates: [] };
|
|
342
363
|
}
|
|
343
|
-
const plan = createAlterTablePlan(oldTable, newTable, opts,
|
|
344
|
-
const dmp = driver.createDumper();
|
|
364
|
+
const plan = createAlterTablePlan(oldTable, newTable, opts, wholeOldDb, wholeNewDb, driver);
|
|
365
|
+
const dmp = driver.createDumper({ useHardSeparator: true });
|
|
345
366
|
if (!driver.dialect.disableExplicitTransaction)
|
|
346
367
|
dmp.beginTransaction();
|
|
347
368
|
plan.run(dmp);
|
|
@@ -353,9 +374,9 @@ function getAlterTableScript(oldTable, newTable, opts, db, driver) {
|
|
|
353
374
|
};
|
|
354
375
|
}
|
|
355
376
|
exports.getAlterTableScript = getAlterTableScript;
|
|
356
|
-
function getAlterDatabaseScript(oldDb, newDb, opts,
|
|
357
|
-
const plan = createAlterDatabasePlan(oldDb, newDb, opts,
|
|
358
|
-
const dmp = driver.createDumper();
|
|
377
|
+
function getAlterDatabaseScript(oldDb, newDb, opts, wholeOldDb, wholeNewDb, driver) {
|
|
378
|
+
const plan = createAlterDatabasePlan(oldDb, newDb, opts, wholeOldDb, wholeNewDb, driver);
|
|
379
|
+
const dmp = driver.createDumper({ useHardSeparator: true });
|
|
359
380
|
if (!driver.dialect.disableExplicitTransaction)
|
|
360
381
|
dmp.beginTransaction();
|
|
361
382
|
plan.run(dmp);
|
|
@@ -389,6 +410,16 @@ function matchPairedObjects(db1, db2, opts) {
|
|
|
389
410
|
if (fk1)
|
|
390
411
|
fk2.pairingId = fk1.pairingId;
|
|
391
412
|
}
|
|
413
|
+
for (const uq2 of obj2.uniques) {
|
|
414
|
+
const uq1 = obj1.uniques.find(x => (0, isEqual_1.default)(x.columns.map(y => (0, pick_1.default)(y, ['columnName'])), uq2.columns.map(y => (0, pick_1.default)(y, ['columnName']))));
|
|
415
|
+
if (uq1)
|
|
416
|
+
uq2.pairingId = uq1.pairingId;
|
|
417
|
+
}
|
|
418
|
+
for (const ix2 of obj2.indexes) {
|
|
419
|
+
const ix1 = obj1.indexes.find(x => testEqualNames(x.constraintName, ix2.constraintName, opts));
|
|
420
|
+
if (ix1)
|
|
421
|
+
ix2.pairingId = ix1.pairingId;
|
|
422
|
+
}
|
|
392
423
|
}
|
|
393
424
|
}
|
|
394
425
|
}
|
|
@@ -396,3 +427,10 @@ function matchPairedObjects(db1, db2, opts) {
|
|
|
396
427
|
return res;
|
|
397
428
|
}
|
|
398
429
|
exports.matchPairedObjects = matchPairedObjects;
|
|
430
|
+
exports.modelCompareDbDiffOptions = {
|
|
431
|
+
ignoreCase: true,
|
|
432
|
+
schemaMode: 'ignore',
|
|
433
|
+
ignoreConstraintNames: true,
|
|
434
|
+
ignoreForeignKeyActions: true,
|
|
435
|
+
ignoreDataTypes: true,
|
|
436
|
+
};
|
package/lib/driverBase.d.ts
CHANGED
|
@@ -14,6 +14,6 @@ export declare const driverBase: {
|
|
|
14
14
|
analyseSingleObject(pool: any, name: any, typeField?: string): Promise<any>;
|
|
15
15
|
analyseSingleTable(pool: any, name: any): any;
|
|
16
16
|
analyseIncremental(pool: any, structure: any, version: any): Promise<any>;
|
|
17
|
-
createDumper(): any;
|
|
17
|
+
createDumper(options?: any): any;
|
|
18
18
|
script(pool: any, sql: any): Promise<void>;
|
|
19
19
|
};
|
package/lib/driverBase.js
CHANGED
|
@@ -47,8 +47,8 @@ exports.driverBase = {
|
|
|
47
47
|
return analyser.incrementalAnalysis(structure);
|
|
48
48
|
});
|
|
49
49
|
},
|
|
50
|
-
createDumper() {
|
|
51
|
-
return new this.dumperClass(this);
|
|
50
|
+
createDumper(options = null) {
|
|
51
|
+
return new this.dumperClass(this, options);
|
|
52
52
|
},
|
|
53
53
|
script(pool, sql) {
|
|
54
54
|
return __awaiter(this, void 0, void 0, function* () {
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -27,3 +27,5 @@ __exportStar(require("./diffTools"), exports);
|
|
|
27
27
|
__exportStar(require("./schemaEditorTools"), exports);
|
|
28
28
|
__exportStar(require("./yamlModelConv"), exports);
|
|
29
29
|
__exportStar(require("./stringTools"), exports);
|
|
30
|
+
__exportStar(require("./computeDiffRows"), exports);
|
|
31
|
+
__exportStar(require("./preloadedRowsTools"), exports);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.enrichWithPreloadedRows = void 0;
|
|
16
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
17
|
+
function enrichWithPreloadedRows(dbModel, dbTarget, conn, driver) {
|
|
18
|
+
var _a, _b, _c;
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
// const res = { ...dbTarget, tables: [...(dbTarget.tables || [])] };
|
|
21
|
+
const repl = {};
|
|
22
|
+
for (const tableTarget of dbTarget.tables) {
|
|
23
|
+
const tableModel = dbModel.tables.find(x => x.pairingId == tableTarget.pairingId);
|
|
24
|
+
if ((((_a = tableModel.preloadedRows) === null || _a === void 0 ? void 0 : _a.length) || 0) == 0)
|
|
25
|
+
continue;
|
|
26
|
+
const keyColumns = tableModel.preloadedRowsKey || ((_c = (_b = tableModel.primaryKey) === null || _b === void 0 ? void 0 : _b.columns) === null || _c === void 0 ? void 0 : _c.map(x => x.columnName));
|
|
27
|
+
if (((keyColumns === null || keyColumns === void 0 ? void 0 : keyColumns.length) || 0) == 0)
|
|
28
|
+
continue;
|
|
29
|
+
const dmp = driver.createDumper();
|
|
30
|
+
if (keyColumns.length == 1) {
|
|
31
|
+
dmp.putCmd('^select * ^from %f ^where %i ^in (%,v)', tableTarget, keyColumns[0], tableModel.preloadedRows.map(x => x[keyColumns[0]]));
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
dmp.put('^select * ^from %f ^where', tableTarget);
|
|
35
|
+
dmp.putCollection(' ^or ', tableTarget.preloadedRows, row => {
|
|
36
|
+
dmp.put('(');
|
|
37
|
+
dmp.putCollection(' ^and ', keyColumns, col => dmp.put('%i=%v', col, row[col]));
|
|
38
|
+
dmp.put(')');
|
|
39
|
+
});
|
|
40
|
+
dmp.endCommand();
|
|
41
|
+
}
|
|
42
|
+
const resp = yield driver.query(conn, dmp.s);
|
|
43
|
+
repl[tableTarget.pairingId] = Object.assign(Object.assign({}, tableTarget), { preloadedRows: resp.rows, preloadedRowsKey: keyColumns });
|
|
44
|
+
}
|
|
45
|
+
if (lodash_1.default.isEmpty(repl))
|
|
46
|
+
return dbTarget;
|
|
47
|
+
return Object.assign(Object.assign({}, dbTarget), { tables: dbTarget.tables.map(x => repl[x.pairingId] || x) });
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
exports.enrichWithPreloadedRows = enrichWithPreloadedRows;
|
package/lib/yamlModelConv.d.ts
CHANGED
package/lib/yamlModelConv.js
CHANGED
|
@@ -85,6 +85,8 @@ function tableInfoFromYaml(table, allTables) {
|
|
|
85
85
|
columns: table.primaryKey.map(columnName => ({ columnName })),
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
|
+
res.preloadedRows = table.data;
|
|
89
|
+
res.preloadedRowsKey = table.insertKey;
|
|
88
90
|
return res;
|
|
89
91
|
}
|
|
90
92
|
exports.tableInfoFromYaml = tableInfoFromYaml;
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "4.4.
|
|
2
|
+
"version": "4.4.3",
|
|
3
3
|
"name": "dbgate-tools",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"typings": "lib/index.d.ts",
|
|
@@ -25,13 +25,14 @@
|
|
|
25
25
|
],
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/node": "^13.7.0",
|
|
28
|
-
"dbgate-types": "^4.4.
|
|
28
|
+
"dbgate-types": "^4.4.3",
|
|
29
29
|
"jest": "^24.9.0",
|
|
30
30
|
"ts-jest": "^25.2.1",
|
|
31
31
|
"typescript": "^4.4.3"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"lodash": "^4.17.21",
|
|
35
|
+
"dbgate-query-splitter": "^4.4.3",
|
|
35
36
|
"uuid": "^3.4.0"
|
|
36
37
|
}
|
|
37
38
|
}
|