dbgate-api-premium 6.4.0 → 6.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.
- package/package.json +6 -6
- package/src/controllers/config.js +6 -2
- package/src/controllers/databaseConnections.js +6 -0
- package/src/controllers/sessions.js +2 -2
- package/src/currentVersion.js +2 -2
- package/src/proc/databaseConnectionProcess.js +8 -2
- package/src/proc/sessionProcess.js +2 -2
- package/src/shell/executeQuery.js +6 -2
- package/src/utility/handleQueryStream.js +53 -12
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.4.
|
|
4
|
+
"version": "6.4.2",
|
|
5
5
|
"homepage": "https://dbgate.org/",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"compare-versions": "^3.6.0",
|
|
31
31
|
"cors": "^2.8.5",
|
|
32
32
|
"cross-env": "^6.0.3",
|
|
33
|
-
"dbgate-datalib": "^6.4.
|
|
34
|
-
"dbgate-query-splitter": "^4.11.
|
|
35
|
-
"dbgate-sqltree": "^6.4.
|
|
36
|
-
"dbgate-tools": "^6.4.
|
|
33
|
+
"dbgate-datalib": "^6.4.2",
|
|
34
|
+
"dbgate-query-splitter": "^4.11.5",
|
|
35
|
+
"dbgate-sqltree": "^6.4.2",
|
|
36
|
+
"dbgate-tools": "^6.4.2",
|
|
37
37
|
"debug": "^4.3.4",
|
|
38
38
|
"diff": "^5.0.0",
|
|
39
39
|
"diff2html": "^3.4.13",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"@types/fs-extra": "^9.0.11",
|
|
87
87
|
"@types/lodash": "^4.14.149",
|
|
88
|
-
"dbgate-types": "^6.4.
|
|
88
|
+
"dbgate-types": "^6.4.2",
|
|
89
89
|
"env-cmd": "^10.1.0",
|
|
90
90
|
"jsdoc-to-markdown": "^9.0.5",
|
|
91
91
|
"node-loader": "^1.0.2",
|
|
@@ -298,8 +298,12 @@ module.exports = {
|
|
|
298
298
|
|
|
299
299
|
changelog_meta: true,
|
|
300
300
|
async changelog() {
|
|
301
|
-
|
|
302
|
-
|
|
301
|
+
try {
|
|
302
|
+
const resp = await axios.default.get('https://raw.githubusercontent.com/dbgate/dbgate/master/CHANGELOG.md');
|
|
303
|
+
return resp.data;
|
|
304
|
+
} catch (err) {
|
|
305
|
+
return ''
|
|
306
|
+
}
|
|
303
307
|
},
|
|
304
308
|
|
|
305
309
|
checkLicense_meta: true,
|
|
@@ -304,6 +304,12 @@ module.exports = {
|
|
|
304
304
|
return this.loadDataCore('loadKeys', { conid, database, root, filter, limit });
|
|
305
305
|
},
|
|
306
306
|
|
|
307
|
+
scanKeys_meta: true,
|
|
308
|
+
async scanKeys({ conid, database, root, pattern, cursor, count }, req) {
|
|
309
|
+
testConnectionPermission(conid, req);
|
|
310
|
+
return this.loadDataCore('scanKeys', { conid, database, root, pattern, cursor, count });
|
|
311
|
+
},
|
|
312
|
+
|
|
307
313
|
exportKeys_meta: true,
|
|
308
314
|
async exportKeys({ conid, database, options }, req) {
|
|
309
315
|
testConnectionPermission(conid, req);
|
|
@@ -141,7 +141,7 @@ module.exports = {
|
|
|
141
141
|
},
|
|
142
142
|
|
|
143
143
|
executeQuery_meta: true,
|
|
144
|
-
async executeQuery({ sesid, sql, autoCommit }) {
|
|
144
|
+
async executeQuery({ sesid, sql, autoCommit, limitRows }) {
|
|
145
145
|
const session = this.opened.find(x => x.sesid == sesid);
|
|
146
146
|
if (!session) {
|
|
147
147
|
throw new Error('Invalid session');
|
|
@@ -149,7 +149,7 @@ module.exports = {
|
|
|
149
149
|
|
|
150
150
|
logger.info({ sesid, sql }, 'Processing query');
|
|
151
151
|
this.dispatchMessage(sesid, 'Query execution started');
|
|
152
|
-
session.subprocess.send({ msgtype: 'executeQuery', sql, autoCommit });
|
|
152
|
+
session.subprocess.send({ msgtype: 'executeQuery', sql, autoCommit, limitRows });
|
|
153
153
|
|
|
154
154
|
return { state: 'ok' };
|
|
155
155
|
},
|
package/src/currentVersion.js
CHANGED
|
@@ -12,6 +12,7 @@ const {
|
|
|
12
12
|
ScriptWriterEval,
|
|
13
13
|
SqlGenerator,
|
|
14
14
|
playJsonScriptWriter,
|
|
15
|
+
serializeJsTypesForJsonStringify,
|
|
15
16
|
} = require('dbgate-tools');
|
|
16
17
|
const requireEngineDriver = require('../utility/requireEngineDriver');
|
|
17
18
|
const { connectUtility } = require('../utility/connectUtility');
|
|
@@ -232,7 +233,7 @@ async function handleQueryData({ msgid, sql, range }, skipReadonlyCheck = false)
|
|
|
232
233
|
try {
|
|
233
234
|
if (!skipReadonlyCheck) ensureExecuteCustomScript(driver);
|
|
234
235
|
const res = await driver.query(dbhan, sql, { range });
|
|
235
|
-
process.send({ msgtype: 'response', msgid, ...res });
|
|
236
|
+
process.send({ msgtype: 'response', msgid, ...serializeJsTypesForJsonStringify(res) });
|
|
236
237
|
} catch (err) {
|
|
237
238
|
process.send({
|
|
238
239
|
msgtype: 'response',
|
|
@@ -254,7 +255,7 @@ async function handleDriverDataCore(msgid, callMethod, { logName }) {
|
|
|
254
255
|
const driver = requireEngineDriver(storedConnection);
|
|
255
256
|
try {
|
|
256
257
|
const result = await callMethod(driver);
|
|
257
|
-
process.send({ msgtype: 'response', msgid, result });
|
|
258
|
+
process.send({ msgtype: 'response', msgid, result: serializeJsTypesForJsonStringify(result) });
|
|
258
259
|
} catch (err) {
|
|
259
260
|
logger.error(extractErrorLogData(err, { logName }), `Error when handling message ${logName}`);
|
|
260
261
|
process.send({ msgtype: 'response', msgid, errorMessage: extractErrorMessage(err, 'Error executing DB data') });
|
|
@@ -274,6 +275,10 @@ async function handleLoadKeys({ msgid, root, filter, limit }) {
|
|
|
274
275
|
return handleDriverDataCore(msgid, driver => driver.loadKeys(dbhan, root, filter, limit), { logName: 'loadKeys' });
|
|
275
276
|
}
|
|
276
277
|
|
|
278
|
+
async function handleScanKeys({ msgid, pattern, cursor, count }) {
|
|
279
|
+
return handleDriverDataCore(msgid, driver => driver.scanKeys(dbhan, pattern, cursor, count), { logName: 'scanKeys' });
|
|
280
|
+
}
|
|
281
|
+
|
|
277
282
|
async function handleExportKeys({ msgid, options }) {
|
|
278
283
|
return handleDriverDataCore(msgid, driver => driver.exportKeys(dbhan, options), { logName: 'exportKeys' });
|
|
279
284
|
}
|
|
@@ -452,6 +457,7 @@ const messageHandlers = {
|
|
|
452
457
|
updateCollection: handleUpdateCollection,
|
|
453
458
|
collectionData: handleCollectionData,
|
|
454
459
|
loadKeys: handleLoadKeys,
|
|
460
|
+
scanKeys: handleScanKeys,
|
|
455
461
|
loadKeyInfo: handleLoadKeyInfo,
|
|
456
462
|
callMethod: handleCallMethod,
|
|
457
463
|
loadKeyTableRange: handleLoadKeyTableRange,
|
|
@@ -117,7 +117,7 @@ async function handleExecuteControlCommand({ command }) {
|
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
async function handleExecuteQuery({ sql, autoCommit }) {
|
|
120
|
+
async function handleExecuteQuery({ sql, autoCommit, limitRows }) {
|
|
121
121
|
lastActivity = new Date().getTime();
|
|
122
122
|
|
|
123
123
|
await waitConnected();
|
|
@@ -146,7 +146,7 @@ async function handleExecuteQuery({ sql, autoCommit }) {
|
|
|
146
146
|
...driver.getQuerySplitterOptions('stream'),
|
|
147
147
|
returnRichInfo: true,
|
|
148
148
|
})) {
|
|
149
|
-
await handleQueryStream(dbhan, driver, queryStreamInfoHolder, sqlItem);
|
|
149
|
+
await handleQueryStream(dbhan, driver, queryStreamInfoHolder, sqlItem, undefined, limitRows);
|
|
150
150
|
// const handler = new StreamHandler(resultIndex);
|
|
151
151
|
// const stream = await driver.stream(systemConnection, sqlItem, handler);
|
|
152
152
|
// handler.stream = stream;
|
|
@@ -14,6 +14,7 @@ const logger = getLogger('execQuery');
|
|
|
14
14
|
* @param {string} [options.sql] - SQL query
|
|
15
15
|
* @param {string} [options.sqlFile] - SQL file
|
|
16
16
|
* @param {boolean} [options.logScriptItems] - whether to log script items instead of whole script
|
|
17
|
+
* @param {boolean} [options.skipLogging] - whether to skip logging
|
|
17
18
|
*/
|
|
18
19
|
async function executeQuery({
|
|
19
20
|
connection = undefined,
|
|
@@ -22,8 +23,9 @@ async function executeQuery({
|
|
|
22
23
|
sql,
|
|
23
24
|
sqlFile = undefined,
|
|
24
25
|
logScriptItems = false,
|
|
26
|
+
skipLogging = false,
|
|
25
27
|
}) {
|
|
26
|
-
if (!logScriptItems) {
|
|
28
|
+
if (!logScriptItems && !skipLogging) {
|
|
27
29
|
logger.info({ sql: getLimitedQuery(sql) }, `Execute query`);
|
|
28
30
|
}
|
|
29
31
|
|
|
@@ -36,7 +38,9 @@ async function executeQuery({
|
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
try {
|
|
39
|
-
|
|
41
|
+
if (!skipLogging) {
|
|
42
|
+
logger.debug(`Running SQL query, length: ${sql.length}`);
|
|
43
|
+
}
|
|
40
44
|
|
|
41
45
|
await driver.script(dbhan, sql, { logScriptItems });
|
|
42
46
|
} finally {
|
|
@@ -4,6 +4,7 @@ const fs = require('fs');
|
|
|
4
4
|
const _ = require('lodash');
|
|
5
5
|
|
|
6
6
|
const { jsldir } = require('../utility/directories');
|
|
7
|
+
const { serializeJsTypesReplacer } = require('dbgate-tools');
|
|
7
8
|
|
|
8
9
|
class QueryStreamTableWriter {
|
|
9
10
|
constructor(sesid = undefined) {
|
|
@@ -38,7 +39,7 @@ class QueryStreamTableWriter {
|
|
|
38
39
|
|
|
39
40
|
row(row) {
|
|
40
41
|
// console.log('ACCEPT ROW', row);
|
|
41
|
-
this.currentStream.write(JSON.stringify(row) + '\n');
|
|
42
|
+
this.currentStream.write(JSON.stringify(row, serializeJsTypesReplacer) + '\n');
|
|
42
43
|
this.currentRowCount += 1;
|
|
43
44
|
|
|
44
45
|
if (!this.plannedStats) {
|
|
@@ -81,20 +82,27 @@ class QueryStreamTableWriter {
|
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
close(afterClose) {
|
|
84
|
-
|
|
85
|
-
this.currentStream
|
|
86
|
-
this.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
return new Promise(resolve => {
|
|
86
|
+
if (this.currentStream) {
|
|
87
|
+
this.currentStream.end(() => {
|
|
88
|
+
this.writeCurrentStats(true, true);
|
|
89
|
+
if (afterClose) afterClose();
|
|
90
|
+
resolve();
|
|
91
|
+
});
|
|
92
|
+
} else {
|
|
93
|
+
resolve();
|
|
94
|
+
}
|
|
95
|
+
});
|
|
90
96
|
}
|
|
91
97
|
}
|
|
92
98
|
|
|
93
99
|
class StreamHandler {
|
|
94
|
-
constructor(queryStreamInfoHolder, resolve, startLine, sesid = undefined) {
|
|
100
|
+
constructor(queryStreamInfoHolder, resolve, startLine, sesid = undefined, limitRows = undefined) {
|
|
95
101
|
this.recordset = this.recordset.bind(this);
|
|
96
102
|
this.startLine = startLine;
|
|
97
103
|
this.sesid = sesid;
|
|
104
|
+
this.limitRows = limitRows;
|
|
105
|
+
this.rowsLimitOverflow = false;
|
|
98
106
|
this.row = this.row.bind(this);
|
|
99
107
|
// this.error = this.error.bind(this);
|
|
100
108
|
this.done = this.done.bind(this);
|
|
@@ -106,6 +114,7 @@ class StreamHandler {
|
|
|
106
114
|
this.plannedStats = false;
|
|
107
115
|
this.queryStreamInfoHolder = queryStreamInfoHolder;
|
|
108
116
|
this.resolve = resolve;
|
|
117
|
+
this.rowCounter = 0;
|
|
109
118
|
// currentHandlers = [...currentHandlers, this];
|
|
110
119
|
}
|
|
111
120
|
|
|
@@ -117,6 +126,9 @@ class StreamHandler {
|
|
|
117
126
|
}
|
|
118
127
|
|
|
119
128
|
recordset(columns) {
|
|
129
|
+
if (this.rowsLimitOverflow) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
120
132
|
this.closeCurrentWriter();
|
|
121
133
|
this.currentWriter = new QueryStreamTableWriter(this.sesid);
|
|
122
134
|
this.currentWriter.initializeFromQuery(
|
|
@@ -124,6 +136,7 @@ class StreamHandler {
|
|
|
124
136
|
this.queryStreamInfoHolder.resultIndex
|
|
125
137
|
);
|
|
126
138
|
this.queryStreamInfoHolder.resultIndex += 1;
|
|
139
|
+
this.rowCounter = 0;
|
|
127
140
|
|
|
128
141
|
// this.writeCurrentStats();
|
|
129
142
|
|
|
@@ -134,8 +147,36 @@ class StreamHandler {
|
|
|
134
147
|
// }, 500);
|
|
135
148
|
}
|
|
136
149
|
row(row) {
|
|
137
|
-
if (this.
|
|
138
|
-
|
|
150
|
+
if (this.rowsLimitOverflow) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (this.limitRows && this.rowCounter >= this.limitRows) {
|
|
155
|
+
process.send({
|
|
156
|
+
msgtype: 'info',
|
|
157
|
+
info: { message: `Rows limit overflow, loaded ${this.rowCounter} rows, canceling query`, severity: 'error' },
|
|
158
|
+
sesid: this.sesid,
|
|
159
|
+
});
|
|
160
|
+
this.rowsLimitOverflow = true;
|
|
161
|
+
|
|
162
|
+
this.queryStreamInfoHolder.canceled = true;
|
|
163
|
+
if (this.currentWriter) {
|
|
164
|
+
this.currentWriter.close().then(() => {
|
|
165
|
+
process.exit(0);
|
|
166
|
+
});
|
|
167
|
+
} else {
|
|
168
|
+
process.exit(0);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (this.currentWriter) {
|
|
175
|
+
this.currentWriter.row(row);
|
|
176
|
+
this.rowCounter += 1;
|
|
177
|
+
} else if (row.message) {
|
|
178
|
+
process.send({ msgtype: 'info', info: { message: row.message }, sesid: this.sesid });
|
|
179
|
+
}
|
|
139
180
|
// this.onRow(this.jslid);
|
|
140
181
|
}
|
|
141
182
|
// error(error) {
|
|
@@ -160,10 +201,10 @@ class StreamHandler {
|
|
|
160
201
|
}
|
|
161
202
|
}
|
|
162
203
|
|
|
163
|
-
function handleQueryStream(dbhan, driver, queryStreamInfoHolder, sqlItem, sesid = undefined) {
|
|
204
|
+
function handleQueryStream(dbhan, driver, queryStreamInfoHolder, sqlItem, sesid = undefined, limitRows = undefined) {
|
|
164
205
|
return new Promise((resolve, reject) => {
|
|
165
206
|
const start = sqlItem.trimStart || sqlItem.start;
|
|
166
|
-
const handler = new StreamHandler(queryStreamInfoHolder, resolve, start && start.line, sesid);
|
|
207
|
+
const handler = new StreamHandler(queryStreamInfoHolder, resolve, start && start.line, sesid, limitRows);
|
|
167
208
|
driver.stream(dbhan, sqlItem.text, handler);
|
|
168
209
|
});
|
|
169
210
|
}
|