Use new DittoDB module, rename old interface to DittoTables

This commit is contained in:
Alex Gleason 2024-04-19 12:26:15 -05:00
parent 4085443e45
commit 3753648f99
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
4 changed files with 20 additions and 102 deletions

View File

@ -1,93 +1,10 @@
import fs from 'node:fs/promises';
import path from 'node:path';
import { FileMigrationProvider, Kysely, Migrator, PolySqliteDialect } from '@/deps.ts';
import { Conf } from '@/config.ts';
import { setPragma } from '@/pragma.ts';
import SqliteWorker from '@/workers/sqlite.ts';
import { DittoDB } from '@/db/DittoDB.ts';
import { FileMigrationProvider, Migrator } from '@/deps.ts';
interface DittoDB {
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;
}
const sqliteWorker = new SqliteWorker();
await sqliteWorker.open(Conf.dbPath);
const db = new Kysely<DittoDB>({
dialect: new PolySqliteDialect({
database: sqliteWorker,
}),
});
// Set PRAGMA values.
await Promise.all([
setPragma(db, 'synchronous', 'normal'),
setPragma(db, 'temp_store', 'memory'),
setPragma(db, 'mmap_size', Conf.sqlite.mmapSize),
]);
const db = await DittoDB.getInstance();
const migrator = new Migrator({
db,
@ -120,4 +37,4 @@ async function migrate() {
await migrate();
export { type AuthorStatsRow, db, type DittoDB, type EventRow, type EventStatsRow, type TagRow };
export { db };

View File

@ -14,4 +14,4 @@ export class DittoDB {
throw new Error('Unsupported database URL.');
}
}
}
}

View File

@ -1,10 +1,11 @@
import { type AuthorStatsRow, db, type DittoDB, type EventStatsRow } from '@/db.ts';
import { db } from '@/db.ts';
import { DittoTables } from '@/db/DittoTables.ts';
import { Debug, type InsertQueryBuilder, type NostrEvent } from '@/deps.ts';
import { eventsDB } from '@/storages.ts';
import { findReplyTag } from '@/tags.ts';
type AuthorStat = keyof Omit<AuthorStatsRow, 'pubkey'>;
type EventStat = keyof Omit<EventStatsRow, 'event_id'>;
type AuthorStat = keyof Omit<DittoTables['author_stats'], 'pubkey'>;
type EventStat = keyof Omit<DittoTables['event_stats'], 'event_id'>;
type AuthorStatDiff = ['author_stats', pubkey: string, stat: AuthorStat, diff: number];
type EventStatDiff = ['event_stats', eventId: string, stat: EventStat, diff: number];
@ -15,7 +16,7 @@ const debug = Debug('ditto:stats');
/** Store stats for the event in LMDB. */
async function updateStats(event: NostrEvent) {
let prev: NostrEvent | undefined;
const queries: InsertQueryBuilder<DittoDB, any, unknown>[] = [];
const queries: InsertQueryBuilder<DittoTables, any, unknown>[] = [];
// Kind 3 is a special case - replace the count with the new list.
if (event.kind === 3) {
@ -98,8 +99,8 @@ async function getStatsDiff(event: NostrEvent, prev: NostrEvent | undefined): Pr
/** Create an author stats query from the list of diffs. */
function authorStatsQuery(diffs: AuthorStatDiff[]) {
const values: AuthorStatsRow[] = diffs.map(([_, pubkey, stat, diff]) => {
const row: AuthorStatsRow = {
const values: DittoTables['author_stats'][] = diffs.map(([_, pubkey, stat, diff]) => {
const row: DittoTables['author_stats'] = {
pubkey,
followers_count: 0,
following_count: 0,
@ -124,8 +125,8 @@ function authorStatsQuery(diffs: AuthorStatDiff[]) {
/** Create an event stats query from the list of diffs. */
function eventStatsQuery(diffs: EventStatDiff[]) {
const values: EventStatsRow[] = diffs.map(([_, event_id, stat, diff]) => {
const row: EventStatsRow = {
const values: DittoTables['event_stats'][] = diffs.map(([_, event_id, stat, diff]) => {
const row: DittoTables['event_stats'] = {
event_id,
replies_count: 0,
reposts_count: 0,

View File

@ -1,6 +1,6 @@
import { NIP50, NostrFilter } from '@soapbox/nspec';
import { Conf } from '@/config.ts';
import { type DittoDB } from '@/db.ts';
import { DittoTables } from '@/db/DittoTables.ts';
import { Debug, Kysely, type NostrEvent, type NStore, type NStoreOpts, type SelectQueryBuilder } from '@/deps.ts';
import { normalizeFilters } from '@/filter.ts';
import { DittoEvent } from '@/interfaces/DittoEvent.ts';
@ -33,7 +33,7 @@ const tagConditions: Record<string, TagCondition> = {
'role': ({ event, count }) => event.kind === 30361 && count === 0,
};
type EventQuery = SelectQueryBuilder<DittoDB, 'events', {
type EventQuery = SelectQueryBuilder<DittoTables, 'events', {
id: string;
tags: string;
kind: number;
@ -58,10 +58,10 @@ type EventQuery = SelectQueryBuilder<DittoDB, 'events', {
/** SQLite database storage adapter for Nostr events. */
class EventsDB implements NStore {
#db: Kysely<DittoDB>;
#db: Kysely<DittoTables>;
#debug = Debug('ditto:db:events');
constructor(db: Kysely<DittoDB>) {
constructor(db: Kysely<DittoTables>) {
this.#db = db;
}
@ -143,7 +143,7 @@ class EventsDB implements NStore {
}
/** Build the query for a filter. */
getFilterQuery(db: Kysely<DittoDB>, filter: NostrFilter): EventQuery {
getFilterQuery(db: Kysely<DittoTables>, filter: NostrFilter): EventQuery {
let query = db
.selectFrom('events')
.select([
@ -315,7 +315,7 @@ class EventsDB implements NStore {
}
/** Delete events from each table. Should be run in a transaction! */
async deleteEventsTrx(db: Kysely<DittoDB>, filters: NostrFilter[]) {
async deleteEventsTrx(db: Kysely<DittoTables>, filters: NostrFilter[]) {
if (!filters.length) return Promise.resolve();
this.#debug('DELETE', JSON.stringify(filters));