A client for sending queries to the PostgreSQL server over one connection.
{ok, Options} = pgc_client_options:from_uri(~"postgresql://postgres:postgres@localhost/postgres"),
{ok, Client} = pgc_client:start_link(Options),
{ok, #{command := ~"select", rows := 1}, [#{~"answer" := 42}]} =
pgc_client:execute(Client, ~"select $1::int4 as answer", [42]).Rows are maps by default. The row option selects another shape:
{ok, _, [{42, ~"pgc"}]} =
pgc_client:execute(Client, ~"select 42 as answer, 'pgc' as name", [], #{row => tuple}).execute_fold/6 folds over the rows as they arrive, without collecting them:
{ok, #{rows := 10}, 55} = pgc_client:execute_fold(Client, ~"select generate_series(1, 10)", [],
fun (_Columns, [N], Sum) -> {continue, Sum + N} end, 0, #{}).transaction/3 runs a fun in a transaction, committed or rolled back as the fun returns:
42 = pgc_client:transaction(Client, fun () ->
{ok, _, [#{~"answer" := Answer}]} = pgc_client:execute(Client, ~"select 42 as answer", []),
{commit, Answer}
end, #{}).stop/1 closes the connection.
Summary
Types
Runs a parameterized statement through parse/bind/execute, folding Fun over each row as
it arrives. A halted fold cancels the query on the server; see execute/4 for Options'
timeout semantics.
Runs a parameterized statement through parse/bind/execute, collecting every row into a
list shaped per Options' row (map by default).
Encoding and decoding are deliberately done here, in the caller's own process, rather than in
handle_row_data/5/handle_prepare_result/4 (which run in the connection process): the
connection is a shared, serializing bottleneck, while Types (pgc_client_types:t()) wraps a
protected ets table specifically so any number of callers can read it -- and therefore encode
and decode -- concurrently, off the connection's own execution stack. The connection only ever
mediates the wire and owns the (write side of the) type cache; the caller builds its own
pgc_client_codec:t() from Types and this call's codec option (see collect/7).
Functions
Runs a parameterized statement through parse/bind/execute, collecting every row into a list of maps.
Brings ClientRef back to a clean session state -- rolls back any transaction Action left
open, then clears any session-level set it left behind. Meant to be called whenever a
connection is handed back to a pool, between one caller and the next.
Start a new postgresql client connection.
Start a new postgresql client connection registered using
the provided ClientName.
Orders the client to exit and waits for it to terminate.
Types
-type client_name() :: gen_statem:server_name().
-type client_ref() :: gen_statem:server_ref().
-type execute_cache_options() :: false | {true, Key :: unicode:chardata() | atom()}.
-type execute_fold_fun(Acc) :: fun(([#{name := unicode:unicode_binary()}], [term() | null], Acc) -> {continue, Acc} | {halt, Acc}).
Runs a parameterized statement through parse/bind/execute, folding Fun over each row as
it arrives. A halted fold cancels the query on the server; see execute/4 for Options'
timeout semantics.
Fun receives the result's columns, the row's values in column order and the accumulator.
-type execute_options() :: #{row => map | list | tuple | proplist, timeout => timeout() | {abs, integer()}, cache => execute_cache_options(), codec => #{modules => [module()], atom() => term()}}.
Runs a parameterized statement through parse/bind/execute, collecting every row into a
list shaped per Options' row (map by default).
Options' timeout, if given, on expiry, the query is cancelled on the server and
exits with exit({timeout, _}).
Options' cache key names the prepared statement: at most 63 bytes once converted to UTF-8,
as Postgres keeps no more of a name; a longer one raises {pgc, {statement_name_too_long, Name}}.
-type request_error() :: #{severity := panic | fatal | error, code := binary(), message := unicode:unicode_binary(), detail => unicode:unicode_binary(), hint => unicode:unicode_binary(), position => pos_integer(), internal_position => pos_integer(), internal_query => unicode:unicode_binary(), where => [unicode:unicode_binary()], schema => unicode:unicode_binary(), table => unicode:unicode_binary(), column => unicode:unicode_binary(), data_type => unicode:unicode_binary(), constraint => unicode:unicode_binary(), file => unicode:unicode_binary(), line => non_neg_integer(), routine => unicode:unicode_binary()}.
Encoding and decoding are deliberately done here, in the caller's own process, rather than in
handle_row_data/5/handle_prepare_result/4 (which run in the connection process): the
connection is a shared, serializing bottleneck, while Types (pgc_client_types:t()) wraps a
protected ets table specifically so any number of callers can read it -- and therefore encode
and decode -- concurrently, off the connection's own execution stack. The connection only ever
mediates the wire and owns the (write side of the) type cache; the caller builds its own
pgc_client_codec:t() from Types and this call's codec option (see collect/7).
-type result_metadata() :: #{command => binary(), rows => non_neg_integer()}.
-type statement_parameters() :: [term() | null].
-type statement_text() :: unicode:chardata().
-type transaction_options() :: #{isolation => serializable | repeatable_read | read_committed | read_uncommitted | default, access => read_write | read_only | default, deferrable => boolean() | default}.
Functions
-spec execute(ClientRef, Statement, Parameters) -> {ok, Metadata, Rows} | {error, Error} when ClientRef :: client_ref(), Statement :: statement_text(), Parameters :: statement_parameters(), Metadata :: result_metadata(), Rows :: [map()], Error :: request_error().
Runs a parameterized statement through parse/bind/execute, collecting every row into a list of maps.
-spec execute(ClientRef, Statement, Parameters, Options) -> {ok, Metadata, Rows} | {error, Error} when ClientRef :: client_ref(), Statement :: statement_text(), Parameters :: statement_parameters(), Options :: execute_options(), Metadata :: result_metadata(), Rows :: [dynamic()], Error :: request_error().
-spec execute_fold(ClientRef, Statement, Parameters, Fun, Acc, Options) -> {ok, Metadata, Acc} | {error, Error} when ClientRef :: client_ref(), Statement :: statement_text(), Parameters :: statement_parameters(), Fun :: execute_fold_fun(Acc), Options :: execute_fold_options(), Metadata :: result_metadata(), Error :: request_error().
-spec reset(ClientRef) -> ok when ClientRef :: client_ref().
Brings ClientRef back to a clean session state -- rolls back any transaction Action left
open, then clears any session-level set it left behind. Meant to be called whenever a
connection is handed back to a pool, between one caller and the next.
-spec start_link(pgc_client_options:t()) -> gen_statem:start_ret().
Start a new postgresql client connection.
-spec start_link(client_name(), pgc_client_options:t()) -> gen_statem:start_ret().
Start a new postgresql client connection registered using
the provided ClientName.
ClientName specifies the client_name/0 to register for the client process.
-spec stop(client_ref()) -> ok.
Orders the client to exit and waits for it to terminate.
-spec transaction(ClientRef, Fun, Options) -> Result when ClientRef :: client_ref(), Fun :: fun(() -> {commit | rollback, Result}), Options :: transaction_options().