Rand Stats

Protocol::Postgres

zef:leont

Actions Status

Name

Protocol::Postgres - a sans-io postgresql client

Synopsis

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";
	}
}

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.

Client

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.

ResultSet

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.

arrays

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

array

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

value

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

hashes

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

hash

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.

PreparedStatement

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.

close()

This closes the prepared statement.

columns()

This returns the columns of the result once executed.

Notification

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

Author

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.