Skip to content

Commit

Permalink
Merge pull request #13 from aerospike/develop
Browse files Browse the repository at this point in the history
v1.6.0
  • Loading branch information
reugn authored May 17, 2022
2 parents c75bff7 + 86af9f9 commit 5584ff7
Show file tree
Hide file tree
Showing 57 changed files with 1,988 additions and 1,962 deletions.
80 changes: 77 additions & 3 deletions docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@ created upon insertion of a new row.
For more on the [Aerospike data model](https://www.aerospike.com/docs/architecture/data-model.html)
see the Aerospike documentation.

### Table and column naming
You should be aware of the [known limitations](https://docs.aerospike.com/guide/limitations)
on table (set) and column (bin) names in Aerospike.

> Names can include only Latin lowercase and uppercase letters with no diacritical marks (a-z, A-Z), digits 0-9, underscores (_), hyphens (-), and dollar signs ($). This naming guideline is not enforced; however, if you do not follow it, some Aerospike features and tools might not function properly.
Table names are limited to 63 characters and column names to 15 characters.

In the JDBC driver it is recommended that you use quotes around table names. For
example

```sql
SELECT * FROM "top-users";
```

## INSERT

Let's add some rows with explicit primary keys:
Expand All @@ -49,8 +64,11 @@ INSERT INTO port_list (__key, port, description) VALUES ("ror", 3000, "Ruby on R
INSERT INTO port_list (__key, port, description) VALUES ("dis", 3000, "Distributed Interactive Simulation (DIS)");
INSERT INTO port_list (__key, port, description) VALUES ("fcip", 3225, "Fibre Channel over IP (FCIP)");
INSERT INTO port_list (__key, port, description) VALUES ("metasys", 11001, "Johnson Controls Metasys java AC control environment");
INSERT INTO port_list (__key, port, description) VALUES ("memcache", 11211, "Memcached");
INSERT INTO port_list (__key, port, description) VALUES ("battlefield2", 16567, "Battlefield 2");
```

Multiple rows can be inserted at once:
```sql
INSERT INTO port_list (__key, port, description) VALUES ("memcache", 11211, "Memcached"), ("battlefield2", 16567, "Battlefield 2");
```

As an Aerospike row (_record_) must have a primary key, if none is provided
Expand Down Expand Up @@ -98,6 +116,18 @@ __key |description|port |
--------|-----------|-----|
memcache|Memcached |11211|

Batch query for rows in a list of primary keys:

```sql
SELECT * FROM port_list WHERE __key IN ("ntp", "ror");
```

__key|description |extra|port|
-----|---------------------------------------------------|-----|----|
ror |Ruby on Rails development default | |3000|
ntp |Network Time Protocol used for time synchronization| | 123|


### Multiple predicates
Query for rows that satisfy a `WHERE` with more than one predicate

Expand Down Expand Up @@ -128,11 +158,42 @@ cloud9ide|Cloud9 IDE Server |3000|
dis |Distributed Interactive Simulation (DIS)|3000|
ror |Ruby on Rails development default |3000|

Range queries are done using `BETWEEN`.

```sql
SELECT * FROM port_list WHERE port BETWEEN 100 AND 200;
```

__key |description |port|
--------|---------------------------------------------------|----|
snmp |Simple Network Management Protocol (SNMP) | 161|
snmptrap|Simple Network Management Protocol Trap(SNMPTRAP) | 162|
ntp |Network Time Protocol used for time synchronization| 123|

### Secondary Indexes

[Secondary indexes](https://docs.aerospike.com/server/guide/queries)
can be [optionally added](https://docs.aerospike.com/tools/asadm/user_guide/live_cluster_mode_guide#secondary-indexes-1)
to accelerate `BETWEEN` range queries on integer values or equality predicates
on integer or string values. The JDBC driver will create an SI query if a
secondary index is available.

You can use asadm to [add a secondary index](https://docs.aerospike.com/tools/asadm/user_guide/live_cluster_mode_guide#secondary-indexes-1).
```
Admin> enable
Admin+> manage sindex create numeric port-idx ns test set port_list bin port
Admin+> show sindex
~~~~~~Secondary Indexes (2022-05-17 07:12:58 UTC)~~~~~~
Index|Namespace| Set| Bin| Bin| Index|State
Name| | | | Type| Type|
port-idx|test |port_list|port|NUMERIC|DEFAULT|RW
```

## Aggregate functions
Count the records in the table that don't use port 3000:

```sql
SELECT COUNT(*) FROM port_list WHERE port != 3000;
SELECT COUNT(*) FROM port_list WHERE port <> 3000;
```

COUNT(*)|
Expand Down Expand Up @@ -187,6 +248,19 @@ snmptrap |Simple Network Management Protocol Trap(SNMPTRAP) | 1| 162|
Since Aerospike is schemaless, the data browser may need to be refreshed for it
to pick up the new _extra_ column.

Aerospike columns (bins) can be dropped by assinging a `NULL` to them.

```sql
UPDATE port_list SET extra=NULL;
SELECT * FROM port_list WHERE port < 200;
```

__key |description |port|
--------|---------------------------------------------------|----|
ntp |Network Time Protocol used for time synchronization| 123|
snmp |Simple Network Management Protocol (SNMP) | 161|
snmptrap|Simple Network Management Protocol Trap(SNMPTRAP) | 162|

## DELETE

Delete rows that match a WHERE condition on a regular column (a bin):
Expand Down
34 changes: 25 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<name>aerospike-jdbc</name>
<description>A JDBC driver for the Aerospike database</description>
<url>https://github.com/aerospike/aerospike-jdbc</url>
<version>1.5.0</version>
<version>1.6.0</version>

<properties>
<skipTests>false</skipTests>
Expand All @@ -25,10 +25,10 @@
<maven-gpg-plugin.version>1.5</maven-gpg-plugin.version>
<maven-shade-plugin.version>3.1.1</maven-shade-plugin.version>

<aerospike-client.version>5.1.11</aerospike-client.version>
<netty.version>4.1.72.Final</netty.version>
<jackson.version>2.13.1</jackson.version>
<trino-parser.version>362</trino-parser.version>
<aerospike-client.version>6.0.0</aerospike-client.version>
<netty.version>4.1.77.Final</netty.version>
<jackson.version>2.13.3</jackson.version>
<calcite.version>1.30.0</calcite.version>
<httpclient.version>4.5.13</httpclient.version>
</properties>

Expand Down Expand Up @@ -100,9 +100,14 @@
</dependency>

<dependency>
<groupId>io.trino</groupId>
<artifactId>trino-parser</artifactId>
<version>${trino-parser.version}</version>
<groupId>org.apache.calcite</groupId>
<artifactId>calcite-core</artifactId>
<version>${calcite.version}</version>
</dependency>
<dependency>
<groupId>org.apache.calcite</groupId>
<artifactId>calcite-server</artifactId>
<version>${calcite.version}</version>
</dependency>

<dependency>
Expand All @@ -129,7 +134,7 @@
<dependency>
<groupId>org.jdbi</groupId>
<artifactId>jdbi3-core</artifactId>
<version>3.27.1</version>
<version>3.28.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Expand Down Expand Up @@ -215,6 +220,17 @@
</executions>
<configuration>
<finalName>uber-${artifactId}-${version}</finalName>
<minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</plugin>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1278,7 +1278,7 @@ private int ordinal(ResultSetMetaData md, String columnName) {
private ResultSetMetaData getMetadata(String namespace, String table) {
try {
return connection.createStatement().executeQuery(format(
"select * from %s.%s limit %d", namespace, table, schemaScanRecords)).getMetaData();
"select * from \"%s.%s\" limit %d", namespace, table, schemaScanRecords)).getMetaData();
} catch (SQLException e) {
logger.severe(String.format("Exception in getMetadata, namespace: %s, table: %s",
namespace, table));
Expand Down
23 changes: 12 additions & 11 deletions src/main/java/com/aerospike/jdbc/AerospikePreparedStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@
import com.aerospike.client.Value;
import com.aerospike.jdbc.model.AerospikeQuery;
import com.aerospike.jdbc.model.DataColumn;
import com.aerospike.jdbc.query.AerospikeQueryParser;
import com.aerospike.jdbc.schema.AerospikeSchemaBuilder;
import com.aerospike.jdbc.sql.AerospikeResultSetMetaData;
import com.aerospike.jdbc.sql.SimpleParameterMetaData;
import com.aerospike.jdbc.sql.type.ByteArrayBlob;
import com.aerospike.jdbc.sql.type.StringClob;
import com.aerospike.jdbc.util.IOUtils;
import io.trino.sql.parser.ParsingOptions;
import org.apache.calcite.sql.parser.SqlParseException;

import java.io.DataInputStream;
import java.io.EOFException;
Expand All @@ -28,8 +27,8 @@
import java.util.Optional;
import java.util.logging.Logger;

import static com.aerospike.jdbc.util.Constants.unsupportedException;
import static com.aerospike.jdbc.util.PreparedStatement.parseParameters;
import static io.trino.sql.parser.ParsingOptions.DecimalLiteralTreatment.AS_DOUBLE;
import static java.lang.String.format;

public class AerospikePreparedStatement extends AerospikeStatement implements PreparedStatement {
Expand All @@ -44,23 +43,25 @@ public class AerospikePreparedStatement extends AerospikeStatement implements Pr
public AerospikePreparedStatement(IAerospikeClient client, Connection connection, String sql) {
super(client, connection);
this.sql = sql;
int n = parseParameters(sql, 0).getValue();
parameterValues = new Object[n];
int params = parseParameters(sql, 0).getValue();
parameterValues = new Object[params];
Arrays.fill(parameterValues, Optional.empty());
ParsingOptions parsingOptions = new ParsingOptions(AS_DOUBLE);
io.trino.sql.tree.Statement statement = SQL_PARSER.createStatement(sql, parsingOptions);
query = AerospikeQueryParser.parseSql(statement);
try {
query = AerospikeQuery.parse(sql);
} catch (SqlParseException e) {
throw unsupportedException;
}
columns = AerospikeSchemaBuilder.getSchema(query.getSchemaTable(), client);
}

@Override
public ResultSet executeQuery() {
public ResultSet executeQuery() throws SQLException {
logger.info("AerospikePreparedStatement executeQuery");
return super.executeQuery(sql);
}

@Override
public int executeUpdate() {
public int executeUpdate() throws SQLException {
logger.info("AerospikePreparedStatement executeUpdate");
return super.executeUpdate(sql);
}
Expand Down Expand Up @@ -176,7 +177,7 @@ public void setObject(int parameterIndex, Object x) throws SQLException {
}

@Override
public boolean execute() {
public boolean execute() throws SQLException {
String preparedQuery = prepareQuery();
logger.info(preparedQuery);
return execute(preparedQuery);
Expand Down
30 changes: 13 additions & 17 deletions src/main/java/com/aerospike/jdbc/AerospikeStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
import com.aerospike.client.IAerospikeClient;
import com.aerospike.jdbc.model.AerospikeQuery;
import com.aerospike.jdbc.model.Pair;
import com.aerospike.jdbc.query.AerospikeQueryParser;
import com.aerospike.jdbc.query.QueryPerformer;
import com.aerospike.jdbc.sql.SimpleWrapper;
import com.aerospike.jdbc.util.AuxStatementParser;
import io.trino.sql.parser.ParsingOptions;
import io.trino.sql.parser.SqlParser;
import org.apache.calcite.sql.parser.SqlParseException;

import java.sql.Connection;
import java.sql.ResultSet;
Expand All @@ -18,17 +16,13 @@
import java.sql.Statement;
import java.util.logging.Logger;

import static io.trino.sql.parser.ParsingOptions.DecimalLiteralTreatment.AS_DOUBLE;
import static java.lang.String.format;
import static java.sql.ResultSet.*;

public class AerospikeStatement implements Statement, SimpleWrapper {

private static final Logger logger = Logger.getLogger(AerospikeStatement.class.getName());

public static final SqlParser SQL_PARSER = new SqlParser();
public static final ParsingOptions parsingOptions = new ParsingOptions(AS_DOUBLE);

protected final IAerospikeClient client;
private final Connection connection;
private int maxRows = Integer.MAX_VALUE;
Expand All @@ -48,7 +42,7 @@ public AerospikeStatement(IAerospikeClient client, Connection connection) {
}

@Override
public ResultSet executeQuery(String sql) {
public ResultSet executeQuery(String sql) throws SQLException {
logger.info("executeQuery: " + sql);
AerospikeQuery query = parseQuery(sql);

Expand All @@ -59,20 +53,22 @@ public ResultSet executeQuery(String sql) {
return resultSet;
}

private AerospikeQuery parseQuery(String sql) {
final String sqlEscape = sql.replaceAll("\n", " ");
AerospikeQuery query = AuxStatementParser.hack(sqlEscape).orElseGet(() -> {
io.trino.sql.tree.Statement statement = SQL_PARSER.createStatement(sqlEscape, parsingOptions);
return AerospikeQueryParser.parseSql(statement);
});
private AerospikeQuery parseQuery(String sql) throws SQLException {
sql = sql.replaceAll("\n", " ");
AerospikeQuery query;
try {
query = AerospikeQuery.parse(sql);
} catch (SqlParseException e) {
query = AuxStatementParser.hack(sql);
}
if (query.getSchema() == null) {
query.setSchema(schema);
}
return query;
}

@Override
public int executeUpdate(String sql) {
public int executeUpdate(String sql) throws SQLException {
executeQuery(sql);
return updateCount;
}
Expand Down Expand Up @@ -129,7 +125,7 @@ public SQLWarning getWarnings() {

@Override
public void clearWarnings() {
// TODO make use of warnings
// TODO: make use of warnings
}

@Override
Expand All @@ -138,7 +134,7 @@ public void setCursorName(String name) throws SQLException {
}

@Override
public boolean execute(String sql) {
public boolean execute(String sql) throws SQLException {
resultSet = executeQuery(sql);
return true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.aerospike.jdbc.scan;
package com.aerospike.jdbc.async;

import com.aerospike.client.async.EventLoop;
import com.aerospike.client.async.EventLoops;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.aerospike.jdbc.async;

import com.aerospike.client.AerospikeException;
import com.aerospike.client.BatchRecord;
import com.aerospike.client.listener.BatchOperateListListener;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;

public class FutureBatchOperateListListener implements BatchOperateListListener {

private final CompletableFuture<Integer> totalFuture = new CompletableFuture<>();

@Override
public void onSuccess(List<BatchRecord> list, boolean b) {
totalFuture.complete((int) list.stream().filter(Objects::nonNull).count());
}

@Override
public void onFailure(AerospikeException e) {
totalFuture.completeExceptionally(e);
}

public Future<Integer> getTotal() {
return totalFuture;
}
}
Loading

0 comments on commit 5584ff7

Please sign in to comment.