Skip to content
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

FMWK-298 Support byte array parameter in PreparedStatement #59

Merged
merged 1 commit into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 8 additions & 20 deletions src/main/java/com/aerospike/jdbc/AerospikePreparedStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@

import static com.aerospike.jdbc.util.PreparedStatement.parseParameters;
import static java.lang.String.format;
import static java.util.Objects.isNull;

public class AerospikePreparedStatement extends AerospikeStatement implements PreparedStatement {

Expand All @@ -50,9 +49,8 @@ private Object[] buildSqlParameters(String sql) {

@Override
public ResultSet executeQuery() throws SQLException {
String preparedQueryString = prepareQueryString();
logger.info(() -> "executeQuery: " + preparedQueryString);
AerospikeQuery query = parseQuery(preparedQueryString);
logger.info(() -> format("executeQuery: %s, params: %s", sqlStatement, Arrays.toString(sqlParameters)));
AerospikeQuery query = parseQuery(sqlStatement, Arrays.asList(sqlParameters));
runQuery(query);
return resultSet;
}
Expand Down Expand Up @@ -114,7 +112,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException

@Override
public void setString(int parameterIndex, String x) throws SQLException {
setObject(parameterIndex, format("\"%s\"", x));
setObject(parameterIndex, x);
}

@Override
Expand Down Expand Up @@ -180,25 +178,15 @@ public void setObject(int parameterIndex, Object x) throws SQLException {

@Override
public boolean execute() throws SQLException {
String preparedQueryString = prepareQueryString();
logger.info(() -> "execute: " + preparedQueryString);
AerospikeQuery query = parseQuery(preparedQueryString);
logger.info(() -> format("execute: %s, params: %s", sqlStatement, Arrays.toString(sqlParameters)));
AerospikeQuery query = parseQuery(sqlStatement, Arrays.asList(sqlParameters));
runQuery(query);
return query.getQueryType() == QueryType.SELECT;
}

private String prepareQueryString() {
String preparedQueryString = sqlStatement;
for (Object value : sqlParameters) {
String replacement = isNull(value) ? "?" : value.toString();
preparedQueryString = preparedQueryString.replaceFirst("\\?", replacement);
}
return preparedQueryString;
}

@Override
public void addBatch() throws SQLException {
addBatch(prepareQueryString());
throw new SQLFeatureNotSupportedException(BATCH_NOT_SUPPORTED_MESSAGE);
}

@Override
Expand Down Expand Up @@ -228,7 +216,7 @@ public void setArray(int parameterIndex, Array x) throws SQLException {

@Override
public ResultSetMetaData getMetaData() throws SQLException {
AerospikeQuery query = parseQuery(prepareQueryString());
AerospikeQuery query = parseQuery(sqlStatement, Arrays.asList(sqlParameters));
List<DataColumn> columns = ((AerospikeDatabaseMetadata) connection.getMetaData())
.getSchemaBuilder()
.getSchema(query.getCatalogTable());
Expand Down Expand Up @@ -262,7 +250,7 @@ public void setURL(int parameterIndex, URL url) throws SQLException {

@Override
public ParameterMetaData getParameterMetaData() throws SQLException {
AerospikeQuery query = parseQuery(prepareQueryString());
AerospikeQuery query = parseQuery(sqlStatement, Arrays.asList(sqlParameters));
List<DataColumn> columns = ((AerospikeDatabaseMetadata) connection.getMetaData())
.getSchemaBuilder()
.getSchema(query.getCatalogTable());
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/com/aerospike/jdbc/AerospikeStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.Collection;
import java.util.logging.Logger;

import static java.lang.String.format;
Expand All @@ -24,9 +25,9 @@

public class AerospikeStatement implements Statement, SimpleWrapper {

private static final Logger logger = Logger.getLogger(AerospikeStatement.class.getName());
protected static final String BATCH_NOT_SUPPORTED_MESSAGE = "Batch update is not supported";

private static final String BATCH_NOT_SUPPORTED_MESSAGE = "Batch update is not supported";
private static final Logger logger = Logger.getLogger(AerospikeStatement.class.getName());
private static final String AUTO_GENERATED_KEYS_NOT_SUPPORTED_MESSAGE = "Auto-generated keys are not supported";

protected final IAerospikeClient client;
Expand All @@ -48,7 +49,7 @@ public AerospikeStatement(IAerospikeClient client, AerospikeConnection connectio
@Override
public ResultSet executeQuery(String sql) throws SQLException {
logger.info(() -> "executeQuery: " + sql);
AerospikeQuery query = parseQuery(sql);
AerospikeQuery query = parseQuery(sql, null);
runQuery(query);
return resultSet;
}
Expand All @@ -59,11 +60,11 @@ protected void runQuery(AerospikeQuery query) {
updateCount = result.getRight();
}

protected AerospikeQuery parseQuery(String sql) throws SQLException {
protected AerospikeQuery parseQuery(String sql, Collection<Object> sqlParameters) throws SQLException {
sql = sql.replace("\n", " ");
AerospikeQuery query;
try {
query = AerospikeQuery.parse(sql);
query = AerospikeQuery.parse(sql, sqlParameters);
} catch (Exception e) {
query = AuxStatementParser.parse(sql);
}
Expand Down Expand Up @@ -142,7 +143,7 @@ public void setCursorName(String name) throws SQLException {
@Override
public boolean execute(String sql) throws SQLException {
logger.info(() -> "execute: " + sql);
AerospikeQuery query = parseQuery(sql);
AerospikeQuery query = parseQuery(sql, null);
runQuery(query);
return query.getQueryType() == QueryType.SELECT;
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/aerospike/jdbc/model/AerospikeQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ public AerospikeQuery() {
this.queryType = QueryType.UNKNOWN;
}

public static AerospikeQuery parse(String sql) throws SqlParseException {
public static AerospikeQuery parse(String sql, Collection<Object> sqlParameters) throws SqlParseException {
SqlParser parser = SqlParser.create(sql, sqlParserConfig);
SqlNode parsed = parser.parseQuery();
return parsed.accept(new AerospikeSqlVisitor());
return parsed.accept(new AerospikeSqlVisitor(sqlParameters));
}

public String getCatalog() {
Expand Down
26 changes: 22 additions & 4 deletions src/main/java/com/aerospike/jdbc/model/AerospikeSqlVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,30 @@
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.util.SqlVisitor;

import javax.annotation.Nullable;
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Iterator;
import java.util.stream.Collectors;

import static com.aerospike.jdbc.util.Constants.UNSUPPORTED_QUERY_TYPE_MESSAGE;
import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;

public class AerospikeSqlVisitor implements SqlVisitor<AerospikeQuery> {

private static final String QUERY_PLACEHOLDER = "?";

private final AerospikeQuery query;
private final Iterator<Object> sqlParametersIterator;

public AerospikeSqlVisitor() {
this(null);
}

public AerospikeSqlVisitor(@Nullable Collection<Object> sqlParameters) {
query = new AerospikeQuery();
sqlParametersIterator = sqlParameters != null ? sqlParameters.iterator() : null;
}

@Override
Expand All @@ -45,13 +57,13 @@ public AerospikeQuery visit(SqlCall sqlCall) {
SqlUpdate sql = (SqlUpdate) sqlCall;
query.setQueryType(QueryType.UPDATE);
query.setTable(requireNonNull(sql.getTargetTable()).toString());
query.setValues(sql.getSourceExpressionList().stream()
.map(this::parseValue).collect(Collectors.toList()));
if (sql.getCondition() != null) {
query.setPredicate(parseWhere((SqlBasicCall) sql.getCondition()));
}
query.setColumns(sql.getTargetColumnList().stream()
.map(SqlNode::toString).collect(Collectors.toList()));
query.setValues(sql.getSourceExpressionList().stream()
.map(this::parseValue).collect(Collectors.toList()));
} else if (sqlCall instanceof SqlInsert) {
SqlInsert sql = (SqlInsert) sqlCall;
query.setQueryType(QueryType.INSERT);
Expand Down Expand Up @@ -97,8 +109,10 @@ public AerospikeQuery visit(SqlCall sqlCall) {
} else {
throw new UnsupportedOperationException(UNSUPPORTED_QUERY_TYPE_MESSAGE);
}
} catch (UnsupportedOperationException e) {
throw e;
} catch (Exception e) {
throw new UnsupportedOperationException(UNSUPPORTED_QUERY_TYPE_MESSAGE);
throw new UnsupportedOperationException(UNSUPPORTED_QUERY_TYPE_MESSAGE, e);
}
return query;
}
Expand Down Expand Up @@ -142,7 +156,7 @@ private QueryPredicate parseWhere(SqlBasicCall where) {
}
} else if (where.getOperator() instanceof SqlLikeOperator) {
String binName = where.getOperandList().get(0).toString();
String expression = unwrapString(where.getOperandList().get(1).toString());
String expression = parseValue(where.getOperandList().get(1)).toString();
return new QueryPredicateLike(binName, expression);
} else if (where.getOperator() instanceof SqlBetweenOperator) {
return new QueryPredicateRange(
Expand All @@ -168,6 +182,10 @@ private Object parseValue(SqlNode sqlNode) {
}
} else if (sqlNode instanceof SqlIdentifier) {
return unwrapString(sqlNode.toString());
} else if (sqlNode instanceof SqlDynamicParam
&& unwrapString(sqlNode.toString()).equals(QUERY_PLACEHOLDER)) {
checkState(sqlParametersIterator != null, "SQL parameters is null");
return sqlParametersIterator.next();
}
throw new UnsupportedOperationException(UNSUPPORTED_QUERY_TYPE_MESSAGE);
}
Expand Down
25 changes: 21 additions & 4 deletions src/main/java/com/aerospike/jdbc/predicate/QueryPredicateBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,45 @@ protected QueryPredicateBase(
}

protected static Exp.Type getValueType(Object value) {
if (value instanceof String) {
if (value == null) {
return Exp.Type.NIL;
} else if (value instanceof String) {
return Exp.Type.STRING;
} else if (value instanceof Long) {
} else if (value instanceof Long || value instanceof Integer
|| value instanceof Short || value instanceof Byte) {
return Exp.Type.INT;
} else if (value instanceof Double) {
} else if (value instanceof Double || value instanceof Float) {
return Exp.Type.FLOAT;
} else if (value instanceof Boolean) {
return Exp.Type.BOOL;
} else if (value instanceof byte[]) {
return Exp.Type.BLOB;
} else {
return Exp.Type.STRING;
}
}

protected Exp getValueExp(Object value) {
if (value instanceof String) {
if (value == null) {
return Exp.nil();
} else if (value instanceof String) {
return Exp.val((String) value);
} else if (value instanceof Long) {
return Exp.val((long) value);
} else if (value instanceof Integer) {
return Exp.val((int) value);
} else if (value instanceof Short) {
return Exp.val((short) value);
} else if (value instanceof Byte) {
return Exp.val((byte) value);
} else if (value instanceof Double) {
return Exp.val((double) value);
} else if (value instanceof Float) {
return Exp.val((float) value);
} else if (value instanceof Boolean) {
return Exp.val((boolean) value);
} else if (value instanceof byte[]) {
return Exp.val((byte[]) value);
} else {
return Exp.val(value.toString());
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/aerospike/jdbc/util/PreparedStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ public static Iterable<String> splitQueries(String sql) {
}
}

if (currentQuery.length() > 0 && currentQuery.toString().trim().length() > 0) {
if (currentQuery.length() > 0 && !currentQuery.toString().trim().isEmpty()) {
appendNotEmpty(queries, currentQuery.toString());
}

return queries;
}

private static void appendNotEmpty(Collection<String> queries, String query) {
if (query.trim().length() > 0) {
if (!query.trim().isEmpty()) {
queries.add(query);
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/test/java/com/aerospike/jdbc/JdbcBaseTest.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.aerospike.jdbc;

import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;

import java.sql.Connection;
import java.sql.DriverManager;
Expand All @@ -25,7 +25,7 @@ public abstract class JdbcBaseTest {

protected static Connection connection;

@BeforeSuite
@BeforeClass
public static void connectionInit() throws Exception {
logger.info("connectionInit");
Class.forName("com.aerospike.jdbc.AerospikeDriver").newInstance();
Expand All @@ -34,7 +34,7 @@ public static void connectionInit() throws Exception {
connection.setNetworkTimeout(Executors.newSingleThreadExecutor(), 5000);
}

@AfterSuite
@AfterClass
public static void connectionClose() throws SQLException {
logger.info("connectionClose");
connection.close();
Expand Down
Loading
Loading