pkg:db/postgres
PostgreSQL wire protocol v3 client.
import "pkg:db/postgres"
Overview
Minimal PostgreSQL driver for CRUD operations using the simple query protocol. Connects via TCP, authenticates with cleartext password, executes SQL queries, and returns structured result sets. Hostnames are resolved via vera:net/dns, so both IP addresses and domain names are supported.
Connection string format: postgres://user:password@host:port/database
Limitations (v1):
- Cleartext password authentication only (no MD5/SCRAM)
- No TLS/SSL
- No prepared statements (simple query protocol only)
- All values returned as text strings
Dependencies: vera:net, vera:net/dns, vera:memory, vera:string, vera:binary
Functions
pg_connect
function pg_connect(url: ptr, url_len: i64) -> ptr
Connect to a PostgreSQL server. Parses the connection string, resolves the hostname via DNS, opens a TCP connection, sends a StartupMessage, and handles password authentication.
Parameters:
url(ptr) — pointer to the connection string (e.g.,"postgres://user:pass@host:5432/dbname")url_len(i64) — length of the connection string in bytes
Returns: an opaque connection handle (ptr), or null on failure.
pg_close
function pg_close(conn: ptr)
Close a PostgreSQL connection. Sends a Terminate message to the server, closes the TCP socket, and frees all connection memory.
Parameters:
conn(ptr) — the connection handle returned bypg_connect
pg_exec
function pg_exec(conn: ptr, sql: ptr, sql_len: i64) -> i64
Execute a non-SELECT SQL statement (INSERT, UPDATE, DELETE, CREATE, DROP, etc.) using the simple query protocol.
Parameters:
conn(ptr) — the connection handlesql(ptr) — pointer to the SQL statement textsql_len(i64) — length of the SQL statement in bytes
Returns: the number of affected rows, or -1 on error. For DDL statements (CREATE, DROP), returns 0 on success.
pg_query
function pg_query(conn: ptr, sql: ptr, sql_len: i64) -> ptr
Execute a SELECT statement and return a result set. The caller must call pg_result_free when done with the result.
Parameters:
conn(ptr) — the connection handlesql(ptr) — pointer to the SQL query textsql_len(i64) — length of the SQL query in bytes
Returns: an opaque result set handle (ptr), or null on error.
pg_result_rows
function pg_result_rows(result: ptr) -> i64
Get the number of rows in a result set.
Parameters:
result(ptr) — the result set handle returned bypg_query
Returns: the number of rows.
pg_result_columns
function pg_result_columns(result: ptr) -> i64
Get the number of columns in a result set.
Parameters:
result(ptr) — the result set handle returned bypg_query
Returns: the number of columns.
pg_result_column_name
function pg_result_column_name(result: ptr, col: i64, out_buf: ptr, out_size: i64) -> i64
Get a column name by index. Copies the name into the caller-provided buffer.
Parameters:
result(ptr) — the result set handlecol(i64) — zero-based column indexout_buf(ptr) — caller-allocated buffer for the column nameout_size(i64) — size ofout_bufin bytes
Returns: the number of bytes written to out_buf, or -1 if col is out of range.
pg_result_get
function pg_result_get(result: ptr, row: i64, col: i64, out_buf: ptr, out_size: i64) -> i64
Get a cell value as a string. Copies the value into the caller-provided buffer.
Parameters:
result(ptr) — the result set handlerow(i64) — zero-based row indexcol(i64) — zero-based column indexout_buf(ptr) — caller-allocated buffer for the cell valueout_size(i64) — size ofout_bufin bytes
Returns: bytes written to out_buf, 0 for an empty string, or -1 for SQL NULL.
pg_result_is_null
function pg_result_is_null(result: ptr, row: i64, col: i64) -> i32
Check if a cell value is SQL NULL.
Parameters:
result(ptr) — the result set handlerow(i64) — zero-based row indexcol(i64) — zero-based column index
Returns: 1 if the value is NULL, 0 if not NULL, or -1 if the indices are out of range.
pg_result_free
function pg_result_free(result: ptr)
Free a result set and all associated memory. Must be called when you are done reading query results.
Parameters:
result(ptr) — the result set handle to free
Example
import "pkg:db/postgres"
import "vera:memory"
import "vera:io"
data conn_str: "postgres://myuser:mypass@localhost:5432/mydb"
data select_sql: "SELECT id, name FROM users"
data insert_sql: "INSERT INTO users (name) VALUES ('alice')"
function main() -> i32 {
; Connect
constant.ptr p_url, conn_str
constant.i64 url_len, 44
call conn, pg_connect, p_url, url_len
; Execute a write statement
constant.ptr p_insert, insert_sql
constant.i64 insert_len, 41
call affected, pg_exec, conn, p_insert, insert_len
; Execute a query
constant.ptr p_select, select_sql
constant.i64 select_len, 26
call result, pg_query, conn, p_select, select_len
; Read results
call num_rows, pg_result_rows, result
call num_cols, pg_result_columns, result
; Iterate rows
constant.i64 zero, 0
constant.i64 one, 1
copy.i64 row, zero
stack_allocate val_buf, 256, 8
constant.i64 val_size, 256
.row_loop:
compare_signed_greater_equal.i64 done, row, num_rows
branch_if done, .cleanup, .read_row
.read_row:
call len, pg_result_get, result, row, zero, val_buf, val_size
call _, print, val_buf, len
add.i64 row, row, one
jump .row_loop
.cleanup:
; Free result set and close connection
call _, pg_result_free, result
call _, pg_close, conn
constant.i32 exit_ok, 0
return exit_ok
}