NAME

Net::Async::CassandraCQL - use Cassandra databases with IO::Async using CQL

SYNOPSIS

use IO::Async::Loop;
use Net::Async::CassandraCQL;
use Protocol::CassandraCQL qw( CONSISTENCY_QUORUM );

my $loop = IO::Async::Loop->new;

my $cass = Net::Async::CassandraCQL->new(
   host => "localhost",
   keyspace => "my-keyspace",
   default_consistency => CONSISTENCY_QUORUM,
);
$loop->add( $cass );


$cass->connect->get;


my @f;
foreach my $number ( 1 .. 100 ) {
   push @f, $cass->query( "INSERT INTO numbers (v) VALUES $number" );
}
Future->needs_all( @f )->get;


my $get_stmt = $cass->prepare( "SELECT v FROM numbers" )->get;

my ( undef, $result ) = $get_stmt->execute( [] )->get;

foreach my $row ( $result->rows_hash ) {
   say "We have a number " . $row->{v};
}

DESCRIPTION

This module allows use of the CQL3 interface of a Cassandra database. It fully supports asynchronous operation via IO::Async, allowing both direct queries and prepared statements to be managed concurrently, if required. Alternatively, as the interface is entirely based on Future objects, it can be operated synchronously in a blocking fashion by simply awaiting each individual operation by calling the get method.

It is based on Protocol::CassandraCQL, which more completely documents the behaviours and limits of its ability to communicate with Cassandra.

PARAMETERS

The following named parameters may be passed to new or configure:

host => STRING

The hostname of the Cassandra node to connect to

service => STRING

Optional. The service name or port number to connect to.

keyspace => STRING

Optional. If set, a USE keyspace query will be issued as part of the connect method.

default_consistency => INT

Optional. Default consistency level to use if none is provided to query or execute.

METHODS

$str = $cass->quote( $str )

Quotes a string argument suitable for inclusion in an immediate CQL query string.

In general, it is better to use a prepared query and pass the value as an execute parameter though.

$str = $cass->quote_identifier( $str )

Quotes an identifier name suitable for inclusion in a CQL query string.

$f = $cass->connect( %args )

Connects to the Cassandra node an send the OPCODE_STARTUP message. The returned Future will yield nothing on success.

Takes the following named arguments:

host => STRING
service => STRING
keyspace => STRING

Optional. Overrides the configured values.

A host name is required, either as a named argument or as a configured value on the object. If the service name is missing, the default CQL port will be used instead.

$f = $cass->send_message( $opcode, $frame )

Sends a message with the given opcode and Protocol::CassandraCQL::Frame for the message body. The returned Future will yield the response opcode and frame.

( $reply_opcode, $reply_frame ) = $f->get

This is a low-level method; applications should instead use one of the wrapper methods below.

$f = $cass->startup

Sends the initial connection setup message. On success, the returned Future yields nothing.

Normally this is not required as the connect method performs it implicitly.

$f = $cass->options

Requests the list of supported options from the server node. On success, the returned Future yields a HASH reference mapping option names to ARRAY references containing valid values.

$f = $cass->query( $cql, $consistency )

Performs a CQL query. On success, the values returned from the Future will depend on the type of query.

( $type, $result ) = $f->get

For USE queries, the type is keyspace and $result is a string giving the name of the new keyspace.

For CREATE, ALTER and DROP queries, the type is schema_change and $result is a 3-element ARRAY reference containing the type of change, the keyspace and the table name.

For SELECT queries, the type is rows and $result is an instance of Protocol::CassandraCQL::Result containing the returned row data.

For other queries, such as INSERT, UPDATE and DELETE, the future returns nothing.

$f = $cass->query_rows( $cql, $consistency )

A shortcut wrapper for query which expects a rows result and returns it directly. Any other result is treated as an error. The returned Future returns a Protocol::CassandraCQL::Result directly

$result = $f->get

$f = $cass->prepare( $cql )

Prepares a CQL query for later execution. On success, the returned Future yields an instance of a prepared query object (see below).

( $query ) = $f->get

$f = $cass->execute( $id, $data, $consistency )

Executes a previously-prepared statement, given its ID and the binding data. On success, the returned Future will yield results of the same form as the query method. $data should contain a list of encoded byte-string values.

Normally this method is not directly required - instead, use the execute method on the query object itself, as this will encode the parameters correctly.

CONVENIENT WRAPPERS

The following wrapper methods all wrap the basic query operation.

$f = $cass->use_keyspace( $keyspace )

A convenient shortcut to the USE $keyspace query which escapes the keyspace name.

$f = $cass->schema_keyspaces

A shortcut to a SELECT query on system.schema_keyspaces, which returns a result object listing all the keyspaces.

( $result ) = $f->get

Exact details of the returned columns will depend on the Cassandra version, but the result should at least be keyed by the first column, called keyspace_name.

my $keyspaces = $result->rowmap_hash( "keyspace_name" )

$f = $cass->schema_columnfamilies( $keyspace )

A shortcut to a SELECT query on system.schema_columnfamilies, which returns a result object listing all the columnfamilies of the given keyspace.

( $result ) = $f->get

Exact details of the returned columns will depend on the Cassandra version, but the result should at least be keyed by the first column, called columnfamily_name.

my $columnfamilies = $result->rowmap_hash( "columnfamily_name" )

$f = $cass->schema_columns( $keyspace, $columnfamily )

A shortcut to a SELECT query on system.schema_columns, which returns a result object listing all the columns of the given columnfamily.

( $result ) = $f->get

Exact details of the returned columns will depend on the Cassandra version, but the result should at least be keyed by the first column, called column_name.

my $columns = $result->rowmap_hash( "column_name" )

TODO

  • Handle OPCODE_AUTHENTICATE and OPCODE_REGISTER

  • Support frame compression

  • Allow storing multiple Cassandra node hostnames and perform some kind of balancing or failover of connections.

SPONSORS

This code was paid for by

AUTHOR

Paul Evans <leonerd@leonerd.org.uk>