Oliphaunt

Build A Binding

Build a language binding over opaque C handles, raw protocol bytes, explicit response ownership, lifecycle, extensions, and backup APIs.

Use the C ABI when building language bindings or platform SDKs. App developers usually choose Rust, Swift, Kotlin, React Native, TypeScript, or WASM instead.

The C ABI is a binding boundary

Use this surface when you need opaque handles, explicit response ownership, and the native runtime boundary. App-facing SDKs own typed queries and platform lifecycle integration.

C ABI setup path

Native runtime ownership and ABI rules

liboliphaunt
direct ABI

Install

Use released headers, libraries, and runtime assets

Target

New language bindings

SDK owns

Opaque handles, raw protocol bytes, response ownership, and lifecycle.

Verify first

Open an opaque handle, send protocol bytes, free responses, and close cleanly.

Consume released headers, libraries, and native runtime assets.
Open an opaque handle and manage response ownership explicitly.
Build language bindings that expose capabilities, errors, lifecycle, and backup APIs.

Install

Consume the released headers, libraries, and runtime assets for your target. Language bindings package those artifacts through the target ecosystem so app developers install one SDK surface.

Open and query

Open a root, send raw protocol bytes, read backend messages, and close the handle.

#include <oliphaunt.h>
#include <string.h>

OliphauntConfig config = {
    .abi_version = OLIPHAUNT_ABI_VERSION,
    .pgdata = "/app/data/main.oliphaunt/pgdata",
    .username = "app",
    .database = "app",
};

OliphauntHandle *db = NULL;
int rc = oliphaunt_init(&config, &db);
if (rc != 0) {
    return rc;
}

OliphauntResponse response = {0};
const char *sql = "SELECT 1::text AS value";
rc = oliphaunt_exec_simple_query(db, sql, strlen(sql), &response);
oliphaunt_free_response(&response);
oliphaunt_close(db);

Higher-level SDKs own SQL builders, typed parsing, async scheduling, resource selection, and lifecycle integration.

Configure

Configure root, mode, selected extensions, runtime resource paths, startup identity, durability, and owner identity through the ABI config surface.

Choose a mode

The ABI exposes capabilities for the selected target. Direct mode owns one serialized embedded session. Broker and server support appear only when the target runtime advertises those modes.

Handle lifecycle

Each binding runs calls through a single owner queue or equivalent serial executor. A host with exactly one serialized lifetime owner can terminate the resident runtime with oliphaunt_close. A binding with independent environment, worker, or finalizer cleanup owners must instead capture oliphaunt_logical_generation(db) immediately after a successful init and pass only that token to oliphaunt_close_if_generation during teardown. A stale owner receives a positive non-error result while a newer logical lease remains active, instead of closing that lease. If terminal close already completed, the same cleanup is satisfied with zero. Close rejects queued work and waits for active work according to the SDK's platform contract.

Select extensions

Pass exact SQL extension names and resource paths. The ABI loads selected extension artifacts and their declared dependencies.

Back up and restore

Use ABI backup and restore calls for supported physical archive formats. Bindings validate user input before crossing the ABI boundary.

This guide is complete when

Use these checks before moving from a first query to application code.

Handle lifecycle

A binding can open an opaque handle, send protocol bytes, free responses, and close cleanly.

Ownership

The binding exposes response ownership, last-error reads, capabilities, and close state directly.

Runtime assets

The app carries only the native runtime and exact extension artifacts selected by the binding.

Language surface

The public wrapper uses platform-native async, errors, and buffers over the C ABI.

Open the C ABI API map

Troubleshooting

Inspect ABI error codes, oliphaunt_last_error/Oliphaunt error fields, missing runtime resources, root locks, mode capability errors, and PostgreSQL SQLSTATE data.

On this page