mirror of
https://github.com/DocNR/POWR.git
synced 2025-04-23 01:01:27 +00:00
115 lines
3.2 KiB
TypeScript
115 lines
3.2 KiB
TypeScript
// lib/db/services/EventCache.ts
|
|
import { SQLiteDatabase } from 'expo-sqlite';
|
|
import { NostrEvent } from '@/types/nostr';
|
|
|
|
export class EventCache {
|
|
private db: SQLiteDatabase;
|
|
private writeBuffer: { query: string; params: any[] }[] = [];
|
|
|
|
constructor(db: SQLiteDatabase) {
|
|
this.db = db;
|
|
}
|
|
|
|
async setEvent(event: NostrEvent, inTransaction: boolean = false): Promise<void> {
|
|
try {
|
|
// Store queries to execute
|
|
const queries = [
|
|
{
|
|
query: `INSERT OR REPLACE INTO nostr_events
|
|
(id, pubkey, kind, created_at, content, sig, raw_event, received_at)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
params: [
|
|
event.id || '', // Convert undefined to empty string
|
|
event.pubkey || '',
|
|
event.kind,
|
|
event.created_at,
|
|
event.content,
|
|
event.sig || '',
|
|
JSON.stringify(event),
|
|
Date.now()
|
|
]
|
|
},
|
|
// Add metadata query
|
|
{
|
|
query: `INSERT OR REPLACE INTO cache_metadata
|
|
(content_id, content_type, last_accessed, access_count)
|
|
VALUES (?, ?, ?, 1)
|
|
ON CONFLICT(content_id) DO UPDATE SET
|
|
last_accessed = ?,
|
|
access_count = access_count + 1`,
|
|
params: [
|
|
event.id || '',
|
|
'event',
|
|
Date.now(),
|
|
Date.now()
|
|
]
|
|
}
|
|
];
|
|
|
|
// Add tag queries
|
|
event.tags.forEach((tag, index) => {
|
|
queries.push({
|
|
query: `INSERT OR REPLACE INTO event_tags
|
|
(event_id, name, value, index_num)
|
|
VALUES (?, ?, ?, ?)`,
|
|
params: [
|
|
event.id || '',
|
|
tag[0] || '',
|
|
tag[1] || '',
|
|
index
|
|
]
|
|
});
|
|
});
|
|
|
|
// If we're already in a transaction, just execute the queries
|
|
if (inTransaction) {
|
|
for (const { query, params } of queries) {
|
|
await this.db.runAsync(query, params);
|
|
}
|
|
} else {
|
|
// Otherwise, wrap in our own transaction
|
|
await this.db.withTransactionAsync(async () => {
|
|
for (const { query, params } of queries) {
|
|
await this.db.runAsync(query, params);
|
|
}
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('Error caching event:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async getEvent(id: string): Promise<NostrEvent | null> {
|
|
try {
|
|
const event = await this.db.getFirstAsync<any>(
|
|
`SELECT * FROM nostr_events WHERE id = ?`,
|
|
[id]
|
|
);
|
|
|
|
if (!event) return null;
|
|
|
|
// Get tags
|
|
const tags = await this.db.getAllAsync<{ name: string; value: string }>(
|
|
`SELECT name, value FROM event_tags WHERE event_id = ? ORDER BY index_num`,
|
|
[id]
|
|
);
|
|
|
|
// Update access metadata
|
|
await this.db.runAsync(
|
|
`UPDATE cache_metadata
|
|
SET last_accessed = ?, access_count = access_count + 1
|
|
WHERE content_id = ?`,
|
|
[Date.now(), id]
|
|
);
|
|
|
|
return {
|
|
...event,
|
|
tags: tags.map(tag => [tag.name, tag.value])
|
|
};
|
|
} catch (error) {
|
|
console.error('Error getting event from cache:', error);
|
|
return null;
|
|
}
|
|
}
|
|
} |