Skip to content

Commit

Permalink
Merge c42ebdc into 4ba88fb
Browse files Browse the repository at this point in the history
  • Loading branch information
nicktorwald committed Dec 1, 2019
2 parents 4ba88fb + c42ebdc commit 6811c49
Show file tree
Hide file tree
Showing 14 changed files with 585 additions and 25 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ env:
- TNT_VERSION=2x
- TNT_VERSION=2.2
- TNT_VERSION=2.3
- TNT_VERSION=np/gh-2592-prepared-statemets-v2

stages:
- checkstyle
Expand Down
18 changes: 18 additions & 0 deletions .travis/travis.pre.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@

set -exuo pipefail # Strict shell

if [ "${TNT_VERSION}" = "np/gh-2592-prepared-statemets-v2" ]; then
sudo apt-get update

# branch: np/gh-2592-prepared-statemets-v2
# commit: 6df993c3a6068f2d2ed7d7b289644e9a1dd2cfce
wget https://tkn.me/tmp/tarantool_2.3.0.241.g6df993c-1_amd64.deb
wget https://tkn.me/tmp/tarantool-common_2.3.0.241.g6df993c-1_all.deb

# Install dependencies and tarantool packages.
sudo apt-get -y install binutils libgomp1 libicu52 libunwind8
sudo dpkg -i tarantool*.deb
sudo apt-get -y install -f # just in case

sudo tarantoolctl stop example

exit
fi

curl http://download.tarantool.org/tarantool/${TNT_VERSION}/gpgkey | sudo apt-key add -
RELEASE=`lsb_release -c -s`

Expand Down
1 change: 1 addition & 0 deletions src/main/java/org/tarantool/Code.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public enum Code {
UPSERT(9),
CALL(10),
EXECUTE(11),
PREPARE(13),
PING(64),
SUBSCRIBE(66);

Expand Down
2 changes: 2 additions & 0 deletions src/main/java/org/tarantool/Key.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public enum Key implements Callable<Integer> {
SQL_FIELD_TYPE(0x1),

SQL_METADATA(0x32),
SQL_BIND_METADATA(0x33),
SQL_BIND_COUNT(0x34),
SQL_TEXT(0x40),
SQL_BIND(0x41),
SQL_OPTIONS(0x42),
Expand Down
15 changes: 14 additions & 1 deletion src/main/java/org/tarantool/SqlProtoUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,17 @@ public static List<List<Object>> getSQLData(TarantoolPacket pack) {
return (List<List<Object>>) pack.getBody().get(Key.DATA.getId());
}

public static List<SQLMetaData> getSQLBindMetadata(TarantoolPacket pack) {
return getMetadata(pack, Key.SQL_BIND_METADATA);
}

public static List<SQLMetaData> getSQLMetadata(TarantoolPacket pack) {
List<Map<Integer, Object>> meta = (List<Map<Integer, Object>>) pack.getBody().get(Key.SQL_METADATA.getId());
return getMetadata(pack, Key.SQL_METADATA);
}

private static List<SQLMetaData> getMetadata(TarantoolPacket pack, Key targetKey) {
List<Map<Integer, Object>> meta = (List<Map<Integer, Object>>) pack.getBody()
.getOrDefault(targetKey.getId(), Collections.emptyList());
List<SQLMetaData> values = new ArrayList<>(meta.size());
for (Map<Integer, Object> item : meta) {
values.add(new SQLMetaData(
Expand All @@ -42,6 +51,10 @@ public static List<SQLMetaData> getSQLMetadata(TarantoolPacket pack) {
return values;
}

public static String getSQLText(TarantoolPacket pack) {
return pack.getBody().get(Key.SQL_TEXT.getId()).toString();
}

public static Long getSQLRowCount(TarantoolPacket pack) {
Map<Key, Object> info = (Map<Key, Object>) pack.getBody().get(Key.SQL_INFO.getId());
Number rowCount;
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/tarantool/TarantoolClientImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ protected void complete(TarantoolPacket packet, TarantoolOperation operation) {
} catch (TarantoolSchemaException cause) {
fail(target, cause);
}
} else if (operation.getCode() == Code.EXECUTE) {
} else if (operation.isSqlRelated()) {
completeSql(operation, packet);
} else {
((CompletableFuture) result).complete(packet.getData());
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/org/tarantool/TarantoolOperation.java
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ public Code getCode() {
return code;
}

public boolean isSqlRelated() {
return code == Code.EXECUTE || code == Code.PREPARE;
}

public TarantoolOperation getDependedOperation() {
return dependedOperation;
}
Expand Down
160 changes: 142 additions & 18 deletions src/main/java/org/tarantool/jdbc/SQLConnection.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package org.tarantool.jdbc;

import org.tarantool.Code;
import org.tarantool.CommunicationException;
import org.tarantool.Key;
import org.tarantool.SocketChannelProvider;
import org.tarantool.SqlProtoUtils;
import org.tarantool.TarantoolClientConfig;
import org.tarantool.TarantoolClientImpl;
import org.tarantool.TarantoolOperation;
import org.tarantool.TarantoolRequest;
import org.tarantool.TarantoolRequestArgumentFactory;
import org.tarantool.protocol.TarantoolPacket;
import org.tarantool.util.JdbcConstants;
import org.tarantool.util.SQLStates;
Expand Down Expand Up @@ -530,9 +533,10 @@ public int getNetworkTimeout() throws SQLException {
@Override
public SQLResultHolder execute(long timeout, SQLQueryHolder query) throws SQLException {
checkNotClosed();
ExecuteQueryCommand action = new ExecuteQueryCommand(query, client.sqlRawOps());
return (useNetworkTimeout(timeout))
? executeWithNetworkTimeout(query)
: executeWithQueryTimeout(timeout, query);
? executeWithNetworkTimeout(action)
: executeWithQueryTimeout(timeout, action);
}

@Override
Expand All @@ -547,42 +551,64 @@ public SQLBatchResultHolder executeBatch(long timeout, List<SQLQueryHolder> quer
return batchResult;
}

@Override
public SQLPreparedHolder prepare(long timeout, String sqlText) throws SQLException {
checkNotClosed();
PrepareQueryCommand action = new PrepareQueryCommand(sqlText, client.sqlRawOps());
return (useNetworkTimeout(timeout))
? executeWithNetworkTimeout(action)
: executeWithQueryTimeout(timeout, action);
}

private boolean useNetworkTimeout(long timeout) throws SQLException {
int networkTimeout = getNetworkTimeout();
return timeout == 0 || (networkTimeout > 0 && networkTimeout < timeout);
}

private SQLResultHolder executeWithNetworkTimeout(SQLQueryHolder query) throws SQLException {
/**
* Executes a query command using a predefined network timeout.
*
* @param action command to be executed
* @param <R> result of the action
*
* @return query result
*
* @throws SQLException if any execution errors occur
*/
private <R> R executeWithNetworkTimeout(QueryCommand<R> action) throws SQLException {
try {
return client.sqlRawOps().execute(query);
return action.execute();
} catch (Exception e) {
handleException(e);
throw new SQLException(formatError(query), e);
throw new SQLException(formatError(action.getQuery()), e);
}
}

/**
* Executes a query using a custom timeout.
* Executes a query command using a custom timeout.
* In contrast to {@link #executeWithNetworkTimeout(QueryCommand)}
* it provides handling of timeout errors by wrapping them via {@link StatementTimeoutException}.
*
* @param timeout query timeout
* @param query query
* @param timeout command timeout
* @param action command to be executed
* @param <R> result of the action
*
* @return SQL result holder
* @return action result
*
* @throws StatementTimeoutException if query execution took more than query timeout
* @throws SQLException if any other errors occurred
*/
private SQLResultHolder executeWithQueryTimeout(long timeout, SQLQueryHolder query) throws SQLException {
private <R> R executeWithQueryTimeout(long timeout, QueryCommand<R> action) throws SQLException {
try {
return client.sqlRawOps().execute(timeout, query);
return action.execute(timeout);
} catch (Exception e) {
// statement timeout should not affect the current connection
// but can be handled by the caller side
if (e.getCause() instanceof TimeoutException) {
throw new StatementTimeoutException(formatError(query), e.getCause());
throw new StatementTimeoutException(formatError(action.getQuery()), e.getCause());
}
handleException(e);
throw new SQLException(formatError(query), e);
throw new SQLException(formatError(action.getQuery()), e);
}
}

Expand Down Expand Up @@ -746,6 +772,18 @@ private Future<?> executeQuery(SQLQueryHolder queryHolder, long timeoutMillis) {
return exec(request);
}

private Future<?> prepareQuery(String sqlQuery, long timeoutMillis) {
TarantoolRequest prepareRequest = new TarantoolRequest(
Code.PREPARE,
TarantoolRequestArgumentFactory.value(Key.SQL_TEXT),
TarantoolRequestArgumentFactory.value(sqlQuery)
);
if (timeoutMillis > 0) {
prepareRequest.setTimeout(Duration.ofMillis(timeoutMillis));
}
return exec(prepareRequest);
}

final SQLRawOps sqlRawOps = new SQLRawOps() {
@Override
public SQLResultHolder execute(SQLQueryHolder query) {
Expand All @@ -767,6 +805,16 @@ public SQLBatchResultHolder executeBatch(long timeoutMillis, List<SQLQueryHolder
return executeInternal(queries, (query) -> executeQuery(query, timeoutMillis));
}

@Override
public SQLPreparedHolder prepare(String sqlQuery) {
return (SQLPreparedHolder) syncGet(prepareQuery(sqlQuery, 0L));
}

@Override
public SQLPreparedHolder prepare(long timeoutMillis, String sqlQuery) {
return (SQLPreparedHolder) syncGet(prepareQuery(sqlQuery, timeoutMillis));
}

private SQLBatchResultHolder executeInternal(List<SQLQueryHolder> queries,
Function<SQLQueryHolder, Future<?>> fetcher) {
List<Future<?>> sqlFutures = new ArrayList<>();
Expand Down Expand Up @@ -813,11 +861,20 @@ SQLRawOps sqlRawOps() {

@Override
protected void completeSql(TarantoolOperation operation, TarantoolPacket pack) {
Long rowCount = SqlProtoUtils.getSQLRowCount(pack);
SQLResultHolder result = (rowCount == null)
? SQLResultHolder.ofQuery(SqlProtoUtils.getSQLMetadata(pack), SqlProtoUtils.getSQLData(pack))
: SQLResultHolder.ofUpdate(rowCount.intValue(), SqlProtoUtils.getSQLAutoIncrementIds(pack));
((CompletableFuture) operation.getResult()).complete(result);
if (operation.getCode() == Code.PREPARE) {
SQLPreparedHolder result = new SQLPreparedHolder(
SqlProtoUtils.getSQLText(pack),
SqlProtoUtils.getSQLMetadata(pack),
SqlProtoUtils.getSQLBindMetadata(pack)
);
((CompletableFuture) operation.getResult()).complete(result);
} else {
Long rowCount = SqlProtoUtils.getSQLRowCount(pack);
SQLResultHolder result = (rowCount == null)
? SQLResultHolder.ofQuery(SqlProtoUtils.getSQLMetadata(pack), SqlProtoUtils.getSQLData(pack))
: SQLResultHolder.ofUpdate(rowCount.intValue(), SqlProtoUtils.getSQLAutoIncrementIds(pack));
((CompletableFuture) operation.getResult()).complete(result);
}
}

interface SQLRawOps {
Expand All @@ -830,6 +887,73 @@ interface SQLRawOps {

SQLBatchResultHolder executeBatch(long timeoutMillis, List<SQLQueryHolder> queries);

SQLPreparedHolder prepare(String sqlQuery);

SQLPreparedHolder prepare(long timeoutMillis, String sqlQuery);
}

}

private interface QueryCommand<R> {

R execute();

R execute(long timeoutInMillis);

SQLQueryHolder getQuery();

}

private static final class ExecuteQueryCommand implements QueryCommand<SQLResultHolder> {

private SQLQueryHolder query;
private SQLTarantoolClientImpl.SQLRawOps operations;

public ExecuteQueryCommand(SQLQueryHolder query, SQLTarantoolClientImpl.SQLRawOps operations) {
this.query = query;
this.operations = operations;
}

@Override
public SQLResultHolder execute() {
return operations.execute(query);
}

@Override
public SQLResultHolder execute(long timeoutInMillis) {
return operations.execute(timeoutInMillis, query);
}

@Override
public SQLQueryHolder getQuery() {
return query;
}

}

private static final class PrepareQueryCommand implements QueryCommand<SQLPreparedHolder> {

private SQLQueryHolder query;
private SQLTarantoolClientImpl.SQLRawOps operations;

public PrepareQueryCommand(String query, SQLTarantoolClientImpl.SQLRawOps operations) {
this.query = SQLQueryHolder.of(query);
this.operations = operations;
}

@Override
public SQLPreparedHolder execute() {
return operations.prepare(query.getQuery());
}

@Override
public SQLPreparedHolder execute(long timeoutInMillis) {
return operations.prepare(timeoutInMillis, query.getQuery());
}

@Override
public SQLQueryHolder getQuery() {
return query;
}

}
Expand Down

0 comments on commit 6811c49

Please sign in to comment.