diff --git a/packages/api/src/controllers/databaseConnections.js b/packages/api/src/controllers/databaseConnections.js
index 1503e735e..85e90d89d 100644
--- a/packages/api/src/controllers/databaseConnections.js
+++ b/packages/api/src/controllers/databaseConnections.js
@@ -159,7 +159,7 @@ module.exports = {
async collectionData({ conid, database, options }) {
const opened = await this.ensureOpened(conid, database);
const res = await this.sendRequest(opened, { msgtype: 'collectionData', options });
- return res.result;
+ return res.result || null;
},
async loadDataCore(msgtype, { conid, database, ...args }) {
@@ -167,6 +167,10 @@ module.exports = {
const res = await this.sendRequest(opened, { msgtype, ...args });
if (res.errorMessage) {
console.error(res.errorMessage);
+
+ return {
+ errorMessage: res.errorMessage,
+ };
}
return res.result || null;
},
@@ -193,19 +197,26 @@ module.exports = {
callMethod_meta: true,
async callMethod({ conid, database, method, args }) {
- const opened = await this.ensureOpened(conid, database);
- const res = await this.sendRequest(opened, { msgtype: 'callMethod', method, args });
- if (res.errorMessage) {
- console.error(res.errorMessage);
- }
- return res.result || null;
+ return this.loadDataCore('callMethod', { conid, database, method, args });
+
+ // const opened = await this.ensureOpened(conid, database);
+ // const res = await this.sendRequest(opened, { msgtype: 'callMethod', method, args });
+ // if (res.errorMessage) {
+ // console.error(res.errorMessage);
+ // }
+ // return res.result || null;
},
updateCollection_meta: true,
async updateCollection({ conid, database, changeSet }) {
const opened = await this.ensureOpened(conid, database);
const res = await this.sendRequest(opened, { msgtype: 'updateCollection', changeSet });
- return res.result;
+ if (res.errorMessage) {
+ return {
+ errorMessage: res.errorMessage,
+ };
+ }
+ return res.result || null;
},
status_meta: true,
diff --git a/packages/api/src/proc/databaseConnectionProcess.js b/packages/api/src/proc/databaseConnectionProcess.js
index 1f721239a..f10ac1874 100644
--- a/packages/api/src/proc/databaseConnectionProcess.js
+++ b/packages/api/src/proc/databaseConnectionProcess.js
@@ -155,6 +155,7 @@ async function handleRunScript({ msgid, sql }) {
await waitConnected();
const driver = requireEngineDriver(storedConnection);
try {
+ ensureExecuteCustomScript(driver);
await driver.script(systemConnection, sql);
process.send({ msgtype: 'response', msgid });
} catch (err) {
@@ -166,6 +167,7 @@ async function handleQueryData({ msgid, sql }) {
await waitConnected();
const driver = requireEngineDriver(storedConnection);
try {
+ ensureExecuteCustomScript(driver);
const res = await driver.query(systemConnection, sql);
process.send({ msgtype: 'response', msgid, ...res });
} catch (err) {
@@ -204,7 +206,10 @@ async function handleLoadKeyInfo({ msgid, key }) {
}
async function handleCallMethod({ msgid, method, args }) {
- return handleDriverDataCore(msgid, driver => driver.callMethod(systemConnection, method, args));
+ return handleDriverDataCore(msgid, driver => {
+ ensureExecuteCustomScript(driver);
+ return driver.callMethod(systemConnection, method, args);
+ });
}
async function handleLoadKeyTableRange({ msgid, key, cursor, count }) {
@@ -217,10 +222,20 @@ async function handleLoadFieldValues({ msgid, schemaName, pureName, field, searc
);
}
+function ensureExecuteCustomScript(driver) {
+ if (driver.readOnlySessions) {
+ return;
+ }
+ if (storedConnection.isReadOnly) {
+ throw new Error('Connection is read only');
+ }
+}
+
async function handleUpdateCollection({ msgid, changeSet }) {
await waitConnected();
const driver = requireEngineDriver(storedConnection);
try {
+ ensureExecuteCustomScript(driver);
const result = await driver.updateCollection(systemConnection, changeSet);
process.send({ msgtype: 'response', msgid, result });
} catch (err) {
diff --git a/packages/api/src/proc/sessionProcess.js b/packages/api/src/proc/sessionProcess.js
index e11323f2d..6e8355de9 100644
--- a/packages/api/src/proc/sessionProcess.js
+++ b/packages/api/src/proc/sessionProcess.js
@@ -135,10 +135,20 @@ function handleStream(driver, resultIndexHolder, sql) {
});
}
+function ensureExecuteCustomScript(driver) {
+ if (driver.readOnlySessions) {
+ return;
+ }
+ if (storedConnection.isReadOnly) {
+ throw new Error('Connection is read only');
+ }
+}
+
async function handleConnect(connection) {
storedConnection = connection;
const driver = requireEngineDriver(storedConnection);
+ ensureExecuteCustomScript(driver);
systemConnection = await connectUtility(driver, storedConnection);
for (const [resolve] of afterConnectCallbacks) {
resolve();
diff --git a/packages/types/engines.d.ts b/packages/types/engines.d.ts
index d5529be5c..22de715f9 100644
--- a/packages/types/engines.d.ts
+++ b/packages/types/engines.d.ts
@@ -47,6 +47,7 @@ export interface EngineDriver {
title: string;
defaultPort?: number;
databaseEngineTypes: string[];
+ readOnlySessions: boolean,
supportedKeyTypes: { name: string; label: string }[];
supportsDatabaseUrl?: boolean;
isElectronOnly?: boolean;
diff --git a/packages/web/src/tabs/CollectionDataTab.svelte b/packages/web/src/tabs/CollectionDataTab.svelte
index db7ab7728..a48703afb 100644
--- a/packages/web/src/tabs/CollectionDataTab.svelte
+++ b/packages/web/src/tabs/CollectionDataTab.svelte
@@ -173,6 +173,6 @@
-
+
diff --git a/packages/web/src/tabs/QueryTab.svelte b/packages/web/src/tabs/QueryTab.svelte
index 94f50a8b4..dc11c89ee 100644
--- a/packages/web/src/tabs/QueryTab.svelte
+++ b/packages/web/src/tabs/QueryTab.svelte
@@ -140,7 +140,7 @@
}
export function hasConnection() {
- return !!conid;
+ return !!conid && (!$connection.isReadOnly || driver.readOnlySessions);
}
async function executeCore(sql) {
diff --git a/plugins/dbgate-plugin-mongo/src/frontend/driver.js b/plugins/dbgate-plugin-mongo/src/frontend/driver.js
index 146762712..9a06164bf 100644
--- a/plugins/dbgate-plugin-mongo/src/frontend/driver.js
+++ b/plugins/dbgate-plugin-mongo/src/frontend/driver.js
@@ -38,9 +38,9 @@ const driver = {
showConnectionField: (field, values) => {
if (field == 'useDatabaseUrl') return true;
if (values.useDatabaseUrl) {
- return ['databaseUrl', 'defaultDatabase', 'singleDatabase'].includes(field);
+ return ['databaseUrl', 'defaultDatabase', 'singleDatabase', 'isReadOnly'].includes(field);
}
- return ['server', 'port', 'user', 'password', 'defaultDatabase', 'singleDatabase'].includes(field);
+ return ['server', 'port', 'user', 'password', 'defaultDatabase', 'singleDatabase', 'isReadOnly'].includes(field);
},
importExportArgs: [
diff --git a/plugins/dbgate-plugin-mysql/src/frontend/drivers.js b/plugins/dbgate-plugin-mysql/src/frontend/drivers.js
index 7b889f014..77c27ba30 100644
--- a/plugins/dbgate-plugin-mysql/src/frontend/drivers.js
+++ b/plugins/dbgate-plugin-mysql/src/frontend/drivers.js
@@ -46,6 +46,7 @@ const mysqlDriverBase = {
dialect,
defaultPort: 3306,
getQuerySplitterOptions: () => mysqlSplitterOptions,
+ readOnlySessions: true,
getNewObjectTemplates() {
return [