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 957af6f27e8bfd83b6537fe08a039f2878898029 Author: Andrus Adamchik <[email protected]> AuthorDate: Fri Jul 3 16:23:49 2026 -0400 CAY-2912 Compact SQL logger removing FormattedSlf4jJdbcEventLogger ... ongoing refactoring should go smoother without it in the picture --- .../cayenne/log/FormattedSlf4jJdbcEventLogger.java | 128 ---------------- .../log/FormattedSlf4jJdbcEventLoggerTest.java | 167 --------------------- .../asciidoc/_cayenne-guide/part2/customize.adoc | 10 -- 3 files changed, 305 deletions(-) diff --git a/cayenne/src/main/java/org/apache/cayenne/log/FormattedSlf4jJdbcEventLogger.java b/cayenne/src/main/java/org/apache/cayenne/log/FormattedSlf4jJdbcEventLogger.java deleted file mode 100644 index 6bef94dbf..000000000 --- a/cayenne/src/main/java/org/apache/cayenne/log/FormattedSlf4jJdbcEventLogger.java +++ /dev/null @@ -1,128 +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.log; - -import org.apache.cayenne.access.jdbc.PSParameter; -import org.apache.cayenne.configuration.RuntimeProperties; -import org.apache.cayenne.di.Inject; - -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.TreeMap; - -/** - * A {@link Slf4jJdbcEventLogger} extension that provides pretty formatting of the logged SQL messages. - * - * @since 3.1 - * @since 4.0 renamed from FormattedCommonsJdbcEventLogger to FormattedSlf4jJdbcEventLogger as part of migration to SLF4J - */ -public class FormattedSlf4jJdbcEventLogger extends Slf4jJdbcEventLogger { - - private final static Map<String, String> KEYWORDS = new HashMap<>(); - - static { - KEYWORDS.put(" select ", "SELECT"); - KEYWORDS.put(" from ", "FROM"); - KEYWORDS.put(" where ", "WHERE"); - KEYWORDS.put(" order by ", "ORDER BY"); - KEYWORDS.put(" group by ", "GROUP BY"); - KEYWORDS.put(" update ", "UPDATE"); - KEYWORDS.put(" exec ", "EXEC"); - KEYWORDS.put(" set ", "SET"); - KEYWORDS.put(" insert ", "INSERT"); - KEYWORDS.put(" values ", "VALUES"); - KEYWORDS.put(" delete ", "DELETE"); - KEYWORDS.put(" declare ", "DECLARE"); - KEYWORDS.put(" case ", "CASE"); - } - - public FormattedSlf4jJdbcEventLogger(@Inject RuntimeProperties runtimeProperties) { - super(runtimeProperties); - } - - static String formatQuery(String sql) { - Map<Integer, String> scanResult = scanQuery(sql); - Iterator<Integer> iter = scanResult.keySet().iterator(); - int nextKeyIdx = (iter.hasNext()) ? iter.next() : -1; - - StringBuilder buffer = new StringBuilder(); - int apixCount = 0; - int bufferPos = 0; - for (int pos = 0; pos < sql.length(); pos++) { - if (sql.charAt(pos) == '\'') { - apixCount++; - if (pos > 0 && sql.charAt(pos - 1) == '\'') { - apixCount = apixCount - 2; - } - } - if (apixCount % 2 != 0) { - continue; - } - if (pos == nextKeyIdx) { - buffer.append(sql.substring(bufferPos, pos + 1)); - buffer.append("\n"); - String shiftedKeyWrd = scanResult.get(nextKeyIdx); - nextKeyIdx = (iter.hasNext()) ? iter.next() : -1; - buffer.append(shiftedKeyWrd); - pos = pos + shiftedKeyWrd.length(); - bufferPos = pos + 1; - } - else if (sql.charAt(pos) == ',' - || sql.charAt(pos) == ')' - || sql.charAt(pos) == '(') { - buffer.append(sql.substring(bufferPos, pos + 1)); - buffer.append("\n\t"); - bufferPos = pos + 1; - } - } - buffer.append(sql.substring(bufferPos)); - buffer.append("\n"); - String result = buffer.toString(); - while (result.contains(" ")) { - result = result.replaceAll(" ", " "); - } - return result; - } - - private static Map<Integer, String> scanQuery(String sql) { - Map<Integer, String> result = new TreeMap<>(); - String sql2Lower = sql.toLowerCase(); - for (String keyWrd : KEYWORDS.keySet()) { - int prevIdx = 0; - while (true) { - int idx = sql2Lower.indexOf(keyWrd, prevIdx); - if (idx >= 0) { - result.put(idx, KEYWORDS.get(keyWrd)); - prevIdx = idx + 1; - } else { - break; - } - } - } - return result; - } - - @Override - public void logQuery(String sql, PSParameter[] bindings) { - if (isLoggable()) { - super.logQuery(formatQuery(sql), bindings); - } - } -} diff --git a/cayenne/src/test/java/org/apache/cayenne/log/FormattedSlf4jJdbcEventLoggerTest.java b/cayenne/src/test/java/org/apache/cayenne/log/FormattedSlf4jJdbcEventLoggerTest.java deleted file mode 100644 index a21623ffb..000000000 --- a/cayenne/src/test/java/org/apache/cayenne/log/FormattedSlf4jJdbcEventLoggerTest.java +++ /dev/null @@ -1,167 +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.log; - -import org.junit.jupiter.api.Test; - -import static org.apache.cayenne.log.FormattedSlf4jJdbcEventLogger.formatQuery; -import static org.junit.jupiter.api.Assertions.assertEquals; - -/** - * Assertions use text blocks so the resulting SQL layout is visible. The formatter emits trailing spaces on many - * lines and indents continuations with a tab; since text blocks strip trailing whitespace, those are spelled out - * explicitly as {@code \s} (space) and {@code \t} (tab). - */ -public class FormattedSlf4jJdbcEventLoggerTest { - - @Test - public void formatQuery_breaksBeforeKeywords() { - assertEquals(""" - SELECT *\s - FROM ARTIST - """, - formatQuery("SELECT * FROM ARTIST")); - } - - @Test - public void formatQuery_fullSelect() { - assertEquals(""" - SELECT t0.ID, - \t t0.NAME\s - FROM ARTIST t0\s - WHERE t0.NAME = ?\s - ORDER BY t0.NAME - """, - formatQuery("SELECT t0.ID, t0.NAME FROM ARTIST t0 WHERE t0.NAME = ? ORDER BY t0.NAME")); - } - - @Test - public void formatQuery_update() { - assertEquals(""" - UPDATE ARTIST\s - SET NAME = ?\s - WHERE ID = ? - """, - formatQuery("UPDATE ARTIST SET NAME = ? WHERE ID = ?")); - } - - @Test - public void formatQuery_delete() { - assertEquals(""" - DELETE\s - FROM ARTIST\s - WHERE ID = ? - """, - formatQuery("DELETE FROM ARTIST WHERE ID = ?")); - } - - @Test - public void formatQuery_insertBreaksOnParensAndCommas() { - assertEquals(""" - INSERT INTO ARTIST ( - \tID, - \t NAME) - \t\s - VALUES ( - \t?, - \t ?) - \t - """, - formatQuery("INSERT INTO ARTIST (ID, NAME) VALUES (?, ?)")); - } - - @Test - public void formatQuery_groupBy() { - assertEquals(""" - SELECT COUNT( - \t*) - \t\s - FROM ARTIST\s - GROUP BY NAME - """, - formatQuery("SELECT COUNT(*) FROM ARTIST GROUP BY NAME")); - } - - /** - * The leading keyword of a statement has no preceding space, so it is not matched and not broken onto its own line. - */ - @Test - public void formatQuery_leadingKeywordNotBroken() { - assertEquals(""" - SELECT *\s - FROM ARTIST - """, - formatQuery("SELECT * FROM ARTIST")); - } - - /** - * Keywords, commas and parentheses that appear inside a quoted string literal must be left untouched. - */ - @Test - public void formatQuery_ignoresContentInsideStringLiterals() { - assertEquals(""" - SELECT *\s - FROM T\s - WHERE NAME = 'a, b, (c)' - """, - formatQuery("SELECT * FROM T WHERE NAME = 'a, b, (c)'")); - assertEquals(""" - SELECT *\s - FROM T\s - WHERE NAME = 'from the where group' - """, - formatQuery("SELECT * FROM T WHERE NAME = 'from the where group'")); - } - - /** - * A doubled single quote is an escaped apostrophe within a literal and must not toggle the "inside literal" state. - */ - @Test - public void formatQuery_handlesEscapedQuotesInsideLiterals() { - assertEquals(""" - SELECT *\s - FROM T\s - WHERE NAME = 'O''Brien from x' - """, - formatQuery("SELECT * FROM T WHERE NAME = 'O''Brien from x'")); - } - - @Test - public void formatQuery_collapsesRepeatedSpaces() { - assertEquals(""" - SELECT *\s - FROM T - """, - formatQuery("SELECT * FROM T")); - } - - @Test - public void formatQuery_noKeywords() { - assertEquals(""" - no keywords here just text - """, - formatQuery("no keywords here just text")); - } - - @Test - public void formatQuery_empty() { - // a bare newline is clearer as a plain literal than as a text block - assertEquals("\n", formatQuery("")); - } -} diff --git a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/customize.adoc b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/customize.adoc index ab3d5c939..57e7a4205 100644 --- a/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/customize.adoc +++ b/docs/asciidoc/cayenne-guide/src/docs/asciidoc/_cayenne-guide/part2/customize.adoc @@ -265,16 +265,6 @@ While we describe some of them in the following sections, the best way to get a is to check the source code of the Cayenne version you are using and namely look in `org.apache.cayenne.configuration.runtime.CoreModule` - the main built-in module in Cayenne. -Now an example of overriding `JdbcEventLogger` service. The default implementation of this service -is provided by `Slf4jJdbcEventLogger`. But if we want to use `FormattedSlf4jJdbcEventLogger` -(a logger with basic SQL formatting), we can define it like this: - -[source, Java] ----- -binder.bind(JdbcEventLogger.class) - .to(FormattedSlf4jJdbcEventLogger.class); ----- - ==== Using custom data types ===== Value object type
