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
126 lines (109 loc) · 4.36 KB
/
OracleQueryDialect.java
File metadata and controls
126 lines (109 loc) · 4.36 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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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.HashMap;
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
));
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);
private static final Map<Integer, ThrowingBiFunction<ResultSet, Integer, Object, SQLException>> getters = new HashMap<>();
static {
getters.put(Types.DATE, getDate);
getters.put(Types.TIME, getTime);
getters.put(Types.TIMESTAMP, getTimestamp);
getters.put(OracleType.TIMESTAMP.getVendorTypeNumber(), getTimestamp);
getters.put(Types.TIME_WITH_TIMEZONE, getTime);
getters.put(Types.TIMESTAMP_WITH_TIMEZONE, getTimestamp);
getters.put(OracleType.TIMESTAMP_WITH_TIME_ZONE.getVendorTypeNumber(), getTimestamp);
getters.put(OracleType.TIMESTAMP_WITH_LOCAL_TIME_ZONE.getVendorTypeNumber(), getTimestamp);
getters.put(Types.BLOB, blobAsString);
}
public OracleQueryDialect() {
super(false);
}
@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
public boolean requiresUppercaseNames() {
return true;
}
@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;
}
@Override
public boolean acceptsURL(String url) {
return url.startsWith("jdbc:oracle:");
}
@Override
public QueryDialect keepTypes(boolean keepTypes) {
if (keepTypes) {
keepTypes(getters, getObject);
} else {
keepTypes(Collections.emptyMap(), getString);
}
return this;
}
}