···11+<?php
22+33+declare(strict_types=1);
44+55+namespace App\Infrastructure\Database\Schema;
66+77+use App\Infrastructure\Database\Database;
88+99+/**
1010+ * Initialises the schema for the service-level "account" database, which
1111+ * holds account-related and OAuth tables.
1212+ */
1313+final class AccountSchema
1414+{
1515+ public static function apply(Database $db): void
1616+ {
1717+ $pdo = $db->pdo();
1818+1919+ $pdo->exec(
2020+ 'CREATE TABLE IF NOT EXISTS account (
2121+ did TEXT PRIMARY KEY,
2222+ email TEXT NOT NULL UNIQUE,
2323+ password_scrypt TEXT NOT NULL,
2424+ email_confirmed_at TEXT,
2525+ invites_disabled INTEGER NOT NULL DEFAULT 0
2626+ )'
2727+ );
2828+2929+ $pdo->exec(
3030+ 'CREATE TABLE IF NOT EXISTS actor (
3131+ did TEXT PRIMARY KEY,
3232+ handle TEXT UNIQUE,
3333+ created_at TEXT NOT NULL,
3434+ takedown_ref TEXT,
3535+ deactivated_at TEXT,
3636+ delete_after TEXT
3737+ )'
3838+ );
3939+4040+ $pdo->exec(
4141+ 'CREATE TABLE IF NOT EXISTS app_password (
4242+ did TEXT NOT NULL,
4343+ name TEXT NOT NULL,
4444+ password_scrypt TEXT NOT NULL,
4545+ created_at TEXT NOT NULL,
4646+ privileged INTEGER NOT NULL DEFAULT 0,
4747+ PRIMARY KEY (did, name)
4848+ )'
4949+ );
5050+5151+ $pdo->exec(
5252+ 'CREATE TABLE IF NOT EXISTS email_token (
5353+ purpose TEXT NOT NULL,
5454+ did TEXT NOT NULL,
5555+ token TEXT NOT NULL,
5656+ requested_at TEXT NOT NULL,
5757+ PRIMARY KEY (purpose, did),
5858+ UNIQUE (purpose, token)
5959+ )'
6060+ );
6161+6262+ $pdo->exec(
6363+ 'CREATE TABLE IF NOT EXISTS invite_code (
6464+ code TEXT PRIMARY KEY,
6565+ available_uses INTEGER NOT NULL,
6666+ disabled INTEGER NOT NULL DEFAULT 0,
6767+ for_account TEXT NOT NULL,
6868+ created_by TEXT NOT NULL,
6969+ created_at TEXT NOT NULL
7070+ )'
7171+ );
7272+7373+ $pdo->exec(
7474+ 'CREATE TABLE IF NOT EXISTS invite_code_use (
7575+ code TEXT NOT NULL,
7676+ used_by TEXT NOT NULL,
7777+ used_at TEXT NOT NULL,
7878+ PRIMARY KEY (code, used_by, used_at)
7979+ )'
8080+ );
8181+8282+ $pdo->exec(
8383+ 'CREATE TABLE IF NOT EXISTS refresh_token (
8484+ id TEXT PRIMARY KEY,
8585+ did TEXT NOT NULL,
8686+ expires_at TEXT NOT NULL,
8787+ app_password_name TEXT,
8888+ next_id TEXT
8989+ )'
9090+ );
9191+ $pdo->exec('CREATE INDEX IF NOT EXISTS refresh_token_did_idx ON refresh_token (did)');
9292+9393+ $pdo->exec(
9494+ 'CREATE TABLE IF NOT EXISTS account_device (
9595+ did TEXT NOT NULL,
9696+ device_id TEXT NOT NULL,
9797+ created_at TEXT NOT NULL,
9898+ updated_at TEXT NOT NULL,
9999+ PRIMARY KEY (did, device_id)
100100+ )'
101101+ );
102102+103103+ $pdo->exec(
104104+ 'CREATE TABLE IF NOT EXISTS authorized_client (
105105+ did TEXT NOT NULL,
106106+ client_id TEXT NOT NULL,
107107+ created_at TEXT NOT NULL,
108108+ updated_at TEXT NOT NULL,
109109+ data_json TEXT NOT NULL,
110110+ PRIMARY KEY (did, client_id)
111111+ )'
112112+ );
113113+114114+ $pdo->exec(
115115+ 'CREATE TABLE IF NOT EXISTS device (
116116+ id TEXT PRIMARY KEY,
117117+ session_id TEXT NOT NULL,
118118+ user_agent TEXT,
119119+ ip_address TEXT NOT NULL,
120120+ last_seen_at TEXT NOT NULL
121121+ )'
122122+ );
123123+124124+ $pdo->exec(
125125+ 'CREATE TABLE IF NOT EXISTS oauth_token (
126126+ id INTEGER PRIMARY KEY AUTOINCREMENT,
127127+ did TEXT NOT NULL,
128128+ token_id TEXT NOT NULL UNIQUE,
129129+ created_at TEXT NOT NULL,
130130+ updated_at TEXT NOT NULL,
131131+ expires_at TEXT NOT NULL,
132132+ client_id TEXT NOT NULL,
133133+ client_auth_json TEXT NOT NULL,
134134+ device_id TEXT,
135135+ parameters_json TEXT NOT NULL,
136136+ details_json TEXT,
137137+ code TEXT,
138138+ current_refresh_token TEXT,
139139+ scope TEXT
140140+ )'
141141+ );
142142+ $pdo->exec('CREATE INDEX IF NOT EXISTS oauth_token_did_idx ON oauth_token (did)');
143143+ $pdo->exec('CREATE INDEX IF NOT EXISTS oauth_token_code_idx ON oauth_token (code)');
144144+ $pdo->exec(
145145+ 'CREATE INDEX IF NOT EXISTS oauth_token_refresh_idx ON oauth_token (current_refresh_token)'
146146+ );
147147+148148+ $pdo->exec(
149149+ 'CREATE TABLE IF NOT EXISTS used_refresh_token (
150150+ refresh_token TEXT PRIMARY KEY,
151151+ token_id INTEGER NOT NULL
152152+ )'
153153+ );
154154+ $pdo->exec(
155155+ 'CREATE INDEX IF NOT EXISTS used_refresh_token_token_id_idx ON used_refresh_token (token_id)'
156156+ );
157157+158158+ $pdo->exec(
159159+ 'CREATE TABLE IF NOT EXISTS authorization_request (
160160+ id TEXT PRIMARY KEY,
161161+ did TEXT,
162162+ device_id TEXT,
163163+ client_id TEXT NOT NULL,
164164+ client_auth_json TEXT,
165165+ parameters_json TEXT NOT NULL,
166166+ expires_at TEXT NOT NULL,
167167+ code TEXT
168168+ )'
169169+ );
170170+ $pdo->exec(
171171+ 'CREATE INDEX IF NOT EXISTS authorization_request_code_idx ON authorization_request (code)'
172172+ );
173173+174174+ $pdo->exec(
175175+ 'CREATE TABLE IF NOT EXISTS lexicon (
176176+ nsid TEXT PRIMARY KEY,
177177+ created_at TEXT NOT NULL,
178178+ updated_at TEXT NOT NULL,
179179+ last_succeeded_at TEXT,
180180+ uri TEXT,
181181+ lexicon_json TEXT
182182+ )'
183183+ );
184184+ }
185185+}
···11+<?php
22+33+declare(strict_types=1);
44+55+namespace App\Infrastructure\Database\Schema;
66+77+use App\Infrastructure\Database\Database;
88+99+/**
1010+ * Initialises the per-actor SQLite database schema.
1111+ * Mirrors the reference TS actor-store layout.
1212+ */
1313+final class ActorStoreSchema
1414+{
1515+ public static function apply(Database $db): void
1616+ {
1717+ $pdo = $db->pdo();
1818+1919+ $pdo->exec(
2020+ 'CREATE TABLE IF NOT EXISTS record (
2121+ uri TEXT PRIMARY KEY,
2222+ cid TEXT NOT NULL,
2323+ collection TEXT NOT NULL,
2424+ rkey TEXT NOT NULL,
2525+ repo_rev TEXT NOT NULL,
2626+ indexed_at TEXT NOT NULL,
2727+ takedown_ref TEXT
2828+ )'
2929+ );
3030+ $pdo->exec('CREATE INDEX IF NOT EXISTS record_collection_idx ON record (collection)');
3131+3232+ $pdo->exec(
3333+ 'CREATE TABLE IF NOT EXISTS record_blob (
3434+ blob_cid TEXT NOT NULL,
3535+ record_uri TEXT NOT NULL,
3636+ PRIMARY KEY (blob_cid, record_uri)
3737+ )'
3838+ );
3939+ $pdo->exec(
4040+ 'CREATE INDEX IF NOT EXISTS record_blob_record_uri_idx ON record_blob (record_uri)'
4141+ );
4242+4343+ $pdo->exec(
4444+ 'CREATE TABLE IF NOT EXISTS backlink (
4545+ uri TEXT NOT NULL,
4646+ path TEXT NOT NULL,
4747+ link_to TEXT NOT NULL,
4848+ PRIMARY KEY (uri, path, link_to)
4949+ )'
5050+ );
5151+ $pdo->exec('CREATE INDEX IF NOT EXISTS backlink_link_to_idx ON backlink (link_to)');
5252+5353+ $pdo->exec(
5454+ 'CREATE TABLE IF NOT EXISTS blob (
5555+ cid TEXT PRIMARY KEY,
5656+ mime_type TEXT NOT NULL,
5757+ size INTEGER NOT NULL,
5858+ temp_key TEXT,
5959+ created_at TEXT NOT NULL,
6060+ takedown_ref TEXT
6161+ )'
6262+ );
6363+ $pdo->exec('CREATE INDEX IF NOT EXISTS blob_temp_key_idx ON blob (temp_key)');
6464+6565+ $pdo->exec(
6666+ 'CREATE TABLE IF NOT EXISTS repo_block (
6767+ cid TEXT PRIMARY KEY,
6868+ repo_rev TEXT NOT NULL,
6969+ size INTEGER NOT NULL,
7070+ content BLOB NOT NULL
7171+ )'
7272+ );
7373+ $pdo->exec('CREATE INDEX IF NOT EXISTS repo_block_repo_rev_idx ON repo_block (repo_rev)');
7474+7575+ $pdo->exec(
7676+ 'CREATE TABLE IF NOT EXISTS repo_root (
7777+ did TEXT PRIMARY KEY,
7878+ cid TEXT NOT NULL,
7979+ rev TEXT NOT NULL,
8080+ indexed_at TEXT NOT NULL
8181+ )'
8282+ );
8383+8484+ $pdo->exec(
8585+ 'CREATE TABLE IF NOT EXISTS account_pref (
8686+ id INTEGER PRIMARY KEY AUTOINCREMENT,
8787+ name TEXT NOT NULL,
8888+ value_json TEXT NOT NULL
8989+ )'
9090+ );
9191+ $pdo->exec('CREATE INDEX IF NOT EXISTS account_pref_name_idx ON account_pref (name)');
9292+ }
9393+}
···11+<?php
22+33+declare(strict_types=1);
44+55+namespace App\Infrastructure\Database\Schema;
66+77+use App\Infrastructure\Database\Database;
88+99+final class DidCacheSchema
1010+{
1111+ public static function apply(Database $db): void
1212+ {
1313+ $pdo = $db->pdo();
1414+1515+ $pdo->exec(
1616+ 'CREATE TABLE IF NOT EXISTS did_doc (
1717+ did TEXT PRIMARY KEY,
1818+ doc_json TEXT NOT NULL,
1919+ updated_at TEXT NOT NULL
2020+ )'
2121+ );
2222+ }
2323+}
···11+<?php
22+33+declare(strict_types=1);
44+55+namespace App\Infrastructure\Database\Schema;
66+77+use App\Infrastructure\Database\Database;
88+99+final class SequencerSchema
1010+{
1111+ public static function apply(Database $db): void
1212+ {
1313+ $pdo = $db->pdo();
1414+1515+ $pdo->exec(
1616+ 'CREATE TABLE IF NOT EXISTS repo_seq (
1717+ seq INTEGER PRIMARY KEY AUTOINCREMENT,
1818+ did TEXT NOT NULL,
1919+ event_type TEXT NOT NULL,
2020+ event BLOB NOT NULL,
2121+ sequenced_at TEXT NOT NULL,
2222+ invalidated INTEGER NOT NULL DEFAULT 0
2323+ )'
2424+ );
2525+ $pdo->exec('CREATE INDEX IF NOT EXISTS repo_seq_did_idx ON repo_seq (did)');
2626+ }
2727+}