GizStack
View .mdOpen in ChatGPTOpen in Claude

gizlang:postgres

PostgreSQL protocol v3 over System's Stream. One operation owns a connection until ReadyForQuery; rows are owned UTF-8 text, SQL NULL is Option.none().

gizlang
import * as Postgres from "gizlang:postgres";

Types

Options

gizlang
type Options = { host: string; port: i64; user: string; password: string; database: string; tls?: string; }

How to connect to a PostgreSQL server: host, port, user, password and database; with tls, over TLS, the server's certificate checked for its host against the authorities in that PEM file, or the system's when it is "".

  • host: string
  • port: i64
  • user: string
  • password: string
  • database: string
  • tls: _gizlang_sdk_core.Option<string>

PgError

gizlang
type PgError = { sqlstate: string; message: string; detail: string; position: Option<i64>; code: i64; }

SQLSTATE is empty for transport/protocol errors; code preserves IoError.code.

  • sqlstate: string
  • message: string
  • detail: string
  • position: _gizlang_sdk_core.Option<i64>
  • code: i64

Rows

gizlang
type Rows = { columns: Vec<string>; types: Vec<i64>; rows: Vec<Vec<Option<string>>>; command: string; affected: i64; }

A result: column names, their type OIDs, the rows as text, and the command tag.

  • columns: Vec<string>
  • types: Vec<i64>
  • rows: Vec<Vec<_gizlang_sdk_core.Option<string>>>
  • command: string
  • affected: i64

Connection

gizlang
type Connection

A connection to a PostgreSQL server.

Opaque: create and use it through this module's functions.

CString

gizlang
type CString = { value: string; next: i64; }

A complete, valid UTF-8 wire string and its next byte offset.

  • value: string
  • next: i64

Run

gizlang
type Run = { sql: string; params: Vec<Option<string>>; }

One statement run: sql with its text params.

  • sql: string
  • params: Vec<_gizlang_sdk_core.Option<string>>

Pool

gizlang
type Pool

A fixed set of connections that tasks share: with lends one (waiting while all are lent) and takes it back when the work returns. Work returns Result<T, E>, and failure projects a failed loan, as a transaction does. A connection is lent only idle: one the work left closed, busy or inside a transaction is closed and opened again on its next loan. A fault in the work ends its task with the connection. query runs one statement of many tasks at once: the runs that wait while every connection is busy go out in one write on the next free connection, so a busy pool pays one round trip (two system calls) for many runs instead of one each. A fault in a leading task, as in work, leaves the runs it took unanswered.

Opaque: create and use it through this module's functions.

Functions

optionsOf

gizlang
function optionsOf(url: string): Options throws PgError

Parse postgres://USER:PASSWORD@HOST:PORT/DATABASE without percent escapes; without :PASSWORD the password is empty, as libpq reads it (a server that trusts the client asks for none). Parameters after ? as libpq: host=/FOLDER selects the Unix socket folder (HOST can then be empty); sslmode=require, verify-ca or verify-full connect with TLS and always check the server's certificate and name (stricter than libpq's require), against sslrootcert=FILE when given; disable, allow and prefer go on in the clear. Other parameters are ignored.

Effects: fail.

url

gizlang
function url(options: Options): string

Write the connection URL without percent escapes. A host that starts with / is a Unix socket folder, written as an empty HOST and ?host=/FOLDER.

Effects: fail.

writeMessage

gizlang
function writeMessage(out: mut bytes, tag: u64, body: bytes): void

The protocol's writers and lenient reader, shared by this client and GizDB's server and router (db/pg): one encoding of the wire. A message is a tag, its length (itself included) and its body.

Effects: fail.

writeCString

gizlang
function writeCString(out: mut bytes, value: string): void

Appends VALUE and a 0 byte, as the protocol writes text.

Effects: fail.

cstringAt

gizlang
function cstringAt(b: bytes, at: i64): string

The text from AT to the next 0 byte or the end ("" past the end).

Effects: fail.

commandComplete

gizlang
function commandComplete(out: mut bytes, tag: string): void

Appends a CommandComplete message with TAG ("SELECT 1").

Effects: fail.

checkedCStringAt

gizlang
function checkedCStringAt(data: bytes, at: i64): CString throws PgError

The text from AT to the next 0 byte, and the offset after it. It fails when AT is out of range or no 0 byte follows.

Effects: fail.

fatalMessage

gizlang
function fatalMessage(code: string, text: string): bytes

An ErrorResponse of severity FATAL with SQLSTATE CODE.

Effects: fail.

connect

gizlang
function connect(sys: System, options: Options): Connection throws PgError

A connection to the server of OPTIONS, after startup and authentication.

Effects: fail, write, io.

pool

gizlang
function pool(sys: System, options: Options, size: i64): Pool throws PgError requires size> = 1 { const idle = Task.channel<Connection>(size)

A pool of SIZE connections to the server of OPTIONS. Concurrent runs share the connections.

Effects: fail, read, write, io.

boolean

gizlang
function boolean(value: Option<string>): Option<bool>

Decoding reuses Text's parsers; no duplicate numeric conversion API. SQL booleans have one PostgreSQL spelling, so this is the only extra decoder.

dial

gizlang
function dial(sys: System, options: Options): Stream throws PgError

A byte stream to the server of OPTIONS, before any message: a relay (a front that reads the startup itself) uses it as connect does. As libpq, a host starting with "/" is the folder of the server's unix-domain socket.

Effects: fail, io.

Methods

Connection.timeout

gizlang
function Connection.timeout(self: Connection, milliseconds: i64): i64 throws PgError

Limits how long each read or write of the connection may wait, in milliseconds (0 waits forever, the start): a call that waits longer fails, and the connection should then be closed (Stream.timeout).

Effects: fail, read, io.

Connection.close

gizlang
function Connection.close(self: Connection): bool

Sends Terminate and closes the connection. It does nothing after the first call.

Effects: fail, read, write, io.

Connection.query

gizlang
function Connection.query(self: Connection, sql: string, params: Vec<Option<string>>): Rows throws PgError

One run: Parse/Bind/Describe/Execute/Sync in one write. Values are copied into that buffer once; the server infers parameter OIDs from SQL. The first run of a SQL text prepares it under a name with its result columns, so later runs send only Bind/Execute/Sync and the server neither parses nor plans it again (after five runs PostgreSQL may keep a generic plan). A statement the server no longer accepts as prepared (DDL changed what it returns) is forgotten and prepared again on its next run.

Effects: fail, read, write, io.

Connection.queryEach

gizlang
function Connection.queryEach(self: Connection, sql: string, batch: Vec<Vec<Option<string>>>): Vec<Rows> throws PgError

sql once per parameter list of batch, pipelined (TechEmpower's queries test: 20 SELECTs of one row). A failed run does not stop the others. Its error, the first one, is returned after every answer was read, and the runs before and after it still took effect.

Effects: fail, read, write, io.

Connection.pipelined

gizlang
function Connection.pipelined(self: Connection, runs: Vec<Run>): Vec<Result<Rows, PgError>>

runs written in one buffer before any answer is read, so N runs cost one round trip instead of N; their answers in order. Each run ends at its own Sync, so it is its own implicit transaction and fails alone; an invalid one is not sent. A transport or protocol error closes the connection and fails every run not yet answered.

Effects: fail, read, write, io.

Connection.exec

gizlang
function Connection.exec(self: Connection, sql: string): Vec<Rows> throws PgError

The results of each statement of the script SQL, run with the simple query protocol.

Effects: fail, read, write, io.

Connection.copy

gizlang
function Connection.copy(self: Connection, sql: string, input: Option<bytes>): Vec<Rows> throws PgError

The script, as exec; a COPY FROM STDIN in it reads input.

Effects: fail, read, write, io.

Connection.transaction

gizlang
function Connection.transaction<F, E>(self: Connection, work: F, failure: (error: PgError) => E): ReturnType<F>

Work receives the same connection and returns Result<T, E>; failure projects this module's own PgError (BEGIN, COMMIT) into E. A returned error rolls back and reaches the caller unchanged; a commit error also rolls back. Nested helpers are refused.

Pool.with

gizlang
function Pool.with<F, E>(self: Pool, work: F, failure: (error: PgError) => E): ReturnType<F>

Runs WORK with a connection from the pool, then gives the connection back. FAILURE maps an error that gets no connection.

Pool.query

gizlang
function Pool.query(self: Pool, sql: string, params: Vec<Option<string>>): Rows throws PgError

One run of sql on a connection of the pool, pipelined with the runs of other tasks (see Pool). It waits while the pool has SLOTS runs in flight for each connection.

Effects: fail, read, write, console, io.

Pool.close

gizlang
function Pool.close(self: Pool): void

Waits for every connection to come back, then closes them and the pool.

Effects: fail, read, write, io.

Constants

PROTOCOL_VERSION

gizlang
const PROTOCOL_VERSION = 196608

The protocol version 3.0 that a startup message carries.

SSL_REQUEST

gizlang
const SSL_REQUEST = 80877103

The request code of an SSL negotiation.

GSS_REQUEST

gizlang
const GSS_REQUEST = 80877104

The request code of a GSS encryption negotiation.

CANCEL_REQUEST

gizlang
const CANCEL_REQUEST = 80877102

The request code of a query cancel.

MAX_STARTUP_BYTES

gizlang
const MAX_STARTUP_BYTES = 10000

The most bytes of a startup message.

MAX_MESSAGE_BYTES

gizlang
const MAX_MESSAGE_BYTES = 1073741824

The most bytes of one message.

BOOL_OID

gizlang
const BOOL_OID = 16

The PostgreSQL type OID of bool.

BYTEA_OID

gizlang
const BYTEA_OID = 17

The PostgreSQL type OID of bytea.

INT8_OID

gizlang
const INT8_OID = 20

The PostgreSQL type OID of int8.

INT2_OID

gizlang
const INT2_OID = 21

The PostgreSQL type OID of int2.

INT4_OID

gizlang
const INT4_OID = 23

The PostgreSQL type OID of int4.

TEXT_OID

gizlang
const TEXT_OID = 25

The PostgreSQL type OID of text.

FLOAT4_OID

gizlang
const FLOAT4_OID = 700

The PostgreSQL type OID of float4.

FLOAT8_OID

gizlang
const FLOAT8_OID = 701

The PostgreSQL type OID of float8.

BPCHAR_OID

gizlang
const BPCHAR_OID = 1042

The PostgreSQL type OID of bpchar.

VARCHAR_OID

gizlang
const VARCHAR_OID = 1043

The PostgreSQL type OID of varchar.

DATE_OID

gizlang
const DATE_OID = 1082

The PostgreSQL type OID of date.

TIME_OID

gizlang
const TIME_OID = 1083

The PostgreSQL type OID of time.

TIMESTAMP_OID

gizlang
const TIMESTAMP_OID = 1114

The PostgreSQL type OID of timestamp.

TIMESTAMPTZ_OID

gizlang
const TIMESTAMPTZ_OID = 1184

The PostgreSQL type OID of timestamptz.

NUMERIC_OID

gizlang
const NUMERIC_OID = 1700

The PostgreSQL type OID of numeric.

QUERY

gizlang
const QUERY = 81u

The tag byte Q of the query message.

PARSE

gizlang
const PARSE = 80u

The tag byte P of the parse message.

BIND

gizlang
const BIND = 66u

The tag byte B of the bind message.

DESCRIBE

gizlang
const DESCRIBE = 68u

The tag byte D of the describe message.

EXECUTE

gizlang
const EXECUTE = 69u

The tag byte E of the execute message.

CLOSE

gizlang
const CLOSE = 67u

The tag byte C of the close message.

SYNC

gizlang
const SYNC = 83u

The tag byte S of the sync message.

FLUSH

gizlang
const FLUSH = 72u

The tag byte H of the flush message.

TERMINATE

gizlang
const TERMINATE = 88u

The tag byte X of the terminate message.

PASSWORD

gizlang
const PASSWORD = 112u

The tag byte p of the password message.

COPY_DATA

gizlang
const COPY_DATA = 100u

The tag byte d of the copy data message.

COPY_DONE

gizlang
const COPY_DONE = 99u

The tag byte c of the copy done message.

COPY_FAIL

gizlang
const COPY_FAIL = 102u

The tag byte f of the copy fail message.

AUTHENTICATION

gizlang
const AUTHENTICATION = 82u

The tag byte R of the authentication message.

BACKEND_KEY_DATA

gizlang
const BACKEND_KEY_DATA = 75u

The tag byte K of the backend key data message.

COMMAND_COMPLETE

gizlang
const COMMAND_COMPLETE = 67u

The tag byte C of the command complete message.

ERROR_RESPONSE

gizlang
const ERROR_RESPONSE = 69u

The tag byte E of the error response message.

NOTICE_RESPONSE

gizlang
const NOTICE_RESPONSE = 78u

The tag byte N of the notice response message.

PARSE_COMPLETE

gizlang
const PARSE_COMPLETE = 49u

The tag byte 1 of the parse complete message.

BIND_COMPLETE

gizlang
const BIND_COMPLETE = 50u

The tag byte 2 of the bind complete message.

CLOSE_COMPLETE

gizlang
const CLOSE_COMPLETE = 51u

The tag byte 3 of the close complete message.

ROW_DESCRIPTION

gizlang
const ROW_DESCRIPTION = 84u

The tag byte T of the row description message.

DATA_ROW

gizlang
const DATA_ROW = 68u

The tag byte D of the data row message.

PARAMETER_DESCRIPTION

gizlang
const PARAMETER_DESCRIPTION = 116u

The tag byte t of the parameter description message.

PARAMETER_STATUS

gizlang
const PARAMETER_STATUS = 83u

The tag byte S of the parameter status message.

READY_FOR_QUERY

gizlang
const READY_FOR_QUERY = 90u

The tag byte Z of the ready for query message.

EMPTY_QUERY_RESPONSE

gizlang
const EMPTY_QUERY_RESPONSE = 73u

The tag byte I of the empty query response message.

PORTAL_SUSPENDED

gizlang
const PORTAL_SUSPENDED = 115u

The tag byte s of the portal suspended message.

NO_DATA

gizlang
const NO_DATA = 110u

The tag byte n of the no data message.

NOTIFICATION_RESPONSE

gizlang
const NOTIFICATION_RESPONSE = 65u

The tag byte A of the notification response message.

COPY_IN_RESPONSE

gizlang
const COPY_IN_RESPONSE = 71u

The tag byte G of the copy in response message.

COPY_OUT_RESPONSE

gizlang
const COPY_OUT_RESPONSE = 72u

The tag byte H of the copy out response message.

COPY_BOTH_RESPONSE

gizlang
const COPY_BOTH_RESPONSE = 87u

The tag byte W of the copy both response message.

SQLSTATE_FIELD

gizlang
const SQLSTATE_FIELD = 67u

The tag byte C of the sqlstate field message.

MESSAGE_FIELD

gizlang
const MESSAGE_FIELD = 77u

The tag byte M of the message field message.

DETAIL_FIELD

gizlang
const DETAIL_FIELD = 68u

The tag byte D of the detail field message.

POSITION_FIELD

gizlang
const POSITION_FIELD = 80u

The tag byte P of the position field message.

SEVERITY_FIELD

gizlang
const SEVERITY_FIELD = 83u

The tag byte S of the severity field message.

SEVERITY_UNLOCALIZED_FIELD

gizlang
const SEVERITY_UNLOCALIZED_FIELD = 86u

The tag byte V of the severity unlocalized field message.

TARGET_STATEMENT

gizlang
const TARGET_STATEMENT = 83u

The tag byte S of the target statement message.

TARGET_PORTAL

gizlang
const TARGET_PORTAL = 80u

The tag byte P of the target portal message.

TRANSACTION_IDLE

gizlang
const TRANSACTION_IDLE = 73u

The tag byte I of the transaction idle message.

TRANSACTION_ACTIVE

gizlang
const TRANSACTION_ACTIVE = 84u

The tag byte T of the transaction active message.

TRANSACTION_FAILED

gizlang
const TRANSACTION_FAILED = 69u

The tag byte E of the transaction failed message.

AUTH_OK

gizlang
const AUTH_OK = 0

The authentication request code 0: ok (the server's answer to a startup).

AUTH_PASSWORD

gizlang
const AUTH_PASSWORD = 3

The authentication request code 3: password (the server's answer to a startup).

AUTH_MD5

gizlang
const AUTH_MD5 = 5

The authentication request code 5: md5 (the server's answer to a startup).

AUTH_SASL

gizlang
const AUTH_SASL = 10

The authentication request code 10: sasl (the server's answer to a startup).

AUTH_SASL_CONTINUE

gizlang
const AUTH_SASL_CONTINUE = 11

The authentication request code 11: sasl continue (the server's answer to a startup).

AUTH_SASL_FINAL

gizlang
const AUTH_SASL_FINAL = 12

The authentication request code 12: sasl final (the server's answer to a startup).