diff --git a/packages/api/src/controllers/connections.js b/packages/api/src/controllers/connections.js index cf9147eeb..a949e69ac 100644 --- a/packages/api/src/controllers/connections.js +++ b/packages/api/src/controllers/connections.js @@ -199,6 +199,9 @@ module.exports = { } socket.emitChanged('connection-list-changed'); socket.emitChanged('used-apps-changed'); + if (this._closeAll) { + this._closeAll(connection._id); + } // for (const db of connection.databases || []) { // socket.emitChanged(`db-apps-changed-${connection._id}-${db.name}`); // } diff --git a/packages/api/src/controllers/databaseConnections.js b/packages/api/src/controllers/databaseConnections.js index 85c4ddf80..1503e735e 100644 --- a/packages/api/src/controllers/databaseConnections.js +++ b/packages/api/src/controllers/databaseConnections.js @@ -33,6 +33,10 @@ module.exports = { closed: {}, requests: {}, + async _init() { + connections._closeAll = conid => this.closeAll(conid); + }, + handle_structure(conid, database, { structure }) { const existing = this.opened.find(x => x.conid == conid && x.database == database); if (!existing) return; @@ -158,7 +162,7 @@ module.exports = { return res.result; }, - async loadDataCore(msgtype, {conid, database, ...args}) { + async loadDataCore(msgtype, { conid, database, ...args }) { const opened = await this.ensureOpened(conid, database); const res = await this.sendRequest(opened, { msgtype, ...args }); if (res.errorMessage) { @@ -274,6 +278,12 @@ module.exports = { } }, + closeAll(conid, kill = true) { + for (const existing of this.opened.filter(x => x.conid == conid)) { + this.close(conid, existing.database, kill); + } + }, + disconnect_meta: true, async disconnect({ conid, database }) { await this.close(conid, database, true); diff --git a/packages/web/src/modals/ConnectionModalDriverFields.svelte b/packages/web/src/modals/ConnectionModalDriverFields.svelte index 41b6b719e..0d1dc6ac3 100644 --- a/packages/web/src/modals/ConnectionModalDriverFields.svelte +++ b/packages/web/src/modals/ConnectionModalDriverFields.svelte @@ -147,6 +147,10 @@ /> {/if} +{#if driver.showConnectionField('isReadOnly', $values)} + +{/if} + {#if !driver?.showConnectionField || driver.showConnectionField('defaultDatabase', $values)} {/if} diff --git a/plugins/dbgate-plugin-mysql/src/backend/drivers.js b/plugins/dbgate-plugin-mysql/src/backend/drivers.js index e400fc8d6..b84cd775a 100644 --- a/plugins/dbgate-plugin-mysql/src/backend/drivers.js +++ b/plugins/dbgate-plugin-mysql/src/backend/drivers.js @@ -28,7 +28,7 @@ const drivers = driverBases.map(driverBase => ({ ...driverBase, analyserClass: Analyser, - async connect({ server, port, user, password, database, ssl }) { + async connect({ server, port, user, password, database, ssl, isReadOnly }) { const connection = mysql2.createConnection({ host: server, port, @@ -44,6 +44,9 @@ const drivers = driverBases.map(driverBase => ({ // multipleStatements: true, }); connection._database_name = database; + if (isReadOnly) { + await this.query(connection, 'SET SESSION TRANSACTION READ ONLY'); + } return connection; }, async close(pool) { diff --git a/plugins/dbgate-plugin-mysql/src/frontend/drivers.js b/plugins/dbgate-plugin-mysql/src/frontend/drivers.js index 49a089102..7b889f014 100644 --- a/plugins/dbgate-plugin-mysql/src/frontend/drivers.js +++ b/plugins/dbgate-plugin-mysql/src/frontend/drivers.js @@ -41,7 +41,7 @@ const dialect = { const mysqlDriverBase = { ...driverBase, showConnectionField: (field, values) => - ['server', 'port', 'user', 'password', 'defaultDatabase', 'singleDatabase'].includes(field), + ['server', 'port', 'user', 'password', 'defaultDatabase', 'singleDatabase', 'isReadOnly'].includes(field), dumperClass: Dumper, dialect, defaultPort: 3306,