feat: store documents in sqlite

This commit is contained in:
2025-01-05 21:58:07 +01:00
parent 20a2781214
commit d0d49b217d
23 changed files with 1476 additions and 65 deletions

View File

@ -1,31 +0,0 @@
import { Document } from "@lib/documents.ts";
import * as cache from "@lib/cache/cache.ts";
const CACHE_INTERVAL = 60;
const CACHE_KEY = "documents";
export async function getDocuments() {
const res = await cache.get<string>(CACHE_KEY);
if (res) return JSON.parse(res);
return;
}
export function setDocuments(documents: Document[]) {
return cache.set(
CACHE_KEY,
JSON.stringify(documents),
{ expires: CACHE_INTERVAL },
);
}
export function getDocument(id: string) {
return cache.get<string>(CACHE_KEY + ":" + id.replaceAll("/", ":"));
}
export async function setDocument(id: string, content: string) {
await cache.set(
CACHE_KEY + ":" + id.replaceAll("/", ":"),
content,
{ expires: CACHE_INTERVAL },
);
}

View File

@ -8,16 +8,19 @@ import remarkStringify from "https://esm.sh/remark-stringify@10.0.3";
import remarkFrontmatter, {
Root,
} from "https://esm.sh/remark-frontmatter@4.0.1";
import * as cache from "@lib/cache/documents.ts";
import { SILVERBULLET_SERVER } from "@lib/env.ts";
import { fixRenderedMarkdown } from "@lib/helpers.ts";
import { createLogger } from "@lib/log.ts";
import * as typesense from "@lib/typesense.ts";
import { db } from "@lib/sqlite/sqlite.ts";
import { documentTable } from "@lib/sqlite/schema.ts";
import { eq } from "drizzle-orm/sql";
export type Document = {
name: string;
lastModified: number;
contentType: string;
content: string | null;
size: number;
perm: string;
};
@ -25,8 +28,8 @@ export type Document = {
const log = createLogger("documents");
export async function getDocuments(): Promise<Document[]> {
const cachedDocuments = await cache.getDocuments();
if (cachedDocuments) return cachedDocuments;
let documents = await db.select().from(documentTable).all();
if (documents.length) return documents;
const headers = new Headers();
headers.append("Accept", "application/json");
@ -36,10 +39,9 @@ export async function getDocuments(): Promise<Document[]> {
headers: headers,
});
const documents = await response.json();
cache.setDocuments(documents);
typesense.synchronize();
documents = await response.json();
await db.delete(documentTable);
await db.insert(documentTable).values(documents);
return documents;
}
@ -67,8 +69,10 @@ export function createDocument(
}
export async function getDocument(name: string): Promise<string> {
const cachedDocument = await cache.getDocument(name);
if (cachedDocument) return cachedDocument;
const documents = await db.select().from(documentTable).where(
eq(documentTable.name, name),
).limit(1);
if (documents[0]?.content) return documents[0].content;
log.debug("fetching document", { name });
const headers = new Headers();
@ -76,9 +80,9 @@ export async function getDocument(name: string): Promise<string> {
const response = await fetch(SILVERBULLET_SERVER + "/" + name, { headers });
const text = await response.text();
cache.setDocument(name, text);
typesense.synchronize();
await db.update(documentTable).set({
content: text,
}).where(eq(documentTable.name, name));
return text;
}

View File

@ -3,7 +3,6 @@ import { parse, stringify } from "yaml";
import { createCrud } from "@lib/crud.ts";
import { extractHashTags, formatDate } from "@lib/string.ts";
import { fixRenderedMarkdown } from "@lib/helpers.ts";
import { getThumbhash } from "@lib/cache/image.ts";
export type Series = {
id: string;

View File

@ -1,5 +1,6 @@
import { int, integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
import { sql } from "drizzle-orm/sql";
import { contentType } from "https://deno.land/std@0.216.0/media_types/content_type.ts";
export const userTable = sqliteTable("user", {
id: text()
@ -43,3 +44,12 @@ export const imageTable = sqliteTable("image", {
blurhash: text().notNull(),
mime: text().notNull(),
});
export const documentTable = sqliteTable("document", {
name: text().notNull().primaryKey(),
lastModified: integer("last_modified").notNull(),
content: text(),
contentType: text("content_type").notNull(),
size: integer().notNull(),
perm: text().notNull(),
});