This repository was archived by the owner on Feb 13, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOracleQueryDialect.java
More file actions
94 lines (80 loc) · 3.4 KB
/
OracleQueryDialect.java
File metadata and controls
94 lines (80 loc) · 3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package com.upsolver.datasources.jdbc.querybuilders;
import com.upsolver.datasources.jdbc.utils.ThrowingBiFunction;
import oracle.jdbc.OracleType;
import java.math.BigInteger;
import java.sql.Connection;
import java.sql.JDBCType;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLType;
import java.sql.Types;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
public class OracleQueryDialect extends DefaultQueryDialect {
private static final Collection<SQLType> oracleTimeTypes = new HashSet<>(Arrays.asList(
OracleType.TIMESTAMP,
OracleType.TIMESTAMP_WITH_TIME_ZONE,
OracleType.TIMESTAMP_WITH_LOCAL_TIME_ZONE
));
private static final ThrowingBiFunction<ResultSet, Integer, String, SQLException> blobAsString = (rs, i) -> Optional.ofNullable(rs.getBytes(i)).map(bytes -> new BigInteger(1, bytes).toString(16)).orElse(null);
private static final Map<Integer, ThrowingBiFunction<ResultSet, Integer, String, SQLException>> blobValueGetters = Collections.singletonMap(Types.BLOB, blobAsString);
public OracleQueryDialect() {
super(blobValueGetters, IdentifierNormalizer.TO_UPPER_CASE);
}
@Override
public long utcOffsetSeconds(Connection connection) throws SQLException {
var rs =
connection.prepareStatement("SELECT extract(day from (SYSTIMESTAMP - sys_extract_utc(systimestamp)) * 24 * 60 * 60) FROM DUAL")
.executeQuery();
rs.next();
return rs.getLong(1);
}
@Override
protected String rownumCondition(long amount, boolean includeAnd, boolean includeWhere) {
if (amount >= 0) {
var where = includeWhere ? " WHERE " : "";
var and = !includeWhere && includeAnd ? " AND " : "";
return where + and + " ROWNUM <= " + amount + " ";
} else {
return "";
}
}
@Override
protected String endLimit(long amount) {
return "";
}
@Override
public boolean isAutoIncrementColumn(ResultSet columnsResultSet) throws SQLException {
var def = columnsResultSet.getString("COLUMN_DEF");
// Example default value: "ADMIN"."ISEQ$$_20599".nextval
return def != null && def.toUpperCase().endsWith(".NEXTVAL") && def.toUpperCase().contains("ISEQ$$");
}
@Override
public SQLType getSqlType(int code) throws SQLException {
return Optional.ofNullable((SQLType)OracleType.toOracleType(code)).orElseGet(() -> JDBCType.valueOf(code));
}
@Override
public boolean isTimeType(SQLType sqlType) throws SQLException {
return oracleTimeTypes.contains(sqlType) || super.isTimeType(sqlType);
}
@Override
public SQLType getJdbcType(SQLType sqlType) {
if (sqlType instanceof OracleType) {
Integer oracleCode = sqlType.getVendorTypeNumber();
// most of the oracle specific codes are equal to standard JDBC codes.
// So, we do the best effort to return standard JDBCType that to case super.isTimeType() to work correctly.
if (oracleCode != null) {
try {
return JDBCType.valueOf(oracleCode);
} catch (IllegalArgumentException e) {
return sqlType;
}
}
}
return sqlType;
}
}