This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit 24dfb1b0ac5639a39a7837625a709116b280942e
Author: Andrus Adamchik <[email protected]>
AuthorDate: Fri Jul 3 18:07:55 2026 -0400

    CAY-2912 Compact SQL logger
    
    cleanup
---
 .../java/org/apache/cayenne/access/DataNode.java   |  26 +++--
 .../apache/cayenne/access/DataNodeQueryAction.java | 108 ---------------------
 .../org/apache/cayenne/access/LoggingObserver.java |   2 +-
 .../apache/cayenne/access/OperationObserver.java   |   9 +-
 .../cayenne/access/OriginalQueryObserver.java      |  93 ++++++++++++++++++
 .../apache/cayenne/access/LoggingObserverTest.java |  10 +-
 .../org/apache/cayenne/access/MockDataNode.java    |   6 +-
 .../unit/telemetry/TelemetricDataNodeFactory.java  |   4 +-
 8 files changed, 122 insertions(+), 136 deletions(-)

diff --git a/cayenne/src/main/java/org/apache/cayenne/access/DataNode.java 
b/cayenne/src/main/java/org/apache/cayenne/access/DataNode.java
index 4839aa59b..3351852e4 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/DataNode.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/DataNode.java
@@ -194,8 +194,7 @@ public class DataNode {
     }
 
     /**
-     * Returns DbAdapter object. This is a plugin that handles RDBMS
-     * vendor-specific features.
+     * Returns DbAdapter object. This is a plugin that handles RDBMS 
vendor-specific features.
      */
     public DbAdapter getAdapter() {
         return adapter;
@@ -222,26 +221,25 @@ public class DataNode {
      *
      * @since 1.1
      */
-    public void performQueries(Collection<? extends Query> queries, 
OperationObserver operationObserver) {
+    public void performQueries(Collection<? extends Query> queries, 
OperationObserver callback) {
 
         int listSize = queries.size();
         if (listSize == 0) {
             return;
         }
 
-        if (operationObserver.isIteratedResult() && listSize > 1) {
+        if (callback.isIteratedResult() && listSize > 1) {
             throw new CayenneRuntimeException("Iterated queries are not 
allowed in a batch. Batch size: %d", listSize);
         }
 
-
         // do this meaningless inexpensive operation to trigger AutoAdapter 
lazy initialization before opening a
         // connection. Otherwise, we may end up with two connections open 
simultaneously, possibly hitting connection
         // pool upper limit.
         getAdapter().getExtendedTypes();
 
-        OperationObserver instrumentedObserver = sqlLogger.isEnabled()
-                ? new LoggingObserver(operationObserver, sqlLogger)
-                : operationObserver;
+        OperationObserver instrumentedCallback = sqlLogger.isEnabled()
+                ? new LoggingObserver(callback, sqlLogger)
+                : callback;
 
         Transaction tx = BaseTransaction.getThreadTransaction();
         Connection connection;
@@ -253,20 +251,20 @@ public class DataNode {
                 tx.setRollbackOnly();
             }
 
-            instrumentedObserver.nextGlobalException(globalEx);
+            instrumentedCallback.nextGlobalException(globalEx);
             return;
         }
 
         try {
-            DataNodeQueryAction queryRunner = new DataNodeQueryAction(this, 
instrumentedObserver);
-
             for (Query nextQuery : queries) {
 
                 // catch exceptions for each individual query
                 try {
-                    queryRunner.runQuery(connection, nextQuery);
+                    getAdapter()
+                            .getAction(nextQuery, this)
+                            .performAction(connection, new 
OriginalQueryObserver(instrumentedCallback, nextQuery));
                 } catch (Exception queryEx) {
-                    instrumentedObserver.nextQueryException(nextQuery, 
queryEx);
+                    instrumentedCallback.nextQueryException(nextQuery, 
queryEx);
 
                     if (tx != null) {
                         tx.setRollbackOnly();
@@ -275,7 +273,7 @@ public class DataNode {
                 }
             }
 
-            instrumentedObserver.afterLastStatement();
+            instrumentedCallback.onSuccess();
         } finally {
             try {
                 connection.close();
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/DataNodeQueryAction.java 
b/cayenne/src/main/java/org/apache/cayenne/access/DataNodeQueryAction.java
deleted file mode 100644
index a952eb5ba..000000000
--- a/cayenne/src/main/java/org/apache/cayenne/access/DataNodeQueryAction.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*****************************************************************
- *   Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you 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
- *
- *    https://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.
- ****************************************************************/
-
-package org.apache.cayenne.access;
-
-import org.apache.cayenne.ObjectId;
-import org.apache.cayenne.ResultIterator;
-import org.apache.cayenne.access.translator.TranslatedStatement;
-import org.apache.cayenne.query.Query;
-import org.apache.cayenne.query.SQLAction;
-
-import java.sql.Connection;
-import java.util.List;
-
-/**
- * A helper that executes a sequence of queries, providing correct mapping of 
the results
- * to the original query. Note that this class is not thread-safe as it stores 
current
- * query execution state.
- *
- * @since 1.2
- */
-class DataNodeQueryAction {
-
-    final OperationObserver observer;
-    final DataNode node;
-
-    public DataNodeQueryAction(DataNode node, OperationObserver observer) {
-        this.observer = observer;
-        this.node = node;
-    }
-
-    public void runQuery(Connection connection, Query originalQuery) throws 
Exception {
-
-        // wrap to ensure that the result is mapped back to the original 
query, even if
-        // the underlying SQLAction uses query substitute...
-        OperationObserver wrapper = new OperationObserver() {
-
-            @Override
-            public void nextStatement(Query query, TranslatedStatement 
statement) {
-                observer.nextStatement(originalQuery, statement);
-            }
-
-            @Override
-            public void afterLastStatement() {
-                observer.afterLastStatement();
-            }
-
-            @Override
-            public void nextBatchCount(Query query, int[] resultCount) {
-                observer.nextBatchCount(originalQuery, resultCount);
-            }
-
-            @Override
-            public void nextCount(Query query, int resultCount) {
-                observer.nextCount(originalQuery, resultCount);
-            }
-
-            @Override
-            public void nextRows(Query query, List<?> dataRows) {
-                observer.nextRows(originalQuery, dataRows);
-            }
-
-            @Override
-            public void nextRows(Query q, ResultIterator<?> it) {
-                observer.nextRows(originalQuery, it);
-            }
-
-            @Override
-            public void nextGeneratedRows(Query query, ResultIterator<?> keys, 
List<ObjectId> idsToUpdate) {
-                observer.nextGeneratedRows(originalQuery, keys, idsToUpdate);
-            }
-
-            @Override
-            public void nextGlobalException(Exception ex) {
-                observer.nextGlobalException(ex);
-            }
-
-            @Override
-            public void nextQueryException(Query query, Exception ex) {
-                observer.nextQueryException(originalQuery, ex);
-            }
-
-            @Override
-            public boolean isIteratedResult() {
-                return observer.isIteratedResult();
-            }
-        };
-
-        SQLAction action = node.getAdapter().getAction(originalQuery, node);
-        action.performAction(connection, wrapper);
-    }
-}
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/LoggingObserver.java 
b/cayenne/src/main/java/org/apache/cayenne/access/LoggingObserver.java
index e7435503a..204a938c1 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/LoggingObserver.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/LoggingObserver.java
@@ -90,7 +90,7 @@ class LoggingObserver implements OperationObserver {
     }
 
     @Override
-    public void afterLastStatement() {
+    public void onSuccess() {
         flushPending();
         current = null;
     }
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/OperationObserver.java 
b/cayenne/src/main/java/org/apache/cayenne/access/OperationObserver.java
index 63a5a691f..270577503 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/OperationObserver.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/OperationObserver.java
@@ -43,9 +43,11 @@ public interface OperationObserver extends OperationHints {
     }
 
     /**
+     * Called at the end of a multi-query DataNode operation.
+     *
      * @since 5.0
      */
-    default void afterLastStatement() {
+    default void onSuccess() {
     }
 
     /**
@@ -60,7 +62,7 @@ public interface OperationObserver extends OperationHints {
 
     /**
      * Callback method invoked for each processed ResultSet.
-     * 
+     *
      * @since 3.0
      */
     void nextRows(Query query, List<?> dataRows);
@@ -69,13 +71,14 @@ public interface OperationObserver extends OperationHints {
      * Callback method invoked for each opened ResultIterator. If this 
observer requested
      * results to be returned as a ResultIterator, this method is invoked 
instead of
      * {@link #nextRows(Query, List)}.
-     * 
+     *
      * @since 3.0
      */
     void nextRows(Query q, ResultIterator<?> it);
 
     /**
      * Callback method invoked after each batch of generated values is read 
during an update.
+     *
      * @since 4.2
      */
     void nextGeneratedRows(Query query, ResultIterator<?> keys, List<ObjectId> 
idsToUpdate);
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/OriginalQueryObserver.java 
b/cayenne/src/main/java/org/apache/cayenne/access/OriginalQueryObserver.java
new file mode 100644
index 000000000..fc999bc57
--- /dev/null
+++ b/cayenne/src/main/java/org/apache/cayenne/access/OriginalQueryObserver.java
@@ -0,0 +1,93 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you 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
+ *
+ *    https://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.
+ ****************************************************************/
+
+package org.apache.cayenne.access;
+
+import org.apache.cayenne.ObjectId;
+import org.apache.cayenne.ResultIterator;
+import org.apache.cayenne.access.translator.TranslatedStatement;
+import org.apache.cayenne.query.Query;
+
+import java.util.List;
+
+/**
+ * An {@link OperationObserver} decorator that reports all results against the 
original query, even when the underlying
+ * {@link org.apache.cayenne.query.SQLAction} executes a substitute query. All 
callbacks are delegated to the wrapped
+ * observer with the {@code query} argument replaced by the original query.
+ */
+class OriginalQueryObserver implements OperationObserver {
+
+    private final OperationObserver delegate;
+    private final Query originalQuery;
+
+    OriginalQueryObserver(OperationObserver delegate, Query originalQuery) {
+        this.delegate = delegate;
+        this.originalQuery = originalQuery;
+    }
+
+    @Override
+    public void nextStatement(Query query, TranslatedStatement statement) {
+        delegate.nextStatement(originalQuery, statement);
+    }
+
+    @Override
+    public void onSuccess() {
+        delegate.onSuccess();
+    }
+
+    @Override
+    public void nextCount(Query query, int resultCount) {
+        delegate.nextCount(originalQuery, resultCount);
+    }
+
+    @Override
+    public void nextBatchCount(Query query, int[] resultCount) {
+        delegate.nextBatchCount(originalQuery, resultCount);
+    }
+
+    @Override
+    public void nextRows(Query query, List<?> dataRows) {
+        delegate.nextRows(originalQuery, dataRows);
+    }
+
+    @Override
+    public void nextRows(Query query, ResultIterator<?> it) {
+        delegate.nextRows(originalQuery, it);
+    }
+
+    @Override
+    public void nextGeneratedRows(Query query, ResultIterator<?> keys, 
List<ObjectId> idsToUpdate) {
+        delegate.nextGeneratedRows(originalQuery, keys, idsToUpdate);
+    }
+
+    @Override
+    public void nextQueryException(Query query, Exception ex) {
+        delegate.nextQueryException(originalQuery, ex);
+    }
+
+    @Override
+    public void nextGlobalException(Exception ex) {
+        delegate.nextGlobalException(ex);
+    }
+
+    @Override
+    public boolean isIteratedResult() {
+        return delegate.isIteratedResult();
+    }
+}
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/access/LoggingObserverTest.java 
b/cayenne/src/test/java/org/apache/cayenne/access/LoggingObserverTest.java
index ed62645c3..5b3aca43a 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/LoggingObserverTest.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/LoggingObserverTest.java
@@ -117,7 +117,7 @@ public class LoggingObserverTest {
 
         observer.nextStatement(null, select());
         observer.nextRows(null, asList(new Object(), new Object()));
-        observer.afterLastStatement();
+        observer.onSuccess();
 
         assertEquals(List.of("selected:2"), logger.calls);
     }
@@ -131,7 +131,7 @@ public class LoggingObserverTest {
         observer.nextCount(null, 1);
         observer.nextCount(null, 1);
         observer.nextCount(null, 1);
-        observer.afterLastStatement();
+        observer.onSuccess();
 
         assertEquals(List.of("updated:3"), logger.calls);
     }
@@ -145,7 +145,7 @@ public class LoggingObserverTest {
         observer.nextRows(null, List.of(new Object(), new Object(), new 
Object(), new Object(), new Object()));
         observer.nextCount(null, 10);
         observer.nextCount(null, 20);
-        observer.afterLastStatement();
+        observer.onSuccess();
 
         assertEquals(List.of("selected:5", "also updated:10", "also 
updated:20"), logger.calls);
     }
@@ -159,7 +159,7 @@ public class LoggingObserverTest {
         observer.nextStatement(null, select());
         observer.nextRows(null, asList(new Object(), new Object()));
         observer.nextBatchCount(null, new int[0]);
-        observer.afterLastStatement();
+        observer.onSuccess();
 
         assertEquals(List.of("selected:2"), logger.calls);
     }
@@ -174,7 +174,7 @@ public class LoggingObserverTest {
         // a second batch statement should flush the first
         observer.nextStatement(null, batch());
         observer.nextCount(null, 3);
-        observer.afterLastStatement();
+        observer.onSuccess();
 
         assertEquals(List.of("updated:2", "updated:3"), logger.calls);
     }
diff --git a/cayenne/src/test/java/org/apache/cayenne/access/MockDataNode.java 
b/cayenne/src/test/java/org/apache/cayenne/access/MockDataNode.java
index d669519fa..db5522043 100644
--- a/cayenne/src/test/java/org/apache/cayenne/access/MockDataNode.java
+++ b/cayenne/src/test/java/org/apache/cayenne/access/MockDataNode.java
@@ -78,14 +78,14 @@ public class MockDataNode extends DataNode {
     }
 
     @Override
-    public void performQueries(Collection queries, OperationObserver 
operationObserver) {
+    public void performQueries(Collection queries, OperationObserver callback) 
{
         runCount += queries.size();
 
         if (replaceResults) {
-            initWithPresetResults(queries, operationObserver);
+            initWithPresetResults(queries, callback);
         }
         else {
-            node.performQueries(queries, operationObserver);
+            node.performQueries(queries, callback);
         }
     }
 
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/unit/telemetry/TelemetricDataNodeFactory.java
 
b/cayenne/src/test/java/org/apache/cayenne/unit/telemetry/TelemetricDataNodeFactory.java
index 8a49337d1..579ae7a2b 100644
--- 
a/cayenne/src/test/java/org/apache/cayenne/unit/telemetry/TelemetricDataNodeFactory.java
+++ 
b/cayenne/src/test/java/org/apache/cayenne/unit/telemetry/TelemetricDataNodeFactory.java
@@ -44,11 +44,11 @@ public class TelemetricDataNodeFactory extends 
DefaultDataNodeFactory {
         }
 
         @Override
-        public void performQueries(Collection<? extends Query> queries, 
OperationObserver operationObserver) {
+        public void performQueries(Collection<? extends Query> queries, 
OperationObserver callback) {
             if (blockingQueries) {
                 Assertions.fail("Query is unexpected: " + queries);
             }
-            super.performQueries(queries, operationObserver);
+            super.performQueries(queries, callback);
             queryCounter.addAndGet(queries.size());
         }
 

Reply via email to