Skip to content

Commit 7e20a2f

Browse files
committed
Add a simple DataSource implementation
Implement the DataSource interface to be more compatible with JDBC spec. Add JDBC standard and Tarantool specific properties (getters/setters) to follow enterprise features (according to JavaBeans spec). Closes: #175
1 parent 494292b commit 7e20a2f

File tree

11 files changed

+419
-23
lines changed

11 files changed

+419
-23
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,13 +132,13 @@ To configure socket channel provider you should implements SocketChannelProvider
132132
For example:
133133

134134
```
135-
tarantool://localhost:3301?user=test&password=test&socketProvider=abc.xyz.MySocketProvider
135+
jdbc:tarantool://localhost:3301?user=test&password=test&socketProvider=abc.xyz.MySocketProvider
136136
```
137137

138138
Here is an example how you can use the driver covered by Spring `DriverManagerDataSource`:
139139

140140
```java
141-
NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(new DriverManagerDataSource("tarantool://localhost:3301?user=test&password=test"));
141+
NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(new DriverManagerDataSource("jdbc:tarantool://localhost:3301?user=test&password=test"));
142142
RowMapper<Object> rowMapper = new RowMapper<Object>() {
143143
@Override
144144
public Object mapRow(ResultSet resultSet, int i) throws SQLException {

src/it/java/org/tarantool/TestSql.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
//
3737
// public static void main(String[] args) throws IOException, SQLException {
3838
//
39-
// NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(new DriverManagerDataSource("tarantool://localhost:3301?username=test&password=test&socketProvider=org.tarantool.TestSql$TestSocketProvider"));
39+
// NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(new DriverManagerDataSource("jdbc:tarantool://localhost:3301?username=test&password=test&socketProvider=org.tarantool.TestSql$TestSocketProvider"));
4040
// RowMapper<Object> rowMapper = new RowMapper<Object>() {
4141
// @Override
4242
// public Object mapRow(ResultSet resultSet, int i) throws SQLException {

src/main/java/org/tarantool/jdbc/SQLConnection.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public class SQLConnection implements Connection {
5858
private DatabaseMetaData cachedMetadata;
5959
private int resultSetHoldability = UNSET_HOLDABILITY;
6060

61-
SQLConnection(String url, Properties properties) throws SQLException {
61+
public SQLConnection(String url, Properties properties) throws SQLException {
6262
this.url = url;
6363
this.properties = properties;
6464

src/main/java/org/tarantool/jdbc/SQLDriver.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ protected SQLTarantoolClientImpl makeSqlClient(String address, TarantoolClientCo
5757
protected Properties parseQueryString(URI uri, Properties info) throws SQLException {
5858
Properties urlProperties = new Properties();
5959

60+
// get scheme specific part (after the scheme part "jdbc:")
61+
// to correct parse remaining URL
62+
uri = URI.create(uri.getSchemeSpecificPart());
6063
String userInfo = uri.getUserInfo();
6164
if (userInfo != null) {
6265
// Get user and password from the corresponding part of the URI, i.e. before @ sign.
@@ -140,7 +143,7 @@ protected SocketChannelProvider getSocketProviderInstance(String className) thro
140143

141144
@Override
142145
public boolean acceptsURL(String url) throws SQLException {
143-
return url.toLowerCase().startsWith("tarantool:");
146+
return url.toLowerCase().startsWith("jdbc:tarantool:");
144147
}
145148

146149
@Override

src/main/java/org/tarantool/jdbc/SQLProperty.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public enum SQLProperty {
4444
INIT_TIMEOUT(
4545
"initTimeout",
4646
"The number of milliseconds to wait for connection establishment. " +
47-
"The default value is 60000 (1 minute).",
47+
"The default system value is 60000 (1 minute).",
4848
"60000",
4949
null,
5050
false
@@ -84,6 +84,10 @@ public String getDefaultValue() {
8484
return defaultValue;
8585
}
8686

87+
public int getDefaultIntValue() {
88+
return Integer.parseInt(defaultValue);
89+
}
90+
8791
public boolean isRequired() {
8892
return required;
8993
}
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
package org.tarantool.jdbc.ds;
2+
3+
import org.tarantool.jdbc.SQLConnection;
4+
import org.tarantool.jdbc.SQLProperty;
5+
6+
import java.io.PrintWriter;
7+
import java.sql.Connection;
8+
import java.sql.SQLException;
9+
import java.sql.SQLFeatureNotSupportedException;
10+
import java.sql.SQLNonTransientException;
11+
import java.util.Properties;
12+
import java.util.concurrent.TimeUnit;
13+
import java.util.logging.Logger;
14+
import javax.sql.DataSource;
15+
16+
/**
17+
* Simple {@code java.sql.DataSource} implementation.
18+
*/
19+
public class SQLDataSource implements TarantoolDataSource, DataSource {
20+
21+
private PrintWriter logWriter;
22+
private String description;
23+
private String name;
24+
25+
private Properties properties = new Properties();
26+
27+
@Override
28+
public Connection getConnection() throws SQLException {
29+
return new SQLConnection(makeUrl(), new Properties(properties));
30+
}
31+
32+
@Override
33+
public Connection getConnection(String username, String password) throws SQLException {
34+
Properties copyProperties = new Properties(properties);
35+
SQLProperty.USER.setString(copyProperties, username);
36+
SQLProperty.PASSWORD.setString(copyProperties, password);
37+
return new SQLConnection(makeUrl(), copyProperties);
38+
}
39+
40+
@Override
41+
public PrintWriter getLogWriter() {
42+
return logWriter;
43+
}
44+
45+
@Override
46+
public void setLogWriter(PrintWriter out) {
47+
logWriter = out;
48+
}
49+
50+
@Override
51+
public void setLoginTimeout(int seconds) {
52+
SQLProperty.INIT_TIMEOUT.setInt(properties, (int) TimeUnit.SECONDS.toMillis(seconds));
53+
}
54+
55+
@Override
56+
public int getLoginTimeout() throws SQLException {
57+
return (int) TimeUnit.MILLISECONDS.toSeconds(SQLProperty.INIT_TIMEOUT.getInt(properties));
58+
}
59+
60+
@Override
61+
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
62+
throw new SQLFeatureNotSupportedException();
63+
}
64+
65+
@Override
66+
public <T> T unwrap(Class<T> type) throws SQLException {
67+
if (isWrapperFor(type)) {
68+
return type.cast(this);
69+
}
70+
throw new SQLNonTransientException("Statement does not wrap " + type.getName());
71+
}
72+
73+
@Override
74+
public boolean isWrapperFor(Class<?> type) {
75+
return type.isAssignableFrom(this.getClass());
76+
}
77+
78+
@Override
79+
public String getServerName() {
80+
return SQLProperty.HOST.getString(properties);
81+
}
82+
83+
@Override
84+
public void setServerName(String serverName) {
85+
SQLProperty.HOST.setString(properties, serverName);
86+
}
87+
88+
@Override
89+
public int getPortNumber() throws SQLException {
90+
return SQLProperty.PORT.getInt(properties);
91+
}
92+
93+
@Override
94+
public void setPortNumber(int port) {
95+
SQLProperty.PORT.setInt(properties, port);
96+
}
97+
98+
@Override
99+
public String getUser() {
100+
return SQLProperty.USER.getString(properties);
101+
}
102+
103+
@Override
104+
public void setUser(String userName) {
105+
SQLProperty.USER.setString(properties, userName);
106+
}
107+
108+
@Override
109+
public String getPassword() {
110+
return SQLProperty.PASSWORD.getString(properties);
111+
}
112+
113+
@Override
114+
public void setPassword(String password) {
115+
SQLProperty.PASSWORD.setString(properties, password);
116+
}
117+
118+
@Override
119+
public String getDescription() {
120+
return description;
121+
}
122+
123+
@Override
124+
public void setDescription(String description) {
125+
this.description = description;
126+
}
127+
128+
@Override
129+
public String getDataSourceName() {
130+
return name;
131+
}
132+
133+
@Override
134+
public void setDataSourceName(String name) {
135+
this.name = name;
136+
}
137+
138+
@Override
139+
public String getSocketChannelProvider() {
140+
return SQLProperty.SOCKET_CHANNEL_PROVIDER.getString(properties);
141+
}
142+
143+
@Override
144+
public void setSocketChannelProvider(String classFqdn) {
145+
SQLProperty.SOCKET_CHANNEL_PROVIDER.setString(properties, classFqdn);
146+
}
147+
148+
@Override
149+
public int getRequestTimeout() throws SQLException {
150+
return (int) TimeUnit.MILLISECONDS.toSeconds(SQLProperty.REQUEST_TIMEOUT.getInt(properties));
151+
}
152+
153+
@Override
154+
public void setRequestTimeout(int seconds) {
155+
SQLProperty.REQUEST_TIMEOUT.setInt(properties, (int) TimeUnit.SECONDS.toMillis(seconds));
156+
}
157+
158+
private String makeUrl() {
159+
return "jdbc:tarantool://" +
160+
SQLProperty.HOST.getString(properties) + ":" + SQLProperty.PORT.getString(properties);
161+
}
162+
163+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package org.tarantool.jdbc.ds;
2+
3+
import java.sql.SQLException;
4+
5+
/**
6+
* JDBC standard Tarantool specific data source properties.
7+
*/
8+
public interface TarantoolDataSource {
9+
10+
String getServerName() throws SQLException;
11+
12+
void setServerName(String serverName) throws SQLException;
13+
14+
int getPortNumber() throws SQLException;
15+
16+
void setPortNumber(int port) throws SQLException;
17+
18+
String getUser() throws SQLException;
19+
20+
void setUser(String userName) throws SQLException;
21+
22+
String getPassword() throws SQLException;
23+
24+
void setPassword(String password) throws SQLException;
25+
26+
String getDescription() throws SQLException;
27+
28+
void setDescription(String description) throws SQLException;
29+
30+
String getDataSourceName() throws SQLException;
31+
32+
void setDataSourceName(String name) throws SQLException;
33+
34+
String getSocketChannelProvider() throws SQLException;
35+
36+
void setSocketChannelProvider(String classFqdn) throws SQLException;
37+
38+
int getRequestTimeout() throws SQLException;
39+
40+
void setRequestTimeout(int seconds) throws SQLException;
41+
42+
}

src/test/java/org/tarantool/jdbc/AbstractJdbcIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public abstract class AbstractJdbcIT {
2626
private static final Integer port = Integer.valueOf(System.getProperty("tntPort", "3301"));
2727
private static final String user = System.getProperty("tntUser", "test_admin");
2828
private static final String pass = System.getProperty("tntPass", "4pWBZmLEgkmKK5WP");
29-
private static String URL = String.format("tarantool://%s:%d?user=%s&password=%s", host, port, user, pass);
29+
private static String URL = String.format("jdbc:tarantool://%s:%d?user=%s&password=%s", host, port, user, pass);
3030

3131
protected static final String LUA_FILE = "jdk-testing.lua";
3232
protected static final int LISTEN = 3301;

src/test/java/org/tarantool/jdbc/JdbcDriverTest.java

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public void testParseQueryString() throws Exception {
3434
SQLProperty.PASSWORD.setString(prop, "secret");
3535

3636
URI uri = new URI(String.format(
37-
"tarantool://server.local:3302?%s=%s&%s=%d",
37+
"jdbc:tarantool://server.local:3302?%s=%s&%s=%d",
3838
SQLProperty.SOCKET_CHANNEL_PROVIDER.getName(), "some.class",
3939
SQLProperty.REQUEST_TIMEOUT.getName(), 5000)
4040
);
@@ -53,7 +53,7 @@ public void testParseQueryString() throws Exception {
5353
@Test
5454
public void testParseQueryStringUserInfoInURI() throws Exception {
5555
SQLDriver drv = new SQLDriver();
56-
Properties result = drv.parseQueryString(new URI("tarantool://adm:[email protected]"), null);
56+
Properties result = drv.parseQueryString(new URI("jdbc:tarantool://adm:[email protected]"), null);
5757
assertNotNull(result);
5858
assertEquals("server.local", SQLProperty.HOST.getString(result));
5959
assertEquals("3301", SQLProperty.PORT.getString(result));
@@ -64,7 +64,7 @@ public void testParseQueryStringUserInfoInURI() throws Exception {
6464
@Test
6565
public void testParseQueryStringValidations() {
6666
// Check non-number port
67-
checkParseQueryStringValidation("tarantool://0",
67+
checkParseQueryStringValidation("jdbc:tarantool://0",
6868
new Properties() {
6969
{
7070
SQLProperty.PORT.setString(this, "nan");
@@ -73,35 +73,35 @@ public void testParseQueryStringValidations() {
7373
"Property port must be a valid number.");
7474

7575
// Check zero port
76-
checkParseQueryStringValidation("tarantool://0:0", null, "Port is out of range: 0");
76+
checkParseQueryStringValidation("jdbc:tarantool://0:0", null, "Port is out of range: 0");
7777

7878
// Check high port
79-
checkParseQueryStringValidation("tarantool://0:65536", null, "Port is out of range: 65536");
79+
checkParseQueryStringValidation("jdbc:tarantool://0:65536", null, "Port is out of range: 65536");
8080

8181
// Check non-number init timeout
8282
checkParseQueryStringValidation(
83-
String.format("tarantool://0:3301?%s=nan", SQLProperty.INIT_TIMEOUT.getName()),
83+
String.format("jdbc:tarantool://0:3301?%s=nan", SQLProperty.INIT_TIMEOUT.getName()),
8484
null,
8585
"Property initTimeout must be a valid number."
8686
);
8787

8888
// Check negative init timeout
8989
checkParseQueryStringValidation(
90-
String.format("tarantool://0:3301?%s=-100", SQLProperty.INIT_TIMEOUT.getName()),
90+
String.format("jdbc:tarantool://0:3301?%s=-100", SQLProperty.INIT_TIMEOUT.getName()),
9191
null,
9292
"Property initTimeout must not be negative."
9393
);
9494

9595
// Check non-number operation timeout
9696
checkParseQueryStringValidation(
97-
String.format("tarantool://0:3301?%s=nan", SQLProperty.REQUEST_TIMEOUT.getName()),
97+
String.format("jdbc:tarantool://0:3301?%s=nan", SQLProperty.REQUEST_TIMEOUT.getName()),
9898
null,
9999
"Property requestTimeout must be a valid number."
100100
);
101101

102102
// Check negative operation timeout
103103
checkParseQueryStringValidation(
104-
String.format("tarantool://0:3301?%s=-100", SQLProperty.REQUEST_TIMEOUT.getName()),
104+
String.format("jdbc:tarantool://0:3301?%s=-100", SQLProperty.REQUEST_TIMEOUT.getName()),
105105
null,
106106
"Property requestTimeout must not be negative."
107107
);
@@ -111,7 +111,7 @@ public void testParseQueryStringValidations() {
111111
public void testGetPropertyInfo() throws SQLException {
112112
Driver drv = new SQLDriver();
113113
Properties props = new Properties();
114-
DriverPropertyInfo[] info = drv.getPropertyInfo("tarantool://server.local:3302", props);
114+
DriverPropertyInfo[] info = drv.getPropertyInfo("jdbc:tarantool://server.local:3302", props);
115115
assertNotNull(info);
116116
assertEquals(7, info.length);
117117

@@ -167,7 +167,7 @@ public void testNoResponseAfterInitialConnect() throws IOException {
167167
ServerSocket socket = new ServerSocket();
168168
socket.bind(null, 0);
169169
try {
170-
final String url = "tarantool://localhost:" + socket.getLocalPort();
170+
final String url = "jdbc:tarantool://localhost:" + socket.getLocalPort();
171171
final Properties prop = new Properties();
172172
SQLProperty.INIT_TIMEOUT.setInt(prop, 500);
173173
SQLException e = assertThrows(SQLException.class, new Executable() {
@@ -184,12 +184,12 @@ public void execute() throws Throwable {
184184
}
185185

186186
private void checkCustomSocketProviderFail(String providerClassName, String errMsg) throws SQLException {
187-
final Driver drv = DriverManager.getDriver("tarantool:");
187+
final Driver drv = DriverManager.getDriver("jdbc:tarantool:");
188188
final Properties prop = new Properties();
189189
SQLProperty.SOCKET_CHANNEL_PROVIDER.setString(prop, providerClassName);
190190
SQLProperty.INIT_TIMEOUT.setInt(prop, 500);
191191

192-
SQLException e = assertThrows(SQLException.class, () -> drv.connect("tarantool://0:3301", prop));
192+
SQLException e = assertThrows(SQLException.class, () -> drv.connect("jdbc:tarantool://0:3301", prop));
193193
assertTrue(e.getMessage().startsWith(errMsg), e.getMessage());
194194
}
195195

0 commit comments

Comments
 (0)