vow-postgres
vow-postgres connects to PostgreSQL via libpq (or mem:postgres for tests). Install with vpm:
curl -fsSL https://install.vowlang.dev | shexport PATH="$HOME/.local/bin:$PATH"vpm add vow-postgresvpm installSync API (library)
Section titled “Sync API (library)”import vpg from vow_postgres
fn list_widgets(url: String) -> int needs Db { let conn = match vpg.connect(url) { Ok(c) => c, Err(e) => return e.code, }; let rows = match vpg.query(conn, "SELECT id, name FROM widgets") { Ok(r) => r, Err(e) => { let _ = vpg.close(conn); return e.code; }, }; let _ = vpg.close(conn); print(rows); return 0;}Grant: vow run app.vow -- --grant db:postgres://localhost:5432/widgets
Async API (recommended for HTTP apps)
Section titled “Async API (recommended for HTTP apps)”Use await db_query(handle, sql)? inside async fn, then block_on(helper) from sync handlers. Async helpers that call vpg.connect need needs Db; pass the cap with with db { block_on(init_db_work) }.
import vpg from vow_postgresimport vws from vow_web_serverimport json
var g_handle: int64 = 0;var g_db_ok: int = 0;
fn open_db() -> Result<int64, int> needs Db { return match vpg.connect(vpg.dsn_auth("localhost", 5433, "vow", "vow", "todos")) { Ok(c) => Ok(c.handle), Err(e) => Err(e.code), };}
async fn init_db_work() -> int needs Db { let h = open_db()?; let _rows = await db_query(h, "SELECT id, title, done FROM todos ORDER BY id")?; g_handle = h; g_db_ok = 1; return 0;}
fn init_db(caps: Caps) -> int { let db = caps.db?; return with db { block_on(init_db_work) };}
async fn todo_count() -> int { let rows = await db_query(g_handle, "SELECT id FROM todos")?; let doc = json.parse(rows)?; return json_len(doc)?;}
fn api_health(_req: request.Request) -> response.Response { return vws.json(json.stringify({ todos: block_on(todo_count) }));}
fn main(caps: Caps) -> int { if init_db(caps) != 0 { return 1; } // ... vow-web-server setup ... return 0;}Full demo: hello-app/ in the playground (docker compose up, then vow run src/main.vow).
See Async / await for the complete pattern.
DSN helpers
Section titled “DSN helpers”vpg.dsn("localhost", 5432, "user", "dbname")vpg.dsn_auth("localhost", 5432, "user", "password", "dbname")vpg.is_postgres_url(url) // true for postgres:// and mem:postgresErrors
Section titled “Errors”| Code | Meaning |
|---|---|
100 |
Invalid DSN |
1001 |
Capability denied |
1002 |
Connect failed |
2001 |
Query/exec failed |