From e38eb04cc1092ec0980b23e378839256a1a2f621 Mon Sep 17 00:00:00 2001 From: Yuu NAKAJIMA Date: Wed, 24 May 2023 15:57:43 +0900 Subject: [PATCH 1/5] Add execute --- pom.xml | 1 - .../src/main/java/org/nkjmlab/sorm4j/Orm.java | 3 +++ .../sorm4j/internal/OrmConnectionImpl.java | 18 ++++++++++++++++++ .../org/nkjmlab/sorm4j/internal/SormImpl.java | 5 +++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 185ebca6..32993540 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,6 @@ ${project.version} - 1.4.15 UTF-8 diff --git a/sorm4j/src/main/java/org/nkjmlab/sorm4j/Orm.java b/sorm4j/src/main/java/org/nkjmlab/sorm4j/Orm.java index c1e9e56c..cf84c57e 100644 --- a/sorm4j/src/main/java/org/nkjmlab/sorm4j/Orm.java +++ b/sorm4j/src/main/java/org/nkjmlab/sorm4j/Orm.java @@ -145,6 +145,9 @@ public interface Orm { */ int[] deleteIn(String tableName, @SuppressWarnings("unchecked") T... objects); + @Experimental + boolean execute(ParameterizedSql sql); + /** * Executes the query with the given PreparedStatement and applies the given * {@link ResultSetTraverser}. If you want to set parameters to a PreparedStatement object by diff --git a/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/OrmConnectionImpl.java b/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/OrmConnectionImpl.java index aee9b284..5dbdab8b 100644 --- a/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/OrmConnectionImpl.java +++ b/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/OrmConnectionImpl.java @@ -204,6 +204,12 @@ private final R execSqlIfParameterExists(T[] objects, return sqlFunction.apply(mapping); } + @Override + public boolean execute(ParameterizedSql sql) { + return executeAndClose(getLoggerContext(), getJdbcConnection(), getPreparedStatementSupplier(), + getSqlParametersSetter(), sql.getSql(), sql.getParameters()); + } + @Override public T executeQuery(FunctionHandler statementSupplier, ResultSetTraverser traverser) { @@ -933,6 +939,18 @@ private static R executeQueryAndClose(Connection connection, } } + private static boolean executeAndClose(LoggerContext loggerContext, Connection connection, + PreparedStatementSupplier statementSupplier, SqlParametersSetter sqlParametersSetter, + String sql, Object[] parameters) { + try (PreparedStatement stmt = statementSupplier.prepareStatement(connection, sql)) { + sqlParametersSetter.setParameters(stmt, parameters); + boolean ret = stmt.execute(); + return ret; + } catch (SQLException e) { + throw Try.rethrow(e); + } + } + private static R executeQueryAndClose(LoggerContext loggerContext, Connection connection, PreparedStatementSupplier statementSupplier, SqlParametersSetter sqlParametersSetter, String sql, Object[] parameters, ResultSetTraverser resultSetTraverser) { diff --git a/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/SormImpl.java b/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/SormImpl.java index 4e7db9ab..a98f96ab 100644 --- a/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/SormImpl.java +++ b/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/SormImpl.java @@ -510,6 +510,11 @@ public TableSql getTableSql(String tableName) { return applyAndClose(conn -> conn.getTableSql(tableName)); } + @Override + public boolean execute(ParameterizedSql sql) { + return applyAndClose(conn -> conn.execute(sql)); + } + @Override public T executeQuery(FunctionHandler statementSupplier, ResultSetTraverser traverser) { From c1cd076e284acb981ec71d979b5922cf3dfe60a9 Mon Sep 17 00:00:00 2001 From: Yuu NAKAJIMA Date: Wed, 24 May 2023 15:58:20 +0900 Subject: [PATCH 2/5] Add SkipCsvRead.java --- .../sorm4j/util/h2/sql/H2CsvReadSql.java | 16 +++++++++------- .../sorm4j/util/h2/sql/SkipCsvRead.java | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 sorm4j/src/main/java/org/nkjmlab/sorm4j/util/h2/sql/SkipCsvRead.java diff --git a/sorm4j/src/main/java/org/nkjmlab/sorm4j/util/h2/sql/H2CsvReadSql.java b/sorm4j/src/main/java/org/nkjmlab/sorm4j/util/h2/sql/H2CsvReadSql.java index 3ddd040c..3384ba82 100644 --- a/sorm4j/src/main/java/org/nkjmlab/sorm4j/util/h2/sql/H2CsvReadSql.java +++ b/sorm4j/src/main/java/org/nkjmlab/sorm4j/util/h2/sql/H2CsvReadSql.java @@ -17,7 +17,6 @@ import org.nkjmlab.sorm4j.internal.util.ParameterizedStringFormatter; import org.nkjmlab.sorm4j.internal.util.StringCache; import org.nkjmlab.sorm4j.util.table_def.TableDefinition; -import org.nkjmlab.sorm4j.util.table_def.annotation.AutoIncrement; @Experimental public class H2CsvReadSql { @@ -87,7 +86,8 @@ public H2CsvReadSql build() { int index = selectedColumns.indexOf(en.getKey()); if (index == -1) { Object[] params = {en.getKey(), columns}; - throw new IllegalStateException(ParameterizedStringFormatter.LENGTH_256.format("{} is not found in Columns {}", params)); + throw new IllegalStateException(ParameterizedStringFormatter.LENGTH_256 + .format("{} is not found in Columns {}", params)); } selectedColumns.set(index, en.getValue()); }); @@ -164,7 +164,7 @@ public Builder setOrmRecordClass(Class ormRecordClass) { .filter(f -> !java.lang.reflect.Modifier.isStatic(f.getModifiers())) .toArray(Field[]::new); - List autoGeneratedColumn = new ArrayList<>(); + List csvSkipColumns = new ArrayList<>(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; @@ -180,14 +180,16 @@ public Builder setOrmRecordClass(Class ormRecordClass) { if (ann instanceof CsvColumn) { mapCsvColumnToTableColumn(((CsvColumn) ann).value(), StringCache.toUpperSnakeCase(field.getName())); - } else if (ann instanceof AutoIncrement) { - autoGeneratedColumn.add(field); + } else if (ann instanceof SkipCsvRead) { + csvSkipColumns.add(field); } } } - setTableColumns(Stream.of(fields).filter(f -> !autoGeneratedColumn.contains(f)) - .map(f -> StringCache.toUpperSnakeCase(f.getName())).toArray(String[]::new)); + setTableColumns(Stream.of(fields).map(f -> { + return csvSkipColumns.contains(f) ? "null as " + StringCache.toUpperSnakeCase(f.getName()) + : StringCache.toUpperSnakeCase(f.getName()); + }).toArray(String[]::new)); return this; } diff --git a/sorm4j/src/main/java/org/nkjmlab/sorm4j/util/h2/sql/SkipCsvRead.java b/sorm4j/src/main/java/org/nkjmlab/sorm4j/util/h2/sql/SkipCsvRead.java new file mode 100644 index 00000000..65218ac8 --- /dev/null +++ b/sorm4j/src/main/java/org/nkjmlab/sorm4j/util/h2/sql/SkipCsvRead.java @@ -0,0 +1,19 @@ +package org.nkjmlab.sorm4j.util.h2.sql; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + + +/** + * The csvread function of the H2 database skips columns based on their annotations. + * + * @author nkjm + * + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER, ElementType.FIELD}) +public @interface SkipCsvRead { + +} From 19b56382cc3c2ac9be3b946d3aaafb4b36375ba4 Mon Sep 17 00:00:00 2001 From: Yuu NAKAJIMA Date: Wed, 24 May 2023 15:58:44 +0900 Subject: [PATCH 3/5] Refactoring RowMap --- .../org/nkjmlab/sorm4j/result/BasicRowMap.java | 17 ++++++++--------- .../java/org/nkjmlab/sorm4j/result/RowMap.java | 10 ++++++++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/sorm4j/src/main/java/org/nkjmlab/sorm4j/result/BasicRowMap.java b/sorm4j/src/main/java/org/nkjmlab/sorm4j/result/BasicRowMap.java index 1f30330f..93a59a63 100644 --- a/sorm4j/src/main/java/org/nkjmlab/sorm4j/result/BasicRowMap.java +++ b/sorm4j/src/main/java/org/nkjmlab/sorm4j/result/BasicRowMap.java @@ -13,9 +13,8 @@ import java.util.function.BiFunction; import java.util.stream.Collectors; import org.nkjmlab.sorm4j.internal.util.ArrayUtils; -import org.nkjmlab.sorm4j.internal.util.StringCache; -public final class BasicRowMap implements RowMap { +public class BasicRowMap implements RowMap { private final LinkedHashMap map; @@ -28,12 +27,12 @@ public BasicRowMap(int initialCapacity, float loadFactor) { } public BasicRowMap(Map map) { - this.map = map.entrySet().stream().collect(Collectors.toMap(en -> toKey(en.getKey()), - en -> en.getValue(), (v1, v2) -> v1, LinkedHashMap::new)); + this.map = List.copyOf(map.entrySet()).stream().collect(LinkedHashMap::new, + (m, v) -> m.put(toKey(v.getKey()), v.getValue()), LinkedHashMap::putAll); } - private static String toKey(Object key) { - return StringCache.toCanonicalCase(key.toString()); + private static String toKey(String key) { + return RowMap.toKey(key); } @Override @@ -48,7 +47,7 @@ public boolean isEmpty() { @Override public boolean containsKey(Object key) { - return map.containsKey(toKey(key)); + return map.containsKey(toKey(key.toString())); } @Override @@ -58,7 +57,7 @@ public boolean containsValue(Object value) { @Override public Object get(Object key) { - return map.get(toKey(key)); + return map.get(toKey(key.toString())); } @Override @@ -68,7 +67,7 @@ public Object put(String key, Object value) { @Override public Object remove(Object key) { - return map.remove(toKey(key)); + return map.remove(toKey(key.toString())); } @Override diff --git a/sorm4j/src/main/java/org/nkjmlab/sorm4j/result/RowMap.java b/sorm4j/src/main/java/org/nkjmlab/sorm4j/result/RowMap.java index 2888befe..9b90ed7a 100644 --- a/sorm4j/src/main/java/org/nkjmlab/sorm4j/result/RowMap.java +++ b/sorm4j/src/main/java/org/nkjmlab/sorm4j/result/RowMap.java @@ -5,6 +5,7 @@ import java.time.LocalTime; import java.util.List; import java.util.Map; +import org.nkjmlab.sorm4j.internal.util.StringCache; /** * A instance represents a row in a table. This interface extends {@link Map}. The @@ -51,6 +52,15 @@ static RowMap of(String k1, Object v1, String k2, Object v2, String k3, Object v return create(Map.of(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5)); } + /** + * Key to canonical key + * + * @param key + * @return + */ + static String toKey(String key) { + return StringCache.toCanonicalCase(key); + } T[] getArray(String key, Class componentType); From aa2dd36205294633221e2e4431d8f14a5c5854a0 Mon Sep 17 00:00:00 2001 From: Yuu NAKAJIMA Date: Wed, 24 May 2023 16:09:24 +0900 Subject: [PATCH 4/5] Modify execute method. --- sorm4j/src/main/java/org/nkjmlab/sorm4j/Orm.java | 4 ++++ .../org/nkjmlab/sorm4j/internal/OrmConnectionImpl.java | 9 ++++++++- .../main/java/org/nkjmlab/sorm4j/internal/SormImpl.java | 5 +++++ .../src/main/java/org/nkjmlab/sorm4j/result/RowMap.java | 2 ++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/sorm4j/src/main/java/org/nkjmlab/sorm4j/Orm.java b/sorm4j/src/main/java/org/nkjmlab/sorm4j/Orm.java index cf84c57e..4ac70ae4 100644 --- a/sorm4j/src/main/java/org/nkjmlab/sorm4j/Orm.java +++ b/sorm4j/src/main/java/org/nkjmlab/sorm4j/Orm.java @@ -148,6 +148,10 @@ public interface Orm { @Experimental boolean execute(ParameterizedSql sql); + @Experimental + boolean execute(String sql, Object... parameters); + + /** * Executes the query with the given PreparedStatement and applies the given * {@link ResultSetTraverser}. If you want to set parameters to a PreparedStatement object by diff --git a/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/OrmConnectionImpl.java b/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/OrmConnectionImpl.java index 5dbdab8b..90b557f3 100644 --- a/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/OrmConnectionImpl.java +++ b/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/OrmConnectionImpl.java @@ -206,10 +206,17 @@ private final R execSqlIfParameterExists(T[] objects, @Override public boolean execute(ParameterizedSql sql) { + return execute(sql.getSql(), sql.getParameters()); + + } + + @Override + public boolean execute(String sql, Object... parameters) { return executeAndClose(getLoggerContext(), getJdbcConnection(), getPreparedStatementSupplier(), - getSqlParametersSetter(), sql.getSql(), sql.getParameters()); + getSqlParametersSetter(), sql, parameters); } + @Override public T executeQuery(FunctionHandler statementSupplier, ResultSetTraverser traverser) { diff --git a/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/SormImpl.java b/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/SormImpl.java index a98f96ab..0970b557 100644 --- a/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/SormImpl.java +++ b/sorm4j/src/main/java/org/nkjmlab/sorm4j/internal/SormImpl.java @@ -515,6 +515,11 @@ public boolean execute(ParameterizedSql sql) { return applyAndClose(conn -> conn.execute(sql)); } + @Override + public boolean execute(String sql, Object... parameters) { + return applyAndClose(conn -> conn.execute(sql, parameters)); + } + @Override public T executeQuery(FunctionHandler statementSupplier, ResultSetTraverser traverser) { diff --git a/sorm4j/src/main/java/org/nkjmlab/sorm4j/result/RowMap.java b/sorm4j/src/main/java/org/nkjmlab/sorm4j/result/RowMap.java index 9b90ed7a..32d34ab7 100644 --- a/sorm4j/src/main/java/org/nkjmlab/sorm4j/result/RowMap.java +++ b/sorm4j/src/main/java/org/nkjmlab/sorm4j/result/RowMap.java @@ -5,6 +5,7 @@ import java.time.LocalTime; import java.util.List; import java.util.Map; +import org.nkjmlab.sorm4j.annotation.Experimental; import org.nkjmlab.sorm4j.internal.util.StringCache; /** @@ -58,6 +59,7 @@ static RowMap of(String k1, Object v1, String k2, Object v2, String k3, Object v * @param key * @return */ + @Experimental static String toKey(String key) { return StringCache.toCanonicalCase(key); } From da7bf38f9137ce6c1a714feb692bc26d8c0b220e Mon Sep 17 00:00:00 2001 From: Yuu NAKAJIMA Date: Tue, 6 Jun 2023 10:49:48 +0900 Subject: [PATCH 5/5] update pom.xml --- pom.xml | 2 +- sorm4j-example/pom.xml | 8 ++++---- sorm4j-jmh/pom.xml | 2 +- sorm4j/pom.xml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 32993540..1aabb0e6 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ sorm4j-parent sorm4j-parent Simple micro Object-Relation Mapper for Java - 1.4.15 + 1.4.16 pom https://github.com/yuu-nkjm/sorm4j diff --git a/sorm4j-example/pom.xml b/sorm4j-example/pom.xml index 830c13c4..1dbb315c 100644 --- a/sorm4j-example/pom.xml +++ b/sorm4j-example/pom.xml @@ -2,11 +2,11 @@ 4.0.0 org.nkjmlab sorm4j-example - 1.4.13 + 1.4.16 Example of Sorm4j - 1.4.15 + 1.4.16 UTF-8 -Xdoclint:none true @@ -24,13 +24,13 @@ com.h2database h2 - 1.4.200 + 2.1.214 org.apache.logging.log4j log4j-core - 2.17.1 + 2.20.0 diff --git a/sorm4j-jmh/pom.xml b/sorm4j-jmh/pom.xml index 798ab1f4..b613e5ab 100644 --- a/sorm4j-jmh/pom.xml +++ b/sorm4j-jmh/pom.xml @@ -26,7 +26,7 @@ Sorm4j benchmark - 1.4.15 + 1.4.16 UTF-8 diff --git a/sorm4j/pom.xml b/sorm4j/pom.xml index 2ec246c8..d6e89a96 100644 --- a/sorm4j/pom.xml +++ b/sorm4j/pom.xml @@ -7,7 +7,7 @@ org.nkjmlab sorm4j-parent - 1.4.15 + 1.4.16 3.27.0-GA