Rand Stats



Actions Status


Protocol::Postgres - a sans-io postgresql client


use v6.d;
use Protocol::Postgres;

my $socket = await IO::Socket::Async.connect($host, $port);
my $client = Protocol::Postgres::Client.new;
$socket.Supply(:bin).act({ $client.incoming-data($^data) });
$client.outbound-data.act({ $socket.write($^data) });

await $client.startup($user, $database, $password);

my $resultset = await $client.query('SELECT * FROM foo WHERE id = $1', [ 42 ]);
react {
	whenever $resultset.hash-rows -> (:$name, :$description, :$id) {
		say "$name is $description";


Protocol::Postgres is sans-io implementation of (the client side of) the postgresql protocol. It is typically used through the Protocol::Postgres::Client class.


Protocol::Postgres::Client has the following methods

new(--> Protocol::Postgres::Client)

This creates a new postgres client. It supports one optional named argument:

outgoing-data(--> Supply)

This returns a Supply of Blobs to be written to the server.

incoming-data(Blob --> Nil)

This consumes bytes received from the server.

startup($user, $database?, $password? --> Promise)

This starts the handshake to the server. $database may be left undefined, the server will use $user as database name. If a $password is defined, any of clearnext, md5 or SCRAM-SHA-256 based authentication is supported.

The resulting promise will finish when the connection is ready for queries.

query($query, @bind-values --> Promise)

This will issue a query with the given bind values, and return a promise to the result.

For fetching queries such as SELECT the result in the promise will be a ResultSet object, for manipulation (e.g. INSERT) and definition (e.g. CREATE) queries it will result a string describing the change (e.g. DELETE 3). For a COPY FROM query it will Supply with the data stream, and for COPY TO it will be a Supplier.

Both the input types and the output types will be typemapped between Raku types and Postgres types using the typemapper.

query-multiple($query --> Supply[ResultSet])

This will issue a complex query that may contain multiple statements, but can not use bind values. It will return a Supply to the results of each query.

prepare($query, :@input-types --> Promise[PreparedStatement])

This prepares the query, and returns a Promise to the PreparedStatement object. @input-types can be used to pass on hints about the types you're passing in during execute.

method get-channel(Str $name --> Supply)

This returns the Supply for the given channel.

add-enum-type(Str $name, ::Enum --> Promise)

This looks up the oid of postgres enum $name, and adds an appriopriate Type object to the typemap to convert it from/to Enum.

add-composite-type(Str $name, ::Composite, Bool :$positional --> Promise)

This looks up the oid of the postgres composite type <$name>, and maps it to Composite; if $positional is set it will use positional constructor arguments, otherwise named ones are used; it will use a heuristic by default.

add-custom-type(Str $name, ::Custom, &from-string?, &to-string?)

This adds a custom converter from postgres type $name from/to Raku type Custom. By default &from-string will do a coercion, and &to-string will do stringification.

startTls(--> Blob)

This will return the marker that should be written to the server to start upgrading the connection to use TLS. If the server responds with a single S byte the proposal is accepted and the client is expected to initiate the TLS handshake. If the server responds with an N it is rejected, and the connection proceeds in cleartext.

terminate(--> Nil)

This sends a message to the server to terminate the connection

disconnected(--> Promise)

This returns a Promise that must be be kept or broken to signal the connection is lost.

query-status(--> Protocol::Postgres::QueryStatus)

This returns the query status as of the last finished query as a enum Protocol::Postgres::QueryStatus value: Idle (No transaction is active), Transaction (A transaction is currently in progress) or Error (The current transaction has failed and needs to be rolled back).

process-id(--> Int)

This returns the process id of the backend of this connection. This is useful for debugging purposes and for notifications.

get-parameter(Str $name --> Str)

This returns various parameters, currently known parameters are: server_version, server_encoding, client_encoding, application_name, default_transaction_read_only, in_hot_standby, is_superuser, session_authorization, DateStyle, IntervalStyle, TimeZone, integer_datetimes, and standard_conforming_strings.


A Protocol::Postgres::ResultSet represents the results of a query, if any.

columns(--> List)

This returns the column names for this resultset.

rows(--> Supply[List])

This returns a Supply of rows. Each row is a list of values.

hash-rows(--> Supply[Hash])

This returns a Supply of rows. Each row is a hash with the column names as keys and the row values as values.

object-rows(::Class, Bool :$positional --> Supply[Class])

This returns a Supply of objects of class Class, each object is constructed form the row hash unless positional is true in which case it's constructed from the row list.


This returns a sequence of arrays of results from all rows. This may await.


This returns a single array of results from one row. This may await.


This returns a single value from a single row. This may await.


This returns a sequence of hashes of the results from all rows. This may await.


This returns a single hash of the results from one rows. This may await.

objects(::Class, Bool :$positional)

This returns a sequence of objects based on all the rows. This may await.

object(:Class, Bool :$positional)

This returns a single object based on a single row. This may await.


A Protocol::Postgres::PreparedStatement represents a prepated statement. Its reason of existence is to call execute on it.

execute(@arguments --> Promise[ResultSet])

This runs the prepared statement, much like the query method would have done.


This closes the prepared statement.


This returns the columns of the result once executed.


Protocol::Postgres::Notification has the following methods:

sender(--> Int)

This is the process-id of the sender

channel(--> Str)

This is the name of the channel that the notification was sent on

message(--> Str)

This is the message of the notification


Leon Timmermans fawaka@gmail.com

Copyright and License

Copyright 2022 Leon Timmermans

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.