video.cerulea.blue/appview/db.ts
Charlotte Som 89ec573591 ssr for video viewer
this lets us send opengraph tags in the response :D
might make the player also be server-side rendered as well
2026-03-10 23:39:04 +00:00

52 lines
1.8 KiB
TypeScript

import { Database } from "@db/sqlite";
const conn = new Database("./data/video.db");
conn.exec(`pragma journal_mode = WAL;`);
conn.exec(`
CREATE TABLE IF NOT EXISTS allowlist (
repo TEXT NOT NULL UNIQUE PRIMARY KEY -- did
) STRICT;
`);
conn.exec(`
CREATE TABLE IF NOT EXISTS videos (
id INTEGER NOT NULL PRIMARY KEY,
repo TEXT NOT NULL, -- did
cid TEXT NOT NULL, -- blob cid
fetched_at INTEGER NOT NULL DEFAULT (unixepoch()), -- datetime
filename TEXT NOT NULL
) STRICT;
`);
conn.exec(`
CREATE TABLE IF NOT EXISTS records (
repo TEXT NOT NULL, -- did
rkey TEXT NOT NULL,
record TEXT NOT NULL, -- JSON
fetched_at INTEGER NOT NULL DEFAULT (unixepoch()),
PRIMARY KEY (repo, rkey)
) STRICT;
`);
const selectAllowlist = conn.prepare("SELECT 1 FROM allowlist WHERE repo = ?");
const selectVideo = conn.prepare("SELECT filename FROM videos WHERE repo = ? AND cid = ?");
const insertVideo = conn.prepare("INSERT INTO videos (repo, cid, filename) VALUES (?, ?, ?)");
const selectRecord = conn.prepare("SELECT record FROM records WHERE repo = ? AND rkey = ?");
const insertRecord = conn.prepare(
"INSERT OR REPLACE INTO records (repo, rkey, record) VALUES (?, ?, ?)",
);
export const db = {
db: conn,
inAllowlist: (did: string) => (selectAllowlist.value<[boolean]>(did)?.[0] && true) ?? false,
getVideo: (did: string, cid: string) => selectVideo.value<[string]>(did, cid)?.[0],
addVideo: (did: string, cid: string, filename: string) => insertVideo.run(did, cid, filename),
getRecord: <T>(did: string, rkey: string): T | undefined => {
const row = selectRecord.value<[string]>(did, rkey);
return row ? (JSON.parse(row[0]) as T) : undefined;
},
addRecord: (did: string, rkey: string, record: unknown) => {
insertRecord.run(did, rkey, JSON.stringify(record));
},
};