kura_driver_minato (kura_postgres v1.1.0)
View Sourcekura_driver implementation over minato.
Where a query goes
Outside a transaction it goes to the pool: minato:query/4 borrows a
connection, runs the statement and gives it back, all inside the call. Nothing
is held and nothing is threaded through kura.
Inside a transaction it goes to the connection the transaction is running on,
which kura_pool_minato holds and this module finds in the process
dictionary. The reason is that a query written inside transaction/4's
function is handed nothing, so the connection has to be found rather than
passed.
Results and errors
minato answers #{command := atom(), num_rows := integer(), rows := [row()]},
which is the shape kura already reads, and a failing statement answers {error, {pgsql_error, Fields}} with code and constraint as binaries - which is what
kura_repo_worker turns into a changeset error. Nothing in kura had to change
for either.
numeric
numeric decodes to a float here, which is not minato's default: minato hands
back the exact decimal text, because that is what the type is for. kura has
always given callers a float for it, through pg_types, and a driver swap is
the wrong moment to change what avg/1 returns for everybody.
A repo that wants the exact form says numeric_format => binary in its driver
options, and should, for anything that is money.
Timeouts
timeout in the driver options is a deadline on the statement rather than on
the read. minato cancels a statement that outlives it on the server and reads
the cancellation through, so a slow query comes back as SQLSTATE 57014 and the
connection goes back to the pool rather than being closed.
Summary
Functions
Create the database named in Config if it is not there.
Round trip a trivial statement against Pool.
Run a statement on a pool, or on the transaction this process is inside.
Run a statement on a connection the caller checked out.
Run Fun inside a transaction.
Functions
Create the database named in Config if it is not there.
-spec probe_pool(kura_pool:name()) -> ok | {error, term()}.
Round trip a trivial statement against Pool.
Run a statement on a pool, or on the transaction this process is inside.
-spec query_on(kura_pool:conn(), iodata(), [term()], map()) -> dynamic().
Run a statement on a connection the caller checked out.
-spec transaction(module(), kura_pool:name(), fun(() -> term()), map()) -> term().
Run Fun inside a transaction.
BEGIN first, COMMIT on a normal return, ROLLBACK on an exception, which is
then re-raised. Queries inside Fun find the connection through the process
dictionary.
Raises error(transaction_rolled_back) when the server answers the COMMIT
with ROLLBACK, which it does when the transaction had already failed. Nothing
was written, and returning the function's value there would report success for
work the server threw away.