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 fcc7a158dfcf7ed8e0e143c0d22b02417e97c3da
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   | 46 +++++++++-------------
 .../apache/cayenne/access/DataNodeQueryAction.java |  9 ++++-
 .../org/apache/cayenne/access/LoggingObserver.java | 20 +++-------
 .../apache/cayenne/access/OperationObserver.java   |  6 +++
 .../access/translator/TranslatedStatement.java     |  5 +--
 .../apache/cayenne/access/LoggingObserverTest.java | 10 ++---
 .../org/apache/cayenne/access/MockDataNode.java    |  6 +--
 .../unit/telemetry/TelemetricDataNodeFactory.java  |  4 +-
 8 files changed, 48 insertions(+), 58 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 e0fc0a0e3..4839aa59b 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/DataNode.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/DataNode.java
@@ -222,22 +222,27 @@ public class DataNode {
      *
      * @since 1.1
      */
-    public void performQueries(Collection<? extends Query> queries, 
OperationObserver callback) {
+    public void performQueries(Collection<? extends Query> queries, 
OperationObserver operationObserver) {
 
         int listSize = queries.size();
         if (listSize == 0) {
             return;
         }
 
-        if (callback.isIteratedResult() && listSize > 1) {
+        if (operationObserver.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;
+
         Transaction tx = BaseTransaction.getThreadTransaction();
         Connection connection;
 
@@ -248,32 +253,20 @@ public class DataNode {
                 tx.setRollbackOnly();
             }
 
-            callback.nextGlobalException(globalEx);
+            instrumentedObserver.nextGlobalException(globalEx);
             return;
         }
 
-        // when logging is enabled, wrap the observer so it can correlate each 
executed statement with its results
-        // and emit compact log lines; otherwise pass the caller's observer 
through untouched
-        SqlLogger logger = getSqlLogger();
-        LoggingObserver loggingObserver = logger != null && logger.isEnabled()
-                ? new LoggingObserver(callback, logger)
-                : null;
-        OperationObserver observer = loggingObserver != null ? loggingObserver 
: callback;
-
-               try {
-                       DataNodeQueryAction queryRunner = new 
DataNodeQueryAction(this, observer);
+        try {
+            DataNodeQueryAction queryRunner = new DataNodeQueryAction(this, 
instrumentedObserver);
 
-            boolean failed = false;
             for (Query nextQuery : queries) {
 
                 // catch exceptions for each individual query
                 try {
                     queryRunner.runQuery(connection, nextQuery);
                 } catch (Exception queryEx) {
-                    // notify consumer of the exception, stop running further 
queries. The failing statement is not
-                    // logged - its SQL and bindings travel with the thrown 
exception instead.
-                    failed = true;
-                    observer.nextQueryException(nextQuery, queryEx);
+                    instrumentedObserver.nextQueryException(nextQuery, 
queryEx);
 
                     if (tx != null) {
                         tx.setRollbackOnly();
@@ -282,10 +275,7 @@ public class DataNode {
                 }
             }
 
-            // flush any pending statement line (e.g. a summed batch) that 
completed successfully
-            if (!failed && loggingObserver != null) {
-                loggingObserver.flush();
-            }
+            instrumentedObserver.afterLastStatement();
         } finally {
             try {
                 connection.close();
@@ -295,12 +285,12 @@ public class DataNode {
         }
     }
 
-       /**
-        * Returns EntityResolver that handles DataMaps of this node.
-        */
-       public EntityResolver getEntityResolver() {
-               return entityResolver;
-       }
+    /**
+     * Returns EntityResolver that handles DataMaps of this node.
+     */
+    public EntityResolver getEntityResolver() {
+        return entityResolver;
+    }
 
     /**
      * Sets EntityResolver. DataNode relies on externally set EntityResolver, 
so
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/DataNodeQueryAction.java 
b/cayenne/src/main/java/org/apache/cayenne/access/DataNodeQueryAction.java
index fe37e60f6..a952eb5ba 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/DataNodeQueryAction.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/DataNodeQueryAction.java
@@ -37,8 +37,8 @@ import java.util.List;
  */
 class DataNodeQueryAction {
 
-    OperationObserver observer;
-    DataNode node;
+    final OperationObserver observer;
+    final DataNode node;
 
     public DataNodeQueryAction(DataNode node, OperationObserver observer) {
         this.observer = observer;
@@ -56,6 +56,11 @@ class DataNodeQueryAction {
                 observer.nextStatement(originalQuery, statement);
             }
 
+            @Override
+            public void afterLastStatement() {
+                observer.afterLastStatement();
+            }
+
             @Override
             public void nextBatchCount(Query query, int[] resultCount) {
                 observer.nextBatchCount(originalQuery, resultCount);
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 5e78ca5f5..e7435503a 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/LoggingObserver.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/LoggingObserver.java
@@ -34,11 +34,6 @@ import java.util.List;
  * An {@link OperationObserver} decorator that correlates each executed 
statement (reported via
  * {@link #nextStatement}) with its results (reported via the {@code next*} 
callbacks) and drives a {@link SqlLogger}
  * to emit compact, single-line log messages. All callbacks are delegated to 
the wrapped observer unchanged.
- * <p>
- * The first result of a statement produces the main line (SQL + bindings + 
{@code selected:N}/{@code updated:N}); a
- * statement that yields more results reports them as {@code also ...} lines — 
except batches, whose per-row update
- * counts are summed into a single {@code updated:N} line. Exceptions are not 
logged (the SQL travels with the thrown
- * exception instead).
  *
  * @since 5.0
  */
@@ -57,15 +52,6 @@ class LoggingObserver implements OperationObserver {
         this.logger = logger;
     }
 
-    /**
-     * Emits any pending statement line (currently only summed batch updates) 
that has not been logged yet. Called by
-     * {@link DataNode} after the query loop completes.
-     */
-    void flush() {
-        flushPending();
-        current = null;
-    }
-
     private void flushPending() {
         if (!headerEmitted && batchHasUpdate && current != null) {
             logger.logUpdate(current, batchUpdateSum);
@@ -103,6 +89,12 @@ class LoggingObserver implements OperationObserver {
         return total;
     }
 
+    @Override
+    public void afterLastStatement() {
+        flushPending();
+        current = null;
+    }
+
     @Override
     public void nextStatement(Query query, TranslatedStatement statement) {
         flushPending();
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 8b56fecff..63a5a691f 100644
--- a/cayenne/src/main/java/org/apache/cayenne/access/OperationObserver.java
+++ b/cayenne/src/main/java/org/apache/cayenne/access/OperationObserver.java
@@ -42,6 +42,12 @@ public interface OperationObserver extends OperationHints {
     default void nextStatement(Query query, TranslatedStatement statement) {
     }
 
+    /**
+     * @since 5.0
+     */
+    default void afterLastStatement() {
+    }
+
     /**
      * Callback method invoked after an updating query is executed.
      */
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/translator/TranslatedStatement.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/translator/TranslatedStatement.java
index e0492a3ba..6fd66d44b 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/translator/TranslatedStatement.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/translator/TranslatedStatement.java
@@ -20,10 +20,7 @@
 package org.apache.cayenne.access.translator;
 
 /**
- * A common supertype for the immutable results of translating a query to SQL. 
It bundles the final SQL string with
- * the typed, self-describing bindings needed to both execute and log a 
statement, and lets logging and error-reporting
- * treat all four translation flavors ({@link TranslatedSelect}, {@link 
TranslatedBatch}, {@link TranslatedProcedure},
- * {@link TranslatedSQL}) uniformly.
+ * A common supertype for the immutable results of translating a query to SQL.
  *
  * @since 5.0
  */
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 962213e05..ed62645c3 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.flush();
+        observer.afterLastStatement();
 
         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.flush();
+        observer.afterLastStatement();
 
         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.flush();
+        observer.afterLastStatement();
 
         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.flush();
+        observer.afterLastStatement();
 
         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.flush();
+        observer.afterLastStatement();
 
         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 73f2b07e4..d669519fa 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 
resultConsumer) {
+    public void performQueries(Collection queries, OperationObserver 
operationObserver) {
         runCount += queries.size();
 
         if (replaceResults) {
-            initWithPresetResults(queries, resultConsumer);
+            initWithPresetResults(queries, operationObserver);
         }
         else {
-            node.performQueries(queries, resultConsumer);
+            node.performQueries(queries, operationObserver);
         }
     }
 
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 579ae7a2b..8a49337d1 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 callback) {
+        public void performQueries(Collection<? extends Query> queries, 
OperationObserver operationObserver) {
             if (blockingQueries) {
                 Assertions.fail("Query is unexpected: " + queries);
             }
-            super.performQueries(queries, callback);
+            super.performQueries(queries, operationObserver);
             queryCounter.addAndGet(queries.size());
         }
 

Reply via email to