You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2018/10/18 14:30:03 UTC

[1/4] cayenne git commit: CAY-2485 Added CompactSl4jJdbcEventLogger.

Repository: cayenne
Updated Branches:
  refs/heads/master 5855ffc71 -> 7694a64d3


CAY-2485 Added CompactSl4jJdbcEventLogger.


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/a07bba55
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/a07bba55
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/a07bba55

Branch: refs/heads/master
Commit: a07bba5542a79f534b80bab28de2b1354a52d593
Parents: 20b166a
Author: kkomyak <co...@gmail.com>
Authored: Wed Oct 10 11:18:17 2018 +0300
Committer: kkomyak <co...@gmail.com>
Committed: Thu Oct 11 16:40:30 2018 +0300

----------------------------------------------------------------------
 cayenne-server/pom.xml                          |   6 +
 .../cayenne/log/CompactSl4jJdbcEventLogger.java | 201 +++++++++++++++++++
 .../log/CompactSl4jJdbcEventLoggerTest.java     | 109 ++++++++++
 .../cayenne/log/Slf4jJdbcEventLoggerTest.java   |   4 -
 .../org/apache/cayenne/log/TestAppender.java    |  16 ++
 .../src/test/resources/logback-test.xml         |  42 ++++
 6 files changed, 374 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/a07bba55/cayenne-server/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/pom.xml b/cayenne-server/pom.xml
index 0ede0dd..e965ffa 100644
--- a/cayenne-server/pom.xml
+++ b/cayenne-server/pom.xml
@@ -46,6 +46,12 @@
 
 		<!-- Test dependencies -->
 		<dependency>
+			<groupId>ch.qos.logback</groupId>
+			<artifactId>logback-classic</artifactId>
+			<version>1.0.13</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
 			<groupId>junit</groupId>
 			<artifactId>junit</artifactId>
 			<scope>test</scope>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a07bba55/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSl4jJdbcEventLogger.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSl4jJdbcEventLogger.java b/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSl4jJdbcEventLogger.java
new file mode 100644
index 0000000..38e4370
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSl4jJdbcEventLogger.java
@@ -0,0 +1,201 @@
+/*****************************************************************
+ *   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
+ *
+ *    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.
+ ****************************************************************/
+package org.apache.cayenne.log;
+
+import org.apache.cayenne.access.translator.DbAttributeBinding;
+import org.apache.cayenne.access.translator.ParameterBinding;
+import org.apache.cayenne.configuration.RuntimeProperties;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.map.DbAttribute;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * @since 4.1
+ */
+public class CompactSl4jJdbcEventLogger extends Slf4jJdbcEventLogger {
+
+    private static final String UNION = "UNION";
+    private static final String SELECT = "SELECT";
+    private static final String FROM = "FROM";
+    private static final String SPACE = " ";
+
+    public CompactSl4jJdbcEventLogger(@Inject RuntimeProperties runtimeProperties) {
+        super(runtimeProperties);
+    }
+
+    @Override
+    public void logQuery(String sql, ParameterBinding[] bindings) {
+        if (!isLoggable()) {
+            return;
+        }
+
+        String str;
+        if (sql.toUpperCase().contains(UNION)) {
+            str = processUnionSql(sql);
+        } else {
+            str = formatSqlSelectColumns(sql);
+        }
+
+        StringBuilder stringBuilder = new StringBuilder(str);
+        appendParameters(stringBuilder, "bind", bindings);
+        if (stringBuilder.length() < 0) {
+            return;
+        }
+
+        super.logQuery(stringBuilder.toString(), new ParameterBinding[0]);
+    }
+
+    private String processUnionSql(String sql) {
+
+        String modified = Pattern.compile(UNION.toLowerCase(), Pattern.CASE_INSENSITIVE).matcher(sql).replaceAll(UNION);
+        String[] queries = modified.split(
+                UNION);
+        List<String> formattedQueries = Arrays.stream(queries).map(this::formatSqlSelectColumns).collect(Collectors.toList());
+        StringBuilder buffer = new StringBuilder();
+        boolean used =  false;
+        for (String q: formattedQueries) {
+            if(!used){
+                used = true;
+            } else {
+                buffer.append(SPACE).append(UNION);
+            }
+            buffer.append(q);
+        }
+        return buffer.toString();
+    }
+
+    private String formatSqlSelectColumns(String sql) {
+        int selectIndex = sql.toUpperCase().indexOf(SELECT);
+        if (selectIndex == -1) {
+            return sql;
+        }
+        selectIndex += SELECT.length();
+        int fromIndex = sql.toUpperCase().indexOf(FROM);
+        String columns = sql.substring(selectIndex, fromIndex);
+        String[] columnsArray = columns.split(",");
+        if (columnsArray.length <= 3) {
+            return sql;
+        }
+
+        columns = "(" + columnsArray.length + " columns)";
+        return new StringBuilder(sql.substring(0, selectIndex))
+                .append(SPACE)
+                .append(columns)
+                .append(SPACE)
+                .append(sql, fromIndex, sql.length())
+                .toString();
+    }
+
+    private void appendParameters(StringBuilder buffer, String label, ParameterBinding[] bindings) {
+        int bindingLength = bindings.length;
+        if (bindingLength == 0) {
+            return;
+        }
+
+        buildBinding(buffer, label, collectBindings(bindings));
+    }
+
+    @SuppressWarnings("unchecked")
+    private Map<String, List<String>> collectBindings(ParameterBinding[] bindings) {
+        Map<String, List<String>> bindingsMap = new HashMap<>();
+
+        String key = null;
+        String value;
+        for (int i = 0; i < bindings.length; i++) {
+            ParameterBinding b = bindings[i];
+
+            if (b.isExcluded()) {
+                continue;
+            }
+
+            if (b instanceof DbAttributeBinding) {
+                DbAttribute attribute = ((DbAttributeBinding) b).getAttribute();
+                if (attribute != null) {
+                    key = attribute.getName();
+                }
+            }
+
+            if (b.getExtendedType() != null) {
+                value = b.getExtendedType().toString(b.getValue());
+            } else if(b.getValue() == null) {
+                value = "NULL";
+            } else {
+                value = new StringBuilder(b.getValue().getClass().getName())
+                        .append("@")
+                        .append(System.identityHashCode(b.getValue())).toString();
+            }
+
+            List<String> objects = bindingsMap.computeIfAbsent(key, k -> new ArrayList<>());
+            objects.add(value);
+        }
+
+        return bindingsMap;
+    }
+
+    private void buildBinding(StringBuilder buffer, String label, Map<String, List<String>> bindingsMap) {
+        int j = 1;
+        boolean hasIncluded = false;
+        for (String k : bindingsMap.keySet()) {
+            if (!hasIncluded) {
+                hasIncluded = true;
+                buffer.append(" [").append(label).append(": ");
+            } else {
+                buffer.append(", ");
+            }
+            buffer.append(j).append("->").append(k).append(": ");
+
+            List<String> bindingsList = bindingsMap.get(k);
+            if (bindingsList.size() == 1 ) {
+                buffer.append(bindingsList.get(0));
+            } else {
+                buffer.append("{");
+                boolean wasAdded = false;
+                for (Object val : bindingsList) {
+                    if (wasAdded) {
+                        buffer.append(", ");
+                    } else {
+                        wasAdded = true;
+                    }
+                    buffer.append(val);
+                }
+                buffer.append("}");
+            }
+            j++;
+        }
+
+        if (hasIncluded) {
+            buffer.append("]");
+        }
+    }
+
+    @Override
+    public void logBeginTransaction(String transactionLabel) {
+    }
+
+    @Override
+    public void logCommitTransaction(String transactionLabel) {
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a07bba55/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSl4jJdbcEventLoggerTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSl4jJdbcEventLoggerTest.java b/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSl4jJdbcEventLoggerTest.java
new file mode 100644
index 0000000..f7dbe76
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSl4jJdbcEventLoggerTest.java
@@ -0,0 +1,109 @@
+/*****************************************************************
+ *   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
+ *
+ *    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.
+ ****************************************************************/
+package org.apache.cayenne.log;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.spi.LoggingEvent;
+import org.apache.cayenne.access.translator.DbAttributeBinding;
+import org.apache.cayenne.access.types.BooleanType;
+import org.apache.cayenne.access.types.CharType;
+import org.apache.cayenne.access.types.ExtendedType;
+import org.apache.cayenne.access.types.IntegerType;
+import org.apache.cayenne.configuration.DefaultRuntimeProperties;
+import org.apache.cayenne.map.DbAttribute;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+
+public class CompactSl4jJdbcEventLoggerTest {
+
+    @Before
+    public void before() {
+        TestAppender.events.clear();
+    }
+
+    @Test
+    public void logWithCompact_Union() {
+
+        CompactSl4jJdbcEventLogger compactSl4jJdbcEventLogger = new CompactSl4jJdbcEventLogger(new DefaultRuntimeProperties(Collections.emptyMap()));
+        DbAttributeBinding[] bindings = createBindings();
+        final List<LoggingEvent> log = TestAppender.events;
+        assertEquals(log.size(), 0);
+
+        compactSl4jJdbcEventLogger.logQuery(
+                "SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.F_KEY2 AS ec0_2," +
+                        " t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
+                        "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?", createBindings());
+        assertEquals(log.size(), 1);
+        LoggingEvent firstLogEntry = log.get(0);
+        assertThat(firstLogEntry.getLevel(), is(Level.INFO));
+        assertThat(firstLogEntry.getMessage(), is("SELECT (4 columns) FROM COMPOUND_FK_TEST t0 " +
+                "INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
+                "WHERE t1.NAME LIKE ? [bind: 1->t0.NAME: {'', 52, 'true'}, 2->t0.F_KEY1: 'true'] "));
+        assertThat(firstLogEntry.getLoggerName(), is("org.apache.cayenne.log.JdbcEventLogger"));
+
+        compactSl4jJdbcEventLogger.logQuery(
+                "SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, " +
+                        "t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
+                        "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?" +
+                        "UNION ALL " +
+                        "SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1," +
+                        " t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
+                        "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?" +
+                        "union all " +
+                        "SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.F_KEY2 AS ec0_2," +
+                        " t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
+                        "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?", bindings);
+        assertEquals(log.size(), 2);
+         firstLogEntry = log.get(1);
+        assertThat(firstLogEntry.getLevel(), is(Level.INFO));
+        assertThat(firstLogEntry.getMessage(), is("SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 " +
+                "INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
+                "WHERE t1.NAME LIKE ? UNION ALL SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.PKEY AS ec0_3 " +
+                "FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
+                "WHERE t1.NAME LIKE ? UNION all SELECT (4 columns) FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
+                "WHERE t1.NAME LIKE ? [bind: 1->t0.NAME: {'', 52, 'true'}, 2->t0.F_KEY1: 'true'] "));
+        assertThat(firstLogEntry.getLoggerName(), is("org.apache.cayenne.log.JdbcEventLogger"));
+
+    }
+
+    private DbAttributeBinding [] createBindings() {
+        return new DbAttributeBinding[] { createBinding("t0.NAME", 1, "", new CharType(false, false)),
+                                            createBinding("t0.NAME", 2, 52, new IntegerType()),
+                                            createBinding("t0.NAME", 3, true, new BooleanType()),
+                                            createBinding("t0.F_KEY1", 4, true, new BooleanType())};
+    }
+
+    private DbAttributeBinding createBinding(String name, int position, Object object, ExtendedType type){
+
+        DbAttributeBinding dbAttributeBinding = new DbAttributeBinding(new DbAttribute(name));
+        dbAttributeBinding.setValue(object);
+        dbAttributeBinding.setStatementPosition(position);
+        if (type != null) {
+            dbAttributeBinding.setExtendedType(type);
+        }
+
+        return dbAttributeBinding;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a07bba55/cayenne-server/src/test/java/org/apache/cayenne/log/Slf4jJdbcEventLoggerTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/log/Slf4jJdbcEventLoggerTest.java b/cayenne-server/src/test/java/org/apache/cayenne/log/Slf4jJdbcEventLoggerTest.java
index a41861c..322eb7f 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/log/Slf4jJdbcEventLoggerTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/log/Slf4jJdbcEventLoggerTest.java
@@ -18,14 +18,10 @@
  ****************************************************************/
 package org.apache.cayenne.log;
 
-import org.apache.cayenne.configuration.DefaultRuntimeProperties;
 import org.apache.cayenne.util.IDUtil;
 import org.junit.Test;
 
-import java.util.Collections;
-
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 
 public class Slf4jJdbcEventLoggerTest {
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a07bba55/cayenne-server/src/test/java/org/apache/cayenne/log/TestAppender.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/log/TestAppender.java b/cayenne-server/src/test/java/org/apache/cayenne/log/TestAppender.java
new file mode 100644
index 0000000..5560c07
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/log/TestAppender.java
@@ -0,0 +1,16 @@
+package org.apache.cayenne.log;
+
+import ch.qos.logback.classic.spi.LoggingEvent;
+import ch.qos.logback.core.AppenderBase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class TestAppender extends AppenderBase<LoggingEvent> {
+    static List<LoggingEvent> events = new ArrayList<>();
+
+    @Override
+    protected void append(LoggingEvent e) {
+        events.add(e);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/a07bba55/cayenne-server/src/test/resources/logback-test.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/logback-test.xml b/cayenne-server/src/test/resources/logback-test.xml
new file mode 100644
index 0000000..616beac
--- /dev/null
+++ b/cayenne-server/src/test/resources/logback-test.xml
@@ -0,0 +1,42 @@
+<configuration>
+
+    <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
+
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <layout class="ch.qos.logback.classic.PatternLayout">
+            <Pattern>
+                %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+            </Pattern>
+        </layout>
+    </appender>
+
+
+    <appender name="TEST-INFO"
+              class="org.apache.cayenne.log.TestAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <Pattern>
+                %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+            </Pattern>
+        </encoder>
+
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- rollover daily -->
+            <fileNamePattern>archived/error.%d{yyyy-MM-dd}.%i.log
+            </fileNamePattern>
+            <timeBasedFileNamingAndTriggeringPolicy
+                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+
+    </appender>
+
+    <root level="info">
+        <appender-ref ref="TEST-INFO" />
+    </root>
+
+    <logger name="org.apache.cayenne" level="info">
+        <appender-ref ref="STDOUT"/>
+    </logger>
+
+</configuration>
\ No newline at end of file


[4/4] cayenne git commit: CAY-2485 Compact Slf4j Logger additional tests release notes cleanup

Posted by nt...@apache.org.
CAY-2485 Compact Slf4j Logger
  additional tests
  release notes
  cleanup


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/7694a64d
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/7694a64d
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/7694a64d

Branch: refs/heads/master
Commit: 7694a64d3b83175e3e2ffd2db315e78c1bf0813f
Parents: a4ad4b6
Author: Nikita Timofeev <st...@gmail.com>
Authored: Thu Oct 18 17:29:52 2018 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Thu Oct 18 17:29:52 2018 +0300

----------------------------------------------------------------------
 RELEASE-NOTES.txt                               |  1 +
 .../log/CompactSlf4jJdbcEventLogger.java        | 15 ++--
 .../log/CompactSlf4jJdbcEventLoggerTest.java    | 80 +++++++++++++-------
 .../src/test/resources/logback-test.xml         | 42 ----------
 4 files changed, 60 insertions(+), 78 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/7694a64d/RELEASE-NOTES.txt
----------------------------------------------------------------------
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index e1c1e28..dce64ec 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -20,6 +20,7 @@ CAY-2473 Modeler: cleanup attributes and relationship editors
 CAY-2474 Modeler: swap buttons in dialog toolbar
 CAY-2475 Modeler: move inheritance icon to name column in objAttr table and objRel table
 CAY-2481 Support for Object[] as return type in SQLTemplate and SQLExec
+CAY-2485 Compact Slf4j Logger
 CAY-2487 Removed usage of CayenneException.
 CAY-2489 Add validation to the case of not to PK relationships
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7694a64d/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLogger.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLogger.java b/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLogger.java
index d4d57a9..b6ea8b3 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLogger.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLogger.java
@@ -65,8 +65,7 @@ public class CompactSlf4jJdbcEventLogger extends Slf4jJdbcEventLogger {
     protected String processUnionSql(String sql) {
 
         String modified = Pattern.compile(UNION.toLowerCase(), Pattern.CASE_INSENSITIVE).matcher(sql).replaceAll(UNION);
-        String[] queries = modified.split(
-                UNION);
+        String[] queries = modified.split(UNION);
         List<String> formattedQueries = Arrays.stream(queries).map(this::trimSqlSelectColumns).collect(Collectors.toList());
         StringBuilder buffer = new StringBuilder();
         boolean used =  false;
@@ -119,9 +118,7 @@ public class CompactSlf4jJdbcEventLogger extends Slf4jJdbcEventLogger {
 
         String key = null;
         String value;
-        for (int i = 0; i < bindings.length; i++) {
-            ParameterBinding b = bindings[i];
-
+        for (ParameterBinding b : bindings) {
             if (b.isExcluded()) {
                 continue;
             }
@@ -135,12 +132,12 @@ public class CompactSlf4jJdbcEventLogger extends Slf4jJdbcEventLogger {
 
             if (b.getExtendedType() != null) {
                 value = b.getExtendedType().toString(b.getValue());
-            } else if(b.getValue() == null) {
+            } else if (b.getValue() == null) {
                 value = "NULL";
             } else {
-                value = new StringBuilder(b.getValue().getClass().getName())
-                        .append("@")
-                        .append(System.identityHashCode(b.getValue())).toString();
+                value = b.getValue().getClass().getName() +
+                        "@" +
+                        System.identityHashCode(b.getValue());
             }
 
             List<String> objects = bindingsMap.computeIfAbsent(key, k -> new ArrayList<>());

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7694a64d/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLoggerTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLoggerTest.java b/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLoggerTest.java
index 4846463..84ecd6c 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLoggerTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLoggerTest.java
@@ -25,32 +25,54 @@ import org.apache.cayenne.access.types.ExtendedType;
 import org.apache.cayenne.access.types.IntegerType;
 import org.apache.cayenne.configuration.DefaultRuntimeProperties;
 import org.apache.cayenne.map.DbAttribute;
+import org.junit.Before;
 import org.junit.Test;
 
 import java.util.Collections;
 
-import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.*;
 
 public class CompactSlf4jJdbcEventLoggerTest {
 
-    @Test
-    public void logWithCompact_Union() {
+    private CompactSlf4jJdbcEventLogger logger;
 
-        CompactSlf4jJdbcEventLogger compactSl4jJdbcEventLogger = new CompactSlf4jJdbcEventLogger(new DefaultRuntimeProperties(Collections.emptyMap()));
-        DbAttributeBinding[] bindings = createBindings();
+    @Before
+    public void createLogger() {
+        logger = new CompactSlf4jJdbcEventLogger(new DefaultRuntimeProperties(Collections.emptyMap()));
+    }
+
+    @Test
+    public void compactSimpleSql() {
+        String processesSelectSql = logger.trimSqlSelectColumns(
+                "SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.F_KEY2 AS ec0_2," +
+                        " t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
+                        "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?");
 
-        String processesSelectSql = compactSl4jJdbcEventLogger.trimSqlSelectColumns("SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.F_KEY2 AS ec0_2," +
-                " t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
-                "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?");
         assertEquals(processesSelectSql, "SELECT (4 columns) FROM COMPOUND_FK_TEST t0 " +
                 "INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
-                        "WHERE t1.NAME LIKE ?");
+                "WHERE t1.NAME LIKE ?");
+    }
 
-        StringBuilder buffer = new StringBuilder();
-        compactSl4jJdbcEventLogger.appendParameters(buffer, "bind", bindings);
-        assertThat(buffer.toString(), is("[bind: 1->t0.NAME: {'', 52, 'true'}, 2->t0.F_KEY1: 'true']"));
-        String processedUnionSql = compactSl4jJdbcEventLogger.processUnionSql(
+
+    @Test
+    public void compactNotSelect() {
+        String processedSql = logger.trimSqlSelectColumns(
+                "UPDATE test SET name = 'abc', value = 123 WHERE id = 321");
+
+        assertEquals("UPDATE test SET name = 'abc', value = 123 WHERE id = 321", processedSql);
+    }
+
+    @Test
+    public void compactSubSelect() {
+        String processedSql = logger.trimSqlSelectColumns(
+                "INSERT INTO test1 SELECT column1, column2, column3, column4, column5, column6 FROM test2 WHERE id = 321");
+
+        assertEquals("INSERT INTO test1 SELECT (6 columns) FROM test2 WHERE id = 321", processedSql);
+    }
+
+    @Test
+    public void compactUnion() {
+        String processedUnionSql = logger.processUnionSql(
                 "SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, " +
                         "t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
                         "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?" +
@@ -63,31 +85,35 @@ public class CompactSlf4jJdbcEventLoggerTest {
                         " t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
                         "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?");
 
-        assertThat(processedUnionSql, is("SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 " +
+        assertEquals(processedUnionSql,
+                "SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 " +
                 "INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
                 "WHERE t1.NAME LIKE ? UNION ALL SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.PKEY AS ec0_3 " +
                 "FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
-                "WHERE t1.NAME LIKE ? UNION all SELECT (4 columns) FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
-                "WHERE t1.NAME LIKE ?"));
-
+                "WHERE t1.NAME LIKE ? UNION all SELECT (4 columns) FROM COMPOUND_FK_TEST t0 " +
+                "INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
+                "WHERE t1.NAME LIKE ?");
     }
 
-    private DbAttributeBinding [] createBindings() {
-        return new DbAttributeBinding[] { createBinding("t0.NAME", 1, "", new CharType(false, false)),
-                                            createBinding("t0.NAME", 2, 52, new IntegerType()),
-                                            createBinding("t0.NAME", 3, true, new BooleanType()),
-                                            createBinding("t0.F_KEY1", 4, true, new BooleanType())};
+    @Test
+    public void compactBindings() {
+        StringBuilder buffer = new StringBuilder();
+        DbAttributeBinding[] bindings = new DbAttributeBinding[] {
+                createBinding("t0.NAME", 1, "", new CharType(false, false)),
+                createBinding("t0.NAME", 2, 52, new IntegerType()),
+                createBinding("t0.NAME", 3, true, new BooleanType()),
+                createBinding("t0.F_KEY1", 4, true, new BooleanType())
+        };
+        logger.appendParameters(buffer, "bind", bindings);
+
+        assertEquals(buffer.toString(), "[bind: 1->t0.NAME: {'', 52, 'true'}, 2->t0.F_KEY1: 'true']");
     }
 
     private DbAttributeBinding createBinding(String name, int position, Object object, ExtendedType type){
-
         DbAttributeBinding dbAttributeBinding = new DbAttributeBinding(new DbAttribute(name));
         dbAttributeBinding.setValue(object);
         dbAttributeBinding.setStatementPosition(position);
-        if (type != null) {
-            dbAttributeBinding.setExtendedType(type);
-        }
-
+        dbAttributeBinding.setExtendedType(type);
         return dbAttributeBinding;
     }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/7694a64d/cayenne-server/src/test/resources/logback-test.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/resources/logback-test.xml b/cayenne-server/src/test/resources/logback-test.xml
deleted file mode 100644
index 616beac..0000000
--- a/cayenne-server/src/test/resources/logback-test.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<configuration>
-
-    <statusListener class="ch.qos.logback.core.status.NopStatusListener" />
-
-    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
-        <layout class="ch.qos.logback.classic.PatternLayout">
-            <Pattern>
-                %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
-            </Pattern>
-        </layout>
-    </appender>
-
-
-    <appender name="TEST-INFO"
-              class="org.apache.cayenne.log.TestAppender">
-        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
-            <Pattern>
-                %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
-            </Pattern>
-        </encoder>
-
-        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
-            <!-- rollover daily -->
-            <fileNamePattern>archived/error.%d{yyyy-MM-dd}.%i.log
-            </fileNamePattern>
-            <timeBasedFileNamingAndTriggeringPolicy
-                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
-                <maxFileSize>10MB</maxFileSize>
-            </timeBasedFileNamingAndTriggeringPolicy>
-        </rollingPolicy>
-
-    </appender>
-
-    <root level="info">
-        <appender-ref ref="TEST-INFO" />
-    </root>
-
-    <logger name="org.apache.cayenne" level="info">
-        <appender-ref ref="STDOUT"/>
-    </logger>
-
-</configuration>
\ No newline at end of file


[2/4] cayenne git commit: CAY-2485 Refactored logger to have possibility to test without adding logback.

Posted by nt...@apache.org.
CAY-2485 Refactored logger to have possibility to test without adding logback.


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/d8d2ec5d
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/d8d2ec5d
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/d8d2ec5d

Branch: refs/heads/master
Commit: d8d2ec5de67e0c203ee73a85bba7192fe0ba86f4
Parents: a07bba5
Author: kkomyak <co...@gmail.com>
Authored: Mon Oct 15 12:23:41 2018 +0300
Committer: kkomyak <co...@gmail.com>
Committed: Mon Oct 15 12:37:29 2018 +0300

----------------------------------------------------------------------
 cayenne-server/pom.xml                          |   6 -
 .../cayenne/log/CompactSl4jJdbcEventLogger.java | 201 -------------------
 .../log/CompactSlf4jJdbcEventLogger.java        | 196 ++++++++++++++++++
 .../cayenne/log/Slf4jJdbcEventLogger.java       |   2 +-
 .../log/CompactSl4jJdbcEventLoggerTest.java     | 109 ----------
 .../log/CompactSlf4jJdbcEventLoggerTest.java    |  93 +++++++++
 .../org/apache/cayenne/log/TestAppender.java    |  16 --
 7 files changed, 290 insertions(+), 333 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/d8d2ec5d/cayenne-server/pom.xml
----------------------------------------------------------------------
diff --git a/cayenne-server/pom.xml b/cayenne-server/pom.xml
index e965ffa..0ede0dd 100644
--- a/cayenne-server/pom.xml
+++ b/cayenne-server/pom.xml
@@ -46,12 +46,6 @@
 
 		<!-- Test dependencies -->
 		<dependency>
-			<groupId>ch.qos.logback</groupId>
-			<artifactId>logback-classic</artifactId>
-			<version>1.0.13</version>
-			<scope>test</scope>
-		</dependency>
-		<dependency>
 			<groupId>junit</groupId>
 			<artifactId>junit</artifactId>
 			<scope>test</scope>

http://git-wip-us.apache.org/repos/asf/cayenne/blob/d8d2ec5d/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSl4jJdbcEventLogger.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSl4jJdbcEventLogger.java b/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSl4jJdbcEventLogger.java
deleted file mode 100644
index 38e4370..0000000
--- a/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSl4jJdbcEventLogger.java
+++ /dev/null
@@ -1,201 +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
- *
- *    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.
- ****************************************************************/
-package org.apache.cayenne.log;
-
-import org.apache.cayenne.access.translator.DbAttributeBinding;
-import org.apache.cayenne.access.translator.ParameterBinding;
-import org.apache.cayenne.configuration.RuntimeProperties;
-import org.apache.cayenne.di.Inject;
-import org.apache.cayenne.map.DbAttribute;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-
-/**
- * @since 4.1
- */
-public class CompactSl4jJdbcEventLogger extends Slf4jJdbcEventLogger {
-
-    private static final String UNION = "UNION";
-    private static final String SELECT = "SELECT";
-    private static final String FROM = "FROM";
-    private static final String SPACE = " ";
-
-    public CompactSl4jJdbcEventLogger(@Inject RuntimeProperties runtimeProperties) {
-        super(runtimeProperties);
-    }
-
-    @Override
-    public void logQuery(String sql, ParameterBinding[] bindings) {
-        if (!isLoggable()) {
-            return;
-        }
-
-        String str;
-        if (sql.toUpperCase().contains(UNION)) {
-            str = processUnionSql(sql);
-        } else {
-            str = formatSqlSelectColumns(sql);
-        }
-
-        StringBuilder stringBuilder = new StringBuilder(str);
-        appendParameters(stringBuilder, "bind", bindings);
-        if (stringBuilder.length() < 0) {
-            return;
-        }
-
-        super.logQuery(stringBuilder.toString(), new ParameterBinding[0]);
-    }
-
-    private String processUnionSql(String sql) {
-
-        String modified = Pattern.compile(UNION.toLowerCase(), Pattern.CASE_INSENSITIVE).matcher(sql).replaceAll(UNION);
-        String[] queries = modified.split(
-                UNION);
-        List<String> formattedQueries = Arrays.stream(queries).map(this::formatSqlSelectColumns).collect(Collectors.toList());
-        StringBuilder buffer = new StringBuilder();
-        boolean used =  false;
-        for (String q: formattedQueries) {
-            if(!used){
-                used = true;
-            } else {
-                buffer.append(SPACE).append(UNION);
-            }
-            buffer.append(q);
-        }
-        return buffer.toString();
-    }
-
-    private String formatSqlSelectColumns(String sql) {
-        int selectIndex = sql.toUpperCase().indexOf(SELECT);
-        if (selectIndex == -1) {
-            return sql;
-        }
-        selectIndex += SELECT.length();
-        int fromIndex = sql.toUpperCase().indexOf(FROM);
-        String columns = sql.substring(selectIndex, fromIndex);
-        String[] columnsArray = columns.split(",");
-        if (columnsArray.length <= 3) {
-            return sql;
-        }
-
-        columns = "(" + columnsArray.length + " columns)";
-        return new StringBuilder(sql.substring(0, selectIndex))
-                .append(SPACE)
-                .append(columns)
-                .append(SPACE)
-                .append(sql, fromIndex, sql.length())
-                .toString();
-    }
-
-    private void appendParameters(StringBuilder buffer, String label, ParameterBinding[] bindings) {
-        int bindingLength = bindings.length;
-        if (bindingLength == 0) {
-            return;
-        }
-
-        buildBinding(buffer, label, collectBindings(bindings));
-    }
-
-    @SuppressWarnings("unchecked")
-    private Map<String, List<String>> collectBindings(ParameterBinding[] bindings) {
-        Map<String, List<String>> bindingsMap = new HashMap<>();
-
-        String key = null;
-        String value;
-        for (int i = 0; i < bindings.length; i++) {
-            ParameterBinding b = bindings[i];
-
-            if (b.isExcluded()) {
-                continue;
-            }
-
-            if (b instanceof DbAttributeBinding) {
-                DbAttribute attribute = ((DbAttributeBinding) b).getAttribute();
-                if (attribute != null) {
-                    key = attribute.getName();
-                }
-            }
-
-            if (b.getExtendedType() != null) {
-                value = b.getExtendedType().toString(b.getValue());
-            } else if(b.getValue() == null) {
-                value = "NULL";
-            } else {
-                value = new StringBuilder(b.getValue().getClass().getName())
-                        .append("@")
-                        .append(System.identityHashCode(b.getValue())).toString();
-            }
-
-            List<String> objects = bindingsMap.computeIfAbsent(key, k -> new ArrayList<>());
-            objects.add(value);
-        }
-
-        return bindingsMap;
-    }
-
-    private void buildBinding(StringBuilder buffer, String label, Map<String, List<String>> bindingsMap) {
-        int j = 1;
-        boolean hasIncluded = false;
-        for (String k : bindingsMap.keySet()) {
-            if (!hasIncluded) {
-                hasIncluded = true;
-                buffer.append(" [").append(label).append(": ");
-            } else {
-                buffer.append(", ");
-            }
-            buffer.append(j).append("->").append(k).append(": ");
-
-            List<String> bindingsList = bindingsMap.get(k);
-            if (bindingsList.size() == 1 ) {
-                buffer.append(bindingsList.get(0));
-            } else {
-                buffer.append("{");
-                boolean wasAdded = false;
-                for (Object val : bindingsList) {
-                    if (wasAdded) {
-                        buffer.append(", ");
-                    } else {
-                        wasAdded = true;
-                    }
-                    buffer.append(val);
-                }
-                buffer.append("}");
-            }
-            j++;
-        }
-
-        if (hasIncluded) {
-            buffer.append("]");
-        }
-    }
-
-    @Override
-    public void logBeginTransaction(String transactionLabel) {
-    }
-
-    @Override
-    public void logCommitTransaction(String transactionLabel) {
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/d8d2ec5d/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLogger.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLogger.java b/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLogger.java
new file mode 100644
index 0000000..d4d57a9
--- /dev/null
+++ b/cayenne-server/src/main/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLogger.java
@@ -0,0 +1,196 @@
+/*****************************************************************
+ *   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
+ *
+ *    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.
+ ****************************************************************/
+package org.apache.cayenne.log;
+
+import org.apache.cayenne.access.translator.DbAttributeBinding;
+import org.apache.cayenne.access.translator.ParameterBinding;
+import org.apache.cayenne.configuration.RuntimeProperties;
+import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.map.DbAttribute;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * @since 4.1
+ */
+public class CompactSlf4jJdbcEventLogger extends Slf4jJdbcEventLogger {
+
+    private static final String UNION = "UNION";
+    private static final String SELECT = "SELECT";
+    private static final String FROM = "FROM";
+    private static final String SPACE = " ";
+
+    public CompactSlf4jJdbcEventLogger(@Inject RuntimeProperties runtimeProperties) {
+        super(runtimeProperties);
+    }
+
+    @Override
+    public void logQuery(String sql, ParameterBinding[] bindings) {
+        if (!isLoggable()) {
+            return;
+        }
+
+        String str;
+        if (sql.toUpperCase().contains(UNION)) {
+            str = processUnionSql(sql);
+        } else {
+            str = trimSqlSelectColumns(sql);
+        }
+
+        super.logQuery(str, bindings);
+    }
+
+    protected String processUnionSql(String sql) {
+
+        String modified = Pattern.compile(UNION.toLowerCase(), Pattern.CASE_INSENSITIVE).matcher(sql).replaceAll(UNION);
+        String[] queries = modified.split(
+                UNION);
+        List<String> formattedQueries = Arrays.stream(queries).map(this::trimSqlSelectColumns).collect(Collectors.toList());
+        StringBuilder buffer = new StringBuilder();
+        boolean used =  false;
+        for (String q: formattedQueries) {
+            if(!used){
+                used = true;
+            } else {
+                buffer.append(SPACE).append(UNION);
+            }
+            buffer.append(q);
+        }
+        return buffer.toString();
+    }
+
+    protected String trimSqlSelectColumns(String sql) {
+        int selectIndex = sql.toUpperCase().indexOf(SELECT);
+        if (selectIndex == -1) {
+            return sql;
+        }
+        selectIndex += SELECT.length();
+        int fromIndex = sql.toUpperCase().indexOf(FROM);
+        String columns = sql.substring(selectIndex, fromIndex);
+        String[] columnsArray = columns.split(",");
+        if (columnsArray.length <= 3) {
+            return sql;
+        }
+
+        columns = "(" + columnsArray.length + " columns)";
+        return new StringBuilder(sql.substring(0, selectIndex))
+                .append(SPACE)
+                .append(columns)
+                .append(SPACE)
+                .append(sql, fromIndex, sql.length())
+                .toString();
+    }
+
+    @Override
+    protected void appendParameters(StringBuilder buffer, String label, ParameterBinding[] bindings) {
+        int bindingLength = bindings.length;
+        if (bindingLength == 0) {
+            return;
+        }
+
+        buildBinding(buffer, label, collectBindings(bindings));
+    }
+
+    @SuppressWarnings("unchecked")
+    private Map<String, List<String>> collectBindings(ParameterBinding[] bindings) {
+        Map<String, List<String>> bindingsMap = new HashMap<>();
+
+        String key = null;
+        String value;
+        for (int i = 0; i < bindings.length; i++) {
+            ParameterBinding b = bindings[i];
+
+            if (b.isExcluded()) {
+                continue;
+            }
+
+            if (b instanceof DbAttributeBinding) {
+                DbAttribute attribute = ((DbAttributeBinding) b).getAttribute();
+                if (attribute != null) {
+                    key = attribute.getName();
+                }
+            }
+
+            if (b.getExtendedType() != null) {
+                value = b.getExtendedType().toString(b.getValue());
+            } else if(b.getValue() == null) {
+                value = "NULL";
+            } else {
+                value = new StringBuilder(b.getValue().getClass().getName())
+                        .append("@")
+                        .append(System.identityHashCode(b.getValue())).toString();
+            }
+
+            List<String> objects = bindingsMap.computeIfAbsent(key, k -> new ArrayList<>());
+            objects.add(value);
+        }
+
+        return bindingsMap;
+    }
+
+    private void buildBinding(StringBuilder buffer, String label, Map<String, List<String>> bindingsMap) {
+        int j = 1;
+        boolean hasIncluded = false;
+        for (String k : bindingsMap.keySet()) {
+            if (!hasIncluded) {
+                hasIncluded = true;
+                buffer.append("[").append(label).append(": ");
+            } else {
+                buffer.append(", ");
+            }
+            buffer.append(j).append("->").append(k).append(": ");
+
+            List<String> bindingsList = bindingsMap.get(k);
+            if (bindingsList.size() == 1 ) {
+                buffer.append(bindingsList.get(0));
+            } else {
+                buffer.append("{");
+                boolean wasAdded = false;
+                for (Object val : bindingsList) {
+                    if (wasAdded) {
+                        buffer.append(", ");
+                    } else {
+                        wasAdded = true;
+                    }
+                    buffer.append(val);
+                }
+                buffer.append("}");
+            }
+            j++;
+        }
+
+        if (hasIncluded) {
+            buffer.append("]");
+        }
+    }
+
+    @Override
+    public void logBeginTransaction(String transactionLabel) {
+    }
+
+    @Override
+    public void logCommitTransaction(String transactionLabel) {
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/d8d2ec5d/cayenne-server/src/main/java/org/apache/cayenne/log/Slf4jJdbcEventLogger.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/log/Slf4jJdbcEventLogger.java b/cayenne-server/src/main/java/org/apache/cayenne/log/Slf4jJdbcEventLogger.java
index 3cdf779..3318493 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/log/Slf4jJdbcEventLogger.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/log/Slf4jJdbcEventLogger.java
@@ -91,7 +91,7 @@ public class Slf4jJdbcEventLogger implements JdbcEventLogger {
 	}
 
 	@SuppressWarnings("unchecked")
-	private void appendParameters(StringBuilder buffer, String label, ParameterBinding[] bindings) {
+	protected void appendParameters(StringBuilder buffer, String label, ParameterBinding[] bindings) {
 
 		int len = bindings.length;
 		if (len > 0) {

http://git-wip-us.apache.org/repos/asf/cayenne/blob/d8d2ec5d/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSl4jJdbcEventLoggerTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSl4jJdbcEventLoggerTest.java b/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSl4jJdbcEventLoggerTest.java
deleted file mode 100644
index f7dbe76..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSl4jJdbcEventLoggerTest.java
+++ /dev/null
@@ -1,109 +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
- *
- *    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.
- ****************************************************************/
-package org.apache.cayenne.log;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.spi.LoggingEvent;
-import org.apache.cayenne.access.translator.DbAttributeBinding;
-import org.apache.cayenne.access.types.BooleanType;
-import org.apache.cayenne.access.types.CharType;
-import org.apache.cayenne.access.types.ExtendedType;
-import org.apache.cayenne.access.types.IntegerType;
-import org.apache.cayenne.configuration.DefaultRuntimeProperties;
-import org.apache.cayenne.map.DbAttribute;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Collections;
-import java.util.List;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.*;
-
-public class CompactSl4jJdbcEventLoggerTest {
-
-    @Before
-    public void before() {
-        TestAppender.events.clear();
-    }
-
-    @Test
-    public void logWithCompact_Union() {
-
-        CompactSl4jJdbcEventLogger compactSl4jJdbcEventLogger = new CompactSl4jJdbcEventLogger(new DefaultRuntimeProperties(Collections.emptyMap()));
-        DbAttributeBinding[] bindings = createBindings();
-        final List<LoggingEvent> log = TestAppender.events;
-        assertEquals(log.size(), 0);
-
-        compactSl4jJdbcEventLogger.logQuery(
-                "SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.F_KEY2 AS ec0_2," +
-                        " t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
-                        "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?", createBindings());
-        assertEquals(log.size(), 1);
-        LoggingEvent firstLogEntry = log.get(0);
-        assertThat(firstLogEntry.getLevel(), is(Level.INFO));
-        assertThat(firstLogEntry.getMessage(), is("SELECT (4 columns) FROM COMPOUND_FK_TEST t0 " +
-                "INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
-                "WHERE t1.NAME LIKE ? [bind: 1->t0.NAME: {'', 52, 'true'}, 2->t0.F_KEY1: 'true'] "));
-        assertThat(firstLogEntry.getLoggerName(), is("org.apache.cayenne.log.JdbcEventLogger"));
-
-        compactSl4jJdbcEventLogger.logQuery(
-                "SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, " +
-                        "t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
-                        "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?" +
-                        "UNION ALL " +
-                        "SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1," +
-                        " t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
-                        "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?" +
-                        "union all " +
-                        "SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.F_KEY2 AS ec0_2," +
-                        " t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
-                        "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?", bindings);
-        assertEquals(log.size(), 2);
-         firstLogEntry = log.get(1);
-        assertThat(firstLogEntry.getLevel(), is(Level.INFO));
-        assertThat(firstLogEntry.getMessage(), is("SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 " +
-                "INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
-                "WHERE t1.NAME LIKE ? UNION ALL SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.PKEY AS ec0_3 " +
-                "FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
-                "WHERE t1.NAME LIKE ? UNION all SELECT (4 columns) FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
-                "WHERE t1.NAME LIKE ? [bind: 1->t0.NAME: {'', 52, 'true'}, 2->t0.F_KEY1: 'true'] "));
-        assertThat(firstLogEntry.getLoggerName(), is("org.apache.cayenne.log.JdbcEventLogger"));
-
-    }
-
-    private DbAttributeBinding [] createBindings() {
-        return new DbAttributeBinding[] { createBinding("t0.NAME", 1, "", new CharType(false, false)),
-                                            createBinding("t0.NAME", 2, 52, new IntegerType()),
-                                            createBinding("t0.NAME", 3, true, new BooleanType()),
-                                            createBinding("t0.F_KEY1", 4, true, new BooleanType())};
-    }
-
-    private DbAttributeBinding createBinding(String name, int position, Object object, ExtendedType type){
-
-        DbAttributeBinding dbAttributeBinding = new DbAttributeBinding(new DbAttribute(name));
-        dbAttributeBinding.setValue(object);
-        dbAttributeBinding.setStatementPosition(position);
-        if (type != null) {
-            dbAttributeBinding.setExtendedType(type);
-        }
-
-        return dbAttributeBinding;
-    }
-}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/d8d2ec5d/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLoggerTest.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLoggerTest.java b/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLoggerTest.java
new file mode 100644
index 0000000..4846463
--- /dev/null
+++ b/cayenne-server/src/test/java/org/apache/cayenne/log/CompactSlf4jJdbcEventLoggerTest.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
+ *
+ *    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.
+ ****************************************************************/
+package org.apache.cayenne.log;
+
+import org.apache.cayenne.access.translator.DbAttributeBinding;
+import org.apache.cayenne.access.types.BooleanType;
+import org.apache.cayenne.access.types.CharType;
+import org.apache.cayenne.access.types.ExtendedType;
+import org.apache.cayenne.access.types.IntegerType;
+import org.apache.cayenne.configuration.DefaultRuntimeProperties;
+import org.apache.cayenne.map.DbAttribute;
+import org.junit.Test;
+
+import java.util.Collections;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+
+public class CompactSlf4jJdbcEventLoggerTest {
+
+    @Test
+    public void logWithCompact_Union() {
+
+        CompactSlf4jJdbcEventLogger compactSl4jJdbcEventLogger = new CompactSlf4jJdbcEventLogger(new DefaultRuntimeProperties(Collections.emptyMap()));
+        DbAttributeBinding[] bindings = createBindings();
+
+        String processesSelectSql = compactSl4jJdbcEventLogger.trimSqlSelectColumns("SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.F_KEY2 AS ec0_2," +
+                " t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
+                "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?");
+        assertEquals(processesSelectSql, "SELECT (4 columns) FROM COMPOUND_FK_TEST t0 " +
+                "INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
+                        "WHERE t1.NAME LIKE ?");
+
+        StringBuilder buffer = new StringBuilder();
+        compactSl4jJdbcEventLogger.appendParameters(buffer, "bind", bindings);
+        assertThat(buffer.toString(), is("[bind: 1->t0.NAME: {'', 52, 'true'}, 2->t0.F_KEY1: 'true']"));
+        String processedUnionSql = compactSl4jJdbcEventLogger.processUnionSql(
+                "SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, " +
+                        "t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
+                        "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?" +
+                        "UNION ALL " +
+                        "SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1," +
+                        " t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
+                        "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?" +
+                        "union all " +
+                        "SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.F_KEY2 AS ec0_2," +
+                        " t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST " +
+                        "t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) WHERE t1.NAME LIKE ?");
+
+        assertThat(processedUnionSql, is("SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.PKEY AS ec0_3 FROM COMPOUND_FK_TEST t0 " +
+                "INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
+                "WHERE t1.NAME LIKE ? UNION ALL SELECT t0.NAME AS ec0_0, t0.F_KEY1 AS ec0_1, t0.PKEY AS ec0_3 " +
+                "FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
+                "WHERE t1.NAME LIKE ? UNION all SELECT (4 columns) FROM COMPOUND_FK_TEST t0 INNER JOIN COMPOUND_PK_TEST t1 ON (t0.F_KEY1 = t1.KEY1 AND t0.F_KEY2 = t1.KEY2) " +
+                "WHERE t1.NAME LIKE ?"));
+
+    }
+
+    private DbAttributeBinding [] createBindings() {
+        return new DbAttributeBinding[] { createBinding("t0.NAME", 1, "", new CharType(false, false)),
+                                            createBinding("t0.NAME", 2, 52, new IntegerType()),
+                                            createBinding("t0.NAME", 3, true, new BooleanType()),
+                                            createBinding("t0.F_KEY1", 4, true, new BooleanType())};
+    }
+
+    private DbAttributeBinding createBinding(String name, int position, Object object, ExtendedType type){
+
+        DbAttributeBinding dbAttributeBinding = new DbAttributeBinding(new DbAttribute(name));
+        dbAttributeBinding.setValue(object);
+        dbAttributeBinding.setStatementPosition(position);
+        if (type != null) {
+            dbAttributeBinding.setExtendedType(type);
+        }
+
+        return dbAttributeBinding;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/d8d2ec5d/cayenne-server/src/test/java/org/apache/cayenne/log/TestAppender.java
----------------------------------------------------------------------
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/log/TestAppender.java b/cayenne-server/src/test/java/org/apache/cayenne/log/TestAppender.java
deleted file mode 100644
index 5560c07..0000000
--- a/cayenne-server/src/test/java/org/apache/cayenne/log/TestAppender.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.apache.cayenne.log;
-
-import ch.qos.logback.classic.spi.LoggingEvent;
-import ch.qos.logback.core.AppenderBase;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class TestAppender extends AppenderBase<LoggingEvent> {
-    static List<LoggingEvent> events = new ArrayList<>();
-
-    @Override
-    protected void append(LoggingEvent e) {
-        events.add(e);
-    }
-}
\ No newline at end of file


[3/4] cayenne git commit: Merge PR #333

Posted by nt...@apache.org.
Merge PR #333


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/a4ad4b6d
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/a4ad4b6d
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/a4ad4b6d

Branch: refs/heads/master
Commit: a4ad4b6d0d38750a0d9dac3c193c2e3d73989e14
Parents: 5855ffc d8d2ec5
Author: Nikita Timofeev <st...@gmail.com>
Authored: Thu Oct 18 17:14:13 2018 +0300
Committer: Nikita Timofeev <st...@gmail.com>
Committed: Thu Oct 18 17:14:13 2018 +0300

----------------------------------------------------------------------
 .../log/CompactSlf4jJdbcEventLogger.java        | 196 +++++++++++++++++++
 .../cayenne/log/Slf4jJdbcEventLogger.java       |   2 +-
 .../log/CompactSlf4jJdbcEventLoggerTest.java    |  93 +++++++++
 .../cayenne/log/Slf4jJdbcEventLoggerTest.java   |   4 -
 .../src/test/resources/logback-test.xml         |  42 ++++
 5 files changed, 332 insertions(+), 5 deletions(-)
----------------------------------------------------------------------