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,