NAME

Protocol::Dqlite - Dqlite 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 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 as well as 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 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)