From 4f8667da827e417fbee661dee247297cb7bef45b Mon Sep 17 00:00:00 2001 From: Mike Dilger Date: Sat, 24 Dec 2022 07:01:42 +1300 Subject: [PATCH] schema3: extended person_relay, event_relationship, event_hashtag --- src/db/event_hashtag.rs | 51 +++++++++++++++++++++++++++++++ src/db/event_relationship.rs | 59 ++++++++++++++++++++++++++++++++++++ src/db/mod.rs | 7 +++++ src/db/person_relay.rs | 42 ++++++++++++++++++------- src/db/schema3.sql | 21 +++++++++++++ src/globals.rs | 3 +- 6 files changed, 170 insertions(+), 13 deletions(-) create mode 100644 src/db/event_hashtag.rs create mode 100644 src/db/event_relationship.rs create mode 100644 src/db/schema3.sql diff --git a/src/db/event_hashtag.rs b/src/db/event_hashtag.rs new file mode 100644 index 00000000..d5c43d44 --- /dev/null +++ b/src/db/event_hashtag.rs @@ -0,0 +1,51 @@ +use crate::error::Error; +use crate::globals::GLOBALS; +use serde::{Deserialize, Serialize}; +use tokio::task::spawn_blocking; + +#[derive(Debug, Serialize, Deserialize)] +pub struct DbEventHashtag { + pub event: String, + pub hashtag: String, +} + +impl DbEventHashtag { + #[allow(dead_code)] + pub async fn insert(&self) -> Result<(), Error> { + let event = self.event.clone(); + let hashtag = self.hashtag.clone(); + let sql = "INSERT OR IGNORE INTO event_hashtag (event, hashtag) VALUES (?, ?)"; + spawn_blocking(move || { + let maybe_db = GLOBALS.db.blocking_lock(); + let db = maybe_db.as_ref().unwrap(); + let mut stmt = db.prepare(sql)?; + stmt.execute((&event, &hashtag))?; + Ok::<(), Error>(()) + }) + .await??; + Ok(()) + } + + #[allow(dead_code)] + pub async fn get_events_with_hashtag(hashtag: String) -> Result, Error> { + let sql = "SELECT event FROM event_hashtag WHERE hashtag=?"; + let output: Result, Error> = spawn_blocking(move || { + let maybe_db = GLOBALS.db.blocking_lock(); + let db = maybe_db.as_ref().unwrap(); + let mut stmt = db.prepare(sql)?; + let rows = stmt.query_map([hashtag.clone()], |row| { + Ok(DbEventHashtag { + event: row.get(0)?, + hashtag: hashtag.clone(), + }) + })?; + let mut output: Vec = Vec::new(); + for row in rows { + output.push(row?); + } + Ok(output) + }) + .await?; + output + } +} diff --git a/src/db/event_relationship.rs b/src/db/event_relationship.rs new file mode 100644 index 00000000..159050ce --- /dev/null +++ b/src/db/event_relationship.rs @@ -0,0 +1,59 @@ +use crate::error::Error; +use crate::globals::GLOBALS; +use nostr_types::Id; +use serde::{Deserialize, Serialize}; +use tokio::task::spawn_blocking; + +#[derive(Debug, Serialize, Deserialize)] +pub struct DbEventRelationship { + pub original: String, + pub referring: String, + pub relationship: String, + pub content: Option, +} + +impl DbEventRelationship { + #[allow(dead_code)] + pub async fn insert(&self) -> Result<(), Error> { + let original = self.original.clone(); + let referring = self.referring.clone(); + let relationship = self.relationship.clone(); + let content = self.content.clone(); + let sql = "INSERT OR IGNORE INTO event_relationship (original, referring, relationship, content) VALUES (?, ?, ?, ?)"; + spawn_blocking(move || { + let maybe_db = GLOBALS.db.blocking_lock(); + let db = maybe_db.as_ref().unwrap(); + let mut stmt = db.prepare(sql)?; + stmt.execute((&original, &referring, &relationship, &content))?; + Ok::<(), Error>(()) + }) + .await??; + Ok(()) + } + + #[allow(dead_code)] + pub async fn get_events_referring_to(id: Id) -> Result, Error> { + let sql = + "SELECT referring, relationship, content FROM event_relationship WHERE original=?"; + let output: Result, Error> = spawn_blocking(move || { + let maybe_db = GLOBALS.db.blocking_lock(); + let db = maybe_db.as_ref().unwrap(); + let mut stmt = db.prepare(sql)?; + let rows = stmt.query_map([id.as_hex_string()], |row| { + Ok(DbEventRelationship { + original: id.as_hex_string(), + referring: row.get(0)?, + relationship: row.get(1)?, + content: row.get(2)?, + }) + })?; + let mut output: Vec = Vec::new(); + for row in rows { + output.push(row?); + } + Ok(output) + }) + .await?; + output + } +} diff --git a/src/db/mod.rs b/src/db/mod.rs index 57e10bcf..288c7a40 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -4,9 +4,15 @@ pub use event::DbEvent; mod event_seen; pub use event_seen::DbEventSeen; +mod event_hashtag; +pub use event_hashtag::DbEventHashtag; + mod event_tag; pub use event_tag::DbEventTag; +mod event_relationship; +pub use event_relationship::DbEventRelationship; + mod relay; pub use relay::DbRelay; @@ -99,6 +105,7 @@ macro_rules! apply_sql { fn upgrade(db: &Connection, mut version: u16) -> Result<(), Error> { apply_sql!(db, version, 1, "schema1.sql"); apply_sql!(db, version, 2, "schema2.sql"); + apply_sql!(db, version, 3, "schema3.sql"); info!("Database is at version {}", version); Ok(()) diff --git a/src/db/person_relay.rs b/src/db/person_relay.rs index 579ddb1e..f7bdf69a 100644 --- a/src/db/person_relay.rs +++ b/src/db/person_relay.rs @@ -4,18 +4,22 @@ use nostr_types::PublicKeyHex; use serde::{Deserialize, Serialize}; use tokio::task::spawn_blocking; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Default, Serialize, Deserialize)] pub struct DbPersonRelay { pub person: String, pub relay: String, - pub recommended: u8, pub last_fetched: Option, + pub last_suggested_kind2: Option, + pub last_suggested_kind3: Option, + pub last_suggested_nip23: Option, + pub last_suggested_nip35: Option, + pub last_suggested_bytag: Option, } impl DbPersonRelay { #[allow(dead_code)] pub async fn fetch(criteria: Option<&str>) -> Result, Error> { - let sql = "SELECT person, relay, recommended, last_fetched FROM person_relay".to_owned(); + let sql = "SELECT person, relay, last_fetched, last_suggested_kind2, last_suggested_kind3, last_suggested_nip23, last_suggested_nip35, last_suggested_bytag FROM person_relay".to_owned(); let sql = match criteria { None => sql, Some(crit) => format!("{} WHERE {}", sql, crit), @@ -30,8 +34,12 @@ impl DbPersonRelay { Ok(DbPersonRelay { person: row.get(0)?, relay: row.get(1)?, - recommended: row.get(2)?, - last_fetched: row.get(3)?, + last_fetched: row.get(2)?, + last_suggested_kind2: row.get(3)?, + last_suggested_kind3: row.get(4)?, + last_suggested_nip23: row.get(5)?, + last_suggested_nip35: row.get(6)?, + last_suggested_bytag: row.get(7)?, }) })?; @@ -53,7 +61,9 @@ impl DbPersonRelay { } let sql = format!( - "SELECT person, relay, recommended, person_relay.last_fetched \ + "SELECT person, relay, person_relay.last_fetched, \ + last_suggested_kind2, last_suggested_kind3, last_suggested_nip23, \ + last_suggested_nip35, last_suggested_bytag \ FROM person_relay \ INNER JOIN relay ON person_relay.relay=relay.url \ WHERE person IN ({}) ORDER BY person, relay.rank DESC", @@ -71,8 +81,12 @@ impl DbPersonRelay { Ok(DbPersonRelay { person: row.get(0)?, relay: row.get(1)?, - recommended: row.get(2)?, - last_fetched: row.get(3)?, + last_fetched: row.get(2)?, + last_suggested_kind2: row.get(3)?, + last_suggested_kind3: row.get(4)?, + last_suggested_nip23: row.get(5)?, + last_suggested_nip35: row.get(6)?, + last_suggested_bytag: row.get(7)?, }) })?; @@ -123,8 +137,10 @@ impl DbPersonRelay { } pub async fn insert(person_relay: DbPersonRelay) -> Result<(), Error> { - let sql = "INSERT OR IGNORE INTO person_relay (person, relay, recommended, last_fetched) \ - VALUES (?1, ?2, ?3, ?4)"; + let sql = "INSERT OR IGNORE INTO person_relay (person, relay, last_fetched, \ + last_suggested_kind2, last_suggested_kind3, last_suggested_nip23, \ + last_suggested_nip35, last_suggested_bytag) \ + VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; spawn_blocking(move || { let maybe_db = GLOBALS.db.blocking_lock(); @@ -134,8 +150,12 @@ impl DbPersonRelay { stmt.execute(( &person_relay.person, &person_relay.relay, - &person_relay.recommended, &person_relay.last_fetched, + &person_relay.last_suggested_kind2, + &person_relay.last_suggested_kind3, + &person_relay.last_suggested_nip23, + &person_relay.last_suggested_nip35, + &person_relay.last_suggested_bytag, ))?; Ok::<(), Error>(()) }) diff --git a/src/db/schema3.sql b/src/db/schema3.sql new file mode 100644 index 00000000..eb183c52 --- /dev/null +++ b/src/db/schema3.sql @@ -0,0 +1,21 @@ + +ALTER TABLE person_relay ADD COLUMN last_suggested_kind2 INTEGER DEFAULT NULL; +ALTER TABLE person_relay ADD COLUMN last_suggested_kind3 INTEGER DEFAULT NULL; +ALTER TABLE person_relay ADD COLUMN last_suggested_nip23 INTEGER DEFAULT NULL; +ALTER TABLE person_relay ADD COLUMN last_suggested_nip35 INTEGER DEFAULT NULL; +ALTER TABLE person_relay ADD COLUMN last_suggested_bytag INTEGER DEFAULT NULL; +ALTER TABLE person_relay DROP COLUMN recommended; + +CREATE TABLE event_relationship ( + original TEXT NOT NULL, + referring TEXT NOT NULL, + relationship TEXT CHECK (relationship IN ('reply', 'quote', 'reaction', 'deletion')) NOT NULL, + content TEXT DEFAULT NULL, + UNIQUE(original, referring) +); + +CREATE TABLE event_hashtag ( + event TEXT NOT NULL, + hashtag TEXT NOT NULL, + UNIQUE(event, hashtag) +); diff --git a/src/globals.rs b/src/globals.rs index 51a96e69..d17b2435 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -485,8 +485,7 @@ pub async fn follow_key_and_relay(pubkey: String, relay: String) -> Result