1NAME 2 `Net::Async::CassandraCQL' - use Cassandra databases with IO::Async 3 using CQL 4 5SYNOPSIS 6 use IO::Async::Loop; 7 use Net::Async::CassandraCQL; 8 use Protocol::CassandraCQL qw( CONSISTENCY_QUORUM ); 9 10 my $loop = IO::Async::Loop->new; 11 12 my $cass = Net::Async::CassandraCQL->new( 13 host => "localhost", 14 keyspace => "my-keyspace", 15 default_consistency => CONSISTENCY_QUORUM, 16 ); 17 $loop->add( $cass ); 18 19 $cass->connect->get; 20 21 my @f; 22 foreach my $number ( 1 .. 100 ) { 23 push @f, $cass->query( "INSERT INTO numbers (v) VALUES $number" ); 24 } 25 Future->needs_all( @f )->get; 26 27 my $get_stmt = $cass->prepare( "SELECT v FROM numbers" )->get; 28 29 my ( undef, $result ) = $get_stmt->execute( [] )->get; 30 31 foreach my $row ( $result->rows_hash ) { 32 say "We have a number " . $row->{v}; 33 } 34 35DESCRIPTION 36 This module allows use of the `CQL3' interface of a Cassandra database. 37 It fully supports asynchronous operation via IO::Async, allowing both 38 direct queries and prepared statements to be managed concurrently, if 39 required. Alternatively, as the interface is entirely based on Future 40 objects, it can be operated synchronously in a blocking fashion by 41 simply awaiting each individual operation by calling the `get' method. 42 43 It is based on Protocol::CassandraCQL, which more completely documents 44 the behaviours and limits of its ability to communicate with Cassandra. 45 46EVENTS 47 on_node_up $nodeid 48 on_node_down $nodeid 49 The node's status has changed. `$nodeid' is the node's IP address as a 50 text string. 51 52 on_node_new $nodeid 53 on_node_removed $nodeid 54 A new node has been added to the cluster, or an existing node has been 55 decommissioned and removed. 56 57 These four events are obtained from event watches on the actual node 58 connections and filtered to remove duplicates. The use of multiple 59 primaries should improve the reliability of notifications, though if 60 multiple nodes fail at or around the same time this may go unreported, 61 as no node will ever report its own failure. 62 63PARAMETERS 64 The following named parameters may be passed to `new' or `configure': 65 66 host => STRING 67 hosts => ARRAY of STRING 68 The hostnames of Cassandra node to connect to initially. If more 69 than one host is provided in an array, they will be attempted 70 sequentially until one succeeds during the intial connect phase. 71 72 service => STRING 73 Optional. The service name or port number to connect to. 74 75 username => STRING 76 password => STRING 77 Optional. Authentication details to use for 78 `PasswordAuthenticator'. 79 80 keyspace => STRING 81 Optional. If set, a `USE keyspace' query will be issued as part 82 of the connect method. 83 84 default_consistency => INT 85 Optional. Default consistency level to use if none is provided 86 to `query' or `execute'. 87 88 primaries => INT 89 Optional. The number of primary node connections to maintain. 90 Defaults to 1 if not specified. 91 92 prefer_dc => STRING 93 Optional. If set, prefer to pick primary nodes from the given 94 data center, only falling back on others if there are not enough 95 available. 96 97 cql_version => INT 98 Optional. Version of the CQL wire protocol to negotiate during 99 connection. Defaults to 1. 100 101METHODS 102 $str = $cass->quote( $str ) 103 Quotes a string argument suitable for inclusion in an immediate CQL 104 query string. 105 106 In general, it is better to use a prepared query and pass the value as 107 an execute parameter though. 108 109 $str = $cass->quote_identifier( $str ) 110 Quotes an identifier name suitable for inclusion in a CQL query string. 111 112 $cass->connect( %args ) ==> () 113 Connects to the Cassandra node and starts up the connection. The 114 returned Future will yield nothing on success. 115 116 Takes the following named arguments: 117 118 host => STRING 119 hosts => ARRAY of STRING 120 service => STRING 121 122 A set of host names are required, either as a named argument or as a 123 configured value on the object. If the service name is missing, the 124 default CQL port will be used instead. 125 126 $cass->close_when_idle ==> $cass 127 Stops accepting new queries and prepares all the existing connections to 128 be closed once every outstanding query has been responded to. Returns a 129 future that will eventually yield the CassandraCQL object, when all the 130 connections are closed. 131 132 After calling this method it will be an error to invoke `query', 133 `prepare', `execute' or the various other methods derived from them. 134 135 $cass->close_now 136 Immediately closes all node connections and shuts down the object. Any 137 outstanding or queued queries will immediately fail. Consider this as a 138 "last resort" failure shutdown, as compared to the graceful draining 139 behaviour of `close_when_idle'. 140 141 $cass->query( $cql, $consistency, %other_args ) ==> ( $type, $result ) 142 Performs a CQL query. On success, the values returned from the Future 143 will depend on the type of query. 144 145 For `USE' queries, the type is `keyspace' and `$result' is a string 146 giving the name of the new keyspace. 147 148 For `CREATE', `ALTER' and `DROP' queries, the type is `schema_change' 149 and `$result' is a 3-element ARRAY reference containing the type of 150 change, the keyspace and the table name. 151 152 For `SELECT' queries, the type is `rows' and `$result' is an instance of 153 Protocol::CassandraCQL::Result containing the returned row data. 154 155 For other queries, such as `INSERT', `UPDATE' and `DELETE', the future 156 returns nothing. 157 158 `%other_args' may be any of the following, when using `cql_version' 2 or 159 above: 160 161 skip_metadata => BOOL 162 Requests the server does not include result metadata in the 163 response. It will be up to the caller to provide this, via 164 `set_metadata' on the returned Result object, before it can be 165 used. 166 167 page_size => INT 168 Requests that the server returns at most the given number of 169 rows. If any further remain, the result object will include the 170 `paging_state' field. This can be passed in another `query' call 171 to obtain the next set of data. 172 173 paging_state => INT 174 Requests that the server continues a paged request from this 175 position, given in a previous response. 176 177 serial_consistency => INT 178 Sets the consistency level for serial operations in the query. 179 Must be one of `CONSISTENCY_SERIAL' or 180 `CONSISTENCY_LOCAL_SERIAL'. 181 182 $cass->query_rows( $cql, $consistency, %other_args ) ==> $result 183 A shortcut wrapper for `query' which expects a `rows' result and returns 184 it directly. Any other result is treated as an error. The returned 185 Future returns a `Protocol::CassandraCQL::Result' directly 186 187 $cass->prepare( $cql ) ==> $query 188 Prepares a CQL query for later execution. On success, the returned 189 Future yields an instance of a prepared query object (see below). 190 191 Query objects stored internally cached by the CQL string; subsequent 192 calls to `prepare' with the same exact CQL string will yield the same 193 object immediately, saving a roundtrip. 194 195 $cass->execute( $query, $data, $consistency, %other_args ) ==> ( $type, $result ) 196 Executes a previously-prepared statement, given the binding data. On 197 success, the returned Future will yield results of the same form as the 198 `query' method. `$data' should contain a list of encoded byte-string 199 values. 200 201 Normally this method is not directly required - instead, use the 202 `execute' method on the query object itself, as this will encode the 203 parameters correctly. 204 205 `%other_args' may be as for the `query' method. 206 207CONVENIENT WRAPPERS 208 The following wrapper methods all wrap the basic `query' operation. 209 210 $cass->schema_keyspaces ==> $result 211 A shortcut to a `SELECT' query on `system.schema_keyspaces', which 212 returns a result object listing all the keyspaces. 213 214 Exact details of the returned columns will depend on the Cassandra 215 version, but the result should at least be keyed by the first column, 216 called `keyspace_name'. 217 218 my $keyspaces = $result->rowmap_hash( "keyspace_name" ) 219 220 $cass->schema_columnfamilies( $keyspace ) ==> $result 221 A shortcut to a `SELECT' query on `system.schema_columnfamilies', which 222 returns a result object listing all the columnfamilies of the given 223 keyspace. 224 225 Exact details of the returned columns will depend on the Cassandra 226 version, but the result should at least be keyed by the first column, 227 called `columnfamily_name'. 228 229 my $columnfamilies = $result->rowmap_hash( "columnfamily_name" ) 230 231 $cass->schema_columns( $keyspace, $columnfamily ) ==> $result 232 A shortcut to a `SELECT' query on `system.schema_columns', which returns 233 a result object listing all the columns of the given columnfamily. 234 235 Exact details of the returned columns will depend on the Cassandra 236 version, but the result should at least be keyed by the first column, 237 called `column_name'. 238 239 my $columns = $result->rowmap_hash( "column_name" ) 240 241TODO 242 * Allow other load-balancing strategies than roundrobin. 243 244 * Adjust connected primary nodes when changing `primaries' 245 parameter. 246 247 * Allow backup nodes, for faster connection failover. 248 249 * Support LZ4 compression when using CQL version 2. 250 251 This is blocked on RT #92825 252 253SPONSORS 254 This code was paid for by 255 256 * Perceptyx http://www.perceptyx.com/ 257 258 * Shadowcat Systems http://www.shadow.cat 259 260AUTHOR 261 Paul Evans <leonerd@leonerd.org.uk> 262 263