schema3: extended person_relay, event_relationship, event_hashtag

This commit is contained in:
Mike Dilger 2022-12-24 07:01:42 +13:00
parent 07e904ffac
commit 4f8667da82
6 changed files with 170 additions and 13 deletions

51
src/db/event_hashtag.rs Normal file
View File

@ -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<Vec<DbEventHashtag>, Error> {
let sql = "SELECT event FROM event_hashtag WHERE hashtag=?";
let output: Result<Vec<DbEventHashtag>, 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<DbEventHashtag> = Vec::new();
for row in rows {
output.push(row?);
}
Ok(output)
})
.await?;
output
}
}

View File

@ -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<String>,
}
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<Vec<DbEventRelationship>, Error> {
let sql =
"SELECT referring, relationship, content FROM event_relationship WHERE original=?";
let output: Result<Vec<DbEventRelationship>, 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<DbEventRelationship> = Vec::new();
for row in rows {
output.push(row?);
}
Ok(output)
})
.await?;
output
}
}

View File

@ -4,9 +4,15 @@ pub use event::DbEvent;
mod event_seen; mod event_seen;
pub use event_seen::DbEventSeen; pub use event_seen::DbEventSeen;
mod event_hashtag;
pub use event_hashtag::DbEventHashtag;
mod event_tag; mod event_tag;
pub use event_tag::DbEventTag; pub use event_tag::DbEventTag;
mod event_relationship;
pub use event_relationship::DbEventRelationship;
mod relay; mod relay;
pub use relay::DbRelay; pub use relay::DbRelay;
@ -99,6 +105,7 @@ macro_rules! apply_sql {
fn upgrade(db: &Connection, mut version: u16) -> Result<(), Error> { fn upgrade(db: &Connection, mut version: u16) -> Result<(), Error> {
apply_sql!(db, version, 1, "schema1.sql"); apply_sql!(db, version, 1, "schema1.sql");
apply_sql!(db, version, 2, "schema2.sql"); apply_sql!(db, version, 2, "schema2.sql");
apply_sql!(db, version, 3, "schema3.sql");
info!("Database is at version {}", version); info!("Database is at version {}", version);
Ok(()) Ok(())

View File

@ -4,18 +4,22 @@ use nostr_types::PublicKeyHex;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::task::spawn_blocking; use tokio::task::spawn_blocking;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Default, Serialize, Deserialize)]
pub struct DbPersonRelay { pub struct DbPersonRelay {
pub person: String, pub person: String,
pub relay: String, pub relay: String,
pub recommended: u8,
pub last_fetched: Option<u64>, pub last_fetched: Option<u64>,
pub last_suggested_kind2: Option<u64>,
pub last_suggested_kind3: Option<u64>,
pub last_suggested_nip23: Option<u64>,
pub last_suggested_nip35: Option<u64>,
pub last_suggested_bytag: Option<u64>,
} }
impl DbPersonRelay { impl DbPersonRelay {
#[allow(dead_code)] #[allow(dead_code)]
pub async fn fetch(criteria: Option<&str>) -> Result<Vec<DbPersonRelay>, Error> { pub async fn fetch(criteria: Option<&str>) -> Result<Vec<DbPersonRelay>, 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 { let sql = match criteria {
None => sql, None => sql,
Some(crit) => format!("{} WHERE {}", sql, crit), Some(crit) => format!("{} WHERE {}", sql, crit),
@ -30,8 +34,12 @@ impl DbPersonRelay {
Ok(DbPersonRelay { Ok(DbPersonRelay {
person: row.get(0)?, person: row.get(0)?,
relay: row.get(1)?, relay: row.get(1)?,
recommended: row.get(2)?, last_fetched: row.get(2)?,
last_fetched: row.get(3)?, 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!( 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 \ FROM person_relay \
INNER JOIN relay ON person_relay.relay=relay.url \ INNER JOIN relay ON person_relay.relay=relay.url \
WHERE person IN ({}) ORDER BY person, relay.rank DESC", WHERE person IN ({}) ORDER BY person, relay.rank DESC",
@ -71,8 +81,12 @@ impl DbPersonRelay {
Ok(DbPersonRelay { Ok(DbPersonRelay {
person: row.get(0)?, person: row.get(0)?,
relay: row.get(1)?, relay: row.get(1)?,
recommended: row.get(2)?, last_fetched: row.get(2)?,
last_fetched: row.get(3)?, 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> { pub async fn insert(person_relay: DbPersonRelay) -> Result<(), Error> {
let sql = "INSERT OR IGNORE INTO person_relay (person, relay, recommended, last_fetched) \ let sql = "INSERT OR IGNORE INTO person_relay (person, relay, last_fetched, \
VALUES (?1, ?2, ?3, ?4)"; last_suggested_kind2, last_suggested_kind3, last_suggested_nip23, \
last_suggested_nip35, last_suggested_bytag) \
VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
spawn_blocking(move || { spawn_blocking(move || {
let maybe_db = GLOBALS.db.blocking_lock(); let maybe_db = GLOBALS.db.blocking_lock();
@ -134,8 +150,12 @@ impl DbPersonRelay {
stmt.execute(( stmt.execute((
&person_relay.person, &person_relay.person,
&person_relay.relay, &person_relay.relay,
&person_relay.recommended,
&person_relay.last_fetched, &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>(()) Ok::<(), Error>(())
}) })

21
src/db/schema3.sql Normal file
View File

@ -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)
);

View File

@ -485,8 +485,7 @@ pub async fn follow_key_and_relay(pubkey: String, relay: String) -> Result<DbPer
DbPersonRelay::insert(DbPersonRelay { DbPersonRelay::insert(DbPersonRelay {
person: pubkey, person: pubkey,
relay, relay,
recommended: 0, ..Default::default()
last_fetched: None,
}) })
.await .await
.map_err(|e| format!("{}", e))?; .map_err(|e| format!("{}", e))?;