dbgate-tools 5.5.6 → 5.5.7-alpha.16
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 +4 -2
- package/lib/alterPlan.d.ts +7 -1
- package/lib/alterPlan.js +22 -4
- package/lib/database-info-alter-processor.d.ts +1 -0
- package/lib/database-info-alter-processor.js +4 -0
- package/lib/diffTools.d.ts +5 -0
- package/lib/diffTools.js +126 -19
- package/lib/driverBase.js +6 -0
- package/lib/getConnectionLabel.js +3 -0
- package/lib/stringTools.d.ts +1 -0
- package/lib/stringTools.js +11 -1
- package/lib/yamlModelConv.js +5 -1
- package/package.json +4 -3
package/lib/SqlDumper.d.ts
CHANGED
|
@@ -102,6 +102,7 @@ export declare class SqlDumper implements AlterProcessor {
|
|
|
102
102
|
}): void;
|
|
103
103
|
changeTableSchema(obj: TableInfo, schema: string): void;
|
|
104
104
|
renameTable(obj: TableInfo, newname: string): void;
|
|
105
|
+
renameSqlObject(obj: SqlObjectInfo, newname: string): void;
|
|
105
106
|
beginTransaction(): void;
|
|
106
107
|
commitTransaction(): void;
|
|
107
108
|
rollbackTransaction(): void;
|
package/lib/SqlDumper.js
CHANGED
|
@@ -299,7 +299,7 @@ class SqlDumper {
|
|
|
299
299
|
createTablePrimaryKeyCore(table) {
|
|
300
300
|
if (table.primaryKey) {
|
|
301
301
|
this.put(',&n');
|
|
302
|
-
if (table.primaryKey.constraintName) {
|
|
302
|
+
if (table.primaryKey.constraintName && !this.dialect.anonymousPrimaryKey) {
|
|
303
303
|
this.put('^constraint %i', table.primaryKey.constraintName);
|
|
304
304
|
}
|
|
305
305
|
this.put(' ^primary ^key (%,i)', table.primaryKey.columns.map(x => x.columnName));
|
|
@@ -529,6 +529,7 @@ class SqlDumper {
|
|
|
529
529
|
}
|
|
530
530
|
changeTableSchema(obj, schema) { }
|
|
531
531
|
renameTable(obj, newname) { }
|
|
532
|
+
renameSqlObject(obj, newname) { }
|
|
532
533
|
beginTransaction() {
|
|
533
534
|
this.putCmd('^begin ^transaction');
|
|
534
535
|
}
|
|
@@ -597,7 +598,8 @@ class SqlDumper {
|
|
|
597
598
|
}
|
|
598
599
|
}
|
|
599
600
|
createSqlObject(obj) {
|
|
600
|
-
this.
|
|
601
|
+
this.putRaw(obj.createSql);
|
|
602
|
+
this.endCommand();
|
|
601
603
|
}
|
|
602
604
|
getSqlObjectSqlName(ojectTypeField) {
|
|
603
605
|
switch (ojectTypeField) {
|
package/lib/alterPlan.d.ts
CHANGED
|
@@ -21,6 +21,11 @@ interface AlterOperation_RenameTable {
|
|
|
21
21
|
object: TableInfo;
|
|
22
22
|
newName: string;
|
|
23
23
|
}
|
|
24
|
+
interface AlterOperation_RenameSqlObject {
|
|
25
|
+
operationType: 'renameSqlObject';
|
|
26
|
+
object: SqlObjectInfo;
|
|
27
|
+
newName: string;
|
|
28
|
+
}
|
|
24
29
|
interface AlterOperation_CreateColumn {
|
|
25
30
|
operationType: 'createColumn';
|
|
26
31
|
newObject: ColumnInfo;
|
|
@@ -77,7 +82,7 @@ interface AlterOperation_SetTableOption {
|
|
|
77
82
|
optionName: string;
|
|
78
83
|
optionValue: string;
|
|
79
84
|
}
|
|
80
|
-
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 | AlterOperation_SetTableOption;
|
|
85
|
+
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 | AlterOperation_SetTableOption | AlterOperation_RenameSqlObject;
|
|
81
86
|
export declare class AlterPlan {
|
|
82
87
|
wholeOldDb: DatabaseInfo;
|
|
83
88
|
wholeNewDb: DatabaseInfo;
|
|
@@ -101,6 +106,7 @@ export declare class AlterPlan {
|
|
|
101
106
|
changeConstraint(oldConstraint: ConstraintInfo, newConstraint: ConstraintInfo): void;
|
|
102
107
|
dropConstraint(constraint: ConstraintInfo): void;
|
|
103
108
|
renameTable(table: TableInfo, newName: string): void;
|
|
109
|
+
renameSqlObject(table: TableInfo, newName: string): void;
|
|
104
110
|
renameColumn(column: ColumnInfo, newName: string): void;
|
|
105
111
|
renameConstraint(constraint: ConstraintInfo, newName: string): void;
|
|
106
112
|
recreateTable(table: TableInfo, operations: AlterOperation[]): void;
|
package/lib/alterPlan.js
CHANGED
|
@@ -90,6 +90,13 @@ class AlterPlan {
|
|
|
90
90
|
newName,
|
|
91
91
|
});
|
|
92
92
|
}
|
|
93
|
+
renameSqlObject(table, newName) {
|
|
94
|
+
this.operations.push({
|
|
95
|
+
operationType: 'renameSqlObject',
|
|
96
|
+
object: table,
|
|
97
|
+
newName,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
93
100
|
renameColumn(column, newName) {
|
|
94
101
|
this.operations.push({
|
|
95
102
|
operationType: 'renameColumn',
|
|
@@ -290,7 +297,7 @@ class AlterPlan {
|
|
|
290
297
|
}
|
|
291
298
|
// console.log('*****************RECREATED NEEDED', op, operationType, isAllowed);
|
|
292
299
|
// console.log(this.dialect);
|
|
293
|
-
if (this.opts.noDropTable) {
|
|
300
|
+
if (this.opts.noDropTable && !this.opts.allowTableRecreateWhenNoDrop) {
|
|
294
301
|
// skip this operation, as it cannot be achieved
|
|
295
302
|
return [];
|
|
296
303
|
}
|
|
@@ -341,7 +348,9 @@ class AlterPlan {
|
|
|
341
348
|
return this.operations;
|
|
342
349
|
}
|
|
343
350
|
const fks = [];
|
|
344
|
-
const res = this.operations
|
|
351
|
+
const res = this.operations
|
|
352
|
+
.filter(op => op.operationType != 'createConstraint')
|
|
353
|
+
.map(op => {
|
|
345
354
|
if (op.operationType == 'createTable') {
|
|
346
355
|
fks.push(...(op.newObject.foreignKeys || []));
|
|
347
356
|
return Object.assign(Object.assign({}, op), { newObject: Object.assign(Object.assign({}, op.newObject), { foreignKeys: [] }) });
|
|
@@ -350,6 +359,7 @@ class AlterPlan {
|
|
|
350
359
|
});
|
|
351
360
|
return [
|
|
352
361
|
...res,
|
|
362
|
+
...this.operations.filter(op => op.operationType == 'createConstraint'),
|
|
353
363
|
...fks.map(fk => ({
|
|
354
364
|
operationType: 'createConstraint',
|
|
355
365
|
newObject: fk,
|
|
@@ -366,8 +376,13 @@ class AlterPlan {
|
|
|
366
376
|
return false;
|
|
367
377
|
if (this.opts.noDropConstraint && op.operationType == 'dropConstraint')
|
|
368
378
|
return false;
|
|
369
|
-
if (
|
|
370
|
-
|
|
379
|
+
// if (
|
|
380
|
+
// this.opts.noDropSqlObject &&
|
|
381
|
+
// op.operationType == 'dropSqlObject' &&
|
|
382
|
+
// // allow to drop previously deleted SQL objects
|
|
383
|
+
// !hasDeletedPrefix(op.oldObject.pureName, this.opts, this.opts.deletedSqlObjectPrefix)
|
|
384
|
+
// )
|
|
385
|
+
// return false;
|
|
371
386
|
return true;
|
|
372
387
|
});
|
|
373
388
|
}
|
|
@@ -418,6 +433,9 @@ function runAlterOperation(op, processor) {
|
|
|
418
433
|
case 'renameTable':
|
|
419
434
|
processor.renameTable(op.object, op.newName);
|
|
420
435
|
break;
|
|
436
|
+
case 'renameSqlObject':
|
|
437
|
+
processor.renameSqlObject(op.object, op.newName);
|
|
438
|
+
break;
|
|
421
439
|
case 'renameConstraint':
|
|
422
440
|
processor.renameConstraint(op.object, op.newName);
|
|
423
441
|
break;
|
|
@@ -13,6 +13,7 @@ export declare class DatabaseInfoAlterProcessor {
|
|
|
13
13
|
changeConstraint(oldConstraint: ConstraintInfo, newConstraint: ConstraintInfo): void;
|
|
14
14
|
dropConstraint(constraint: ConstraintInfo): void;
|
|
15
15
|
renameTable(table: TableInfo, newName: string): void;
|
|
16
|
+
renameSqlObject(obj: SqlObjectInfo, newName: string): void;
|
|
16
17
|
renameColumn(column: ColumnInfo, newName: string): void;
|
|
17
18
|
renameConstraint(constraint: ConstraintInfo, newName: string): void;
|
|
18
19
|
recreateTable(oldTable: TableInfo, newTable: TableInfo): void;
|
|
@@ -91,6 +91,10 @@ class DatabaseInfoAlterProcessor {
|
|
|
91
91
|
renameTable(table, newName) {
|
|
92
92
|
this.db.tables.find(x => x.pureName == table.pureName && x.schemaName == table.schemaName).pureName = newName;
|
|
93
93
|
}
|
|
94
|
+
renameSqlObject(obj, newName) {
|
|
95
|
+
this.db[obj.objectTypeField].find(x => x.pureName == obj.pureName && x.schemaName == obj.schemaName).pureName =
|
|
96
|
+
newName;
|
|
97
|
+
}
|
|
94
98
|
renameColumn(column, newName) {
|
|
95
99
|
const table = this.db.tables.find(x => x.pureName == column.pureName && x.schemaName == column.schemaName);
|
|
96
100
|
table.columns.find(x => x.columnName == column.columnName).columnName = newName;
|
package/lib/diffTools.d.ts
CHANGED
|
@@ -8,9 +8,13 @@ export interface DbDiffOptions {
|
|
|
8
8
|
rightImplicitSchema?: string;
|
|
9
9
|
ignoreConstraintNames?: boolean;
|
|
10
10
|
noDropTable?: boolean;
|
|
11
|
+
allowTableRecreateWhenNoDrop?: boolean;
|
|
12
|
+
deletedTablePrefix?: string;
|
|
11
13
|
noDropColumn?: boolean;
|
|
14
|
+
deletedColumnPrefix?: string;
|
|
12
15
|
noDropConstraint?: boolean;
|
|
13
16
|
noDropSqlObject?: boolean;
|
|
17
|
+
deletedSqlObjectPrefix?: string;
|
|
14
18
|
noRenameTable?: boolean;
|
|
15
19
|
noRenameColumn?: boolean;
|
|
16
20
|
ignoreForeignKeyActions?: boolean;
|
|
@@ -19,6 +23,7 @@ export interface DbDiffOptions {
|
|
|
19
23
|
export declare function generateTablePairingId(table: TableInfo): TableInfo;
|
|
20
24
|
export declare function removeTablePairingId(table: TableInfo): TableInfo;
|
|
21
25
|
export declare function generateDbPairingId(db: DatabaseInfo): DatabaseInfo;
|
|
26
|
+
export declare function hasDeletedPrefix(name: string, opts: DbDiffOptions, deletedPrefix?: string): boolean;
|
|
22
27
|
export declare function testEqualColumns(a: ColumnInfo, b: ColumnInfo, checkName: boolean, checkDefault: boolean, opts?: DbDiffOptions): boolean;
|
|
23
28
|
export declare function testEqualTypes(a: ColumnInfo, b: ColumnInfo, opts?: DbDiffOptions): boolean;
|
|
24
29
|
export declare function testEqualTables(a: TableInfo, b: TableInfo, opts: DbDiffOptions, wholeOldDb: DatabaseInfo, wholeNewDb: DatabaseInfo, driver: EngineDriver): boolean;
|
package/lib/diffTools.js
CHANGED
|
@@ -3,14 +3,17 @@ 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.modelCompareDbDiffOptions = exports.matchPairedObjects = exports.getAlterDatabaseScript = exports.getAlterTableScript = exports.createAlterDatabasePlan = exports.createAlterTablePlan = exports.testEqualSqlObjects = exports.testEqualTables = exports.testEqualTypes = exports.testEqualColumns = exports.generateDbPairingId = exports.removeTablePairingId = 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.hasDeletedPrefix = exports.generateDbPairingId = exports.removeTablePairingId = 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"));
|
|
10
|
+
const toposort_1 = __importDefault(require("toposort"));
|
|
10
11
|
const omit_1 = __importDefault(require("lodash/omit"));
|
|
11
12
|
const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
|
|
12
13
|
const isEqual_1 = __importDefault(require("lodash/isEqual"));
|
|
13
14
|
const pick_1 = __importDefault(require("lodash/pick"));
|
|
15
|
+
const compact_1 = __importDefault(require("lodash/compact"));
|
|
16
|
+
const isString_1 = __importDefault(require("lodash/isString"));
|
|
14
17
|
function generateTablePairingId(table) {
|
|
15
18
|
var _a, _b, _c, _d, _e;
|
|
16
19
|
if (!table)
|
|
@@ -42,7 +45,36 @@ function generateDbPairingId(db) {
|
|
|
42
45
|
tables: (_a = db.tables) === null || _a === void 0 ? void 0 : _a.map(generateTablePairingId), views: (_b = db.views) === null || _b === void 0 ? void 0 : _b.map(generateObjectPairingId), procedures: (_c = db.procedures) === null || _c === void 0 ? void 0 : _c.map(generateObjectPairingId), functions: (_d = db.functions) === null || _d === void 0 ? void 0 : _d.map(generateObjectPairingId), triggers: (_e = db.triggers) === null || _e === void 0 ? void 0 : _e.map(generateObjectPairingId), matviews: (_f = db.matviews) === null || _f === void 0 ? void 0 : _f.map(generateObjectPairingId) });
|
|
43
46
|
}
|
|
44
47
|
exports.generateDbPairingId = generateDbPairingId;
|
|
45
|
-
function
|
|
48
|
+
function getNameWithoutDeletedPrefix(name, opts, deletedPrefix) {
|
|
49
|
+
if (deletedPrefix) {
|
|
50
|
+
if (opts.ignoreCase) {
|
|
51
|
+
if ((name || '').toLowerCase().startsWith(deletedPrefix.toLowerCase())) {
|
|
52
|
+
return name.slice(deletedPrefix.length);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if ((name || '').startsWith(deletedPrefix)) {
|
|
57
|
+
return name.slice(deletedPrefix.length);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return name;
|
|
62
|
+
}
|
|
63
|
+
function hasDeletedPrefix(name, opts, deletedPrefix) {
|
|
64
|
+
if (deletedPrefix) {
|
|
65
|
+
if (opts.ignoreCase) {
|
|
66
|
+
return (name || '').toLowerCase().startsWith(deletedPrefix.toLowerCase());
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
return (name || '').startsWith(deletedPrefix);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
exports.hasDeletedPrefix = hasDeletedPrefix;
|
|
75
|
+
function testEqualNames(a, b, opts, deletedPrefix) {
|
|
76
|
+
a = getNameWithoutDeletedPrefix(a, opts, deletedPrefix);
|
|
77
|
+
b = getNameWithoutDeletedPrefix(b, opts, deletedPrefix);
|
|
46
78
|
if (opts.ignoreCase)
|
|
47
79
|
return (a || '').toLowerCase() == (b || '').toLowerCase();
|
|
48
80
|
return a == b;
|
|
@@ -58,16 +90,25 @@ function testEqualSchemas(lschema, rschema, opts) {
|
|
|
58
90
|
rschema = null;
|
|
59
91
|
return testEqualNames(lschema, rschema, opts);
|
|
60
92
|
}
|
|
61
|
-
function testEqualFullNames(lft, rgt, opts) {
|
|
93
|
+
function testEqualFullNames(lft, rgt, opts, deletedPrefix) {
|
|
62
94
|
if (lft == null || rgt == null)
|
|
63
95
|
return lft == rgt;
|
|
64
|
-
return testEqualSchemas(lft.schemaName, rgt.schemaName, opts) &&
|
|
96
|
+
return (testEqualSchemas(lft.schemaName, rgt.schemaName, opts) &&
|
|
97
|
+
testEqualNames(lft.pureName, rgt.pureName, opts, deletedPrefix));
|
|
65
98
|
}
|
|
66
99
|
function testEqualDefaultValues(value1, value2) {
|
|
67
100
|
if (value1 == null)
|
|
68
101
|
return value2 == null || value2 == 'NULL';
|
|
69
102
|
if (value2 == null)
|
|
70
103
|
return value1 == null || value1 == 'NULL';
|
|
104
|
+
if ((0, isString_1.default)(value1) && (0, isString_1.default)(value2)) {
|
|
105
|
+
value1 = value1.trim();
|
|
106
|
+
value2 = value2.trim();
|
|
107
|
+
if (value1.startsWith("'") && value1.endsWith("'") && value2.startsWith("'") && value2.endsWith("'")) {
|
|
108
|
+
return value1 == value2;
|
|
109
|
+
}
|
|
110
|
+
return value1.toLowerCase() == value2.toLowerCase();
|
|
111
|
+
}
|
|
71
112
|
return value1 == value2;
|
|
72
113
|
}
|
|
73
114
|
function testEqualColumns(a, b, checkName, checkDefault, opts = {}) {
|
|
@@ -267,24 +308,43 @@ function planAlterTable(plan, oldTable, newTable, opts) {
|
|
|
267
308
|
if (!opts.noDropConstraint) {
|
|
268
309
|
constraintPairs.filter(x => x[1] == null).forEach(x => plan.dropConstraint(x[0]));
|
|
269
310
|
}
|
|
270
|
-
if (
|
|
311
|
+
if (opts.deletedColumnPrefix) {
|
|
312
|
+
columnPairs
|
|
313
|
+
.filter(x => x[1] == null)
|
|
314
|
+
.forEach(x => {
|
|
315
|
+
if (!hasDeletedPrefix(x[0].columnName, opts, opts.deletedColumnPrefix)) {
|
|
316
|
+
plan.renameColumn(x[0], opts.deletedColumnPrefix + x[0].columnName);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
else if (!opts.noDropColumn) {
|
|
271
321
|
columnPairs.filter(x => x[1] == null).forEach(x => plan.dropColumn(x[0]));
|
|
272
322
|
}
|
|
273
323
|
if (!testEqualFullNames(oldTable, newTable, opts) && !opts.noRenameTable) {
|
|
274
324
|
plan.renameTable(oldTable, newTable.pureName);
|
|
275
325
|
}
|
|
326
|
+
if (hasDeletedPrefix(oldTable.pureName, opts, opts.deletedTablePrefix)) {
|
|
327
|
+
plan.renameTable(oldTable, newTable.pureName);
|
|
328
|
+
}
|
|
276
329
|
columnPairs.filter(x => x[0] == null).forEach(x => plan.createColumn(x[1]));
|
|
277
330
|
columnPairs
|
|
278
331
|
.filter(x => x[0] && x[1])
|
|
279
332
|
.forEach(x => {
|
|
280
|
-
|
|
281
|
-
|
|
333
|
+
let srccol = x[0];
|
|
334
|
+
let dstcol = x[1];
|
|
335
|
+
if (hasDeletedPrefix(srccol.columnName, opts, opts.deletedColumnPrefix)) {
|
|
336
|
+
plan.renameColumn(srccol, dstcol.columnName);
|
|
337
|
+
// rename is already done
|
|
338
|
+
srccol = Object.assign(Object.assign({}, srccol), { columnName: dstcol.columnName });
|
|
339
|
+
}
|
|
340
|
+
if (!testEqualColumns(srccol, dstcol, true, true, opts)) {
|
|
341
|
+
if (testEqualColumns(srccol, dstcol, false, true, opts) && !opts.noRenameColumn) {
|
|
282
342
|
// console.log('PLAN RENAME COLUMN')
|
|
283
|
-
plan.renameColumn(
|
|
343
|
+
plan.renameColumn(srccol, dstcol.columnName);
|
|
284
344
|
}
|
|
285
345
|
else {
|
|
286
346
|
// console.log('PLAN CHANGE COLUMN', x[0], x[1]);
|
|
287
|
-
plan.changeColumn(
|
|
347
|
+
plan.changeColumn(srccol, dstcol);
|
|
288
348
|
}
|
|
289
349
|
}
|
|
290
350
|
});
|
|
@@ -325,7 +385,8 @@ function testEqualTables(a, b, opts, wholeOldDb, wholeNewDb, driver) {
|
|
|
325
385
|
}
|
|
326
386
|
exports.testEqualTables = testEqualTables;
|
|
327
387
|
function testEqualSqlObjects(a, b, opts) {
|
|
328
|
-
|
|
388
|
+
var _a, _b;
|
|
389
|
+
return ((_a = a.createSql) === null || _a === void 0 ? void 0 : _a.trim()) == ((_b = b.createSql) === null || _b === void 0 ? void 0 : _b.trim());
|
|
329
390
|
}
|
|
330
391
|
exports.testEqualSqlObjects = testEqualSqlObjects;
|
|
331
392
|
function createAlterTablePlan(oldTable, newTable, opts, wholeOldDb, wholeNewDb, driver) {
|
|
@@ -344,6 +405,36 @@ function createAlterTablePlan(oldTable, newTable, opts, wholeOldDb, wholeNewDb,
|
|
|
344
405
|
return plan;
|
|
345
406
|
}
|
|
346
407
|
exports.createAlterTablePlan = createAlterTablePlan;
|
|
408
|
+
function sortViewsByDependency(views) {
|
|
409
|
+
const viewNames = [];
|
|
410
|
+
const viewDict = {};
|
|
411
|
+
for (const view of views) {
|
|
412
|
+
if (!viewNames.includes(view.pureName)) {
|
|
413
|
+
viewNames.push(view.pureName);
|
|
414
|
+
}
|
|
415
|
+
viewDict[view.pureName] = viewDict[view.pureName]
|
|
416
|
+
? `${viewDict[view.pureName]} ${view.createSql}}`
|
|
417
|
+
: view.createSql;
|
|
418
|
+
}
|
|
419
|
+
const edges = [];
|
|
420
|
+
for (const viewName of viewNames) {
|
|
421
|
+
edges.push([viewName, null]);
|
|
422
|
+
const viewText = viewDict[viewName];
|
|
423
|
+
for (const otherView of viewNames) {
|
|
424
|
+
if (otherView === viewName)
|
|
425
|
+
continue;
|
|
426
|
+
if ((' ' + viewText + ' ').match('[\\W]' + otherView + '[\\W]')) {
|
|
427
|
+
edges.push([otherView, viewName]);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
const ordered = (0, compact_1.default)((0, toposort_1.default)(edges));
|
|
432
|
+
const res = [];
|
|
433
|
+
for (const viewName of ordered) {
|
|
434
|
+
res.push(...views.filter(x => x.pureName == viewName));
|
|
435
|
+
}
|
|
436
|
+
return res;
|
|
437
|
+
}
|
|
347
438
|
function createAlterDatabasePlan(oldDb, newDb, opts, wholeOldDb, wholeNewDb, driver) {
|
|
348
439
|
const plan = new alterPlan_1.AlterPlan(wholeOldDb, wholeNewDb, driver.dialect, opts);
|
|
349
440
|
for (const objectTypeField of ['tables', 'views', 'procedures', 'matviews', 'functions']) {
|
|
@@ -351,7 +442,10 @@ function createAlterDatabasePlan(oldDb, newDb, opts, wholeOldDb, wholeNewDb, dri
|
|
|
351
442
|
const newobj = (newDb[objectTypeField] || []).find(x => x.pairingId == oldobj.pairingId);
|
|
352
443
|
if (objectTypeField == 'tables') {
|
|
353
444
|
if (newobj == null) {
|
|
354
|
-
if (!opts.
|
|
445
|
+
if (opts.deletedTablePrefix && !hasDeletedPrefix(oldobj.pureName, opts, opts.deletedTablePrefix)) {
|
|
446
|
+
plan.renameTable(oldobj, opts.deletedTablePrefix + oldobj.pureName);
|
|
447
|
+
}
|
|
448
|
+
else if (!opts.noDropTable) {
|
|
355
449
|
plan.dropTable(oldobj);
|
|
356
450
|
}
|
|
357
451
|
}
|
|
@@ -361,20 +455,33 @@ function createAlterDatabasePlan(oldDb, newDb, opts, wholeOldDb, wholeNewDb, dri
|
|
|
361
455
|
}
|
|
362
456
|
else {
|
|
363
457
|
if (newobj == null) {
|
|
364
|
-
if (
|
|
458
|
+
if (opts.deletedSqlObjectPrefix &&
|
|
459
|
+
driver.dialect.renameSqlObject &&
|
|
460
|
+
!hasDeletedPrefix(oldobj.pureName, opts, opts.deletedSqlObjectPrefix)) {
|
|
461
|
+
plan.renameSqlObject(oldobj, opts.deletedSqlObjectPrefix + oldobj.pureName);
|
|
462
|
+
}
|
|
463
|
+
else if (!opts.noDropSqlObject) {
|
|
365
464
|
plan.dropSqlObject(oldobj);
|
|
366
465
|
}
|
|
367
466
|
}
|
|
368
|
-
else
|
|
369
|
-
|
|
370
|
-
if (!opts.noDropSqlObject) {
|
|
467
|
+
else {
|
|
468
|
+
if (opts.deletedSqlObjectPrefix && hasDeletedPrefix(oldobj.pureName, opts, opts.deletedSqlObjectPrefix)) {
|
|
371
469
|
plan.dropSqlObject(oldobj);
|
|
470
|
+
plan.createSqlObject(newobj);
|
|
471
|
+
}
|
|
472
|
+
else if (!testEqualSqlObjects(oldobj, newobj, opts)) {
|
|
473
|
+
plan.recreates.sqlObjects += 1;
|
|
474
|
+
plan.dropSqlObject(oldobj);
|
|
475
|
+
plan.createSqlObject(newobj);
|
|
372
476
|
}
|
|
373
|
-
plan.createSqlObject(newobj);
|
|
374
477
|
}
|
|
375
478
|
}
|
|
376
479
|
}
|
|
377
|
-
|
|
480
|
+
let newList = newDb[objectTypeField] || [];
|
|
481
|
+
if (objectTypeField == 'views') {
|
|
482
|
+
newList = sortViewsByDependency(newList);
|
|
483
|
+
}
|
|
484
|
+
for (const newobj of newList) {
|
|
378
485
|
const oldobj = (oldDb[objectTypeField] || []).find(x => x.pairingId == newobj.pairingId);
|
|
379
486
|
if (objectTypeField == 'tables') {
|
|
380
487
|
if (oldobj == null) {
|
|
@@ -422,12 +529,12 @@ function matchPairedObjects(db1, db2, opts) {
|
|
|
422
529
|
const res = (0, cloneDeep_1.default)(db2);
|
|
423
530
|
for (const objectTypeField of ['tables', 'views', 'procedures', 'matviews', 'functions']) {
|
|
424
531
|
for (const obj2 of res[objectTypeField] || []) {
|
|
425
|
-
const obj1 = db1[objectTypeField].find(x => testEqualFullNames(x, obj2, opts));
|
|
532
|
+
const obj1 = db1[objectTypeField].find(x => testEqualFullNames(x, obj2, opts, objectTypeField == 'tables' ? opts.deletedTablePrefix : opts.deletedSqlObjectPrefix));
|
|
426
533
|
if (obj1) {
|
|
427
534
|
obj2.pairingId = obj1.pairingId;
|
|
428
535
|
if (objectTypeField == 'tables') {
|
|
429
536
|
for (const col2 of obj2.columns) {
|
|
430
|
-
const col1 = obj1.columns.find(x => testEqualNames(x.columnName, col2.columnName, opts));
|
|
537
|
+
const col1 = obj1.columns.find(x => testEqualNames(x.columnName, col2.columnName, opts, opts.deletedColumnPrefix));
|
|
431
538
|
if (col1)
|
|
432
539
|
col2.pairingId = col1.pairingId;
|
|
433
540
|
}
|
package/lib/driverBase.js
CHANGED
|
@@ -18,6 +18,9 @@ const SqlDumper_1 = require("./SqlDumper");
|
|
|
18
18
|
const dbgate_query_splitter_1 = require("dbgate-query-splitter");
|
|
19
19
|
const dbgate_sqltree_1 = require("dbgate-sqltree");
|
|
20
20
|
const detectSqlFilterBehaviour_1 = require("./detectSqlFilterBehaviour");
|
|
21
|
+
const getLogger_1 = require("./getLogger");
|
|
22
|
+
const stringTools_1 = require("./stringTools");
|
|
23
|
+
const logger = (0, getLogger_1.getLogger)('driverBase');
|
|
21
24
|
const dialect = {
|
|
22
25
|
limitSelect: true,
|
|
23
26
|
rangeSelect: true,
|
|
@@ -89,6 +92,9 @@ exports.driverBase = {
|
|
|
89
92
|
}
|
|
90
93
|
for (const sqlItem of (0, dbgate_query_splitter_1.splitQuery)(sql, this.getQuerySplitterOptions('script'))) {
|
|
91
94
|
try {
|
|
95
|
+
if (options === null || options === void 0 ? void 0 : options.logScriptItems) {
|
|
96
|
+
logger.info({ sql: (0, stringTools_1.getLimitedQuery)(sqlItem) }, `Execute script item`);
|
|
97
|
+
}
|
|
92
98
|
yield this.query(pool, sqlItem, Object.assign({ discardResult: true }, options === null || options === void 0 ? void 0 : options.queryOptions));
|
|
93
99
|
}
|
|
94
100
|
catch (err) {
|
|
@@ -26,6 +26,9 @@ function getConnectionLabelCore(connection, { allowExplicitDatabase = true } = {
|
|
|
26
26
|
if (connection.databaseFile) {
|
|
27
27
|
return getDatabaseFileLabel(connection.databaseFile);
|
|
28
28
|
}
|
|
29
|
+
if (connection.useSshTunnel && connection.server == 'localhost') {
|
|
30
|
+
return `${connection.sshHost} - SSH`;
|
|
31
|
+
}
|
|
29
32
|
if (connection.server) {
|
|
30
33
|
return connection.server;
|
|
31
34
|
}
|
package/lib/stringTools.d.ts
CHANGED
package/lib/stringTools.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.safeFormatDate = exports.extractErrorLogData = exports.extractErrorStackTrace = exports.extractErrorMessage = exports.getConvertValueMenu = exports.detectTypeIcon = exports.detectCellDataType = exports.parseSqlDefaultValue = exports.getAsImageSrc = exports.arrayBufferToBase64 = exports.isWktGeometry = exports.getIconForRedisType = exports.isJsonLikeLongString = exports.shouldOpenMultilineDialog = exports.safeJsonParse = exports.stringifyCellValue = exports.parseCellValue = exports.hexStringToArray = exports.arrayToHexString = void 0;
|
|
6
|
+
exports.getLimitedQuery = exports.safeFormatDate = exports.extractErrorLogData = exports.extractErrorStackTrace = exports.extractErrorMessage = exports.getConvertValueMenu = exports.detectTypeIcon = exports.detectCellDataType = exports.parseSqlDefaultValue = exports.getAsImageSrc = exports.arrayBufferToBase64 = exports.isWktGeometry = exports.getIconForRedisType = exports.isJsonLikeLongString = exports.shouldOpenMultilineDialog = exports.safeJsonParse = exports.stringifyCellValue = exports.parseCellValue = exports.hexStringToArray = exports.arrayToHexString = void 0;
|
|
7
7
|
const isString_1 = __importDefault(require("lodash/isString"));
|
|
8
8
|
const isArray_1 = __importDefault(require("lodash/isArray"));
|
|
9
9
|
const isDate_1 = __importDefault(require("lodash/isDate"));
|
|
@@ -489,3 +489,13 @@ function safeFormatDate(date) {
|
|
|
489
489
|
}
|
|
490
490
|
}
|
|
491
491
|
exports.safeFormatDate = safeFormatDate;
|
|
492
|
+
function getLimitedQuery(sql) {
|
|
493
|
+
if (!sql) {
|
|
494
|
+
return sql;
|
|
495
|
+
}
|
|
496
|
+
if (sql.length > 1000) {
|
|
497
|
+
return sql.substring(0, 1000) + '...';
|
|
498
|
+
}
|
|
499
|
+
return sql;
|
|
500
|
+
}
|
|
501
|
+
exports.getLimitedQuery = getLimitedQuery;
|
package/lib/yamlModelConv.js
CHANGED
|
@@ -37,10 +37,11 @@ function columnInfoFromYaml(column, table) {
|
|
|
37
37
|
const res = {
|
|
38
38
|
pureName: table.name,
|
|
39
39
|
columnName: column.name,
|
|
40
|
-
dataType: column.length ? `${column.type}(${column.length})` : column.type,
|
|
40
|
+
dataType: column.length ? `${column.type}(${column.length < 0 ? 'max' : column.length})` : column.type,
|
|
41
41
|
autoIncrement: column.autoIncrement,
|
|
42
42
|
notNull: column.notNull || (table.primaryKey && table.primaryKey.includes(column.name)),
|
|
43
43
|
defaultValue: column.default,
|
|
44
|
+
defaultConstraint: column.default != null ? `DF_${table.name}_${column.name}` : undefined,
|
|
44
45
|
};
|
|
45
46
|
return res;
|
|
46
47
|
}
|
|
@@ -67,6 +68,7 @@ function convertForeignKeyFromYaml(col, table, allTables) {
|
|
|
67
68
|
return null;
|
|
68
69
|
return {
|
|
69
70
|
constraintType: 'foreignKey',
|
|
71
|
+
constraintName: `FK_${table.name}_${col.name}`,
|
|
70
72
|
pureName: table.name,
|
|
71
73
|
refTableName: col.references,
|
|
72
74
|
deleteAction: col.refDeleteAction,
|
|
@@ -89,6 +91,7 @@ function tableInfoFromYaml(table, allTables) {
|
|
|
89
91
|
res.primaryKey = {
|
|
90
92
|
pureName: table.name,
|
|
91
93
|
constraintType: 'primaryKey',
|
|
94
|
+
constraintName: `PK_${table.name}`,
|
|
92
95
|
columns: table.primaryKey.map(columnName => ({ columnName })),
|
|
93
96
|
};
|
|
94
97
|
}
|
|
@@ -96,6 +99,7 @@ function tableInfoFromYaml(table, allTables) {
|
|
|
96
99
|
res.sortingKey = {
|
|
97
100
|
pureName: table.name,
|
|
98
101
|
constraintType: 'sortingKey',
|
|
102
|
+
constraintName: `SK_${table.name}`,
|
|
99
103
|
columns: table.sortingKey.map(columnName => ({ columnName })),
|
|
100
104
|
};
|
|
101
105
|
}
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "5.5.
|
|
2
|
+
"version": "5.5.7-alpha.16",
|
|
3
3
|
"name": "dbgate-tools",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"typings": "lib/index.d.ts",
|
|
@@ -25,18 +25,19 @@
|
|
|
25
25
|
],
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/node": "^13.7.0",
|
|
28
|
-
"dbgate-types": "^5.5.
|
|
28
|
+
"dbgate-types": "^5.5.7-alpha.16",
|
|
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
|
"dbgate-query-splitter": "^4.11.2",
|
|
35
|
-
"dbgate-sqltree": "^5.5.
|
|
35
|
+
"dbgate-sqltree": "^5.5.7-alpha.16",
|
|
36
36
|
"debug": "^4.3.4",
|
|
37
37
|
"json-stable-stringify": "^1.0.1",
|
|
38
38
|
"lodash": "^4.17.21",
|
|
39
39
|
"pinomin": "^1.0.4",
|
|
40
|
+
"toposort": "^2.0.2",
|
|
40
41
|
"uuid": "^3.4.0"
|
|
41
42
|
}
|
|
42
43
|
}
|