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) =>