harn-stdlib 0.8.51

Embedded Harn standard library source catalog
Documentation
/**
 * std/postgres — Postgres persistence helpers.
 *
 * The pg_* functions are VM builtins registered by the Rust stdlib. This
 * module carries the public handle and result shapes so import-aware
 * tools and the typechecker know what scripts get back from the runtime.
 *
 * v1 surface (issue #2500):
 *
 *   let pool = pg_pool("env:DATABASE_URL", {max_connections: 5})
 *   pg_execute(pool, "insert into ledger (id, amount) values ($1, $2)", [id, amount])
 *   let row = pg_query_one(pool, "select balance from ledger where id = $1", [id])
 *
 *   pg_transaction(pool, { tx ->
 *     pg_savepoint(tx, "before_charge")
 *     pg_execute(tx, "update ledger set balance = balance - $1 where id = $2", [amount, id])
 *     if (balance_after_too_low()) {
 *       pg_rollback_to_savepoint(tx, "before_charge")
 *     } else {
 *       pg_release_savepoint(tx, "before_charge")
 *     }
 *   })
 *
 *   pg_migrate(pool, {dir: "./migrations"})  // applies pending .sql files
 *
 * v2 surface (issue #2512):
 *
 *   // Advisory locks (transaction-scoped, auto-released on commit/rollback).
 *   pg_transaction(pool, { tx ->
 *     pg_advisory_xact_lock(tx, "release-cut", {tenant_namespace: true})
 *     // ...
 *   })
 *   pg_with_advisory_lock(pool, 0x1234, { tx -> /* exclusive section */ })
 *
 *   // LISTEN/NOTIFY with auto-reconnect (sqlx's PgListener).
 *   let listener = pg_listen(pool, ["receipts.updated", "captain.notice"])
 *   let notification = pg_listener_recv(listener, 5000)  // timeout in ms
 *   pg_listener_close(listener)
 *   pg_notify(pool, "receipts.updated", {receipt_id: "r1"})
 *
 *   // Pool + statement-cache + circuit-breaker observability.
 *   let stats = pg_pool_stats(pool)
 *     // → {size, idle, in_use, max_connections, statement_cache_capacity,
 *     //    replicas, circuit_state, circuit_failures, circuit_opened_at_ms}
 *
 *   // Schema introspection.
 *   pg_introspect_tables(pool, {schema: "public"})
 *   pg_introspect_columns(pool, "receipts")
 *   pg_introspect_indexes(pool, "receipts")
 *
 *   // Declarative partition helpers (pg_partman-style, no extension).
 *   pg_partition_attach(pool, "events", "events_2026_05",
 *                       {from: "2026-05-01", to: "2026-06-01"})  // RANGE
 *   pg_partition_attach(pool, "events", "events_h0",
 *                       {modulus: 4, remainder: 0})              // HASH
 *   pg_partition_detach(pool, "events", "events_2026_03")
 *   pg_partition_prune(pool, "events", "2026-01-01")   // recurses sub-partition trees
 *   pg_partition_retain(pool, "events", {keep_days: 90})         // retention policy
 *   pg_partition_create_for_window(pool, "events",
 *                       {interval: "day", ahead: 7})  // pre-create next 7 days
 *
 *   // Read-replica routing (per-query opt-in).
 *   let pool = pg_pool("env:DATABASE_URL", {
 *     max_connections: 10,
 *     replicas: ["env:DATABASE_REPLICA_URL", "env:DATABASE_REPLICA2_URL"],
 *     circuit_breaker: {failure_threshold: 5, reset_after_ms: 30000},
 *   })
 *   pg_query(pool, "select * from receipts where id = $1", [id], {read_only: true})
 *
 * `pg_mock_pool(fixtures)` returns a deterministic mock so unit tests do
 * not need a live database.
 */
type PgPool = {_type: "pg_pool", id: string}

type PgTx = {_type: "pg_tx", id: string}

type PgMockPool = {_type: "pg_mock_pool", id: string}

type PgListener = {_type: "pg_listener", id: string}

type PgHandle = PgPool | PgTx | PgMockPool

type PgExecuteResult = {rows_affected: int, duration_ms: int}

type PgMigrateResult = {
  applied: list<string>,
  skipped: list<string>,
  available: list<string>,
  dry_run: bool,
  duration_ms: int,
  table: string,
}

type PgPoolStats = {
  size: int,
  idle: int,
  in_use: int,
  max_connections: int,
  statement_cache_capacity: int,
  replicas: int,
  circuit_state: string,
  circuit_failures: int,
  circuit_opened_at_ms: int?,
}

type PgIntrospectedTable = {schema: string, table: string, kind: string}

type PgIntrospectedColumn = {
  column: string,
  type: string,
  data_type: string,
  nullable: bool,
  default: string?,
}

type PgIntrospectedIndex = {index: string, columns: list<string>, unique: bool, primary: bool}

type PgNotification = {channel: string, payload: string, process_id: int}