From b0f921afa6d6f4239a0388b37a947ac93b988c10 Mon Sep 17 00:00:00 2001 From: Ainur Date: Mon, 4 Mar 2024 19:35:32 +0100 Subject: [PATCH 01/25] CB-4806 transactions api --- .../schema/service.sql.graphqls | 23 ++++ .../service/sql/DBWServiceSQL.java | 18 ++++ .../service/sql/WebSQLContextInfo.java | 101 +++++++++++++++++- .../service/sql/WebServiceBindingSQL.java | 19 +++- .../service/sql/impl/WebServiceSQL.java | 16 ++- 5 files changed, 171 insertions(+), 6 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls b/server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls index b51bb1cd2f..0aa108efe0 100644 --- a/server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls +++ b/server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls @@ -44,6 +44,7 @@ type SQLContextInfo { id: ID! projectId: ID! connectionId: ID! + autoCommit: Boolean defaultCatalog: String defaultSchema: String @@ -401,4 +402,26 @@ extend type Mutation { asyncSqlRowDataCountResult(taskId: ID!): Int! + @since(version: "24.0.1") + asyncSqlSetAutoCommit( + projectId: ID, + connectionId: ID!, + contextId: ID!, + autoCommit: Boolean! + ): AsyncTaskInfo! + + @since(version: "24.0.1") + asyncSqlCommitTransaction( + projectId: ID, + connectionId: ID!, + contextId: ID! + ): AsyncTaskInfo! + + @since(version: "24.0.1") + asyncSqlRollbackTransaction( + projectId: ID, + connectionId: ID!, + contextId: ID! + ): AsyncTaskInfo! + } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/DBWServiceSQL.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/DBWServiceSQL.java index 3dcb4b5f64..752357ba66 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/DBWServiceSQL.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/DBWServiceSQL.java @@ -172,4 +172,22 @@ String generateGroupByQuery(@NotNull WebSQLContextInfo contextInfo, @Nullable @WebAction Long getRowDataCountResult(@NotNull WebSession webSession, @NotNull String taskId) throws DBWebException; + + @WebAction + WebAsyncTaskInfo asyncSqlSetAutoCommit( + @NotNull WebSession webSession, + @NotNull WebSQLContextInfo contextInfo, + boolean autoCommit + ) throws DBWebException; + + @WebAction + WebAsyncTaskInfo asyncSqlRollbackTransaction( + @NotNull WebSession webSession, + @NotNull WebSQLContextInfo contextInfo + ) throws DBWebException; + + @WebAction + WebAsyncTaskInfo asyncSqlCommitTransaction( + @NotNull WebSession webSession, + @NotNull WebSQLContextInfo sqlContext); } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLContextInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLContextInfo.java index 2a554eccd3..0269549079 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLContextInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLContextInfo.java @@ -19,20 +19,26 @@ import io.cloudbeaver.DBWebException; import io.cloudbeaver.WebAction; import io.cloudbeaver.WebProjectImpl; +import io.cloudbeaver.model.WebAsyncTaskInfo; +import io.cloudbeaver.model.session.WebAsyncTaskProcessor; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.model.session.WebSessionProvider; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; +import org.jkiss.dbeaver.model.DBUtils; import org.jkiss.dbeaver.model.data.DBDAttributeBinding; -import org.jkiss.dbeaver.model.exec.DBCException; -import org.jkiss.dbeaver.model.exec.DBCExecutionContextDefaults; -import org.jkiss.dbeaver.model.exec.DBExecUtils; +import org.jkiss.dbeaver.model.exec.*; +import org.jkiss.dbeaver.model.qm.QMTransactionState; +import org.jkiss.dbeaver.model.qm.QMUtils; +import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; import org.jkiss.dbeaver.model.struct.DBSDataContainer; import org.jkiss.dbeaver.model.struct.rdb.DBSCatalog; import org.jkiss.dbeaver.model.struct.rdb.DBSSchema; +import org.jkiss.dbeaver.utils.RuntimeUtils; import org.jkiss.utils.CommonUtils; +import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; @@ -170,4 +176,93 @@ void dispose() { public WebSession getWebSession() { return processor.getWebSession(); } + + + /////////////////////////////////////////////////////// + // Transactions + + public WebAsyncTaskInfo setAutoCommit(boolean autoCommit) { + DBCExecutionContext context = processor.getExecutionContext(); + DBCTransactionManager txnManager = DBUtils.getTransactionManager(context); + WebAsyncTaskProcessor runnable = new WebAsyncTaskProcessor<>() { + @Override + public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + if (txnManager != null) { + monitor.beginTask("Change connection auto-commit to " + autoCommit, 1); + try { + monitor.subTask("Change context '" + context.getContextName() + "' auto-commit state"); + txnManager.setAutoCommit(monitor, autoCommit); + result = true; + } catch (DBException e) { + throw new InvocationTargetException(e); + } finally { + monitor.done(); + } + } + + } + }; + return getWebSession().createAndRunAsyncTask("Set auto-commit", runnable); + + } + + public WebAsyncTaskInfo commitTransaction() { + DBCExecutionContext context = processor.getExecutionContext(); + DBCTransactionManager txnManager = DBUtils.getTransactionManager(context); + WebAsyncTaskProcessor runnable = new WebAsyncTaskProcessor<>() { + @Override + public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + if (txnManager != null) { + QMTransactionState txnInfo = QMUtils.getTransactionState(context); + try (DBCSession session = context.openSession(monitor, DBCExecutionPurpose.UTIL, "Commit transaction")) { + txnManager.commit(session); + } catch (DBCException e) { + throw new InvocationTargetException(e); + } + result = """ + Transaction has been committed + + Query count: %s + + Duration: %s + """.formatted( + txnInfo.getUpdateCount(), + RuntimeUtils.formatExecutionTime(System.currentTimeMillis() - txnInfo.getTransactionStartTime()) + ); + } + } + }; + return getWebSession().createAndRunAsyncTask("Commit transaction", runnable); + } + + + public WebAsyncTaskInfo rollbackTransaction() { + DBCExecutionContext context = processor.getExecutionContext(); + DBCTransactionManager txnManager = DBUtils.getTransactionManager(context); + WebAsyncTaskProcessor runnable = new WebAsyncTaskProcessor<>() { + @Override + public void run(DBRProgressMonitor monitor) throws InvocationTargetException, InterruptedException { + if (txnManager != null) { + QMTransactionState txnInfo = QMUtils.getTransactionState(context); + try (DBCSession session = context.openSession(monitor, DBCExecutionPurpose.UTIL, "Rollback transaction")) { + txnManager.rollback(session, null); + } catch (DBCException e) { + throw new InvocationTargetException(e); + } + result = """ + Transaction has been rolled back + + Query count: %s + + Duration: %s + """.formatted( + txnInfo.getUpdateCount(), + RuntimeUtils.formatExecutionTime(System.currentTimeMillis() - txnInfo.getTransactionStartTime()) + ); + } + } + }; + + return getWebSession().createAndRunAsyncTask("Rollback transaction", runnable); + } } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java index cc266b8265..662fe6bd7e 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebServiceBindingSQL.java @@ -207,8 +207,23 @@ public void bindWiring(DBWBindingContext model) throws DBWebException { getService(env).getRowDataCountResult( getWebSession(env), env.getArgument("taskId") - ) - ); + )) + .dataFetcher("asyncSqlSetAutoCommit", env -> + getService(env).asyncSqlSetAutoCommit( + getWebSession(env), + getSQLContext(env), + env.getArgument("autoCommit") + )) + .dataFetcher("asyncSqlCommitTransaction", env -> + getService(env).asyncSqlCommitTransaction( + getWebSession(env), + getSQLContext(env) + )) + .dataFetcher("asyncSqlRollbackTransaction", env -> + getService(env).asyncSqlRollbackTransaction( + getWebSession(env), + getSQLContext(env) + )); } @NotNull diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java index 8728b647c6..e07d0e24cd 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java @@ -48,7 +48,6 @@ import org.jkiss.dbeaver.model.sql.registry.SQLGeneratorConfigurationRegistry; import org.jkiss.dbeaver.model.sql.registry.SQLGeneratorDescriptor; import org.jkiss.dbeaver.model.struct.DBSDataContainer; -import org.jkiss.dbeaver.model.struct.DBSEntity; import org.jkiss.dbeaver.model.struct.DBSObject; import org.jkiss.dbeaver.model.struct.DBSWrapper; import org.jkiss.dbeaver.utils.RuntimeUtils; @@ -579,4 +578,19 @@ public Long getRowDataCountResult(@NotNull WebSession webSession, @NotNull Strin return null; } + @Override + public WebAsyncTaskInfo asyncSqlSetAutoCommit(@NotNull WebSession webSession, @NotNull WebSQLContextInfo contextInfo, boolean autoCommit) throws DBWebException { + return contextInfo.setAutoCommit(autoCommit); + } + + @Override + public WebAsyncTaskInfo asyncSqlRollbackTransaction(@NotNull WebSession webSession, @NotNull WebSQLContextInfo contextInfo) throws DBWebException { + return contextInfo.rollbackTransaction(); + } + + @Override + public WebAsyncTaskInfo asyncSqlCommitTransaction(@NotNull WebSession webSession, @NotNull WebSQLContextInfo contextInfo) { + return contextInfo.commitTransaction(); + } + } From c2e081de42caaeac24ee800195ff60e0803eaf72 Mon Sep 17 00:00:00 2001 From: naumov Date: Tue, 5 Mar 2024 16:22:58 +0100 Subject: [PATCH 02/25] CB-1084 add commit mode plugin --- .../plugin-datasource-commit-mode/.gitignore | 17 ++++++++ .../package.json | 29 +++++++++++++ .../public/icons/commit.png | Bin 0 -> 827 bytes .../public/icons/commit_mode_auto.png | Bin 0 -> 650 bytes .../public/icons/commit_mode_manual.png | Bin 0 -> 1024 bytes .../public/icons/rollback.png | Bin 0 -> 805 bytes .../src/CommitModeManagerBootstrap.ts | 38 ++++++++++++++++++ .../src/CommitModeManagerService.ts | 13 ++++++ .../src/LocaleService.ts | 35 ++++++++++++++++ .../src/actions/ACTION_COMMIT.ts | 14 +++++++ .../src/actions/ACTION_COMMIT_MODE_TOGGLE.ts | 14 +++++++ .../src/actions/ACTION_ROLLBACK.ts | 14 +++++++ .../src/index.ts | 1 + .../src/locales/en.ts | 6 +++ .../src/locales/it.ts | 6 +++ .../src/locales/ru.ts | 6 +++ .../src/locales/zh.ts | 6 +++ .../src/manifest.ts | 20 +++++++++ .../tsconfig.json | 34 ++++++++++++++++ 19 files changed, 253 insertions(+) create mode 100644 webapp/packages/plugin-datasource-commit-mode/.gitignore create mode 100644 webapp/packages/plugin-datasource-commit-mode/package.json create mode 100644 webapp/packages/plugin-datasource-commit-mode/public/icons/commit.png create mode 100644 webapp/packages/plugin-datasource-commit-mode/public/icons/commit_mode_auto.png create mode 100644 webapp/packages/plugin-datasource-commit-mode/public/icons/commit_mode_manual.png create mode 100644 webapp/packages/plugin-datasource-commit-mode/public/icons/rollback.png create mode 100644 webapp/packages/plugin-datasource-commit-mode/src/CommitModeManagerBootstrap.ts create mode 100644 webapp/packages/plugin-datasource-commit-mode/src/CommitModeManagerService.ts create mode 100644 webapp/packages/plugin-datasource-commit-mode/src/LocaleService.ts create mode 100644 webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_COMMIT.ts create mode 100644 webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts create mode 100644 webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_ROLLBACK.ts create mode 100644 webapp/packages/plugin-datasource-commit-mode/src/index.ts create mode 100644 webapp/packages/plugin-datasource-commit-mode/src/locales/en.ts create mode 100644 webapp/packages/plugin-datasource-commit-mode/src/locales/it.ts create mode 100644 webapp/packages/plugin-datasource-commit-mode/src/locales/ru.ts create mode 100644 webapp/packages/plugin-datasource-commit-mode/src/locales/zh.ts create mode 100644 webapp/packages/plugin-datasource-commit-mode/src/manifest.ts create mode 100644 webapp/packages/plugin-datasource-commit-mode/tsconfig.json diff --git a/webapp/packages/plugin-datasource-commit-mode/.gitignore b/webapp/packages/plugin-datasource-commit-mode/.gitignore new file mode 100644 index 0000000000..15bc16c7c3 --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/.gitignore @@ -0,0 +1,17 @@ +# dependencies +/node_modules + +# testing +/coverage + +# production +/lib + +# misc +.DS_Store +.env* + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/webapp/packages/plugin-datasource-commit-mode/package.json b/webapp/packages/plugin-datasource-commit-mode/package.json new file mode 100644 index 0000000000..4f370943ac --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/package.json @@ -0,0 +1,29 @@ +{ + "name": "@cloudbeaver/plugin-datasource-commit-mode", + "sideEffects": [ + "src/**/*.css", + "src/**/*.scss", + "public/**/*" + ], + "version": "0.1.0", + "description": "", + "license": "Apache-2.0", + "main": "dist/index.js", + "scripts": { + "build": "tsc -b", + "lint": "eslint ./src/ --ext .ts,.tsx", + "lint-fix": "eslint ./src/ --ext .ts,.tsx --fix", + "validate-dependencies": "core-cli-validate-dependencies", + "update-ts-references": "rimraf --glob dist && typescript-resolve-references" + }, + "dependencies": { + "@cloudbeaver/core-di": "~0.1.0", + "@cloudbeaver/core-localization": "~0.1.0", + "@cloudbeaver/core-view": "~0.1.0", + "@cloudbeaver/plugin-top-app-bar": "~0.1.0" + }, + "peerDependencies": {}, + "devDependencies": { + "typescript": "^5.3.2" + } +} diff --git a/webapp/packages/plugin-datasource-commit-mode/public/icons/commit.png b/webapp/packages/plugin-datasource-commit-mode/public/icons/commit.png new file mode 100644 index 0000000000000000000000000000000000000000..f0d157102af79583c78a66faab2f597ff0795b7b GIT binary patch literal 827 zcmV-B1H}A^P)Px%^+`lQR9Fe^S4~J%Q4~JszL__UKb50KC>4@Sg>AAK6(owtO=egy)~;Q<7FxEA zHsPieN&+b=B8rJZ3|F=3XA`M~{S6vwB@;tBjuVWo=#GytXfLcUar2v_@CT<47X5n&hyr}U&5a2|_NXmxe; zUlDOLQMCg5ItFGqI02lr=SX9j98>jk^U*yFK2OMvR>C42#GBh?Y5d6E(i&B6ka_ZE zVk{b?<-&ZS5|F7KY72y8HmQ+ztY`xKWilnP;t7Z(+@0^-devQ(1UN8Knpkg|Omu}B zy;#=h8d6IHrvT7~R1Lv~!1lB9C z<`u}=HcYH?^a0{sB9T|l&G|mR5~X1!ygh1*j3#UnT-Fjm#J}tl+}2iIe2ekyUXwJE z4k)cAD=lDvKO`V^7ivmw>VRwU7V+jQfS?eNj-Ib|e5RCQ^P^@fR4&4a3km~;wA7M3i_k`3`3)o3NDVG&@@nAiD z%7!>N;GBh6#|40(gpi+1kL-eQ`}o6pk17|;@+dxS-HHM38&)FmFHeE3VC2$)b|p35 znX0qjc9&GXU~Q5p#O`~%p7_n%Tm=ZeOa)3ezkH~3zs+JBW?RGxFfDUiQ)>VT`1JsD z<$T$0&Hbp=IqXF_2uNhfrUWBFRb?sxw&->J%Qx+)cyOXu1xd#&3czkPBp8nUPUj?a z2xN=kmrD}~Abe-5bXy=4b@ld77>tL!O}D)8C7Zp z23lM<+#Q1>6leo`4E>z)13wr+CnJ7qu7!qXBQP79t~m9$(f2>(U^Gy{b=;m)H32?( z+fwzM5&kTBIP=^y?`K~RvwiNIj|6t53&3{6Ft-QjgMVeW>yes@!j=F4002ovPDHLk FV1mDcc+da< literal 0 HcmV?d00001 diff --git a/webapp/packages/plugin-datasource-commit-mode/public/icons/commit_mode_auto.png b/webapp/packages/plugin-datasource-commit-mode/public/icons/commit_mode_auto.png new file mode 100644 index 0000000000000000000000000000000000000000..43b5d257f25fab92d701c5e8aba8ec16d462a295 GIT binary patch literal 650 zcmV;50(Jd~P)Px%L`g(JR9Fe^R=;Z$K@@&(cW*bwU-1kfXl18ZMDI>P3-J%Ivd}&VBIx0jDJ+A9 zVA2E?uF=NALjM6pK_ciK!6INIA_NN&(QI{TJYHo3$By=DCP4N(A<%F@zoxB%5-X z0Fgu{%%!Obb4N4D#$5Lm5uMAV03D~+X`Wch=7!~I2Znu-=bxWj8e2nknPc19_t*vB z3lv@C+@Af_hf(qeEICtbwt^MQ@CdLAMCz*s8?(@P{W%YR&TL(y~G$+E*7 z1mX|e0U-z9emu92#z*k>#?&Xh&av#G!*F8(^#`4C=s}ZWzZR#t>gV5N7N(E!ugwtGzl)SBZVF4vFA#ZUDx{l)u kDf>Sm8;^vMHRh$jUv;j#B5zr!4FCWD07*qoM6N<$g0)pGHUIzs literal 0 HcmV?d00001 diff --git a/webapp/packages/plugin-datasource-commit-mode/public/icons/commit_mode_manual.png b/webapp/packages/plugin-datasource-commit-mode/public/icons/commit_mode_manual.png new file mode 100644 index 0000000000000000000000000000000000000000..9bfc23c42d30a38b385e8c491aef01088bd9a035 GIT binary patch literal 1024 zcmV+b1poVqP)Px&x=BPqR9Fe!R$XWmR}{YI&g{nQCMFoPsT6A^3L>FRHkL*UuGDI+4?@A!C-Dyi zL1abn!3Tdp3Vkq?B8cFF&=)HrXz4>=8d5B6lEEs``fsA~Cy9T{W;Z*tckc1bWXH^o zv%4mB5FD7j=l7m(&bjxTW$Yb4FxB|64(${}Oiad~E6UQIT`hmPeYl%>7qmL%pooGo zFpB(vg(xd_R_R9|1L@X-M0E2OJ>?R3H?sIxNAIr;*&2%muB^mrv$Hnbp!~6EuAVr3 zH8hfma4#Jw04C*LWcU^5e3?Xfn81Chs?cr<{E<@eIg7Grux9{RmcB5}0H|CnOY5kV z+@!qQw3Vr;p8?Ce!h;dqpz3w%oW`ci=>)8DnJ;(fKr;XtI449Z)&KC~QYWBy4KxFk z>J*jWDIm*x13P@60H_38B03LetK#EeY;feDq2qNKqZBnf|DA^C!L_CUpkdk7`YMoh2CHI)dFyU%aCy89QF; z6Hw3nENK>GQqPx>O_!gY4WR9amZVL$(y&yDjo=o^_XEN=R!~F7&uo2RsM4VMA>MKE zm(FC1?>(o%e4m=o4I0YX;(aGLy9D&_CP#C;YC>Fw0>DU!U&|Wi!f`8pNZZ}Izl=v& z)p!XC!9%LjS2Im{E=^E z@yzIxmbvxuoFN~d*9L8A^XzEX_utN&-&h-Nwge*?F}(J~hZQb9gG8GQ zwl*mc!(Q1N@xU7V>?U;$tqp$L*4+5_y|ji>7Vd)Iwv6=*rbo|SeiFB|0PGG{<3T^m zNdu^@QtG~*Umx?^%#r1U%pCZA;PE&Q21i)my}i{sw68rC0ceA1V^&SL)GT>zLrZY% z!UNq9a*3@3*wdYC?e#SzVG#gfnoLL>%}e>JZFb#y5vRA5e_1(o$}_#m)}P856#?iU z&cx}p>}$$7y@`(Mex3diZLMTm06;C5VUwS+qQG~OsW<&}rDR|tM(gWtml{BBKO2Cm us>@Ajt^&lOSwMaKzwTYJKiv-R9sLp_DsRPx%-$_J4R9Fe^S6@g|Q5gTuuDVp5gcKA>>K1KC1>2mupn8ZP5PB)Fhu*9gdnkJ- zdJd|W7DbS~)r&!ISr9&i7%X(VkxH0t$xNXFty$^RyK_(9sji-LnO?)|_TqtYzQ5=9 zJKy>4?zsR39z?_sbjB;m9Jvd?PA~>8(f2(^B z^Xu5+LT|&p;c9XHT(VSwU?e{C4}69YGMFo2RU2c~44~GCSxY4(0)bm`%m+a5zWBw! zVPm1S&X|7%W3P+xRwSe&5EJc^t&U^E3Gj`qMj|f+3=;an!b5Xq^G1LJV{cWM2^5(P z>(QMhjxLQt%)ExKv*&mYPP3iswi1Y*_mAV6{3ne-Bu*uRpyc%k1l%QYlfY&L3SI$Q zAH${AHVe#g2~9f~=vlKXF9g&M|9vyCp%?rJY$q^rs=0Ku$$i||q19~b5hNNs^|Rxj zpWy3vG8uNOA~;hB^Y|*$YE8|9g%OcQlBJ2t6i6%eVMj+U& z&LQCGkx)%9f*kb@jJL@I{%WI*HLdu1?xLD@6D=ogZ$jTds?%9U&gKH=w!QtS$2h&g z+wY%7wVeP5sqIar`MmNV(|8@3D^VM^@?N|(*akhkg=$?TVsSrNkN?(96hiuN+x`!(*zN-U3HM2%uunwKrs z5`K8l;)>GkuiNUs8POj?buE<9ZbKJm-1R(e^0GIUy2I^q1r((nD1C+($em)+YBD}r z%HogAIgGhs#3`<=ujtQo(9rqJ_s@W2GOp532YQBP4WCp2ZansAu>517B@oFO600000NkvXXu0mjf$_{;x literal 0 HcmV?d00001 diff --git a/webapp/packages/plugin-datasource-commit-mode/src/CommitModeManagerBootstrap.ts b/webapp/packages/plugin-datasource-commit-mode/src/CommitModeManagerBootstrap.ts new file mode 100644 index 0000000000..dc7210316d --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/src/CommitModeManagerBootstrap.ts @@ -0,0 +1,38 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { Bootstrap, injectable } from '@cloudbeaver/core-di'; +import { ActionService, MenuService } from '@cloudbeaver/core-view'; +import { MENU_APP_ACTIONS } from '@cloudbeaver/plugin-top-app-bar'; + +import { ACTION_COMMIT } from './actions/ACTION_COMMIT'; +import { ACTION_COMMIT_MODE_TOGGLE } from './actions/ACTION_COMMIT_MODE_TOGGLE'; +import { ACTION_ROLLBACK } from './actions/ACTION_ROLLBACK'; + +@injectable() +export class CommitModeManagerBootstrap extends Bootstrap { + constructor(private readonly menuService: MenuService, private readonly actionService: ActionService) { + super(); + } + + register() { + this.menuService.addCreator({ + menus: [MENU_APP_ACTIONS], + getItems: (context, items) => [...items, ACTION_COMMIT, ACTION_ROLLBACK, ACTION_COMMIT_MODE_TOGGLE], + }); + + this.actionService.addHandler({ + id: 'commit-mode-base', + isActionApplicable: (context, action) => [ACTION_COMMIT, ACTION_ROLLBACK, ACTION_COMMIT_MODE_TOGGLE].includes(action), + isLabelVisible: (context, action) => action === ACTION_COMMIT || action === ACTION_ROLLBACK, + isHidden: (context, action) => false, + handler: (context, action) => {}, + }); + } + + load() {} +} diff --git a/webapp/packages/plugin-datasource-commit-mode/src/CommitModeManagerService.ts b/webapp/packages/plugin-datasource-commit-mode/src/CommitModeManagerService.ts new file mode 100644 index 0000000000..bb8b5502d2 --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/src/CommitModeManagerService.ts @@ -0,0 +1,13 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { injectable } from '@cloudbeaver/core-di'; + +@injectable() +export class CommitModeManagerService { + constructor() {} +} diff --git a/webapp/packages/plugin-datasource-commit-mode/src/LocaleService.ts b/webapp/packages/plugin-datasource-commit-mode/src/LocaleService.ts new file mode 100644 index 0000000000..edeb82d255 --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/src/LocaleService.ts @@ -0,0 +1,35 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { Bootstrap, injectable } from '@cloudbeaver/core-di'; +import { LocalizationService } from '@cloudbeaver/core-localization'; + +@injectable() +export class LocaleService extends Bootstrap { + constructor(private readonly localizationService: LocalizationService) { + super(); + } + + register(): void | Promise { + this.localizationService.addProvider(this.provider.bind(this)); + } + + load(): void | Promise {} + + private async provider(locale: string) { + switch (locale) { + case 'ru': + return (await import('./locales/ru')).default; + case 'it': + return (await import('./locales/it')).default; + case 'zh': + return (await import('./locales/zh')).default; + default: + return (await import('./locales/en')).default; + } + } +} diff --git a/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_COMMIT.ts b/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_COMMIT.ts new file mode 100644 index 0000000000..08eea6418a --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_COMMIT.ts @@ -0,0 +1,14 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { createAction } from '@cloudbeaver/core-view'; + +export const ACTION_COMMIT = createAction('commit', { + label: 'plugin_datasource_commit_mode_commit', + tooltip: 'plugin_datasource_commit_mode_commit', + icon: '/icons/commit.png', +}); diff --git a/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts b/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts new file mode 100644 index 0000000000..95c6682c22 --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts @@ -0,0 +1,14 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { createAction } from '@cloudbeaver/core-view'; + +export const ACTION_COMMIT_MODE_TOGGLE = createAction('commit-mode-toggle', { + label: 'plugin_datasource_commit_mode_switch_to_manual_commit_mode', + tooltip: 'plugin_datasource_commit_mode_switch_to_manual_commit_mode', + icon: '/icons/commit_mode_auto.png', +}); diff --git a/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_ROLLBACK.ts b/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_ROLLBACK.ts new file mode 100644 index 0000000000..bfddeaab7e --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_ROLLBACK.ts @@ -0,0 +1,14 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { createAction } from '@cloudbeaver/core-view'; + +export const ACTION_ROLLBACK = createAction('rollback', { + label: 'plugin_datasource_commit_mode_rollback', + tooltip: 'plugin_datasource_commit_mode_rollback', + icon: '/icons/rollback.png', +}); diff --git a/webapp/packages/plugin-datasource-commit-mode/src/index.ts b/webapp/packages/plugin-datasource-commit-mode/src/index.ts new file mode 100644 index 0000000000..116e1ebecf --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/src/index.ts @@ -0,0 +1 @@ +export { datasourceCommitModePlugin } from './manifest'; diff --git a/webapp/packages/plugin-datasource-commit-mode/src/locales/en.ts b/webapp/packages/plugin-datasource-commit-mode/src/locales/en.ts new file mode 100644 index 0000000000..d37366d1e5 --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/src/locales/en.ts @@ -0,0 +1,6 @@ +export default [ + ['plugin_datasource_commit_mode_commit', 'Commit'], + ['plugin_datasource_commit_mode_rollback', 'Rollback'], + ['plugin_datasource_commit_mode_switch_to_auto_commit_mode', 'Switch to auto-commit'], + ['plugin_datasource_commit_mode_switch_to_manual_commit_mode', 'Switch to manual commit'], +]; diff --git a/webapp/packages/plugin-datasource-commit-mode/src/locales/it.ts b/webapp/packages/plugin-datasource-commit-mode/src/locales/it.ts new file mode 100644 index 0000000000..06ee063126 --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/src/locales/it.ts @@ -0,0 +1,6 @@ +export default [ + ['plugin_datasource_commit_mode_commit', 'Commit'], + ['plugin_datasource_commit_mode_rollback', 'Rollback'], + ['plugin_datasource_commit_mode_switch_to_auto_commit', 'Switch to auto-commit'], + ['plugin_datasource_commit_mode_switch_to_manual_commit_mode', 'Switch to manual commit'], +]; diff --git a/webapp/packages/plugin-datasource-commit-mode/src/locales/ru.ts b/webapp/packages/plugin-datasource-commit-mode/src/locales/ru.ts new file mode 100644 index 0000000000..06ee063126 --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/src/locales/ru.ts @@ -0,0 +1,6 @@ +export default [ + ['plugin_datasource_commit_mode_commit', 'Commit'], + ['plugin_datasource_commit_mode_rollback', 'Rollback'], + ['plugin_datasource_commit_mode_switch_to_auto_commit', 'Switch to auto-commit'], + ['plugin_datasource_commit_mode_switch_to_manual_commit_mode', 'Switch to manual commit'], +]; diff --git a/webapp/packages/plugin-datasource-commit-mode/src/locales/zh.ts b/webapp/packages/plugin-datasource-commit-mode/src/locales/zh.ts new file mode 100644 index 0000000000..06ee063126 --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/src/locales/zh.ts @@ -0,0 +1,6 @@ +export default [ + ['plugin_datasource_commit_mode_commit', 'Commit'], + ['plugin_datasource_commit_mode_rollback', 'Rollback'], + ['plugin_datasource_commit_mode_switch_to_auto_commit', 'Switch to auto-commit'], + ['plugin_datasource_commit_mode_switch_to_manual_commit_mode', 'Switch to manual commit'], +]; diff --git a/webapp/packages/plugin-datasource-commit-mode/src/manifest.ts b/webapp/packages/plugin-datasource-commit-mode/src/manifest.ts new file mode 100644 index 0000000000..48e34d418a --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/src/manifest.ts @@ -0,0 +1,20 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import type { PluginManifest } from '@cloudbeaver/core-di'; + +import { CommitModeManagerBootstrap } from './CommitModeManagerBootstrap'; +import { CommitModeManagerService } from './CommitModeManagerService'; +import { LocaleService } from './LocaleService'; + +export const datasourceCommitModePlugin: PluginManifest = { + info: { + name: 'Datasource commit mode plugin', + }, + + providers: [CommitModeManagerBootstrap, LocaleService, CommitModeManagerService], +}; diff --git a/webapp/packages/plugin-datasource-commit-mode/tsconfig.json b/webapp/packages/plugin-datasource-commit-mode/tsconfig.json new file mode 100644 index 0000000000..99f6d7d12d --- /dev/null +++ b/webapp/packages/plugin-datasource-commit-mode/tsconfig.json @@ -0,0 +1,34 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "dist", + "tsBuildInfoFile": "dist/tsconfig.tsbuildinfo" + }, + "references": [ + { + "path": "../core-di/tsconfig.json" + }, + { + "path": "../core-localization/tsconfig.json" + }, + { + "path": "../core-view/tsconfig.json" + }, + { + "path": "../plugin-top-app-bar/tsconfig.json" + } + ], + "include": [ + "__custom_mocks__/**/*", + "src/**/*", + "src/**/*.json", + "src/**/*.css", + "src/**/*.scss" + ], + "exclude": [ + "**/node_modules", + "lib/**/*", + "dist/**/*" + ] +} From 0ebf7e90dfd3676daaa4c1b32a208b361b73ed02 Mon Sep 17 00:00:00 2001 From: naumov Date: Tue, 5 Mar 2024 16:45:19 +0100 Subject: [PATCH 03/25] CB-1084 rename plugin --- .../src/index.ts | 1 - .../src/locales/en.ts | 6 ------ .../src/locales/it.ts | 6 ------ .../src/locales/ru.ts | 6 ------ .../src/locales/zh.ts | 6 ------ .../src/manifest.ts | 20 ------------------ .../.gitignore | 0 .../package.json | 2 +- .../public/icons/commit.png | Bin .../public/icons/commit_mode_auto.png | Bin .../public/icons/commit_mode_manual.png | Bin .../public/icons/rollback.png | Bin .../src/LocaleService.ts | 0 .../src/TransactionManagerBootstrap.ts} | 2 +- .../src/TransactionManagerService.ts} | 2 +- .../src/actions/ACTION_COMMIT.ts | 4 ++-- .../src/actions/ACTION_COMMIT_MODE_TOGGLE.ts | 4 ++-- .../src/actions/ACTION_ROLLBACK.ts | 4 ++-- .../src/index.ts | 1 + .../src/locales/en.ts | 6 ++++++ .../src/locales/it.ts | 6 ++++++ .../src/locales/ru.ts | 6 ++++++ .../src/locales/zh.ts | 6 ++++++ .../src/manifest.ts | 20 ++++++++++++++++++ .../tsconfig.json | 0 25 files changed, 54 insertions(+), 54 deletions(-) delete mode 100644 webapp/packages/plugin-datasource-commit-mode/src/index.ts delete mode 100644 webapp/packages/plugin-datasource-commit-mode/src/locales/en.ts delete mode 100644 webapp/packages/plugin-datasource-commit-mode/src/locales/it.ts delete mode 100644 webapp/packages/plugin-datasource-commit-mode/src/locales/ru.ts delete mode 100644 webapp/packages/plugin-datasource-commit-mode/src/locales/zh.ts delete mode 100644 webapp/packages/plugin-datasource-commit-mode/src/manifest.ts rename webapp/packages/{plugin-datasource-commit-mode => plugin-datasource-transaction-manager}/.gitignore (100%) rename webapp/packages/{plugin-datasource-commit-mode => plugin-datasource-transaction-manager}/package.json (92%) rename webapp/packages/{plugin-datasource-commit-mode => plugin-datasource-transaction-manager}/public/icons/commit.png (100%) rename webapp/packages/{plugin-datasource-commit-mode => plugin-datasource-transaction-manager}/public/icons/commit_mode_auto.png (100%) rename webapp/packages/{plugin-datasource-commit-mode => plugin-datasource-transaction-manager}/public/icons/commit_mode_manual.png (100%) rename webapp/packages/{plugin-datasource-commit-mode => plugin-datasource-transaction-manager}/public/icons/rollback.png (100%) rename webapp/packages/{plugin-datasource-commit-mode => plugin-datasource-transaction-manager}/src/LocaleService.ts (100%) rename webapp/packages/{plugin-datasource-commit-mode/src/CommitModeManagerBootstrap.ts => plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts} (95%) rename webapp/packages/{plugin-datasource-commit-mode/src/CommitModeManagerService.ts => plugin-datasource-transaction-manager/src/TransactionManagerService.ts} (88%) rename webapp/packages/{plugin-datasource-commit-mode => plugin-datasource-transaction-manager}/src/actions/ACTION_COMMIT.ts (75%) rename webapp/packages/{plugin-datasource-commit-mode => plugin-datasource-transaction-manager}/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts (71%) rename webapp/packages/{plugin-datasource-commit-mode => plugin-datasource-transaction-manager}/src/actions/ACTION_ROLLBACK.ts (75%) create mode 100644 webapp/packages/plugin-datasource-transaction-manager/src/index.ts create mode 100644 webapp/packages/plugin-datasource-transaction-manager/src/locales/en.ts create mode 100644 webapp/packages/plugin-datasource-transaction-manager/src/locales/it.ts create mode 100644 webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts create mode 100644 webapp/packages/plugin-datasource-transaction-manager/src/locales/zh.ts create mode 100644 webapp/packages/plugin-datasource-transaction-manager/src/manifest.ts rename webapp/packages/{plugin-datasource-commit-mode => plugin-datasource-transaction-manager}/tsconfig.json (100%) diff --git a/webapp/packages/plugin-datasource-commit-mode/src/index.ts b/webapp/packages/plugin-datasource-commit-mode/src/index.ts deleted file mode 100644 index 116e1ebecf..0000000000 --- a/webapp/packages/plugin-datasource-commit-mode/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { datasourceCommitModePlugin } from './manifest'; diff --git a/webapp/packages/plugin-datasource-commit-mode/src/locales/en.ts b/webapp/packages/plugin-datasource-commit-mode/src/locales/en.ts deleted file mode 100644 index d37366d1e5..0000000000 --- a/webapp/packages/plugin-datasource-commit-mode/src/locales/en.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default [ - ['plugin_datasource_commit_mode_commit', 'Commit'], - ['plugin_datasource_commit_mode_rollback', 'Rollback'], - ['plugin_datasource_commit_mode_switch_to_auto_commit_mode', 'Switch to auto-commit'], - ['plugin_datasource_commit_mode_switch_to_manual_commit_mode', 'Switch to manual commit'], -]; diff --git a/webapp/packages/plugin-datasource-commit-mode/src/locales/it.ts b/webapp/packages/plugin-datasource-commit-mode/src/locales/it.ts deleted file mode 100644 index 06ee063126..0000000000 --- a/webapp/packages/plugin-datasource-commit-mode/src/locales/it.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default [ - ['plugin_datasource_commit_mode_commit', 'Commit'], - ['plugin_datasource_commit_mode_rollback', 'Rollback'], - ['plugin_datasource_commit_mode_switch_to_auto_commit', 'Switch to auto-commit'], - ['plugin_datasource_commit_mode_switch_to_manual_commit_mode', 'Switch to manual commit'], -]; diff --git a/webapp/packages/plugin-datasource-commit-mode/src/locales/ru.ts b/webapp/packages/plugin-datasource-commit-mode/src/locales/ru.ts deleted file mode 100644 index 06ee063126..0000000000 --- a/webapp/packages/plugin-datasource-commit-mode/src/locales/ru.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default [ - ['plugin_datasource_commit_mode_commit', 'Commit'], - ['plugin_datasource_commit_mode_rollback', 'Rollback'], - ['plugin_datasource_commit_mode_switch_to_auto_commit', 'Switch to auto-commit'], - ['plugin_datasource_commit_mode_switch_to_manual_commit_mode', 'Switch to manual commit'], -]; diff --git a/webapp/packages/plugin-datasource-commit-mode/src/locales/zh.ts b/webapp/packages/plugin-datasource-commit-mode/src/locales/zh.ts deleted file mode 100644 index 06ee063126..0000000000 --- a/webapp/packages/plugin-datasource-commit-mode/src/locales/zh.ts +++ /dev/null @@ -1,6 +0,0 @@ -export default [ - ['plugin_datasource_commit_mode_commit', 'Commit'], - ['plugin_datasource_commit_mode_rollback', 'Rollback'], - ['plugin_datasource_commit_mode_switch_to_auto_commit', 'Switch to auto-commit'], - ['plugin_datasource_commit_mode_switch_to_manual_commit_mode', 'Switch to manual commit'], -]; diff --git a/webapp/packages/plugin-datasource-commit-mode/src/manifest.ts b/webapp/packages/plugin-datasource-commit-mode/src/manifest.ts deleted file mode 100644 index 48e34d418a..0000000000 --- a/webapp/packages/plugin-datasource-commit-mode/src/manifest.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ -import type { PluginManifest } from '@cloudbeaver/core-di'; - -import { CommitModeManagerBootstrap } from './CommitModeManagerBootstrap'; -import { CommitModeManagerService } from './CommitModeManagerService'; -import { LocaleService } from './LocaleService'; - -export const datasourceCommitModePlugin: PluginManifest = { - info: { - name: 'Datasource commit mode plugin', - }, - - providers: [CommitModeManagerBootstrap, LocaleService, CommitModeManagerService], -}; diff --git a/webapp/packages/plugin-datasource-commit-mode/.gitignore b/webapp/packages/plugin-datasource-transaction-manager/.gitignore similarity index 100% rename from webapp/packages/plugin-datasource-commit-mode/.gitignore rename to webapp/packages/plugin-datasource-transaction-manager/.gitignore diff --git a/webapp/packages/plugin-datasource-commit-mode/package.json b/webapp/packages/plugin-datasource-transaction-manager/package.json similarity index 92% rename from webapp/packages/plugin-datasource-commit-mode/package.json rename to webapp/packages/plugin-datasource-transaction-manager/package.json index 4f370943ac..540d14e1a2 100644 --- a/webapp/packages/plugin-datasource-commit-mode/package.json +++ b/webapp/packages/plugin-datasource-transaction-manager/package.json @@ -1,5 +1,5 @@ { - "name": "@cloudbeaver/plugin-datasource-commit-mode", + "name": "@cloudbeaver/plugin-datasource-transaction-manager", "sideEffects": [ "src/**/*.css", "src/**/*.scss", diff --git a/webapp/packages/plugin-datasource-commit-mode/public/icons/commit.png b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit.png similarity index 100% rename from webapp/packages/plugin-datasource-commit-mode/public/icons/commit.png rename to webapp/packages/plugin-datasource-transaction-manager/public/icons/commit.png diff --git a/webapp/packages/plugin-datasource-commit-mode/public/icons/commit_mode_auto.png b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto.png similarity index 100% rename from webapp/packages/plugin-datasource-commit-mode/public/icons/commit_mode_auto.png rename to webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto.png diff --git a/webapp/packages/plugin-datasource-commit-mode/public/icons/commit_mode_manual.png b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual.png similarity index 100% rename from webapp/packages/plugin-datasource-commit-mode/public/icons/commit_mode_manual.png rename to webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual.png diff --git a/webapp/packages/plugin-datasource-commit-mode/public/icons/rollback.png b/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback.png similarity index 100% rename from webapp/packages/plugin-datasource-commit-mode/public/icons/rollback.png rename to webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback.png diff --git a/webapp/packages/plugin-datasource-commit-mode/src/LocaleService.ts b/webapp/packages/plugin-datasource-transaction-manager/src/LocaleService.ts similarity index 100% rename from webapp/packages/plugin-datasource-commit-mode/src/LocaleService.ts rename to webapp/packages/plugin-datasource-transaction-manager/src/LocaleService.ts diff --git a/webapp/packages/plugin-datasource-commit-mode/src/CommitModeManagerBootstrap.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts similarity index 95% rename from webapp/packages/plugin-datasource-commit-mode/src/CommitModeManagerBootstrap.ts rename to webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts index dc7210316d..8e8dbc4740 100644 --- a/webapp/packages/plugin-datasource-commit-mode/src/CommitModeManagerBootstrap.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts @@ -14,7 +14,7 @@ import { ACTION_COMMIT_MODE_TOGGLE } from './actions/ACTION_COMMIT_MODE_TOGGLE'; import { ACTION_ROLLBACK } from './actions/ACTION_ROLLBACK'; @injectable() -export class CommitModeManagerBootstrap extends Bootstrap { +export class TransactionManagerBootstrap extends Bootstrap { constructor(private readonly menuService: MenuService, private readonly actionService: ActionService) { super(); } diff --git a/webapp/packages/plugin-datasource-commit-mode/src/CommitModeManagerService.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts similarity index 88% rename from webapp/packages/plugin-datasource-commit-mode/src/CommitModeManagerService.ts rename to webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts index bb8b5502d2..1ff3d64168 100644 --- a/webapp/packages/plugin-datasource-commit-mode/src/CommitModeManagerService.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts @@ -8,6 +8,6 @@ import { injectable } from '@cloudbeaver/core-di'; @injectable() -export class CommitModeManagerService { +export class TransactionManagerService { constructor() {} } diff --git a/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_COMMIT.ts b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT.ts similarity index 75% rename from webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_COMMIT.ts rename to webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT.ts index 08eea6418a..9bf2484c41 100644 --- a/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_COMMIT.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT.ts @@ -8,7 +8,7 @@ import { createAction } from '@cloudbeaver/core-view'; export const ACTION_COMMIT = createAction('commit', { - label: 'plugin_datasource_commit_mode_commit', - tooltip: 'plugin_datasource_commit_mode_commit', + label: 'plugin_datasource_transaction_manager_commit', + tooltip: 'plugin_datasource_transaction_manager_commit', icon: '/icons/commit.png', }); diff --git a/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts similarity index 71% rename from webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts rename to webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts index 95c6682c22..ab6b8907f8 100644 --- a/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts @@ -8,7 +8,7 @@ import { createAction } from '@cloudbeaver/core-view'; export const ACTION_COMMIT_MODE_TOGGLE = createAction('commit-mode-toggle', { - label: 'plugin_datasource_commit_mode_switch_to_manual_commit_mode', - tooltip: 'plugin_datasource_commit_mode_switch_to_manual_commit_mode', + label: 'plugin_datasource_transaction_manager_commit_mode_switch_to_manual', + tooltip: 'plugin_datasource_transaction_manager_commit_mode_switch_to_manual', icon: '/icons/commit_mode_auto.png', }); diff --git a/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_ROLLBACK.ts b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_ROLLBACK.ts similarity index 75% rename from webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_ROLLBACK.ts rename to webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_ROLLBACK.ts index bfddeaab7e..0d6c26d1c8 100644 --- a/webapp/packages/plugin-datasource-commit-mode/src/actions/ACTION_ROLLBACK.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_ROLLBACK.ts @@ -8,7 +8,7 @@ import { createAction } from '@cloudbeaver/core-view'; export const ACTION_ROLLBACK = createAction('rollback', { - label: 'plugin_datasource_commit_mode_rollback', - tooltip: 'plugin_datasource_commit_mode_rollback', + label: 'plugin_datasource_transaction_manager_rollback', + tooltip: 'plugin_datasource_transaction_manager_rollback', icon: '/icons/rollback.png', }); diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/index.ts b/webapp/packages/plugin-datasource-transaction-manager/src/index.ts new file mode 100644 index 0000000000..08e0384d3c --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/src/index.ts @@ -0,0 +1 @@ +export { datasourceTransactionManagerPlugin } from './manifest'; diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/locales/en.ts b/webapp/packages/plugin-datasource-transaction-manager/src/locales/en.ts new file mode 100644 index 0000000000..8acc6a3a5f --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/src/locales/en.ts @@ -0,0 +1,6 @@ +export default [ + ['plugin_datasource_transaction_manager_commit', 'Commit'], + ['plugin_datasource_transaction_manager_rollback', 'Rollback'], + ['plugin_datasource_transaction_manager_commit_mode_switch_to_auto', 'Switch to auto-commit'], + ['plugin_datasource_transaction_manager_commit_mode_switch_to_manual', 'Switch to manual commit'], +]; diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/locales/it.ts b/webapp/packages/plugin-datasource-transaction-manager/src/locales/it.ts new file mode 100644 index 0000000000..8acc6a3a5f --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/src/locales/it.ts @@ -0,0 +1,6 @@ +export default [ + ['plugin_datasource_transaction_manager_commit', 'Commit'], + ['plugin_datasource_transaction_manager_rollback', 'Rollback'], + ['plugin_datasource_transaction_manager_commit_mode_switch_to_auto', 'Switch to auto-commit'], + ['plugin_datasource_transaction_manager_commit_mode_switch_to_manual', 'Switch to manual commit'], +]; diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts b/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts new file mode 100644 index 0000000000..8acc6a3a5f --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts @@ -0,0 +1,6 @@ +export default [ + ['plugin_datasource_transaction_manager_commit', 'Commit'], + ['plugin_datasource_transaction_manager_rollback', 'Rollback'], + ['plugin_datasource_transaction_manager_commit_mode_switch_to_auto', 'Switch to auto-commit'], + ['plugin_datasource_transaction_manager_commit_mode_switch_to_manual', 'Switch to manual commit'], +]; diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/locales/zh.ts b/webapp/packages/plugin-datasource-transaction-manager/src/locales/zh.ts new file mode 100644 index 0000000000..8acc6a3a5f --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/src/locales/zh.ts @@ -0,0 +1,6 @@ +export default [ + ['plugin_datasource_transaction_manager_commit', 'Commit'], + ['plugin_datasource_transaction_manager_rollback', 'Rollback'], + ['plugin_datasource_transaction_manager_commit_mode_switch_to_auto', 'Switch to auto-commit'], + ['plugin_datasource_transaction_manager_commit_mode_switch_to_manual', 'Switch to manual commit'], +]; diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/manifest.ts b/webapp/packages/plugin-datasource-transaction-manager/src/manifest.ts new file mode 100644 index 0000000000..abe7c1b876 --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/src/manifest.ts @@ -0,0 +1,20 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import type { PluginManifest } from '@cloudbeaver/core-di'; + +import { LocaleService } from './LocaleService'; +import { TransactionManagerBootstrap } from './TransactionManagerBootstrap'; +import { TransactionManagerService } from './TransactionManagerService'; + +export const datasourceTransactionManagerPlugin: PluginManifest = { + info: { + name: 'Datasource transaction manager plugin', + }, + + providers: [TransactionManagerBootstrap, LocaleService, TransactionManagerService], +}; diff --git a/webapp/packages/plugin-datasource-commit-mode/tsconfig.json b/webapp/packages/plugin-datasource-transaction-manager/tsconfig.json similarity index 100% rename from webapp/packages/plugin-datasource-commit-mode/tsconfig.json rename to webapp/packages/plugin-datasource-transaction-manager/tsconfig.json From cb42abfe5367f0062d8230e1ce61a6953bcefdc3 Mon Sep 17 00:00:00 2001 From: Ainur Date: Tue, 5 Mar 2024 17:00:30 +0100 Subject: [PATCH 04/25] CB-4806 add is auto commit property to web context --- .../service/sql/WebSQLContextInfo.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLContextInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLContextInfo.java index 0269549079..9851362478 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLContextInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLContextInfo.java @@ -29,6 +29,7 @@ import org.jkiss.dbeaver.model.DBUtils; import org.jkiss.dbeaver.model.data.DBDAttributeBinding; import org.jkiss.dbeaver.model.exec.*; +import org.jkiss.dbeaver.model.meta.Property; import org.jkiss.dbeaver.model.qm.QMTransactionState; import org.jkiss.dbeaver.model.qm.QMUtils; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; @@ -265,4 +266,18 @@ public void run(DBRProgressMonitor monitor) throws InvocationTargetException, In return getWebSession().createAndRunAsyncTask("Rollback transaction", runnable); } + + @Property + public Boolean isAutoCommit() throws DBWebException { + DBCExecutionContext context = processor.getExecutionContext(); + DBCTransactionManager txnManager = DBUtils.getTransactionManager(context); + if (txnManager == null) { + return null; + } + try { + return txnManager.isAutoCommit(); + } catch (DBException e) { + throw new DBWebException("Error getting auto-commit parameter from context", e); + } + } } From b210c7530a72fa2ba8ac690dabfb8110e9e62dba Mon Sep 17 00:00:00 2001 From: naumov Date: Wed, 6 Mar 2024 14:39:53 +0100 Subject: [PATCH 05/25] CB-1084 add gql queries --- .../ConnectionExecutionContextResource.ts | 7 ++ .../fragments/ExecutionContextInfo.gql | 13 +- .../asyncSqlCommitTransaction.gql | 5 + .../asyncSqlRollbackTransaction.gql | 5 + .../transactions/asyncSqlSetAutoCommit.gql | 5 + .../src/TransactionManagerBootstrap.ts | 55 ++++++++- .../src/TransactionManagerService.ts | 112 +++++++++++++++++- 7 files changed, 189 insertions(+), 13 deletions(-) create mode 100644 webapp/packages/core-sdk/src/queries/transactions/asyncSqlCommitTransaction.gql create mode 100644 webapp/packages/core-sdk/src/queries/transactions/asyncSqlRollbackTransaction.gql create mode 100644 webapp/packages/core-sdk/src/queries/transactions/asyncSqlSetAutoCommit.gql diff --git a/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextResource.ts b/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextResource.ts index a840a75282..d90d4870c8 100644 --- a/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextResource.ts +++ b/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextResource.ts @@ -134,6 +134,13 @@ export class ConnectionExecutionContextResource extends CachedMapResource context.connectionId === connection.connectionId && context.projectId === connection.projectId); + const key = resourceKeyList(contexts.map(context => context.id)); + + await this.refresh(key); + } + protected async loader(originalKey: ResourceKey): Promise> { const contextsList: IConnectionExecutionContextInfo[] = []; let projectId: string | undefined; diff --git a/webapp/packages/core-sdk/src/queries/fragments/ExecutionContextInfo.gql b/webapp/packages/core-sdk/src/queries/fragments/ExecutionContextInfo.gql index eb1925b4d8..9f23894015 100644 --- a/webapp/packages/core-sdk/src/queries/fragments/ExecutionContextInfo.gql +++ b/webapp/packages/core-sdk/src/queries/fragments/ExecutionContextInfo.gql @@ -1,7 +1,8 @@ fragment ExecutionContextInfo on SQLContextInfo { - id - projectId - connectionId - defaultCatalog - defaultSchema -} \ No newline at end of file + id + projectId + connectionId + autoCommit + defaultCatalog + defaultSchema +} diff --git a/webapp/packages/core-sdk/src/queries/transactions/asyncSqlCommitTransaction.gql b/webapp/packages/core-sdk/src/queries/transactions/asyncSqlCommitTransaction.gql new file mode 100644 index 0000000000..6fc4fae90e --- /dev/null +++ b/webapp/packages/core-sdk/src/queries/transactions/asyncSqlCommitTransaction.gql @@ -0,0 +1,5 @@ +mutation asyncSqlCommitTransaction($projectId: ID, $connectionId: ID!, $contextId: ID!) { + taskInfo: asyncSqlCommitTransaction(projectId: $projectId, connectionId: $connectionId, contextId: $contextId) { + ...AsyncTaskInfo + } +} diff --git a/webapp/packages/core-sdk/src/queries/transactions/asyncSqlRollbackTransaction.gql b/webapp/packages/core-sdk/src/queries/transactions/asyncSqlRollbackTransaction.gql new file mode 100644 index 0000000000..d21d537ee2 --- /dev/null +++ b/webapp/packages/core-sdk/src/queries/transactions/asyncSqlRollbackTransaction.gql @@ -0,0 +1,5 @@ +mutation asyncSqlRollbackTransaction($projectId: ID, $connectionId: ID!, $contextId: ID!) { + taskInfo: asyncSqlRollbackTransaction(projectId: $projectId, connectionId: $connectionId, contextId: $contextId) { + ...AsyncTaskInfo + } +} diff --git a/webapp/packages/core-sdk/src/queries/transactions/asyncSqlSetAutoCommit.gql b/webapp/packages/core-sdk/src/queries/transactions/asyncSqlSetAutoCommit.gql new file mode 100644 index 0000000000..7a1f75cc3d --- /dev/null +++ b/webapp/packages/core-sdk/src/queries/transactions/asyncSqlSetAutoCommit.gql @@ -0,0 +1,5 @@ +mutation asyncSqlSetAutoCommit($projectId: ID, $connectionId: ID!, $contextId: ID!, $autoCommit: Boolean!) { + taskInfo: asyncSqlSetAutoCommit(projectId: $projectId, connectionId: $connectionId, contextId: $contextId, autoCommit: $autoCommit) { + ...AsyncTaskInfo + } +} diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts index 8e8dbc4740..1a6d6a2dba 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts @@ -7,30 +7,73 @@ */ import { Bootstrap, injectable } from '@cloudbeaver/core-di'; import { ActionService, MenuService } from '@cloudbeaver/core-view'; +import { ConnectionSchemaManagerService } from '@cloudbeaver/plugin-datasource-context-switch'; import { MENU_APP_ACTIONS } from '@cloudbeaver/plugin-top-app-bar'; import { ACTION_COMMIT } from './actions/ACTION_COMMIT'; import { ACTION_COMMIT_MODE_TOGGLE } from './actions/ACTION_COMMIT_MODE_TOGGLE'; import { ACTION_ROLLBACK } from './actions/ACTION_ROLLBACK'; +import { TransactionManagerService } from './TransactionManagerService'; @injectable() export class TransactionManagerBootstrap extends Bootstrap { - constructor(private readonly menuService: MenuService, private readonly actionService: ActionService) { + constructor( + private readonly menuService: MenuService, + private readonly actionService: ActionService, + private readonly connectionSchemaManagerService: ConnectionSchemaManagerService, + private readonly transactionManagerService: TransactionManagerService, + ) { super(); } register() { this.menuService.addCreator({ menus: [MENU_APP_ACTIONS], - getItems: (context, items) => [...items, ACTION_COMMIT, ACTION_ROLLBACK, ACTION_COMMIT_MODE_TOGGLE], + isApplicable: () => !!this.connectionSchemaManagerService.currentConnection?.connected && !!this.transactionManagerService.currentContext, + getItems: (_, items) => [...items, ACTION_COMMIT, ACTION_ROLLBACK, ACTION_COMMIT_MODE_TOGGLE], }); this.actionService.addHandler({ id: 'commit-mode-base', - isActionApplicable: (context, action) => [ACTION_COMMIT, ACTION_ROLLBACK, ACTION_COMMIT_MODE_TOGGLE].includes(action), - isLabelVisible: (context, action) => action === ACTION_COMMIT || action === ACTION_ROLLBACK, - isHidden: (context, action) => false, - handler: (context, action) => {}, + isActionApplicable: (_, action) => [ACTION_COMMIT, ACTION_ROLLBACK, ACTION_COMMIT_MODE_TOGGLE].includes(action), + isLabelVisible: (_, action) => action === ACTION_COMMIT || action === ACTION_ROLLBACK, + getActionInfo: (_, action) => { + if (action === ACTION_COMMIT_MODE_TOGGLE) { + const auto = this.transactionManagerService.autoCommitMode; + const icon = `/icons/commit_mode_${auto ? 'auto' : 'manual'}.png`; + const label = `plugin_datasource_transaction_manager_commit_mode_switch_to_${auto ? 'manual' : 'auto'}`; + + return { ...action.info, icon, label, tooltip: label }; + } + + return action.info; + }, + isHidden: (context, action) => { + if (action === ACTION_COMMIT || action === ACTION_ROLLBACK) { + return this.transactionManagerService.autoCommitMode; + } + + return false; + }, + handler: async (_, action) => { + const context = this.transactionManagerService.currentContext; + + if (!context) { + return; + } + + switch (action) { + case ACTION_COMMIT: + await this.transactionManagerService.commit(context.connectionId, context.id); + break; + case ACTION_ROLLBACK: + await this.transactionManagerService.rollback(context.connectionId, context.id); + break; + case ACTION_COMMIT_MODE_TOGGLE: + await this.transactionManagerService.setAutoCommit(context.connectionId, context.id, !context.autoCommit); + break; + } + }, }); } diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts index 1ff3d64168..f09764558c 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts @@ -5,9 +5,119 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ +import { computed, makeAutoObservable } from 'mobx'; + +import { ConnectionExecutionContextResource, createConnectionParam } from '@cloudbeaver/core-connections'; import { injectable } from '@cloudbeaver/core-di'; +import { NotificationService } from '@cloudbeaver/core-events'; +import { AsyncTaskInfoService, GraphQLService } from '@cloudbeaver/core-sdk'; +import { TableViewerStorageService } from '@cloudbeaver/plugin-data-viewer'; +import { ConnectionSchemaManagerService } from '@cloudbeaver/plugin-datasource-context-switch'; +import { NavigationTabsService } from '@cloudbeaver/plugin-navigation-tabs'; +import { SqlDataSourceService } from '@cloudbeaver/plugin-sql-editor'; + +const DEFAULT_AUTO_COMMIT = true; @injectable() export class TransactionManagerService { - constructor() {} + get currentContext() { + const tab = this.navigationTabsService.currentTab; + + if (tab) { + const model = this.tableViewerStorageService.get(tab.handlerState.tableId); + + if (model) { + return model.source.executionContext?.context; + } + + const source = this.sqlDataSourceService.get(tab.handlerState.editorId); + + if (source) { + return source.executionContext; + } + } + + return null; + } + + get autoCommitMode() { + const context = this.currentContext; + + if (context) { + return context.autoCommit ?? DEFAULT_AUTO_COMMIT; + } + + return DEFAULT_AUTO_COMMIT; + } + + constructor( + private readonly notificationService: NotificationService, + private readonly graphQLService: GraphQLService, + private readonly asyncTaskInfoService: AsyncTaskInfoService, + private readonly navigationTabsService: NavigationTabsService, + private readonly tableViewerStorageService: TableViewerStorageService, + private readonly connectionExecutionContextResource: ConnectionExecutionContextResource, + private readonly connectionSchemaManagerService: ConnectionSchemaManagerService, + private readonly sqlDataSourceService: SqlDataSourceService, + ) { + makeAutoObservable(this, { + currentContext: computed, + autoCommitMode: computed, + }); + } + + async setAutoCommit(connectionId: string, contextId: string, autoCommit: boolean) { + const task = this.asyncTaskInfoService.create(async () => { + const { taskInfo } = await this.graphQLService.sdk.asyncSqlSetAutoCommit({ + connectionId, + contextId, + autoCommit, + }); + + return taskInfo; + }); + + await this.asyncTaskInfoService.run(task); + + if (this.currentContext) { + const param = createConnectionParam(this.currentContext.projectId, this.currentContext.connectionId); + await this.connectionExecutionContextResource.refreshConnectionContexts(param); + } + } + + async commit(connectionId: string, contextId: string) { + const task = this.asyncTaskInfoService.create(async () => { + const { taskInfo } = await this.graphQLService.sdk.asyncSqlCommitTransaction({ + connectionId, + contextId, + }); + + return taskInfo; + }); + + const result = await this.asyncTaskInfoService.run(task); + const connection = this.connectionSchemaManagerService.currentConnection; + + if (result.taskResult) { + this.notificationService.logInfo({ title: connection?.name ?? result.name ?? '', message: result.taskResult }); + } + } + + async rollback(connectionId: string, contextId: string) { + const task = this.asyncTaskInfoService.create(async () => { + const { taskInfo } = await this.graphQLService.sdk.asyncSqlRollbackTransaction({ + connectionId, + contextId, + }); + + return taskInfo; + }); + + const result = await this.asyncTaskInfoService.run(task); + const connection = this.connectionSchemaManagerService.currentConnection; + + if (result.taskResult) { + this.notificationService.logInfo({ title: connection?.name ?? result.name ?? '', message: result.taskResult }); + } + } } From fa094817addfc7d6089a092960a41064db0a4baa Mon Sep 17 00:00:00 2001 From: naumov Date: Wed, 6 Mar 2024 15:22:35 +0100 Subject: [PATCH 06/25] CB-1084 add loaders --- .../src/TransactionManagerBootstrap.ts | 36 +++++++++++++++++- .../src/TransactionManagerService.ts | 37 ++++++++++++++++++- 2 files changed, 71 insertions(+), 2 deletions(-) diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts index 1a6d6a2dba..588f8438aa 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts @@ -48,7 +48,41 @@ export class TransactionManagerBootstrap extends Bootstrap { return action.info; }, - isHidden: (context, action) => { + isDisabled: (_, action) => { + const context = this.transactionManagerService.currentContext; + + if (!context) { + return false; + } + + const state = this.transactionManagerService.processState.get(context.connectionId); + + if (!state) { + return false; + } + + return state.mode || state.commit || state.rollback; + }, + isLoading: (_, action) => { + const context = this.transactionManagerService.currentContext; + + if (!context) { + return false; + } + + const state = this.transactionManagerService.processState.get(context.connectionId); + + if (!state) { + return false; + } + + if (action === ACTION_COMMIT_MODE_TOGGLE) { + return state.mode; + } + + return action === ACTION_COMMIT ? state.commit : state.rollback; + }, + isHidden: (_, action) => { if (action === ACTION_COMMIT || action === ACTION_ROLLBACK) { return this.transactionManagerService.autoCommitMode; } diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts index f09764558c..81006ff6d8 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts @@ -5,7 +5,7 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ -import { computed, makeAutoObservable } from 'mobx'; +import { computed, makeAutoObservable, observable } from 'mobx'; import { ConnectionExecutionContextResource, createConnectionParam } from '@cloudbeaver/core-connections'; import { injectable } from '@cloudbeaver/core-di'; @@ -16,6 +16,17 @@ import { ConnectionSchemaManagerService } from '@cloudbeaver/plugin-datasource-c import { NavigationTabsService } from '@cloudbeaver/plugin-navigation-tabs'; import { SqlDataSourceService } from '@cloudbeaver/plugin-sql-editor'; +type ConnectionId = string; + +interface IProcessData { + mode: boolean; + commit: boolean; + rollback: boolean; +} + +type ProcessType = keyof IProcessData; + +const DEFAULT_PROCESS_DATA_GETTER: () => IProcessData = () => ({ mode: false, commit: false, rollback: false }); const DEFAULT_AUTO_COMMIT = true; @injectable() @@ -50,6 +61,8 @@ export class TransactionManagerService { return DEFAULT_AUTO_COMMIT; } + readonly processState: Map; + constructor( private readonly notificationService: NotificationService, private readonly graphQLService: GraphQLService, @@ -60,13 +73,18 @@ export class TransactionManagerService { private readonly connectionSchemaManagerService: ConnectionSchemaManagerService, private readonly sqlDataSourceService: SqlDataSourceService, ) { + this.processState = new Map(); + makeAutoObservable(this, { currentContext: computed, autoCommitMode: computed, + processState: observable, }); } async setAutoCommit(connectionId: string, contextId: string, autoCommit: boolean) { + this.changeProcessStatus(connectionId, 'mode', true); + const task = this.asyncTaskInfoService.create(async () => { const { taskInfo } = await this.graphQLService.sdk.asyncSqlSetAutoCommit({ connectionId, @@ -83,9 +101,13 @@ export class TransactionManagerService { const param = createConnectionParam(this.currentContext.projectId, this.currentContext.connectionId); await this.connectionExecutionContextResource.refreshConnectionContexts(param); } + + this.changeProcessStatus(connectionId, 'mode', false); } async commit(connectionId: string, contextId: string) { + this.changeProcessStatus(connectionId, 'commit', true); + const task = this.asyncTaskInfoService.create(async () => { const { taskInfo } = await this.graphQLService.sdk.asyncSqlCommitTransaction({ connectionId, @@ -101,9 +123,13 @@ export class TransactionManagerService { if (result.taskResult) { this.notificationService.logInfo({ title: connection?.name ?? result.name ?? '', message: result.taskResult }); } + + this.changeProcessStatus(connectionId, 'commit', false); } async rollback(connectionId: string, contextId: string) { + this.changeProcessStatus(connectionId, 'rollback', true); + const task = this.asyncTaskInfoService.create(async () => { const { taskInfo } = await this.graphQLService.sdk.asyncSqlRollbackTransaction({ connectionId, @@ -119,5 +145,14 @@ export class TransactionManagerService { if (result.taskResult) { this.notificationService.logInfo({ title: connection?.name ?? result.name ?? '', message: result.taskResult }); } + + this.changeProcessStatus(connectionId, 'rollback', false); + } + + private changeProcessStatus(connectionId: string, type: ProcessType, value: boolean) { + const currentState = this.processState.get(connectionId) || DEFAULT_PROCESS_DATA_GETTER(); + + currentState[type] = value; + this.processState.set(connectionId, currentState); } } From 9ef63b06791c0f70f4a1fd4f4b716eb6fd7af687 Mon Sep 17 00:00:00 2001 From: Ainur Date: Wed, 6 Mar 2024 15:31:32 +0100 Subject: [PATCH 07/25] CB-4806 transactions for update results --- .../service/sql/WebSQLProcessor.java | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java index 3b98256a50..4d1302d141 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java @@ -358,9 +358,15 @@ public WebSQLExecuteInfo updateResultsDataBatch( try (DBCSession session = executionContext.openSession(monitor, DBCExecutionPurpose.USER, "Update data in container")) { DBCTransactionManager txnManager = DBUtils.getTransactionManager(executionContext); boolean revertToAutoCommit = false; - if (txnManager != null && txnManager.isSupportsTransactions() && txnManager.isAutoCommit()) { - txnManager.setAutoCommit(monitor, false); - revertToAutoCommit = true; + boolean isAutoCommitEnabled = true; + DBCSavepoint savepoint = null; + if (txnManager != null) { + isAutoCommitEnabled = txnManager.isAutoCommit(); + if (txnManager.isSupportsTransactions() && isAutoCommitEnabled) { + txnManager.setAutoCommit(monitor, false); + savepoint = txnManager.setSavepoint(monitor, null); + revertToAutoCommit = true; + } } try { Map options = Collections.emptyMap(); @@ -375,17 +381,27 @@ public WebSQLExecuteInfo updateResultsDataBatch( newResultSetRows.add(new WebSQLQueryResultSetRow(rowValues, null)); } - if (txnManager != null && txnManager.isSupportsTransactions()) { + if (txnManager != null && txnManager.isSupportsTransactions() && isAutoCommitEnabled) { txnManager.commit(session); } } catch (Exception e) { if (txnManager != null && txnManager.isSupportsTransactions()) { - txnManager.rollback(session, null); + txnManager.rollback(session, savepoint); } throw new DBCException("Error persisting data changes", e); } finally { - if (revertToAutoCommit) { - txnManager.setAutoCommit(monitor, true); + if (txnManager != null) { + if (revertToAutoCommit) { + txnManager.setAutoCommit(monitor, true); + } + try { + if (savepoint != null) { + txnManager.releaseSavepoint(monitor, savepoint); + } + } catch (Throwable e) { + // Maybe savepoints not supported + log.debug("Can't release savepoint", e); + } } } } From a8e6696c0c30ca10e2005b34cc3650cd217bbd0b Mon Sep 17 00:00:00 2001 From: Ainur Date: Wed, 6 Mar 2024 17:36:16 +0100 Subject: [PATCH 08/25] CB-4806 fix text --- .../src/io/cloudbeaver/service/sql/WebSQLContextInfo.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLContextInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLContextInfo.java index 9851362478..4856ed809b 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLContextInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLContextInfo.java @@ -222,9 +222,7 @@ public void run(DBRProgressMonitor monitor) throws InvocationTargetException, In } result = """ Transaction has been committed - Query count: %s - Duration: %s """.formatted( txnInfo.getUpdateCount(), @@ -252,9 +250,7 @@ public void run(DBRProgressMonitor monitor) throws InvocationTargetException, In } result = """ Transaction has been rolled back - Query count: %s - Duration: %s """.formatted( txnInfo.getUpdateCount(), From 2e32dd60f00d8f961f8f79b7db2bf59f9bcf229f Mon Sep 17 00:00:00 2001 From: naumov Date: Thu, 7 Mar 2024 15:12:28 +0100 Subject: [PATCH 09/25] CB-1084 pass execution context via extensions --- .../extensions/IExecutionContextProvider.ts | 22 ++++ webapp/packages/core-connections/src/index.ts | 1 + .../ConnectionSchemaManagerService.ts | 14 +++ .../public/icons/commit.png | Bin 827 -> 0 bytes .../public/icons/commit.svg | 13 +++ .../public/icons/commit_mode_auto.png | Bin 650 -> 0 bytes .../public/icons/commit_mode_auto.svg | 20 ++++ .../public/icons/commit_mode_manual.png | Bin 1024 -> 0 bytes .../public/icons/commit_mode_manual.svg | 20 ++++ .../public/icons/rollback.png | Bin 805 -> 0 bytes .../public/icons/rollback.svg | 13 +++ .../src/ITransactionExecutionContext.ts | 19 ++++ .../src/TransactionExecutionContext.ts | 70 +++++++++++++ .../src/TransactionManagerBootstrap.ts | 30 +----- .../src/TransactionManagerService.ts | 97 ++++++------------ .../src/actions/ACTION_COMMIT.ts | 2 +- .../src/actions/ACTION_COMMIT_MODE_TOGGLE.ts | 2 +- .../src/actions/ACTION_ROLLBACK.ts | 2 +- .../src/SqlEditorTabService.ts | 7 ++ 19 files changed, 234 insertions(+), 98 deletions(-) create mode 100644 webapp/packages/core-connections/src/extensions/IExecutionContextProvider.ts delete mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/commit.png create mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/commit.svg delete mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto.png create mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto.svg delete mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual.png create mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual.svg delete mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback.png create mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback.svg create mode 100644 webapp/packages/plugin-datasource-transaction-manager/src/ITransactionExecutionContext.ts create mode 100644 webapp/packages/plugin-datasource-transaction-manager/src/TransactionExecutionContext.ts diff --git a/webapp/packages/core-connections/src/extensions/IExecutionContextProvider.ts b/webapp/packages/core-connections/src/extensions/IExecutionContextProvider.ts new file mode 100644 index 0000000000..599597d0f9 --- /dev/null +++ b/webapp/packages/core-connections/src/extensions/IExecutionContextProvider.ts @@ -0,0 +1,22 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { createExtension, IExtension, isExtension } from '@cloudbeaver/core-extensions'; + +import type { IConnectionExecutionContextInfo } from '../ConnectionExecutionContext/ConnectionExecutionContextResource'; + +const EXECUTION_CONTEXT_PROVIDER_SYMBOL = Symbol('@extension/ExecutionContextProvider'); + +export type IExecutionContextProvider = (context: T) => IConnectionExecutionContextInfo | undefined; + +export function executionContextProvider(provider: IExecutionContextProvider) { + return createExtension(provider, EXECUTION_CONTEXT_PROVIDER_SYMBOL); +} + +export function isExecutionContextProvider(obj: IExtension): obj is IExecutionContextProvider & IExtension { + return isExtension(obj, EXECUTION_CONTEXT_PROVIDER_SYMBOL); +} diff --git a/webapp/packages/core-connections/src/index.ts b/webapp/packages/core-connections/src/index.ts index ede58b7a42..202ebbf4a9 100644 --- a/webapp/packages/core-connections/src/index.ts +++ b/webapp/packages/core-connections/src/index.ts @@ -9,6 +9,7 @@ export * from './extensions/IObjectCatalogProvider'; export * from './extensions/IObjectCatalogSetter'; export * from './extensions/IObjectSchemaProvider'; export * from './extensions/IObjectSchemaSetter'; +export * from './extensions/IExecutionContextProvider'; export * from './NavTree/ConnectionNavNodeService'; export * from './NavTree/NavNodeExtensionsService'; export * from './NavTree/getConnectionFolderIdFromNodeId'; diff --git a/webapp/packages/plugin-datasource-context-switch/src/ConnectionSchemaManager/ConnectionSchemaManagerService.ts b/webapp/packages/plugin-datasource-context-switch/src/ConnectionSchemaManager/ConnectionSchemaManagerService.ts index 2f0d71d4c1..e61ff1e75f 100644 --- a/webapp/packages/plugin-datasource-context-switch/src/ConnectionSchemaManager/ConnectionSchemaManagerService.ts +++ b/webapp/packages/plugin-datasource-context-switch/src/ConnectionSchemaManager/ConnectionSchemaManagerService.ts @@ -15,12 +15,14 @@ import { IConnectionInfoParams, IConnectionProvider, IConnectionSetter, + IExecutionContextProvider, IObjectCatalogProvider, IObjectCatalogSetter, IObjectSchemaProvider, IObjectSchemaSetter, isConnectionProvider, isConnectionSetter, + isExecutionContextProvider, isObjectCatalogProvider, isObjectCatalogSetter, isObjectSchemaProvider, @@ -58,6 +60,7 @@ interface IActiveItem { getCurrentConnectionId?: IConnectionProvider; getCurrentSchemaId?: IObjectSchemaProvider; getCurrentCatalogId?: IObjectCatalogProvider; + getCurrentExecutionContext?: IExecutionContextProvider; changeConnectionId?: IConnectionSetter; changeProjectId?: IProjectSetter; changeCatalogId?: IObjectCatalogSetter; @@ -121,6 +124,14 @@ export class ConnectionSchemaManagerService { return this.activeObjectCatalogId; } + get activeExecutionContext() { + if (!this.activeItem?.getCurrentExecutionContext) { + return; + } + + return this.activeItem.getCurrentExecutionContext(this.activeItem.context); + } + get currentObjectSchemaId(): string | undefined { if (this.pendingSchemaId !== null) { return this.pendingSchemaId; @@ -442,6 +453,9 @@ export class ConnectionSchemaManagerService { .on(isObjectSchemaProvider, extension => { item.getCurrentSchemaId = extension; }) + .on(isExecutionContextProvider, extension => { + item.getCurrentExecutionContext = extension; + }) .on(isProjectSetter, extension => { item.changeProjectId = extension; diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit.png b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit.png deleted file mode 100644 index f0d157102af79583c78a66faab2f597ff0795b7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 827 zcmV-B1H}A^P)Px%^+`lQR9Fe^S4~J%Q4~JszL__UKb50KC>4@Sg>AAK6(owtO=egy)~;Q<7FxEA zHsPieN&+b=B8rJZ3|F=3XA`M~{S6vwB@;tBjuVWo=#GytXfLcUar2v_@CT<47X5n&hyr}U&5a2|_NXmxe; zUlDOLQMCg5ItFGqI02lr=SX9j98>jk^U*yFK2OMvR>C42#GBh?Y5d6E(i&B6ka_ZE zVk{b?<-&ZS5|F7KY72y8HmQ+ztY`xKWilnP;t7Z(+@0^-devQ(1UN8Knpkg|Omu}B zy;#=h8d6IHrvT7~R1Lv~!1lB9C z<`u}=HcYH?^a0{sB9T|l&G|mR5~X1!ygh1*j3#UnT-Fjm#J}tl+}2iIe2ekyUXwJE z4k)cAD=lDvKO`V^7ivmw>VRwU7V+jQfS?eNj-Ib|e5RCQ^P^@fR4&4a3km~;wA7M3i_k`3`3)o3NDVG&@@nAiD z%7!>N;GBh6#|40(gpi+1kL-eQ`}o6pk17|;@+dxS-HHM38&)FmFHeE3VC2$)b|p35 znX0qjc9&GXU~Q5p#O`~%p7_n%Tm=ZeOa)3ezkH~3zs+JBW?RGxFfDUiQ)>VT`1JsD z<$T$0&Hbp=IqXF_2uNhfrUWBFRb?sxw&->J%Qx+)cyOXu1xd#&3czkPBp8nUPUj?a z2xN=kmrD}~Abe-5bXy=4b@ld77>tL!O}D)8C7Zp z23lM<+#Q1>6leo`4E>z)13wr+CnJ7qu7!qXBQP79t~m9$(f2>(U^Gy{b=;m)H32?( z+fwzM5&kTBIP=^y?`K~RvwiNIj|6t53&3{6Ft-QjgMVeW>yes@!j=F4002ovPDHLk FV1mDcc+da< diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit.svg new file mode 100644 index 0000000000..d120e7a133 --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit.svg @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto.png b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto.png deleted file mode 100644 index 43b5d257f25fab92d701c5e8aba8ec16d462a295..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 650 zcmV;50(Jd~P)Px%L`g(JR9Fe^R=;Z$K@@&(cW*bwU-1kfXl18ZMDI>P3-J%Ivd}&VBIx0jDJ+A9 zVA2E?uF=NALjM6pK_ciK!6INIA_NN&(QI{TJYHo3$By=DCP4N(A<%F@zoxB%5-X z0Fgu{%%!Obb4N4D#$5Lm5uMAV03D~+X`Wch=7!~I2Znu-=bxWj8e2nknPc19_t*vB z3lv@C+@Af_hf(qeEICtbwt^MQ@CdLAMCz*s8?(@P{W%YR&TL(y~G$+E*7 z1mX|e0U-z9emu92#z*k>#?&Xh&av#G!*F8(^#`4C=s}ZWzZR#t>gV5N7N(E!ugwtGzl)SBZVF4vFA#ZUDx{l)u kDf>Sm8;^vMHRh$jUv;j#B5zr!4FCWD07*qoM6N<$g0)pGHUIzs diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto.svg new file mode 100644 index 0000000000..34f2bfaa11 --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual.png b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual.png deleted file mode 100644 index 9bfc23c42d30a38b385e8c491aef01088bd9a035..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1024 zcmV+b1poVqP)Px&x=BPqR9Fe!R$XWmR}{YI&g{nQCMFoPsT6A^3L>FRHkL*UuGDI+4?@A!C-Dyi zL1abn!3Tdp3Vkq?B8cFF&=)HrXz4>=8d5B6lEEs``fsA~Cy9T{W;Z*tckc1bWXH^o zv%4mB5FD7j=l7m(&bjxTW$Yb4FxB|64(${}Oiad~E6UQIT`hmPeYl%>7qmL%pooGo zFpB(vg(xd_R_R9|1L@X-M0E2OJ>?R3H?sIxNAIr;*&2%muB^mrv$Hnbp!~6EuAVr3 zH8hfma4#Jw04C*LWcU^5e3?Xfn81Chs?cr<{E<@eIg7Grux9{RmcB5}0H|CnOY5kV z+@!qQw3Vr;p8?Ce!h;dqpz3w%oW`ci=>)8DnJ;(fKr;XtI449Z)&KC~QYWBy4KxFk z>J*jWDIm*x13P@60H_38B03LetK#EeY;feDq2qNKqZBnf|DA^C!L_CUpkdk7`YMoh2CHI)dFyU%aCy89QF; z6Hw3nENK>GQqPx>O_!gY4WR9amZVL$(y&yDjo=o^_XEN=R!~F7&uo2RsM4VMA>MKE zm(FC1?>(o%e4m=o4I0YX;(aGLy9D&_CP#C;YC>Fw0>DU!U&|Wi!f`8pNZZ}Izl=v& z)p!XC!9%LjS2Im{E=^E z@yzIxmbvxuoFN~d*9L8A^XzEX_utN&-&h-Nwge*?F}(J~hZQb9gG8GQ zwl*mc!(Q1N@xU7V>?U;$tqp$L*4+5_y|ji>7Vd)Iwv6=*rbo|SeiFB|0PGG{<3T^m zNdu^@QtG~*Umx?^%#r1U%pCZA;PE&Q21i)my}i{sw68rC0ceA1V^&SL)GT>zLrZY% z!UNq9a*3@3*wdYC?e#SzVG#gfnoLL>%}e>JZFb#y5vRA5e_1(o$}_#m)}P856#?iU z&cx}p>}$$7y@`(Mex3diZLMTm06;C5VUwS+qQG~OsW<&}rDR|tM(gWtml{BBKO2Cm us>@Ajt^&lOSwMaKzwTYJKiv-R9sLp_DsR + + + + + + + + + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback.png b/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback.png deleted file mode 100644 index 23a4b52a616c41e9c441992b88506ca03b28b103..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 805 zcmV+=1KRwFP)Px%-$_J4R9Fe^S6@g|Q5gTuuDVp5gcKA>>K1KC1>2mupn8ZP5PB)Fhu*9gdnkJ- zdJd|W7DbS~)r&!ISr9&i7%X(VkxH0t$xNXFty$^RyK_(9sji-LnO?)|_TqtYzQ5=9 zJKy>4?zsR39z?_sbjB;m9Jvd?PA~>8(f2(^B z^Xu5+LT|&p;c9XHT(VSwU?e{C4}69YGMFo2RU2c~44~GCSxY4(0)bm`%m+a5zWBw! zVPm1S&X|7%W3P+xRwSe&5EJc^t&U^E3Gj`qMj|f+3=;an!b5Xq^G1LJV{cWM2^5(P z>(QMhjxLQt%)ExKv*&mYPP3iswi1Y*_mAV6{3ne-Bu*uRpyc%k1l%QYlfY&L3SI$Q zAH${AHVe#g2~9f~=vlKXF9g&M|9vyCp%?rJY$q^rs=0Ku$$i||q19~b5hNNs^|Rxj zpWy3vG8uNOA~;hB^Y|*$YE8|9g%OcQlBJ2t6i6%eVMj+U& z&LQCGkx)%9f*kb@jJL@I{%WI*HLdu1?xLD@6D=ogZ$jTds?%9U&gKH=w!QtS$2h&g z+wY%7wVeP5sqIar`MmNV(|8@3D^VM^@?N|(*akhkg=$?TVsSrNkN?(96hiuN+x`!(*zN-U3HM2%uunwKrs z5`K8l;)>GkuiNUs8POj?buE<9ZbKJm-1R(e^0GIUy2I^q1r((nD1C+($em)+YBD}r z%HogAIgGhs#3`<=ujtQo(9rqJ_s@W2GOp532YQBP4WCp2ZansAu>517B@oFO600000NkvXXu0mjf$_{;x diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback.svg new file mode 100644 index 0000000000..1d695d1074 --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback.svg @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/ITransactionExecutionContext.ts b/webapp/packages/plugin-datasource-transaction-manager/src/ITransactionExecutionContext.ts new file mode 100644 index 0000000000..92f717d28d --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/src/ITransactionExecutionContext.ts @@ -0,0 +1,19 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import type { IConnectionExecutionContextInfo } from '@cloudbeaver/core-connections'; +import type { ITask } from '@cloudbeaver/core-executor'; + +export interface ITransactionExecutionContext { + readonly context: IConnectionExecutionContextInfo | undefined; + readonly executing: boolean; + readonly cancellable: boolean; + + run: (task: () => Promise, cancel?: () => Promise | void, end?: () => Promise | void) => ITask; + cancel: () => Promise; + destroy: () => Promise; +} diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionExecutionContext.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionExecutionContext.ts new file mode 100644 index 0000000000..0a3045f8f2 --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionExecutionContext.ts @@ -0,0 +1,70 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +import { computed, makeObservable, observable } from 'mobx'; + +import type { ConnectionExecutionContextResource, IConnectionExecutionContextInfo } from '@cloudbeaver/core-connections'; +import type { ITask, TaskScheduler } from '@cloudbeaver/core-executor'; + +import type { ITransactionExecutionContext } from './ITransactionExecutionContext'; + +export class TransactionExecutionContext implements ITransactionExecutionContext { + get context(): IConnectionExecutionContextInfo | undefined { + return this.connectionExecutionContextResource.get(this.contextId); + } + + get executing(): boolean { + return this.scheduler.isExecuting(this.contextId); + } + + get cancellable(): boolean { + return this.currentTask?.cancellable || false; + } + + private currentTask: ITask | null; + + constructor( + private readonly scheduler: TaskScheduler, + private readonly connectionExecutionContextResource: ConnectionExecutionContextResource, + private readonly contextId: string, + ) { + this.currentTask = null; + makeObservable(this, { + currentTask: observable.ref, + context: computed, + executing: computed, + cancellable: computed, + }); + } + + run(task: () => Promise, cancel?: () => Promise | void, end?: () => Promise | void): ITask { + if (!this.context) { + throw new Error('Execution Context not found'); + } + + this.currentTask = this.scheduler + .schedule(this.contextId, task, { cancel }) + .finally(end) + .finally(() => { + this.currentTask = null; + }); + + return this.currentTask; + } + + async cancel(): Promise { + await this.scheduler.cancel(this.contextId); + } + + async destroy(): Promise { + if (!this.context) { + return; + } + + await this.cancel(); + } +} diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts index 588f8438aa..fb2716317d 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts @@ -40,7 +40,7 @@ export class TransactionManagerBootstrap extends Bootstrap { getActionInfo: (_, action) => { if (action === ACTION_COMMIT_MODE_TOGGLE) { const auto = this.transactionManagerService.autoCommitMode; - const icon = `/icons/commit_mode_${auto ? 'auto' : 'manual'}.png`; + const icon = `/icons/commit_mode_${auto ? 'auto' : 'manual'}.svg`; const label = `plugin_datasource_transaction_manager_commit_mode_switch_to_${auto ? 'manual' : 'auto'}`; return { ...action.info, icon, label, tooltip: label }; @@ -55,32 +55,8 @@ export class TransactionManagerBootstrap extends Bootstrap { return false; } - const state = this.transactionManagerService.processState.get(context.connectionId); - - if (!state) { - return false; - } - - return state.mode || state.commit || state.rollback; - }, - isLoading: (_, action) => { - const context = this.transactionManagerService.currentContext; - - if (!context) { - return false; - } - - const state = this.transactionManagerService.processState.get(context.connectionId); - - if (!state) { - return false; - } - - if (action === ACTION_COMMIT_MODE_TOGGLE) { - return state.mode; - } - - return action === ACTION_COMMIT ? state.commit : state.rollback; + const transaction = this.transactionManagerService.transactions.get(context.id); + return transaction.executing; }, isHidden: (_, action) => { if (action === ACTION_COMMIT || action === ACTION_ROLLBACK) { diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts index 81006ff6d8..8261265165 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts @@ -5,50 +5,24 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ -import { computed, makeAutoObservable, observable } from 'mobx'; +import { computed, makeAutoObservable } from 'mobx'; -import { ConnectionExecutionContextResource, createConnectionParam } from '@cloudbeaver/core-connections'; +import { ConnectionExecutionContextResource } from '@cloudbeaver/core-connections'; import { injectable } from '@cloudbeaver/core-di'; import { NotificationService } from '@cloudbeaver/core-events'; +import { TaskScheduler } from '@cloudbeaver/core-executor'; import { AsyncTaskInfoService, GraphQLService } from '@cloudbeaver/core-sdk'; -import { TableViewerStorageService } from '@cloudbeaver/plugin-data-viewer'; +import { MetadataMap } from '@cloudbeaver/core-utils'; import { ConnectionSchemaManagerService } from '@cloudbeaver/plugin-datasource-context-switch'; -import { NavigationTabsService } from '@cloudbeaver/plugin-navigation-tabs'; -import { SqlDataSourceService } from '@cloudbeaver/plugin-sql-editor'; -type ConnectionId = string; +import { TransactionExecutionContext } from './TransactionExecutionContext'; -interface IProcessData { - mode: boolean; - commit: boolean; - rollback: boolean; -} - -type ProcessType = keyof IProcessData; - -const DEFAULT_PROCESS_DATA_GETTER: () => IProcessData = () => ({ mode: false, commit: false, rollback: false }); const DEFAULT_AUTO_COMMIT = true; @injectable() export class TransactionManagerService { get currentContext() { - const tab = this.navigationTabsService.currentTab; - - if (tab) { - const model = this.tableViewerStorageService.get(tab.handlerState.tableId); - - if (model) { - return model.source.executionContext?.context; - } - - const source = this.sqlDataSourceService.get(tab.handlerState.editorId); - - if (source) { - return source.executionContext; - } - } - - return null; + return this.connectionSchemaManagerService.activeExecutionContext; } get autoCommitMode() { @@ -61,29 +35,29 @@ export class TransactionManagerService { return DEFAULT_AUTO_COMMIT; } - readonly processState: Map; + readonly transactions: MetadataMap; + readonly scheduler: TaskScheduler; constructor( private readonly notificationService: NotificationService, private readonly graphQLService: GraphQLService, private readonly asyncTaskInfoService: AsyncTaskInfoService, - private readonly navigationTabsService: NavigationTabsService, - private readonly tableViewerStorageService: TableViewerStorageService, private readonly connectionExecutionContextResource: ConnectionExecutionContextResource, private readonly connectionSchemaManagerService: ConnectionSchemaManagerService, - private readonly sqlDataSourceService: SqlDataSourceService, ) { - this.processState = new Map(); + this.scheduler = new TaskScheduler((a, b) => a === b); + this.transactions = new MetadataMap( + contextId => new TransactionExecutionContext(this.scheduler, this.connectionExecutionContextResource, contextId), + ); makeAutoObservable(this, { currentContext: computed, autoCommitMode: computed, - processState: observable, }); } async setAutoCommit(connectionId: string, contextId: string, autoCommit: boolean) { - this.changeProcessStatus(connectionId, 'mode', true); + const transaction = this.transactions.get(contextId); const task = this.asyncTaskInfoService.create(async () => { const { taskInfo } = await this.graphQLService.sdk.asyncSqlSetAutoCommit({ @@ -95,18 +69,18 @@ export class TransactionManagerService { return taskInfo; }); - await this.asyncTaskInfoService.run(task); - - if (this.currentContext) { - const param = createConnectionParam(this.currentContext.projectId, this.currentContext.connectionId); - await this.connectionExecutionContextResource.refreshConnectionContexts(param); - } - - this.changeProcessStatus(connectionId, 'mode', false); + await transaction.run( + async () => await this.asyncTaskInfoService.run(task), + () => this.asyncTaskInfoService.cancel(task.id), + () => { + this.asyncTaskInfoService.remove(task.id); + this.connectionExecutionContextResource.markOutdated(); + }, + ); } async commit(connectionId: string, contextId: string) { - this.changeProcessStatus(connectionId, 'commit', true); + const transaction = this.transactions.get(contextId); const task = this.asyncTaskInfoService.create(async () => { const { taskInfo } = await this.graphQLService.sdk.asyncSqlCommitTransaction({ @@ -117,18 +91,15 @@ export class TransactionManagerService { return taskInfo; }); - const result = await this.asyncTaskInfoService.run(task); + const info = await transaction.run(async () => await this.asyncTaskInfoService.run(task)); const connection = this.connectionSchemaManagerService.currentConnection; + const message = typeof info.taskResult === 'string' ? info.taskResult : ''; - if (result.taskResult) { - this.notificationService.logInfo({ title: connection?.name ?? result.name ?? '', message: result.taskResult }); - } - - this.changeProcessStatus(connectionId, 'commit', false); + this.notificationService.logInfo({ title: connection?.name ?? info.name ?? '', message }); } async rollback(connectionId: string, contextId: string) { - this.changeProcessStatus(connectionId, 'rollback', true); + const transaction = this.transactions.get(contextId); const task = this.asyncTaskInfoService.create(async () => { const { taskInfo } = await this.graphQLService.sdk.asyncSqlRollbackTransaction({ @@ -139,20 +110,10 @@ export class TransactionManagerService { return taskInfo; }); - const result = await this.asyncTaskInfoService.run(task); + const info = await transaction.run(async () => await this.asyncTaskInfoService.run(task)); const connection = this.connectionSchemaManagerService.currentConnection; + const message = typeof info.taskResult === 'string' ? info.taskResult : ''; - if (result.taskResult) { - this.notificationService.logInfo({ title: connection?.name ?? result.name ?? '', message: result.taskResult }); - } - - this.changeProcessStatus(connectionId, 'rollback', false); - } - - private changeProcessStatus(connectionId: string, type: ProcessType, value: boolean) { - const currentState = this.processState.get(connectionId) || DEFAULT_PROCESS_DATA_GETTER(); - - currentState[type] = value; - this.processState.set(connectionId, currentState); + this.notificationService.logInfo({ title: connection?.name ?? info.name ?? '', message }); } } diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT.ts b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT.ts index 9bf2484c41..9c1b1441cb 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT.ts @@ -10,5 +10,5 @@ import { createAction } from '@cloudbeaver/core-view'; export const ACTION_COMMIT = createAction('commit', { label: 'plugin_datasource_transaction_manager_commit', tooltip: 'plugin_datasource_transaction_manager_commit', - icon: '/icons/commit.png', + icon: '/icons/commit.svg', }); diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts index ab6b8907f8..bcfd2f13a7 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts @@ -10,5 +10,5 @@ import { createAction } from '@cloudbeaver/core-view'; export const ACTION_COMMIT_MODE_TOGGLE = createAction('commit-mode-toggle', { label: 'plugin_datasource_transaction_manager_commit_mode_switch_to_manual', tooltip: 'plugin_datasource_transaction_manager_commit_mode_switch_to_manual', - icon: '/icons/commit_mode_auto.png', + icon: '/icons/commit_mode_auto.svg', }); diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_ROLLBACK.ts b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_ROLLBACK.ts index 0d6c26d1c8..09589a31f8 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_ROLLBACK.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_ROLLBACK.ts @@ -10,5 +10,5 @@ import { createAction } from '@cloudbeaver/core-view'; export const ACTION_ROLLBACK = createAction('rollback', { label: 'plugin_datasource_transaction_manager_rollback', tooltip: 'plugin_datasource_transaction_manager_rollback', - icon: '/icons/rollback.png', + icon: '/icons/rollback.svg', }); diff --git a/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTabService.ts b/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTabService.ts index b1e9c41be9..a4d7857fd1 100644 --- a/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTabService.ts +++ b/webapp/packages/plugin-sql-editor-navigation-tab/src/SqlEditorTabService.ts @@ -18,6 +18,7 @@ import { ConnectionsManagerService, ContainerResource, createConnectionParam, + executionContextProvider, ICatalogData, IConnectionExecutorData, IConnectionInfoParams, @@ -95,6 +96,7 @@ export class SqlEditorTabService extends Bootstrap { connectionProvider(this.getConnectionId.bind(this)), objectCatalogProvider(this.getObjectCatalogId.bind(this)), objectSchemaProvider(this.getObjectSchemaId.bind(this)), + executionContextProvider(this.getExecutionContext.bind(this)), projectSetter(this.setProjectId.bind(this)), connectionSetter((connectionId, tab) => this.setConnectionId(tab, connectionId)), objectCatalogSetter(this.setObjectCatalogId.bind(this)), @@ -339,6 +341,11 @@ export class SqlEditorTabService extends Bootstrap { return context?.defaultSchema; } + private getExecutionContext(tab: ITab) { + const dataSource = this.sqlDataSourceService.get(tab.handlerState.editorId); + return dataSource?.executionContext; + } + private setProjectId(projectId: string | null, tab: ITab): boolean { const dataSource = this.sqlDataSourceService.get(tab.handlerState.editorId); From 86ea3754e2fd6ba5a3330b106afed68a38096c6f Mon Sep 17 00:00:00 2001 From: naumov Date: Thu, 7 Mar 2024 15:25:59 +0100 Subject: [PATCH 10/25] CB-1084 handle errors --- .../package.json | 9 ++- .../src/TransactionManagerService.ts | 56 +++++++++++++------ .../src/locales/en.ts | 3 + .../src/locales/it.ts | 3 + .../src/locales/ru.ts | 3 + .../src/locales/zh.ts | 3 + .../tsconfig.json | 18 ++++++ 7 files changed, 77 insertions(+), 18 deletions(-) diff --git a/webapp/packages/plugin-datasource-transaction-manager/package.json b/webapp/packages/plugin-datasource-transaction-manager/package.json index 540d14e1a2..bd452af51a 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/package.json +++ b/webapp/packages/plugin-datasource-transaction-manager/package.json @@ -17,10 +17,17 @@ "update-ts-references": "rimraf --glob dist && typescript-resolve-references" }, "dependencies": { + "@cloudbeaver/core-connections": "~0.1.0", "@cloudbeaver/core-di": "~0.1.0", + "@cloudbeaver/core-events": "~0.1.0", + "@cloudbeaver/core-executor": "~0.1.0", "@cloudbeaver/core-localization": "~0.1.0", + "@cloudbeaver/core-sdk": "~0.1.0", + "@cloudbeaver/core-utils": "~0.1.0", "@cloudbeaver/core-view": "~0.1.0", - "@cloudbeaver/plugin-top-app-bar": "~0.1.0" + "@cloudbeaver/plugin-datasource-context-switch": "~0.1.0", + "@cloudbeaver/plugin-top-app-bar": "~0.1.0", + "mobx": "^6.12.0" }, "peerDependencies": {}, "devDependencies": { diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts index 8261265165..0fba70e831 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts @@ -69,14 +69,19 @@ export class TransactionManagerService { return taskInfo; }); - await transaction.run( - async () => await this.asyncTaskInfoService.run(task), - () => this.asyncTaskInfoService.cancel(task.id), - () => { - this.asyncTaskInfoService.remove(task.id); - this.connectionExecutionContextResource.markOutdated(); - }, - ); + try { + await transaction.run( + async () => await this.asyncTaskInfoService.run(task), + () => this.asyncTaskInfoService.cancel(task.id), + () => { + this.asyncTaskInfoService.remove(task.id); + }, + ); + + this.connectionExecutionContextResource.markOutdated(); + } catch (exception: any) { + this.notificationService.logException(exception, 'plugin_datasource_transaction_manager_commit_mode_fail'); + } } async commit(connectionId: string, contextId: string) { @@ -91,11 +96,20 @@ export class TransactionManagerService { return taskInfo; }); - const info = await transaction.run(async () => await this.asyncTaskInfoService.run(task)); - const connection = this.connectionSchemaManagerService.currentConnection; - const message = typeof info.taskResult === 'string' ? info.taskResult : ''; + try { + const info = await transaction.run( + async () => await this.asyncTaskInfoService.run(task), + () => this.asyncTaskInfoService.cancel(task.id), + () => this.asyncTaskInfoService.remove(task.id), + ); + + const connection = this.connectionSchemaManagerService.currentConnection; + const message = typeof info.taskResult === 'string' ? info.taskResult : ''; - this.notificationService.logInfo({ title: connection?.name ?? info.name ?? '', message }); + this.notificationService.logInfo({ title: connection?.name ?? info.name ?? '', message }); + } catch (exception: any) { + this.notificationService.logException(exception, 'plugin_datasource_transaction_manager_commit_fail'); + } } async rollback(connectionId: string, contextId: string) { @@ -110,10 +124,18 @@ export class TransactionManagerService { return taskInfo; }); - const info = await transaction.run(async () => await this.asyncTaskInfoService.run(task)); - const connection = this.connectionSchemaManagerService.currentConnection; - const message = typeof info.taskResult === 'string' ? info.taskResult : ''; - - this.notificationService.logInfo({ title: connection?.name ?? info.name ?? '', message }); + try { + const info = await transaction.run( + async () => await this.asyncTaskInfoService.run(task), + () => this.asyncTaskInfoService.cancel(task.id), + () => this.asyncTaskInfoService.remove(task.id), + ); + const connection = this.connectionSchemaManagerService.currentConnection; + const message = typeof info.taskResult === 'string' ? info.taskResult : ''; + + this.notificationService.logInfo({ title: connection?.name ?? info.name ?? '', message }); + } catch (exception: any) { + this.notificationService.logException(exception, 'plugin_datasource_transaction_manager_rollback_fail'); + } } } diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/locales/en.ts b/webapp/packages/plugin-datasource-transaction-manager/src/locales/en.ts index 8acc6a3a5f..4dd50d2fd4 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/locales/en.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/locales/en.ts @@ -3,4 +3,7 @@ export default [ ['plugin_datasource_transaction_manager_rollback', 'Rollback'], ['plugin_datasource_transaction_manager_commit_mode_switch_to_auto', 'Switch to auto-commit'], ['plugin_datasource_transaction_manager_commit_mode_switch_to_manual', 'Switch to manual commit'], + ['plugin_datasource_transaction_manager_commit_fail', 'Failed to commit transaction'], + ['plugin_datasource_transaction_manager_rollback_fail', 'Failed to rollback transaction'], + ['plugin_datasource_transaction_manager_commit_mode_fail', 'Failed to change commit mode'], ]; diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/locales/it.ts b/webapp/packages/plugin-datasource-transaction-manager/src/locales/it.ts index 8acc6a3a5f..4dd50d2fd4 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/locales/it.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/locales/it.ts @@ -3,4 +3,7 @@ export default [ ['plugin_datasource_transaction_manager_rollback', 'Rollback'], ['plugin_datasource_transaction_manager_commit_mode_switch_to_auto', 'Switch to auto-commit'], ['plugin_datasource_transaction_manager_commit_mode_switch_to_manual', 'Switch to manual commit'], + ['plugin_datasource_transaction_manager_commit_fail', 'Failed to commit transaction'], + ['plugin_datasource_transaction_manager_rollback_fail', 'Failed to rollback transaction'], + ['plugin_datasource_transaction_manager_commit_mode_fail', 'Failed to change commit mode'], ]; diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts b/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts index 8acc6a3a5f..4dd50d2fd4 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts @@ -3,4 +3,7 @@ export default [ ['plugin_datasource_transaction_manager_rollback', 'Rollback'], ['plugin_datasource_transaction_manager_commit_mode_switch_to_auto', 'Switch to auto-commit'], ['plugin_datasource_transaction_manager_commit_mode_switch_to_manual', 'Switch to manual commit'], + ['plugin_datasource_transaction_manager_commit_fail', 'Failed to commit transaction'], + ['plugin_datasource_transaction_manager_rollback_fail', 'Failed to rollback transaction'], + ['plugin_datasource_transaction_manager_commit_mode_fail', 'Failed to change commit mode'], ]; diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/locales/zh.ts b/webapp/packages/plugin-datasource-transaction-manager/src/locales/zh.ts index 8acc6a3a5f..4dd50d2fd4 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/locales/zh.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/locales/zh.ts @@ -3,4 +3,7 @@ export default [ ['plugin_datasource_transaction_manager_rollback', 'Rollback'], ['plugin_datasource_transaction_manager_commit_mode_switch_to_auto', 'Switch to auto-commit'], ['plugin_datasource_transaction_manager_commit_mode_switch_to_manual', 'Switch to manual commit'], + ['plugin_datasource_transaction_manager_commit_fail', 'Failed to commit transaction'], + ['plugin_datasource_transaction_manager_rollback_fail', 'Failed to rollback transaction'], + ['plugin_datasource_transaction_manager_commit_mode_fail', 'Failed to change commit mode'], ]; diff --git a/webapp/packages/plugin-datasource-transaction-manager/tsconfig.json b/webapp/packages/plugin-datasource-transaction-manager/tsconfig.json index 99f6d7d12d..f72500d70a 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/tsconfig.json +++ b/webapp/packages/plugin-datasource-transaction-manager/tsconfig.json @@ -6,15 +6,33 @@ "tsBuildInfoFile": "dist/tsconfig.tsbuildinfo" }, "references": [ + { + "path": "../core-connections/tsconfig.json" + }, { "path": "../core-di/tsconfig.json" }, + { + "path": "../core-events/tsconfig.json" + }, + { + "path": "../core-executor/tsconfig.json" + }, { "path": "../core-localization/tsconfig.json" }, + { + "path": "../core-sdk/tsconfig.json" + }, + { + "path": "../core-utils/tsconfig.json" + }, { "path": "../core-view/tsconfig.json" }, + { + "path": "../plugin-datasource-context-switch/tsconfig.json" + }, { "path": "../plugin-top-app-bar/tsconfig.json" } From d21fbfd038900cb9e4e8d2b21e94341395f180ea Mon Sep 17 00:00:00 2001 From: naumov Date: Thu, 7 Mar 2024 15:32:39 +0100 Subject: [PATCH 11/25] CB-1084 get connection before the task execution --- .../src/TransactionManagerService.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts index 0fba70e831..3137935eaa 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts @@ -7,7 +7,7 @@ */ import { computed, makeAutoObservable } from 'mobx'; -import { ConnectionExecutionContextResource } from '@cloudbeaver/core-connections'; +import { Connection, ConnectionExecutionContextResource } from '@cloudbeaver/core-connections'; import { injectable } from '@cloudbeaver/core-di'; import { NotificationService } from '@cloudbeaver/core-events'; import { TaskScheduler } from '@cloudbeaver/core-executor'; @@ -96,14 +96,16 @@ export class TransactionManagerService { return taskInfo; }); + let connection: Connection | undefined; + try { + connection = this.connectionSchemaManagerService.currentConnection; const info = await transaction.run( async () => await this.asyncTaskInfoService.run(task), () => this.asyncTaskInfoService.cancel(task.id), () => this.asyncTaskInfoService.remove(task.id), ); - const connection = this.connectionSchemaManagerService.currentConnection; const message = typeof info.taskResult === 'string' ? info.taskResult : ''; this.notificationService.logInfo({ title: connection?.name ?? info.name ?? '', message }); @@ -124,13 +126,16 @@ export class TransactionManagerService { return taskInfo; }); + let connection: Connection | undefined; + try { + connection = this.connectionSchemaManagerService.currentConnection; const info = await transaction.run( async () => await this.asyncTaskInfoService.run(task), () => this.asyncTaskInfoService.cancel(task.id), () => this.asyncTaskInfoService.remove(task.id), ); - const connection = this.connectionSchemaManagerService.currentConnection; + const message = typeof info.taskResult === 'string' ? info.taskResult : ''; this.notificationService.logInfo({ title: connection?.name ?? info.name ?? '', message }); From 0069a3db7bc0282561dd651a10f083957a36bf83 Mon Sep 17 00:00:00 2001 From: naumov Date: Thu, 7 Mar 2024 16:00:02 +0100 Subject: [PATCH 12/25] CB-1084 grab connection from transaction context --- .../src/TransactionManagerService.ts | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts index 3137935eaa..110548c658 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts @@ -7,7 +7,7 @@ */ import { computed, makeAutoObservable } from 'mobx'; -import { Connection, ConnectionExecutionContextResource } from '@cloudbeaver/core-connections'; +import { ConnectionExecutionContextResource, ConnectionInfoResource, createConnectionParam } from '@cloudbeaver/core-connections'; import { injectable } from '@cloudbeaver/core-di'; import { NotificationService } from '@cloudbeaver/core-events'; import { TaskScheduler } from '@cloudbeaver/core-executor'; @@ -44,6 +44,7 @@ export class TransactionManagerService { private readonly asyncTaskInfoService: AsyncTaskInfoService, private readonly connectionExecutionContextResource: ConnectionExecutionContextResource, private readonly connectionSchemaManagerService: ConnectionSchemaManagerService, + private readonly connectionInfoResource: ConnectionInfoResource, ) { this.scheduler = new TaskScheduler((a, b) => a === b); this.transactions = new MetadataMap( @@ -73,9 +74,7 @@ export class TransactionManagerService { await transaction.run( async () => await this.asyncTaskInfoService.run(task), () => this.asyncTaskInfoService.cancel(task.id), - () => { - this.asyncTaskInfoService.remove(task.id); - }, + () => this.asyncTaskInfoService.remove(task.id), ); this.connectionExecutionContextResource.markOutdated(); @@ -96,16 +95,15 @@ export class TransactionManagerService { return taskInfo; }); - let connection: Connection | undefined; - try { - connection = this.connectionSchemaManagerService.currentConnection; const info = await transaction.run( async () => await this.asyncTaskInfoService.run(task), () => this.asyncTaskInfoService.cancel(task.id), () => this.asyncTaskInfoService.remove(task.id), ); + const connectionParam = createConnectionParam(transaction.context!.projectId, transaction.context!.connectionId); + const connection = this.connectionInfoResource.get(connectionParam); const message = typeof info.taskResult === 'string' ? info.taskResult : ''; this.notificationService.logInfo({ title: connection?.name ?? info.name ?? '', message }); @@ -126,16 +124,15 @@ export class TransactionManagerService { return taskInfo; }); - let connection: Connection | undefined; - try { - connection = this.connectionSchemaManagerService.currentConnection; const info = await transaction.run( async () => await this.asyncTaskInfoService.run(task), () => this.asyncTaskInfoService.cancel(task.id), () => this.asyncTaskInfoService.remove(task.id), ); + const connectionParam = createConnectionParam(transaction.context!.projectId, transaction.context!.connectionId); + const connection = this.connectionInfoResource.get(connectionParam); const message = typeof info.taskResult === 'string' ? info.taskResult : ''; this.notificationService.logInfo({ title: connection?.name ?? info.name ?? '', message }); From 03ed2f0a9c6c0b4c3ee323a07804160ab48c6346 Mon Sep 17 00:00:00 2001 From: naumov Date: Mon, 11 Mar 2024 13:58:39 +0100 Subject: [PATCH 13/25] CB-1084 support execution context provider for the object viewer --- .../public/icons/commit.svg | 10 ++++++--- .../public/icons/commit_m.svg | 17 ++++++++++++++ .../public/icons/commit_mode_auto.svg | 22 ++++++++++--------- .../public/icons/commit_mode_auto_m.svg | 22 +++++++++++++++++++ .../public/icons/commit_mode_auto_sm.svg | 22 +++++++++++++++++++ .../public/icons/commit_mode_manual.svg | 21 +++++++++--------- .../public/icons/commit_mode_manual_m.svg | 21 ++++++++++++++++++ .../public/icons/commit_mode_manual_sm.svg | 20 +++++++++++++++++ .../public/icons/commit_sm.svg | 19 ++++++++++++++++ .../public/icons/rollback.svg | 8 ++++--- .../public/icons/rollback_m.svg | 15 +++++++++++++ .../public/icons/rollback_sm.svg | 15 +++++++++++++ .../src/TransactionManagerBootstrap.ts | 4 +++- .../src/actions/ACTION_COMMIT.ts | 2 +- .../src/actions/ACTION_COMMIT_MODE_TOGGLE.ts | 2 +- .../src/actions/ACTION_ROLLBACK.ts | 2 +- .../src/ObjectViewerTabService.ts | 16 ++++++++++++++ 17 files changed, 208 insertions(+), 30 deletions(-) create mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_m.svg create mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto_m.svg create mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto_sm.svg create mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual_m.svg create mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual_sm.svg create mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_sm.svg create mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback_m.svg create mode 100644 webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback_sm.svg diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit.svg index d120e7a133..e640e089ef 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit.svg +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit.svg @@ -3,11 +3,15 @@ - - + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_m.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_m.svg new file mode 100644 index 0000000000..f07ddff927 --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_m.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto.svg index 34f2bfaa11..cfa19cd5a2 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto.svg +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto.svg @@ -3,18 +3,20 @@ - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto_m.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto_m.svg new file mode 100644 index 0000000000..812bca94d1 --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto_m.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto_sm.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto_sm.svg new file mode 100644 index 0000000000..fbc45eba62 --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_auto_sm.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual.svg index 83f2d08d99..62920cce76 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual.svg +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual.svg @@ -3,18 +3,19 @@ - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual_m.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual_m.svg new file mode 100644 index 0000000000..82ca26326a --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual_m.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual_sm.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual_sm.svg new file mode 100644 index 0000000000..f23fd9fbe5 --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_mode_manual_sm.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_sm.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_sm.svg new file mode 100644 index 0000000000..6ef412d43f --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/commit_sm.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback.svg index 1d695d1074..6932be5834 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback.svg +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback.svg @@ -3,11 +3,13 @@ - - + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback_m.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback_m.svg new file mode 100644 index 0000000000..c469264a9a --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback_m.svg @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback_sm.svg b/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback_sm.svg new file mode 100644 index 0000000000..f206366047 --- /dev/null +++ b/webapp/packages/plugin-datasource-transaction-manager/public/icons/rollback_sm.svg @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts index fb2716317d..e4fa1703c5 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts @@ -40,7 +40,7 @@ export class TransactionManagerBootstrap extends Bootstrap { getActionInfo: (_, action) => { if (action === ACTION_COMMIT_MODE_TOGGLE) { const auto = this.transactionManagerService.autoCommitMode; - const icon = `/icons/commit_mode_${auto ? 'auto' : 'manual'}.svg`; + const icon = `/icons/commit_mode_${auto ? 'auto' : 'manual'}_m.svg`; const label = `plugin_datasource_transaction_manager_commit_mode_switch_to_${auto ? 'manual' : 'auto'}`; return { ...action.info, icon, label, tooltip: label }; @@ -82,6 +82,8 @@ export class TransactionManagerBootstrap extends Bootstrap { case ACTION_COMMIT_MODE_TOGGLE: await this.transactionManagerService.setAutoCommit(context.connectionId, context.id, !context.autoCommit); break; + default: + break; } }, }); diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT.ts b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT.ts index 9c1b1441cb..be41e45f51 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT.ts @@ -10,5 +10,5 @@ import { createAction } from '@cloudbeaver/core-view'; export const ACTION_COMMIT = createAction('commit', { label: 'plugin_datasource_transaction_manager_commit', tooltip: 'plugin_datasource_transaction_manager_commit', - icon: '/icons/commit.svg', + icon: '/icons/commit_m.svg', }); diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts index bcfd2f13a7..bc0f868d46 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts @@ -10,5 +10,5 @@ import { createAction } from '@cloudbeaver/core-view'; export const ACTION_COMMIT_MODE_TOGGLE = createAction('commit-mode-toggle', { label: 'plugin_datasource_transaction_manager_commit_mode_switch_to_manual', tooltip: 'plugin_datasource_transaction_manager_commit_mode_switch_to_manual', - icon: '/icons/commit_mode_auto.svg', + icon: '/icons/commit_mode_auto_m.svg', }); diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_ROLLBACK.ts b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_ROLLBACK.ts index 09589a31f8..feb3c3f771 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_ROLLBACK.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_ROLLBACK.ts @@ -10,5 +10,5 @@ import { createAction } from '@cloudbeaver/core-view'; export const ACTION_ROLLBACK = createAction('rollback', { label: 'plugin_datasource_transaction_manager_rollback', tooltip: 'plugin_datasource_transaction_manager_rollback', - icon: '/icons/rollback.svg', + icon: '/icons/rollback_m.svg', }); diff --git a/webapp/packages/plugin-object-viewer/src/ObjectViewerTabService.ts b/webapp/packages/plugin-object-viewer/src/ObjectViewerTabService.ts index 508e6e8d62..444e774960 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectViewerTabService.ts +++ b/webapp/packages/plugin-object-viewer/src/ObjectViewerTabService.ts @@ -9,11 +9,13 @@ import { action, makeObservable, runInAction } from 'mobx'; import { Connection, + ConnectionExecutionContextResource, ConnectionInfoActiveProjectKey, ConnectionInfoResource, ConnectionNavNodeService, connectionProvider, createConnectionParam, + executionContextProvider, IConnectionInfoParams, objectCatalogProvider, objectSchemaProvider, @@ -45,6 +47,7 @@ export class ObjectViewerTabService { private readonly navigationTabsService: NavigationTabsService, private readonly connectionInfoResource: ConnectionInfoResource, private readonly connectionNavNodeService: ConnectionNavNodeService, + private readonly connectionExecutionContextResource: ConnectionExecutionContextResource, ) { this.tabHandler = this.navigationTabsService.registerTabHandler({ key: objectViewerTabHandlerKey, @@ -61,6 +64,7 @@ export class ObjectViewerTabService { connectionProvider(this.getConnection.bind(this)), objectCatalogProvider(this.getDBObjectCatalog.bind(this)), objectSchemaProvider(this.getDBObjectSchema.bind(this)), + executionContextProvider(this.getExecutionContext.bind(this)), ], }); @@ -308,6 +312,18 @@ export class ObjectViewerTabService { return nodeInfo.schemaId; } + private getExecutionContext(context: ITab) { + const connectionKey = context.handlerState.connectionKey; + + if (!connectionKey) { + return; + } + + return this.connectionExecutionContextResource.values.find( + c => c.connectionId === connectionKey.connectionId && c.projectId === connectionKey.projectId, + ); + } + private selectObjectTab(tab: ITab) { if (tab.handlerState.error) { return; From a71c8e50b2863cf50ba657044cdc7f2b394eee25 Mon Sep 17 00:00:00 2001 From: naumov Date: Mon, 11 Mar 2024 14:09:57 +0100 Subject: [PATCH 14/25] CB-1084 refresh context manually --- .../src/TransactionManagerService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts index 110548c658..a884021f0f 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts @@ -77,7 +77,7 @@ export class TransactionManagerService { () => this.asyncTaskInfoService.remove(task.id), ); - this.connectionExecutionContextResource.markOutdated(); + await this.connectionExecutionContextResource.refresh(); } catch (exception: any) { this.notificationService.logException(exception, 'plugin_datasource_transaction_manager_commit_mode_fail'); } From 6430617f2e4469b07e6c3117e5b5b20d594772b7 Mon Sep 17 00:00:00 2001 From: naumov Date: Mon, 11 Mar 2024 14:21:02 +0100 Subject: [PATCH 15/25] CB-1084 check options panel status --- .../src/TransactionManagerBootstrap.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts index e4fa1703c5..3c217f389c 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts @@ -6,6 +6,7 @@ * you may not use this file except in compliance with the License. */ import { Bootstrap, injectable } from '@cloudbeaver/core-di'; +import { OptionsPanelService } from '@cloudbeaver/core-ui'; import { ActionService, MenuService } from '@cloudbeaver/core-view'; import { ConnectionSchemaManagerService } from '@cloudbeaver/plugin-datasource-context-switch'; import { MENU_APP_ACTIONS } from '@cloudbeaver/plugin-top-app-bar'; @@ -22,6 +23,7 @@ export class TransactionManagerBootstrap extends Bootstrap { private readonly actionService: ActionService, private readonly connectionSchemaManagerService: ConnectionSchemaManagerService, private readonly transactionManagerService: TransactionManagerService, + private readonly optionsPanelService: OptionsPanelService, ) { super(); } @@ -29,7 +31,10 @@ export class TransactionManagerBootstrap extends Bootstrap { register() { this.menuService.addCreator({ menus: [MENU_APP_ACTIONS], - isApplicable: () => !!this.connectionSchemaManagerService.currentConnection?.connected && !!this.transactionManagerService.currentContext, + isApplicable: () => + !this.optionsPanelService.active && + !!this.connectionSchemaManagerService.currentConnection?.connected && + !!this.transactionManagerService.currentContext, getItems: (_, items) => [...items, ACTION_COMMIT, ACTION_ROLLBACK, ACTION_COMMIT_MODE_TOGGLE], }); From 2404c46c9555897a2685a49f20a36c7acc23438f Mon Sep 17 00:00:00 2001 From: naumov Date: Mon, 11 Mar 2024 19:13:54 +0100 Subject: [PATCH 16/25] CB-1084 move transaction logic to the ConnectionExecutionContext --- .../ConnectionExecutionContext.ts | 88 ++++++++++- .../ConnectionExecutionContextResource.ts | 7 - .../ConnectionExecutionContextService.ts | 18 ++- .../src/ITransactionExecutionContext.ts | 19 --- .../src/TransactionExecutionContext.ts | 70 --------- .../src/TransactionManagerBootstrap.ts | 101 ++++++++++--- .../src/TransactionManagerService.ts | 143 ------------------ .../src/locales/ru.ts | 10 +- .../src/manifest.ts | 3 +- 9 files changed, 189 insertions(+), 270 deletions(-) delete mode 100644 webapp/packages/plugin-datasource-transaction-manager/src/ITransactionExecutionContext.ts delete mode 100644 webapp/packages/plugin-datasource-transaction-manager/src/TransactionExecutionContext.ts delete mode 100644 webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts diff --git a/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContext.ts b/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContext.ts index 31b804d9c0..d205f4d2af 100644 --- a/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContext.ts +++ b/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContext.ts @@ -8,10 +8,13 @@ import { computed, makeObservable, observable } from 'mobx'; import type { ITask, TaskScheduler } from '@cloudbeaver/core-executor'; +import type { AsyncTaskInfoService, GraphQLService } from '@cloudbeaver/core-sdk'; import type { ConnectionExecutionContextResource, IConnectionExecutionContextInfo } from './ConnectionExecutionContextResource'; import type { IConnectionExecutionContext } from './IConnectionExecutionContext'; +const DEFAULT_AUTO_COMMIT = true; + export class ConnectionExecutionContext implements IConnectionExecutionContext { get context(): IConnectionExecutionContextInfo | undefined { return this.connectionExecutionContextResource.get(this.contextId); @@ -25,12 +28,22 @@ export class ConnectionExecutionContext implements IConnectionExecutionContext { return this.currentTask?.cancellable || false; } + get currentCommitMode() { + if (this.context) { + return this.context.autoCommit ?? DEFAULT_AUTO_COMMIT; + } + + return DEFAULT_AUTO_COMMIT; + } + private currentTask: ITask | null; constructor( + private readonly contextId: string, private readonly scheduler: TaskScheduler, private readonly connectionExecutionContextResource: ConnectionExecutionContextResource, - private readonly contextId: string, + private readonly asyncTaskInfoService: AsyncTaskInfoService, + private readonly graphQLService: GraphQLService, ) { this.currentTask = null; makeObservable(this, { @@ -38,6 +51,7 @@ export class ConnectionExecutionContext implements IConnectionExecutionContext { context: computed, executing: computed, cancellable: computed, + currentCommitMode: computed, }); } @@ -76,4 +90,76 @@ export class ConnectionExecutionContext implements IConnectionExecutionContext { return await this.connectionExecutionContextResource.update(this.contextId, defaultCatalog, defaultSchema); } + + async setAutoCommit(auto: boolean) { + const result = await this.withContext(async context => { + const task = this.asyncTaskInfoService.create(async () => { + const { taskInfo } = await this.graphQLService.sdk.asyncSqlSetAutoCommit({ + connectionId: context.connectionId, + contextId: context.id, + autoCommit: auto, + }); + + return taskInfo; + }); + + return await this.run( + async () => await this.asyncTaskInfoService.run(task), + () => this.asyncTaskInfoService.cancel(task.id), + () => this.asyncTaskInfoService.remove(task.id), + ); + }); + + return result; + } + + async commit() { + const result = await this.withContext(async context => { + const task = this.asyncTaskInfoService.create(async () => { + const { taskInfo } = await this.graphQLService.sdk.asyncSqlCommitTransaction({ + connectionId: context.connectionId, + contextId: context.id, + }); + + return taskInfo; + }); + + return await this.run( + async () => await this.asyncTaskInfoService.run(task), + () => this.asyncTaskInfoService.cancel(task.id), + () => this.asyncTaskInfoService.remove(task.id), + ); + }); + + return result; + } + + async rollback() { + const result = await this.withContext(async context => { + const task = this.asyncTaskInfoService.create(async () => { + const { taskInfo } = await this.graphQLService.sdk.asyncSqlRollbackTransaction({ + connectionId: context.connectionId, + contextId: context.id, + }); + + return taskInfo; + }); + + return await this.run( + async () => await this.asyncTaskInfoService.run(task), + () => this.asyncTaskInfoService.cancel(task.id), + () => this.asyncTaskInfoService.remove(task.id), + ); + }); + + return result; + } + + private withContext(callback: (context: IConnectionExecutionContextInfo) => Promise): Promise { + if (!this.context) { + throw new Error('Execution Context not found'); + } + + return callback(this.context); + } } diff --git a/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextResource.ts b/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextResource.ts index d90d4870c8..a840a75282 100644 --- a/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextResource.ts +++ b/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextResource.ts @@ -134,13 +134,6 @@ export class ConnectionExecutionContextResource extends CachedMapResource context.connectionId === connection.connectionId && context.projectId === connection.projectId); - const key = resourceKeyList(contexts.map(context => context.id)); - - await this.refresh(key); - } - protected async loader(originalKey: ResourceKey): Promise> { const contextsList: IConnectionExecutionContextInfo[] = []; let projectId: string | undefined; diff --git a/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextService.ts b/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextService.ts index 8747a60e2b..6da75ec1ea 100644 --- a/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextService.ts +++ b/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContextService.ts @@ -8,6 +8,7 @@ import { injectable } from '@cloudbeaver/core-di'; import { TaskScheduler } from '@cloudbeaver/core-executor'; import { CachedMapAllKey, ResourceKeyUtils } from '@cloudbeaver/core-resource'; +import { AsyncTaskInfoService, GraphQLService } from '@cloudbeaver/core-sdk'; import { MetadataMap } from '@cloudbeaver/core-utils'; import type { IConnectionInfoParams } from '../CONNECTION_INFO_PARAM_SCHEMA'; @@ -19,8 +20,21 @@ export class ConnectionExecutionContextService { private readonly contexts: MetadataMap; protected scheduler: TaskScheduler; - constructor(readonly connectionExecutionContextResource: ConnectionExecutionContextResource) { - this.contexts = new MetadataMap(contextId => new ConnectionExecutionContext(this.scheduler, this.connectionExecutionContextResource, contextId)); + constructor( + readonly connectionExecutionContextResource: ConnectionExecutionContextResource, + private readonly asyncTaskInfoService: AsyncTaskInfoService, + private readonly GraphQLService: GraphQLService, + ) { + this.contexts = new MetadataMap( + contextId => + new ConnectionExecutionContext( + contextId, + this.scheduler, + this.connectionExecutionContextResource, + this.asyncTaskInfoService, + this.GraphQLService, + ), + ); this.scheduler = new TaskScheduler((a, b) => a === b); this.connectionExecutionContextResource.onItemDelete.addHandler(key => ResourceKeyUtils.forEach(key, contextId => this.contexts.delete(contextId)), diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/ITransactionExecutionContext.ts b/webapp/packages/plugin-datasource-transaction-manager/src/ITransactionExecutionContext.ts deleted file mode 100644 index 92f717d28d..0000000000 --- a/webapp/packages/plugin-datasource-transaction-manager/src/ITransactionExecutionContext.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ -import type { IConnectionExecutionContextInfo } from '@cloudbeaver/core-connections'; -import type { ITask } from '@cloudbeaver/core-executor'; - -export interface ITransactionExecutionContext { - readonly context: IConnectionExecutionContextInfo | undefined; - readonly executing: boolean; - readonly cancellable: boolean; - - run: (task: () => Promise, cancel?: () => Promise | void, end?: () => Promise | void) => ITask; - cancel: () => Promise; - destroy: () => Promise; -} diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionExecutionContext.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionExecutionContext.ts deleted file mode 100644 index 0a3045f8f2..0000000000 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionExecutionContext.ts +++ /dev/null @@ -1,70 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ -import { computed, makeObservable, observable } from 'mobx'; - -import type { ConnectionExecutionContextResource, IConnectionExecutionContextInfo } from '@cloudbeaver/core-connections'; -import type { ITask, TaskScheduler } from '@cloudbeaver/core-executor'; - -import type { ITransactionExecutionContext } from './ITransactionExecutionContext'; - -export class TransactionExecutionContext implements ITransactionExecutionContext { - get context(): IConnectionExecutionContextInfo | undefined { - return this.connectionExecutionContextResource.get(this.contextId); - } - - get executing(): boolean { - return this.scheduler.isExecuting(this.contextId); - } - - get cancellable(): boolean { - return this.currentTask?.cancellable || false; - } - - private currentTask: ITask | null; - - constructor( - private readonly scheduler: TaskScheduler, - private readonly connectionExecutionContextResource: ConnectionExecutionContextResource, - private readonly contextId: string, - ) { - this.currentTask = null; - makeObservable(this, { - currentTask: observable.ref, - context: computed, - executing: computed, - cancellable: computed, - }); - } - - run(task: () => Promise, cancel?: () => Promise | void, end?: () => Promise | void): ITask { - if (!this.context) { - throw new Error('Execution Context not found'); - } - - this.currentTask = this.scheduler - .schedule(this.contextId, task, { cancel }) - .finally(end) - .finally(() => { - this.currentTask = null; - }); - - return this.currentTask; - } - - async cancel(): Promise { - await this.scheduler.cancel(this.contextId); - } - - async destroy(): Promise { - if (!this.context) { - return; - } - - await this.cancel(); - } -} diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts index 3c217f389c..b93289963c 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts @@ -5,7 +5,16 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ +import { + ConnectionExecutionContext, + ConnectionExecutionContextResource, + ConnectionExecutionContextService, + ConnectionInfoResource, + createConnectionParam, +} from '@cloudbeaver/core-connections'; import { Bootstrap, injectable } from '@cloudbeaver/core-di'; +import { NotificationService } from '@cloudbeaver/core-events'; +import type { AsyncTaskInfo } from '@cloudbeaver/core-sdk'; import { OptionsPanelService } from '@cloudbeaver/core-ui'; import { ActionService, MenuService } from '@cloudbeaver/core-view'; import { ConnectionSchemaManagerService } from '@cloudbeaver/plugin-datasource-context-switch'; @@ -14,7 +23,6 @@ import { MENU_APP_ACTIONS } from '@cloudbeaver/plugin-top-app-bar'; import { ACTION_COMMIT } from './actions/ACTION_COMMIT'; import { ACTION_COMMIT_MODE_TOGGLE } from './actions/ACTION_COMMIT_MODE_TOGGLE'; import { ACTION_ROLLBACK } from './actions/ACTION_ROLLBACK'; -import { TransactionManagerService } from './TransactionManagerService'; @injectable() export class TransactionManagerBootstrap extends Bootstrap { @@ -22,8 +30,11 @@ export class TransactionManagerBootstrap extends Bootstrap { private readonly menuService: MenuService, private readonly actionService: ActionService, private readonly connectionSchemaManagerService: ConnectionSchemaManagerService, - private readonly transactionManagerService: TransactionManagerService, + private readonly connectionExecutionContextService: ConnectionExecutionContextService, + private readonly connectionExecutionContextResource: ConnectionExecutionContextResource, + private readonly connectionInfoResource: ConnectionInfoResource, private readonly optionsPanelService: OptionsPanelService, + private readonly notificationService: NotificationService, ) { super(); } @@ -33,8 +44,8 @@ export class TransactionManagerBootstrap extends Bootstrap { menus: [MENU_APP_ACTIONS], isApplicable: () => !this.optionsPanelService.active && - !!this.connectionSchemaManagerService.currentConnection?.connected && - !!this.transactionManagerService.currentContext, + this.connectionSchemaManagerService.currentConnection?.connected === true && + this.connectionSchemaManagerService.activeExecutionContext !== undefined, getItems: (_, items) => [...items, ACTION_COMMIT, ACTION_ROLLBACK, ACTION_COMMIT_MODE_TOGGLE], }); @@ -43,8 +54,14 @@ export class TransactionManagerBootstrap extends Bootstrap { isActionApplicable: (_, action) => [ACTION_COMMIT, ACTION_ROLLBACK, ACTION_COMMIT_MODE_TOGGLE].includes(action), isLabelVisible: (_, action) => action === ACTION_COMMIT || action === ACTION_ROLLBACK, getActionInfo: (_, action) => { + const transaction = this.getContextTransaction(); + + if (!transaction) { + return action.info; + } + if (action === ACTION_COMMIT_MODE_TOGGLE) { - const auto = this.transactionManagerService.autoCommitMode; + const auto = transaction.currentCommitMode; const icon = `/icons/commit_mode_${auto ? 'auto' : 'manual'}_m.svg`; const label = `plugin_datasource_transaction_manager_commit_mode_switch_to_${auto ? 'manual' : 'auto'}`; @@ -53,39 +70,59 @@ export class TransactionManagerBootstrap extends Bootstrap { return action.info; }, - isDisabled: (_, action) => { - const context = this.transactionManagerService.currentContext; + isDisabled: () => { + const transaction = this.getContextTransaction(); + return transaction?.executing === true; + }, + isHidden: (_, action) => { + const transaction = this.getContextTransaction(); - if (!context) { - return false; + if (!transaction) { + return true; } - const transaction = this.transactionManagerService.transactions.get(context.id); - return transaction.executing; - }, - isHidden: (_, action) => { if (action === ACTION_COMMIT || action === ACTION_ROLLBACK) { - return this.transactionManagerService.autoCommitMode; + return transaction.currentCommitMode; } return false; }, handler: async (_, action) => { - const context = this.transactionManagerService.currentContext; + const transaction = this.getContextTransaction(); - if (!context) { + if (!transaction) { return; } switch (action) { - case ACTION_COMMIT: - await this.transactionManagerService.commit(context.connectionId, context.id); + case ACTION_COMMIT: { + try { + const result = await transaction.commit(); + this.showTransactionResult(transaction, result); + } catch (exception: any) { + this.notificationService.logException(exception, 'plugin_datasource_transaction_manager_commit_fail'); + } + break; - case ACTION_ROLLBACK: - await this.transactionManagerService.rollback(context.connectionId, context.id); + } + case ACTION_ROLLBACK: { + try { + const result = await transaction.rollback(); + this.showTransactionResult(transaction, result); + } catch (exception: any) { + this.notificationService.logException(exception, 'plugin_datasource_transaction_manager_rollback_fail'); + } + break; + } case ACTION_COMMIT_MODE_TOGGLE: - await this.transactionManagerService.setAutoCommit(context.connectionId, context.id, !context.autoCommit); + try { + await transaction.setAutoCommit(!transaction.currentCommitMode); + await this.connectionExecutionContextResource.refresh(); + } catch (exception: any) { + this.notificationService.logException(exception, 'plugin_datasource_transaction_manager_commit_mode_fail'); + } + break; default: break; @@ -95,4 +132,26 @@ export class TransactionManagerBootstrap extends Bootstrap { } load() {} + + private showTransactionResult(transaction: ConnectionExecutionContext, taskInfo: AsyncTaskInfo) { + if (!transaction.context) { + return; + } + + const connectionParam = createConnectionParam(transaction.context.projectId, transaction.context.connectionId); + const connection = this.connectionInfoResource.get(connectionParam); + const message = typeof taskInfo.taskResult === 'string' ? taskInfo.taskResult : ''; + + this.notificationService.logInfo({ title: connection?.name ?? taskInfo.name ?? '', message }); + } + + private getContextTransaction() { + const context = this.connectionSchemaManagerService.activeExecutionContext; + + if (!context) { + return; + } + + return this.connectionExecutionContextService.get(context.id); + } } diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts deleted file mode 100644 index a884021f0f..0000000000 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerService.ts +++ /dev/null @@ -1,143 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ -import { computed, makeAutoObservable } from 'mobx'; - -import { ConnectionExecutionContextResource, ConnectionInfoResource, createConnectionParam } from '@cloudbeaver/core-connections'; -import { injectable } from '@cloudbeaver/core-di'; -import { NotificationService } from '@cloudbeaver/core-events'; -import { TaskScheduler } from '@cloudbeaver/core-executor'; -import { AsyncTaskInfoService, GraphQLService } from '@cloudbeaver/core-sdk'; -import { MetadataMap } from '@cloudbeaver/core-utils'; -import { ConnectionSchemaManagerService } from '@cloudbeaver/plugin-datasource-context-switch'; - -import { TransactionExecutionContext } from './TransactionExecutionContext'; - -const DEFAULT_AUTO_COMMIT = true; - -@injectable() -export class TransactionManagerService { - get currentContext() { - return this.connectionSchemaManagerService.activeExecutionContext; - } - - get autoCommitMode() { - const context = this.currentContext; - - if (context) { - return context.autoCommit ?? DEFAULT_AUTO_COMMIT; - } - - return DEFAULT_AUTO_COMMIT; - } - - readonly transactions: MetadataMap; - readonly scheduler: TaskScheduler; - - constructor( - private readonly notificationService: NotificationService, - private readonly graphQLService: GraphQLService, - private readonly asyncTaskInfoService: AsyncTaskInfoService, - private readonly connectionExecutionContextResource: ConnectionExecutionContextResource, - private readonly connectionSchemaManagerService: ConnectionSchemaManagerService, - private readonly connectionInfoResource: ConnectionInfoResource, - ) { - this.scheduler = new TaskScheduler((a, b) => a === b); - this.transactions = new MetadataMap( - contextId => new TransactionExecutionContext(this.scheduler, this.connectionExecutionContextResource, contextId), - ); - - makeAutoObservable(this, { - currentContext: computed, - autoCommitMode: computed, - }); - } - - async setAutoCommit(connectionId: string, contextId: string, autoCommit: boolean) { - const transaction = this.transactions.get(contextId); - - const task = this.asyncTaskInfoService.create(async () => { - const { taskInfo } = await this.graphQLService.sdk.asyncSqlSetAutoCommit({ - connectionId, - contextId, - autoCommit, - }); - - return taskInfo; - }); - - try { - await transaction.run( - async () => await this.asyncTaskInfoService.run(task), - () => this.asyncTaskInfoService.cancel(task.id), - () => this.asyncTaskInfoService.remove(task.id), - ); - - await this.connectionExecutionContextResource.refresh(); - } catch (exception: any) { - this.notificationService.logException(exception, 'plugin_datasource_transaction_manager_commit_mode_fail'); - } - } - - async commit(connectionId: string, contextId: string) { - const transaction = this.transactions.get(contextId); - - const task = this.asyncTaskInfoService.create(async () => { - const { taskInfo } = await this.graphQLService.sdk.asyncSqlCommitTransaction({ - connectionId, - contextId, - }); - - return taskInfo; - }); - - try { - const info = await transaction.run( - async () => await this.asyncTaskInfoService.run(task), - () => this.asyncTaskInfoService.cancel(task.id), - () => this.asyncTaskInfoService.remove(task.id), - ); - - const connectionParam = createConnectionParam(transaction.context!.projectId, transaction.context!.connectionId); - const connection = this.connectionInfoResource.get(connectionParam); - const message = typeof info.taskResult === 'string' ? info.taskResult : ''; - - this.notificationService.logInfo({ title: connection?.name ?? info.name ?? '', message }); - } catch (exception: any) { - this.notificationService.logException(exception, 'plugin_datasource_transaction_manager_commit_fail'); - } - } - - async rollback(connectionId: string, contextId: string) { - const transaction = this.transactions.get(contextId); - - const task = this.asyncTaskInfoService.create(async () => { - const { taskInfo } = await this.graphQLService.sdk.asyncSqlRollbackTransaction({ - connectionId, - contextId, - }); - - return taskInfo; - }); - - try { - const info = await transaction.run( - async () => await this.asyncTaskInfoService.run(task), - () => this.asyncTaskInfoService.cancel(task.id), - () => this.asyncTaskInfoService.remove(task.id), - ); - - const connectionParam = createConnectionParam(transaction.context!.projectId, transaction.context!.connectionId); - const connection = this.connectionInfoResource.get(connectionParam); - const message = typeof info.taskResult === 'string' ? info.taskResult : ''; - - this.notificationService.logInfo({ title: connection?.name ?? info.name ?? '', message }); - } catch (exception: any) { - this.notificationService.logException(exception, 'plugin_datasource_transaction_manager_rollback_fail'); - } - } -} diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts b/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts index 4dd50d2fd4..772c2c8a29 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts @@ -1,9 +1,9 @@ export default [ ['plugin_datasource_transaction_manager_commit', 'Commit'], ['plugin_datasource_transaction_manager_rollback', 'Rollback'], - ['plugin_datasource_transaction_manager_commit_mode_switch_to_auto', 'Switch to auto-commit'], - ['plugin_datasource_transaction_manager_commit_mode_switch_to_manual', 'Switch to manual commit'], - ['plugin_datasource_transaction_manager_commit_fail', 'Failed to commit transaction'], - ['plugin_datasource_transaction_manager_rollback_fail', 'Failed to rollback transaction'], - ['plugin_datasource_transaction_manager_commit_mode_fail', 'Failed to change commit mode'], + ['plugin_datasource_transaction_manager_commit_mode_switch_to_auto', 'Переключить в авто-коммит'], + ['plugin_datasource_transaction_manager_commit_mode_switch_to_manual', 'Переключить в ручной коммит'], + ['plugin_datasource_transaction_manager_commit_fail', 'Не удалось выполнить коммит'], + ['plugin_datasource_transaction_manager_rollback_fail', 'Не удалось выполнить откат'], + ['plugin_datasource_transaction_manager_commit_mode_fail', 'Не удалось переключить режим коммита'], ]; diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/manifest.ts b/webapp/packages/plugin-datasource-transaction-manager/src/manifest.ts index abe7c1b876..b46508e305 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/manifest.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/manifest.ts @@ -9,12 +9,11 @@ import type { PluginManifest } from '@cloudbeaver/core-di'; import { LocaleService } from './LocaleService'; import { TransactionManagerBootstrap } from './TransactionManagerBootstrap'; -import { TransactionManagerService } from './TransactionManagerService'; export const datasourceTransactionManagerPlugin: PluginManifest = { info: { name: 'Datasource transaction manager plugin', }, - providers: [TransactionManagerBootstrap, LocaleService, TransactionManagerService], + providers: [TransactionManagerBootstrap, LocaleService], }; From 08c308ee5d2a709ac2fc50f3136c9ddfed0cd2a3 Mon Sep 17 00:00:00 2001 From: Ainur Date: Tue, 12 Mar 2024 12:21:26 +0100 Subject: [PATCH 17/25] CB-4806 make project id required --- .../io.cloudbeaver.server/schema/service.sql.graphqls | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls b/server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls index 0aa108efe0..d5ab8ee8e8 100644 --- a/server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls +++ b/server/bundles/io.cloudbeaver.server/schema/service.sql.graphqls @@ -404,7 +404,7 @@ extend type Mutation { @since(version: "24.0.1") asyncSqlSetAutoCommit( - projectId: ID, + projectId: ID!, connectionId: ID!, contextId: ID!, autoCommit: Boolean! @@ -412,14 +412,14 @@ extend type Mutation { @since(version: "24.0.1") asyncSqlCommitTransaction( - projectId: ID, + projectId: ID!, connectionId: ID!, contextId: ID! ): AsyncTaskInfo! @since(version: "24.0.1") asyncSqlRollbackTransaction( - projectId: ID, + projectId: ID!, connectionId: ID!, contextId: ID! ): AsyncTaskInfo! From 2f2e35f10ab6f7c2704daeb4b329e63223480d22 Mon Sep 17 00:00:00 2001 From: naumov Date: Tue, 12 Mar 2024 15:42:10 +0100 Subject: [PATCH 18/25] CB-1084 make actions naming more unique --- .../ConnectionExecutionContext.ts | 41 ++++++++---- .../AsyncTask/ASYNC_TASK_STATUS_FINISHED.ts | 8 +++ webapp/packages/core-sdk/src/index.ts | 1 + .../asyncSqlCommitTransaction.gql | 2 +- .../asyncSqlRollbackTransaction.gql | 2 +- .../transactions/asyncSqlSetAutoCommit.gql | 2 +- .../src/TransactionManagerBootstrap.ts | 62 +++++++++++-------- ...> ACTION_DATASOURCE_TRANSACTION_COMMIT.ts} | 2 +- ...ASOURCE_TRANSACTION_COMMIT_MODE_TOGGLE.ts} | 2 +- ...ACTION_DATASOURCE_TRANSACTION_ROLLBACK.ts} | 2 +- 10 files changed, 79 insertions(+), 45 deletions(-) create mode 100644 webapp/packages/core-sdk/src/AsyncTask/ASYNC_TASK_STATUS_FINISHED.ts rename webapp/packages/plugin-datasource-transaction-manager/src/actions/{ACTION_COMMIT.ts => ACTION_DATASOURCE_TRANSACTION_COMMIT.ts} (81%) rename webapp/packages/plugin-datasource-transaction-manager/src/actions/{ACTION_COMMIT_MODE_TOGGLE.ts => ACTION_DATASOURCE_TRANSACTION_COMMIT_MODE_TOGGLE.ts} (79%) rename webapp/packages/plugin-datasource-transaction-manager/src/actions/{ACTION_ROLLBACK.ts => ACTION_DATASOURCE_TRANSACTION_ROLLBACK.ts} (80%) diff --git a/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContext.ts b/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContext.ts index d205f4d2af..e6bb20ea7b 100644 --- a/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContext.ts +++ b/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContext.ts @@ -8,12 +8,16 @@ import { computed, makeObservable, observable } from 'mobx'; import type { ITask, TaskScheduler } from '@cloudbeaver/core-executor'; -import type { AsyncTaskInfoService, GraphQLService } from '@cloudbeaver/core-sdk'; +import { ASYNC_TASK_STATUS_FINISHED, AsyncTaskInfo, type AsyncTaskInfoService, type GraphQLService } from '@cloudbeaver/core-sdk'; import type { ConnectionExecutionContextResource, IConnectionExecutionContextInfo } from './ConnectionExecutionContextResource'; import type { IConnectionExecutionContext } from './IConnectionExecutionContext'; -const DEFAULT_AUTO_COMMIT = true; +export interface IConnectionExecutionContextUpdateTaskInfo { + success: boolean; + name?: string; + result?: string | boolean; +} export class ConnectionExecutionContext implements IConnectionExecutionContext { get context(): IConnectionExecutionContextInfo | undefined { @@ -28,12 +32,12 @@ export class ConnectionExecutionContext implements IConnectionExecutionContext { return this.currentTask?.cancellable || false; } - get currentCommitMode() { - if (this.context) { - return this.context.autoCommit ?? DEFAULT_AUTO_COMMIT; + get autoCommit() { + if (!this.context) { + return; } - return DEFAULT_AUTO_COMMIT; + return this.context.autoCommit; } private currentTask: ITask | null; @@ -51,7 +55,7 @@ export class ConnectionExecutionContext implements IConnectionExecutionContext { context: computed, executing: computed, cancellable: computed, - currentCommitMode: computed, + autoCommit: computed, }); } @@ -91,10 +95,11 @@ export class ConnectionExecutionContext implements IConnectionExecutionContext { return await this.connectionExecutionContextResource.update(this.contextId, defaultCatalog, defaultSchema); } - async setAutoCommit(auto: boolean) { + async setAutoCommit(auto: boolean): Promise { const result = await this.withContext(async context => { const task = this.asyncTaskInfoService.create(async () => { const { taskInfo } = await this.graphQLService.sdk.asyncSqlSetAutoCommit({ + projectId: context.projectId, connectionId: context.connectionId, contextId: context.id, autoCommit: auto, @@ -110,13 +115,14 @@ export class ConnectionExecutionContext implements IConnectionExecutionContext { ); }); - return result; + return mapAsyncTaskInfo(result); } - async commit() { + async commit(): Promise { const result = await this.withContext(async context => { const task = this.asyncTaskInfoService.create(async () => { const { taskInfo } = await this.graphQLService.sdk.asyncSqlCommitTransaction({ + projectId: context.projectId, connectionId: context.connectionId, contextId: context.id, }); @@ -131,13 +137,14 @@ export class ConnectionExecutionContext implements IConnectionExecutionContext { ); }); - return result; + return mapAsyncTaskInfo(result); } - async rollback() { + async rollback(): Promise { const result = await this.withContext(async context => { const task = this.asyncTaskInfoService.create(async () => { const { taskInfo } = await this.graphQLService.sdk.asyncSqlRollbackTransaction({ + projectId: context.projectId, connectionId: context.connectionId, contextId: context.id, }); @@ -152,7 +159,7 @@ export class ConnectionExecutionContext implements IConnectionExecutionContext { ); }); - return result; + return mapAsyncTaskInfo(result); } private withContext(callback: (context: IConnectionExecutionContextInfo) => Promise): Promise { @@ -163,3 +170,11 @@ export class ConnectionExecutionContext implements IConnectionExecutionContext { return callback(this.context); } } + +function mapAsyncTaskInfo(info: AsyncTaskInfo): IConnectionExecutionContextUpdateTaskInfo { + return { + success: info.status === ASYNC_TASK_STATUS_FINISHED && !info.error, + name: info.name, + result: info.taskResult, + }; +} diff --git a/webapp/packages/core-sdk/src/AsyncTask/ASYNC_TASK_STATUS_FINISHED.ts b/webapp/packages/core-sdk/src/AsyncTask/ASYNC_TASK_STATUS_FINISHED.ts new file mode 100644 index 0000000000..3e6302449e --- /dev/null +++ b/webapp/packages/core-sdk/src/AsyncTask/ASYNC_TASK_STATUS_FINISHED.ts @@ -0,0 +1,8 @@ +/* + * CloudBeaver - Cloud Database Manager + * Copyright (C) 2020-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0. + * you may not use this file except in compliance with the License. + */ +export const ASYNC_TASK_STATUS_FINISHED = 'Finished'; diff --git a/webapp/packages/core-sdk/src/index.ts b/webapp/packages/core-sdk/src/index.ts index 4f112e88e0..cde6c88a3c 100644 --- a/webapp/packages/core-sdk/src/index.ts +++ b/webapp/packages/core-sdk/src/index.ts @@ -1,5 +1,6 @@ export * from './AsyncTask/AsyncTask'; export * from './AsyncTask/AsyncTaskInfoService'; +export * from './AsyncTask/ASYNC_TASK_STATUS_FINISHED'; export * from './Extensions/uploadBlobResultSetExtension'; export * from './CustomGraphQLClient'; export * from './DetailsError'; diff --git a/webapp/packages/core-sdk/src/queries/transactions/asyncSqlCommitTransaction.gql b/webapp/packages/core-sdk/src/queries/transactions/asyncSqlCommitTransaction.gql index 6fc4fae90e..8253d797a6 100644 --- a/webapp/packages/core-sdk/src/queries/transactions/asyncSqlCommitTransaction.gql +++ b/webapp/packages/core-sdk/src/queries/transactions/asyncSqlCommitTransaction.gql @@ -1,4 +1,4 @@ -mutation asyncSqlCommitTransaction($projectId: ID, $connectionId: ID!, $contextId: ID!) { +mutation asyncSqlCommitTransaction($projectId: ID!, $connectionId: ID!, $contextId: ID!) { taskInfo: asyncSqlCommitTransaction(projectId: $projectId, connectionId: $connectionId, contextId: $contextId) { ...AsyncTaskInfo } diff --git a/webapp/packages/core-sdk/src/queries/transactions/asyncSqlRollbackTransaction.gql b/webapp/packages/core-sdk/src/queries/transactions/asyncSqlRollbackTransaction.gql index d21d537ee2..2b13f458cf 100644 --- a/webapp/packages/core-sdk/src/queries/transactions/asyncSqlRollbackTransaction.gql +++ b/webapp/packages/core-sdk/src/queries/transactions/asyncSqlRollbackTransaction.gql @@ -1,4 +1,4 @@ -mutation asyncSqlRollbackTransaction($projectId: ID, $connectionId: ID!, $contextId: ID!) { +mutation asyncSqlRollbackTransaction($projectId: ID!, $connectionId: ID!, $contextId: ID!) { taskInfo: asyncSqlRollbackTransaction(projectId: $projectId, connectionId: $connectionId, contextId: $contextId) { ...AsyncTaskInfo } diff --git a/webapp/packages/core-sdk/src/queries/transactions/asyncSqlSetAutoCommit.gql b/webapp/packages/core-sdk/src/queries/transactions/asyncSqlSetAutoCommit.gql index 7a1f75cc3d..9b2a6de697 100644 --- a/webapp/packages/core-sdk/src/queries/transactions/asyncSqlSetAutoCommit.gql +++ b/webapp/packages/core-sdk/src/queries/transactions/asyncSqlSetAutoCommit.gql @@ -1,4 +1,4 @@ -mutation asyncSqlSetAutoCommit($projectId: ID, $connectionId: ID!, $contextId: ID!, $autoCommit: Boolean!) { +mutation asyncSqlSetAutoCommit($projectId: ID!, $connectionId: ID!, $contextId: ID!, $autoCommit: Boolean!) { taskInfo: asyncSqlSetAutoCommit(projectId: $projectId, connectionId: $connectionId, contextId: $contextId, autoCommit: $autoCommit) { ...AsyncTaskInfo } diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts index b93289963c..8ec695af04 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts @@ -11,18 +11,18 @@ import { ConnectionExecutionContextService, ConnectionInfoResource, createConnectionParam, + IConnectionExecutionContextUpdateTaskInfo, } from '@cloudbeaver/core-connections'; import { Bootstrap, injectable } from '@cloudbeaver/core-di'; import { NotificationService } from '@cloudbeaver/core-events'; -import type { AsyncTaskInfo } from '@cloudbeaver/core-sdk'; import { OptionsPanelService } from '@cloudbeaver/core-ui'; import { ActionService, MenuService } from '@cloudbeaver/core-view'; import { ConnectionSchemaManagerService } from '@cloudbeaver/plugin-datasource-context-switch'; import { MENU_APP_ACTIONS } from '@cloudbeaver/plugin-top-app-bar'; -import { ACTION_COMMIT } from './actions/ACTION_COMMIT'; -import { ACTION_COMMIT_MODE_TOGGLE } from './actions/ACTION_COMMIT_MODE_TOGGLE'; -import { ACTION_ROLLBACK } from './actions/ACTION_ROLLBACK'; +import { ACTION_DATASOURCE_TRANSACTION_COMMIT } from './actions/ACTION_DATASOURCE_TRANSACTION_COMMIT'; +import { ACTION_DATASOURCE_TRANSACTION_COMMIT_MODE_TOGGLE } from './actions/ACTION_DATASOURCE_TRANSACTION_COMMIT_MODE_TOGGLE'; +import { ACTION_DATASOURCE_TRANSACTION_ROLLBACK } from './actions/ACTION_DATASOURCE_TRANSACTION_ROLLBACK'; @injectable() export class TransactionManagerBootstrap extends Bootstrap { @@ -42,17 +42,31 @@ export class TransactionManagerBootstrap extends Bootstrap { register() { this.menuService.addCreator({ menus: [MENU_APP_ACTIONS], - isApplicable: () => - !this.optionsPanelService.active && - this.connectionSchemaManagerService.currentConnection?.connected === true && - this.connectionSchemaManagerService.activeExecutionContext !== undefined, - getItems: (_, items) => [...items, ACTION_COMMIT, ACTION_ROLLBACK, ACTION_COMMIT_MODE_TOGGLE], + isApplicable: () => { + const transaction = this.getContextTransaction(); + + return ( + !this.optionsPanelService.active && + this.connectionSchemaManagerService.currentConnection?.connected === true && + transaction?.context !== undefined && + transaction.autoCommit !== undefined + ); + }, + getItems: (_, items) => [ + ...items, + ACTION_DATASOURCE_TRANSACTION_COMMIT, + ACTION_DATASOURCE_TRANSACTION_ROLLBACK, + ACTION_DATASOURCE_TRANSACTION_COMMIT_MODE_TOGGLE, + ], }); this.actionService.addHandler({ id: 'commit-mode-base', - isActionApplicable: (_, action) => [ACTION_COMMIT, ACTION_ROLLBACK, ACTION_COMMIT_MODE_TOGGLE].includes(action), - isLabelVisible: (_, action) => action === ACTION_COMMIT || action === ACTION_ROLLBACK, + isActionApplicable: (_, action) => + [ACTION_DATASOURCE_TRANSACTION_COMMIT, ACTION_DATASOURCE_TRANSACTION_ROLLBACK, ACTION_DATASOURCE_TRANSACTION_COMMIT_MODE_TOGGLE].includes( + action, + ), + isLabelVisible: (_, action) => action === ACTION_DATASOURCE_TRANSACTION_COMMIT || action === ACTION_DATASOURCE_TRANSACTION_ROLLBACK, getActionInfo: (_, action) => { const transaction = this.getContextTransaction(); @@ -60,8 +74,8 @@ export class TransactionManagerBootstrap extends Bootstrap { return action.info; } - if (action === ACTION_COMMIT_MODE_TOGGLE) { - const auto = transaction.currentCommitMode; + if (action === ACTION_DATASOURCE_TRANSACTION_COMMIT_MODE_TOGGLE) { + const auto = transaction.autoCommit; const icon = `/icons/commit_mode_${auto ? 'auto' : 'manual'}_m.svg`; const label = `plugin_datasource_transaction_manager_commit_mode_switch_to_${auto ? 'manual' : 'auto'}`; @@ -81,8 +95,8 @@ export class TransactionManagerBootstrap extends Bootstrap { return true; } - if (action === ACTION_COMMIT || action === ACTION_ROLLBACK) { - return transaction.currentCommitMode; + if (action === ACTION_DATASOURCE_TRANSACTION_COMMIT || action === ACTION_DATASOURCE_TRANSACTION_ROLLBACK) { + return transaction.autoCommit === true; } return false; @@ -95,7 +109,7 @@ export class TransactionManagerBootstrap extends Bootstrap { } switch (action) { - case ACTION_COMMIT: { + case ACTION_DATASOURCE_TRANSACTION_COMMIT: { try { const result = await transaction.commit(); this.showTransactionResult(transaction, result); @@ -105,7 +119,7 @@ export class TransactionManagerBootstrap extends Bootstrap { break; } - case ACTION_ROLLBACK: { + case ACTION_DATASOURCE_TRANSACTION_ROLLBACK: { try { const result = await transaction.rollback(); this.showTransactionResult(transaction, result); @@ -115,34 +129,30 @@ export class TransactionManagerBootstrap extends Bootstrap { break; } - case ACTION_COMMIT_MODE_TOGGLE: + case ACTION_DATASOURCE_TRANSACTION_COMMIT_MODE_TOGGLE: try { - await transaction.setAutoCommit(!transaction.currentCommitMode); + await transaction.setAutoCommit(!transaction.autoCommit); await this.connectionExecutionContextResource.refresh(); } catch (exception: any) { this.notificationService.logException(exception, 'plugin_datasource_transaction_manager_commit_mode_fail'); } - break; - default: break; } }, }); } - load() {} - - private showTransactionResult(transaction: ConnectionExecutionContext, taskInfo: AsyncTaskInfo) { + private showTransactionResult(transaction: ConnectionExecutionContext, info: IConnectionExecutionContextUpdateTaskInfo) { if (!transaction.context) { return; } const connectionParam = createConnectionParam(transaction.context.projectId, transaction.context.connectionId); const connection = this.connectionInfoResource.get(connectionParam); - const message = typeof taskInfo.taskResult === 'string' ? taskInfo.taskResult : ''; + const message = typeof info.result === 'string' ? info.result : ''; - this.notificationService.logInfo({ title: connection?.name ?? taskInfo.name ?? '', message }); + this.notificationService.logInfo({ title: connection?.name ?? info.name ?? '', message }); } private getContextTransaction() { diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT.ts b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_DATASOURCE_TRANSACTION_COMMIT.ts similarity index 81% rename from webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT.ts rename to webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_DATASOURCE_TRANSACTION_COMMIT.ts index be41e45f51..ed5c81d8d9 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_DATASOURCE_TRANSACTION_COMMIT.ts @@ -7,7 +7,7 @@ */ import { createAction } from '@cloudbeaver/core-view'; -export const ACTION_COMMIT = createAction('commit', { +export const ACTION_DATASOURCE_TRANSACTION_COMMIT = createAction('datasource-transaction-commit', { label: 'plugin_datasource_transaction_manager_commit', tooltip: 'plugin_datasource_transaction_manager_commit', icon: '/icons/commit_m.svg', diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_DATASOURCE_TRANSACTION_COMMIT_MODE_TOGGLE.ts similarity index 79% rename from webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts rename to webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_DATASOURCE_TRANSACTION_COMMIT_MODE_TOGGLE.ts index bc0f868d46..66f485f534 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_COMMIT_MODE_TOGGLE.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_DATASOURCE_TRANSACTION_COMMIT_MODE_TOGGLE.ts @@ -7,7 +7,7 @@ */ import { createAction } from '@cloudbeaver/core-view'; -export const ACTION_COMMIT_MODE_TOGGLE = createAction('commit-mode-toggle', { +export const ACTION_DATASOURCE_TRANSACTION_COMMIT_MODE_TOGGLE = createAction('datasource-transaction-commit-mode-toggle', { label: 'plugin_datasource_transaction_manager_commit_mode_switch_to_manual', tooltip: 'plugin_datasource_transaction_manager_commit_mode_switch_to_manual', icon: '/icons/commit_mode_auto_m.svg', diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_ROLLBACK.ts b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_DATASOURCE_TRANSACTION_ROLLBACK.ts similarity index 80% rename from webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_ROLLBACK.ts rename to webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_DATASOURCE_TRANSACTION_ROLLBACK.ts index feb3c3f771..e801026795 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_ROLLBACK.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/actions/ACTION_DATASOURCE_TRANSACTION_ROLLBACK.ts @@ -7,7 +7,7 @@ */ import { createAction } from '@cloudbeaver/core-view'; -export const ACTION_ROLLBACK = createAction('rollback', { +export const ACTION_DATASOURCE_TRANSACTION_ROLLBACK = createAction('datasource-transaction-rollback', { label: 'plugin_datasource_transaction_manager_rollback', tooltip: 'plugin_datasource_transaction_manager_rollback', icon: '/icons/rollback_m.svg', From d5708f1c4805d6a3b0234a813430110c087c4b1d Mon Sep 17 00:00:00 2001 From: naumov Date: Tue, 12 Mar 2024 16:02:37 +0100 Subject: [PATCH 19/25] CB-1084 remove success flag --- .../ConnectionExecutionContext.ts | 4 +--- .../core-sdk/src/AsyncTask/ASYNC_TASK_STATUS_FINISHED.ts | 8 -------- webapp/packages/core-sdk/src/index.ts | 1 - 3 files changed, 1 insertion(+), 12 deletions(-) delete mode 100644 webapp/packages/core-sdk/src/AsyncTask/ASYNC_TASK_STATUS_FINISHED.ts diff --git a/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContext.ts b/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContext.ts index e6bb20ea7b..b06e38d3d8 100644 --- a/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContext.ts +++ b/webapp/packages/core-connections/src/ConnectionExecutionContext/ConnectionExecutionContext.ts @@ -8,13 +8,12 @@ import { computed, makeObservable, observable } from 'mobx'; import type { ITask, TaskScheduler } from '@cloudbeaver/core-executor'; -import { ASYNC_TASK_STATUS_FINISHED, AsyncTaskInfo, type AsyncTaskInfoService, type GraphQLService } from '@cloudbeaver/core-sdk'; +import type { AsyncTaskInfo, AsyncTaskInfoService, GraphQLService } from '@cloudbeaver/core-sdk'; import type { ConnectionExecutionContextResource, IConnectionExecutionContextInfo } from './ConnectionExecutionContextResource'; import type { IConnectionExecutionContext } from './IConnectionExecutionContext'; export interface IConnectionExecutionContextUpdateTaskInfo { - success: boolean; name?: string; result?: string | boolean; } @@ -173,7 +172,6 @@ export class ConnectionExecutionContext implements IConnectionExecutionContext { function mapAsyncTaskInfo(info: AsyncTaskInfo): IConnectionExecutionContextUpdateTaskInfo { return { - success: info.status === ASYNC_TASK_STATUS_FINISHED && !info.error, name: info.name, result: info.taskResult, }; diff --git a/webapp/packages/core-sdk/src/AsyncTask/ASYNC_TASK_STATUS_FINISHED.ts b/webapp/packages/core-sdk/src/AsyncTask/ASYNC_TASK_STATUS_FINISHED.ts deleted file mode 100644 index 3e6302449e..0000000000 --- a/webapp/packages/core-sdk/src/AsyncTask/ASYNC_TASK_STATUS_FINISHED.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * CloudBeaver - Cloud Database Manager - * Copyright (C) 2020-2024 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0. - * you may not use this file except in compliance with the License. - */ -export const ASYNC_TASK_STATUS_FINISHED = 'Finished'; diff --git a/webapp/packages/core-sdk/src/index.ts b/webapp/packages/core-sdk/src/index.ts index cde6c88a3c..4f112e88e0 100644 --- a/webapp/packages/core-sdk/src/index.ts +++ b/webapp/packages/core-sdk/src/index.ts @@ -1,6 +1,5 @@ export * from './AsyncTask/AsyncTask'; export * from './AsyncTask/AsyncTaskInfoService'; -export * from './AsyncTask/ASYNC_TASK_STATUS_FINISHED'; export * from './Extensions/uploadBlobResultSetExtension'; export * from './CustomGraphQLClient'; export * from './DetailsError'; From c2fc9944e4abb6e8eb63bc36e6c35bf82bd00310 Mon Sep 17 00:00:00 2001 From: naumov Date: Tue, 12 Mar 2024 16:20:37 +0100 Subject: [PATCH 20/25] CB-1084 add plugin to default product --- .../plugin-datasource-transaction-manager/package.json | 1 + .../plugin-datasource-transaction-manager/tsconfig.json | 3 +++ webapp/packages/product-default/package.json | 1 + webapp/packages/product-default/src/index.ts | 2 ++ webapp/packages/product-default/tsconfig.json | 3 +++ 5 files changed, 10 insertions(+) diff --git a/webapp/packages/plugin-datasource-transaction-manager/package.json b/webapp/packages/plugin-datasource-transaction-manager/package.json index bd452af51a..cc10783b7a 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/package.json +++ b/webapp/packages/plugin-datasource-transaction-manager/package.json @@ -23,6 +23,7 @@ "@cloudbeaver/core-executor": "~0.1.0", "@cloudbeaver/core-localization": "~0.1.0", "@cloudbeaver/core-sdk": "~0.1.0", + "@cloudbeaver/core-ui": "~0.1.0", "@cloudbeaver/core-utils": "~0.1.0", "@cloudbeaver/core-view": "~0.1.0", "@cloudbeaver/plugin-datasource-context-switch": "~0.1.0", diff --git a/webapp/packages/plugin-datasource-transaction-manager/tsconfig.json b/webapp/packages/plugin-datasource-transaction-manager/tsconfig.json index f72500d70a..f336f7ca0b 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/tsconfig.json +++ b/webapp/packages/plugin-datasource-transaction-manager/tsconfig.json @@ -24,6 +24,9 @@ { "path": "../core-sdk/tsconfig.json" }, + { + "path": "../core-ui/tsconfig.json" + }, { "path": "../core-utils/tsconfig.json" }, diff --git a/webapp/packages/product-default/package.json b/webapp/packages/product-default/package.json index 331f2ebe4d..599560f9c7 100644 --- a/webapp/packages/product-default/package.json +++ b/webapp/packages/product-default/package.json @@ -46,6 +46,7 @@ "@cloudbeaver/plugin-data-viewer": "~0.1.0", "@cloudbeaver/plugin-data-viewer-result-set-grouping": "~0.1.0", "@cloudbeaver/plugin-datasource-context-switch": "~0.1.0", + "@cloudbeaver/plugin-datasource-transaction-manager": "~0.1.0", "@cloudbeaver/plugin-ddl-viewer": "~0.1.0", "@cloudbeaver/plugin-devtools": "~0.1.0", "@cloudbeaver/plugin-gis-viewer": "~0.1.0", diff --git a/webapp/packages/product-default/src/index.ts b/webapp/packages/product-default/src/index.ts index 70751df971..b4b13d7e6b 100644 --- a/webapp/packages/product-default/src/index.ts +++ b/webapp/packages/product-default/src/index.ts @@ -17,6 +17,7 @@ import { dataSpreadsheetNewManifest } from '@cloudbeaver/plugin-data-spreadsheet import { dataViewerManifest } from '@cloudbeaver/plugin-data-viewer'; import { dvResultSetGroupingPlugin } from '@cloudbeaver/plugin-data-viewer-result-set-grouping'; import { datasourceContextSwitchPluginManifest } from '@cloudbeaver/plugin-datasource-context-switch'; +import { datasourceTransactionManagerPlugin } from '@cloudbeaver/plugin-datasource-transaction-manager'; import ddlViewer from '@cloudbeaver/plugin-ddl-viewer'; import devTools from '@cloudbeaver/plugin-devtools'; import gisViewer from '@cloudbeaver/plugin-gis-viewer'; @@ -106,6 +107,7 @@ const PLUGINS: PluginManifest[] = [ root, sessionExpirationPlugin, toolsPanel, + datasourceTransactionManagerPlugin, projects, browserPlugin, navigationTreeFilters, diff --git a/webapp/packages/product-default/tsconfig.json b/webapp/packages/product-default/tsconfig.json index ead0ffaad6..0f5134c4b2 100644 --- a/webapp/packages/product-default/tsconfig.json +++ b/webapp/packages/product-default/tsconfig.json @@ -69,6 +69,9 @@ { "path": "../plugin-datasource-context-switch/tsconfig.json" }, + { + "path": "../plugin-datasource-transaction-manager/tsconfig.json" + }, { "path": "../plugin-ddl-viewer/tsconfig.json" }, From 9e1d3847ce030cfd3396995b9b5cfb681ca5dc16 Mon Sep 17 00:00:00 2001 From: naumov Date: Thu, 14 Mar 2024 17:47:06 +0100 Subject: [PATCH 21/25] CB-1084 show confirm dialog --- .../src/TransactionManagerBootstrap.ts | 56 ++++++++++++++++--- .../src/locales/en.ts | 1 + .../src/locales/it.ts | 1 + .../src/locales/ru.ts | 1 + .../src/locales/zh.ts | 1 + 5 files changed, 53 insertions(+), 7 deletions(-) diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts index 8ec695af04..156374bbaa 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts @@ -5,16 +5,22 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ +import { ConfirmationDialog } from '@cloudbeaver/core-blocks'; import { ConnectionExecutionContext, ConnectionExecutionContextResource, ConnectionExecutionContextService, ConnectionInfoResource, + ConnectionsManagerService, createConnectionParam, IConnectionExecutionContextUpdateTaskInfo, + IConnectionExecutorData, } from '@cloudbeaver/core-connections'; import { Bootstrap, injectable } from '@cloudbeaver/core-di'; +import { CommonDialogService, DialogueStateResult } from '@cloudbeaver/core-dialogs'; import { NotificationService } from '@cloudbeaver/core-events'; +import { ExecutorInterrupter, type IExecutionContextProvider } from '@cloudbeaver/core-executor'; +import { LocalizationService } from '@cloudbeaver/core-localization'; import { OptionsPanelService } from '@cloudbeaver/core-ui'; import { ActionService, MenuService } from '@cloudbeaver/core-view'; import { ConnectionSchemaManagerService } from '@cloudbeaver/plugin-datasource-context-switch'; @@ -33,13 +39,18 @@ export class TransactionManagerBootstrap extends Bootstrap { private readonly connectionExecutionContextService: ConnectionExecutionContextService, private readonly connectionExecutionContextResource: ConnectionExecutionContextResource, private readonly connectionInfoResource: ConnectionInfoResource, + private readonly connectionsManagerService: ConnectionsManagerService, private readonly optionsPanelService: OptionsPanelService, private readonly notificationService: NotificationService, + private readonly commonDialogService: CommonDialogService, + private readonly localizationService: LocalizationService, ) { super(); } register() { + this.connectionsManagerService.onDisconnect.addHandler(this.disconnectHandler.bind(this)); + this.menuService.addCreator({ menus: [MENU_APP_ACTIONS], isApplicable: () => { @@ -110,13 +121,7 @@ export class TransactionManagerBootstrap extends Bootstrap { switch (action) { case ACTION_DATASOURCE_TRANSACTION_COMMIT: { - try { - const result = await transaction.commit(); - this.showTransactionResult(transaction, result); - } catch (exception: any) { - this.notificationService.logException(exception, 'plugin_datasource_transaction_manager_commit_fail'); - } - + await this.commit(transaction); break; } case ACTION_DATASOURCE_TRANSACTION_ROLLBACK: { @@ -164,4 +169,41 @@ export class TransactionManagerBootstrap extends Bootstrap { return this.connectionExecutionContextService.get(context.id); } + + private async disconnectHandler(data: IConnectionExecutorData, contexts: IExecutionContextProvider) { + for (const connection of data.connections) { + const context = this.connectionExecutionContextResource.values.find( + c => c.connectionId === connection.connectionId && c.projectId === connection.projectId, + ); + + if (context) { + const transaction = this.connectionExecutionContextService.get(context.id); + + if (transaction?.autoCommit === false) { + const connectionData = this.connectionInfoResource.get(connection); + const state = await this.commonDialogService.open(ConfirmationDialog, { + title: `${this.localizationService.translate('plugin_datasource_transaction_manager_commit')} (${connectionData?.name ?? context.id})`, + message: 'plugin_datasource_transaction_manager_commit_confirmation_message', + confirmActionText: 'plugin_datasource_transaction_manager_commit', + extraStatus: 'no', + }); + + if (state === DialogueStateResult.Resolved) { + await this.commit(transaction); + } else if (state === DialogueStateResult.Rejected) { + ExecutorInterrupter.interrupt(contexts); + } + } + } + } + } + + private async commit(transaction: ConnectionExecutionContext) { + try { + const result = await transaction.commit(); + this.showTransactionResult(transaction, result); + } catch (exception: any) { + this.notificationService.logException(exception, 'plugin_datasource_transaction_manager_commit_fail'); + } + } } diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/locales/en.ts b/webapp/packages/plugin-datasource-transaction-manager/src/locales/en.ts index 4dd50d2fd4..f113567706 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/locales/en.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/locales/en.ts @@ -6,4 +6,5 @@ export default [ ['plugin_datasource_transaction_manager_commit_fail', 'Failed to commit transaction'], ['plugin_datasource_transaction_manager_rollback_fail', 'Failed to rollback transaction'], ['plugin_datasource_transaction_manager_commit_mode_fail', 'Failed to change commit mode'], + ['plugin_datasource_transaction_manager_commit_confirmation_message', 'Do you want to commit changes?'], ]; diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/locales/it.ts b/webapp/packages/plugin-datasource-transaction-manager/src/locales/it.ts index 4dd50d2fd4..f113567706 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/locales/it.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/locales/it.ts @@ -6,4 +6,5 @@ export default [ ['plugin_datasource_transaction_manager_commit_fail', 'Failed to commit transaction'], ['plugin_datasource_transaction_manager_rollback_fail', 'Failed to rollback transaction'], ['plugin_datasource_transaction_manager_commit_mode_fail', 'Failed to change commit mode'], + ['plugin_datasource_transaction_manager_commit_confirmation_message', 'Do you want to commit changes?'], ]; diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts b/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts index 772c2c8a29..921b0e3d58 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/locales/ru.ts @@ -6,4 +6,5 @@ export default [ ['plugin_datasource_transaction_manager_commit_fail', 'Не удалось выполнить коммит'], ['plugin_datasource_transaction_manager_rollback_fail', 'Не удалось выполнить откат'], ['plugin_datasource_transaction_manager_commit_mode_fail', 'Не удалось переключить режим коммита'], + ['plugin_datasource_transaction_manager_commit_confirmation_message', 'Вы хотите зафиксировать изменения?'], ]; diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/locales/zh.ts b/webapp/packages/plugin-datasource-transaction-manager/src/locales/zh.ts index 4dd50d2fd4..f113567706 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/locales/zh.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/locales/zh.ts @@ -6,4 +6,5 @@ export default [ ['plugin_datasource_transaction_manager_commit_fail', 'Failed to commit transaction'], ['plugin_datasource_transaction_manager_rollback_fail', 'Failed to rollback transaction'], ['plugin_datasource_transaction_manager_commit_mode_fail', 'Failed to change commit mode'], + ['plugin_datasource_transaction_manager_commit_confirmation_message', 'Do you want to commit changes?'], ]; From e4ab4f5b777d28083e969302cc8704f01ce207bc Mon Sep 17 00:00:00 2001 From: naumov Date: Thu, 14 Mar 2024 18:13:57 +0100 Subject: [PATCH 22/25] CB-1084 always fire disconnect through executor --- .../src/ConnectionsManagerService.ts | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/webapp/packages/core-connections/src/ConnectionsManagerService.ts b/webapp/packages/core-connections/src/ConnectionsManagerService.ts index 82f695bd68..529ff7efe0 100644 --- a/webapp/packages/core-connections/src/ConnectionsManagerService.ts +++ b/webapp/packages/core-connections/src/ConnectionsManagerService.ts @@ -152,7 +152,24 @@ export class ConnectionsManagerService { if (!connection.connected) { return; } - await this.connectionInfo.close(createConnectionParam(connection)); + + const param = createConnectionParam(connection); + + const contexts = await this.onDisconnect.execute({ + connections: [param], + state: 'before', + }); + + if (ExecutorInterrupter.isInterrupted(contexts)) { + return; + } + + await this.connectionInfo.close(param); + + this.onDisconnect.execute({ + connections: [param], + state: 'after', + }); } async closeAllConnections(): Promise { @@ -166,6 +183,7 @@ export class ConnectionsManagerService { for (const connection of this.projectConnections) { await this._closeConnectionAsync(connection); } + notification.close(); } catch (e: any) { controller.reject(e); @@ -179,14 +197,6 @@ export class ConnectionsManagerService { if (!connection || !connection.connected) { return; } - const contexts = await this.onDisconnect.execute({ - connections: [createConnectionParam(connection)], - state: 'before', - }); - - if (ExecutorInterrupter.isInterrupted(contexts)) { - return; - } const { controller, notification } = this.notificationService.processNotification(() => ProcessSnackbar, {}, { title: 'Disconnecting...' }); @@ -194,10 +204,6 @@ export class ConnectionsManagerService { await this._closeConnectionAsync(connection); notification.close(); - this.onDisconnect.execute({ - connections: [createConnectionParam(connection)], - state: 'after', - }); } catch (exception: any) { controller.reject(exception); } From 1c6beab7f566b5c1ecd566ff015397e713ca55af Mon Sep 17 00:00:00 2001 From: naumov Date: Thu, 14 Mar 2024 19:04:36 +0100 Subject: [PATCH 23/25] CB-1084 adjust behaviour --- .../src/ConnectionsManagerService.ts | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/webapp/packages/core-connections/src/ConnectionsManagerService.ts b/webapp/packages/core-connections/src/ConnectionsManagerService.ts index 529ff7efe0..5146828808 100644 --- a/webapp/packages/core-connections/src/ConnectionsManagerService.ts +++ b/webapp/packages/core-connections/src/ConnectionsManagerService.ts @@ -153,10 +153,17 @@ export class ConnectionsManagerService { return; } - const param = createConnectionParam(connection); + await this.connectionInfo.close(createConnectionParam(connection)); + } + + async closeAllConnections(): Promise { + if (this.disconnecting) { + return; + } + const connectionParams = this.projectConnections.map(connection => createConnectionParam(connection)); const contexts = await this.onDisconnect.execute({ - connections: [param], + connections: connectionParams, state: 'before', }); @@ -164,24 +171,16 @@ export class ConnectionsManagerService { return; } - await this.connectionInfo.close(param); - - this.onDisconnect.execute({ - connections: [param], - state: 'after', - }); - } - - async closeAllConnections(): Promise { - if (this.disconnecting) { - return; - } this.disconnecting = true; const { controller, notification } = this.notificationService.processNotification(() => ProcessSnackbar, {}, { title: 'Disconnecting...' }); try { for (const connection of this.projectConnections) { await this._closeConnectionAsync(connection); + this.onDisconnect.execute({ + connections: [createConnectionParam(connection)], + state: 'after', + }); } notification.close(); @@ -197,6 +196,14 @@ export class ConnectionsManagerService { if (!connection || !connection.connected) { return; } + const contexts = await this.onDisconnect.execute({ + connections: [createConnectionParam(connection)], + state: 'before', + }); + + if (ExecutorInterrupter.isInterrupted(contexts)) { + return; + } const { controller, notification } = this.notificationService.processNotification(() => ProcessSnackbar, {}, { title: 'Disconnecting...' }); @@ -204,6 +211,10 @@ export class ConnectionsManagerService { await this._closeConnectionAsync(connection); notification.close(); + this.onDisconnect.execute({ + connections: [createConnectionParam(connection)], + state: 'after', + }); } catch (exception: any) { controller.reject(exception); } From 0dd614c60bfed7000d54bb3d7b204fd2c200eba2 Mon Sep 17 00:00:00 2001 From: naumov Date: Fri, 15 Mar 2024 15:05:20 +0100 Subject: [PATCH 24/25] CB-1084 add more explicit check --- .../src/TransactionManagerBootstrap.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts index 156374bbaa..27c9c4f437 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts @@ -22,6 +22,7 @@ import { NotificationService } from '@cloudbeaver/core-events'; import { ExecutorInterrupter, type IExecutionContextProvider } from '@cloudbeaver/core-executor'; import { LocalizationService } from '@cloudbeaver/core-localization'; import { OptionsPanelService } from '@cloudbeaver/core-ui'; +import { isNotNullDefined } from '@cloudbeaver/core-utils'; import { ActionService, MenuService } from '@cloudbeaver/core-view'; import { ConnectionSchemaManagerService } from '@cloudbeaver/plugin-datasource-context-switch'; import { MENU_APP_ACTIONS } from '@cloudbeaver/plugin-top-app-bar'; @@ -59,8 +60,8 @@ export class TransactionManagerBootstrap extends Bootstrap { return ( !this.optionsPanelService.active && this.connectionSchemaManagerService.currentConnection?.connected === true && - transaction?.context !== undefined && - transaction.autoCommit !== undefined + !!transaction?.context && + isNotNullDefined(transaction.autoCommit) ); }, getItems: (_, items) => [ From be12770e390e3459f4dca2a74b2b893c82d7f834 Mon Sep 17 00:00:00 2001 From: naumov Date: Fri, 15 Mar 2024 15:28:59 +0100 Subject: [PATCH 25/25] CB-1084 interrupt disconnect if commit fails --- .../src/TransactionManagerBootstrap.ts | 46 ++++++++++--------- .../src/ObjectViewerTabService.ts | 5 +- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts index 27c9c4f437..8dae08b56c 100644 --- a/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts +++ b/webapp/packages/plugin-datasource-transaction-manager/src/TransactionManagerBootstrap.ts @@ -15,6 +15,7 @@ import { createConnectionParam, IConnectionExecutionContextUpdateTaskInfo, IConnectionExecutorData, + isConnectionInfoParamEqual, } from '@cloudbeaver/core-connections'; import { Bootstrap, injectable } from '@cloudbeaver/core-di'; import { CommonDialogService, DialogueStateResult } from '@cloudbeaver/core-dialogs'; @@ -172,39 +173,40 @@ export class TransactionManagerBootstrap extends Bootstrap { } private async disconnectHandler(data: IConnectionExecutorData, contexts: IExecutionContextProvider) { - for (const connection of data.connections) { - const context = this.connectionExecutionContextResource.values.find( - c => c.connectionId === connection.connectionId && c.projectId === connection.projectId, - ); - - if (context) { - const transaction = this.connectionExecutionContextService.get(context.id); - - if (transaction?.autoCommit === false) { - const connectionData = this.connectionInfoResource.get(connection); - const state = await this.commonDialogService.open(ConfirmationDialog, { - title: `${this.localizationService.translate('plugin_datasource_transaction_manager_commit')} (${connectionData?.name ?? context.id})`, - message: 'plugin_datasource_transaction_manager_commit_confirmation_message', - confirmActionText: 'plugin_datasource_transaction_manager_commit', - extraStatus: 'no', - }); - - if (state === DialogueStateResult.Resolved) { - await this.commit(transaction); - } else if (state === DialogueStateResult.Rejected) { - ExecutorInterrupter.interrupt(contexts); + if (data.state === 'before') { + for (const connectionKey of data.connections) { + const context = this.connectionExecutionContextResource.values.find(connection => isConnectionInfoParamEqual(connection, connectionKey)); + + if (context) { + const transaction = this.connectionExecutionContextService.get(context.id); + + if (transaction?.autoCommit === false) { + const connectionData = this.connectionInfoResource.get(connectionKey); + const state = await this.commonDialogService.open(ConfirmationDialog, { + title: `${this.localizationService.translate('plugin_datasource_transaction_manager_commit')} (${connectionData?.name ?? context.id})`, + message: 'plugin_datasource_transaction_manager_commit_confirmation_message', + confirmActionText: 'plugin_datasource_transaction_manager_commit', + extraStatus: 'no', + }); + + if (state === DialogueStateResult.Resolved) { + await this.commit(transaction, () => ExecutorInterrupter.interrupt(contexts)); + } else if (state === DialogueStateResult.Rejected) { + ExecutorInterrupter.interrupt(contexts); + } } } } } } - private async commit(transaction: ConnectionExecutionContext) { + private async commit(transaction: ConnectionExecutionContext, onError?: (exception: any) => void) { try { const result = await transaction.commit(); this.showTransactionResult(transaction, result); } catch (exception: any) { this.notificationService.logException(exception, 'plugin_datasource_transaction_manager_commit_fail'); + onError?.(exception); } } } diff --git a/webapp/packages/plugin-object-viewer/src/ObjectViewerTabService.ts b/webapp/packages/plugin-object-viewer/src/ObjectViewerTabService.ts index 8c07275776..720faaec96 100644 --- a/webapp/packages/plugin-object-viewer/src/ObjectViewerTabService.ts +++ b/webapp/packages/plugin-object-viewer/src/ObjectViewerTabService.ts @@ -18,6 +18,7 @@ import { createConnectionParam, executionContextProvider, IConnectionInfoParams, + isConnectionInfoParamEqual, objectCatalogProvider, objectSchemaProvider, } from '@cloudbeaver/core-connections'; @@ -340,9 +341,7 @@ export class ObjectViewerTabService { return; } - return this.connectionExecutionContextResource.values.find( - c => c.connectionId === connectionKey.connectionId && c.projectId === connectionKey.projectId, - ); + return this.connectionExecutionContextResource.values.find(connection => isConnectionInfoParamEqual(connection, connectionKey)); } private selectObjectTab(tab: ITab) {