# 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).

