dbgate-tools 6.2.1 → 6.3.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.
@@ -27,7 +27,10 @@ export declare class DatabaseAnalyser {
27
27
  getDeletedObjects(snapshot: any): any[];
28
28
  feedback(obj: any): void;
29
29
  getModifications(): Promise<any[]>;
30
- analyserQuery(template: any, typeFields: any, replacements?: {}): Promise<import("dbgate-types").QueryResult>;
30
+ analyserQuery(template: any, typeFields: any, replacements?: {}): Promise<import("dbgate-types").QueryResult | {
31
+ rows: any[];
32
+ isError: boolean;
33
+ }>;
31
34
  static createEmptyStructure(): DatabaseInfo;
32
35
  static byTableFilter(table: any): (x: any) => boolean;
33
36
  static extractPrimaryKeys(table: any, pkColumns: any): {
@@ -333,6 +333,7 @@ class DatabaseAnalyser {
333
333
  logger.error((0, stringTools_1.extractErrorLogData)(err, { template }), 'Error running analyser query');
334
334
  return {
335
335
  rows: [],
336
+ isError: true,
336
337
  };
337
338
  }
338
339
  });
@@ -10,8 +10,7 @@ export declare class ScriptWriter {
10
10
  assign(variableName: any, functionName: any, props: any): void;
11
11
  assignValue(variableName: any, jsonValue: any): void;
12
12
  requirePackage(packageName: any): void;
13
- copyStream(sourceVar: any, targetVar: any, colmapVar?: any): void;
14
- dumpDatabase(options: any): void;
13
+ copyStream(sourceVar: any, targetVar: any, colmapVar?: any, progressName?: string): void;
15
14
  importDatabase(options: any): void;
16
15
  dataDuplicator(options: any): void;
17
16
  comment(s: any): void;
@@ -27,9 +26,8 @@ export declare class ScriptWriterJson {
27
26
  endLine(): void;
28
27
  assign(variableName: any, functionName: any, props: any): void;
29
28
  assignValue(variableName: any, jsonValue: any): void;
30
- copyStream(sourceVar: any, targetVar: any, colmapVar?: any): void;
29
+ copyStream(sourceVar: any, targetVar: any, colmapVar?: any, progressName?: string): void;
31
30
  comment(text: any): void;
32
- dumpDatabase(options: any): void;
33
31
  importDatabase(options: any): void;
34
32
  dataDuplicator(options: any): void;
35
33
  getScript(schedule?: any): {
@@ -37,16 +37,14 @@ class ScriptWriter {
37
37
  requirePackage(packageName) {
38
38
  this.packageNames.push(packageName);
39
39
  }
40
- copyStream(sourceVar, targetVar, colmapVar = null) {
41
- if (colmapVar) {
42
- this._put(`await dbgateApi.copyStream(${sourceVar}, ${targetVar}, {columns: ${colmapVar}});`);
43
- }
44
- else {
45
- this._put(`await dbgateApi.copyStream(${sourceVar}, ${targetVar});`);
46
- }
47
- }
48
- dumpDatabase(options) {
49
- this._put(`await dbgateApi.dumpDatabase(${JSON.stringify(options)});`);
40
+ copyStream(sourceVar, targetVar, colmapVar = null, progressName) {
41
+ let opts = '{';
42
+ if (colmapVar)
43
+ opts += `columns: ${colmapVar}, `;
44
+ if (progressName)
45
+ opts += `progressName: "${progressName}", `;
46
+ opts += '}';
47
+ this._put(`await dbgateApi.copyStream(${sourceVar}, ${targetVar}, ${opts});`);
50
48
  }
51
49
  importDatabase(options) {
52
50
  this._put(`await dbgateApi.importDatabase(${JSON.stringify(options)});`);
@@ -103,12 +101,13 @@ class ScriptWriterJson {
103
101
  jsonValue,
104
102
  });
105
103
  }
106
- copyStream(sourceVar, targetVar, colmapVar = null) {
104
+ copyStream(sourceVar, targetVar, colmapVar = null, progressName) {
107
105
  this.commands.push({
108
106
  type: 'copyStream',
109
107
  sourceVar,
110
108
  targetVar,
111
109
  colmapVar,
110
+ progressName,
112
111
  });
113
112
  }
114
113
  comment(text) {
@@ -117,12 +116,6 @@ class ScriptWriterJson {
117
116
  text,
118
117
  });
119
118
  }
120
- dumpDatabase(options) {
121
- this.commands.push({
122
- type: 'dumpDatabase',
123
- options,
124
- });
125
- }
126
119
  importDatabase(options) {
127
120
  this.commands.push({
128
121
  type: 'importDatabase',
@@ -163,7 +156,7 @@ function jsonScriptToJavascript(json) {
163
156
  script.assignValue(cmd.variableName, cmd.jsonValue);
164
157
  break;
165
158
  case 'copyStream':
166
- script.copyStream(cmd.sourceVar, cmd.targetVar, cmd.colmapVar);
159
+ script.copyStream(cmd.sourceVar, cmd.targetVar, cmd.colmapVar, cmd.progressName);
167
160
  break;
168
161
  case 'endLine':
169
162
  script.endLine();
@@ -171,9 +164,6 @@ function jsonScriptToJavascript(json) {
171
164
  case 'comment':
172
165
  script.comment(cmd.text);
173
166
  break;
174
- case 'dumpDatabase':
175
- script.dumpDatabase(cmd.options);
176
- break;
177
167
  case 'importDatabase':
178
168
  script.importDatabase(cmd.options);
179
169
  break;
@@ -17,6 +17,8 @@ const intersection_1 = __importDefault(require("lodash/intersection"));
17
17
  const fromPairs_1 = __importDefault(require("lodash/fromPairs"));
18
18
  const getLogger_1 = require("./getLogger");
19
19
  const tableTransforms_1 = require("./tableTransforms");
20
+ const rowProgressReporter_1 = require("./rowProgressReporter");
21
+ const stringTools_1 = require("./stringTools");
20
22
  const logger = (0, getLogger_1.getLogger)('bulkStreamBase');
21
23
  function createBulkInsertStreamBase(driver, stream, dbhan, name, options) {
22
24
  const fullNameQuoted = name.schemaName
@@ -31,6 +33,7 @@ function createBulkInsertStreamBase(driver, stream, dbhan, name, options) {
31
33
  writable.columnNames = null;
32
34
  writable.columnDataTypes = null;
33
35
  writable.requireFixedStructure = driver.databaseEngineTypes.includes('sql');
36
+ writable.rowsReporter = new rowProgressReporter_1.RowProgressReporter(options.progressName);
34
37
  writable.addRow = (row) => __awaiter(this, void 0, void 0, function* () {
35
38
  if (writable.structure) {
36
39
  writable.buffer.push(row);
@@ -42,77 +45,91 @@ function createBulkInsertStreamBase(driver, stream, dbhan, name, options) {
42
45
  });
43
46
  writable.checkStructure = () => __awaiter(this, void 0, void 0, function* () {
44
47
  var _a;
45
- let structure = (_a = options.targetTableStructure) !== null && _a !== void 0 ? _a : (yield driver.analyseSingleTable(dbhan, name));
46
- if (structure) {
47
- writable.structure = structure;
48
- }
49
- if (structure && options.dropIfExists) {
50
- logger.info(`Dropping table ${fullNameQuoted}`);
51
- yield driver.script(dbhan, `DROP TABLE ${fullNameQuoted}`);
52
- }
53
- if (options.createIfNotExists && (!structure || options.dropIfExists)) {
54
- const dmp = driver.createDumper();
55
- const createdTableInfo = driver.adaptTableInfo((0, tableTransforms_1.prepareTableForImport)(Object.assign(Object.assign({}, writable.structure), name)));
56
- dmp.createTable(createdTableInfo);
57
- logger.info({ sql: dmp.s }, `Creating table ${fullNameQuoted}`);
58
- yield driver.script(dbhan, dmp.s);
59
- structure = yield driver.analyseSingleTable(dbhan, name);
60
- writable.structure = structure;
61
- }
62
- if (!writable.structure) {
63
- throw new Error(`Error importing table - ${fullNameQuoted} not found`);
48
+ try {
49
+ let structure = (_a = options.targetTableStructure) !== null && _a !== void 0 ? _a : (yield driver.analyseSingleTable(dbhan, name));
50
+ if (structure) {
51
+ writable.structure = structure;
52
+ }
53
+ if (structure && options.dropIfExists) {
54
+ logger.info(`Dropping table ${fullNameQuoted}`);
55
+ yield driver.script(dbhan, `DROP TABLE ${fullNameQuoted}`);
56
+ }
57
+ if (options.createIfNotExists && (!structure || options.dropIfExists)) {
58
+ const dmp = driver.createDumper();
59
+ const createdTableInfo = driver.adaptTableInfo((0, tableTransforms_1.prepareTableForImport)(Object.assign(Object.assign({}, writable.structure), name)));
60
+ dmp.createTable(createdTableInfo);
61
+ logger.info({ sql: dmp.s }, `Creating table ${fullNameQuoted}`);
62
+ yield driver.script(dbhan, dmp.s);
63
+ structure = yield driver.analyseSingleTable(dbhan, name);
64
+ writable.structure = structure;
65
+ }
66
+ if (!writable.structure) {
67
+ throw new Error(`Error importing table - ${fullNameQuoted} not found`);
68
+ }
69
+ if (options.truncate) {
70
+ yield driver.script(dbhan, `TRUNCATE TABLE ${fullNameQuoted}`);
71
+ }
72
+ writable.columnNames = (0, intersection_1.default)(structure.columns.map(x => x.columnName), writable.structure.columns.map(x => x.columnName));
73
+ writable.columnDataTypes = (0, fromPairs_1.default)(writable.columnNames.map(colName => {
74
+ var _a;
75
+ return [
76
+ colName,
77
+ (_a = writable.structure.columns.find(x => x.columnName == colName)) === null || _a === void 0 ? void 0 : _a.dataType,
78
+ ];
79
+ }));
64
80
  }
65
- if (options.truncate) {
66
- yield driver.script(dbhan, `TRUNCATE TABLE ${fullNameQuoted}`);
81
+ catch (err) {
82
+ logger.error((0, stringTools_1.extractErrorLogData)(err), 'Error during preparing bulk insert table, stopped');
83
+ writable.destroy(err);
67
84
  }
68
- writable.columnNames = (0, intersection_1.default)(structure.columns.map(x => x.columnName), writable.structure.columns.map(x => x.columnName));
69
- writable.columnDataTypes = (0, fromPairs_1.default)(writable.columnNames.map(colName => {
70
- var _a;
71
- return [
72
- colName,
73
- (_a = writable.structure.columns.find(x => x.columnName == colName)) === null || _a === void 0 ? void 0 : _a.dataType,
74
- ];
75
- }));
76
85
  });
77
86
  writable.send = () => __awaiter(this, void 0, void 0, function* () {
78
87
  const rows = writable.buffer;
79
88
  writable.buffer = [];
80
- if (driver.dialect.allowMultipleValuesInsert) {
81
- const dmp = driver.createDumper();
82
- dmp.putRaw(`INSERT INTO ${fullNameQuoted} (`);
83
- dmp.putCollection(',', writable.columnNames, col => dmp.putRaw(driver.dialect.quoteIdentifier(col)));
84
- dmp.putRaw(')\n VALUES\n');
85
- let wasRow = false;
86
- for (const row of rows) {
87
- if (wasRow)
88
- dmp.putRaw(',\n');
89
- dmp.putRaw('(');
90
- dmp.putCollection(',', writable.columnNames, col => { var _a; return dmp.putValue(row[col], (_a = writable.columnDataTypes) === null || _a === void 0 ? void 0 : _a[col]); });
91
- dmp.putRaw(')');
92
- wasRow = true;
93
- }
94
- dmp.putRaw(';');
95
- // require('fs').writeFileSync('/home/jena/test.sql', dmp.s);
96
- // console.log(dmp.s);
97
- yield driver.query(dbhan, dmp.s, { discardResult: true });
98
- }
99
- else {
100
- for (const row of rows) {
89
+ try {
90
+ if (driver.dialect.allowMultipleValuesInsert) {
101
91
  const dmp = driver.createDumper();
102
92
  dmp.putRaw(`INSERT INTO ${fullNameQuoted} (`);
103
93
  dmp.putCollection(',', writable.columnNames, col => dmp.putRaw(driver.dialect.quoteIdentifier(col)));
104
94
  dmp.putRaw(')\n VALUES\n');
105
- dmp.putRaw('(');
106
- dmp.putCollection(',', writable.columnNames, col => { var _a; return dmp.putValue(row[col], (_a = writable.columnDataTypes) === null || _a === void 0 ? void 0 : _a[col]); });
107
- dmp.putRaw(')');
95
+ let wasRow = false;
96
+ for (const row of rows) {
97
+ if (wasRow)
98
+ dmp.putRaw(',\n');
99
+ dmp.putRaw('(');
100
+ dmp.putCollection(',', writable.columnNames, col => { var _a; return dmp.putValue(row[col], (_a = writable.columnDataTypes) === null || _a === void 0 ? void 0 : _a[col]); });
101
+ dmp.putRaw(')');
102
+ wasRow = true;
103
+ }
104
+ dmp.putRaw(';');
105
+ // require('fs').writeFileSync('/home/jena/test.sql', dmp.s);
108
106
  // console.log(dmp.s);
109
107
  yield driver.query(dbhan, dmp.s, { discardResult: true });
108
+ writable.rowsReporter.add(rows.length);
109
+ }
110
+ else {
111
+ for (const row of rows) {
112
+ const dmp = driver.createDumper();
113
+ dmp.putRaw(`INSERT INTO ${fullNameQuoted} (`);
114
+ dmp.putCollection(',', writable.columnNames, col => dmp.putRaw(driver.dialect.quoteIdentifier(col)));
115
+ dmp.putRaw(')\n VALUES\n');
116
+ dmp.putRaw('(');
117
+ dmp.putCollection(',', writable.columnNames, col => { var _a; return dmp.putValue(row[col], (_a = writable.columnDataTypes) === null || _a === void 0 ? void 0 : _a[col]); });
118
+ dmp.putRaw(')');
119
+ // console.log(dmp.s);
120
+ yield driver.query(dbhan, dmp.s, { discardResult: true });
121
+ writable.rowsReporter.add(1);
122
+ }
123
+ }
124
+ if (options.commitAfterInsert) {
125
+ const dmp = driver.createDumper();
126
+ dmp.commitTransaction();
127
+ yield driver.query(dbhan, dmp.s, { discardResult: true });
110
128
  }
111
129
  }
112
- if (options.commitAfterInsert) {
113
- const dmp = driver.createDumper();
114
- dmp.commitTransaction();
115
- yield driver.query(dbhan, dmp.s, { discardResult: true });
130
+ catch (err) {
131
+ logger.error((0, stringTools_1.extractErrorLogData)(err), 'Error during base bulk insert, insert stopped');
132
+ writable.destroy(err);
116
133
  }
117
134
  });
118
135
  writable.sendIfFull = () => __awaiter(this, void 0, void 0, function* () {
@@ -127,6 +144,7 @@ function createBulkInsertStreamBase(driver, stream, dbhan, name, options) {
127
144
  });
128
145
  writable._final = (callback) => __awaiter(this, void 0, void 0, function* () {
129
146
  yield writable.send();
147
+ writable.rowsReporter.finish();
130
148
  callback();
131
149
  });
132
150
  return writable;
@@ -0,0 +1,4 @@
1
+ import { TableInfo } from 'dbgate-types';
2
+ export declare function chooseTopTables(tables: TableInfo[], count: number, tableFilter: string, omitTablesFilter: string): TableInfo[];
3
+ export declare const DIAGRAM_ZOOMS: number[];
4
+ export declare const DIAGRAM_DEFAULT_WATERMARK = "Powered by [dbgate.io](https://dbgate.io)";
@@ -0,0 +1,62 @@
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.DIAGRAM_DEFAULT_WATERMARK = exports.DIAGRAM_ZOOMS = exports.chooseTopTables = void 0;
7
+ const structureTools_1 = require("./structureTools");
8
+ const sortBy_1 = __importDefault(require("lodash/sortBy"));
9
+ const uniq_1 = __importDefault(require("lodash/uniq"));
10
+ const filterName_1 = require("./filterName");
11
+ function tableWeight(table, maxRowcount) {
12
+ var _a, _b;
13
+ let weight = 0;
14
+ const tableDependenciesCount = (0, uniq_1.default)(((_a = table.dependencies) === null || _a === void 0 ? void 0 : _a.map(x => x.pureName)) || []).length;
15
+ const tableFkCount = (0, uniq_1.default)(((_b = table.foreignKeys) === null || _b === void 0 ? void 0 : _b.map(x => x.refTableName)) || []).length;
16
+ if (table.primaryKey)
17
+ weight += 1;
18
+ if (tableFkCount)
19
+ weight += tableFkCount * 1;
20
+ if (maxRowcount && table.tableRowCount) {
21
+ const rowcount = parseInt(table.tableRowCount);
22
+ if (rowcount > 0)
23
+ weight += Math.log(rowcount) * table.columns.length * (tableFkCount || 1) * (tableDependenciesCount || 1);
24
+ }
25
+ else {
26
+ if (table.columns)
27
+ weight += table.columns.length * 2;
28
+ }
29
+ if (table.dependencies)
30
+ weight += tableDependenciesCount * 10;
31
+ if (maxRowcount)
32
+ return weight;
33
+ }
34
+ function chooseTopTables(tables, count, tableFilter, omitTablesFilter) {
35
+ const filteredTables = tables.filter(table => {
36
+ if (tableFilter) {
37
+ if (!(0, filterName_1.filterName)(tableFilter, table === null || table === void 0 ? void 0 : table.pureName))
38
+ return false;
39
+ }
40
+ if (omitTablesFilter) {
41
+ if ((0, filterName_1.filterName)(omitTablesFilter, table === null || table === void 0 ? void 0 : table.pureName))
42
+ return false;
43
+ }
44
+ return true;
45
+ });
46
+ if (!(count > 0)) {
47
+ return filteredTables;
48
+ }
49
+ const dbinfo = {
50
+ tables: filteredTables,
51
+ };
52
+ const extended = (0, structureTools_1.extendDatabaseInfo)(dbinfo);
53
+ const maxRowcount = Math.max(...extended.tables
54
+ .map(x => x.tableRowCount || 0)
55
+ .map(x => parseInt(x))
56
+ .filter(x => x > 0));
57
+ const sorted = (0, sortBy_1.default)((0, sortBy_1.default)(extended.tables, x => `${x.schemaName}.${x.pureName}`), table => -tableWeight(table, maxRowcount));
58
+ return sorted.slice(0, count);
59
+ }
60
+ exports.chooseTopTables = chooseTopTables;
61
+ exports.DIAGRAM_ZOOMS = [0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.8, 1, 1.25, 1.5, 1.75, 2];
62
+ exports.DIAGRAM_DEFAULT_WATERMARK = 'Powered by [dbgate.io](https://dbgate.io)';
package/lib/filterName.js CHANGED
@@ -6,9 +6,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.tokenizeBySearchFilter = exports.filterNameCompoud = exports.filterName = void 0;
7
7
  const compact_1 = __importDefault(require("lodash/compact"));
8
8
  const startCase_1 = __importDefault(require("lodash/startCase"));
9
- // export interface FilterNameDefinition {
10
- // childName: string;
11
- // }
9
+ function parseTokenTree(filter) {
10
+ const factors = filter
11
+ .split(',')
12
+ .map(x => x.trim())
13
+ .filter(x => x.length > 0);
14
+ return {
15
+ factors: factors.map(x => ({
16
+ tokens: x
17
+ .split(' ')
18
+ .map(x => x.trim())
19
+ .filter(x => x.length > 0),
20
+ })),
21
+ };
22
+ }
12
23
  function camelMatch(filter, text) {
13
24
  if (!text)
14
25
  return false;
@@ -28,23 +39,25 @@ function filterName(filter, ...names) {
28
39
  if (!filter)
29
40
  return true;
30
41
  // const camelVariants = [name.replace(/[^A-Z]/g, '')]
31
- const tokens = filter.split(' ').map(x => x.trim());
42
+ const tree = parseTokenTree(filter);
43
+ if (tree.factors.length == 0)
44
+ return true;
32
45
  const namesCompacted = (0, compact_1.default)(names);
33
- for (const token of tokens) {
34
- const found = namesCompacted.find(name => camelMatch(token, name));
35
- if (!found)
36
- return false;
46
+ for (const factor of tree.factors) {
47
+ let factorOk = true;
48
+ for (const token of factor.tokens) {
49
+ const found = namesCompacted.find(name => camelMatch(token, name));
50
+ if (!found)
51
+ factorOk = false;
52
+ }
53
+ if (factorOk) {
54
+ return true;
55
+ }
37
56
  }
38
- return true;
57
+ return false;
39
58
  }
40
59
  exports.filterName = filterName;
41
- function filterNameCompoud(filter, namesMain, namesChild) {
42
- if (!filter)
43
- return 'both';
44
- // const camelVariants = [name.replace(/[^A-Z]/g, '')]
45
- const tokens = filter.split(' ').map(x => x.trim());
46
- const namesCompactedMain = (0, compact_1.default)(namesMain);
47
- const namesCompactedChild = (0, compact_1.default)(namesChild);
60
+ function clasifyCompoudCategory(tokens, namesCompactedMain, namesCompactedChild) {
48
61
  let isMainOnly = true;
49
62
  let isChildOnly = true;
50
63
  for (const token of tokens) {
@@ -65,12 +78,39 @@ function filterNameCompoud(filter, namesMain, namesChild) {
65
78
  return 'child';
66
79
  return 'none';
67
80
  }
81
+ function filterNameCompoud(filter, namesMain, namesChild) {
82
+ if (!filter)
83
+ return 'both';
84
+ // const camelVariants = [name.replace(/[^A-Z]/g, '')]
85
+ const tree = parseTokenTree(filter);
86
+ const namesCompactedMain = (0, compact_1.default)(namesMain);
87
+ const namesCompactedChild = (0, compact_1.default)(namesChild);
88
+ if (tree.factors.length == 0)
89
+ return 'both';
90
+ const factorRes = [];
91
+ for (const factor of tree.factors) {
92
+ const category = clasifyCompoudCategory(factor.tokens, namesCompactedMain, namesCompactedChild);
93
+ factorRes.push(category);
94
+ }
95
+ if (factorRes.includes('both'))
96
+ return 'both';
97
+ if (factorRes.includes('main') && factorRes.includes('child'))
98
+ return 'both';
99
+ if (factorRes.includes('main'))
100
+ return 'main';
101
+ if (factorRes.includes('child'))
102
+ return 'child';
103
+ return 'none';
104
+ }
68
105
  exports.filterNameCompoud = filterNameCompoud;
69
106
  function tokenizeBySearchFilter(text, filter) {
70
107
  var _a, _b;
71
108
  const camelTokens = [];
72
109
  const stdTokens = [];
73
- for (const token of filter.split(' ').map(x => x.trim())) {
110
+ for (const token of filter
111
+ .split(/[ ,]/)
112
+ .map(x => x.trim())
113
+ .filter(x => x.length > 0)) {
74
114
  if (token.replace(/[A-Z]/g, '').length == 0) {
75
115
  camelTokens.push(token);
76
116
  }
@@ -0,0 +1 @@
1
+ declare const tokenizeBySearchFilter: any;
@@ -0,0 +1,18 @@
1
+ const { tokenizeBySearchFilter } = require('./filterName');
2
+ test('tokenize single token', () => {
3
+ const tokenized = tokenizeBySearchFilter('Album', 'al');
4
+ // console.log(JSON.stringify(tokenized, null, 2));
5
+ expect(tokenized).toEqual([
6
+ { text: 'Al', isMatch: true },
7
+ { text: 'bum', isMatch: false },
8
+ ]);
9
+ });
10
+ test('tokenize two tokens', () => {
11
+ const tokenized = tokenizeBySearchFilter('Album', 'al,um');
12
+ // console.log(JSON.stringify(tokenized, null, 2));
13
+ expect(tokenized).toEqual([
14
+ { text: 'Al', isMatch: true },
15
+ { text: 'b', isMatch: false },
16
+ { text: 'um', isMatch: true },
17
+ ]);
18
+ });
@@ -3,3 +3,4 @@ export declare function getConnectionLabel(connection: any, { allowExplicitDatab
3
3
  allowExplicitDatabase?: boolean;
4
4
  showUnsaved?: boolean;
5
5
  }): any;
6
+ export declare function getEngineLabel(connection: any): any;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getConnectionLabel = exports.getDatabaseFileLabel = void 0;
3
+ exports.getEngineLabel = exports.getConnectionLabel = exports.getDatabaseFileLabel = void 0;
4
4
  function getDatabaseFileLabel(databaseFile) {
5
5
  if (!databaseFile)
6
6
  return databaseFile;
@@ -45,3 +45,11 @@ function getConnectionLabel(connection, { allowExplicitDatabase = true, showUnsa
45
45
  return res;
46
46
  }
47
47
  exports.getConnectionLabel = getConnectionLabel;
48
+ function getEngineLabel(connection) {
49
+ const match = ((connection === null || connection === void 0 ? void 0 : connection.engine) || '').match(/^([^@]*)@/);
50
+ if (match) {
51
+ return match[1];
52
+ }
53
+ return connection === null || connection === void 0 ? void 0 : connection.engine;
54
+ }
55
+ exports.getEngineLabel = getEngineLabel;
package/lib/index.d.ts CHANGED
@@ -25,3 +25,5 @@ export * from './detectSqlFilterBehaviour';
25
25
  export * from './filterBehaviours';
26
26
  export * from './schemaInfoTools';
27
27
  export * from './dbKeysLoader';
28
+ export * from './rowProgressReporter';
29
+ export * from './diagramTools';
package/lib/index.js CHANGED
@@ -41,3 +41,5 @@ __exportStar(require("./detectSqlFilterBehaviour"), exports);
41
41
  __exportStar(require("./filterBehaviours"), exports);
42
42
  __exportStar(require("./schemaInfoTools"), exports);
43
43
  __exportStar(require("./dbKeysLoader"), exports);
44
+ __exportStar(require("./rowProgressReporter"), exports);
45
+ __exportStar(require("./diagramTools"), exports);
@@ -0,0 +1,10 @@
1
+ export declare class RowProgressReporter {
2
+ progressName: any;
3
+ field: string;
4
+ counter: number;
5
+ timeoutHandle: any;
6
+ constructor(progressName: any, field?: string);
7
+ add(count: number): void;
8
+ finish(): void;
9
+ send(): void;
10
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RowProgressReporter = void 0;
4
+ class RowProgressReporter {
5
+ constructor(progressName, field = 'writtenRowCount') {
6
+ this.progressName = progressName;
7
+ this.field = field;
8
+ this.counter = 0;
9
+ this.timeoutHandle = null;
10
+ }
11
+ add(count) {
12
+ this.counter += count;
13
+ if (!this.progressName) {
14
+ return;
15
+ }
16
+ if (this.timeoutHandle) {
17
+ return;
18
+ }
19
+ this.timeoutHandle = setTimeout(() => {
20
+ this.timeoutHandle = null;
21
+ this.send();
22
+ }, 1000);
23
+ }
24
+ finish() {
25
+ if (!this.progressName) {
26
+ return;
27
+ }
28
+ if (this.timeoutHandle) {
29
+ clearTimeout(this.timeoutHandle);
30
+ this.timeoutHandle = null;
31
+ }
32
+ this.send();
33
+ }
34
+ send() {
35
+ if (!this.progressName) {
36
+ return;
37
+ }
38
+ process.send({
39
+ msgtype: 'progress',
40
+ progressName: this.progressName,
41
+ [this.field]: this.counter,
42
+ });
43
+ }
44
+ }
45
+ exports.RowProgressReporter = RowProgressReporter;
@@ -7,12 +7,13 @@ exports.skipDbGateInternalObjects = exports.removePreloadedRowsFromStructure = e
7
7
  const flatten_1 = __importDefault(require("lodash/flatten"));
8
8
  const uniq_1 = __importDefault(require("lodash/uniq"));
9
9
  const keys_1 = __importDefault(require("lodash/keys"));
10
+ const compact_1 = __importDefault(require("lodash/compact"));
10
11
  function addTableDependencies(db) {
11
12
  if (!db.tables) {
12
13
  return db;
13
14
  }
14
- const allForeignKeys = (0, flatten_1.default)(db.tables.map(x => x.foreignKeys || []));
15
- return Object.assign(Object.assign({}, db), { tables: db.tables.map(table => (Object.assign(Object.assign({}, table), { dependencies: allForeignKeys.filter(x => x.refSchemaName == table.schemaName && x.refTableName == table.pureName) }))) });
15
+ const allForeignKeys = (0, flatten_1.default)(db.tables.map(x => (x === null || x === void 0 ? void 0 : x.foreignKeys) || []));
16
+ return Object.assign(Object.assign({}, db), { tables: (0, compact_1.default)(db.tables).map(table => (Object.assign(Object.assign({}, table), { dependencies: allForeignKeys.filter(x => x.refSchemaName == table.schemaName && x.refTableName == table.pureName) }))) });
16
17
  }
17
18
  exports.addTableDependencies = addTableDependencies;
18
19
  function extendTableInfo(table) {
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "6.2.1",
2
+ "version": "6.3.2",
3
3
  "name": "dbgate-tools",
4
4
  "main": "lib/index.js",
5
5
  "typings": "lib/index.d.ts",
@@ -17,22 +17,23 @@
17
17
  "scripts": {
18
18
  "build": "tsc",
19
19
  "start": "tsc --watch",
20
+ "prepublishOnly": "yarn build",
20
21
  "test": "jest",
21
- "prepublishOnly": "yarn build"
22
+ "test:ci": "jest --json --outputFile=result.json --testLocationInResults"
22
23
  },
23
24
  "files": [
24
25
  "lib"
25
26
  ],
26
27
  "devDependencies": {
27
28
  "@types/node": "^13.7.0",
28
- "dbgate-types": "^6.2.1",
29
- "jest": "^24.9.0",
30
- "ts-jest": "^25.2.1",
29
+ "dbgate-types": "^6.3.2",
30
+ "jest": "^28.1.3",
31
+ "ts-jest": "^28.0.7",
31
32
  "typescript": "^4.4.3"
32
33
  },
33
34
  "dependencies": {
34
35
  "dbgate-query-splitter": "^4.11.3",
35
- "dbgate-sqltree": "^6.2.1",
36
+ "dbgate-sqltree": "^6.3.2",
36
37
  "debug": "^4.3.4",
37
38
  "json-stable-stringify": "^1.0.1",
38
39
  "lodash": "^4.17.21",