# NAME Protocol::Dqlite - [Dqlite](https://dqlite.io) in Perl # SYNOPSIS use autodie; my $dqlite = Protocol::Dqlite->new(); my $socket = IO::Socket::INET->new('127.0.0.1:9001') or die; syswrite $s, Protocol::Dqlite::handshake(); # Register ourselves as a Dqlite client: syswrite $s, Protocol::Dqlite::request( Protocol::Dqlite::REQUEST_CLIENT, 0 ); # Await the server’s acknowledgement: while (sysread $s, my $buf, 512) { my ($msg) = $dqlite->feed($buf); next if !$msg; last if $msg isa Protocol::Dqlite::Response::WELCOME; # An unexpected response. Better bail out … # require Data::Dumper; die Data::Dumper::Dumper($msg); } … and now you can exchange messages as you wish. # DESCRIPTION This module implements message parsing and creation for [Dqlite](https://dqlite.io) clients. To use this module you’ll need to write the I/O logic yourself. # CHARACTER ENCODING Strings designated as “blob”s are _byte_ strings. All other strings into & out of this module are _character_ strings. Decode & encode accordingly. # CONSTANTS The following derive from the [documentation of Dqlite’s wire protocol](https://dqlite.io/docs/protocol) as well as [protocol.h](https://github.com/canonical/dqlite/blob/master/src/protocol.h) in Dqlite’s source code. ## Role Codes `ROLE_VOTER`, `ROLE_STANDBY`, `ROLE_SPARE` ## Tuple Member Types - Numbers: `TUPLE_INT64`, `TUPLE_FLOAT` - Buffers: `TUPLE_STRING`, `TUPLE_BLOB` - Time: `TUPLE_UNIXTIME`, `TUPLE_ISO8601` - Other: `TUPLE_NULL`, `TUPLE_BOOLEAN` ## Request Message Types - `REQUEST_LEADER` (0) - `REQUEST_CLIENT` (1) - `REQUEST_OPEN` (3) - `REQUEST_PREPARE` (4) - `REQUEST_EXEC` (5) - `REQUEST_QUERY` (6) - `REQUEST_FINALIZE` (7) - `REQUEST_EXEC_SQL` (8) - `REQUEST_QUERY_SQL` (9) - `REQUEST_INTERRUPT` (10) - `REQUEST_CONNECT` (11) - `REQUEST_ADD` (12) - `REQUEST_ASSIGN` (13) - `REQUEST_REMOVE` (14) - `REQUEST_DUMP` (15) - `REQUEST_CLUSTER` (16) ## Other - `handshake` - The string to send after establishing a connection to the server. # STATIC FUNCTIONS ## $bytes = request( $TYPE, @ARGUMENTS ) Returns a byte buffer of a Dqlite message. $TYPE is one of the `REQUEST_*` constants listed above. @ARGUMENTS are as Dqlite’s [wire protocol documentation](https://dqlite.io/docs/protocol) indicates. Dqlite tuples are expressed as type/value pairs. Example: my $bytes = Protocol::Dqlite::request( Protocol::Dqlite::REQUEST_PREPARE, 12, "SELECT ?, ?", Protocol::Dqlite::TUPLE_INT64 => 12345, Protocol::Dqlite::TUPLE_BLOB => "\x00\x01\x02", ); # METHODS ## $obj = _CLASS_->new() Instantiates _CLASS_. ## @messages = _OBJ_->feed( $BYTES ) Give new input to _OBJ_. Returns any messages parsed out of $BYTES as `Protocol::Dqlite::Response` instances. # RESPONSE CLASSES All of the below extend `Protocol::Dqlite::Response`. They expose various accessors as documented below: - `Protocol::Dqlite::Response::FAILURE`: `code()`, `message()` - `Protocol::Dqlite::Response::SERVER`: `id()`, `address()`, `role()` - `Protocol::Dqlite::Response::WELCOME`: (none) - `Protocol::Dqlite::Response::SERVERS`: `count()`, `id()`, `address()`, `role()`; the latter 3 require an index argument, which MUST be between 0 and (`count()` - 1), inclusive. - `Protocol::Dqlite::Response::DB`: `id()` - `Protocol::Dqlite::Response::STMT`: `database_id()`, `statement_id()`, `params_count()` - `Protocol::Dqlite::Response::RESULT`: `last_row_id()`, `rows_count()` - `Protocol::Dqlite::Response::ROWS`: - `is_final()` - `column_names()` - returns a list, or a count in scalar context - `rows_count()` - `row_types()`, `row_data()` - these need an index, max=(`rows_count()`-1) - `Protocol::Dqlite::Response::EMPTY`: (none) - `Protocol::Dqlite::Response::FILES`: `names()` (list/count) and `content()` (takes an index)