From 9814f9277a40dbdc622cef9e50756ab8bf7c0950 Mon Sep 17 00:00:00 2001 From: Jack Chakany Date: Wed, 12 Mar 2025 11:15:23 -0400 Subject: [PATCH] change all cols in events to virtual ones that are generated on read, additionally refactor the insert event function --- migrations/001-nostr_events/up.sql | 17 +++++--- src/db.rs | 66 ++++++------------------------ src/main.rs | 2 +- 3 files changed, 24 insertions(+), 61 deletions(-) diff --git a/migrations/001-nostr_events/up.sql b/migrations/001-nostr_events/up.sql index d1852ec..bb45ba2 100644 --- a/migrations/001-nostr_events/up.sql +++ b/migrations/001-nostr_events/up.sql @@ -1,9 +1,14 @@ CREATE TABLE IF NOT EXISTS events ( id TEXT PRIMARY KEY, - pubkey TEXT NOT NULL, - created_at INTEGER NOT NULL, - kind INTEGER NOT NULL, - tags TEXT NOT NULL CHECK (json_valid (tags)), - content TEXT NOT NULL, - sig TEXT + pubkey TEXT NOT NULL GENERATED ALWAYS AS (jsonb_extract (raw, '$.pubkey')), + created_at INTEGER NOT NULL GENERATED ALWAYS AS (jsonb_extract (raw, '$.created_at')) VIRTUAL, + kind INTEGER NOT NULL GENERATED ALWAYS AS (jsonb_extract (raw, '$.kind')) VIRTUAL, + tags BLOB NOT NULL GENERATED ALWAYS AS (jsonb_extract (raw, '$.tags')) VIRTUAL, + content TEXT NOT NULL GENERATED ALWAYS AS (jsonb_extract (raw, '$.content')) VIRTUAL, + sig TEXT GENERATED ALWAYS AS (jsonb_extract (raw, '$.sig')) VIRTUAL, + raw BLOB NOT NULL ); + +-- indexes +CREATE INDEX idx_events_pubkey ON events (pubkey); +CREATE INDEX idx_events_kind ON events (created_at); diff --git a/src/db.rs b/src/db.rs index dc47ca5..420f397 100644 --- a/src/db.rs +++ b/src/db.rs @@ -30,11 +30,7 @@ impl Db { Ok(Self { connection: conn }) } - /// Store a mail event in the database - /// - /// This function first attempts to unwrap the gift wrap if necessary, - /// and then stores the event in the database. - pub fn store_mail_event( + pub fn store_event( &self, event: &Event, account_manager: &mut AccountManager, @@ -43,53 +39,33 @@ impl Db { let store_unwrapped = is_gift_wrap(event) && account_manager.unwrap_gift_wrap(event).is_ok(); - // Determine what event to store if store_unwrapped { - // Unwrap succeeded, store the unwrapped event let unwrapped = account_manager.unwrap_gift_wrap(event).unwrap(); + let mut rumor = unwrapped.rumor.clone(); + rumor.ensure_id(); - // Get event details from the unwrapped gift - let id = match unwrapped.rumor.id { - Some(id) => id.to_string(), - None => "unknown".to_string(), - }; - let pubkey = unwrapped.rumor.pubkey.to_string(); - let created_at = unwrapped.rumor.created_at.as_u64(); - let kind = unwrapped.rumor.kind.as_u16() as u32; - let tags_json = json!(unwrapped.rumor.tags).to_string(); - let content = unwrapped.rumor.content.clone(); - let sig = unwrapped.sender.to_string(); // Use sender pubkey as signature reference + let id = rumor.id.expect("Invalid Gift Wrapped Event: There is no ID!").to_hex(); + let raw = json!(rumor).to_string(); - // Store the unwrapped event in the database self.connection.execute( - "INSERT OR REPLACE INTO events (id, pubkey, created_at, kind, tags, content, sig) - VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)", - (id, pubkey, created_at, kind, tags_json, content, sig), + "INSERT INTO events (id, raw) + VALUES (?1, ?2)", + (id, raw), )?; } else { - // Use original event - // Convert tags to JSON string for storage - let tags_json = json!(event.tags).to_string(); - - // Get event details let id = event.id.to_string(); - let pubkey = event.pubkey.to_string(); - let created_at = event.created_at.as_u64(); - let kind = event.kind.as_u16() as u32; - let sig = event.sig.to_string(); + let raw = json!(event).to_string(); - // Store the event in the database self.connection.execute( - "INSERT OR REPLACE INTO events (id, pubkey, created_at, kind, tags, content, sig) - VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)", - (id, pubkey, created_at, kind, tags_json, &event.content, sig), + "INSERT INTO events (id, raw) + VALUES (?1, ?2)", + (id, raw), )?; } Ok(()) } - /// Check if the database contains an event with the given ID pub fn has_event(&self, event_id: &str) -> Result { let count: i64 = self.connection.query_row( "SELECT COUNT(*) FROM events WHERE id = ?", @@ -125,24 +101,6 @@ impl Db { Ok(ids) } - - /// Get the JSON representation of an event by its ID - pub fn get_event_json(&self, event_id: &str) -> Result> { - let result = self.connection.query_row( - "SELECT json_object('id', id, 'pubkey', pubkey, 'created_at', created_at, - 'kind', kind, 'tags', json(tags), 'content', content, - 'sig', sig) - FROM events WHERE id = ?", - [event_id], - |row| row.get::<_, String>(0), - ); - - match result { - Ok(json) => Ok(Some(json)), - Err(rusqlite::Error::QueryReturnedNoRows) => Ok(None), - Err(e) => Err(e.into()), - } - } } /// Check if an event is a gift wrap diff --git a/src/main.rs b/src/main.rs index 0cfee52..ba95caa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -182,7 +182,7 @@ fn process_event(app: &mut Hoot, _sub_id: &str, event_json: &str) { app.events.push(event.clone()); // Store the event in the database - if let Err(e) = app.db.store_mail_event(&event, &mut app.account_manager) { + if let Err(e) = app.db.store_event(&event, &mut app.account_manager) { error!("Failed to store event in database: {}", e); } else { debug!("Successfully stored event with id {} in database", event.id);