Skip to content

vow-postgres

vow-postgres connects to PostgreSQL via libpq (or mem:postgres for tests). Install with vpm:

Terminal window
curl -fsSL https://install.vowlang.dev | sh
export PATH="$HOME/.local/bin:$PATH"
vpm add vow-postgres
vpm install
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

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_postgres
import vws from vow_web_server
import 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.

vpg.dsn("localhost", 5432, "user", "dbname")
vpg.dsn_auth("localhost", 5432, "user", "password", "dbname")
vpg.is_postgres_url(url) // true for postgres:// and mem:postgres
Code Meaning
100 Invalid DSN
1001 Capability denied
1002 Connect failed
2001 Query/exec failed