dbgate-api 6.6.1 → 6.6.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.
@@ -3,7 +3,7 @@ const path = require('path');
3
3
  const crypto = require('crypto');
4
4
  const { filesdir, archivedir, resolveArchiveFolder, uploadsdir, appdir, jsldir } = require('../utility/directories');
5
5
  const getChartExport = require('../utility/getChartExport');
6
- const { hasPermission } = require('../utility/hasPermission');
6
+ const { hasPermission, loadPermissionsFromRequest } = require('../utility/hasPermission');
7
7
  const socket = require('../utility/socket');
8
8
  const scheduler = require('./scheduler');
9
9
  const getDiagramExport = require('../utility/getDiagramExport');
@@ -31,7 +31,8 @@ function deserialize(format, text) {
31
31
  module.exports = {
32
32
  list_meta: true,
33
33
  async list({ folder }, req) {
34
- if (!hasPermission(`files/${folder}/read`, req)) return [];
34
+ const loadedPermissions = await loadPermissionsFromRequest(req);
35
+ if (!hasPermission(`files/${folder}/read`, loadedPermissions)) return [];
35
36
  const dir = path.join(filesdir(), folder);
36
37
  if (!(await fs.exists(dir))) return [];
37
38
  const files = (await fs.readdir(dir)).map(file => ({ folder, file }));
@@ -40,10 +41,11 @@ module.exports = {
40
41
 
41
42
  listAll_meta: true,
42
43
  async listAll(_params, req) {
44
+ const loadedPermissions = await loadPermissionsFromRequest(req);
43
45
  const folders = await fs.readdir(filesdir());
44
46
  const res = [];
45
47
  for (const folder of folders) {
46
- if (!hasPermission(`files/${folder}/read`, req)) continue;
48
+ if (!hasPermission(`files/${folder}/read`, loadedPermissions)) continue;
47
49
  const dir = path.join(filesdir(), folder);
48
50
  const files = (await fs.readdir(dir)).map(file => ({ folder, file }));
49
51
  res.push(...files);
@@ -53,7 +55,8 @@ module.exports = {
53
55
 
54
56
  delete_meta: true,
55
57
  async delete({ folder, file }, req) {
56
- if (!hasPermission(`files/${folder}/write`, req)) return false;
58
+ const loadedPermissions = await loadPermissionsFromRequest(req);
59
+ if (!hasPermission(`files/${folder}/write`, loadedPermissions)) return false;
57
60
  if (!checkSecureFilePathsWithoutDirectory(folder, file)) {
58
61
  return false;
59
62
  }
@@ -65,7 +68,8 @@ module.exports = {
65
68
 
66
69
  rename_meta: true,
67
70
  async rename({ folder, file, newFile }, req) {
68
- if (!hasPermission(`files/${folder}/write`, req)) return false;
71
+ const loadedPermissions = await loadPermissionsFromRequest(req);
72
+ if (!hasPermission(`files/${folder}/write`, loadedPermissions)) return false;
69
73
  if (!checkSecureFilePathsWithoutDirectory(folder, file, newFile)) {
70
74
  return false;
71
75
  }
@@ -86,10 +90,11 @@ module.exports = {
86
90
 
87
91
  copy_meta: true,
88
92
  async copy({ folder, file, newFile }, req) {
93
+ const loadedPermissions = await loadPermissionsFromRequest(req);
89
94
  if (!checkSecureFilePathsWithoutDirectory(folder, file, newFile)) {
90
95
  return false;
91
96
  }
92
- if (!hasPermission(`files/${folder}/write`, req)) return false;
97
+ if (!hasPermission(`files/${folder}/write`, loadedPermissions)) return false;
93
98
  await fs.copyFile(path.join(filesdir(), folder, file), path.join(filesdir(), folder, newFile));
94
99
  socket.emitChanged(`files-changed`, { folder });
95
100
  socket.emitChanged(`all-files-changed`);
@@ -113,7 +118,8 @@ module.exports = {
113
118
  });
114
119
  return deserialize(format, text);
115
120
  } else {
116
- if (!hasPermission(`files/${folder}/read`, req)) return null;
121
+ const loadedPermissions = await loadPermissionsFromRequest(req);
122
+ if (!hasPermission(`files/${folder}/read`, loadedPermissions)) return null;
117
123
  const text = await fs.readFile(path.join(filesdir(), folder, file), { encoding: 'utf-8' });
118
124
  return deserialize(format, text);
119
125
  }
@@ -131,18 +137,19 @@ module.exports = {
131
137
 
132
138
  save_meta: true,
133
139
  async save({ folder, file, data, format }, req) {
140
+ const loadedPermissions = await loadPermissionsFromRequest(req);
134
141
  if (!checkSecureFilePathsWithoutDirectory(folder, file)) {
135
142
  return false;
136
143
  }
137
144
 
138
145
  if (folder.startsWith('archive:')) {
139
- if (!hasPermission(`archive/write`, req)) return false;
146
+ if (!hasPermission(`archive/write`, loadedPermissions)) return false;
140
147
  const dir = resolveArchiveFolder(folder.substring('archive:'.length));
141
148
  await fs.writeFile(path.join(dir, file), serialize(format, data));
142
149
  socket.emitChanged(`archive-files-changed`, { folder: folder.substring('archive:'.length) });
143
150
  return true;
144
151
  } else if (folder.startsWith('app:')) {
145
- if (!hasPermission(`apps/write`, req)) return false;
152
+ if (!hasPermission(`apps/write`, loadedPermissions)) return false;
146
153
  const app = folder.substring('app:'.length);
147
154
  await fs.writeFile(path.join(appdir(), app, file), serialize(format, data));
148
155
  socket.emitChanged(`app-files-changed`, { app });
@@ -150,7 +157,7 @@ module.exports = {
150
157
  apps.emitChangedDbApp(folder);
151
158
  return true;
152
159
  } else {
153
- if (!hasPermission(`files/${folder}/write`, req)) return false;
160
+ if (!hasPermission(`files/${folder}/write`, loadedPermissions)) return false;
154
161
  const dir = path.join(filesdir(), folder);
155
162
  if (!(await fs.exists(dir))) {
156
163
  await fs.mkdir(dir);
@@ -177,7 +184,8 @@ module.exports = {
177
184
 
178
185
  favorites_meta: true,
179
186
  async favorites(_params, req) {
180
- if (!hasPermission(`files/favorites/read`, req)) return [];
187
+ const loadedPermissions = await loadPermissionsFromRequest(req);
188
+ if (!hasPermission(`files/favorites/read`, loadedPermissions)) return [];
181
189
  const dir = path.join(filesdir(), 'favorites');
182
190
  if (!(await fs.exists(dir))) return [];
183
191
  const files = await fs.readdir(dir);
@@ -234,16 +242,17 @@ module.exports = {
234
242
 
235
243
  getFileRealPath_meta: true,
236
244
  async getFileRealPath({ folder, file }, req) {
245
+ const loadedPermissions = await loadPermissionsFromRequest(req);
237
246
  if (folder.startsWith('archive:')) {
238
- if (!hasPermission(`archive/write`, req)) return false;
247
+ if (!hasPermission(`archive/write`, loadedPermissions)) return false;
239
248
  const dir = resolveArchiveFolder(folder.substring('archive:'.length));
240
249
  return path.join(dir, file);
241
250
  } else if (folder.startsWith('app:')) {
242
- if (!hasPermission(`apps/write`, req)) return false;
251
+ if (!hasPermission(`apps/write`, loadedPermissions)) return false;
243
252
  const app = folder.substring('app:'.length);
244
253
  return path.join(appdir(), app, file);
245
254
  } else {
246
- if (!hasPermission(`files/${folder}/write`, req)) return false;
255
+ if (!hasPermission(`files/${folder}/write`, loadedPermissions)) return false;
247
256
  const dir = path.join(filesdir(), folder);
248
257
  if (!(await fs.exists(dir))) {
249
258
  await fs.mkdir(dir);
@@ -297,7 +306,8 @@ module.exports = {
297
306
 
298
307
  exportFile_meta: true,
299
308
  async exportFile({ folder, file, filePath }, req) {
300
- if (!hasPermission(`files/${folder}/read`, req)) return false;
309
+ const loadedPermissions = await loadPermissionsFromRequest(req);
310
+ if (!hasPermission(`files/${folder}/read`, loadedPermissions)) return false;
301
311
  await fs.copyFile(path.join(filesdir(), folder, file), filePath);
302
312
  return true;
303
313
  },
@@ -7,7 +7,7 @@ const socket = require('../utility/socket');
7
7
  const compareVersions = require('compare-versions');
8
8
  const requirePlugin = require('../shell/requirePlugin');
9
9
  const downloadPackage = require('../utility/downloadPackage');
10
- const { hasPermission } = require('../utility/hasPermission');
10
+ const { hasPermission, loadPermissionsFromRequest } = require('../utility/hasPermission');
11
11
  const _ = require('lodash');
12
12
  const packagedPluginsContent = require('../packagedPluginsContent');
13
13
 
@@ -118,7 +118,8 @@ module.exports = {
118
118
 
119
119
  install_meta: true,
120
120
  async install({ packageName }, req) {
121
- if (!hasPermission(`plugins/install`, req)) return;
121
+ const loadedPermissions = await loadPermissionsFromRequest(req);
122
+ if (!hasPermission(`plugins/install`, loadedPermissions)) return;
122
123
  const dir = path.join(pluginsdir(), packageName);
123
124
  // @ts-ignore
124
125
  if (!(await fs.exists(dir))) {
@@ -132,7 +133,8 @@ module.exports = {
132
133
 
133
134
  uninstall_meta: true,
134
135
  async uninstall({ packageName }, req) {
135
- if (!hasPermission(`plugins/install`, req)) return;
136
+ const loadedPermissions = await loadPermissionsFromRequest(req);
137
+ if (!hasPermission(`plugins/install`, loadedPermissions)) return;
136
138
  const dir = path.join(pluginsdir(), packageName);
137
139
  await fs.rmdir(dir, { recursive: true });
138
140
  socket.emitChanged(`installed-plugins-changed`);
@@ -143,7 +145,8 @@ module.exports = {
143
145
 
144
146
  upgrade_meta: true,
145
147
  async upgrade({ packageName }, req) {
146
- if (!hasPermission(`plugins/install`, req)) return;
148
+ const loadedPermissions = await loadPermissionsFromRequest(req);
149
+ if (!hasPermission(`plugins/install`, loadedPermissions)) return;
147
150
  const dir = path.join(pluginsdir(), packageName);
148
151
  // @ts-ignore
149
152
  if (await fs.exists(dir)) {
@@ -21,6 +21,7 @@ const processArgs = require('../utility/processArgs');
21
21
  const platformInfo = require('../utility/platformInfo');
22
22
  const { checkSecureDirectories, checkSecureDirectoriesInScript } = require('../utility/security');
23
23
  const { sendToAuditLog, logJsonRunnerScript } = require('../utility/auditlog');
24
+ const { testStandardPermission } = require('../utility/hasPermission');
24
25
  const logger = getLogger('runners');
25
26
 
26
27
  function extractPlugins(script) {
@@ -273,6 +274,8 @@ module.exports = {
273
274
 
274
275
  start_meta: true,
275
276
  async start({ script }, req) {
277
+ await testStandardPermission('run-shell-script', req);
278
+
276
279
  const runid = crypto.randomUUID();
277
280
 
278
281
  if (script.type == 'json') {
@@ -3,7 +3,7 @@ const fs = require('fs-extra');
3
3
  const path = require('path');
4
4
  const cron = require('node-cron');
5
5
  const runners = require('./runners');
6
- const { hasPermission } = require('../utility/hasPermission');
6
+ const { hasPermission, loadPermissionsFromRequest } = require('../utility/hasPermission');
7
7
  const { getLogger } = require('dbgate-tools');
8
8
 
9
9
  const logger = getLogger('scheduler');
@@ -30,7 +30,8 @@ module.exports = {
30
30
  },
31
31
 
32
32
  async reload(_params, req) {
33
- if (!hasPermission('files/shell/read', req)) return;
33
+ const loadedPermissions = await loadPermissionsFromRequest(req);
34
+ if (!hasPermission('files/shell/read', loadedPermissions)) return;
34
35
  const shellDir = path.join(filesdir(), 'shell');
35
36
  await this.unload();
36
37
  if (!(await fs.exists(shellDir))) return;
@@ -8,7 +8,13 @@ const { handleProcessCommunication } = require('../utility/processComm');
8
8
  const lock = new AsyncLock();
9
9
  const config = require('./config');
10
10
  const processArgs = require('../utility/processArgs');
11
- const { testConnectionPermission } = require('../utility/hasPermission');
11
+ const {
12
+ testConnectionPermission,
13
+ loadPermissionsFromRequest,
14
+ hasPermission,
15
+ loadDatabasePermissionsFromRequest,
16
+ getDatabasePermissionRole,
17
+ } = require('../utility/hasPermission');
12
18
  const { MissingCredentialsError } = require('../utility/exceptions');
13
19
  const pipeForkLogs = require('../utility/pipeForkLogs');
14
20
  const { getLogger, extractErrorLogData } = require('dbgate-tools');
@@ -40,7 +46,7 @@ module.exports = {
40
46
  existing.status = status;
41
47
  socket.emitChanged(`server-status-changed`);
42
48
  },
43
- handle_ping() {},
49
+ handle_ping() { },
44
50
  handle_response(conid, { msgid, ...response }) {
45
51
  const [resolve, reject] = this.requests[msgid];
46
52
  resolve(response);
@@ -135,7 +141,7 @@ module.exports = {
135
141
 
136
142
  disconnect_meta: true,
137
143
  async disconnect({ conid }, req) {
138
- testConnectionPermission(conid, req);
144
+ await testConnectionPermission(conid, req);
139
145
  await this.close(conid, true);
140
146
  return { status: 'ok' };
141
147
  },
@@ -144,7 +150,9 @@ module.exports = {
144
150
  async listDatabases({ conid }, req) {
145
151
  if (!conid) return [];
146
152
  if (conid == '__model') return [];
147
- testConnectionPermission(conid, req);
153
+ const loadedPermissions = await loadPermissionsFromRequest(req);
154
+
155
+ await testConnectionPermission(conid, req, loadedPermissions);
148
156
  const opened = await this.ensureOpened(conid);
149
157
  sendToAuditLog(req, {
150
158
  category: 'serverop',
@@ -157,12 +165,29 @@ module.exports = {
157
165
  sessionGroup: 'listDatabases',
158
166
  message: `Loaded databases for connection`,
159
167
  });
168
+
169
+ if (!hasPermission(`all-databases`, loadedPermissions)) {
170
+ // filter databases by permissions
171
+ const databasePermissions = await loadDatabasePermissionsFromRequest(req);
172
+ const res = [];
173
+ for (const db of opened?.databases ?? []) {
174
+ const databasePermissionRole = getDatabasePermissionRole(db.id, db.name, databasePermissions);
175
+ if (databasePermissionRole != 'deny') {
176
+ res.push({
177
+ ...db,
178
+ databasePermissionRole,
179
+ });
180
+ }
181
+ }
182
+ return res;
183
+ }
184
+
160
185
  return opened?.databases ?? [];
161
186
  },
162
187
 
163
188
  version_meta: true,
164
189
  async version({ conid }, req) {
165
- testConnectionPermission(conid, req);
190
+ await testConnectionPermission(conid, req);
166
191
  const opened = await this.ensureOpened(conid);
167
192
  return opened?.version ?? null;
168
193
  },
@@ -202,7 +227,7 @@ module.exports = {
202
227
 
203
228
  refresh_meta: true,
204
229
  async refresh({ conid, keepOpen }, req) {
205
- testConnectionPermission(conid, req);
230
+ await testConnectionPermission(conid, req);
206
231
  if (!keepOpen) this.close(conid);
207
232
 
208
233
  await this.ensureOpened(conid);
@@ -210,7 +235,7 @@ module.exports = {
210
235
  },
211
236
 
212
237
  async sendDatabaseOp({ conid, msgtype, name }, req) {
213
- testConnectionPermission(conid, req);
238
+ await testConnectionPermission(conid, req);
214
239
  const opened = await this.ensureOpened(conid);
215
240
  if (!opened) {
216
241
  return null;
@@ -252,7 +277,7 @@ module.exports = {
252
277
  },
253
278
 
254
279
  async loadDataCore(msgtype, { conid, ...args }, req) {
255
- testConnectionPermission(conid, req);
280
+ await testConnectionPermission(conid, req);
256
281
  const opened = await this.ensureOpened(conid);
257
282
  if (!opened) {
258
283
  return null;
@@ -270,13 +295,43 @@ module.exports = {
270
295
 
271
296
  serverSummary_meta: true,
272
297
  async serverSummary({ conid }, req) {
273
- testConnectionPermission(conid, req);
298
+ await testConnectionPermission(conid, req);
299
+ logger.info({ conid }, 'DBGM-00260 Processing server summary');
274
300
  return this.loadDataCore('serverSummary', { conid });
275
301
  },
276
302
 
303
+ listDatabaseProcesses_meta: true,
304
+ async listDatabaseProcesses(ctx, req) {
305
+ const { conid } = ctx;
306
+ // logger.info({ conid }, 'DBGM-00261 Listing processes of database server');
307
+ testConnectionPermission(conid, req);
308
+
309
+ const opened = await this.ensureOpened(conid);
310
+ if (!opened) {
311
+ return null;
312
+ }
313
+ if (opened.connection.isReadOnly) return false;
314
+
315
+ return this.sendRequest(opened, { msgtype: 'listDatabaseProcesses' });
316
+ },
317
+
318
+ killDatabaseProcess_meta: true,
319
+ async killDatabaseProcess(ctx, req) {
320
+ const { conid, pid } = ctx;
321
+ testConnectionPermission(conid, req);
322
+
323
+ const opened = await this.ensureOpened(conid);
324
+ if (!opened) {
325
+ return null;
326
+ }
327
+ if (opened.connection.isReadOnly) return false;
328
+
329
+ return this.sendRequest(opened, { msgtype: 'killDatabaseProcess', pid });
330
+ },
331
+
277
332
  summaryCommand_meta: true,
278
333
  async summaryCommand({ conid, command, row }, req) {
279
- testConnectionPermission(conid, req);
334
+ await testConnectionPermission(conid, req);
280
335
  const opened = await this.ensureOpened(conid);
281
336
  if (!opened) {
282
337
  return null;
@@ -12,6 +12,7 @@ const { getLogger, extractErrorLogData } = require('dbgate-tools');
12
12
  const pipeForkLogs = require('../utility/pipeForkLogs');
13
13
  const config = require('./config');
14
14
  const { sendToAuditLog } = require('../utility/auditlog');
15
+ const { testStandardPermission, testDatabaseRolePermission } = require('../utility/hasPermission');
15
16
 
16
17
  const logger = getLogger('sessions');
17
18
 
@@ -94,7 +95,7 @@ module.exports = {
94
95
  socket.emit(`session-initialize-file-${jslid}`);
95
96
  },
96
97
 
97
- handle_ping() {},
98
+ handle_ping() { },
98
99
 
99
100
  create_meta: true,
100
101
  async create({ conid, database }) {
@@ -148,10 +149,12 @@ module.exports = {
148
149
 
149
150
  executeQuery_meta: true,
150
151
  async executeQuery({ sesid, sql, autoCommit, autoDetectCharts, limitRows, frontMatter }, req) {
152
+ await testStandardPermission('dbops/query', req);
151
153
  const session = this.opened.find(x => x.sesid == sesid);
152
154
  if (!session) {
153
155
  throw new Error('Invalid session');
154
156
  }
157
+ await testDatabaseRolePermission(session.conid, session.database, 'run_script', req);
155
158
 
156
159
  sendToAuditLog(req, {
157
160
  category: 'dbop',
@@ -13,10 +13,6 @@ module.exports = {
13
13
  return null;
14
14
  },
15
15
 
16
- async loadSuperadminPermissions() {
17
- return [];
18
- },
19
-
20
16
  getConnectionsForLoginPage_meta: true,
21
17
  async getConnectionsForLoginPage() {
22
18
  return null;
@@ -1,5 +1,5 @@
1
1
 
2
2
  module.exports = {
3
- version: '6.6.1',
4
- buildTime: '2025-08-14T15:32:31.645Z'
3
+ version: '6.6.2',
4
+ buildTime: '2025-08-29T07:26:23.163Z'
5
5
  };
package/src/index.js CHANGED
@@ -5,6 +5,7 @@ const moment = require('moment');
5
5
  const path = require('path');
6
6
  const { logsdir, setLogsFilePath, getLogsFilePath } = require('./utility/directories');
7
7
  const currentVersion = require('./currentVersion');
8
+ const _ = require('lodash');
8
9
 
9
10
  const logger = getLogger('apiIndex');
10
11
 
@@ -68,7 +69,7 @@ function configureLogger() {
68
69
  }
69
70
  const additionals = {};
70
71
  const finalMsg =
71
- msg.msg && msg.msg.match(/^DBGM-\d\d\d\d\d/)
72
+ _.isString(msg.msg) && msg.msg.match(/^DBGM-\d\d\d\d\d/)
72
73
  ? {
73
74
  ...msg,
74
75
  msg: msg.msg.substring(10).trimStart(),
@@ -17,13 +17,14 @@ const requireEngineDriver = require('../utility/requireEngineDriver');
17
17
  const { connectUtility } = require('../utility/connectUtility');
18
18
  const { handleProcessCommunication } = require('../utility/processComm');
19
19
  const generateDeploySql = require('../shell/generateDeploySql');
20
- const { dumpSqlSelect } = require('dbgate-sqltree');
20
+ const { dumpSqlSelect, scriptToSql } = require('dbgate-sqltree');
21
21
  const { allowExecuteCustomScript, handleQueryStream } = require('../utility/handleQueryStream');
22
22
  const dbgateApi = require('../shell');
23
23
  const requirePlugin = require('../shell/requirePlugin');
24
24
  const path = require('path');
25
25
  const { rundir } = require('../utility/directories');
26
26
  const fs = require('fs-extra');
27
+ const { changeSetToSql } = require('dbgate-datalib');
27
28
 
28
29
  const logger = getLogger('dbconnProcess');
29
30
 
@@ -348,6 +349,27 @@ async function handleUpdateCollection({ msgid, changeSet }) {
348
349
  }
349
350
  }
350
351
 
352
+ async function handleSaveTableData({ msgid, changeSet }) {
353
+ await waitStructure();
354
+ try {
355
+ const driver = requireEngineDriver(storedConnection);
356
+ const script = driver.createSaveChangeSetScript(changeSet, analysedStructure, () =>
357
+ changeSetToSql(changeSet, analysedStructure, driver.dialect)
358
+ );
359
+ const sql = scriptToSql(driver, script);
360
+ await driver.script(dbhan, sql, { useTransaction: true });
361
+ process.send({ msgtype: 'response', msgid });
362
+ } catch (err) {
363
+ process.send({
364
+ msgtype: 'response',
365
+ msgid,
366
+ errorMessage: extractErrorMessage(err, 'Error executing SQL script'),
367
+ });
368
+ }
369
+
370
+
371
+ }
372
+
351
373
  async function handleSqlPreview({ msgid, objects, options }) {
352
374
  await waitStructure();
353
375
  const driver = requireEngineDriver(storedConnection);
@@ -464,6 +486,7 @@ const messageHandlers = {
464
486
  runScript: handleRunScript,
465
487
  runOperation: handleRunOperation,
466
488
  updateCollection: handleUpdateCollection,
489
+ saveTableData: handleSaveTableData,
467
490
  collectionData: handleCollectionData,
468
491
  loadKeys: handleLoadKeys,
469
492
  scanKeys: handleScanKeys,
@@ -146,6 +146,30 @@ async function handleServerSummary({ msgid }) {
146
146
  return handleDriverDataCore(msgid, driver => driver.serverSummary(dbhan));
147
147
  }
148
148
 
149
+ async function handleKillDatabaseProcess({ msgid, pid }) {
150
+ await waitConnected();
151
+ const driver = requireEngineDriver(storedConnection);
152
+
153
+ try {
154
+ const result = await driver.killProcess(dbhan, Number(pid));
155
+ process.send({ msgtype: 'response', msgid, result });
156
+ } catch (err) {
157
+ process.send({ msgtype: 'response', msgid, errorMessage: err.message });
158
+ }
159
+ }
160
+
161
+ async function handleListDatabaseProcesses({ msgid }) {
162
+ await waitConnected();
163
+ const driver = requireEngineDriver(storedConnection);
164
+
165
+ try {
166
+ const result = await driver.listProcesses(dbhan);
167
+ process.send({ msgtype: 'response', msgid, result });
168
+ } catch (err) {
169
+ process.send({ msgtype: 'response', msgid, errorMessage: err.message });
170
+ }
171
+ }
172
+
149
173
  async function handleSummaryCommand({ msgid, command, row }) {
150
174
  return handleDriverDataCore(msgid, driver => driver.summaryCommand(dbhan, command, row));
151
175
  }
@@ -154,6 +178,8 @@ const messageHandlers = {
154
178
  connect: handleConnect,
155
179
  ping: handlePing,
156
180
  serverSummary: handleServerSummary,
181
+ killDatabaseProcess: handleKillDatabaseProcess,
182
+ listDatabaseProcesses: handleListDatabaseProcesses,
157
183
  summaryCommand: handleSummaryCommand,
158
184
  createDatabase: props => handleDatabaseOp('createDatabase', props),
159
185
  dropDatabase: props => handleDatabaseOp('dropDatabase', props),