-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathTestedDataSourceProvider.java
125 lines (100 loc) · 4.48 KB
/
TestedDataSourceProvider.java
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
package org.utplsql.cli.datasource;
import oracle.jdbc.pool.OracleDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.utplsql.api.EnvironmentVariableUtil;
import org.utplsql.cli.ConnectionConfig;
import org.utplsql.cli.exception.DatabaseConnectionFailed;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestedDataSourceProvider {
interface ConnectStringPossibility {
String getConnectString(ConnectionConfig config);
String getMaskedConnectString(ConnectionConfig config);
}
private static final Logger logger = LoggerFactory.getLogger(TestedDataSourceProvider.class);
private final ConnectionConfig config;
private final List<ConnectStringPossibility> possibilities = new ArrayList<>();
private final int maxConnections;
public TestedDataSourceProvider(ConnectionConfig config, int maxConnections) {
this.config = config;
this.maxConnections = maxConnections;
possibilities.add(new ThickConnectStringPossibility());
possibilities.add(new ThinConnectStringPossibility());
}
public DataSource getDataSource() throws SQLException {
InitializableOracleDataSource ds = new InitializableOracleDataSource();
setInitSqlFrom_NLS_LANG(ds);
setThickOrThinJdbcUrl(ds);
return ds;
}
private void setThickOrThinJdbcUrl(OracleDataSource ds) throws SQLException {
List<String> errors = new ArrayList<>();
Throwable lastException = null;
ds.setUser(config.getUser());
ds.setPassword(config.getPassword());
for (ConnectStringPossibility possibility : possibilities) {
ds.setURL(possibility.getConnectString(config));
try (Connection ignored = ds.getConnection()) {
logger.info("Use connection string {}", possibility.getMaskedConnectString(config));
return;
} catch (UnsatisfiedLinkError | Exception e) {
errors.add(possibility.getMaskedConnectString(config) + ": " + e.getMessage());
lastException = e;
}
}
errors.forEach(System.out::println);
throw new DatabaseConnectionFailed(lastException);
}
private void setInitSqlFrom_NLS_LANG(InitializableOracleDataSource ds) {
String nls_lang = EnvironmentVariableUtil.getEnvValue("NLS_LANG");
if (nls_lang != null) {
Pattern pattern = Pattern.compile("^([a-zA-Z ]+)?_?([a-zA-Z ]+)?\\.?([a-zA-Z0-9]+)?$");
Matcher matcher = pattern.matcher(nls_lang);
List<String> sqlCommands = new ArrayList<>(2);
if (matcher.matches()) {
if (matcher.group(1) != null) {
sqlCommands.add(String.format("ALTER SESSION SET NLS_LANGUAGE='%s'", matcher.group(1)));
}
if (matcher.group(2) != null) {
sqlCommands.add(String.format("ALTER SESSION SET NLS_TERRITORY='%s'", matcher.group(2)));
}
if (sqlCommands.size() > 0) {
StringBuilder sb = new StringBuilder();
sb.append("BEGIN\n");
for (String command : sqlCommands) {
sb.append(String.format("EXECUTE IMMEDIATE q'[%s]';\n", command));
}
sb.append("END;");
logger.debug("NLS settings: {}", sb.toString());
ds.setConnectionInitSql(sb.toString());
}
}
}
}
private static class ThickConnectStringPossibility implements ConnectStringPossibility {
@Override
public String getConnectString(ConnectionConfig config) {
return "jdbc:oracle:oci8:@" + config.getConnect();
}
@Override
public String getMaskedConnectString(ConnectionConfig config) {
return "jdbc:oracle:oci8:****/****@" + config.getConnect();
}
}
private static class ThinConnectStringPossibility implements ConnectStringPossibility {
@Override
public String getConnectString(ConnectionConfig config) {
return "jdbc:oracle:thin:@" + config.getConnect();
}
@Override
public String getMaskedConnectString(ConnectionConfig config) {
return "jdbc:oracle:thin:****/****@" + config.getConnect();
}
}
}