postgres
| Kind | ffi-c |
|---|---|
| Capabilities | ffi net |
| Categories | database ffi |
| Keywords | postgres postgresql database sql libpq |
PostgreSQL bindings for Kit using libpq
Files
| File | Description |
|---|---|
.editorconfig | Editor formatting configuration |
.gitignore | Git ignore rules for build artifacts and dependencies |
.tool-versions | asdf tool versions (Zig, Kit) |
LICENSE | MIT license file |
README.md | This file |
examples/postgres.kit | Example: postgres |
kit.toml | Package manifest with metadata and dependencies |
src/postgres.kit | PostgreSQL Bindings for Kit - Full-featured database access |
tests/postgres.test.kit | Tests for postgres |
Dependencies
No Kit package dependencies.
Native Dependencies
Requires the libpq client library:
| Platform | Install Command |
|---|---|
| macOS | brew install libpq |
| Ubuntu | sudo apt install libpq-dev |
| Fedora | sudo dnf install libpq-devel |
Related Packages
- kit-pg-parser - PostgreSQL SQL parser - parse, validate, normalize, and fingerprint SQL queries using libpg_query
- kit-query - Fluent SQL query builder for Kit
Installation
kit add gitlab.com/kit-lang/packages/kit-postgres.gitUsage
import Kit.Postgres as Postgres
# Connect to database (URL or parameter format)
db = Postgres.connect "postgresql://user:password@localhost:5432/mydb"
defer Postgres.close db
if Postgres.is-connected? db then
# Query rows
match db.query "SELECT id, name FROM users"
| Ok rows ->
List.each (fn(row) =>
match Map.get "name" row
| Some (DbString name) -> println "User: ${name}"
| _ -> println "NULL"
) rows
| Err e -> println "Query error: ${e}"
# Parameterized query (SQL injection safe)
match db.query-params "SELECT * FROM users WHERE name = $1" ["Alice"]
| Ok rows -> println "Found ${List.length rows} users"
| Err e -> println "Error: ${e}"
# Execute statements (INSERT, UPDATE, DELETE)
match db.execute "INSERT INTO users (name) VALUES ('Bob')"
| Ok _ -> println "Inserted"
| Err e -> println "Error: ${e}"
# Parameterized execute
match db.execute-params "UPDATE users SET name = $1 WHERE id = $2" ["Charlie", "1"]
| Ok _ -> println "Updated"
| Err e -> println "Error: ${e}"
# Escape string for safe SQL inclusion
escaped = db.escape "O'Brien"
println "Escaped: ${escaped}"
else
println "Connection failed"Development
Running Examples
Run examples with the interpreter:
kit run examples/postgres.kitCompile examples to a native binary:
kit build examples/postgres.kit -o postgres && ./postgresRunning Tests
Run the test suite:
kit testRun the test suite with coverage:
kit test --coverageRunning kit dev
Run the standard development workflow (format, check, test):
kit devThis will:
- Format and check source files in
src/ - Run tests in
tests/with coverage
Generating Documentation
Generate API documentation from doc comments:
kit docNote: Kit sources with doc comments (##) will generate HTML documents in docs/*.html
Cleaning Build Artifacts
Remove generated files, caches, and build artifacts:
kit task cleanNote: Defined in kit.toml.
Local Installation
To install this package locally for development:
kit installThis installs the package to ~/.kit/packages/@kit/postgres/, making it available for import as Kit.Postgres in other projects.
License
This package is released under the MIT License - see LICENSE for details.
Exported Functions & Types
connection-ok
Connection established successfully
connection-bad
Connection failed or was terminated
pgres-empty-query
Query returned no results (empty query string)
pgres-command-ok
Command completed successfully without returning rows (INSERT, UPDATE, DELETE, etc.)
pgres-tuples-ok
Query completed successfully and returned rows
pgres-copy-out
Server is ready to send COPY data to client
pgres-copy-in
Server is ready to receive COPY data from client
pgres-bad-response
Server sent a response the client could not understand
pgres-nonfatal-error
Non-fatal error occurred (notice or warning)
pgres-fatal-error
Fatal error occurred during query execution
PostgresError
PostgreSQL error type for typed error handling. Variants distinguish between different failure modes.
Variants
PostgresConnectionError {message}PostgresQueryError {message}PostgresExecError {message}DbValue
Database value type representing PostgreSQL column values. Row records contain Option DbValue for each column: - None: SQL NULL - Some (DbString s): Scalar string value - Some (DbArray items): Array of strings
match Map.get "tags" row
| Some (DbArray tags) -> List.each println tags
| Some (DbString s) -> println s
| None -> println "NULL"Variants
DbString {String}DbArray {_0}oid-bool
Boolean type
oid-int2
Small integer type (int2, 2 bytes)
oid-int4
Integer type (int4, 4 bytes)
oid-int8
Big integer type (int8, 8 bytes)
oid-float4
Single precision floating point (float4, 4 bytes)
oid-float8
Double precision floating point (float8, 8 bytes)
oid-numeric
Arbitrary precision numeric type
oid-text
Variable-length text type
oid-varchar
Variable-length character type with limit
oid-char
Single character type
oid-bpchar
Blank-padded fixed-length character type
oid-name
Internal name type (63-byte fixed length)
oid-date
Calendar date type (year, month, day)
oid-time
Time of day type (no time zone)
oid-timestamp
Date and time type (no time zone)
oid-timestamptz
Date and time type with time zone
oid-interval
Time interval type
oid-uuid
Universally unique identifier type
oid-json
JSON text type
oid-jsonb
Binary JSON type (decomposed, indexed)
oid-bytea
Binary data type (byte array)
oid-bool-array
Boolean array type
oid-int2-array
Small integer array type
oid-int4-array
Integer array type
oid-int8-array
Big integer array type
oid-float4-array
Single precision float array type
oid-float8-array
Double precision float array type
oid-numeric-array
Numeric array type
oid-text-array
Text array type
oid-varchar-array
Varchar array type
oid-char-array
Char array type
oid-bpchar-array
Blank-padded char array type
oid-name-array
Name array type
oid-date-array
Date array type
oid-time-array
Time array type
oid-timestamp-array
Timestamp array type
oid-timestamptz-array
Timestamp with time zone array type
oid-uuid-array
UUID array type
oid-json-array
JSON array type
oid-jsonb-array
Binary JSON array type
connect
Note: This module uses Kit's standard Result type (Ok a | Err PostgresError).
Connect to PostgreSQL database and return a connection object.
Parameters:
Connection string format: "host=localhost port=5432 dbname=mydb user=myuser password=secret"
Database URL format: "postgresql://user:password@localhost:5432/mydb" "postgres://user:password@localhost/mydb"
Returns: - handle: Ptr - Internal libpq connection handle- driver: String - "postgres"- connected: Bool - Connection status- error: String - Error message if connection failed- query: Function - Execute query and return rows- execute: Function - Execute statement- escape: Function - Escape string for safe SQL inclusion- query-params: Function - Execute query with $1, $2 parameters- execute-params: Function - Execute statement with $1, $2 parameters
Note: Returns connection object even if connection fails. Check with is-connected?
String -> {handle: Ptr, driver: String, connected: Bool, error: String, query: String -> Result [Map String (Option DbValue)] PostgresError, execute: String -> Result Int PostgresError, escape: String -> String, query-params: String -> [String] -> Result [Map String (Option DbValue)] PostgresError, execute-params: String -> [String] -> Result Int PostgresError}
db = Postgres.connect "postgresql://localhost/mydb"
if Postgres.is-connected? db then
result = db.query "SELECT * FROM users"
# Parameterized query (SQL injection safe)
result = db.query-params "SELECT * FROM users WHERE name = $1" ["Alice"]
try-connect
Try to connect to PostgreSQL database with Result type error handling.
Parameters:
Returns:
Note: Unlike connect, this immediately closes connection on failure.
String -> Result {handle: Ptr, driver: String, connected: Bool, error: String, query: String -> Result [Map String (Option DbValue)] PostgresError, execute: String -> Result Int PostgresError, escape: String -> String, query-params: String -> [String] -> Result [Map String (Option DbValue)] PostgresError, execute-params: String -> [String] -> Result Int PostgresError} PostgresError
match Postgres.try-connect "postgresql://user:pass@localhost/mydb"
| Ok db ->
result = db.query "SELECT * FROM users"
Postgres.close db
| Err e ->
print "Connection failed: ${PostgresError.message e}"
is-connected?
Check if a database connection is currently valid and active.
Parameters:
Returns:
{connected: Bool} -> Bool
if Postgres.is-connected? db then
# Perform queries
close
Close a database connection and release associated resources.
Parameters:
Returns:
Note: Always close connections when done to free resources.
{handle: Ptr} -> Unit
db = Postgres.connect "postgresql://localhost/mydb"
# ... use db ...
Postgres.close db
query
Execute a query and return all rows as a list of records.
Parameters:
Returns:
Row format: - Each row is a Record (map) with column names as keys - Values are Option DbValue: - None: SQL NULL - Some (DbString s): Scalar value as string - Some (DbArray items): PostgreSQL array as List String
Array columns are automatically parsed from PostgreSQL text format.
Ptr -> NonEmptyString -> Result [Map String (Option DbValue)] PostgresError
match Map.get "name" row
| Some (DbString name) -> println "Name: ${name}"
| _ -> println "No name"
match Map.get "tags" row
| Some (DbArray tags) -> List.each println tags
| _ -> println "No tags"
match query handle "SELECT id, name FROM users"
| Ok rows ->
List.each (fn(row) =>
match Map.get "name" row
| Some (Some name) -> print name
| Some None -> print "NULL"
| None -> print "Column not found"
) rows
| Err e -> print "Error: ${PostgresError.show e}"
execute
Execute a SQL statement (INSERT, UPDATE, DELETE, CREATE, etc.).
Parameters:
Returns:
Note: Use for statements that don't return rows (INSERT, UPDATE, DELETE, CREATE, DROP, etc.)
Ptr -> NonEmptyString -> Result Int PostgresError
match execute handle "INSERT INTO users (name) VALUES ('Alice')"
| Ok _ -> print "Statement executed"
| Err e -> print "Error: ${PostgresError.show e}"
escape
Escape a string value for safe inclusion in SQL queries.
Parameters:
Returns:
Note: Uses libpq's PQescapeLiteral for proper escaping with correct memory management. The returned string includes surrounding quotes, so use it directly: "WHERE name = ${escaped}" NOT "WHERE name = '${escaped}'"
Ptr -> String -> String
escaped = escape handle "O'Brien"
# => "'O''Brien'"
query-str = "SELECT * FROM users WHERE name = ${escaped}"
query-params
Execute a query with parameterized values for SQL injection protection.
Parameters:
Returns:
Note: Uses native PQexecParams for proper parameterized queries. Parameters are 1-indexed ($1 is first parameter).
Ptr -> NonEmptyString -> [String] -> Result [Map String (Option DbValue)] PostgresError
match query-params handle "SELECT * FROM users WHERE name = $1 AND status = $2" ["Alice", "active"]
| Ok rows -> process rows
| Err e -> print "Error: ${PostgresError.show e}"
execute-params
Execute a statement with parameterized values for SQL injection protection.
Parameters:
Returns:
Ptr -> NonEmptyString -> [String] -> Result Int PostgresError
match execute-params handle "INSERT INTO users (name, email) VALUES ($1, $2)" ["Alice", "alice@example.com"]
| Ok _ -> print "Inserted"
| Err e -> print "Error: ${PostgresError.show e}"
parse-array
Parse a PostgreSQL text-format array string into a list of strings.
Handles the PostgreSQL array text representation format: - Empty arrays: {} -> [] - Simple values: {a,b,c} -> ["a", "b", "c"] - Quoted values: {"hello world","with,comma"} -> ["hello world", "with,comma"] - Escaped quotes: {"say \"hello\""} -> ["say \"hello\""] - Escaped backslashes: {"back\\slash"} -> ["back\slash"] - NULL values: {a,NULL,b} -> ["a", None, "b"] (represented as empty string)
Note: This handles 1-dimensional arrays. Nested arrays are returned as raw strings.
String -> [String]