Postgres
On run(), if Postgres connects, Keel ensures the table:
CREATE TABLE IF NOT EXISTS items (
id SERIAL PRIMARY KEY,
title TEXT NOT NULL DEFAULT '',
body TEXT NOT NULL DEFAULT '',
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
)
id and created_at are always added. You only name the text columns in api("items", "title, body").
Database URL
Order:
store(url)if you called itBURAAQ_DATABASE_URLfrom the process, from~/.buraaq/dock/env, or from an env file next to the binaryDATABASE_URL- Windows play fallback (
localhost/buraaq_play) - Linux localhost only if
BURAAQ_PG_LOCAL=1: a shared VPS often already has someone else's Postgres on 5432
$env:BURAAQ_DATABASE_URL = "host=127.0.0.1 port=5432 dbname=app user=postgres"
Or store("...") in source before run(). Credentials belong on the host when you ship. Do not pack secrets into a .bur unless you intend that.
Managed Postgres works the same way. Neon and similar poolers need sslmode=require. Keel reconnects when the pooler drops an idle socket (/api/health is SELECT 1). Never commit the URL.
Linux hosts need libpq5. land.sh installs it. The runtime loads libpq.so.5 / libpq.dll at process start: it does not bake a password.
When to use std.db
connect, exec, quote, disconnect when the resource helper cannot express the query (joins, aggregates, admin scripts). For ordinary title/body lists, api() is the whole backend.
use std.db.{connect, exec, quote, disconnect}
fn main() {
connect("host=127.0.0.1 port=5432 dbname=app user=postgres")
exec("select 1")
disconnect()
}
Quote user text with quote: never concatenate SQL.
Shipping
Postgres lives next to the dock, not inside the .bur. Dock copies ~/.buraaq/dock/env into the launched process. Same idea as not stuffing a database into a Docker image: the process is native; the data is the host's.
