# gizweb:files

An app's stored files. The bytes are a file in the app's folder, named by their SHA-256, so one content is kept once; a record holds the owner, type and size. Their bytes together stay under the app's quota (counters.giz). A record is written only after its bytes, so a record never lacks them.

```gizlang
import * as Files from "gizweb:files";
```

## Types

### `Stored`

```gizlang
type Stored = { @Key id: string; @Index("owner") owner: string; type: string; size: i64; @Index("digest") digest: string; }
```

One stored file: who owns it, its media type, size and the SHA-256 of its bytes (hex).

- `id`: `string`
- `owner`: `string`
- `type`: `string`
- `size`: `i64`
- `digest`: `string`

### `Files`

```gizlang
type Files = { sys: System; db: Data.Db; folder: string; }
```

Where the files are: the records in DB and the bytes in FOLDER.

- `sys`: `gizlang_system.System`
- `db`: `M73.Db`
- `folder`: `string`

## Functions

### `install`

```gizlang
function install(d: Data.Db): bool throws Model.Rejection
```

Makes the files table when it is not there.

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

### `put`

```gizlang
function put(files: Files, id: string, owner: string, type: string, content: bytes, quota: i64): Stored throws Model.Rejection
```

Stores CONTENT as file ID of OWNER with media TYPE, when all files stay within QUOTA bytes; a 429 otherwise.

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

### `find`

```gizlang
function find(files: Files, id: string): Option<Stored> throws Model.Rejection
```

The record of file ID.

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

### `read`

```gizlang
function read(files: Files, stored: Stored): bytes throws Model.Rejection
```

The bytes of STORED, checked against its digest.

Effects: fail, io.

### `remove`

```gizlang
function remove(files: Files, id: string, owner: string): bool throws Model.Rejection
```

Removes file ID of OWNER; false when OWNER has no such file.

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

