Skip to content

Initial JDBC support #99

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Dec 13, 2018
13 changes: 12 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,16 @@ before_script:
- src/test/travis.pre.sh

script:
- mvn verify
- |
if [ "${TRAVIS_JDK_VERSION}" = openjdk11 ]; then
mvn verify jacoco:report
else
mvn verify
fi
- cat testroot/jdk-testing.log

after_success:
- |
if [ "${TRAVIS_JDK_VERSION}" = openjdk11 ]; then
mvn coveralls:report -DrepoToken=${COVERALLS_TOKEN}
fi
39 changes: 37 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ align="right">

# Java connector for Tarantool 1.7.4+

[![Coverage Status][coveralls-badge]][coveralls-page]

[coveralls-badge]: https://coveralls.io/repos/github/tarantool/tarantool-java/badge.svg?branch=master
[coveralls-page]: https://coveralls.io/github/tarantool/tarantool-java?branch=master

[![Join the chat at https://gitter.im/tarantool/tarantool-java](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/tarantool/tarantool-java?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

To get the Java connector for Tarantool 1.6.9, visit
Expand Down Expand Up @@ -115,7 +120,37 @@ Feel free to override any method of `TarantoolClientImpl`. For example, to hook
all the results, you could override this:

```java
protected void complete(long code, FutureImpl<List> q);
protected void complete(long code, FutureImpl<?> q);
```

## Spring NamedParameterJdbcTemplate usage example

To configure sockets you should implements SQLSocketProvider and add socketProvider=abc.xyz.MySocketProvider to connect url.
For example tarantool://localhost:3301?user=test&password=test&socketProvider=abc.xyz.MySocketProvider

```java
NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(new DriverManagerDataSource("tarantool://localhost:3301?user=test&password=test"));
RowMapper<Object> rowMapper = new RowMapper<Object>() {
@Override
public Object mapRow(ResultSet resultSet, int i) throws SQLException {
return Arrays.asList(resultSet.getInt(1), resultSet.getString(2));
}
};

try {
System.out.println(template.update("drop table hello_world", Collections.<String, Object>emptyMap()));
} catch (Exception ignored) {
}

System.out.println(template.update("create table hello_world(hello int not null PRIMARY KEY, world varchar(255) not null)", Collections.<String, Object>emptyMap()));
Map<String, Object> params = new LinkedHashMap<String, Object>();
params.put("text", "hello world");
params.put("id", 1);

System.out.println(template.update("insert into hello_world(hello, world) values(:id,:text)", params));
System.out.println(template.query("select * from hello_world", rowMapper));

System.out.println(template.query("select * from hello_world where hello=:id", Collections.singletonMap("id", 1), rowMapper));
```

For more implementation details, see [API documentation](http://tarantool.github.io/tarantool-java/apidocs/index.html).
Expand All @@ -131,4 +166,4 @@ base for possible answers and solutions.
To run tests
```
./mvnw clean test
```
```
27 changes: 27 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,33 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.2</version>
<executions>
<execution>
<id>prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eluder.coveralls</groupId>
<artifactId>coveralls-maven-plugin</artifactId>
<version>4.3.0</version>
<dependencies>
<!-- Support reporting to coveralls on Java 9. -->
<!-- https://github.com/trautonen/coveralls-maven-plugin/issues/112 -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>

Expand Down
61 changes: 61 additions & 0 deletions src/it/java/org/tarantool/TestSql.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//package org.tarantool;
//
//import java.io.IOException;
//import java.net.InetSocketAddress;
//import java.net.Socket;
//import java.net.URI;
//import java.sql.ResultSet;
//import java.sql.SQLException;
//import java.util.Arrays;
//import java.util.Collections;
//import java.util.LinkedHashMap;
//import java.util.Map;
//import java.util.Properties;
//
//import org.springframework.jdbc.core.RowMapper;
//import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
//import org.springframework.jdbc.datasource.DriverManagerDataSource;
//import org.tarantool.jdbc.SQLSocketProvider;
//
//public class TestSql {
//
// public static class TestSocketProvider implements SQLSocketProvider {
//
// @Override
// public Socket getConnectedSocket(URI uri, Properties params) {
// Socket socket;
// socket = new Socket();
// try {
// socket.connect(new InetSocketAddress(params.getProperty("host","localhost"), Integer.parseInt(params.getProperty("port", "3301"))));
// } catch (Exception e) {
// throw new RuntimeException("Couldn't connect to tarantool using" + params, e);
// }
// return socket;
// }
// }
//
// public static void main(String[] args) throws IOException, SQLException {
//
// NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(new DriverManagerDataSource("tarantool://localhost:3301?username=test&password=test&socketProvider=org.tarantool.TestSql$TestSocketProvider"));
// RowMapper<Object> rowMapper = new RowMapper<Object>() {
// @Override
// public Object mapRow(ResultSet resultSet, int i) throws SQLException {
// return Arrays.asList(resultSet.getInt(1), resultSet.getString(2));
// }
// };
//
// try {
// System.out.println(template.update("drop table hello_world", Collections.<String, Object>emptyMap()));
// } catch (Exception ignored) {
// }
// System.out.println(template.update("create table hello_world(hello int not null PRIMARY KEY, world varchar(255) not null)", Collections.<String, Object>emptyMap()));
// Map<String, Object> params = new LinkedHashMap<String, Object>();
// params.put("text", "hello world");
// params.put("id", 1);
//
// System.out.println(template.update("insert into hello_world(hello, world) values(:id,:text)", params));
// System.out.println(template.query("select * from hello_world", rowMapper));
//
// System.out.println(template.query("select * from hello_world where hello=:id", Collections.singletonMap("id", 1), rowMapper));
// }
//}
2 changes: 1 addition & 1 deletion src/it/java/org/tarantool/TestTarantoolClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ protected void reconnect(int retry, Throwable lastError) {
}

@Override
protected void complete(long code, FutureImpl<List<?>> q) {
protected void complete(long code, FutureImpl<?> q) {
super.complete(code, q);
if (code != 0) {
System.out.println(code);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/tarantool/AbstractTarantoolOps.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
public abstract class AbstractTarantoolOps<Space, Tuple, Operation, Result> implements TarantoolClientOps<Space, Tuple, Operation, Result> {
private Code callCode = Code.OLD_CALL;

public abstract Result exec(Code code, Object... args);
protected abstract Result exec(Code code, Object... args);

public Result select(Space space, Space index, Tuple key, int offset, int limit, Iterator iterator) {
return select(space, index, key, offset, limit, iterator.getValue());
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/tarantool/Code.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

public enum Code {
SELECT(1), INSERT(2), REPLACE(3), UPDATE(4),
DELETE(5), OLD_CALL(6), AUTH(7), EVAL(8), UPSERT(9), CALL(10), PING(64), SUBSCRIBE(66);
DELETE(5), OLD_CALL(6), AUTH(7), EVAL(8), UPSERT(9), CALL(10), EXECUTE(11) , PING(64), SUBSCRIBE(66),;

int id;

Expand Down
7 changes: 6 additions & 1 deletion src/main/java/org/tarantool/FutureImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@

public class FutureImpl<V> extends AbstractQueuedSynchronizer implements Future<V> {
protected final long id;
protected Code code;
protected V value;
protected Exception error;

public FutureImpl(long id) {
public FutureImpl(long id, Code code) {
this.id = id;
this.code = code;
setState(1);
}

Expand Down Expand Up @@ -91,4 +93,7 @@ public Long getId() {
return id;
}

public Code getCode() {
return code;
}
}
87 changes: 87 additions & 0 deletions src/main/java/org/tarantool/JDBCBridge.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package org.tarantool;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import org.tarantool.jdbc.SQLResultSet;

public class JDBCBridge {
public static final JDBCBridge EMPTY = new JDBCBridge(Collections.<TarantoolBase.SQLMetaData>emptyList(), Collections.<List<Object>>emptyList());

final List<TarantoolBase.SQLMetaData> sqlMetadata;
final Map<String,Integer> columnsByName;
final List<List<Object>> rows;

protected JDBCBridge(TarantoolConnection connection) {
this(connection.getSQLMetadata(),connection.getSQLData());
}

protected JDBCBridge(List<TarantoolBase.SQLMetaData> sqlMetadata, List<List<Object>> rows) {
this.sqlMetadata = sqlMetadata;
this.rows = rows;
columnsByName = new LinkedHashMap<String, Integer>((int) Math.ceil(sqlMetadata.size() / 0.75), 0.75f);
for (int i = 0; i < sqlMetadata.size(); i++) {
columnsByName.put(sqlMetadata.get(i).getName(), i + 1);
}
}

public static JDBCBridge query(TarantoolConnection connection, String sql, Object ... params) {
connection.sql(sql, params);
return new JDBCBridge(connection);
}

public static int update(TarantoolConnection connection, String sql, Object ... params) {
return connection.update(sql, params).intValue();
}

public static JDBCBridge mock(List<String> fields, List<List<Object>> values) {
List<TarantoolBase.SQLMetaData> meta = new ArrayList<TarantoolBase.SQLMetaData>(fields.size());
for(String field:fields) {
meta.add(new TarantoolBase.SQLMetaData(field));
}
return new JDBCBridge(meta, values);
}

public static Object execute(TarantoolConnection connection, String sql, Object ... params) {
connection.sql(sql, params);
Long rowCount = connection.getSqlRowCount();
if(rowCount == null) {
return new SQLResultSet(new JDBCBridge(connection));
}
return rowCount.intValue();
}


public String getColumnName(int columnIndex) {
return columnIndex > sqlMetadata.size() ? null : sqlMetadata.get(columnIndex - 1).getName();
}

public Integer getColumnIndex(String columnName) {
return columnsByName.get(columnName);
}

public int getColumnCount() {
return columnsByName.size();
}

public ListIterator<List<Object>> iterator() {
return rows.listIterator();
}

public int size() {
return rows.size();
}

@Override
public String toString() {
return "JDBCBridge{" +
"sqlMetadata=" + sqlMetadata +
", columnsByName=" + columnsByName +
", rows=" + rows +
'}';
}
}
10 changes: 9 additions & 1 deletion src/main/java/org/tarantool/Key.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,15 @@ public enum Key implements Callable<Integer> {
TUPLE(0x21), FUNCTION(0x22),
USER_NAME(0x23),EXPRESSION(0x27),
UPSERT_OPS(0x28),
DATA(0x30), ERROR(0x31);
DATA(0x30), ERROR(0x31),

SQL_FIELD_NAME(0),
SQL_METADATA(0x32),
SQL_TEXT(0x40),
SQL_BIND(0x41),
SQL_OPTIONS(0x42),
SQL_INFO(0x42),
SQL_ROW_COUNT(0);

int id;

Expand Down
Loading