dbgate-api-premium 6.2.0 → 6.2.1
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.
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbgate-api-premium",
|
|
3
3
|
"main": "src/index.js",
|
|
4
|
-
"version": "6.2.
|
|
4
|
+
"version": "6.2.1",
|
|
5
5
|
"homepage": "https://dbgate.org/",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"compare-versions": "^3.6.0",
|
|
30
30
|
"cors": "^2.8.5",
|
|
31
31
|
"cross-env": "^6.0.3",
|
|
32
|
-
"dbgate-datalib": "^6.2.
|
|
32
|
+
"dbgate-datalib": "^6.2.1",
|
|
33
33
|
"dbgate-query-splitter": "^4.11.3",
|
|
34
|
-
"dbgate-sqltree": "^6.2.
|
|
35
|
-
"dbgate-tools": "^6.2.
|
|
34
|
+
"dbgate-sqltree": "^6.2.1",
|
|
35
|
+
"dbgate-tools": "^6.2.1",
|
|
36
36
|
"debug": "^4.3.4",
|
|
37
37
|
"diff": "^5.0.0",
|
|
38
38
|
"diff2html": "^3.4.13",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"devDependencies": {
|
|
84
84
|
"@types/fs-extra": "^9.0.11",
|
|
85
85
|
"@types/lodash": "^4.14.149",
|
|
86
|
-
"dbgate-types": "^6.2.
|
|
86
|
+
"dbgate-types": "^6.2.1",
|
|
87
87
|
"env-cmd": "^10.1.0",
|
|
88
88
|
"jsdoc-to-markdown": "^9.0.5",
|
|
89
89
|
"node-loader": "^1.0.2",
|
|
@@ -56,12 +56,19 @@ module.exports = {
|
|
|
56
56
|
handle_done(sesid, props) {
|
|
57
57
|
socket.emit(`session-done-${sesid}`);
|
|
58
58
|
if (!props.skipFinishedMessage) {
|
|
59
|
-
|
|
59
|
+
if (props.controlCommand) {
|
|
60
|
+
this.dispatchMessage(sesid, `${_.startCase(props.controlCommand)} finished`);
|
|
61
|
+
} else {
|
|
62
|
+
this.dispatchMessage(sesid, 'Query execution finished');
|
|
63
|
+
}
|
|
60
64
|
}
|
|
61
65
|
const session = this.opened.find(x => x.sesid == sesid);
|
|
62
66
|
if (session.loadingReader_jslid) {
|
|
63
67
|
socket.emit(`session-jslid-done-${session.loadingReader_jslid}`);
|
|
64
68
|
}
|
|
69
|
+
if (props.autoCommit) {
|
|
70
|
+
this.executeControlCommand({ sesid, command: 'commitTransaction' });
|
|
71
|
+
}
|
|
65
72
|
if (session.killOnDone) {
|
|
66
73
|
this.kill({ sesid });
|
|
67
74
|
}
|
|
@@ -131,7 +138,7 @@ module.exports = {
|
|
|
131
138
|
},
|
|
132
139
|
|
|
133
140
|
executeQuery_meta: true,
|
|
134
|
-
async executeQuery({ sesid, sql }) {
|
|
141
|
+
async executeQuery({ sesid, sql, autoCommit }) {
|
|
135
142
|
const session = this.opened.find(x => x.sesid == sesid);
|
|
136
143
|
if (!session) {
|
|
137
144
|
throw new Error('Invalid session');
|
|
@@ -139,7 +146,21 @@ module.exports = {
|
|
|
139
146
|
|
|
140
147
|
logger.info({ sesid, sql }, 'Processing query');
|
|
141
148
|
this.dispatchMessage(sesid, 'Query execution started');
|
|
142
|
-
session.subprocess.send({ msgtype: 'executeQuery', sql });
|
|
149
|
+
session.subprocess.send({ msgtype: 'executeQuery', sql, autoCommit });
|
|
150
|
+
|
|
151
|
+
return { state: 'ok' };
|
|
152
|
+
},
|
|
153
|
+
|
|
154
|
+
executeControlCommand_meta: true,
|
|
155
|
+
async executeControlCommand({ sesid, command }) {
|
|
156
|
+
const session = this.opened.find(x => x.sesid == sesid);
|
|
157
|
+
if (!session) {
|
|
158
|
+
throw new Error('Invalid session');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
logger.info({ sesid, command }, 'Processing control command');
|
|
162
|
+
this.dispatchMessage(sesid, `${_.startCase(command)} started`);
|
|
163
|
+
session.subprocess.send({ msgtype: 'executeControlCommand', command });
|
|
143
164
|
|
|
144
165
|
return { state: 'ok' };
|
|
145
166
|
},
|
package/src/currentVersion.js
CHANGED
|
@@ -245,7 +245,47 @@ async function handleStopProfiler({ jslid }) {
|
|
|
245
245
|
currentProfiler = null;
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
-
async function
|
|
248
|
+
async function handleExecuteControlCommand({ command }) {
|
|
249
|
+
lastActivity = new Date().getTime();
|
|
250
|
+
|
|
251
|
+
await waitConnected();
|
|
252
|
+
const driver = requireEngineDriver(storedConnection);
|
|
253
|
+
|
|
254
|
+
if (command == 'commitTransaction' && !allowExecuteCustomScript(driver)) {
|
|
255
|
+
process.send({
|
|
256
|
+
msgtype: 'info',
|
|
257
|
+
info: {
|
|
258
|
+
message: 'Connection without read-only sessions is read only',
|
|
259
|
+
severity: 'error',
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
process.send({ msgtype: 'done', skipFinishedMessage: true });
|
|
263
|
+
return;
|
|
264
|
+
//process.send({ msgtype: 'error', error: e.message });
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
executingScripts++;
|
|
268
|
+
try {
|
|
269
|
+
const dmp = driver.createDumper();
|
|
270
|
+
switch (command) {
|
|
271
|
+
case 'commitTransaction':
|
|
272
|
+
await dmp.commitTransaction();
|
|
273
|
+
break;
|
|
274
|
+
case 'rollbackTransaction':
|
|
275
|
+
await dmp.rollbackTransaction();
|
|
276
|
+
break;
|
|
277
|
+
case 'beginTransaction':
|
|
278
|
+
await dmp.beginTransaction();
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
await driver.query(dbhan, dmp.s, { discardResult: true });
|
|
282
|
+
process.send({ msgtype: 'done', controlCommand: command });
|
|
283
|
+
} finally {
|
|
284
|
+
executingScripts--;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
async function handleExecuteQuery({ sql, autoCommit }) {
|
|
249
289
|
lastActivity = new Date().getTime();
|
|
250
290
|
|
|
251
291
|
await waitConnected();
|
|
@@ -279,7 +319,7 @@ async function handleExecuteQuery({ sql }) {
|
|
|
279
319
|
// handler.stream = stream;
|
|
280
320
|
// resultIndex = handler.resultIndex;
|
|
281
321
|
}
|
|
282
|
-
process.send({ msgtype: 'done' });
|
|
322
|
+
process.send({ msgtype: 'done', autoCommit });
|
|
283
323
|
} finally {
|
|
284
324
|
executingScripts--;
|
|
285
325
|
}
|
|
@@ -323,6 +363,7 @@ function handlePing() {
|
|
|
323
363
|
const messageHandlers = {
|
|
324
364
|
connect: handleConnect,
|
|
325
365
|
executeQuery: handleExecuteQuery,
|
|
366
|
+
executeControlCommand: handleExecuteControlCommand,
|
|
326
367
|
executeReader: handleExecuteReader,
|
|
327
368
|
startProfiler: handleStartProfiler,
|
|
328
369
|
stopProfiler: handleStopProfiler,
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs-extra');
|
|
3
|
+
const executeQuery = require('./executeQuery');
|
|
4
|
+
const { connectUtility } = require('../utility/connectUtility');
|
|
5
|
+
const requireEngineDriver = require('../utility/requireEngineDriver');
|
|
6
|
+
const { getAlterDatabaseScript, DatabaseAnalyser, runCommandOnDriver } = require('dbgate-tools');
|
|
7
|
+
const importDbModel = require('../utility/importDbModel');
|
|
8
|
+
const jsonLinesReader = require('./jsonLinesReader');
|
|
9
|
+
const tableWriter = require('./tableWriter');
|
|
10
|
+
const copyStream = require('./copyStream');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Deploys database model stored in modelFolder (table as yamls) to database
|
|
14
|
+
* @param {object} options
|
|
15
|
+
* @param {connectionType} options.connection - connection object
|
|
16
|
+
* @param {object} options.systemConnection - system connection (result of driver.connect). If not provided, new connection will be created
|
|
17
|
+
* @param {object} options.driver - driver object. If not provided, it will be loaded from connection
|
|
18
|
+
* @param {string} options.folder - folder with model files (YAML files for tables, SQL files for views, procedures, ...)
|
|
19
|
+
* @param {function[]} options.modelTransforms - array of functions for transforming model
|
|
20
|
+
*/
|
|
21
|
+
async function importDbFromFolder({ connection, systemConnection, driver, folder, modelTransforms }) {
|
|
22
|
+
if (!driver) driver = requireEngineDriver(connection);
|
|
23
|
+
const dbhan = systemConnection || (await connectUtility(driver, connection, 'read'));
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
const model = await importDbModel(folder);
|
|
27
|
+
|
|
28
|
+
let modelAdapted = {
|
|
29
|
+
...model,
|
|
30
|
+
tables: model.tables.map(table => driver.adaptTableInfo(table)),
|
|
31
|
+
};
|
|
32
|
+
for (const transform of modelTransforms || []) {
|
|
33
|
+
modelAdapted = transform(modelAdapted);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const modelNoFk = {
|
|
37
|
+
...modelAdapted,
|
|
38
|
+
tables: modelAdapted.tables.map(table => ({
|
|
39
|
+
...table,
|
|
40
|
+
foreignKeys: [],
|
|
41
|
+
})),
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// const plan = createAlterDatabasePlan(
|
|
45
|
+
// DatabaseAnalyser.createEmptyStructure(),
|
|
46
|
+
// driver.dialect.enableAllForeignKeys ? modelAdapted : modelNoFk,
|
|
47
|
+
// {},
|
|
48
|
+
// DatabaseAnalyser.createEmptyStructure(),
|
|
49
|
+
// driver.dialect.enableAllForeignKeys ? modelAdapted : modelNoFk,
|
|
50
|
+
// driver
|
|
51
|
+
// );
|
|
52
|
+
// const dmp1 = driver.createDumper({ useHardSeparator: true });
|
|
53
|
+
// if (driver.dialect.enableAllForeignKeys) {
|
|
54
|
+
// dmp1.enableAllForeignKeys(false);
|
|
55
|
+
// }
|
|
56
|
+
// plan.run(dmp1);
|
|
57
|
+
// if (driver.dialect.enableAllForeignKeys) {
|
|
58
|
+
// dmp1.enableAllForeignKeys(true);
|
|
59
|
+
// }
|
|
60
|
+
|
|
61
|
+
const { sql } = getAlterDatabaseScript(
|
|
62
|
+
DatabaseAnalyser.createEmptyStructure(),
|
|
63
|
+
driver.dialect.enableAllForeignKeys ? modelAdapted : modelNoFk,
|
|
64
|
+
{},
|
|
65
|
+
DatabaseAnalyser.createEmptyStructure(),
|
|
66
|
+
driver.dialect.enableAllForeignKeys ? modelAdapted : modelNoFk,
|
|
67
|
+
driver
|
|
68
|
+
);
|
|
69
|
+
// console.log('CREATING STRUCTURE:', sql);
|
|
70
|
+
await executeQuery({ connection, systemConnection: dbhan, driver, sql, logScriptItems: true });
|
|
71
|
+
|
|
72
|
+
if (driver.dialect.enableAllForeignKeys) {
|
|
73
|
+
await runCommandOnDriver(dbhan, driver, dmp => dmp.enableAllForeignKeys(false));
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
for (const table of modelAdapted.tables) {
|
|
77
|
+
const fileName = path.join(folder, `${table.pureName}.jsonl`);
|
|
78
|
+
if (await fs.exists(fileName)) {
|
|
79
|
+
const src = await jsonLinesReader({ fileName });
|
|
80
|
+
const dst = await tableWriter({
|
|
81
|
+
systemConnection: dbhan,
|
|
82
|
+
pureName: table.pureName,
|
|
83
|
+
driver,
|
|
84
|
+
targetTableStructure: table,
|
|
85
|
+
});
|
|
86
|
+
await copyStream(src, dst);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (driver.dialect.enableAllForeignKeys) {
|
|
91
|
+
await runCommandOnDriver(dbhan, driver, dmp => dmp.enableAllForeignKeys(true));
|
|
92
|
+
} else if (driver.dialect.createForeignKey) {
|
|
93
|
+
const dmp = driver.createDumper();
|
|
94
|
+
for (const table of modelAdapted.tables) {
|
|
95
|
+
for (const fk of table.foreignKeys) {
|
|
96
|
+
dmp.createForeignKey(fk);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// create foreign keys
|
|
101
|
+
await executeQuery({ connection, systemConnection: dbhan, driver, sql: dmp.s, logScriptItems: true });
|
|
102
|
+
}
|
|
103
|
+
} finally {
|
|
104
|
+
if (!systemConnection) {
|
|
105
|
+
await driver.close(dbhan);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
module.exports = importDbFromFolder;
|
package/src/shell/index.js
CHANGED
|
@@ -35,6 +35,7 @@ const sqlTextReplacementTransform = require('./sqlTextReplacementTransform');
|
|
|
35
35
|
const autoIndexForeignKeysTransform = require('./autoIndexForeignKeysTransform');
|
|
36
36
|
const generateDeploySql = require('./generateDeploySql');
|
|
37
37
|
const dropAllDbObjects = require('./dropAllDbObjects');
|
|
38
|
+
const importDbFromFolder = require('./importDbFromFolder');
|
|
38
39
|
|
|
39
40
|
const dbgateApi = {
|
|
40
41
|
queryReader,
|
|
@@ -73,6 +74,7 @@ const dbgateApi = {
|
|
|
73
74
|
autoIndexForeignKeysTransform,
|
|
74
75
|
generateDeploySql,
|
|
75
76
|
dropAllDbObjects,
|
|
77
|
+
importDbFromFolder,
|
|
76
78
|
};
|
|
77
79
|
|
|
78
80
|
requirePlugin.initializeDbgateApi(dbgateApi);
|
package/src/shell/tableWriter.js
CHANGED
|
@@ -15,6 +15,7 @@ const logger = getLogger('tableWriter');
|
|
|
15
15
|
* @param {boolean} options.truncate - truncate table before insert
|
|
16
16
|
* @param {boolean} options.createIfNotExists - create table if not exists
|
|
17
17
|
* @param {boolean} options.commitAfterInsert - commit transaction after insert
|
|
18
|
+
* @param {any} options.targetTableStructure - target table structure (don't analyse if given)
|
|
18
19
|
* @returns {Promise<writerType>} - writer object
|
|
19
20
|
*/
|
|
20
21
|
async function tableWriter({ connection, schemaName, pureName, driver, systemConnection, ...options }) {
|