mirror of
https://github.com/mikedilger/gossip.git
synced 2024-09-29 16:31:18 +00:00
Events::get_local_events_by_filter()
This commit is contained in:
parent
e8ac8d4d5f
commit
80f03a57fe
123
src/events.rs
123
src/events.rs
@ -2,7 +2,8 @@ use crate::error::Error;
|
||||
use crate::globals::GLOBALS;
|
||||
use async_recursion::async_recursion;
|
||||
use dashmap::DashMap;
|
||||
use nostr_types::{Event, Id};
|
||||
use nostr_types::{Event, Filter, Id};
|
||||
use std::fmt::Display;
|
||||
use tokio::task;
|
||||
|
||||
pub struct Events {
|
||||
@ -30,7 +31,7 @@ impl Events {
|
||||
self.events.get(id).map(|e| e.value().to_owned())
|
||||
}
|
||||
|
||||
/// Get the event from memory, and also try the database
|
||||
/// Get the event from memory, and also try the database, by Id
|
||||
pub async fn get_local(&self, id: Id) -> Result<Option<Event>, Error> {
|
||||
if let Some(e) = self.get(&id) {
|
||||
return Ok(Some(e));
|
||||
@ -61,6 +62,92 @@ impl Events {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get event from database, by Filter
|
||||
#[allow(dead_code)]
|
||||
pub async fn get_local_events_by_filter(&self, filter: Filter) -> Result<Vec<Event>, Error> {
|
||||
let mut conditions: Vec<String> = Vec::new();
|
||||
if !filter.ids.is_empty() {
|
||||
conditions.push(build_prefix_condition("id", &filter.ids));
|
||||
}
|
||||
if !filter.authors.is_empty() {
|
||||
conditions.push(build_prefix_condition("pubkey", &filter.authors));
|
||||
}
|
||||
if !filter.kinds.is_empty() {
|
||||
let mut c = "kind in (".to_owned();
|
||||
let mut virgin = true;
|
||||
for kind in filter.kinds.iter() {
|
||||
if !virgin {
|
||||
c.push(',');
|
||||
}
|
||||
virgin = false;
|
||||
let k: u64 = (*kind).into();
|
||||
c.push_str(&format!("{}", k));
|
||||
}
|
||||
c.push(')');
|
||||
conditions.push(c);
|
||||
}
|
||||
if !filter.a.is_empty() {
|
||||
conditions.push(build_tag_condition("a", &filter.a));
|
||||
}
|
||||
if !filter.d.is_empty() {
|
||||
conditions.push(build_tag_condition("d", &filter.d));
|
||||
}
|
||||
if !filter.e.is_empty() {
|
||||
conditions.push(build_tag_condition("e", &filter.e));
|
||||
}
|
||||
if !filter.g.is_empty() {
|
||||
conditions.push(build_tag_condition("g", &filter.g));
|
||||
}
|
||||
if !filter.p.is_empty() {
|
||||
conditions.push(build_tag_condition("p", &filter.p));
|
||||
}
|
||||
if !filter.r.is_empty() {
|
||||
conditions.push(build_tag_condition("r", &filter.r));
|
||||
}
|
||||
if !filter.t.is_empty() {
|
||||
conditions.push(build_tag_condition("t", &filter.t));
|
||||
}
|
||||
if let Some(since) = filter.since {
|
||||
conditions.push(format!("created_at >= {}", since.0));
|
||||
}
|
||||
if let Some(until) = filter.until {
|
||||
conditions.push(format!("created_at <= {}", until.0));
|
||||
}
|
||||
|
||||
let mut sql = format!("SELECT raw FROM event WHERE {}", conditions.join(" AND "));
|
||||
|
||||
if let Some(limit) = filter.limit {
|
||||
sql.push_str(&(format!(" LIMIT {}", limit)));
|
||||
}
|
||||
|
||||
tracing::trace!("get_local_events_by_filter SQL={}", &sql);
|
||||
|
||||
let events_result = task::spawn_blocking(move || -> Result<Vec<Event>, Error> {
|
||||
let maybe_db = GLOBALS.db.blocking_lock();
|
||||
let db = maybe_db.as_ref().unwrap();
|
||||
let mut stmt = db.prepare(&sql)?;
|
||||
let mut rows = stmt.raw_query();
|
||||
let mut events: Vec<Event> = Vec::new();
|
||||
while let Some(row) = rows.next()? {
|
||||
let s: String = row.get(0)?;
|
||||
events.push(serde_json::from_str(&s)?);
|
||||
}
|
||||
Ok(events)
|
||||
})
|
||||
.await?;
|
||||
let events = events_result?;
|
||||
|
||||
for event in events.iter() {
|
||||
// Process that event
|
||||
crate::process::process_new_event(event, false, None, None).await?;
|
||||
|
||||
// Add to memory
|
||||
self.insert(event.clone());
|
||||
}
|
||||
|
||||
Ok(events)
|
||||
}
|
||||
|
||||
#[async_recursion]
|
||||
pub async fn get_highest_local_parent(&self, id: &Id) -> Result<Option<Id>, Error> {
|
||||
if let Some(event) = self.get_local(*id).await? {
|
||||
@ -81,3 +168,35 @@ impl Events {
|
||||
self.events.iter()
|
||||
}
|
||||
}
|
||||
|
||||
fn build_prefix_condition<T: Display>(field: &str, values: &[T]) -> String {
|
||||
let mut c = "(".to_owned();
|
||||
let mut virgin = true;
|
||||
for val in values.iter() {
|
||||
if !virgin {
|
||||
c.push_str(" OR ");
|
||||
}
|
||||
virgin = false;
|
||||
c.push_str(&format!("{} LIKE '{}%'", field, val));
|
||||
}
|
||||
c.push(')');
|
||||
c
|
||||
}
|
||||
|
||||
fn build_tag_condition<T: Display>(tag: &str, values: &[T]) -> String {
|
||||
// "id in (SELECT event FROM event_tag WHERE label='e' AND field0={})";
|
||||
let mut c = format!(
|
||||
"id in (SELECT event FROM event_tag WHERE label='{}' AND field0 IN (",
|
||||
tag
|
||||
);
|
||||
let mut virgin = true;
|
||||
for val in values.iter() {
|
||||
if !virgin {
|
||||
c.push(',');
|
||||
}
|
||||
virgin = false;
|
||||
c.push_str(&format!("'{}'", val));
|
||||
}
|
||||
c.push_str("))");
|
||||
c
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user