Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit 55f58fb

Browse files
committed
rebased this branch on master, fixed problems, added tests
1 parent 9221172 commit 55f58fb

File tree

9 files changed

+115
-32
lines changed

9 files changed

+115
-32
lines changed

src/main/java/com/upsolver/datasources/jdbc/querybuilders/DefaultQueryDialect.java

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public class DefaultQueryDialect implements QueryDialect {
4040
protected static final ThrowingBiFunction<ResultSet, Integer, Object, SQLException> getTime = (rs, i) -> rs.getTime(i).getTime();
4141
protected static final ThrowingBiFunction<ResultSet, Integer, Object, SQLException> getTimestamp = (rs, i) -> rs.getTimestamp(i).getTime();
4242

43-
protected static final Map<Integer, ThrowingBiFunction<ResultSet, Integer, Object, SQLException>> dateTimeGetters = new HashMap<>();
43+
private static final Map<Integer, ThrowingBiFunction<ResultSet, Integer, Object, SQLException>> dateTimeGetters = new HashMap<>();
4444
static {
4545
dateTimeGetters.put(Types.DATE, getDate);
4646
dateTimeGetters.put(Types.TIME, getTime);
@@ -49,16 +49,16 @@ public class DefaultQueryDialect implements QueryDialect {
4949
dateTimeGetters.put(Types.TIMESTAMP_WITH_TIMEZONE, getTimestamp);
5050
}
5151

52-
private final Map<Integer, ThrowingBiFunction<ResultSet, Integer, Object, SQLException>> valueGetters;
53-
private final ThrowingBiFunction<ResultSet, Integer, Object, SQLException> defaultValueGetter;
52+
private Map<Integer, ThrowingBiFunction<ResultSet, Integer, Object, SQLException>> valueGetters;
53+
private ThrowingBiFunction<ResultSet, Integer, Object, SQLException> defaultValueGetter;
5454

55-
public DefaultQueryDialect(boolean keepType) {
56-
this(keepType ? dateTimeGetters : Collections.emptyMap(), keepType ? getObject : getString);
55+
56+
public DefaultQueryDialect() {
57+
this(false);
5758
}
5859

59-
protected DefaultQueryDialect(Map<Integer, ThrowingBiFunction<ResultSet, Integer, Object, SQLException>> valueGetters, ThrowingBiFunction<ResultSet, Integer, Object, SQLException> defaultValueGetter) {
60-
this.valueGetters = valueGetters;
61-
this.defaultValueGetter = defaultValueGetter;
60+
public DefaultQueryDialect(boolean keepType) {
61+
keepTypes(keepType);
6262
}
6363

6464
@Override
@@ -287,4 +287,21 @@ public ThrowingBiFunction<ResultSet, Integer, Object, SQLException> getValueGett
287287
public boolean acceptsURL(String url) {
288288
return url.startsWith("jdbc:");
289289
}
290+
291+
@Override
292+
public QueryDialect keepTypes(boolean keepTypes) {
293+
if (keepTypes) {
294+
keepTypes(dateTimeGetters, getObject);
295+
} else {
296+
keepTypes(Collections.emptyMap(), getString);
297+
}
298+
return this;
299+
}
300+
301+
protected final void keepTypes(
302+
Map<Integer, ThrowingBiFunction<ResultSet, Integer, Object, SQLException>> valueGetters,
303+
ThrowingBiFunction<ResultSet, Integer, Object, SQLException> defaultValueGetter) {
304+
this.valueGetters = valueGetters;
305+
this.defaultValueGetter = defaultValueGetter;
306+
}
290307
}

src/main/java/com/upsolver/datasources/jdbc/querybuilders/OracleQueryDialect.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class OracleQueryDialect extends DefaultQueryDialect {
2525
OracleType.TIMESTAMP_WITH_LOCAL_TIME_ZONE
2626
));
2727

28-
private static final ThrowingBiFunction<ResultSet, Integer, Object, SQLException> blobAsString = (rs, i) -> Optional.ofNullable(rs.getBytes(i)).map(bytes -> new BigInteger(1, bytes).toString(16)).orElse(null);
28+
protected static final ThrowingBiFunction<ResultSet, Integer, Object, SQLException> blobAsString = (rs, i) -> Optional.ofNullable(rs.getBytes(i)).map(bytes -> new BigInteger(1, bytes).toString(16)).orElse(null);
2929
private static final Map<Integer, ThrowingBiFunction<ResultSet, Integer, Object, SQLException>> getters = new HashMap<>();
3030
static {
3131
getters.put(Types.DATE, getDate);
@@ -39,8 +39,8 @@ public class OracleQueryDialect extends DefaultQueryDialect {
3939
getters.put(Types.BLOB, blobAsString);
4040
}
4141

42-
public OracleQueryDialect(boolean keepType) {
43-
super(keepType ? getters : Collections.emptyMap(), keepType ? getObject : getString);
42+
public OracleQueryDialect() {
43+
super(false);
4444
}
4545

4646
@Override
@@ -113,4 +113,14 @@ public SQLType getJdbcType(SQLType sqlType) {
113113
public boolean acceptsURL(String url) {
114114
return url.startsWith("jdbc:oracle:");
115115
}
116+
117+
@Override
118+
public QueryDialect keepTypes(boolean keepTypes) {
119+
if (keepTypes) {
120+
keepTypes(getters, getObject);
121+
} else {
122+
keepTypes(Collections.emptyMap(), getString);
123+
}
124+
return this;
125+
}
116126
}

src/main/java/com/upsolver/datasources/jdbc/querybuilders/PostgreSqlQueryDialect.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import java.util.TimeZone;
77

88
public class PostgreSqlQueryDialect extends DefaultQueryDialect {
9-
public PostgreSqlQueryDialect(boolean keepType) {
10-
super(keepType);
9+
public PostgreSqlQueryDialect() {
10+
super(false);
1111
}
1212

1313
public long utcOffsetSeconds(Connection connection) throws SQLException {

src/main/java/com/upsolver/datasources/jdbc/querybuilders/QueryDialect.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ NamedPreparedStatment queryFullTable(TableInfo tableInfo,
7272

7373
ThrowingBiFunction<ResultSet, Integer, Object, SQLException> getValueGetter(int sqlType);
7474

75-
ThrowingBiFunction<ResultSet, Integer, String, SQLException> getStringValueGetter(int sqlType);
76-
7775
boolean acceptsURL(String url);
76+
77+
QueryDialect keepTypes(boolean keepType);
7878
}

src/main/java/com/upsolver/datasources/jdbc/querybuilders/QueryDialectProvider.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
import java.util.stream.StreamSupport;
55

66
public class QueryDialectProvider {
7-
public static QueryDialect forConnection(String connectionString) {
7+
public static QueryDialect forConnection(String connectionString, boolean keepTypes) {
88
String connStr = connectionString.toLowerCase();
99
Iterable<QueryDialect> iterable = () -> ServiceLoader.load(QueryDialect.class).iterator();
1010
return StreamSupport.stream(iterable.spliterator(), false)
1111
.filter(d -> d.acceptsURL(connStr))
1212
.findFirst()
13-
.orElseGet(DefaultQueryDialect::new);
13+
.orElseGet(DefaultQueryDialect::new)
14+
.keepTypes(keepTypes);
1415
}
1516
}

src/main/java/com/upsolver/datasources/jdbc/querybuilders/RedshiftQueryDialect.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import java.util.TimeZone;
77

88
public class RedshiftQueryDialect extends DefaultQueryDialect {
9-
public RedshiftQueryDialect(boolean keepType) {
10-
super(keepType);
9+
public RedshiftQueryDialect() {
10+
super(false);
1111
}
1212

1313
public long utcOffsetSeconds(Connection connection) throws SQLException {

src/main/java/com/upsolver/datasources/jdbc/querybuilders/SnowflakeQueryDialect.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
import java.util.TimeZone;
66

77
public class SnowflakeQueryDialect extends DefaultQueryDialect {
8-
public SnowflakeQueryDialect(boolean keepType) {
9-
super(keepType);
8+
public SnowflakeQueryDialect() {
9+
super(false);
1010
}
1111

1212
public long utcOffsetSeconds(Connection connection) throws SQLException {

src/main/java/com/upsolver/datasources/jdbc/querybuilders/SqlServerQueryDialect.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ public class SqlServerQueryDialect extends DefaultQueryDialect {
2222
private static final Collection<SQLType> sqlServerTimeTypes = sqlServerTypes.values().stream()
2323
.filter(f -> sqlServerTimeTypeCodes.contains(f.getVendorTypeNumber())).collect(Collectors.toSet());
2424

25-
public SqlServerQueryDialect(boolean keepType) {
26-
super(keepType);
25+
public SqlServerQueryDialect() {
26+
super(false);
2727
}
2828

2929
@Override
Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,97 @@
11
package com.upsolver.datasources.jdbc.querybuilders;
22

3+
import oracle.jdbc.OracleType;
34
import org.junit.Test;
5+
import org.junit.runner.RunWith;
6+
import org.junit.runners.Parameterized;
47

8+
import java.sql.JDBCType;
9+
import java.sql.Types;
10+
import java.util.Arrays;
11+
import java.util.Collection;
12+
import java.util.HashSet;
13+
import java.util.Set;
14+
import java.util.stream.Stream;
15+
16+
import static com.upsolver.datasources.jdbc.querybuilders.DefaultQueryDialect.getDate;
17+
import static com.upsolver.datasources.jdbc.querybuilders.DefaultQueryDialect.getObject;
18+
import static com.upsolver.datasources.jdbc.querybuilders.DefaultQueryDialect.getString;
19+
import static com.upsolver.datasources.jdbc.querybuilders.DefaultQueryDialect.getTime;
20+
import static com.upsolver.datasources.jdbc.querybuilders.DefaultQueryDialect.getTimestamp;
21+
import static com.upsolver.datasources.jdbc.querybuilders.OracleQueryDialect.blobAsString;
22+
import static java.util.Collections.singleton;
23+
import static java.util.stream.Collectors.toList;
524
import static org.junit.Assert.assertEquals;
625

26+
@RunWith(Parameterized.class)
727
public class QueryDialectProviderTest {
28+
private static final Set<Integer> dateTimeTypes = new HashSet<>(Arrays.asList(Types.DATE, Types.TIMESTAMP, Types.TIMESTAMP_WITH_TIMEZONE, Types.TIME, Types.TIME_WITH_TIMEZONE));
29+
private final boolean keepTypes;
30+
31+
public QueryDialectProviderTest(boolean keepTypes) {
32+
this.keepTypes = keepTypes;
33+
}
34+
35+
@Parameterized.Parameters(name = "keepTypes={0}" )
36+
public static Collection<Boolean> parameters() {
37+
return Arrays.asList(true, false);
38+
}
39+
840
@Test
941
public void testDefault() {
10-
test("jdbc:unknown", DefaultQueryDialect.class);
42+
test("jdbc:unknown", DefaultQueryDialect.class, dateTimeTypes);
1143
}
1244

13-
1445
@Test
1546
public void sqlServer() {
16-
test("jdbc:sqlserver://database-1.foo.us-east-1.rds.amazonaws.com:1433", SqlServerQueryDialect.class);
47+
test("jdbc:sqlserver://database-1.foo.us-east-1.rds.amazonaws.com:1433", SqlServerQueryDialect.class, dateTimeTypes);
1748
}
1849

1950
@Test
2051
public void oracle() {
21-
test("jdbc:oracle:thin:@//temp-oracle.foo.us-east-1.rds.amazonaws.com:1521/test", OracleQueryDialect.class);
52+
Collection<Integer> specialTypes = Stream.of(dateTimeTypes, singleton(Types.BLOB)).flatMap(Collection::stream).collect(toList());
53+
QueryDialect dialect = test("jdbc:oracle:thin:@//temp-oracle.foo.us-east-1.rds.amazonaws.com:1521/test", OracleQueryDialect.class, specialTypes);
54+
if (keepTypes) {
55+
assertEquals(getTimestamp, dialect.getValueGetter(OracleType.TIMESTAMP_WITH_TIME_ZONE.getVendorTypeNumber()));
56+
assertEquals(getTimestamp, dialect.getValueGetter(OracleType.TIMESTAMP_WITH_LOCAL_TIME_ZONE.getVendorTypeNumber()));
57+
assertEquals(blobAsString, dialect.getValueGetter(Types.BLOB));
58+
}
2259
}
2360

2461
@Test
2562
public void redshift() {
26-
test("jdbc:redshift://redshift-cluster-1.foo.us-east-1.redshift.amazonaws.com:5439/dev", RedshiftQueryDialect.class);
63+
test("jdbc:redshift://redshift-cluster-1.foo.us-east-1.redshift.amazonaws.com:5439/dev", RedshiftQueryDialect.class, dateTimeTypes);
2764
}
2865

2966
@Test
3067
public void postgres() {
31-
test("jdbc:postgresql://1.1.1.1:5432/test_db", PostgreSqlQueryDialect.class);
68+
test("jdbc:postgresql://1.1.1.1:5432/test_db", PostgreSqlQueryDialect.class, dateTimeTypes);
3269
}
3370

3471
@Test
3572
public void snowflake() {
36-
test("jdbc:snowflake://oka43275.us-east-1.snowflakecomputing.com?db=demo_db&warehouse=test1", SnowflakeQueryDialect.class);
73+
test("jdbc:snowflake://oka43275.us-east-1.snowflakecomputing.com?db=demo_db&warehouse=test1", SnowflakeQueryDialect.class, dateTimeTypes);
74+
}
75+
76+
private QueryDialect test(String url, Class<? extends QueryDialect> expectedDialectClass, Collection<Integer> specialTypes) {
77+
QueryDialect dialect = QueryDialectProvider.forConnection(url, keepTypes);
78+
assertEquals(expectedDialectClass, dialect.getClass());
79+
assertGetters(dialect, specialTypes);
80+
return dialect;
3781
}
3882

39-
private void test(String url, Class<? extends QueryDialect> expectedDialectClass) {
40-
assertEquals(expectedDialectClass, QueryDialectProvider.forConnection(url).getClass());
83+
private void assertGetters(QueryDialect dialect, Collection<Integer> specialTypes) {
84+
if (keepTypes) {
85+
assertEquals(getDate, dialect.getValueGetter(Types.DATE));
86+
assertEquals(getTimestamp, dialect.getValueGetter(Types.TIMESTAMP));
87+
assertEquals(getTimestamp, dialect.getValueGetter(Types.TIMESTAMP_WITH_TIMEZONE));
88+
assertEquals(getTime, dialect.getValueGetter(Types.TIME));
89+
assertEquals(getTime, dialect.getValueGetter(Types.TIME_WITH_TIMEZONE));
90+
Arrays.stream(JDBCType.values())
91+
.filter(t -> !specialTypes.contains(t.getVendorTypeNumber()))
92+
.forEach(t -> assertEquals(t.getName(), getObject, dialect.getValueGetter(t.getVendorTypeNumber())));
93+
} else {
94+
Arrays.stream(JDBCType.values()).forEach(t -> assertEquals(getString, dialect.getValueGetter(t.getVendorTypeNumber())));
95+
}
4196
}
4297
}

0 commit comments

Comments
 (0)