# gizdb:access

The native application boundary of db/server's existing actor. This module owns session/cursor delivery, never an Engine, storage ledger, executor or change log.

```gizlang
import * as Access from "gizdb:access";
```

## Types

### `Config`

```gizlang
type Config = { authority: Security.Authority; maxSessions: i64; maxCursors: i64; budget: ExecutionBudget; leaseMs: i64; }
```

The settings of an actor: the authority that admits principals, the most sessions and cursors, the execution budget,
and how long a watch lives without a read.

- `authority`: `gizlang_security.Authority`
- `maxSessions`: `i64`
- `maxCursors`: `i64`
- `budget`: `_gizlang_lib_db__sql__exec__execenv.ExecutionBudget`
- `leaseMs`: `i64`

### `Token`

```gizlang
type Token
```

A data session or resource: its number and the actor's keyed proof of it, so a token crosses
threads as a plain value and still cannot be forged.

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

### `Definition`

```gizlang
type Definition = { tree: Select; parameters: Vec<Typed.Slot>; outputs: Vec<Typed.Slot>; values: Vec<Value>; meaning: bytes; sql: string; }
```

A read: its tree, slots and values, and SQL, the text of the statement that its plan is kept under ("" for none).

- `tree`: `_gizlang_lib_db__sql__ast.Select`
- `parameters`: `Vec<M54.Slot>`
- `outputs`: `Vec<M54.Slot>`
- `values`: `Vec<M55.Value>`
- `meaning`: `bytes`
- `sql`: `string`

### `Control`

```gizlang
type Control = | { kind: "load"; collection: string; identity: string; } | { kind: "store"; collection: string; identity: string; expected: i64; payload: string; }
```

A catalog command of a session: load a record of a collection, or store one when its version is EXPECTED.

- `load`
- `store`

### `Command`

```gizlang
type Command = | { kind: "transaction"; session: Token; transaction: Option<Token>; operation: TransactionCommand; } | { kind: "control"; session: Token; operation: Control; } | { kind: "connect"; identity: string; secret: bytes; } | { kind: "frontier"; session: Token; } | { kind: "proveKey"; session: Token; table: string; keys: Vec<Typed.Slot>; editable: Vec<Typed.Slot>; } | { kind: "publishMetric"; session: Token; model: Semantic.Model; metric: Semantic.Metric; definition: Definition; expected: i64; } | { kind: "read"; session: Token; definition: Definition; } | { kind: "page"; session: Token; reader: Token; rows: i64; bytes: i64; } | { kind: "write"; session: Token; statements: Vec<Statement>; params: Vec<Value>; } | { kind: "apply"; session: Token; statements: Vec<Statement>; params: Vec<Value>; basis: Position; } | { kind: "observe"; session: Token; view: string; definition: Definition; } | { kind: "changes"; session: Token; watch: Token; after: Position; } | { kind: "retire"; session: Token; resource: Token; } | { kind: "disconnect"; session: Token; }
```

What a client asks of the actor: connect, a read, a write, a transaction step, a catalog command, a page of a
reader, the changes of a watch, or disconnect.

- `transaction`
- `control`
- `connect`
- `frontier`
- `proveKey`
- `publishMetric`
- `read`
- `page`
- `write`
- `apply`
- `observe`
- `changes`
- `retire`
- `disconnect`

### `Reply`

```gizlang
type Reply = | { kind: "control"; record: Option<Catalog.Record>; } | { kind: "connected"; session: Token; } | { kind: "opened"; reader: Token; columns: Vec<string>; types: Vec<Type>; position: Position; } | { kind: "batch"; batch: Batch; position: Position; } | { kind: "blocked"; rows: i64; bytes: i64; } | { kind: "yield"; } | { kind: "done"; position: Position; } | { kind: "written"; affected: i64; position: Position; } | { kind: "observed"; watch: Token; columns: Vec<string>; types: Vec<Type>; position: Position; generation: i64; } | { kind: "delta"; delivery: Delivery; } | { kind: "closed"; }
```

What the actor answers to a command.

- `control`
- `connected`
- `opened`
- `batch`
- `blocked`
- `yield`
- `done`
- `written`
- `observed`
- `delta`
- `closed`

### `Request`

```gizlang
type Request = { command: Ref<Command>; answer: Task.Channel<Result<Reply, DbError>>; }
```

A command and the channel of its answer.

- `command`: `Ref<M47.Command>`
- `answer`: `gizlang_task.Channel<_gizlang_sdk_core.Result<M47.Reply, M56.DbError>>`

### `Inbox`

```gizlang
type Inbox = { pending: Vec<Request>; running: Vec<Request>; closed: bool; }
```

The requests the relay queued (`pending`) and those the actor has taken but not answered (`running`): `abort` answers both.

- `pending`: `Vec<M47.Request>`
- `running`: `Vec<M47.Request>`
- `closed`: `bool`

### `Call`

```gizlang
type Call = { command: Command; answer: Task.Channel<Result<Reply, DbError>>; }
```

A command and the channel of its reply, as it crosses threads.

- `command`: `M47.Command`
- `answer`: `gizlang_task.Channel<_gizlang_sdk_core.Result<M47.Reply, M56.DbError>>`

### `Endpoint`

```gizlang
type Endpoint
```

`_commits` counts the commands that changed data, so a reader waits for it to move and then asks (Connection.commits).

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

### `Connection`

```gizlang
type Connection = { endpoint: Endpoint; token: Token; identity: string; }
```

A session with the actor: where it is, its token and the identity that opened it.

- `endpoint`: `M47.Endpoint`
- `token`: `M47.Token`
- `identity`: `string`

### `Transaction`

```gizlang
type Transaction = { connection: Connection; token: Token; }
```

An open transaction of a connection.

- `connection`: `M47.Connection`
- `token`: `M47.Token`

### `Actor`

```gizlang
type Actor = { config: Config; endpoint: Endpoint; stream: Stream; inbox: Ref<Inbox>; wake: Stream; relay: Task.Task<bool>; key: bytes; sessions: Vec<Session>; readers: Vec<Reader>; watches: Vec<Watch>; next: i64; plans: Map<string, Cached>; }
```

`stream` becomes readable when `inbox` has requests: the relay task, on the actor's thread,
moves each Call from the endpoint into the inbox and writes `wake`.

- `config`: `M47.Config`
- `endpoint`: `M47.Endpoint`
- `stream`: `gizlang_system.Stream`
- `inbox`: `Ref<M47.Inbox>`
- `wake`: `gizlang_system.Stream`
- `relay`: `gizlang_task.Task<bool>`
- `key`: `bytes`
- `sessions`: `Vec<M47.Session>`
- `readers`: `Vec<M47.Reader>`
- `watches`: `Vec<M47.Watch>`
- `next`: `i64`
- `plans`: `_gizlang_sdk_collections.Map<string, _gizlang_lib_db__sql__conn.Cached>`

### `Local`

```gizlang
type Local = { connection: Connection; endpoint: Endpoint; identity: string; secret: bytes; authority: Security.Authority; worker: Task.Task<Result<bool, DbError>>; }
```

An embedded database: the data actor in this process, on the database in
`dir`, with `bytes` of memory and of temporary space. Its worker task owns
the engine and ends when the last connection closes; `Local.close` closes
the first connection and waits for it. `authority` holds the principals that may
connect: register more to let them in.

- `connection`: `M47.Connection`
- `endpoint`: `M47.Endpoint`
- `identity`: `string`
- `secret`: `bytes`
- `authority`: `gizlang_security.Authority`
- `worker`: `gizlang_task.Task<_gizlang_sdk_core.Result<bool, M56.DbError>>`

## Functions

### `mailbox`

```gizlang
function mailbox(sys: System): Result<Actor, DbError>
```

An actor with no sessions, and the stream pair that wakes it.

Effects: fail, read, write, io.

### `local`

```gizlang
function local(sys: System, dir: Dir, identity: string, bytes: i64): Result<Local, DbError>
```

An engine in the folder DIR for IDENTITY in this process, with at most BYTES of memory and a connection to it. A
second opener of the folder fails.

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

### `connect`

```gizlang
function connect(endpoint: Endpoint, identity: string, secret: bytes): Result<Connection, DbError>
```

A session for IDENTITY with SECRET at ENDPOINT. It fails when the authority refuses them.

Effects: fail, io.

### `native`

```gizlang
function native(connection: Connection, identity: string): Source.Source
```

The GizDB data source of a connection: every capability, a snapshot read and a watch.

Effects: fail.

### `tokenText`

```gizlang
function tokenText(t: Token): string
```

A token as text ("ID.PROOF"), for a client to hold and give back: it is the capability it names.

Effects: fail.

### `readToken`

```gizlang
function readToken(text: string): Option<Token>
```

The token of its text ("ID.PROOF", tokenText), or none when the text is not one.

Effects: fail.

### `statementKinds`

```gizlang
function statementKinds(sql: string): Result<Vec<string>, string>
```

The kind of each statement in `sql` ("select" for SELECT, WITH and VALUES), or why it does not parse: for a
caller outside GizDB that must refuse some statements before it runs them.

Effects: fail.

## Methods

### `Local.connect`

```gizlang
function Local.connect(self: Local): Result<Connection, DbError>
```

Another connection to the same embedded database.

Effects: fail, io.

### `Local.close`

```gizlang
function Local.close(self: Local): Result<bool, DbError>
```

Close the first connection and wait for the worker; close every other connection first.

Effects: fail, io.

### `Endpoint.call`

```gizlang
function Endpoint.call(self: Endpoint, command: Command): Result<Reply, DbError>
```

One request and its reply, from a task of any thread.

Effects: fail, io.

### `Connection.control`

```gizlang
function Connection.control(self: Connection, operation: Control): Result<Option<Catalog.Record>, DbError>
```

Presentation metadata participates in native CAS, backup and recovery.
It cannot publish semantic certificates or replace an execution checkpoint.

Effects: fail, io.

### `Connection.read`

```gizlang
function Connection.read<P, R>(self: Connection, query: Query.Prepared<P, R>, input: P): Result<Reply, DbError>
```

Runs QUERY with INPUT; the first page of rows and a reader for the rest.

### `Connection.observe`

```gizlang
function Connection.observe<P, R>(self: Connection, view: string, query: Query.Prepared<P, R>, input: P): Result<Reply, DbError>
```

Runs QUERY with INPUT as the live view VIEW; its rows and a watch of its changes.

### `Connection.page`

```gizlang
function Connection.page(self: Connection, reader: Token, rows: i64, bytes: i64): Result<Reply, DbError>
```

The next page of READER: at most ROWS rows and BYTES bytes.

Effects: fail, io.

### `Connection.changes`

```gizlang
function Connection.changes(self: Connection, watch: Token, after: Position): Result<Reply, DbError>
```

The changes of WATCH after the position AFTER.

Effects: fail, io.

### `Connection.commits`

```gizlang
function Connection.commits(self: Connection): i64
```

How many commands have changed data since the actor began.

Effects: io.

### `Connection.write`

```gizlang
function Connection.write(self: Connection, statements: Vec<Statement>, params: Vec<Value>): Result<Reply, DbError>
```

Runs STATEMENTS with PARAMS as one write.

Effects: fail, io.

### `Connection.frontier`

```gizlang
function Connection.frontier(self: Connection): Result<Position, DbError>
```

The position of the last commit that the session can see.

Effects: fail, io.

### `Connection.proveKey`

```gizlang
function Connection.proveKey(self: Connection, table: string, keys: Vec<Typed.Slot>, editable: Vec<Typed.Slot>): Result<bool, DbError>
```

Validate trusted writeback metadata against the actor's actual storage key.
This proof never grants writes: the normal SQL ACL admits every mutation.

Effects: fail, io.

### `Connection.publishMetric`

```gizlang
function Connection.publishMetric<P, R>(self: Connection, model: Semantic.Model, metric: Semantic.Metric, query: Query.Prepared<P, R>, input: P, expected: i64): Result<i64, DbError>
```

Publish the actual calculation/result contract through the authenticated
actor. A web/client certification flag alone never grants certified reads.

### `Connection.apply`

```gizlang
function Connection.apply(self: Connection, statements: Vec<Statement>, params: Vec<Value>, basis: Position, approved: bool): Result<Reply, DbError>
```

A preview is an optimistic receipt, never authority to replay stale work.

Effects: fail, io.

### `Connection.begin`

```gizlang
function Connection.begin(self: Connection): Result<Transaction, DbError>
```

One actor session owns one open transaction, with an absolute lease.
BEGIN requests REPEATABLE READ: the engine keeps one snapshot and checks
write conflicts. It does not validate every read as SERIALIZABLE does.
The isolation tests cover same-row updates and disjoint-row write skew.
Readers retain the staged image at read(), until the transaction ends.
A failed write, expired lease or closed connection rolls back the whole tx.

Effects: fail, io.

### `Transaction.read`

```gizlang
function Transaction.read<P, R>(self: Transaction, query: Query.Prepared<P, R>, input: P): Result<Reply, DbError>
```

Runs QUERY with INPUT in the transaction.

### `Transaction.page`

```gizlang
function Transaction.page(self: Transaction, reader: Token, rows: i64, bytes: i64): Result<Reply, DbError>
```

The next page of READER in the transaction.

Effects: fail, io.

### `Transaction.write`

```gizlang
function Transaction.write(self: Transaction, statements: Vec<Statement>, params: Vec<Value>): Result<Reply, DbError>
```

Stage affected rows at the transaction's snapshot. Only commit publishes them.

Effects: fail, io.

### `Transaction.savepoint`

```gizlang
function Transaction.savepoint(self: Transaction, name: string): Result<Reply, DbError>
```

Makes the savepoint NAME.

Effects: fail, io.

### `Transaction.release`

```gizlang
function Transaction.release(self: Transaction, name: string): Result<Reply, DbError>
```

Forgets the savepoint NAME and keeps its changes.

Effects: fail, io.

### `Transaction.rollbackTo`

```gizlang
function Transaction.rollbackTo(self: Transaction, name: string): Result<Reply, DbError>
```

Undoes the changes after the savepoint NAME.

Effects: fail, io.

### `Transaction.commit`

```gizlang
function Transaction.commit(self: Transaction): Result<Position, DbError>
```

Commits the transaction; the position of the commit.

Effects: fail, io.

### `Transaction.rollback`

```gizlang
function Transaction.rollback(self: Transaction): Result<Reply, DbError>
```

Undoes the transaction.

Effects: fail, io.

### `Connection.retire`

```gizlang
function Connection.retire(self: Connection, resource: Token): Result<Reply, DbError>
```

Frees the reader or watch RESOURCE.

Effects: fail, io.

### `Connection.close`

```gizlang
function Connection.close(self: Connection): Result<Reply, DbError>
```

Ends the session and frees all that it holds.

Effects: fail, io.

### `Command.pageBytes`

```gizlang
function Command.pageBytes(self: Command): i64
```

The bytes a page command asks for; 0 for any other command.

### `Actor.dispatch`

```gizlang
function Actor.dispatch(self: mut Actor, e: mut Engine, sys: System, storage: mut StorageContext, policy: ResourcePolicy, command: Command): Result<Reply, DbError>
```

Run one command. A command that changed data moves the commit count (Connection.commits) before the caller is answered.

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

### `Actor.drain`

```gizlang
function Actor.drain(self: mut Actor, e: mut Engine, sys: System, storage: mut StorageContext, policy: ResourcePolicy): void
```

Runs the queued requests and answers each, until the inbox is empty.

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

### `Actor.take`

```gizlang
function Actor.take(self: Actor): Vec<Request>
```

Takes the queued requests and marks them as running.

Effects: fail, read, write.

### `Actor.abort`

```gizlang
function Actor.abort(self: Actor, why: string): void
```

After the actor's task failed (a fault ends it without `close`): refuses new calls and answers every queued or
taken request with `stopped`, so no caller waits for a reply that never comes. The engine state is not touched.

Effects: fail, read, write, io.

### `Actor.close`

```gizlang
function Actor.close(self: mut Actor, e: mut Engine, storage: mut StorageContext): Result<bool, DbError>
```

Ends every transaction, answers the queued requests with an error, and closes the inbox.

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

## Constants

### `PAGE_BYTES`

```gizlang
const PAGE_BYTES = 262144
```

The bytes of one response page of the data actor (Connection.page, Source cursors).

### `PAGE_MOST_BYTES`

```gizlang
const PAGE_MOST_BYTES = 67108864
```

The most bytes one page may ask for: a row larger than PAGE_BYTES is delivered alone in a page of its own size (the server reserves the credit it is asked for).

