Table Of Contents

6.9. Java

6.9.1. Introduction

This document is an introduction to the quasardb Java API. It is primarily focused on timeseries, and will guide you through the various ways you can interact with the QuasarDB backend.

Note

If you are looking for a more comprehensive reference, please refer directly to our Javadoc.

6.9.2. Requirements

6.9.3. Adding QuasarDB to your build

QuasarDB’s Maven group ID is net.quasardb and the artifact ID is qdb.

Maven

To add a dependency on the QuasarDB Java API using Maven, use the following:

<dependency>
  <groupId>net.quasardb</groupId>
  <artifactId>qdb</artifactId>
  <version>2.6.0-1</version>
</dependency>

Gradle

To add a dependency using Gradle:

dependencies {
  compile "net.quasardb.qdb:2.6.0-1"
}

Snapshot releases

We continuously release snapshot releases on Sonatype’s OSS repository. To gain access to it, please add Sonatype’s snapshot repository to your build profile. For Maven, this can be achieved by adding the following profile to your settings.xml:

<profile>
  <id>allow-snapshots</id>
    <activation><activeByDefault>true</activeByDefault></activation>
    <repositories>
    <repository>
      <id>snapshots-repo</id>
      <url>https://oss.sonatype.org/content/repositories/snapshots</url>
      <releases><enabled>false</enabled></releases>
      <snapshots><enabled>true</enabled></snapshots>
    </repository>
  </repositories>
</profile>

Please adjust your artifact version accordingly by appending the appropriate -SNAPSHOT qualifier as documented at the official Maven documentation.

6.9.4. Connecting to the database

QuasarDB provides thread-safe access to a cluster using the Session class. This class comes with a built-in, high-performance connection pool that can be shared between multiple threads. You are encourage to reuse this object as often as possible, ideally only creating a single instance during the lifetime of your JVM process.

Establishing a connection

You connect to a QuasarDB cluster by calling the connect function of the Session class and establishing a connection with a QuasarDB cluster like this:

try {
  Session mySession = Session.connect(uri);
} catch (ConnectionRefusedException ex) {
  System.err.println("Failed to connect to " + uri +
                     ", make sure server is running!");
  System.exit(1);
}

Establishing a secure connection

By providing additional SecurityOptions when establishing a connection, we get a secure connection to the cluster:

try {
  Session mySession = Session.connect(new Session.SecurityOptions("userName",
                                                                  "userPrivateKey",
                                                                  "clusterPublicKey"),
                                      uri);
} catch (ConnectionRefusedException ex) {
  System.err.println("Failed to connect to " + uri +
                     ", make sure server is running!");
  System.exit(1);
}

6.9.5. Table management

The Java API exposes its timeseries using the Table class.

Create

You can invoke the create to create a new timeseries table:

Column[] columns = {
  new Column.Double("double_val"),
  new Column.Int64("int_val"),
  new Column.Timestamp("ts_val")
};

Table myTable = Table.create(session, "my_table", columns, 3600000);

The example above will create a table my_table with three different columns with a shard size of 1 hour. You can choose to omit the shard size, in which case the default shard size of 1 day will be chosen. Please refer to the Column class to see a full overiew of the supported column types.

6.9.6. Writing data

When writing data to a Table, QuasarDB maintains a local buffer before writing data. This approach ensures batches of data are written in bulk, minimalising overhead and improving performance.

We provide several mechanisms for you to write data. Which mechanism works best for you depends upon your use case, but when in doubt you should use the AutoFlushWriter.

Note

Individual batches are always written atomically, which means that a buffer is either completely visible to other clients, or not at all.

Explicit flushing

The most basic write access is to make use of a Writer and periodically calling flush on that Writer. You can create a new Writer by calling the writer method of the Table class like this:

Writer w = Table.writer(session, myTable);
for (long i = 0; i < 10000; ++i) {
  w.append(generateRow());
}
w.flush();
w.close(); // call when done

The code above will locally buffer all 10,000 rows before writing them all in a single, atomic batch operation when flush is called. Naturally, these rows will not be visible to any other client until the flush operation completes.

Implicit flushing

If all you care about is that the buffer is flushed periodically every N rows, we provide an AutoFlushWriter which you can create by calling the autoFlushWriter method of the Table class like this:

Writer w = Table.autoFlushWriter(session, myTable);
for (long i = 0; i < 75000; ++i) {
  w.append(generateRow());
}
w.flush(); // otherwise some data might not be fully flushed!
w.close();

The code above initialises an AutoFlushWriter with default arguments. By default, this means 50,000 rows. If you would like to excercise more control over flush interval behaviour, you can customise the flush interval like this:

Writer w = Table.autoFlushWriter(session, myTable, 1);
for (long i = 0; i < 1000; ++i) {
  w.append(generateRow());
}
// flush not necessary in this case!

As a means of example, the code above will flush the buffer every 1 rows (i.e. every write is a flush). In practice, we recommend you to use as high a number as possible that works for your use case.

6.9.7. Reading data

The Java API provides access to both a bulk Reader class which should be used for large table scans, and a Reader class which can be used for more refined querying.

Reader

Assuming you already have a reference to a Reader, you can scan this table as follows:

Reader r = Table.reader(session, myTable, myTimeRange);
while (r.hasNext() == true) {
  Row row = r.next();
  System.out.println(row.toString());
}

As you can see above, the Reader exposes a simple Iterator interface that allows you to iterate over Row objects. When you prefer a more functional-style, we also expose the underlying dataset as a Java8 stream:

Table
  .reader(session, t, myTimeRange)
  .stream()
  .parallel()
  .filter(myClass::isValid)
  .forEach(System.out::println);

Query

Note

For more information about the query language itself, see our Queries documentation.

For more ad-hoc analysis and aggregations, you can use our Query class:

Result r = Query.of("select double_val from "  + myTable.getName() + " in range(now, +1h)")
                .execute(session);
for (Result.Table t : r.tables) {
  System.out.println("has table with results: " + t.toString());
}

And the Query API also provides Stream-based access to the Result set:

Query.of("select double_val from "  + myTable.getName() + " in range(now, +1h)")
  .execute(session)
  .parallel()
  .filter(myClass::isValid)
  .forEach(System.out::println);

The code above will query the double_val column from your time range, and return the entire Result object. We also suggest you explore our Javadoc to see a more comprehensive overview on how to inspect the Result object.

6.9.8. Reference

This chapter contains a short summary of our Java API. For more a complete reference, please see our Javadoc.

class net::quasardb::qdb::Session::SecurityOptions

Optional configuration for establishing a secure connection.

Inherits from Serializable

Public Functions

net.quasardb.qdb.Session.SecurityOptions.SecurityOptions(String userName, String userPrivateKey, String clusterPublicKey)

Parameters
  • userName: Username to use when authenticating to the cluster.
  • userPrivateKey: Private key of the user.
  • clusterPublicKey: Public key of the cluster.

class net::quasardb::qdb::Session

Represents a connection with the QuasarDB cluster. This class is backed by a connection pool, and is thread-safe. You are encouraged to reuse this object as much as possible, ideally only creating a single session for the lifetime of your process.

Public Static Functions

static Session net.quasardb.qdb.Session.connect(String uri)

Establishes a connection

Return
A QuasarDB session
Parameters
  • uri: Fully qualified quasardb cluster uri, e.g. qdb://127.0.0.1:2836

static Session net.quasardb.qdb.Session.connect(SecurityOptions options, String uri)

Establishes a secure connection

Return
A secure QuasarDB session
Parameters
  • options: Security options for authenticating with cluster
  • uri: Fully qualified quasardb cluster uri, e.g. qdb://127.0.0.1:2836

class net::quasardb::qdb::ts::Table

Represents a timeseries Table. Typically you do not have to initialise this class directly, but instead initialise another component that operates on top of this table using writer, autoFlushWriter or reader.

Inherits from Serializable

Public Functions

String net.quasardb.qdb.ts.Table.getName()

Returns the timeseries table name.

Column [] net.quasardb.qdb.ts.Table.getColumns()

Returns column representation of this table.

int net.quasardb.qdb.ts.Table.columnIndexById(String id)

Utility function that looks up a column’s index by its id. The first column starts with 0.

Return
The index of the column inside the timeseries table definition.
Parameters
  • id: String identifier of the column.

Public Static Functions

static Table net.quasardb.qdb.ts.Table.create(Session session, String name, Column [] columns)

Create new timeseries table with a default shard size.

Return
Reference to the newly created timeseries table.
Parameters
  • session: Active session with the QuasarDB cluster.
  • name: Unique identifier for this timeseries table.
  • columns: Column definitions of this table. The ordering of the array will persist through the table definition and cannot be changed after creation.

static Table net.quasardb.qdb.ts.Table.create(Session session, String name, Column [] columns, long shardSize)

Create new timeseries table.

Return
Reference to the newly created timeseries table.
Parameters
  • session: Active session with the QuasarDB cluster.
  • name: Unique identifier for this timeseries table.
  • columns: Column definitions of this table. The ordering of the array will persist through the table definition and cannot be changed after creation.
  • shardSize: The size of the shards in ms.

static Writer net.quasardb.qdb.ts.Table.writer(Session session, String name)

Initializes new writer for a timeseries table.

Parameters
  • session: Active session with the QuasarDB cluster.
  • name: Timeseries table name. Must already exist.

static Writer net.quasardb.qdb.ts.Table.writer(Session session, Table table)

Initializes new writer for a timeseries table.

Parameters
  • session: Active session with the QuasarDB cluster.
  • table: Timeseries table.

static AutoFlushWriter net.quasardb.qdb.ts.Table.autoFlushWriter(Session session, String name)

Initializes new writer for a timeseries table that periodically flushes its local cache.

Parameters
  • session: Active session with the QuasarDB cluster.
  • name: Timeseries table name. Must already exist.

static AutoFlushWriter net.quasardb.qdb.ts.Table.autoFlushWriter(Session session, Table table)

Initializes new writer for a timeseries table that periodically flushes its local cache.

Parameters
  • session: Active session with the QuasarDB cluster.
  • table: Timeseries table.

static AutoFlushWriter net.quasardb.qdb.ts.Table.autoFlushWriter(Session session, String name, long threshold)

Initializes new writer for a timeseries table that periodically flushes its local cache.

Parameters
  • session: Active session with the QuasarDB cluster.
  • name: Timeseries table name. Must already exist.
  • threshold: The amount of rows to keep in local buffer before automatic flushing occurs.

static AutoFlushWriter net.quasardb.qdb.ts.Table.autoFlushWriter(Session session, Table table, long threshold)

Initializes new writer for a timeseries table that periodically flushes its local cache.

Parameters
  • session: Active session with the QuasarDB cluster.
  • table: Timeseries table.
  • threshold: The amount of rows to keep in local buffer before automatic flushing occurs.

static Reader net.quasardb.qdb.ts.Table.reader(Session session, String name, TimeRange [] ranges)

Initializes new reader for a timeseries table.

Parameters
  • session: Active session with the QuasarDB cluster.
  • name: Timeseries table name. Must already exist.
  • ranges: Time ranges to look for.

static Reader net.quasardb.qdb.ts.Table.reader(Session session, Table table, TimeRange [] ranges)

Initializes new reader for a timeseries table.

Parameters
  • session: Active session with the QuasarDB cluster.
  • table: Timeseries table.
  • ranges: Time time ranges to look for.

class net::quasardb::qdb::ts::Column

Holds information about a single column.

Subclassed by net.quasardb.qdb.ts.Column.Blob, net.quasardb.qdb.ts.Column.Double, net.quasardb.qdb.ts.Column.Int64, net.quasardb.qdb.ts.Column.Timestamp

Public Functions

net.quasardb.qdb.ts.Column.Column(String name, Value.Type type)

Create a column with a certain type.

String net.quasardb.qdb.ts.Column.getName()

Provides access to the column’s name.

Value.Type net.quasardb.qdb.ts.Column.getType()

Provides access to the column’s type.

class Blob

A blob column.

Inherits from net.quasardb.qdb.ts.Column

class Double

A double precision column.

Inherits from net.quasardb.qdb.ts.Column

class Int64

A 64 bit integer column.

Inherits from net.quasardb.qdb.ts.Column

class Timestamp

A timestamp column.

Inherits from net.quasardb.qdb.ts.Column

class net::quasardb::qdb::ts::Writer

High-performance bulk writer for a QuasarDB timeseries table.

Do not construct this class directly, but rather using Table#writer.

Inherits from AutoCloseable, Flushable

Subclassed by net.quasardb.qdb.ts.AutoFlushWriter

Public Functions

Table net.quasardb.qdb.ts.Writer.getTable()

Returns the underlying table that is being written to.

void net.quasardb.qdb.ts.Writer.close()

Closes the timeseries table and local cache so that memory can be reclaimed. Flushes all remaining output.

void net.quasardb.qdb.ts.Writer.flush()

Flush current local cache to server.

void net.quasardb.qdb.ts.Writer.append(Row row)

Append a new row to the local table cache. Should be periodically flushed, unless an AutoFlushWriter is used.

See
flush
See
Table::autoFlushWriter

void net.quasardb.qdb.ts.Writer.append(Timespec timestamp, Value [] value)

Append a new row to the local table cache. Should be periodically flushed, unless an AutoFlushWriter is used.

See
flush
See
Table::autoFlushWriter

void net.quasardb.qdb.ts.Writer.append(LocalDateTime timestamp, Value [] value)

Append a new row to the local table cache. Should be periodically flushed, unless an AutoFlushWriter is used.

See
flush
See
Table::autoFlushWriter

void net.quasardb.qdb.ts.Writer.append(Timestamp timestamp, Value [] value)

Append a new row to the local table cache. Should be periodically flushed, unless an AutoFlushWriter is used.

See
flush
See
Table::autoFlushWriter

class net::quasardb::qdb::ts::AutoFlushWriter

An implementation of a Writer that automatically flushes the local cache when a certain threshold has been reached.

Inherits from net.quasardb.qdb.ts.Writer

class net::quasardb::qdb::ts::Reader

High-performance bulk reader for a QuasarDB timeseries table. This class follows the general Iterator pattern, and allows you to scan entire timeseries tables in bulk.

Inherits from AutoCloseable, Iterator< Row >

Public Functions

Table net.quasardb.qdb.ts.Reader.getTable()

Return
The underlying table that is being written to.

void net.quasardb.qdb.ts.Reader.close()

Closes the timeseries table and local cache so that memory can be reclaimed.

boolean net.quasardb.qdb.ts.Reader.hasNext()

Check whether there is another row available for reading or not. When this function returns true, it is safe to call next.

Return
Returns true when another row is available for reading.

Row net.quasardb.qdb.ts.Reader.next()

Modifies internal state to move forward to the next row. Make sure to check whether it is safe to read the next row using hasNext.

Return
The next row.
Exceptions
  • InvalidIteratorException: Thrown when the iterator has reached the end and no next row is available.

Stream<Row> net.quasardb.qdb.ts.Reader.stream()

Provides stream-based access.

class net::quasardb::qdb::ts::Query

Represents a timeseries query.

Use this class directly if you’re planning on writing complex, custom queries. If your queries are relatively simple, consider using the QueryBuilder instead.

See
QueryBuilder

Public Static Functions

static Query net.quasardb.qdb.ts.Query.create()

Creates a new, empty query instance.

static Query net.quasardb.qdb.ts.Query.of(String query)

Returns new Query instance based on a string.

Parameters
  • query: The query string to execute. Refer to the QuasarDB documentation for the full query syntax.

class net::quasardb::qdb::ts::TimeRange

Inherits from Serializable

Public Functions

TimeRange net.quasardb.qdb.ts.TimeRange.withBegin(Timespec b)

Returns a copy of this timerange with a different begin.

TimeRange net.quasardb.qdb.ts.TimeRange.withEnd(Timespec e)

Returns a copy of this timerange with a different end.

class net::quasardb::qdb::ts::Row

Represents a timeseries row.

Inherits from Serializable

class net::quasardb::qdb::ts::Value

Represents a timeseries table.

Inherits from Serializable

Public Functions

void net.quasardb.qdb.ts.Value.setNull()

Updates value to represent an unintialised value.

void net.quasardb.qdb.ts.Value.setInt64(long value)

Updates value to take a certain long integer value;

void net.quasardb.qdb.ts.Value.setDouble(double value)

Updates value to take a certain double value;

void net.quasardb.qdb.ts.Value.setTimestamp(Timespec value)

Updates value to take a certain long integer value;

void net.quasardb.qdb.ts.Value.setBlob(byte[] value)

Updates value to take a certain blob value. Warning: assumes byte array will stay in memory for as long as this object lives.

void net.quasardb.qdb.ts.Value.setBlob(ByteBuffer value)

Updates value to take a certain blob value;

Public Static Functions

static Value net.quasardb.qdb.ts.Value.createNull()

Create a null / empty value.

static Value net.quasardb.qdb.ts.Value.createInt64(long value)

Represents a long integer

static Value net.quasardb.qdb.ts.Value.createDouble(double value)

Represents a double value.

static Value net.quasardb.qdb.ts.Value.createTimestamp(Timespec value)

Represents a long integer

static Value net.quasardb.qdb.ts.Value.createBlob(byte[] value)

Represents a blob value. Warning: assumes byte array will stay in memory for as long as this object lives.

static Value net.quasardb.qdb.ts.Value.createSafeBlob(byte[] value)

Represents a safe blob value that copies the byte array.

class net::quasardb::qdb::ts::Result

The result of a Query

Public Functions

net.quasardb.qdb.ts.Result.Result()

Create a new empty result.

net.quasardb.qdb.ts.Result.Result(Table[] tables)

Create a new result from result tables.

Parameters
  • tables: An array of tables that the Result describes.

String net.quasardb.qdb.ts.Result.toString()

Access to a String representation of this Result.

Stream<Row> net.quasardb.qdb.ts.Result.stream()

Provides stream-based access.

Public Members

Table [] net.quasardb.qdb.ts.Result.tables

The tables that are part of the Query result. A single Query can return multiple tables.

class Row

Represents a single Result row.

Public Members

String net.quasardb.qdb.ts.Result.Row.tableName

The name of the table the Row is from.

String [] net.quasardb.qdb.ts.Result.Row.columns

The column identifiers of the Table the Row is from.

Value [] net.quasardb.qdb.ts.Result.Row.values

The values of this row. Contains exactly one value per column.

class Table

Represents a Table that is part of the Query result.

Public Functions

Row [] net.quasardb.qdb.ts.Result.Table.flatten()

Flattens this Table by coercing the columns/values into Rows.

Public Members

String net.quasardb.qdb.ts.Result.Table.name

The name of this table.

String [] net.quasardb.qdb.ts.Result.Table.columns

The columns identifiers of this Table.

Value [][] net.quasardb.qdb.ts.Result.Table.rows

A array of all rows. Contains exactly one value per column.

arrow_backPrevious
6.8. Hadoop integration
Next arrow_forward
6.10. Java (Legacy API)