dbgate-tools 5.5.7-alpha.16 → 5.5.7-alpha.26

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.
@@ -75,7 +75,7 @@ class DatabaseAnalyser {
75
75
  }
76
76
  fullAnalysis() {
77
77
  return __awaiter(this, void 0, void 0, function* () {
78
- logger.info(`Performing full analysis, DB=${(0, schemaInfoTools_1.dbNameLogCategory)(this.dbhan.database)}, engine=${this.driver.engine}`);
78
+ logger.debug(`Performing full analysis, DB=${(0, schemaInfoTools_1.dbNameLogCategory)(this.dbhan.database)}, engine=${this.driver.engine}`);
79
79
  const res = this.addEngineField(yield this._runAnalysis());
80
80
  // console.log('FULL ANALYSIS', res);
81
81
  return res;
@@ -52,7 +52,7 @@ class ScriptWriter {
52
52
  this._put(`await dbgateApi.importDatabase(${JSON.stringify(options)});`);
53
53
  }
54
54
  dataDuplicator(options) {
55
- this._put(`await dbgateApi.dataDuplicator(${JSON.stringify(options)});`);
55
+ this._put(`await dbgateApi.dataDuplicator(${JSON.stringify(options, null, 2)});`);
56
56
  }
57
57
  comment(s) {
58
58
  this._put(`// ${s}`);
package/lib/SqlDumper.js CHANGED
@@ -473,6 +473,9 @@ class SqlDumper {
473
473
  this.put('%i %k', col.columnName, col.isDescending == true ? 'DESC' : 'ASC');
474
474
  });
475
475
  this.put('&<&n)');
476
+ if (ix.filterDefinition && this.dialect.filteredIndexes) {
477
+ this.put('&n^where %s', ix.filterDefinition);
478
+ }
476
479
  this.endCommand();
477
480
  }
478
481
  dropUnique(uq) {
@@ -56,6 +56,7 @@ interface AlterOperation_ChangeConstraint {
56
56
  interface AlterOperation_DropConstraint {
57
57
  operationType: 'dropConstraint';
58
58
  oldObject: ConstraintInfo;
59
+ isRecreate?: boolean;
59
60
  }
60
61
  interface AlterOperation_RenameConstraint {
61
62
  operationType: 'renameConstraint';
@@ -82,7 +83,7 @@ interface AlterOperation_SetTableOption {
82
83
  optionName: string;
83
84
  optionValue: string;
84
85
  }
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;
86
+ export 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;
86
87
  export declare class AlterPlan {
87
88
  wholeOldDb: DatabaseInfo;
88
89
  wholeNewDb: DatabaseInfo;
package/lib/alterPlan.js CHANGED
@@ -184,14 +184,15 @@ class AlterPlan {
184
184
  ]) {
185
185
  if (op.operationType == testedOperationType) {
186
186
  const constraints = this._getDependendColumnConstraints(testedObject, testedDependencies);
187
- if (constraints.length > 0 && this.opts.noDropConstraint) {
188
- return [];
189
- }
187
+ // if (constraints.length > 0 && this.opts.noDropConstraint) {
188
+ // return [];
189
+ // }
190
190
  const res = [
191
191
  ...constraints.map(oldObject => {
192
192
  const opRes = {
193
193
  operationType: 'dropConstraint',
194
194
  oldObject,
195
+ isRecreate: true,
195
196
  };
196
197
  return opRes;
197
198
  }),
@@ -225,14 +226,15 @@ class AlterPlan {
225
226
  ];
226
227
  }
227
228
  if (op.operationType == 'changeConstraint') {
228
- if (this.opts.noDropConstraint) {
229
- // skip constraint recreate
230
- return [];
231
- }
229
+ // if (this.opts.noDropConstraint) {
230
+ // // skip constraint recreate
231
+ // return [];
232
+ // }
232
233
  this.recreates.constraints += 1;
233
234
  const opDrop = {
234
235
  operationType: 'dropConstraint',
235
236
  oldObject: op.oldObject,
237
+ isRecreate: true,
236
238
  };
237
239
  const opCreate = {
238
240
  operationType: 'createConstraint',
@@ -374,7 +376,7 @@ class AlterPlan {
374
376
  return false;
375
377
  if (this.opts.noDropTable && op.operationType == 'recreateTable')
376
378
  return false;
377
- if (this.opts.noDropConstraint && op.operationType == 'dropConstraint')
379
+ if (this.opts.noDropConstraint && op.operationType == 'dropConstraint' && !op.isRecreate)
378
380
  return false;
379
381
  // if (
380
382
  // this.opts.noDropSqlObject &&
@@ -1,5 +1,6 @@
1
1
  import { DbDiffOptions, testEqualTables, testEqualSqlObjects } from './diffTools';
2
2
  import type { DatabaseInfo, EngineDriver, SqlObjectInfo, TableInfo } from 'dbgate-types';
3
+ import { AlterOperation } from './alterPlan';
3
4
  export declare function computeDiffRowsCore(sourceList: any, targetList: any, testEqual: any): any[];
4
5
  export declare const DbDiffCompareDefs: {
5
6
  tables: {
@@ -35,4 +36,16 @@ export declare const DbDiffCompareDefs: {
35
36
  };
36
37
  export declare function computeDbDiffRows(sourceDb: DatabaseInfo, targetDb: DatabaseInfo, opts: DbDiffOptions, driver: EngineDriver): any[];
37
38
  export declare function computeTableDiffColumns(sourceTable: TableInfo, targetTable: TableInfo, opts: DbDiffOptions, driver: EngineDriver): any[];
39
+ export interface DiffOperationItemDisplay {
40
+ operationType: string;
41
+ name: string;
42
+ sqlScript: string;
43
+ identifier?: string;
44
+ }
45
+ export declare function getOperationDisplay(operation: AlterOperation, driver: EngineDriver): DiffOperationItemDisplay;
46
+ export declare function computeObjectDiffOperations(sourceObject: {
47
+ objectTypeField: string;
48
+ }, targetObject: {
49
+ objectTypeField: string;
50
+ }, sourceDb: DatabaseInfo, targetDb: DatabaseInfo, opts: DbDiffOptions, driver: EngineDriver): DiffOperationItemDisplay[];
38
51
  export declare function getCreateObjectScript(obj: TableInfo | SqlObjectInfo, driver: EngineDriver): string;
@@ -3,9 +3,11 @@ 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.getCreateObjectScript = exports.computeTableDiffColumns = exports.computeDbDiffRows = exports.DbDiffCompareDefs = exports.computeDiffRowsCore = void 0;
6
+ exports.getCreateObjectScript = exports.computeObjectDiffOperations = exports.getOperationDisplay = exports.computeTableDiffColumns = exports.computeDbDiffRows = exports.DbDiffCompareDefs = exports.computeDiffRowsCore = void 0;
7
7
  const diffTools_1 = require("./diffTools");
8
8
  const lodash_1 = __importDefault(require("lodash"));
9
+ const structureTools_1 = require("./structureTools");
10
+ const alterPlan_1 = require("./alterPlan");
9
11
  function computeDiffRowsCore(sourceList, targetList, testEqual) {
10
12
  const res = [];
11
13
  for (const obj of sourceList) {
@@ -95,6 +97,33 @@ function computeTableDiffColumns(sourceTable, targetTable, opts, driver) {
95
97
  });
96
98
  }
97
99
  exports.computeTableDiffColumns = computeTableDiffColumns;
100
+ function getOperationDisplay(operation, driver) {
101
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
102
+ const op = operation;
103
+ const name = (_u = (_s = (_q = (_o = (_l = (_j = (_g = (_e = (_c = (_a = op === null || op === void 0 ? void 0 : op.newName) !== null && _a !== void 0 ? _a : (_b = op === null || op === void 0 ? void 0 : op.newObject) === null || _b === void 0 ? void 0 : _b.columnName) !== null && _c !== void 0 ? _c : (_d = op === null || op === void 0 ? void 0 : op.newObject) === null || _d === void 0 ? void 0 : _d.constraintName) !== null && _e !== void 0 ? _e : (_f = op === null || op === void 0 ? void 0 : op.newObject) === null || _f === void 0 ? void 0 : _f.pureName) !== null && _g !== void 0 ? _g : (_h = op === null || op === void 0 ? void 0 : op.oldObject) === null || _h === void 0 ? void 0 : _h.columnName) !== null && _j !== void 0 ? _j : (_k = op === null || op === void 0 ? void 0 : op.oldObject) === null || _k === void 0 ? void 0 : _k.constraintName) !== null && _l !== void 0 ? _l : (_m = op === null || op === void 0 ? void 0 : op.oldObject) === null || _m === void 0 ? void 0 : _m.pureName) !== null && _o !== void 0 ? _o : (_p = op === null || op === void 0 ? void 0 : op.table) === null || _p === void 0 ? void 0 : _p.pureName) !== null && _q !== void 0 ? _q : (_r = op === null || op === void 0 ? void 0 : op.object) === null || _r === void 0 ? void 0 : _r.columnName) !== null && _s !== void 0 ? _s : (_t = op === null || op === void 0 ? void 0 : op.object) === null || _t === void 0 ? void 0 : _t.constraintName) !== null && _u !== void 0 ? _u : (_v = op === null || op === void 0 ? void 0 : op.object) === null || _v === void 0 ? void 0 : _v.pureName;
104
+ const dmp = driver.createDumper();
105
+ (0, alterPlan_1.runAlterOperation)(operation, dmp);
106
+ return {
107
+ operationType: operation.operationType,
108
+ name,
109
+ sqlScript: dmp.s,
110
+ identifier: dmp.s,
111
+ };
112
+ }
113
+ exports.getOperationDisplay = getOperationDisplay;
114
+ function computeObjectDiffOperations(sourceObject, targetObject, sourceDb, targetDb, opts, driver) {
115
+ if (!driver)
116
+ return [];
117
+ const srcdb = sourceObject
118
+ ? (0, structureTools_1.extendDatabaseInfo)({ [sourceObject.objectTypeField]: [sourceObject] })
119
+ : (0, structureTools_1.extendDatabaseInfo)({});
120
+ const dstdb = targetObject
121
+ ? (0, structureTools_1.extendDatabaseInfo)({ [targetObject.objectTypeField]: [targetObject] })
122
+ : (0, structureTools_1.extendDatabaseInfo)({});
123
+ const plan = (0, diffTools_1.createAlterDatabasePlan)(dstdb, srcdb, opts, targetDb, sourceDb, driver);
124
+ return plan.operations.map(item => getOperationDisplay(item, driver));
125
+ }
126
+ exports.computeObjectDiffOperations = computeObjectDiffOperations;
98
127
  function getCreateObjectScript(obj, driver) {
99
128
  if (!obj || !driver)
100
129
  return '';
@@ -41,7 +41,7 @@ export declare function getAlterTableScript(oldTable: TableInfo, newTable: Table
41
41
  sqlObjects: number;
42
42
  };
43
43
  };
44
- export declare function getAlterDatabaseScript(oldDb: DatabaseInfo, newDb: DatabaseInfo, opts: DbDiffOptions, wholeOldDb: DatabaseInfo, wholeNewDb: DatabaseInfo, driver: EngineDriver): {
44
+ export declare function getAlterDatabaseScript(oldDb: DatabaseInfo, newDb: DatabaseInfo, opts: DbDiffOptions, wholeOldDb: DatabaseInfo, wholeNewDb: DatabaseInfo, driver: EngineDriver, transformPlan?: (plan: AlterPlan) => void): {
45
45
  sql: string;
46
46
  recreates: {
47
47
  tables: number;
package/lib/diffTools.js CHANGED
@@ -6,14 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
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
- const json_stable_stringify_1 = __importDefault(require("json-stable-stringify"));
10
9
  const toposort_1 = __importDefault(require("toposort"));
11
- const omit_1 = __importDefault(require("lodash/omit"));
12
10
  const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
13
11
  const isEqual_1 = __importDefault(require("lodash/isEqual"));
14
12
  const pick_1 = __importDefault(require("lodash/pick"));
15
13
  const compact_1 = __importDefault(require("lodash/compact"));
16
14
  const isString_1 = __importDefault(require("lodash/isString"));
15
+ const structureTools_1 = require("./structureTools");
17
16
  function generateTablePairingId(table) {
18
17
  var _a, _b, _c, _d, _e;
19
18
  if (!table)
@@ -31,6 +30,12 @@ function removeTablePairingId(table) {
31
30
  return Object.assign(Object.assign({}, table), { columns: (_a = table.columns) === null || _a === void 0 ? void 0 : _a.map(col => (Object.assign(Object.assign({}, col), { pairingId: undefined }))), foreignKeys: (_b = table.foreignKeys) === null || _b === void 0 ? void 0 : _b.map(cnt => (Object.assign(Object.assign({}, cnt), { pairingId: undefined }))), checks: (_c = table.checks) === null || _c === void 0 ? void 0 : _c.map(cnt => (Object.assign(Object.assign({}, cnt), { pairingId: undefined }))), indexes: (_d = table.indexes) === null || _d === void 0 ? void 0 : _d.map(cnt => (Object.assign(Object.assign({}, cnt), { pairingId: undefined }))), uniques: (_e = table.uniques) === null || _e === void 0 ? void 0 : _e.map(cnt => (Object.assign(Object.assign({}, cnt), { pairingId: undefined }))), pairingId: undefined });
32
31
  }
33
32
  exports.removeTablePairingId = removeTablePairingId;
33
+ function simplifySqlExpression(sql) {
34
+ return (sql || '')
35
+ .replace(/[\s\(\)\[\]\"]/g, '')
36
+ .toLowerCase()
37
+ .trim();
38
+ }
34
39
  function generateObjectPairingId(obj) {
35
40
  if (obj.objectTypeField)
36
41
  return Object.assign(Object.assign({}, obj), { pairingId: obj.pairingId || (0, v1_1.default)() });
@@ -216,19 +221,86 @@ function testEqualColumns(a, b, checkName, checkDefault, opts = {}) {
216
221
  return true;
217
222
  }
218
223
  exports.testEqualColumns = testEqualColumns;
219
- function testEqualConstraints(a, b, opts = {}) {
220
- const omitList = [];
221
- if (opts.ignoreForeignKeyActions) {
222
- omitList.push('updateAction');
223
- omitList.push('deleteAction');
224
- }
225
- if (opts.ignoreConstraintNames) {
226
- omitList.push('constraintName');
224
+ function testEqualColumnRefs(a, b, opts) {
225
+ if (a.length != b.length)
226
+ return false;
227
+ for (let i = 0; i < a.length; i++) {
228
+ if (!testEqualNames(a[i].columnName, b[i].columnName, opts))
229
+ return false;
230
+ if (!testEqualNames(a[i].refColumnName, b[i].refColumnName, opts))
231
+ return false;
227
232
  }
228
- if (opts.schemaMode == 'ignore') {
229
- omitList.push('schemaName');
230
- omitList.push('refSchemaName');
233
+ return true;
234
+ }
235
+ function testEqualPrimaryKeys(a, b, opts) {
236
+ if (!testEqualColumnRefs(a.columns, b.columns, opts))
237
+ return false;
238
+ return true;
239
+ }
240
+ function testEqualForeignKeys(a, b, opts) {
241
+ if (!testEqualColumnRefs(a.columns, b.columns, opts))
242
+ return false;
243
+ if (!opts.ignoreConstraintNames && !testEqualNames(a.constraintName, b.constraintName, opts))
244
+ return false;
245
+ return true;
246
+ }
247
+ function testEqualIndex(a, b, opts) {
248
+ if (!testEqualColumnRefs(a.columns, b.columns, opts))
249
+ return false;
250
+ if (!!a.isUnique != !!b.isUnique)
251
+ return false;
252
+ if (simplifySqlExpression(a.filterDefinition) != simplifySqlExpression(b.filterDefinition))
253
+ return false;
254
+ if (!opts.ignoreConstraintNames && !testEqualNames(a.constraintName, b.constraintName, opts))
255
+ return false;
256
+ return true;
257
+ }
258
+ function testEqualUnique(a, b, opts) {
259
+ if (!testEqualColumnRefs(a.columns, b.columns, opts))
260
+ return false;
261
+ if (!opts.ignoreConstraintNames && !testEqualNames(a.constraintName, b.constraintName, opts))
262
+ return false;
263
+ return true;
264
+ }
265
+ function testEqualCheck(a, b, opts) {
266
+ if (a.definition != b.definition)
267
+ return false;
268
+ if (!opts.ignoreConstraintNames && !testEqualNames(a.constraintName, b.constraintName, opts))
269
+ return false;
270
+ return true;
271
+ }
272
+ function testEqualConstraints(a, b, opts = {}) {
273
+ if (a.constraintType != b.constraintType) {
274
+ console.debug(`Constraint ${a.pureName}: different constraint type: ${a.constraintType}, ${b.constraintType}`);
275
+ return false;
231
276
  }
277
+ switch (a.constraintType) {
278
+ case 'primaryKey':
279
+ case 'sortingKey':
280
+ return testEqualPrimaryKeys(a, b, opts);
281
+ case 'foreignKey':
282
+ return testEqualForeignKeys(a, b, opts);
283
+ case 'index':
284
+ return testEqualIndex(a, b, opts);
285
+ case 'unique':
286
+ return testEqualUnique(a, b, opts);
287
+ case 'check':
288
+ return testEqualCheck(a, b, opts);
289
+ }
290
+ console.debug(`Unknown constraint type: ${a.pureName}`);
291
+ return false;
292
+ // const omitList = ['pairingId'];
293
+ // if (opts.ignoreForeignKeyActions) {
294
+ // omitList.push('updateAction');
295
+ // omitList.push('deleteAction');
296
+ // }
297
+ // if (opts.ignoreConstraintNames) {
298
+ // omitList.push('constraintName');
299
+ // }
300
+ // if (opts.schemaMode == 'ignore') {
301
+ // omitList.push('schemaName');
302
+ // omitList.push('refSchemaName');
303
+ // }
232
304
  // if (a.constraintType == 'primaryKey' && b.constraintType == 'primaryKey') {
233
305
  // console.log('PK1', stableStringify(_.omit(a, omitList)));
234
306
  // console.log('PK2', stableStringify(_.omit(b, omitList)));
@@ -241,13 +313,15 @@ function testEqualConstraints(a, b, opts = {}) {
241
313
  // console.log('IX1', stableStringify(_omit(a, omitList)));
242
314
  // console.log('IX2', stableStringify(_omit(b, omitList)));
243
315
  // }
244
- 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));
316
+ // const aStringified = stableStringify(_omit(a, omitList));
317
+ // const bStringified = stableStringify(_omit(b, omitList));
318
+ // return aStringified == bStringified;
245
319
  }
246
320
  function testEqualTypes(a, b, opts = {}) {
247
321
  if (opts.ignoreDataTypes) {
248
322
  return true;
249
323
  }
250
- if ((a.dataType || '').toLowerCase() != (b.dataType || '').toLowerCase()) {
324
+ if (simplifySqlExpression(a.dataType) != simplifySqlExpression(b.dataType)) {
251
325
  console.debug(`Column ${a.pureName}.${a.columnName}, ${b.pureName}.${b.columnName}: different data type: ${a.dataType}, ${b.dataType}`);
252
326
  return false;
253
327
  }
@@ -291,7 +365,7 @@ function createPairs(oldList, newList, additionalCondition = null) {
291
365
  function planTablePreload(plan, oldTable, newTable) {
292
366
  var _a, _b, _c, _d;
293
367
  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));
294
- if (((_c = newTable.preloadedRows) === null || _c === void 0 ? void 0 : _c.length) > 0 && (key === null || key === void 0 ? void 0 : key.length) > 0) {
368
+ if (((_c = newTable.preloadedRows) === null || _c === void 0 ? void 0 : _c.length) > 0 && (key === null || key === void 0 ? void 0 : key.length) > 0 && (0, structureTools_1.detectChangesInPreloadedRows)(oldTable, newTable)) {
295
369
  plan.fillPreloadedRows(newTable, oldTable === null || oldTable === void 0 ? void 0 : oldTable.preloadedRows, newTable.preloadedRows, key, newTable.preloadedRowsInsertOnly, (_d = newTable.columns.find(x => x.autoIncrement)) === null || _d === void 0 ? void 0 : _d.columnName);
296
370
  }
297
371
  }
@@ -357,7 +431,6 @@ function planAlterTable(plan, oldTable, newTable, opts) {
357
431
  }
358
432
  });
359
433
  constraintPairs.filter(x => x[0] == null).forEach(x => plan.createConstraint(x[1]));
360
- planTablePreload(plan, oldTable, newTable);
361
434
  planChangeTableOptions(plan, oldTable, newTable, opts);
362
435
  // console.log('oldTable', oldTable);
363
436
  // console.log('newTable', newTable);
@@ -380,8 +453,16 @@ function planChangeTableOptions(plan, oldTable, newTable, opts) {
380
453
  function testEqualTables(a, b, opts, wholeOldDb, wholeNewDb, driver) {
381
454
  const plan = new alterPlan_1.AlterPlan(wholeOldDb, wholeNewDb, driver.dialect, opts);
382
455
  planAlterTable(plan, a, b, opts);
383
- // console.log('plan.operations', a, b, plan.operations);
384
- return plan.operations.length == 0;
456
+ // if (plan.operations.length > 0) {
457
+ // console.log('************** plan.operations', a, b, plan.operations);
458
+ // }
459
+ if (plan.operations.length > 0) {
460
+ return false;
461
+ }
462
+ if ((0, structureTools_1.detectChangesInPreloadedRows)(a, b)) {
463
+ return false;
464
+ }
465
+ return true;
385
466
  }
386
467
  exports.testEqualTables = testEqualTables;
387
468
  function testEqualSqlObjects(a, b, opts) {
@@ -400,6 +481,7 @@ function createAlterTablePlan(oldTable, newTable, opts, wholeOldDb, wholeNewDb,
400
481
  }
401
482
  else {
402
483
  planAlterTable(plan, oldTable, newTable, opts);
484
+ planTablePreload(plan, oldTable, newTable);
403
485
  }
404
486
  plan.transformPlan();
405
487
  return plan;
@@ -451,6 +533,7 @@ function createAlterDatabasePlan(oldDb, newDb, opts, wholeOldDb, wholeNewDb, dri
451
533
  }
452
534
  else {
453
535
  planAlterTable(plan, oldobj, newobj, opts);
536
+ planTablePreload(plan, oldobj, newobj);
454
537
  }
455
538
  }
456
539
  else {
@@ -512,8 +595,11 @@ function getAlterTableScript(oldTable, newTable, opts, wholeOldDb, wholeNewDb, d
512
595
  };
513
596
  }
514
597
  exports.getAlterTableScript = getAlterTableScript;
515
- function getAlterDatabaseScript(oldDb, newDb, opts, wholeOldDb, wholeNewDb, driver) {
598
+ function getAlterDatabaseScript(oldDb, newDb, opts, wholeOldDb, wholeNewDb, driver, transformPlan = null) {
516
599
  const plan = createAlterDatabasePlan(oldDb, newDb, opts, wholeOldDb, wholeNewDb, driver);
600
+ if (transformPlan) {
601
+ transformPlan(plan);
602
+ }
517
603
  const dmp = driver.createDumper({ useHardSeparator: true });
518
604
  plan.run(dmp);
519
605
  return {
@@ -563,7 +649,6 @@ function matchPairedObjects(db1, db2, opts) {
563
649
  exports.matchPairedObjects = matchPairedObjects;
564
650
  exports.modelCompareDbDiffOptions = {
565
651
  ignoreCase: true,
566
- schemaMode: 'ignore',
567
652
  ignoreConstraintNames: true,
568
653
  ignoreForeignKeyActions: true,
569
654
  ignoreDataTypes: true,
package/lib/driverBase.js CHANGED
@@ -93,7 +93,7 @@ exports.driverBase = {
93
93
  for (const sqlItem of (0, dbgate_query_splitter_1.splitQuery)(sql, this.getQuerySplitterOptions('script'))) {
94
94
  try {
95
95
  if (options === null || options === void 0 ? void 0 : options.logScriptItems) {
96
- logger.info({ sql: (0, stringTools_1.getLimitedQuery)(sqlItem) }, `Execute script item`);
96
+ logger.info({ sql: (0, stringTools_1.getLimitedQuery)(sqlItem) }, 'Execute script item');
97
97
  }
98
98
  yield this.query(pool, sqlItem, Object.assign({ discardResult: true }, options === null || options === void 0 ? void 0 : options.queryOptions));
99
99
  }
@@ -33,3 +33,4 @@ export declare function extractErrorLogData(err: any, additionalFields?: {}): {
33
33
  };
34
34
  export declare function safeFormatDate(date: any): any;
35
35
  export declare function getLimitedQuery(sql: string): string;
36
+ export declare function pinoLogRecordToMessageRecord(logRecord: any, defaultSeverity?: string): any;
@@ -1,9 +1,20 @@
1
1
  "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
2
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
15
  };
5
16
  Object.defineProperty(exports, "__esModule", { value: true });
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;
17
+ exports.pinoLogRecordToMessageRecord = 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
18
  const isString_1 = __importDefault(require("lodash/isString"));
8
19
  const isArray_1 = __importDefault(require("lodash/isArray"));
9
20
  const isDate_1 = __importDefault(require("lodash/isDate"));
@@ -499,3 +510,17 @@ function getLimitedQuery(sql) {
499
510
  return sql;
500
511
  }
501
512
  exports.getLimitedQuery = getLimitedQuery;
513
+ function pinoLogRecordToMessageRecord(logRecord, defaultSeverity = 'info') {
514
+ var _a;
515
+ const { level, time, msg } = logRecord, rest = __rest(logRecord, ["level", "time", "msg"]);
516
+ const levelToSeverity = {
517
+ 10: 'debug',
518
+ 20: 'debug',
519
+ 30: 'info',
520
+ 40: 'info',
521
+ 50: 'error',
522
+ 60: 'error',
523
+ };
524
+ return Object.assign(Object.assign({}, rest), { time, message: msg, severity: (_a = levelToSeverity[level]) !== null && _a !== void 0 ? _a : defaultSeverity });
525
+ }
526
+ exports.pinoLogRecordToMessageRecord = pinoLogRecordToMessageRecord;
@@ -13,3 +13,19 @@ export declare function isViewInfo(obj: {
13
13
  export declare function isCollectionInfo(obj: {
14
14
  objectTypeField?: string;
15
15
  }): obj is CollectionInfo;
16
+ export declare function filterStructureBySchema(db: DatabaseInfo, schema: string): DatabaseInfo;
17
+ export declare function getSchemasUsedByStructure(db: DatabaseInfo): string[] | DatabaseInfo;
18
+ export declare function replaceSchemaInStructure(db: DatabaseInfo, schema: string): DatabaseInfo;
19
+ export declare function skipNamesInStructureByRegex(db: DatabaseInfo, regex: RegExp): DatabaseInfo;
20
+ export declare function detectChangesInPreloadedRows(oldTable: TableInfo, newTable: TableInfo): boolean;
21
+ export declare function removePreloadedRowsFromStructure(db: DatabaseInfo): DatabaseInfo;
22
+ export declare function skipDbGateInternalObjects(db: DatabaseInfo): {
23
+ tables: TableInfo[];
24
+ engine?: string;
25
+ collections: CollectionInfo[];
26
+ views: ViewInfo[];
27
+ matviews: ViewInfo[];
28
+ procedures: import("dbgate-types").ProcedureInfo[];
29
+ functions: import("dbgate-types").FunctionInfo[];
30
+ triggers: import("dbgate-types").TriggerInfo[];
31
+ };
@@ -3,8 +3,10 @@ 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.isCollectionInfo = exports.isViewInfo = exports.isTableInfo = exports.isTableColumnUnique = exports.extendDatabaseInfoFromApps = exports.extendDatabaseInfo = exports.extendTableInfo = exports.addTableDependencies = void 0;
6
+ exports.skipDbGateInternalObjects = exports.removePreloadedRowsFromStructure = exports.detectChangesInPreloadedRows = exports.skipNamesInStructureByRegex = exports.replaceSchemaInStructure = exports.getSchemasUsedByStructure = exports.filterStructureBySchema = exports.isCollectionInfo = exports.isViewInfo = exports.isTableInfo = exports.isTableColumnUnique = exports.extendDatabaseInfoFromApps = exports.extendDatabaseInfo = exports.extendTableInfo = exports.addTableDependencies = void 0;
7
7
  const flatten_1 = __importDefault(require("lodash/flatten"));
8
+ const uniq_1 = __importDefault(require("lodash/uniq"));
9
+ const keys_1 = __importDefault(require("lodash/keys"));
8
10
  function addTableDependencies(db) {
9
11
  if (!db.tables) {
10
12
  return db;
@@ -61,3 +63,89 @@ function isCollectionInfo(obj) {
61
63
  return obj.objectTypeField == 'collections';
62
64
  }
63
65
  exports.isCollectionInfo = isCollectionInfo;
66
+ function filterStructureBySchema(db, schema) {
67
+ if (!db) {
68
+ return db;
69
+ }
70
+ return Object.assign(Object.assign({}, db), { tables: (db.tables || []).filter(x => x.schemaName == schema), views: (db.views || []).filter(x => x.schemaName == schema), collections: (db.collections || []).filter(x => x.schemaName == schema), matviews: (db.matviews || []).filter(x => x.schemaName == schema), procedures: (db.procedures || []).filter(x => x.schemaName == schema), functions: (db.functions || []).filter(x => x.schemaName == schema), triggers: (db.triggers || []).filter(x => x.schemaName == schema) });
71
+ }
72
+ exports.filterStructureBySchema = filterStructureBySchema;
73
+ function getSchemasUsedByStructure(db) {
74
+ if (!db) {
75
+ return db;
76
+ }
77
+ return (0, uniq_1.default)([
78
+ ...(db.tables || []).map(x => x.schemaName),
79
+ ...(db.views || []).map(x => x.schemaName),
80
+ ...(db.collections || []).map(x => x.schemaName),
81
+ ...(db.matviews || []).map(x => x.schemaName),
82
+ ...(db.procedures || []).map(x => x.schemaName),
83
+ ...(db.functions || []).map(x => x.schemaName),
84
+ ...(db.triggers || []).map(x => x.schemaName),
85
+ ]);
86
+ }
87
+ exports.getSchemasUsedByStructure = getSchemasUsedByStructure;
88
+ function replaceSchemaInStructure(db, schema) {
89
+ if (!db) {
90
+ return db;
91
+ }
92
+ return Object.assign(Object.assign({}, db), { tables: (db.tables || []).map(tbl => (Object.assign(Object.assign({}, tbl), { schemaName: schema, columns: (tbl.columns || []).map(column => (Object.assign(Object.assign({}, column), { schemaName: schema }))), primaryKey: tbl.primaryKey ? Object.assign(Object.assign({}, tbl.primaryKey), { schemaName: schema }) : undefined, sortingKey: tbl.sortingKey ? Object.assign(Object.assign({}, tbl.sortingKey), { schemaName: schema }) : undefined, foreignKeys: (tbl.foreignKeys || []).map(fk => (Object.assign(Object.assign({}, fk), { refSchemaName: schema, schemaName: schema }))), indexes: (tbl.indexes || []).map(idx => (Object.assign(Object.assign({}, idx), { schemaName: schema }))), uniques: (tbl.uniques || []).map(idx => (Object.assign(Object.assign({}, idx), { schemaName: schema }))), checks: (tbl.checks || []).map(idx => (Object.assign(Object.assign({}, idx), { schemaName: schema }))) }))), views: (db.views || []).map(x => (Object.assign(Object.assign({}, x), { schemaName: schema }))), collections: (db.collections || []).map(x => (Object.assign(Object.assign({}, x), { schemaName: schema }))), matviews: (db.matviews || []).map(x => (Object.assign(Object.assign({}, x), { schemaName: schema }))), procedures: (db.procedures || []).map(x => (Object.assign(Object.assign({}, x), { schemaName: schema }))), functions: (db.functions || []).map(x => (Object.assign(Object.assign({}, x), { schemaName: schema }))), triggers: (db.triggers || []).map(x => (Object.assign(Object.assign({}, x), { schemaName: schema }))) });
93
+ }
94
+ exports.replaceSchemaInStructure = replaceSchemaInStructure;
95
+ function skipNamesInStructureByRegex(db, regex) {
96
+ if (!db) {
97
+ return db;
98
+ }
99
+ return Object.assign(Object.assign({}, db), { tables: (db.tables || []).filter(tbl => !regex.test(tbl.pureName)), views: (db.views || []).filter(tbl => !regex.test(tbl.pureName)), collections: (db.collections || []).filter(tbl => !regex.test(tbl.pureName)), matviews: (db.matviews || []).filter(tbl => !regex.test(tbl.pureName)), procedures: (db.procedures || []).filter(tbl => !regex.test(tbl.pureName)), functions: (db.functions || []).filter(tbl => !regex.test(tbl.pureName)), triggers: (db.triggers || []).filter(tbl => !regex.test(tbl.pureName)) });
100
+ }
101
+ exports.skipNamesInStructureByRegex = skipNamesInStructureByRegex;
102
+ function detectChangesInPreloadedRows(oldTable, newTable) {
103
+ var _a, _b, _c, _d;
104
+ const key = (newTable === null || newTable === void 0 ? void 0 : newTable.preloadedRowsKey) ||
105
+ (oldTable === null || oldTable === void 0 ? void 0 : oldTable.preloadedRowsKey) ||
106
+ ((_b = (_a = newTable === null || newTable === void 0 ? void 0 : newTable.primaryKey) === null || _a === void 0 ? void 0 : _a.columns) === null || _b === void 0 ? void 0 : _b.map(x => x.columnName)) ||
107
+ ((_d = (_c = oldTable === null || oldTable === void 0 ? void 0 : oldTable.primaryKey) === null || _c === void 0 ? void 0 : _c.columns) === null || _d === void 0 ? void 0 : _d.map(x => x.columnName));
108
+ const oldRows = (oldTable === null || oldTable === void 0 ? void 0 : oldTable.preloadedRows) || [];
109
+ const newRows = (newTable === null || newTable === void 0 ? void 0 : newTable.preloadedRows) || [];
110
+ const insertOnly = (newTable === null || newTable === void 0 ? void 0 : newTable.preloadedRowsInsertOnly) || (oldTable === null || oldTable === void 0 ? void 0 : oldTable.preloadedRowsInsertOnly);
111
+ if (newRows.length != oldRows.length) {
112
+ return true;
113
+ }
114
+ for (const row of newRows) {
115
+ const old = oldRows === null || oldRows === void 0 ? void 0 : oldRows.find(r => key.every(col => r[col] == row[col]));
116
+ const rowKeys = (0, keys_1.default)(row);
117
+ if (old) {
118
+ const updated = [];
119
+ for (const col of rowKeys) {
120
+ if (row[col] != old[col] && !(insertOnly === null || insertOnly === void 0 ? void 0 : insertOnly.includes(col))) {
121
+ updated.push(col);
122
+ }
123
+ }
124
+ if (updated.length > 0) {
125
+ return true;
126
+ }
127
+ }
128
+ else {
129
+ return true;
130
+ }
131
+ }
132
+ for (const row of oldRows || []) {
133
+ const newr = oldRows === null || oldRows === void 0 ? void 0 : oldRows.find(r => key.every(col => r[col] == row[col]));
134
+ if (!newr) {
135
+ return true;
136
+ }
137
+ }
138
+ return false;
139
+ }
140
+ exports.detectChangesInPreloadedRows = detectChangesInPreloadedRows;
141
+ function removePreloadedRowsFromStructure(db) {
142
+ if (!db) {
143
+ return db;
144
+ }
145
+ return Object.assign(Object.assign({}, db), { tables: (db.tables || []).map(tbl => (Object.assign(Object.assign({}, tbl), { preloadedRows: undefined, preloadedRowsKey: undefined, preloadedRowsInsertOnly: undefined }))) });
146
+ }
147
+ exports.removePreloadedRowsFromStructure = removePreloadedRowsFromStructure;
148
+ function skipDbGateInternalObjects(db) {
149
+ return Object.assign(Object.assign({}, db), { tables: (db.tables || []).filter(tbl => tbl.pureName != 'dbgate_deploy_journal') });
150
+ }
151
+ exports.skipDbGateInternalObjects = skipDbGateInternalObjects;
@@ -16,11 +16,19 @@ export interface DatabaseModelFile {
16
16
  text: string;
17
17
  json: {};
18
18
  }
19
+ export interface IndexInfoYaml {
20
+ name: string;
21
+ unique?: boolean;
22
+ filter?: string;
23
+ columns: string[];
24
+ included?: string[];
25
+ }
19
26
  export interface TableInfoYaml {
20
27
  name: string;
21
28
  columns: ColumnInfoYaml[];
22
29
  primaryKey?: string[];
23
30
  sortingKey?: string[];
31
+ indexes?: IndexInfoYaml[];
24
32
  insertKey?: string[];
25
33
  insertOnly?: string[];
26
34
  data?: any[];
@@ -46,6 +46,7 @@ function columnInfoFromYaml(column, table) {
46
46
  return res;
47
47
  }
48
48
  function tableInfoToYaml(table) {
49
+ var _a;
49
50
  const tableCopy = (0, cloneDeep_1.default)(table);
50
51
  const res = {
51
52
  name: tableCopy.pureName,
@@ -59,6 +60,20 @@ function tableInfoToYaml(table) {
59
60
  res.sortingKey = tableCopy.sortingKey.columns.map(x => x.columnName);
60
61
  }
61
62
  // const foreignKeys = (tableCopy.foreignKeys || []).filter(x => !x['_dumped']).map(foreignKeyInfoToYaml);
63
+ if (((_a = tableCopy.indexes) === null || _a === void 0 ? void 0 : _a.length) > 0) {
64
+ res.indexes = tableCopy.indexes.map(index => {
65
+ const idx = {
66
+ name: index.constraintName,
67
+ unique: index.isUnique,
68
+ filter: index.filterDefinition,
69
+ columns: index.columns.filter(x => !x.isIncludedColumn).map(x => x.columnName),
70
+ };
71
+ if (index.columns.some(x => x.isIncludedColumn)) {
72
+ idx.included = index.columns.filter(x => x.isIncludedColumn).map(x => x.columnName);
73
+ }
74
+ return idx;
75
+ });
76
+ }
62
77
  return res;
63
78
  }
64
79
  exports.tableInfoToYaml = tableInfoToYaml;
@@ -82,10 +97,22 @@ function convertForeignKeyFromYaml(col, table, allTables) {
82
97
  };
83
98
  }
84
99
  function tableInfoFromYaml(table, allTables) {
100
+ var _a;
85
101
  const res = {
86
102
  pureName: table.name,
87
103
  columns: table.columns.map(c => columnInfoFromYaml(c, table)),
88
104
  foreignKeys: (0, compact_1.default)(table.columns.filter(x => x.references).map(col => convertForeignKeyFromYaml(col, table, allTables))),
105
+ indexes: (_a = table.indexes) === null || _a === void 0 ? void 0 : _a.map(index => ({
106
+ constraintName: index.name,
107
+ pureName: table.name,
108
+ isUnique: index.unique,
109
+ constraintType: 'index',
110
+ filterDefinition: index.filter,
111
+ columns: [
112
+ ...index.columns.map(columnName => ({ columnName })),
113
+ ...(index.included || []).map(columnName => ({ columnName, isIncludedColumn: true })),
114
+ ],
115
+ })),
89
116
  };
90
117
  if (table.primaryKey) {
91
118
  res.primaryKey = {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.5.7-alpha.16",
2
+ "version": "5.5.7-alpha.26",
3
3
  "name": "dbgate-tools",
4
4
  "main": "lib/index.js",
5
5
  "typings": "lib/index.d.ts",
@@ -25,14 +25,14 @@
25
25
  ],
26
26
  "devDependencies": {
27
27
  "@types/node": "^13.7.0",
28
- "dbgate-types": "^5.5.7-alpha.16",
28
+ "dbgate-types": "^5.5.7-alpha.26",
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.7-alpha.16",
35
+ "dbgate-sqltree": "^5.5.7-alpha.26",
36
36
  "debug": "^4.3.4",
37
37
  "json-stable-stringify": "^1.0.1",
38
38
  "lodash": "^4.17.21",