# gizdb:schema

One pure schema planner. Catalog readers and command executors belong to callers.

```gizlang
import * as Schema from "gizdb:schema";
```

## Types

### `SchemaColumn`

```gizlang
type SchemaColumn = { name: string; definition: string; nullable: bool; default: Option<string>; earlier: Vec<string>; }
```

A column of a table schema: its name, SQL definition, whether it takes NULL, its default, and its earlier names.

- `name`: `string`
- `definition`: `string`
- `nullable`: `bool`
- `default`: `_gizlang_sdk_core.Option<string>`
- `earlier`: `Vec<string>`

### `Unique`

```gizlang
type Unique = { name: string; columns: Vec<string>; }
```

A unique constraint: its name and columns.

- `name`: `string`
- `columns`: `Vec<string>`

### `Index`

```gizlang
type Index = { name: string; columns: Vec<string>; }
```

An index: its name and columns.

- `name`: `string`
- `columns`: `Vec<string>`

### `DeleteAction`

```gizlang
type DeleteAction = | { kind: "restrict"; } | { kind: "cascade"; } | { kind: "setNull"; }
```

What a foreign key does when the row that it refers to is deleted.

- `restrict`
- `cascade`
- `setNull`

### `Reference`

```gizlang
type Reference = { name: string; columns: Vec<string>; table: string; targets: Vec<string>; onDelete: DeleteAction; }
```

A foreign key: its name, columns, the table and columns that it refers to, and its delete action.

- `name`: `string`
- `columns`: `Vec<string>`
- `table`: `string`
- `targets`: `Vec<string>`
- `onDelete`: `M57.DeleteAction`

### `Check`

```gizlang
type Check = { name: string; sql: string; }
```

A check constraint: its name and SQL condition.

- `name`: `string`
- `sql`: `string`

### `Table`

```gizlang
type Table = { name: string; columns: Vec<SchemaColumn>; key: Vec<string>; uniques: Vec<Unique>; indexes: Vec<Index>; references: Vec<Reference>; checks: Vec<Check>; }
```

A table schema: its name, columns, key, constraints and indexes.

- `name`: `string`
- `columns`: `Vec<M57.SchemaColumn>`
- `key`: `Vec<string>`
- `uniques`: `Vec<M57.Unique>`
- `indexes`: `Vec<M57.Index>`
- `references`: `Vec<M57.Reference>`
- `checks`: `Vec<M57.Check>`

### `Options`

```gizlang
type Options = { nonEmpty: bool; allowDrop: Vec<string>; allowCast: Vec<string>; earlier: Vec<string>; }
```

Earlier table names are newest first. Admission names source columns.
nonEmpty describes the locked catalog snapshot. Use true if unknown.

- `nonEmpty`: `bool`
- `allowDrop`: `Vec<string>`
- `allowCast`: `Vec<string>`
- `earlier`: `Vec<string>`

### `Migration`

```gizlang
type Migration = | { kind: "createTable"; table: Table; } | { kind: "dropTable"; table: Table; } | { kind: "renameTable"; before: string; after: string; } | { kind: "renameColumn"; before: string; after: string; } | { kind: "addColumn"; column: SchemaColumn; } | { kind: "dropColumn"; column: SchemaColumn; } | { kind: "alterType"; name: string; before: string; after: string; lossless: bool; } | { kind: "notNull"; name: string; before: bool; after: bool; } | { kind: "defaultValue"; name: string; before: Option<string>; after: Option<string>; } | { kind: "addKey"; name: string; columns: Vec<string>; } | { kind: "dropKey"; name: string; columns: Vec<string>; } | { kind: "addUnique"; unique: Unique; } | { kind: "dropUnique"; unique: Unique; } | { kind: "addIndex"; index: Index; } | { kind: "dropIndex"; index: Index; } | { kind: "addReference"; reference: Reference; } | { kind: "dropReference"; reference: Reference; } | { kind: "addCheck"; check: Check; } | { kind: "dropCheck"; check: Check; }
```

Native session.giz executes create table (key, unique, references, checks),
add column, rename column, create/drop index, and add primary/foreign key.
Other ALTER operations, including add unique/check, return "not supported yet".
Native AST lowering belongs to typed.giz. This module lowers PostgreSQL text.

- `createTable`
- `dropTable`
- `renameTable`
- `renameColumn`
- `addColumn`
- `dropColumn`
- `alterType`
- `notNull`
- `defaultValue`
- `addKey`
- `dropKey`
- `addUnique`
- `dropUnique`
- `addIndex`
- `dropIndex`
- `addReference`
- `dropReference`
- `addCheck`
- `dropCheck`

### `Plan`

```gizlang
type Plan = { changes: Vec<Migration>; reversible: bool; destructive: Vec<string>; }
```

The changes from one schema to another, whether they can be undone, and the data that they would drop.

- `changes`: `Vec<M57.Migration>`
- `reversible`: `bool`
- `destructive`: `Vec<string>`

## Functions

### `options`

```gizlang
function options(): Options
```

The default options: the table may hold rows, and no drop or cast is allowed.

### `widening`

```gizlang
function widening(before: string, after: string): bool
```

Preserve both fractional digits and integer digits.

Effects: fail.

### `inverse`

```gizlang
function inverse(change: Migration): Option<Migration>
```

Restore the schema. Lossy casts and deleted data have no inverse.

### `plan`

```gizlang
function plan(target: Table, existing: Option<Table>, admission: Options): Result<Plan, string>
```

Plan from a locked catalog snapshot to a declaration. No effects or implicit drops.

Effects: fail.

### `createSql`

```gizlang
function createSql(t: Table, quote: (name: string) => string, suffix: string): Vec<string>
```

CREATE TABLE IF NOT EXISTS, then CREATE INDEX IF NOT EXISTS for each index, in a dialect that writes an
identifier with `quote`. `suffix` follows the table (SQLite's " WITHOUT ROWID").

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

### `sql`

```gizlang
function sql(table: string, change: Migration): string
```

Use the table name at this step. After renameTable, use its after name. PostgreSQL text.

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

### `planStatements`

```gizlang
function planStatements(table: string, changes: Vec<Migration>): Vec<string>
```

PostgreSQL text for planned changes, in order, while tracking table renames.

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

### `column`

```gizlang
function column(name: string, definition: string, earlier: Vec<string>): SchemaColumn
```

A column of a name-only catalog: nullable, no default.

### `changes`

```gizlang
function changes(table: string, exists: bool, columns: Vec<string>, fields: Vec<SchemaColumn>): Result<Vec<Migration>, string>
```

Name-only catalogs cannot prove drops or type changes. Retain unclaimed columns and use desired definitions for
matches. All decisions still use plan; the result has only createTable, renameColumn and addColumn.

Effects: fail.

