dbgate-tools 6.2.0 → 6.3.0

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.
@@ -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;
@@ -39,6 +39,7 @@ export declare class SqlDumper implements AlterProcessor {
39
39
  transform(type: TransformType, dumpExpr: any): void;
40
40
  allowIdentityInsert(table: NamedObjectInfo, allow: boolean): void;
41
41
  enableConstraints(table: NamedObjectInfo, enabled: boolean): void;
42
+ enableAllForeignKeys(enabled: boolean): void;
42
43
  comment(value: string): void;
43
44
  createView(obj: ViewInfo): void;
44
45
  dropView(obj: ViewInfo, { testIfExists }: {
package/lib/SqlDumper.js CHANGED
@@ -224,7 +224,7 @@ class SqlDumper {
224
224
  }
225
225
  }
226
226
  columnDefinition(column, { includeDefault = true, includeNullable = true, includeCollate = true } = {}) {
227
- var _a, _b, _c, _d;
227
+ var _a, _b, _c, _d, _e, _f, _g, _h;
228
228
  if (column.computedExpression) {
229
229
  this.put('^as %s', column.computedExpression);
230
230
  if (column.isPersisted)
@@ -237,11 +237,21 @@ class SqlDumper {
237
237
  }
238
238
  this.putRaw(' ');
239
239
  this.specialColumnOptions(column);
240
- if (includeNullable && !((_b = this.dialect) === null || _b === void 0 ? void 0 : _b.specificNullabilityImplementation)) {
241
- this.put(column.notNull ? '^not ^null' : '^null');
240
+ if ((_b = this.dialect) === null || _b === void 0 ? void 0 : _b.defaultValueBeforeNullability) {
241
+ if (includeDefault && ((_d = (_c = column.defaultValue) === null || _c === void 0 ? void 0 : _c.toString()) === null || _d === void 0 ? void 0 : _d.trim())) {
242
+ this.columnDefault(column);
243
+ }
244
+ if (includeNullable && !((_e = this.dialect) === null || _e === void 0 ? void 0 : _e.specificNullabilityImplementation)) {
245
+ this.put(column.notNull ? '^not ^null' : '^null');
246
+ }
242
247
  }
243
- if (includeDefault && ((_d = (_c = column.defaultValue) === null || _c === void 0 ? void 0 : _c.toString()) === null || _d === void 0 ? void 0 : _d.trim())) {
244
- this.columnDefault(column);
248
+ else {
249
+ if (includeNullable && !((_f = this.dialect) === null || _f === void 0 ? void 0 : _f.specificNullabilityImplementation)) {
250
+ this.put(column.notNull ? '^not ^null' : '^null');
251
+ }
252
+ if (includeDefault && ((_h = (_g = column.defaultValue) === null || _g === void 0 ? void 0 : _g.toString()) === null || _h === void 0 ? void 0 : _h.trim())) {
253
+ this.columnDefault(column);
254
+ }
245
255
  }
246
256
  }
247
257
  columnDefault(column) {
@@ -310,8 +320,9 @@ class SqlDumper {
310
320
  }
311
321
  }
312
322
  createForeignKeyFore(fk) {
313
- if (fk.constraintName != null)
323
+ if (fk.constraintName != null && !this.dialect.anonymousForeignKey) {
314
324
  this.put('^constraint %i ', fk.constraintName);
325
+ }
315
326
  this.put('^foreign ^key (%,i) ^references %f (%,i)', fk.columns.map(x => x.columnName), { schemaName: fk.refSchemaName, pureName: fk.refTableName }, fk.columns.map(x => x.refColumnName));
316
327
  if (fk.deleteAction)
317
328
  this.put(' ^on ^delete %k', fk.deleteAction);
@@ -323,6 +334,7 @@ class SqlDumper {
323
334
  }
324
335
  allowIdentityInsert(table, allow) { }
325
336
  enableConstraints(table, enabled) { }
337
+ enableAllForeignKeys(enabled) { }
326
338
  comment(value) {
327
339
  if (!value)
328
340
  return;
@@ -14,8 +14,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.createBulkInsertStreamBase = void 0;
16
16
  const intersection_1 = __importDefault(require("lodash/intersection"));
17
+ const fromPairs_1 = __importDefault(require("lodash/fromPairs"));
17
18
  const getLogger_1 = require("./getLogger");
18
19
  const tableTransforms_1 = require("./tableTransforms");
20
+ const rowProgressReporter_1 = require("./rowProgressReporter");
21
+ const stringTools_1 = require("./stringTools");
19
22
  const logger = (0, getLogger_1.getLogger)('bulkStreamBase');
20
23
  function createBulkInsertStreamBase(driver, stream, dbhan, name, options) {
21
24
  const fullNameQuoted = name.schemaName
@@ -28,7 +31,9 @@ function createBulkInsertStreamBase(driver, stream, dbhan, name, options) {
28
31
  writable.buffer = [];
29
32
  writable.structure = null;
30
33
  writable.columnNames = null;
34
+ writable.columnDataTypes = null;
31
35
  writable.requireFixedStructure = driver.databaseEngineTypes.includes('sql');
36
+ writable.rowsReporter = new rowProgressReporter_1.RowProgressReporter(options.progressName);
32
37
  writable.addRow = (row) => __awaiter(this, void 0, void 0, function* () {
33
38
  if (writable.structure) {
34
39
  writable.buffer.push(row);
@@ -39,65 +44,92 @@ function createBulkInsertStreamBase(driver, stream, dbhan, name, options) {
39
44
  }
40
45
  });
41
46
  writable.checkStructure = () => __awaiter(this, void 0, void 0, function* () {
42
- let structure = yield driver.analyseSingleTable(dbhan, name);
43
- if (structure) {
44
- writable.structure = structure;
45
- }
46
- if (structure && options.dropIfExists) {
47
- logger.info(`Dropping table ${fullNameQuoted}`);
48
- yield driver.script(dbhan, `DROP TABLE ${fullNameQuoted}`);
49
- }
50
- if (options.createIfNotExists && (!structure || options.dropIfExists)) {
51
- const dmp = driver.createDumper();
52
- const createdTableInfo = driver.adaptTableInfo((0, tableTransforms_1.prepareTableForImport)(Object.assign(Object.assign({}, writable.structure), name)));
53
- dmp.createTable(createdTableInfo);
54
- logger.info({ sql: dmp.s }, `Creating table ${fullNameQuoted}`);
55
- yield driver.script(dbhan, dmp.s);
56
- structure = yield driver.analyseSingleTable(dbhan, name);
47
+ var _a;
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
+ }));
57
80
  }
58
- if (options.truncate) {
59
- 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);
60
84
  }
61
- writable.columnNames = (0, intersection_1.default)(structure.columns.map(x => x.columnName), writable.structure.columns.map(x => x.columnName));
62
85
  });
63
86
  writable.send = () => __awaiter(this, void 0, void 0, function* () {
64
87
  const rows = writable.buffer;
65
88
  writable.buffer = [];
66
- if (driver.dialect.allowMultipleValuesInsert) {
67
- const dmp = driver.createDumper();
68
- dmp.putRaw(`INSERT INTO ${fullNameQuoted} (`);
69
- dmp.putCollection(',', writable.columnNames, col => dmp.putRaw(driver.dialect.quoteIdentifier(col)));
70
- dmp.putRaw(')\n VALUES\n');
71
- let wasRow = false;
72
- for (const row of rows) {
73
- if (wasRow)
74
- dmp.putRaw(',\n');
75
- dmp.putRaw('(');
76
- dmp.putCollection(',', writable.columnNames, col => dmp.putValue(row[col]));
77
- dmp.putRaw(')');
78
- wasRow = true;
79
- }
80
- dmp.putRaw(';');
81
- // require('fs').writeFileSync('/home/jena/test.sql', dmp.s);
82
- // console.log(dmp.s);
83
- yield driver.query(dbhan, dmp.s, { discardResult: true });
84
- }
85
- else {
86
- for (const row of rows) {
89
+ try {
90
+ if (driver.dialect.allowMultipleValuesInsert) {
87
91
  const dmp = driver.createDumper();
88
92
  dmp.putRaw(`INSERT INTO ${fullNameQuoted} (`);
89
93
  dmp.putCollection(',', writable.columnNames, col => dmp.putRaw(driver.dialect.quoteIdentifier(col)));
90
94
  dmp.putRaw(')\n VALUES\n');
91
- dmp.putRaw('(');
92
- dmp.putCollection(',', writable.columnNames, col => dmp.putValue(row[col]));
93
- 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);
106
+ // console.log(dmp.s);
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();
94
127
  yield driver.query(dbhan, dmp.s, { discardResult: true });
95
128
  }
96
129
  }
97
- if (options.commitAfterInsert) {
98
- const dmp = driver.createDumper();
99
- dmp.commitTransaction();
100
- 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);
101
133
  }
102
134
  });
103
135
  writable.sendIfFull = () => __awaiter(this, void 0, void 0, function* () {
@@ -112,6 +144,7 @@ function createBulkInsertStreamBase(driver, stream, dbhan, name, options) {
112
144
  });
113
145
  writable._final = (callback) => __awaiter(this, void 0, void 0, function* () {
114
146
  yield writable.send();
147
+ writable.rowsReporter.finish();
115
148
  callback();
116
149
  });
117
150
  return writable;
@@ -49,6 +49,7 @@ export declare const driverBase: {
49
49
  parseHexAsBuffer: boolean;
50
50
  };
51
51
  createSaveChangeSetScript(changeSet: any, dbinfo: any, defaultCreator: any): any;
52
+ adaptDataType(dataType: string): string;
52
53
  adaptTableInfo(table: any): any;
53
54
  listSchemas(pool: any): Promise<any>;
54
55
  writeQueryFromStream(dbhan: any, sql: any): Promise<any>;
package/lib/driverBase.js CHANGED
@@ -246,8 +246,12 @@ exports.driverBase = {
246
246
  createSaveChangeSetScript(changeSet, dbinfo, defaultCreator) {
247
247
  return defaultCreator(changeSet, dbinfo);
248
248
  },
249
+ adaptDataType(dataType) {
250
+ return dataType;
251
+ },
249
252
  adaptTableInfo(table) {
250
- return table;
253
+ var _a;
254
+ return Object.assign(Object.assign({}, table), { columns: (_a = table.columns) === null || _a === void 0 ? void 0 : _a.map(col => (Object.assign(Object.assign({}, col), { dataType: this.adaptDataType(col.dataType) }))) });
251
255
  },
252
256
  listSchemas(pool) {
253
257
  return __awaiter(this, void 0, void 0, function* () {
@@ -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,4 @@ export * from './detectSqlFilterBehaviour';
25
25
  export * from './filterBehaviours';
26
26
  export * from './schemaInfoTools';
27
27
  export * from './dbKeysLoader';
28
+ export * from './rowProgressReporter';
package/lib/index.js CHANGED
@@ -41,3 +41,4 @@ __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);
@@ -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;
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "6.2.0",
2
+ "version": "6.3.0",
3
3
  "name": "dbgate-tools",
4
4
  "main": "lib/index.js",
5
5
  "typings": "lib/index.d.ts",
@@ -25,14 +25,14 @@
25
25
  ],
26
26
  "devDependencies": {
27
27
  "@types/node": "^13.7.0",
28
- "dbgate-types": "^6.2.0",
28
+ "dbgate-types": "^6.3.0",
29
29
  "jest": "^24.9.0",
30
30
  "ts-jest": "^25.2.1",
31
31
  "typescript": "^4.4.3"
32
32
  },
33
33
  "dependencies": {
34
34
  "dbgate-query-splitter": "^4.11.3",
35
- "dbgate-sqltree": "^6.2.0",
35
+ "dbgate-sqltree": "^6.3.0",
36
36
  "debug": "^4.3.4",
37
37
  "json-stable-stringify": "^1.0.1",
38
38
  "lodash": "^4.17.21",