diff --git a/packages/types/dumper.d.ts b/packages/types/dumper.d.ts
index d2af2879a..746cbbfc2 100644
--- a/packages/types/dumper.d.ts
+++ b/packages/types/dumper.d.ts
@@ -24,4 +24,5 @@ export interface SqlDumper extends AlterProcessor {
truncateTable(table: NamedObjectInfo);
beginTransaction();
commitTransaction();
+ rollbackTransaction();
}
diff --git a/packages/web/src/tabs/QueryTab.svelte b/packages/web/src/tabs/QueryTab.svelte
index 44fbc568c..49551b5a0 100644
--- a/packages/web/src/tabs/QueryTab.svelte
+++ b/packages/web/src/tabs/QueryTab.svelte
@@ -65,7 +65,7 @@
category: 'Query',
name: 'Begin transaction',
icon: 'icon transaction',
- testEnabled: () => !!getCurrentEditor(),
+ testEnabled: () => getCurrentEditor()?.beginTransactionEnabled(),
onClick: () => getCurrentEditor().beginTransaction(),
});
registerCommand({
@@ -74,7 +74,7 @@
name: 'Commit transaction',
toolbarName: 'Commit',
icon: 'icon commit',
- testEnabled: () => !!getCurrentEditor(),
+ testEnabled: () => getCurrentEditor()?.endTransactionEnabled(),
onClick: () => getCurrentEditor().commitTransaction(),
});
registerCommand({
@@ -83,7 +83,7 @@
name: 'Rollback transaction',
toolbarName: 'Rollback',
icon: 'icon rollback',
- testEnabled: () => !!getCurrentEditor(),
+ testEnabled: () => getCurrentEditor()?.endTransactionEnabled(),
onClick: () => getCurrentEditor().rollbackTransaction(),
});
@@ -177,6 +177,7 @@
let intervalId;
let isAiAssistantVisible = isProApp() && localStorage.getItem(`tabdata_isAiAssistantVisible_${tabid}`) == 'true';
let domAiAssistant;
+ let isInTransaction = false;
onMount(() => {
intervalId = setInterval(() => {
@@ -219,6 +220,7 @@
$: {
busy;
sessionId;
+ isInTransaction;
invalidateCommands();
}
@@ -348,6 +350,7 @@
sesid: sessionId,
});
sessionId = null;
+ isInTransaction = false;
busy = false;
timerLabel.stop();
}
@@ -403,6 +406,35 @@
});
}
+ export function beginTransaction() {
+ const dmp = driver.createDumper();
+ dmp.beginTransaction();
+ executeCore(dmp.s);
+ isInTransaction = true;
+ }
+
+ export function beginTransactionEnabled() {
+ return driver?.supportsTransactions && !isInTransaction && !busy;
+ }
+
+ export function endTransactionEnabled() {
+ return !!sessionId && driver?.supportsTransactions && isInTransaction && !busy;
+ }
+
+ export function commitTransaction() {
+ const dmp = driver.createDumper();
+ dmp.commitTransaction();
+ executeCore(dmp.s);
+ isInTransaction = false;
+ }
+
+ export function rollbackTransaction() {
+ const dmp = driver.createDumper();
+ dmp.rollbackTransaction();
+ executeCore(dmp.s);
+ isInTransaction = false;
+ }
+
const handleMesageClick = message => {
// console.log('EDITOR', editorRef.current.editor);
if (domEditor.getEditor()) {
@@ -628,9 +660,21 @@
>
AI Assistant
-
-
-
+
+
+
diff --git a/plugins/dbgate-plugin-postgres/src/frontend/drivers.js b/plugins/dbgate-plugin-postgres/src/frontend/drivers.js
index 7e8dae3b9..21f33683e 100644
--- a/plugins/dbgate-plugin-postgres/src/frontend/drivers.js
+++ b/plugins/dbgate-plugin-postgres/src/frontend/drivers.js
@@ -120,6 +120,7 @@ const dialect = {
const postgresDriverBase = {
...driverBase,
+ supportsTransactions: true,
dumperClass: Dumper,
dialect,
// showConnectionField: (field, values) =>