Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ jobs:
- run:
name: 'Test'
command: |
./mvnw -ntp -B install -Pci -Dgroups=com.querydsl.core.testutil.EmbeddedDatabase
./mvnw -ntp -B install -Pci -Dgroups=com.querydsl.core.testutil.EmbeddedDatabase,com.querydsl.core.testutil.Turso
- save-test-results
testDB2:
# Use the machine executor so we have full VM capabilities (e.g. docker running as admin)
Expand Down
2 changes: 2 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
<mssql.version>13.4.0.jre11</mssql.version>
<cubrid.version>9.3.9.0002</cubrid.version>
<sqlite.version>3.53.2.0</sqlite.version>
<turso.version>0.6.0</turso.version>
<teradata.version>13.10.00.35</teradata.version>
<firebird.version>6.0.5</firebird.version>
<mongodb.version>5.8.0</mongodb.version>
Expand Down Expand Up @@ -998,6 +999,7 @@
com.querydsl.core.testutil.Oracle,
com.querydsl.core.testutil.PostgreSQL,
com.querydsl.core.testutil.SQLite,
com.querydsl.core.testutil.Turso,
com.querydsl.core.testutil.SQLServer,
com.querydsl.core.testutil.SlowTest,
com.querydsl.core.testutil.Performance,
Expand Down
1 change: 1 addition & 0 deletions querydsl-libraries/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
<exclude>cubrid:cubrid-jdbc:*:*:compile</exclude>
<exclude>org.firebirdsql.jdbc:jaybird:*:*:compile</exclude>
<exclude>org.xerial:sqlite-jdbc:*:*:compile</exclude>
<exclude>tech.turso:turso:*:*:compile</exclude>
<!-- hibernate-entitymanager is a legacy artefact and should not be used anymore -->
<exclude>org.hibernate:hibernate-entitymanager</exclude>
<!-- We favor JUL over Slf4j -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ public Collection<Predicate> string(
&& !target.equals(Target.HSQLDB)
&& !target.equals(Target.H2)
&& !target.equals(Target.SQLITE)
&& !target.equals(Target.TURSO)
&& !target.equals(Target.SQLSERVER)) {
rv.add(expr.matches(knownValue.substring(0, 1) + ".*"));
rv.add(expr.matches(".*" + knownValue.substring(1)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ public Collection<Predicate> string(StringExpression expr, StringExpression othe
&& !target.equals(Target.DB2)
&& !target.equals(Target.DERBY)
&& !target.equals(Target.SQLITE)
&& !target.equals(Target.TURSO)
&& !target.equals(Target.SQLSERVER))) {

rv.add(expr.matches(other));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public enum Target {
SQLSERVER,
/** SQLite */
SQLITE,
/** Turso (SQLite-compatible) */
TURSO,
/** */
TERADATA,
/** */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* Licensed 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 com.querydsl.core.testutil;

public interface Turso extends EmbeddedDatabase {}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.querydsl.sql.SQLTemplates;
import com.querydsl.sql.SQLiteTemplates;
import com.querydsl.sql.TeradataTemplates;
import com.querydsl.sql.TursoTemplates;

/**
* @author tiwe
Expand All @@ -33,6 +34,7 @@ public static SQLTemplates getSQLTemplates() {
case ORACLE -> new OracleTemplates();
case POSTGRESQL -> new PostgreSQLTemplates();
case SQLITE -> new SQLiteTemplates();
case TURSO -> new TursoTemplates();
case TERADATA -> new TeradataTemplates();
default -> throw new IllegalStateException("Unknown mode " + mode);
};
Expand Down
7 changes: 7 additions & 0 deletions querydsl-libraries/querydsl-sql/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@
<scope>test</scope>
</dependency>

<dependency>
<groupId>tech.turso</groupId>
<artifactId>turso</artifactId>
<version>${turso.version}</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>io.github.openfeign.querydsl</groupId>
<artifactId>querydsl-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ private static Set<String> readLines(String path) {
public static final Set<String> ORACLE = readLines("oracle");
public static final Set<String> POSTGRESQL = readLines("postgresql");
public static final Set<String> SQLITE = readLines("sqlite");
public static final Set<String> TURSO = readLines("turso");
public static final Set<String> SQLSERVER2005 = readLines("sqlserver2005");
public static final Set<String> SQLSERVER2008 = readLines("sqlserver2008");
public static final Set<String> SQLSERVER2012 = readLines("sqlserver2012");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ public SQLTemplates.Builder getBuilder(DatabaseMetaData md) throws SQLException
return PostgreSQLTemplates.builder();
} else if (name.equals("sqlite")) {
return SQLiteTemplates.builder();
} else if (name.equals("turso")) {
return TursoTemplates.builder();
} else if (name.startsWith("teradata")) {
return TeradataTemplates.builder();
} else if (name.equals("microsoft sql server")) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* Licensed 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 com.querydsl.sql;

import com.querydsl.core.types.Ops;
import com.querydsl.sql.types.BigDecimalAsDoubleType;
import com.querydsl.sql.types.BigIntegerAsLongType;
import java.sql.Types;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoField;

/**
* {@code TursoTemplates} is a SQL dialect for Turso (https://github.com/tursodatabase/turso), a
* SQLite-compatible database
*
* @author tiwe
*/
public class TursoTemplates extends SQLTemplates {

private static final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

private static final DateTimeFormatter dateTimeFormatter =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

private static final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");

@SuppressWarnings("FieldNameHidesFieldInSuperclass") // Intentional
public static final TursoTemplates DEFAULT = new TursoTemplates();

public static Builder builder() {
return new Builder() {
@Override
protected SQLTemplates build(char escape, boolean quote) {
return new TursoTemplates(escape, quote);
}
};
}

public TursoTemplates() {
this('\\', false);
}

public TursoTemplates(boolean quote) {
this('\\', quote);
}

public TursoTemplates(char escape, boolean quote) {
super(Keywords.TURSO, "\"", escape, quote, false);
setDummyTable(null);
addCustomType(BigDecimalAsDoubleType.DEFAULT);
addCustomType(BigIntegerAsLongType.DEFAULT);
setUnionsWrapped(false);
setLimitRequired(true);
setNullsFirst(null);
setNullsLast(null);
setDefaultValues("\ndefault values");
setArraysSupported(false);
setBatchToBulkSupported(false);

setPrecedence(Precedence.COMPARISON - 1, Ops.LT, Ops.GT, Ops.LOE, Ops.GOE);
setPrecedence(Precedence.COMPARISON, Ops.EQ, Ops.EQ_IGNORE_CASE, Ops.NE);

add(Ops.MOD, "{0} % {1}", Precedence.ARITH_HIGH);

add(Ops.INDEX_OF, "charindex({1},{0},1)-1", Precedence.ARITH_LOW);
add(Ops.INDEX_OF_2ARGS, "charindex({1},{0},{2s}+1)-1", Precedence.ARITH_LOW);

add(Ops.StringOps.LOCATE, "charindex({0},{1})");
add(Ops.StringOps.LOCATE2, "charindex({0},{1},{2s})");

// TODO : optimize
add(
Ops.DateTimeOps.YEAR,
"cast(strftime('%Y',{0} / 1000, 'unixepoch', 'localtime') as integer)");
add(
Ops.DateTimeOps.MONTH,
"cast(strftime('%m',{0} / 1000, 'unixepoch', 'localtime') as integer)");
add(
Ops.DateTimeOps.WEEK,
"cast(strftime('%W',{0} / 1000, 'unixepoch', 'localtime') as integer) + 1");
add(
Ops.DateTimeOps.DAY_OF_MONTH,
"cast(strftime('%d',{0} / 1000, 'unixepoch', 'localtime') as integer)");
add(
Ops.DateTimeOps.DAY_OF_WEEK,
"cast(strftime('%w',{0} / 1000, 'unixepoch', 'localtime') as integer) + 1");
add(
Ops.DateTimeOps.DAY_OF_YEAR,
"cast(strftime('%j',{0} / 1000, 'unixepoch', 'localtime') as integer)");
add(
Ops.DateTimeOps.HOUR,
"cast(strftime('%H',{0} / 1000, 'unixepoch', 'localtime') as integer)");
add(
Ops.DateTimeOps.MINUTE,
"cast(strftime('%M',{0} / 1000, 'unixepoch', 'localtime') as integer)");
add(
Ops.DateTimeOps.SECOND,
"cast(strftime('%S',{0} / 1000, 'unixepoch', 'localtime') as integer)");

add(
Ops.DateTimeOps.YEAR_MONTH,
"""
cast(strftime('%Y',{0} / 1000, 'unixepoch', 'localtime') * 100 + strftime('%m',{0} / 1000,\
'unixepoch', 'localtime') as integer)\
""");
add(
Ops.DateTimeOps.YEAR_WEEK,
"cast(strftime('%Y%W',{0} / 1000, 'unixepoch', 'localtime') as integer)");

add(Ops.DateTimeOps.ADD_YEARS, "date({0}, '+{1s} year')");
add(Ops.DateTimeOps.ADD_MONTHS, "date({0}, '+{1s} month')");
add(Ops.DateTimeOps.ADD_WEEKS, "date({0}, '+{1s} week')");
add(Ops.DateTimeOps.ADD_DAYS, "date({0}, '+{1s} day')");
add(Ops.DateTimeOps.ADD_HOURS, "date({0}, '+{1s} hour')");
add(Ops.DateTimeOps.ADD_MINUTES, "date({0}, '+{1s} minute')");
add(Ops.DateTimeOps.ADD_SECONDS, "date({0}, '+{1s} second')");

add(Ops.MathOps.RANDOM, "random()");
add(Ops.MathOps.RANDOM2, "random({0})");
add(Ops.MathOps.LN, "log({0})");
add(Ops.MathOps.LOG, "log({0}) / log({1})", Precedence.ARITH_HIGH);

add(SQLOps.GROUP_CONCAT2, "group_concat({0},{1})");

addTypeNameToCode("text", Types.VARCHAR);
}

@Override
public String serialize(String literal, int jdbcType) {
// XXX doesn't work with LocalDate, LocalDateTime and LocalTime
return switch (jdbcType) {
case Types.TIMESTAMP, TIMESTAMP_WITH_TIMEZONE ->
String.valueOf(
dateTimeFormatter
.parse(literal, LocalDateTime::from)
.toInstant(ZoneOffset.UTC)
.toEpochMilli());
case Types.DATE ->
String.valueOf(
dateFormatter
.parse(literal, LocalDate::from)
.atStartOfDay(ZoneOffset.UTC)
.toInstant()
.toEpochMilli());
case Types.TIME, TIME_WITH_TIMEZONE ->
String.valueOf(
timeFormatter.parse(literal, LocalTime::from).get(ChronoField.MILLI_OF_DAY));
default -> super.serialize(literal, jdbcType);
};
}
}
Loading
Loading