EventsDB -> DittoPgStore

This commit is contained in:
Alex Gleason 2025-02-18 13:32:32 -06:00
parent 3e7f33a63d
commit 37f418899b
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
6 changed files with 27 additions and 27 deletions

View file

@ -6,7 +6,7 @@ import { logi } from '@soapbox/logi';
import { Conf } from '@/config.ts'; import { Conf } from '@/config.ts';
import { wsUrlSchema } from '@/schema.ts'; import { wsUrlSchema } from '@/schema.ts';
import { AdminStore } from '@/storages/AdminStore.ts'; import { AdminStore } from '@/storages/AdminStore.ts';
import { EventsDB } from '@/storages/EventsDB.ts'; import { DittoPgStore } from '@/storages/DittoPgStore.ts';
import { SearchStore } from '@/storages/search-store.ts'; import { SearchStore } from '@/storages/search-store.ts';
import { InternalRelay } from '@/storages/InternalRelay.ts'; import { InternalRelay } from '@/storages/InternalRelay.ts';
import { NPool, NRelay1 } from '@nostrify/nostrify'; import { NPool, NRelay1 } from '@nostrify/nostrify';
@ -14,7 +14,7 @@ import { getRelays } from '@/utils/outbox.ts';
import { seedZapSplits } from '@/utils/zap-split.ts'; import { seedZapSplits } from '@/utils/zap-split.ts';
export class Storages { export class Storages {
private static _db: Promise<EventsDB> | undefined; private static _db: Promise<DittoPgStore> | undefined;
private static _database: Promise<DittoDatabase> | undefined; private static _database: Promise<DittoDatabase> | undefined;
private static _admin: Promise<AdminStore> | undefined; private static _admin: Promise<AdminStore> | undefined;
private static _client: Promise<NPool<NRelay1>> | undefined; private static _client: Promise<NPool<NRelay1>> | undefined;
@ -41,11 +41,11 @@ export class Storages {
} }
/** SQL database to store events this Ditto server cares about. */ /** SQL database to store events this Ditto server cares about. */
public static async db(): Promise<EventsDB> { public static async db(): Promise<DittoPgStore> {
if (!this._db) { if (!this._db) {
this._db = (async () => { this._db = (async () => {
const kysely = await this.kysely(); const kysely = await this.kysely();
const store = new EventsDB({ kysely, pubkey: Conf.pubkey, timeout: Conf.db.timeouts.default }); const store = new DittoPgStore({ kysely, pubkey: Conf.pubkey, timeout: Conf.db.timeouts.default });
await seedZapSplits(store); await seedZapSplits(store);
return store; return store;
})(); })();

View file

@ -4,7 +4,7 @@ import { generateSecretKey } from 'nostr-tools';
import { RelayError } from '@/RelayError.ts'; import { RelayError } from '@/RelayError.ts';
import { eventFixture, genEvent } from '@/test.ts'; import { eventFixture, genEvent } from '@/test.ts';
import { Conf } from '@/config.ts'; import { Conf } from '@/config.ts';
import { EventsDB } from '@/storages/EventsDB.ts'; import { DittoPgStore } from '@/storages/DittoPgStore.ts';
import { createTestDB } from '@/test.ts'; import { createTestDB } from '@/test.ts';
Deno.test('count filters', async () => { Deno.test('count filters', async () => {
@ -254,7 +254,7 @@ Deno.test('NPostgres.query with search', async (t) => {
}); });
}); });
Deno.test('EventsDB.indexTags indexes only the final `e` and `p` tag of kind 7 events', () => { Deno.test('DittoPgStore.indexTags indexes only the final `e` and `p` tag of kind 7 events', () => {
const event = { const event = {
kind: 7, kind: 7,
id: 'a92549a442d306b32273aa9456ba48e3851a4e6203af3f567543298ab964b35b', id: 'a92549a442d306b32273aa9456ba48e3851a4e6203af3f567543298ab964b35b',
@ -285,7 +285,7 @@ Deno.test('EventsDB.indexTags indexes only the final `e` and `p` tag of kind 7 e
'44639d039a7f7fb8772fcfa13d134d3cda684ec34b6a777ead589676f9e8d81b08a24234066dcde1aacfbe193224940fba7586e7197c159757d3caf8f2b57e1b', '44639d039a7f7fb8772fcfa13d134d3cda684ec34b6a777ead589676f9e8d81b08a24234066dcde1aacfbe193224940fba7586e7197c159757d3caf8f2b57e1b',
}; };
const tags = EventsDB.indexTags(event); const tags = DittoPgStore.indexTags(event);
assertEquals(tags, [ assertEquals(tags, [
['e', 'e3653ae41ffb510e5fc071555ecfbc94d2fc31e355d61d941e39a97ac6acb15b'], ['e', 'e3653ae41ffb510e5fc071555ecfbc94d2fc31e355d61d941e39a97ac6acb15b'],

View file

@ -36,8 +36,8 @@ interface TagConditionOpts {
value: string; value: string;
} }
/** Options for the EventsDB store. */ /** Options for the DittoPgStore store. */
interface EventsDBOpts { interface DittoPgStoreOpts {
/** Kysely instance to use. */ /** Kysely instance to use. */
kysely: Kysely<DittoTables>; kysely: Kysely<DittoTables>;
/** Pubkey of the admin account. */ /** Pubkey of the admin account. */
@ -49,18 +49,18 @@ interface EventsDBOpts {
} }
/** SQL database storage adapter for Nostr events. */ /** SQL database storage adapter for Nostr events. */
class EventsDB extends NPostgres { class DittoPgStore extends NPostgres {
/** Conditions for when to index certain tags. */ /** Conditions for when to index certain tags. */
static tagConditions: Record<string, TagCondition> = { static tagConditions: Record<string, TagCondition> = {
'a': ({ count }) => count < 15, 'a': ({ count }) => count < 15,
'd': ({ event, count }) => count === 0 && NKinds.parameterizedReplaceable(event.kind), 'd': ({ event, count }) => count === 0 && NKinds.parameterizedReplaceable(event.kind),
'e': EventsDB.eTagCondition, 'e': DittoPgStore.eTagCondition,
'k': ({ count, value }) => count === 0 && Number.isInteger(Number(value)), 'k': ({ count, value }) => count === 0 && Number.isInteger(Number(value)),
'L': ({ event, count }) => event.kind === 1985 || count === 0, 'L': ({ event, count }) => event.kind === 1985 || count === 0,
'l': ({ event, count }) => event.kind === 1985 || count === 0, 'l': ({ event, count }) => event.kind === 1985 || count === 0,
'n': ({ count, value }) => count < 50 && value.length < 50, 'n': ({ count, value }) => count < 50 && value.length < 50,
'P': ({ count, value }) => count === 0 && isNostrId(value), 'P': ({ count, value }) => count === 0 && isNostrId(value),
'p': EventsDB.pTagCondition, 'p': DittoPgStore.pTagCondition,
'proxy': ({ count, value }) => count === 0 && value.length < 256, 'proxy': ({ count, value }) => count === 0 && value.length < 256,
'q': ({ event, count, value }) => count === 0 && event.kind === 1 && isNostrId(value), 'q': ({ event, count, value }) => count === 0 && event.kind === 1 && isNostrId(value),
'r': ({ event, count }) => (event.kind === 1985 ? count < 20 : count < 3), 'r': ({ event, count }) => (event.kind === 1985 ? count < 20 : count < 3),
@ -119,11 +119,11 @@ class EventsDB extends NPostgres {
return ext; return ext;
} }
constructor(private opts: EventsDBOpts) { constructor(private opts: DittoPgStoreOpts) {
super(opts.kysely, { super(opts.kysely, {
indexTags: EventsDB.indexTags, indexTags: DittoPgStore.indexTags,
indexSearch: EventsDB.searchText, indexSearch: DittoPgStore.searchText,
indexExtensions: EventsDB.indexExtensions, indexExtensions: DittoPgStore.indexExtensions,
}); });
} }
@ -323,7 +323,7 @@ class EventsDB extends NPostgres {
return event.tags.reduce<string[][]>((results, tag, index) => { return event.tags.reduce<string[][]>((results, tag, index) => {
const [name, value] = tag; const [name, value] = tag;
const condition = EventsDB.tagConditions[name] as TagCondition | undefined; const condition = DittoPgStore.tagConditions[name] as TagCondition | undefined;
if (value && condition && value.length < 200 && checkCondition(name, value, condition, index)) { if (value && condition && value.length < 200 && checkCondition(name, value, condition, index)) {
results.push(tag); results.push(tag);
@ -338,12 +338,12 @@ class EventsDB extends NPostgres {
static searchText(event: NostrEvent): string { static searchText(event: NostrEvent): string {
switch (event.kind) { switch (event.kind) {
case 0: case 0:
return EventsDB.buildUserSearchContent(event); return DittoPgStore.buildUserSearchContent(event);
case 1: case 1:
case 20: case 20:
return nip27.replaceAll(event.content, () => ''); return nip27.replaceAll(event.content, () => '');
case 30009: case 30009:
return EventsDB.buildTagsSearchContent(event.tags.filter(([t]) => t !== 'alt')); return DittoPgStore.buildTagsSearchContent(event.tags.filter(([t]) => t !== 'alt'));
case 30360: case 30360:
return event.tags.find(([name]) => name === 'd')?.[1] || ''; return event.tags.find(([name]) => name === 'd')?.[1] || '';
default: default:
@ -434,4 +434,4 @@ class EventsDB extends NPostgres {
} }
} }
export { EventsDB }; export { DittoPgStore };

View file

@ -3,7 +3,7 @@ import { NostrEvent } from '@nostrify/nostrify';
import { finalizeEvent, generateSecretKey } from 'nostr-tools'; import { finalizeEvent, generateSecretKey } from 'nostr-tools';
import { Conf } from '@/config.ts'; import { Conf } from '@/config.ts';
import { EventsDB } from '@/storages/EventsDB.ts'; import { DittoPgStore } from '@/storages/DittoPgStore.ts';
import { purifyEvent } from '@/utils/purify.ts'; import { purifyEvent } from '@/utils/purify.ts';
import { sql } from 'kysely'; import { sql } from 'kysely';
@ -38,7 +38,7 @@ export async function createTestDB(opts?: { pure?: boolean }) {
await DittoDB.migrate(kysely); await DittoDB.migrate(kysely);
const store = new EventsDB({ const store = new DittoPgStore({
kysely, kysely,
timeout: Conf.db.timeouts.default, timeout: Conf.db.timeouts.default,
pubkey: Conf.pubkey, pubkey: Conf.pubkey,

View file

@ -4,7 +4,7 @@ import { NostrEvent, NostrRelayOK, NPolicy } from '@nostrify/nostrify';
import { ReadOnlyPolicy } from '@nostrify/policies'; import { ReadOnlyPolicy } from '@nostrify/policies';
import * as Comlink from 'comlink'; import * as Comlink from 'comlink';
import { EventsDB } from '@/storages/EventsDB.ts'; import { DittoPgStore } from '@/storages/DittoPgStore.ts';
// @ts-ignore Don't try to access the env from this worker. // @ts-ignore Don't try to access the env from this worker.
Deno.env = new Map<string, string>(); Deno.env = new Map<string, string>();
@ -15,7 +15,7 @@ interface PolicyInit {
path: string; path: string;
/** Database URL to connect to. */ /** Database URL to connect to. */
databaseUrl: string; databaseUrl: string;
/** Admin pubkey to use for EventsDB checks. */ /** Admin pubkey to use for DittoPgStore checks. */
pubkey: string; pubkey: string;
} }
@ -32,7 +32,7 @@ export class CustomPolicy implements NPolicy {
const { kysely } = DittoDB.create(databaseUrl, { poolSize: 1 }); const { kysely } = DittoDB.create(databaseUrl, { poolSize: 1 });
const store = new EventsDB({ const store = new DittoPgStore({
kysely, kysely,
pubkey, pubkey,
timeout: 5_000, timeout: 5_000,

View file

@ -1,7 +1,7 @@
import { NostrEvent } from '@nostrify/nostrify'; import { NostrEvent } from '@nostrify/nostrify';
import { Storages } from '../packages/ditto/storages.ts'; import { Storages } from '../packages/ditto/storages.ts';
import { EventsDB } from '../packages/ditto/storages/EventsDB.ts'; import { DittoPgStore } from '../packages/ditto/storages/DittoPgStore.ts';
const kysely = await Storages.kysely(); const kysely = await Storages.kysely();
@ -11,7 +11,7 @@ const query = kysely
for await (const row of query.stream()) { for await (const row of query.stream()) {
const event: NostrEvent = { ...row, created_at: Number(row.created_at) }; const event: NostrEvent = { ...row, created_at: Number(row.created_at) };
const ext = EventsDB.indexExtensions(event); const ext = DittoPgStore.indexExtensions(event);
try { try {
await kysely await kysely