From caeab8c26dc53d6a5cae742a38c4dbd29c052490 Mon Sep 17 00:00:00 2001 From: Rudolf Schmidt Date: Sun, 14 Apr 2024 06:00:06 +0200 Subject: [PATCH 1/2] add sqlite support --- .../repository/config/DialectResolver.java | 9 +- .../data/r2dbc/dialect/DialectResolver.java | 1 + .../core/dialect/SQLiteDialect.java | 96 +++++++++++++++++++ 3 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SQLiteDialect.java diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java index c55240754b1..2960d376492 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java @@ -32,11 +32,7 @@ import org.springframework.data.jdbc.core.dialect.JdbcMySqlDialect; import org.springframework.data.jdbc.core.dialect.JdbcPostgresDialect; import org.springframework.data.jdbc.core.dialect.JdbcSqlServerDialect; -import org.springframework.data.relational.core.dialect.Dialect; -import org.springframework.data.relational.core.dialect.H2Dialect; -import org.springframework.data.relational.core.dialect.HsqlDbDialect; -import org.springframework.data.relational.core.dialect.MariaDbDialect; -import org.springframework.data.relational.core.dialect.OracleDialect; +import org.springframework.data.relational.core.dialect.*; import org.springframework.data.relational.core.sql.IdentifierProcessing; import org.springframework.data.util.Optionals; import org.springframework.jdbc.core.ConnectionCallback; @@ -121,6 +117,9 @@ private static Dialect getDialect(Connection connection) throws SQLException { if (name.contains("h2")) { return H2Dialect.INSTANCE; } + if (name.contains("sqlite")) { + return SQLiteDialect.INSTANCE; + } if (name.contains("mysql")) { return new JdbcMySqlDialect(getIdentifierProcessing(metaData)); } diff --git a/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/DialectResolver.java b/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/DialectResolver.java index 6bd25283fba..77d804e70c7 100644 --- a/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/DialectResolver.java +++ b/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/DialectResolver.java @@ -33,6 +33,7 @@ * resolution uses Spring's {@link SpringFactoriesLoader spring.factories} to determine available extensions. * * @author Mark Paluch + * @author Rudolf Schmidt * @see R2dbcDialect * @see SpringFactoriesLoader */ diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SQLiteDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SQLiteDialect.java new file mode 100644 index 00000000000..06bca2194f0 --- /dev/null +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SQLiteDialect.java @@ -0,0 +1,96 @@ +package org.springframework.data.relational.core.dialect; + +import org.springframework.core.convert.converter.Converter; +import org.springframework.data.convert.ReadingConverter; +import org.springframework.data.convert.WritingConverter; +import org.springframework.data.relational.core.sql.LockOptions; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.Collection; + +/** + * SQL Dialect for SQLite. + * + * @author Rudolf Schmidt + * @since 3.3.0 + */ +public class SQLiteDialect extends AbstractDialect { + + public static final SQLiteDialect INSTANCE = new SQLiteDialect(); + + private SQLiteDialect() { + } + + @Override + public LimitClause limit() { + return new LimitClause() { + @Override + public String getLimit(final long limit) { + return String.format("limit %d", limit); + } + + @Override + public String getOffset(final long offset) { + throw new UnsupportedOperationException("offset alone not supported"); + } + + @Override + public String getLimitOffset(final long limit, final long offset) { + return String.format("limit %d offset %d", limit, offset); + } + + @Override + public Position getClausePosition() { + return Position.AFTER_ORDER_BY; + } + }; + } + + @Override + public LockClause lock() { + return new LockClause() { + @Override + public String getLock(final LockOptions lockOptions) { + return "with lock"; + } + + @Override + public Position getClausePosition() { + return Position.AFTER_ORDER_BY; + } + }; + } + + @Override + public Collection getConverters() { + final var converters = new ArrayList<>(super.getConverters()); + converters.add(LocalDateTimeToNumericConverter.INSTANCE); + converters.add(NumericToLocalDateTimeConverter.INSTANCE); + return converters; + } + + @WritingConverter + private enum LocalDateTimeToNumericConverter implements Converter { + + INSTANCE; + + @Override + public Long convert(final LocalDateTime source) { + return source.atZone(ZoneOffset.UTC).toInstant().toEpochMilli(); + } + } + + @ReadingConverter + private enum NumericToLocalDateTimeConverter implements Converter { + + INSTANCE; + + @Override + public LocalDateTime convert(final Long source) { + return Instant.ofEpochMilli(source).atZone(ZoneOffset.UTC).toLocalDateTime(); + } + } +} From 5bd13e969d07c90ec71bef0c7158f88000586f60 Mon Sep 17 00:00:00 2001 From: Rudolf Schmidt Date: Mon, 15 Apr 2024 16:59:11 +0200 Subject: [PATCH 2/2] added pom dependency for sqlite support, refactored dialect file --- pom.xml | 1 + spring-data-jdbc/pom.xml | 7 ++ .../repository/config/DialectResolver.java | 1 + .../data/r2dbc/dialect/DialectResolver.java | 1 - .../core/dialect/SQLiteDialect.java | 74 ++++++++++--------- 5 files changed, 48 insertions(+), 36 deletions(-) diff --git a/pom.xml b/pom.xml index 02461b8e405..e8d72f5df1e 100644 --- a/pom.xml +++ b/pom.xml @@ -44,6 +44,7 @@ https://stackoverflow.com/q/62263576/66686 --> 23.3.0.23.09 + 3.45.2.0 4.2.0 diff --git a/spring-data-jdbc/pom.xml b/spring-data-jdbc/pom.xml index fddbaab6963..22f29645b84 100644 --- a/spring-data-jdbc/pom.xml +++ b/spring-data-jdbc/pom.xml @@ -153,6 +153,13 @@ test + + org.xerial + sqlite-jdbc + ${sqlite.version} + test + + diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java index 2960d376492..69bcd5bdf2a 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/config/DialectResolver.java @@ -46,6 +46,7 @@ * available {@link JdbcDialectProvider extensions}. * * @author Jens Schauder + * @author Rudolf Schmidt * @since 2.0 * @see Dialect * @see SpringFactoriesLoader diff --git a/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/DialectResolver.java b/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/DialectResolver.java index 77d804e70c7..6bd25283fba 100644 --- a/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/DialectResolver.java +++ b/spring-data-r2dbc/src/main/java/org/springframework/data/r2dbc/dialect/DialectResolver.java @@ -33,7 +33,6 @@ * resolution uses Spring's {@link SpringFactoriesLoader spring.factories} to determine available extensions. * * @author Mark Paluch - * @author Rudolf Schmidt * @see R2dbcDialect * @see SpringFactoriesLoader */ diff --git a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SQLiteDialect.java b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SQLiteDialect.java index 06bca2194f0..e734f79bdd6 100644 --- a/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SQLiteDialect.java +++ b/spring-data-relational/src/main/java/org/springframework/data/relational/core/dialect/SQLiteDialect.java @@ -21,52 +21,56 @@ public class SQLiteDialect extends AbstractDialect { public static final SQLiteDialect INSTANCE = new SQLiteDialect(); + private static final LimitClause LIMIT_CLAUSE = new LimitClause() { + @Override + public String getLimit(long limit) { + return String.format("limit %d", limit); + } + + @Override + public String getOffset(long offset) { + throw new UnsupportedOperationException("offset alone not supported"); + } + + @Override + public String getLimitOffset(long limit, long offset) { + return String.format("limit %d offset %d", limit, offset); + } + + @Override + public Position getClausePosition() { + return Position.AFTER_ORDER_BY; + } + }; + + private static final LockClause LOCK_CLAUSE = new LockClause() { + @Override + public String getLock(LockOptions lockOptions) { + return ""; + } + + @Override + public Position getClausePosition() { + return Position.AFTER_ORDER_BY; + } + }; + private SQLiteDialect() { } @Override public LimitClause limit() { - return new LimitClause() { - @Override - public String getLimit(final long limit) { - return String.format("limit %d", limit); - } - - @Override - public String getOffset(final long offset) { - throw new UnsupportedOperationException("offset alone not supported"); - } - - @Override - public String getLimitOffset(final long limit, final long offset) { - return String.format("limit %d offset %d", limit, offset); - } - - @Override - public Position getClausePosition() { - return Position.AFTER_ORDER_BY; - } - }; + return LIMIT_CLAUSE; } @Override public LockClause lock() { - return new LockClause() { - @Override - public String getLock(final LockOptions lockOptions) { - return "with lock"; - } - - @Override - public Position getClausePosition() { - return Position.AFTER_ORDER_BY; - } - }; + return LOCK_CLAUSE; } @Override public Collection getConverters() { - final var converters = new ArrayList<>(super.getConverters()); + Collection converters = new ArrayList<>(super.getConverters()); converters.add(LocalDateTimeToNumericConverter.INSTANCE); converters.add(NumericToLocalDateTimeConverter.INSTANCE); return converters; @@ -78,7 +82,7 @@ private enum LocalDateTimeToNumericConverter implements Converter