lode/adapters/postgres
A PostgreSQL adapter built on pog (the Gleam client wrapping Erlang pgo).
The adapter is thin: it renders a Query to parameterized SQL via
lode/query/sql, converts our Value params to pog values, runs the
query through pog, and decodes rows back into Dict(String, Value).
IMPORTANT: start the pog connection with pog.rows_as_map(config, True)
so rows come back as column-keyed maps — the row decoder relies on it.
let assert Ok(started) = pog.default_config(process.new_name(“db”)) |> pog.host(“localhost”) |> pog.database(“my_db”) |> pog.rows_as_map(True) |> pog.start let repo = repo.new(postgres.new(started.data))
KNOWN LIMITATION (v0.1): transaction opens a real BEGIN/COMMIT, but repo
operations called inside the body still run on the pool connection, not the
transaction’s checked-out connection. Single-statement round-trips are
correct; multi-statement atomicity needs connection-context threading
through the Adapter (planned).
Values
pub fn new(conn: pog.Connection) -> adapter.Adapter
Build an adapter over an already-started pog connection (started with
rows_as_map(True)).
Installs a lossless numeric decoder on the connection’s type table (so
high-precision decimal columns round-trip without float rounding on read).
This is best-effort — if it can’t be installed the adapter still works, with
numeric reads bounded by float precision.
pub fn with_connection(
repo r: repo.Repo,
body body: fn(pog.Connection) -> a,
) -> a
Run body with the repo’s raw pog.Connection — the escape hatch for
engine-specific code the value layer cannot express: compiled query
functions (squirrel), COPY, advisory locks. On the base repo this is the
pooled connection (pog checks out per statement, so no exclusivity is
implied — unlike the SQLite twin); on a transaction-scoped repo it is the
transaction’s own connection, so body’s statements join the transaction
and roll back with it.
Panics when the repo’s adapter is not this module’s — the connection type would be a lie.