zpg Logo thienpow / zpg Home

Welcome to zpg

zpg is a native PostgreSQL client library for the Zig programming language. It aims to provide a robust, efficient, and easy-to-use interface for interacting with PostgreSQL databases, supporting both simple and extended query protocols, connection pooling, transactions, and a variety of data types.

Features

Installation

Add zpg as a dependency to your build.zig.zon file (details depend on your project setup and dependency management approach).

// Example entry in build.zig.zon (adjust path/URL/hash as needed)
.zpg = .{
    .url = "https://github.com/your_username/zpg/archive/refs/tags/v0.1.0.tar.gz", // Or git dependency
    .hash = "...", // Replace with actual hash
},

Then, add the package to your build.zig:

// In build.zig
const zpg_dep = b.dependency("zpg", .{
    .target = target,
    .optimize = optimize,
});

exe.addModule("zpg", zpg_dep.module("zpg"));

Quick Start

const std = @import("std");
const zpg = @import("zpg");

const User = struct {
    id: i64,
    username: []const u8,

    pub fn deinit(self: User, allocator: std.mem.Allocator) void {
        allocator.free(self.username);
    }
};

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = gpa.allocator();
    defer _ = gpa.deinit();

    // 1. Configure Connection
    const config = zpg.Config{
        .host = "127.0.0.1",
        .port = 5432,
        .username = "postgres",
        .database = "zui", // Your database name
        .password = "postgres", // Your password
        .tls_mode = .disable, // Or .prefer / .require
    };

    // 2. Initialize Connection Pool
    var pool = try zpg.ConnectionPool.init(allocator, config, 3); // Pool of 3 connections
    defer pool.deinit();

    // 3. Get a Pooled Connection
    var pconn = try zpg.PooledConnection.init(&pool, null); // null for no RLS context
    defer pconn.deinit(); // Automatically returns the connection to the pool

    // 4. Create a Query object
    var query = pconn.createQuery(allocator);
    defer query.deinit();

    // 5. Run a simple SELECT query
    const result = try query.run("SELECT id, username FROM users WHERE id = 1", User);

    // 6. Process Results
    switch (result) {
        .select => |users| {
            defer allocator.free(users); // Free the result slice
            std.debug.print("Found {d} user(s):\n", .{users.len});
            for (users) |user| {
                defer user.deinit(allocator); // Free user's allocated fields
                std.debug.print(" - ID: {d}, Username: {s}\n", .{ user.id, user.username });
            }
        },
        .command => |count| {
            std.debug.print("Command affected {d} rows.\n", .{count});
        },
        .success => |ok| {
            std.debug.print("Command success: {}\n", .{ok});
        },
        .explain => |plan| {
             defer {
                 for(plan) |row| row.deinit(allocator);
                 allocator.free(plan);
             }
            std.debug.print("Explain plan received.\n", .{});
            // Process plan rows
        }
    }
}

On This Page