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

View File

@ -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<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 {
#[allow(dead_code)]
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 {
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>(())
})

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 {
person: pubkey,
relay,
recommended: 0,
last_fetched: None,
..Default::default()
})
.await
.map_err(|e| format!("{}", e))?;