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.
@@ -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;
@@ -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
- 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;
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
- db: DatabaseInfo;
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(db: DatabaseInfo, dialect: SqlDialect, opts: DbDiffOptions);
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(db, dialect, opts) {
13
- this.db = db;
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.db.tables.find(x => x.pureName == column.pureName && x.schemaName == column.schemaName);
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.db.tables.find(x => x.pureName == op[objectField].pureName && x.schemaName == op[objectField].schemaName);
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;
@@ -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, db: DatabaseInfo, driver: EngineDriver): boolean;
24
- export declare function createAlterTablePlan(oldTable: TableInfo, newTable: TableInfo, opts: DbDiffOptions, db: DatabaseInfo, driver: EngineDriver): AlterPlan;
25
- export declare function createAlterDatabasePlan(oldDb: DatabaseInfo, newDb: DatabaseInfo, opts: DbDiffOptions, db: DatabaseInfo, driver: EngineDriver): AlterPlan;
26
- export declare function getAlterTableScript(oldTable: TableInfo, newTable: TableInfo, opts: DbDiffOptions, db: DatabaseInfo, driver: EngineDriver): {
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, db: DatabaseInfo, driver: EngineDriver): {
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, db, driver) {
272
- const plan = new alterPlan_1.AlterPlan(db, driver.dialect, opts);
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 createAlterTablePlan(oldTable, newTable, opts, db, driver) {
279
- const plan = new alterPlan_1.AlterPlan(db, driver.dialect, opts);
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, db, driver) {
294
- const plan = new alterPlan_1.AlterPlan(db, driver.dialect, opts);
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 (newobj.createSql != oldobj.createSql) {
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, db, driver) {
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, db, driver);
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, db, driver) {
357
- const plan = createAlterDatabasePlan(oldDb, newDb, opts, db, driver);
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
+ };
@@ -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
@@ -15,3 +15,5 @@ export * from './diffTools';
15
15
  export * from './schemaEditorTools';
16
16
  export * from './yamlModelConv';
17
17
  export * from './stringTools';
18
+ export * from './computeDiffRows';
19
+ export * from './preloadedRowsTools';
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,2 @@
1
+ import { DatabaseInfo, EngineDriver } from 'dbgate-types';
2
+ export declare function enrichWithPreloadedRows(dbModel: DatabaseInfo, dbTarget: DatabaseInfo, conn: any, driver: EngineDriver): Promise<DatabaseInfo>;
@@ -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;
@@ -16,6 +16,8 @@ export interface TableInfoYaml {
16
16
  name: string;
17
17
  columns: ColumnInfoYaml[];
18
18
  primaryKey?: string[];
19
+ insertKey?: string[];
20
+ data?: any[];
19
21
  }
20
22
  export interface ForeignKeyInfoYaml {
21
23
  deleteAction?: string;
@@ -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.0-alpha.2",
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.0-alpha.2",
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
  }