From 91e01b747d3cf7afb4443db93faef4eb898b9f09 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Thu, 25 Feb 2021 11:01:06 +0100 Subject: [PATCH] [jOOQ/jOOQ#11520] Add CallbackTransactionListener --- .../java/org/jooq/TransactionListener.java | 54 +- .../org/jooq/impl/CallbackRecordListener.java | 508 ++++++++++++++++++ .../impl/CallbackTransactionListener.java | 195 +++++++ .../jooq/impl/DefaultTransactionListener.java | 5 + 4 files changed, 761 insertions(+), 1 deletion(-) create mode 100644 jOOQ/src/main/java/org/jooq/impl/CallbackRecordListener.java create mode 100644 jOOQ/src/main/java/org/jooq/impl/CallbackTransactionListener.java diff --git a/jOOQ/src/main/java/org/jooq/TransactionListener.java b/jOOQ/src/main/java/org/jooq/TransactionListener.java index d71e998348..0a81efe402 100644 --- a/jOOQ/src/main/java/org/jooq/TransactionListener.java +++ b/jOOQ/src/main/java/org/jooq/TransactionListener.java @@ -37,6 +37,11 @@ */ package org.jooq; +import java.io.Serializable; +import java.util.function.Consumer; + +import org.jooq.impl.CallbackRecordListener; +import org.jooq.impl.CallbackTransactionListener; /** * The TransactionListener SPI is used to intercept the @@ -44,7 +49,7 @@ package org.jooq; * * @author Lukas Eder */ -public interface TransactionListener { +public interface TransactionListener extends Serializable { /** * Called before {@link TransactionProvider#begin(TransactionContext)}. @@ -76,4 +81,51 @@ public interface TransactionListener { */ void rollbackEnd(TransactionContext ctx); + /** + * Create a {@link TransactionListener} with a + * {@link #onBeginStart(Consumer)} implementation. + */ + static CallbackTransactionListener onBeginStart(Consumer onBeginStart) { + return new CallbackTransactionListener().onBeginStart(onBeginStart); + } + + /** + * Create a {@link TransactionListener} with a {@link #onBeginEnd(Consumer)} + * implementation. + */ + static CallbackTransactionListener onBeginEnd(Consumer onBeginEnd) { + return new CallbackTransactionListener().onBeginEnd(onBeginEnd); + } + + /** + * Create a {@link TransactionListener} with a + * {@link #onCommitStart(Consumer)} implementation. + */ + static CallbackTransactionListener onCommitStart(Consumer onCommitStart) { + return new CallbackTransactionListener().onCommitStart(onCommitStart); + } + + /** + * Create a {@link TransactionListener} with a + * {@link #onCommitEnd(Consumer)} implementation. + */ + static CallbackTransactionListener onCommitEnd(Consumer onCommitEnd) { + return new CallbackTransactionListener().onCommitEnd(onCommitEnd); + } + + /** + * Create a {@link TransactionListener} with a + * {@link #onRollbackStart(Consumer)} implementation. + */ + static CallbackTransactionListener onRollbackStart(Consumer onRollbackStart) { + return new CallbackTransactionListener().onRollbackStart(onRollbackStart); + } + + /** + * Create a {@link TransactionListener} with a + * {@link #onRollbackEnd(Consumer)} implementation. + */ + static CallbackTransactionListener onRollbackEnd(Consumer onRollbackEnd) { + return new CallbackTransactionListener().onRollbackEnd(onRollbackEnd); + } } diff --git a/jOOQ/src/main/java/org/jooq/impl/CallbackRecordListener.java b/jOOQ/src/main/java/org/jooq/impl/CallbackRecordListener.java new file mode 100644 index 0000000000..43360d1d62 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/CallbackRecordListener.java @@ -0,0 +1,508 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Other licenses: + * ----------------------------------------------------------------------------- + * Commercial licenses for this work are available. These replace the above + * ASL 2.0 and offer limited warranties, support, maintenance, and commercial + * database integrations. + * + * For more information, please visit: http://www.jooq.org/licenses + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +package org.jooq.impl; + + +import java.util.function.Consumer; + +import org.jooq.RecordContext; +import org.jooq.RecordListener; + +/** + * A {@link RecordListener} that allows for functional composition. + *

+ * For example:

+ * ParseListener listener = RecordListener
+ *   .onLoadStart(ctx -> something())
+ *   .onLoadEnd(ctx -> something());
+ * 
+ * + * @author Lukas Eder + */ +public final class CallbackRecordListener implements RecordListener { + + /** + * Generated UID + */ + private static final long serialVersionUID = -4135358887698253754L; + + private final Consumer onStoreStart; + private final Consumer onStoreEnd; + private final Consumer onInsertStart; + private final Consumer onInsertEnd; + private final Consumer onUpdateStart; + private final Consumer onUpdateEnd; + private final Consumer onMergeStart; + private final Consumer onMergeEnd; + private final Consumer onDeleteStart; + private final Consumer onDeleteEnd; + private final Consumer onLoadStart; + private final Consumer onLoadEnd; + private final Consumer onRefreshStart; + private final Consumer onRefreshEnd; + private final Consumer onException; + + public CallbackRecordListener() { + this(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); + } + + private CallbackRecordListener( + Consumer onStoreStart, + Consumer onStoreEnd, + Consumer onInsertStart, + Consumer onInsertEnd, + Consumer onUpdateStart, + Consumer onUpdateEnd, + Consumer onMergeStart, + Consumer onMergeEnd, + Consumer onDeleteStart, + Consumer onDeleteEnd, + Consumer onLoadStart, + Consumer onLoadEnd, + Consumer onRefreshStart, + Consumer onRefreshEnd, + Consumer onException + ) { + this.onStoreStart = onStoreStart; + this.onStoreEnd = onStoreEnd; + this.onInsertStart = onInsertStart; + this.onInsertEnd = onInsertEnd; + this.onUpdateStart = onUpdateStart; + this.onUpdateEnd = onUpdateEnd; + this.onMergeStart = onMergeStart; + this.onMergeEnd = onMergeEnd; + this.onDeleteStart = onDeleteStart; + this.onDeleteEnd = onDeleteEnd; + this.onLoadStart = onLoadStart; + this.onLoadEnd = onLoadEnd; + this.onRefreshStart = onRefreshStart; + this.onRefreshEnd = onRefreshEnd; + this.onException = onException; + } + + @Override + public final void storeStart(RecordContext ctx) { + if (onStoreStart != null) + onStoreStart.accept(ctx); + } + + @Override + public final void storeEnd(RecordContext ctx) { + if (onStoreEnd != null) + onStoreEnd.accept(ctx); + } + + @Override + public final void insertStart(RecordContext ctx) { + if (onInsertStart != null) + onInsertStart.accept(ctx); + } + + @Override + public final void insertEnd(RecordContext ctx) { + if (onInsertEnd != null) + onInsertEnd.accept(ctx); + } + + @Override + public final void updateStart(RecordContext ctx) { + if (onUpdateStart != null) + onUpdateStart.accept(ctx); + } + + @Override + public final void updateEnd(RecordContext ctx) { + if (onUpdateEnd != null) + onUpdateEnd.accept(ctx); + } + + @Override + public final void mergeStart(RecordContext ctx) { + if (onMergeStart != null) + onMergeStart.accept(ctx); + } + + @Override + public final void mergeEnd(RecordContext ctx) { + if (onMergeEnd != null) + onMergeEnd.accept(ctx); + } + + @Override + public final void deleteStart(RecordContext ctx) { + if (onDeleteStart != null) + onDeleteStart.accept(ctx); + } + + @Override + public final void deleteEnd(RecordContext ctx) { + if (onDeleteEnd != null) + onDeleteEnd.accept(ctx); + } + + @Override + public final void loadStart(RecordContext ctx) { + if (onLoadStart != null) + onLoadStart.accept(ctx); + } + + @Override + public final void loadEnd(RecordContext ctx) { + if (onLoadEnd != null) + onLoadEnd.accept(ctx); + } + + @Override + public final void refreshStart(RecordContext ctx) { + if (onRefreshStart != null) + onRefreshStart.accept(ctx); + } + + @Override + public final void refreshEnd(RecordContext ctx) { + if (onRefreshEnd != null) + onRefreshEnd.accept(ctx); + } + + @Override + public final void exception(RecordContext ctx) { + if (onException != null) + onException.accept(ctx); + } + + public final CallbackRecordListener onStoreStart(Consumer newOnStoreStart) { + return new CallbackRecordListener( + newOnStoreStart, + onStoreEnd, + onInsertStart, + onInsertEnd, + onUpdateStart, + onUpdateEnd, + onMergeStart, + onMergeEnd, + onDeleteStart, + onDeleteEnd, + onLoadStart, + onLoadEnd, + onRefreshStart, + onRefreshEnd, + onException + ); + } + + public final CallbackRecordListener onStoreEnd(Consumer newOnStoreEnd) { + return new CallbackRecordListener( + onStoreStart, + newOnStoreEnd, + onInsertStart, + onInsertEnd, + onUpdateStart, + onUpdateEnd, + onMergeStart, + onMergeEnd, + onDeleteStart, + onDeleteEnd, + onLoadStart, + onLoadEnd, + onRefreshStart, + onRefreshEnd, + onException + ); + } + + public final CallbackRecordListener onInsertStart(Consumer newOnInsertStart) { + return new CallbackRecordListener( + onStoreStart, + onStoreEnd, + newOnInsertStart, + onInsertEnd, + onUpdateStart, + onUpdateEnd, + onMergeStart, + onMergeEnd, + onDeleteStart, + onDeleteEnd, + onLoadStart, + onLoadEnd, + onRefreshStart, + onRefreshEnd, + onException + ); + } + + public final CallbackRecordListener onInsertEnd(Consumer newOnInsertEnd) { + return new CallbackRecordListener( + onStoreStart, + onStoreEnd, + onInsertStart, + newOnInsertEnd, + onUpdateStart, + onUpdateEnd, + onMergeStart, + onMergeEnd, + onDeleteStart, + onDeleteEnd, + onLoadStart, + onLoadEnd, + onRefreshStart, + onRefreshEnd, + onException + ); + } + + public final CallbackRecordListener onUpdateStart(Consumer newOnUpdateStart) { + return new CallbackRecordListener( + onStoreStart, + onStoreEnd, + onInsertStart, + onInsertEnd, + newOnUpdateStart, + onUpdateEnd, + onMergeStart, + onMergeEnd, + onDeleteStart, + onDeleteEnd, + onLoadStart, + onLoadEnd, + onRefreshStart, + onRefreshEnd, + onException + ); + } + + public final CallbackRecordListener onUpdateEnd(Consumer newOnUpdateEnd) { + return new CallbackRecordListener( + onStoreStart, + onStoreEnd, + onInsertStart, + onInsertEnd, + onUpdateStart, + newOnUpdateEnd, + onMergeStart, + onMergeEnd, + onDeleteStart, + onDeleteEnd, + onLoadStart, + onLoadEnd, + onRefreshStart, + onRefreshEnd, + onException + ); + } + + public final CallbackRecordListener onMergeStart(Consumer newOnMergeStart) { + return new CallbackRecordListener( + onStoreStart, + onStoreEnd, + onInsertStart, + onInsertEnd, + onUpdateStart, + onUpdateEnd, + newOnMergeStart, + onMergeEnd, + onDeleteStart, + onDeleteEnd, + onLoadStart, + onLoadEnd, + onRefreshStart, + onRefreshEnd, + onException + ); + } + + public final CallbackRecordListener onMergeEnd(Consumer newOnMergeEnd) { + return new CallbackRecordListener( + onStoreStart, + onStoreEnd, + onInsertStart, + onInsertEnd, + onUpdateStart, + onUpdateEnd, + onMergeStart, + newOnMergeEnd, + onDeleteStart, + onDeleteEnd, + onLoadStart, + onLoadEnd, + onRefreshStart, + onRefreshEnd, + onException + ); + } + + public final CallbackRecordListener onDeleteStart(Consumer newOnDeleteStart) { + return new CallbackRecordListener( + onStoreStart, + onStoreEnd, + onInsertStart, + onInsertEnd, + onUpdateStart, + onUpdateEnd, + onMergeStart, + onMergeEnd, + newOnDeleteStart, + onDeleteEnd, + onLoadStart, + onLoadEnd, + onRefreshStart, + onRefreshEnd, + onException + ); + } + + public final CallbackRecordListener onDeleteEnd(Consumer newOnDeleteEnd) { + return new CallbackRecordListener( + onStoreStart, + onStoreEnd, + onInsertStart, + onInsertEnd, + onUpdateStart, + onUpdateEnd, + onMergeStart, + onMergeEnd, + onDeleteStart, + newOnDeleteEnd, + onLoadStart, + onLoadEnd, + onRefreshStart, + onRefreshEnd, + onException + ); + } + + public final CallbackRecordListener onLoadStart(Consumer newOnLoadStart) { + return new CallbackRecordListener( + onStoreStart, + onStoreEnd, + onInsertStart, + onInsertEnd, + onUpdateStart, + onUpdateEnd, + onMergeStart, + onMergeEnd, + onDeleteStart, + onDeleteEnd, + newOnLoadStart, + onLoadEnd, + onRefreshStart, + onRefreshEnd, + onException + ); + } + + public final CallbackRecordListener onLoadEnd(Consumer newOnLoadEnd) { + return new CallbackRecordListener( + onStoreStart, + onStoreEnd, + onInsertStart, + onInsertEnd, + onUpdateStart, + onUpdateEnd, + onMergeStart, + onMergeEnd, + onDeleteStart, + onDeleteEnd, + onLoadStart, + newOnLoadEnd, + onRefreshStart, + onRefreshEnd, + onException + ); + } + + public final CallbackRecordListener onRefreshStart(Consumer newOnRefreshStart) { + return new CallbackRecordListener( + onStoreStart, + onStoreEnd, + onInsertStart, + onInsertEnd, + onUpdateStart, + onUpdateEnd, + onMergeStart, + onMergeEnd, + onDeleteStart, + onDeleteEnd, + onLoadStart, + onLoadEnd, + newOnRefreshStart, + onRefreshEnd, + onException + ); + } + + public final CallbackRecordListener onRefreshEnd(Consumer newOnRefreshEnd) { + return new CallbackRecordListener( + onStoreStart, + onStoreEnd, + onInsertStart, + onInsertEnd, + onUpdateStart, + onUpdateEnd, + onMergeStart, + onMergeEnd, + onDeleteStart, + onDeleteEnd, + onLoadStart, + onLoadEnd, + onRefreshStart, + newOnRefreshEnd, + onException + ); + } + + public final CallbackRecordListener onException(Consumer newOnException) { + return new CallbackRecordListener( + onStoreStart, + onStoreEnd, + onInsertStart, + onInsertEnd, + onUpdateStart, + onUpdateEnd, + onMergeStart, + onMergeEnd, + onDeleteStart, + onDeleteEnd, + onLoadStart, + onLoadEnd, + onRefreshStart, + onRefreshEnd, + newOnException + ); + } +} + diff --git a/jOOQ/src/main/java/org/jooq/impl/CallbackTransactionListener.java b/jOOQ/src/main/java/org/jooq/impl/CallbackTransactionListener.java new file mode 100644 index 0000000000..72bbffa81d --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/CallbackTransactionListener.java @@ -0,0 +1,195 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Other licenses: + * ----------------------------------------------------------------------------- + * Commercial licenses for this work are available. These replace the above + * ASL 2.0 and offer limited warranties, support, maintenance, and commercial + * database integrations. + * + * For more information, please visit: http://www.jooq.org/licenses + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + */ +package org.jooq.impl; + + +import java.util.function.Consumer; + +import org.jooq.RecordContext; +import org.jooq.RecordListener; +import org.jooq.TransactionContext; +import org.jooq.TransactionListener; + +/** + * A {@link TransactionListener} that allows for functional composition. + *

+ * For example:

+ * TransactionListener listener = TransactionListener
+ *   .onCommitStart(ctx -> something())
+ *   .onCommitEnd(ctx -> something());
+ * 
+ * + * @author Lukas Eder + */ +public final class CallbackTransactionListener implements TransactionListener { + + /** + * Generated UID + */ + private static final long serialVersionUID = -4135358887698253754L; + + private final Consumer onBeginStart; + private final Consumer onBeginEnd; + private final Consumer onCommitStart; + private final Consumer onCommitEnd; + private final Consumer onRollbackStart; + private final Consumer onRollbackEnd; + + public CallbackTransactionListener() { + this(null, null, null, null, null, null); + } + + private CallbackTransactionListener( + Consumer onBeginStart, + Consumer onBeginEnd, + Consumer onCommitStart, + Consumer onCommitEnd, + Consumer onRollbackStart, + Consumer onRollbackEnd + ) { + this.onBeginStart = onBeginStart; + this.onBeginEnd = onBeginEnd; + this.onCommitStart = onCommitStart; + this.onCommitEnd = onCommitEnd; + this.onRollbackStart = onRollbackStart; + this.onRollbackEnd = onRollbackEnd; + } + + @Override + public final void beginStart(TransactionContext ctx) { + if (onBeginStart != null) + onBeginStart.accept(ctx); + } + + @Override + public final void beginEnd(TransactionContext ctx) { + if (onBeginEnd != null) + onBeginEnd.accept(ctx); + } + + @Override + public final void commitStart(TransactionContext ctx) { + if (onCommitStart != null) + onCommitStart.accept(ctx); + } + + @Override + public final void commitEnd(TransactionContext ctx) { + if (onCommitEnd != null) + onCommitEnd.accept(ctx); + } + + @Override + public final void rollbackStart(TransactionContext ctx) { + if (onRollbackStart != null) + onRollbackStart.accept(ctx); + } + + @Override + public final void rollbackEnd(TransactionContext ctx) { + if (onRollbackEnd != null) + onRollbackEnd.accept(ctx); + } + + public final CallbackTransactionListener onBeginStart(Consumer newOnBeginStart) { + return new CallbackTransactionListener( + newOnBeginStart, + onBeginEnd, + onCommitStart, + onCommitEnd, + onRollbackStart, + onRollbackEnd + ); + } + + public final CallbackTransactionListener onBeginEnd(Consumer newOnBeginEnd) { + return new CallbackTransactionListener( + onBeginStart, + newOnBeginEnd, + onCommitStart, + onCommitEnd, + onRollbackStart, + onRollbackEnd + ); + } + + public final CallbackTransactionListener onCommitStart(Consumer newOnCommitStart) { + return new CallbackTransactionListener( + onBeginStart, + onBeginEnd, + newOnCommitStart, + onCommitEnd, + onRollbackStart, + + onRollbackEnd); + } + + public final CallbackTransactionListener onCommitEnd(Consumer newOnCommitEnd) { + return new CallbackTransactionListener( + onBeginStart, + onBeginEnd, + onCommitStart, + newOnCommitEnd, + onRollbackStart, + onRollbackEnd + ); + } + + public final CallbackTransactionListener onRollbackStart(Consumer newOnRollbackStart) { + return new CallbackTransactionListener( + onBeginStart, + onBeginEnd, + onCommitStart, + onCommitEnd, + newOnRollbackStart, + onRollbackEnd + ); + } + + public final CallbackTransactionListener onRollbackEnd(Consumer newOnRollbackEnd) { + return new CallbackTransactionListener( + onBeginStart, + onBeginEnd, + onCommitStart, + onCommitEnd, + onRollbackStart, + newOnRollbackEnd + ); + } +} + diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultTransactionListener.java b/jOOQ/src/main/java/org/jooq/impl/DefaultTransactionListener.java index 8afa3eb55a..c6b6c3237d 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultTransactionListener.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultTransactionListener.java @@ -50,6 +50,11 @@ import org.jooq.TransactionListener; */ public class DefaultTransactionListener implements TransactionListener { + /** + * Generated UID + */ + private static final long serialVersionUID = -1836373111252221549L; + @Override public void beginStart(TransactionContext ctx) {}