From 29102d272a524ad1ace7fd8bcf0ff02cbb5f9742 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Fri, 19 Apr 2024 12:14:13 -0500 Subject: [PATCH] Add DittoSQLite module --- src/db/DittoTables.ts | 66 ++++++++++++++++++++++++++++++++++ src/db/adapters/DittoSQLite.ts | 52 +++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 src/db/DittoTables.ts create mode 100644 src/db/adapters/DittoSQLite.ts diff --git a/src/db/DittoTables.ts b/src/db/DittoTables.ts new file mode 100644 index 0000000..4d8ce2b --- /dev/null +++ b/src/db/DittoTables.ts @@ -0,0 +1,66 @@ +export interface DittoTables { + events: EventRow; + events_fts: EventFTSRow; + tags: TagRow; + relays: RelayRow; + unattached_media: UnattachedMediaRow; + author_stats: AuthorStatsRow; + event_stats: EventStatsRow; + pubkey_domains: PubkeyDomainRow; +} + +interface AuthorStatsRow { + pubkey: string; + followers_count: number; + following_count: number; + notes_count: number; +} + +interface EventStatsRow { + event_id: string; + replies_count: number; + reposts_count: number; + reactions_count: number; +} + +interface EventRow { + id: string; + kind: number; + pubkey: string; + content: string; + created_at: number; + tags: string; + sig: string; + deleted_at: number | null; +} + +interface EventFTSRow { + id: string; + content: string; +} + +interface TagRow { + tag: string; + value: string; + event_id: string; +} + +interface RelayRow { + url: string; + domain: string; + active: boolean; +} + +interface UnattachedMediaRow { + id: string; + pubkey: string; + url: string; + data: string; + uploaded_at: Date; +} + +interface PubkeyDomainRow { + pubkey: string; + domain: string; + last_updated_at: number; +} diff --git a/src/db/adapters/DittoSQLite.ts b/src/db/adapters/DittoSQLite.ts new file mode 100644 index 0000000..c78ab67 --- /dev/null +++ b/src/db/adapters/DittoSQLite.ts @@ -0,0 +1,52 @@ +import { Conf } from '@/config.ts'; +import { DittoTables } from '@/db/DittoTables.ts'; +import { Kysely, PolySqliteDialect } from '@/deps.ts'; +import { setPragma } from '@/pragma.ts'; +import SqliteWorker from '@/workers/sqlite.ts'; + +export class DittoSQLite { + static db: Kysely | undefined; + + static async getInstance(): Promise> { + if (!this.db) { + const sqliteWorker = new SqliteWorker(); + await sqliteWorker.open(this.path); + + this.db = new Kysely({ + dialect: new PolySqliteDialect({ + database: sqliteWorker, + }), + }); + + // Set PRAGMA values. + await Promise.all([ + setPragma(this.db, 'synchronous', 'normal'), + setPragma(this.db, 'temp_store', 'memory'), + setPragma(this.db, 'mmap_size', Conf.sqlite.mmapSize), + ]); + } + return this.db; + } + + /** Get the relative or absolute path based on the `DATABASE_URL`. */ + static get path() { + if (Deno.env.get('DATABASE_URL') === 'sqlite://:memory:') { + return ':memory:'; + } + + const { host, pathname } = Conf.databaseUrl; + + if (!pathname) return ''; + + // Get relative path. + if (host === '') { + return pathname; + } else if (host === '.') { + return pathname; + } else if (host) { + return host + pathname; + } + + return ''; + } +}