dbgate-tools 4.4.0-alpha.1 → 4.4.2

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,9 +20,14 @@ 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 createAlterTablePlan(oldTable: TableInfo, newTable: TableInfo, opts: DbDiffOptions, db: DatabaseInfo, driver: EngineDriver): AlterPlan;
24
- export declare function createAlterDatabasePlan(oldDb: DatabaseInfo, newDb: DatabaseInfo, opts: DbDiffOptions, db: DatabaseInfo, driver: EngineDriver): AlterPlan;
25
- 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): {
28
+ sql: string;
29
+ recreates: any[];
30
+ } | {
26
31
  sql: string;
27
32
  recreates: {
28
33
  tables: number;
@@ -30,7 +35,7 @@ export declare function getAlterTableScript(oldTable: TableInfo, newTable: Table
30
35
  sqlObjects: number;
31
36
  };
32
37
  };
33
- 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): {
34
39
  sql: string;
35
40
  recreates: {
36
41
  tables: number;
@@ -40,4 +45,5 @@ export declare function getAlterDatabaseScript(oldDb: DatabaseInfo, newDb: Datab
40
45
  isEmpty: boolean;
41
46
  };
42
47
  export declare function matchPairedObjects(db1: DatabaseInfo, db2: DatabaseInfo, opts: DbDiffOptions): DatabaseInfo;
48
+ export declare const modelCompareDbDiffOptions: DbDiffOptions;
43
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.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,11 +280,27 @@ 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 createAlterTablePlan(oldTable, newTable, 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);
287
+ planAlterTable(plan, a, b, opts);
288
+ // console.log('plan.operations', a, b, plan.operations);
289
+ return plan.operations.length == 0;
290
+ }
291
+ exports.testEqualTables = testEqualTables;
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);
273
298
  if (oldTable == null) {
274
299
  plan.createTable(newTable);
300
+ planTablePreload(plan, null, newTable);
301
+ }
302
+ else if (newTable == null) {
303
+ plan.dropTable(oldTable);
275
304
  }
276
305
  else {
277
306
  planAlterTable(plan, oldTable, newTable, opts);
@@ -280,8 +309,8 @@ function createAlterTablePlan(oldTable, newTable, opts, db, driver) {
280
309
  return plan;
281
310
  }
282
311
  exports.createAlterTablePlan = createAlterTablePlan;
283
- function createAlterDatabasePlan(oldDb, newDb, opts, db, driver) {
284
- 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);
285
314
  for (const objectTypeField of ['tables', 'views', 'procedures', 'matviews', 'functions']) {
286
315
  for (const oldobj of oldDb[objectTypeField] || []) {
287
316
  const newobj = (newDb[objectTypeField] || []).find(x => x.pairingId == oldobj.pairingId);
@@ -301,7 +330,7 @@ function createAlterDatabasePlan(oldDb, newDb, opts, db, driver) {
301
330
  plan.dropSqlObject(oldobj);
302
331
  }
303
332
  }
304
- else if (newobj.createSql != oldobj.createSql) {
333
+ else if (!testEqualSqlObjects(oldobj.createSql, newobj.createSql, opts)) {
305
334
  plan.recreates.sqlObjects += 1;
306
335
  if (!opts.noDropSqlObject) {
307
336
  plan.dropSqlObject(oldobj);
@@ -313,8 +342,10 @@ function createAlterDatabasePlan(oldDb, newDb, opts, db, driver) {
313
342
  for (const newobj of newDb[objectTypeField] || []) {
314
343
  const oldobj = (oldDb[objectTypeField] || []).find(x => x.pairingId == newobj.pairingId);
315
344
  if (objectTypeField == 'tables') {
316
- if (oldobj == null)
345
+ if (oldobj == null) {
317
346
  plan.createTable(newobj);
347
+ planTablePreload(plan, null, newobj);
348
+ }
318
349
  }
319
350
  else {
320
351
  if (oldobj == null)
@@ -326,9 +357,12 @@ function createAlterDatabasePlan(oldDb, newDb, opts, db, driver) {
326
357
  return plan;
327
358
  }
328
359
  exports.createAlterDatabasePlan = createAlterDatabasePlan;
329
- function getAlterTableScript(oldTable, newTable, opts, db, driver) {
330
- const plan = createAlterTablePlan(oldTable, newTable, opts, db, driver);
331
- const dmp = driver.createDumper();
360
+ function getAlterTableScript(oldTable, newTable, opts, wholeOldDb, wholeNewDb, driver) {
361
+ if ((!oldTable && !newTable) || !driver) {
362
+ return { sql: '', recreates: [] };
363
+ }
364
+ const plan = createAlterTablePlan(oldTable, newTable, opts, wholeOldDb, wholeNewDb, driver);
365
+ const dmp = driver.createDumper({ useHardSeparator: true });
332
366
  if (!driver.dialect.disableExplicitTransaction)
333
367
  dmp.beginTransaction();
334
368
  plan.run(dmp);
@@ -340,9 +374,9 @@ function getAlterTableScript(oldTable, newTable, opts, db, driver) {
340
374
  };
341
375
  }
342
376
  exports.getAlterTableScript = getAlterTableScript;
343
- function getAlterDatabaseScript(oldDb, newDb, opts, db, driver) {
344
- const plan = createAlterDatabasePlan(oldDb, newDb, opts, db, driver);
345
- 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 });
346
380
  if (!driver.dialect.disableExplicitTransaction)
347
381
  dmp.beginTransaction();
348
382
  plan.run(dmp);
@@ -356,6 +390,8 @@ function getAlterDatabaseScript(oldDb, newDb, opts, db, driver) {
356
390
  }
357
391
  exports.getAlterDatabaseScript = getAlterDatabaseScript;
358
392
  function matchPairedObjects(db1, db2, opts) {
393
+ if (!db1 || !db2)
394
+ return null;
359
395
  const res = (0, cloneDeep_1.default)(db2);
360
396
  for (const objectTypeField of ['tables', 'views', 'procedures', 'matviews', 'functions']) {
361
397
  for (const obj2 of res[objectTypeField] || []) {
@@ -374,6 +410,16 @@ function matchPairedObjects(db1, db2, opts) {
374
410
  if (fk1)
375
411
  fk2.pairingId = fk1.pairingId;
376
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
+ }
377
423
  }
378
424
  }
379
425
  }
@@ -381,3 +427,10 @@ function matchPairedObjects(db1, db2, opts) {
381
427
  return res;
382
428
  }
383
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
@@ -14,3 +14,6 @@ export * from './filterName';
14
14
  export * from './diffTools';
15
15
  export * from './schemaEditorTools';
16
16
  export * from './yamlModelConv';
17
+ export * from './stringTools';
18
+ export * from './computeDiffRows';
19
+ export * from './preloadedRowsTools';
package/lib/index.js CHANGED
@@ -26,3 +26,6 @@ __exportStar(require("./filterName"), exports);
26
26
  __exportStar(require("./diffTools"), exports);
27
27
  __exportStar(require("./schemaEditorTools"), exports);
28
28
  __exportStar(require("./yamlModelConv"), exports);
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;
@@ -0,0 +1,2 @@
1
+ export declare function arrayToHexString(byteArray: any): any;
2
+ export declare function hexStringToArray(inputString: any): any[];
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hexStringToArray = exports.arrayToHexString = void 0;
4
+ function arrayToHexString(byteArray) {
5
+ return byteArray.reduce((output, elem) => output + ('0' + elem.toString(16)).slice(-2), '');
6
+ }
7
+ exports.arrayToHexString = arrayToHexString;
8
+ function hexStringToArray(inputString) {
9
+ var hex = inputString.toString();
10
+ var res = [];
11
+ for (var n = 0; n < hex.length; n += 2) {
12
+ res.push(parseInt(hex.substr(n, 2), 16));
13
+ }
14
+ return res;
15
+ }
16
+ exports.hexStringToArray = hexStringToArray;
@@ -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.1",
2
+ "version": "4.4.2",
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.1",
28
+ "dbgate-types": "^4.4.2",
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.2",
35
36
  "uuid": "^3.4.0"
36
37
  }
37
38
  }