cleanup database class

This commit is contained in:
hzrd149
2025-03-28 13:01:54 +00:00
parent 6f10d7d38a
commit 4f325554ee
3 changed files with 40 additions and 38 deletions

View File

@@ -75,7 +75,6 @@
"@swc-node/register": "^1.10.10", "@swc-node/register": "^1.10.10",
"@swc/core": "^1.11.13", "@swc/core": "^1.11.13",
"@types/better-sqlite3": "^7.6.12", "@types/better-sqlite3": "^7.6.12",
"@types/bun": "^1.2.7",
"@types/cors": "^2.8.17", "@types/cors": "^2.8.17",
"@types/debug": "^4.1.12", "@types/debug": "^4.1.12",
"@types/express": "^4.17.21", "@types/express": "^4.17.21",

26
pnpm-lock.yaml generated
View File

@@ -141,9 +141,6 @@ importers:
'@types/better-sqlite3': '@types/better-sqlite3':
specifier: ^7.6.12 specifier: ^7.6.12
version: 7.6.12 version: 7.6.12
'@types/bun':
specifier: ^1.2.7
version: 1.2.7
'@types/cors': '@types/cors':
specifier: ^2.8.17 specifier: ^2.8.17
version: 2.8.17 version: 2.8.17
@@ -1153,9 +1150,6 @@ packages:
'@types/body-parser@1.19.5': '@types/body-parser@1.19.5':
resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
'@types/bun@1.2.7':
resolution: {integrity: sha512-Xf/nkx1V03GvWEzWrYsOGB1VUvWVtU5p6jHalCxixhhfLgsJN59iT7CRvfBXyEBnYoGCa2orzWj6car/QfTjxw==}
'@types/connect@3.4.38': '@types/connect@3.4.38':
resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==}
@@ -1523,9 +1517,6 @@ packages:
buffer@6.0.3: buffer@6.0.3:
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
bun-types@1.2.7:
resolution: {integrity: sha512-P4hHhk7kjF99acXqKvltyuMQ2kf/rzIw3ylEDpCxDS9Xa0X0Yp/gJu/vDCucmWpiur5qJ0lwB2bWzOXa2GlHqA==}
bytes@3.0.0: bytes@3.0.0:
resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==}
engines: {node: '>= 0.8'} engines: {node: '>= 0.8'}
@@ -2871,8 +2862,8 @@ packages:
resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
serve-static@2.1.0: serve-static@2.2.0:
resolution: {integrity: sha512-A3We5UfEjG8Z7VkDv6uItWw6HY2bBSBJT1KtVESn6EOoOr2jAxNhxWCLY3jDE2WcuHXByWju74ck3ZgLwL8xmA==} resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==}
engines: {node: '>= 18'} engines: {node: '>= 18'}
set-function-length@1.2.2: set-function-length@1.2.2:
@@ -4355,10 +4346,6 @@ snapshots:
'@types/connect': 3.4.38 '@types/connect': 3.4.38
'@types/node': 22.13.14 '@types/node': 22.13.14
'@types/bun@1.2.7':
dependencies:
bun-types: 1.2.7
'@types/connect@3.4.38': '@types/connect@3.4.38':
dependencies: dependencies:
'@types/node': 22.13.14 '@types/node': 22.13.14
@@ -4869,11 +4856,6 @@ snapshots:
base64-js: 1.5.1 base64-js: 1.5.1
ieee754: 1.2.1 ieee754: 1.2.1
bun-types@1.2.7:
dependencies:
'@types/node': 22.13.14
'@types/ws': 8.18.0
bytes@3.0.0: {} bytes@3.0.0: {}
bytes@3.1.2: {} bytes@3.1.2: {}
@@ -5284,7 +5266,7 @@ snapshots:
router: 2.2.0 router: 2.2.0
safe-buffer: 5.2.1 safe-buffer: 5.2.1
send: 1.2.0 send: 1.2.0
serve-static: 2.1.0 serve-static: 2.2.0
setprototypeof: 1.2.0 setprototypeof: 1.2.0
statuses: 2.0.1 statuses: 2.0.1
type-is: 2.0.1 type-is: 2.0.1
@@ -6463,7 +6445,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
serve-static@2.1.0: serve-static@2.2.0:
dependencies: dependencies:
encodeurl: 2.0.0 encodeurl: 2.0.0
escape-html: 1.0.3 escape-html: 1.0.3

View File

@@ -1,3 +1,4 @@
import { ISyncEventStore } from "applesauce-core";
import { Database } from "better-sqlite3"; import { Database } from "better-sqlite3";
import { Filter, NostrEvent, kinds } from "nostr-tools"; import { Filter, NostrEvent, kinds } from "nostr-tools";
import EventEmitter from "events"; import EventEmitter from "events";
@@ -184,7 +185,7 @@ type EventMap = {
"event:removed": [string]; "event:removed": [string];
}; };
export class SQLiteEventStore extends EventEmitter<EventMap> { export class SQLiteEventStore extends EventEmitter<EventMap> implements ISyncEventStore {
db: Database; db: Database;
log = logger.extend("sqlite-event-store"); log = logger.extend("sqlite-event-store");
@@ -330,20 +331,7 @@ export class SQLiteEventStore extends EventEmitter<EventMap> {
} }
} }
removeEvent(id: string) { protected buildConditionsForFilters(filter: Filter) {
const results = this.db.transaction(() => {
this.db.prepare(`DELETE FROM tags WHERE e = ?`).run(id);
this.db.prepare(`DELETE FROM events_fts WHERE id = ?`).run(id);
return this.db.prepare(`DELETE FROM events WHERE events.id = ?`).run(id);
})();
if (results.changes > 0) this.emit("event:removed", id);
return results.changes > 0;
}
buildConditionsForFilters(filter: Filter) {
const joins: string[] = []; const joins: string[] = [];
const conditions: string[] = []; const conditions: string[] = [];
const parameters: (string | number)[] = []; const parameters: (string | number)[] = [];
@@ -484,6 +472,39 @@ export class SQLiteEventStore extends EventEmitter<EventMap> {
return { sql, parameters }; return { sql, parameters };
} }
hasEvent(id: string): boolean {
return this.db.prepare<[string], { id: string }>(`SELECT id FROM events WHERE id = ?`).get(id) !== undefined;
}
getEvent(id: string): NostrEvent | undefined {
const row = this.db.prepare<[string], EventRow>(`SELECT * FROM events WHERE id = ?`).get(id);
if (!row) return undefined;
return parseEventRow(row);
}
hasReplaceable(kind: number, pubkey: string, identifier?: string): boolean {
return this.getReplaceable(kind, pubkey, identifier) !== undefined;
}
getReplaceable(kind: number, pubkey: string, identifier?: string): NostrEvent | undefined {
const filter: Filter = { kinds: [kind], authors: [pubkey], limit: 1 };
if (identifier) filter["#d"] = [identifier];
return this.getEventsForFilters([filter])[0];
}
getReplaceableHistory(kind: number, pubkey: string, identifier?: string): NostrEvent[] {
const filter: Filter = { kinds: [kind], authors: [pubkey] };
if (identifier) filter["#d"] = [identifier];
return this.getEventsForFilters([filter]);
}
getTimeline(filters: Filter | Filter[]): NostrEvent[] {
return this.getEventsForFilters(Array.isArray(filters) ? filters : [filters]);
}
getAll(filters: Filter | Filter[]): Set<NostrEvent> {
return new Set(this.getEventsForFilters(Array.isArray(filters) ? filters : [filters]));
}
getEventsForFilters(filters: Filter[]) { getEventsForFilters(filters: Filter[]) {
const { sql, parameters } = this.buildSQLQueryForFilters(filters); const { sql, parameters } = this.buildSQLQueryForFilters(filters);