mirror of
https://github.com/mikedilger/gossip.git
synced 2024-09-29 00:11:01 +00:00
lmdb: search_event()
This commit is contained in:
parent
6b537dc431
commit
49e7942f0b
@ -1,12 +1,11 @@
|
||||
use crate::error::Error;
|
||||
use crate::globals::GLOBALS;
|
||||
use nostr_types::{Event, IdHex, PublicKeyHex};
|
||||
use nostr_types::{IdHex, PublicKeyHex};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::task::spawn_blocking;
|
||||
|
||||
/*
|
||||
overlord:
|
||||
search
|
||||
|
||||
process:
|
||||
replace
|
||||
@ -29,34 +28,6 @@ pub struct DbEvent {
|
||||
}
|
||||
|
||||
impl DbEvent {
|
||||
pub async fn search(text: &str) -> Result<Vec<Event>, Error> {
|
||||
let sql = format!("SELECT raw FROM event WHERE (kind=1 OR kind=30023) AND (\
|
||||
content LIKE '%{text}%' \
|
||||
OR \
|
||||
id IN (SELECT event FROM event_tag WHERE label IN ('t', 'subject', 'summary', 'title') AND field0 like '%{text}%') \
|
||||
) \
|
||||
ORDER BY created_at DESC");
|
||||
|
||||
let output: Result<Vec<Event>, Error> = spawn_blocking(move || {
|
||||
let db = GLOBALS.db.blocking_lock();
|
||||
let mut stmt = db.prepare(&sql)?;
|
||||
let mut rows = stmt.query([])?;
|
||||
let mut output: Vec<Event> = Vec::new();
|
||||
while let Some(row) = rows.next()? {
|
||||
let raw: String = row.get(0)?;
|
||||
let event: Event = match serde_json::from_str(&raw) {
|
||||
Ok(e) => e,
|
||||
Err(_) => continue, // ignore the error, keep searching
|
||||
};
|
||||
output.push(event);
|
||||
}
|
||||
Ok(output)
|
||||
})
|
||||
.await?;
|
||||
|
||||
output
|
||||
}
|
||||
|
||||
pub async fn insert(event: DbEvent) -> Result<(), Error> {
|
||||
let sql = "INSERT OR IGNORE INTO event (id, raw, pubkey, created_at, kind, content, ots) \
|
||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7)";
|
||||
|
@ -3,7 +3,7 @@ mod minion;
|
||||
use crate::comms::{
|
||||
RelayJob, ToMinionMessage, ToMinionPayload, ToMinionPayloadDetail, ToOverlordMessage,
|
||||
};
|
||||
use crate::db::{DbEvent, DbEventRelay, DbPersonRelay, DbRelay};
|
||||
use crate::db::{DbEventRelay, DbPersonRelay, DbRelay};
|
||||
use crate::error::{Error, ErrorKind};
|
||||
use crate::globals::{ZapState, GLOBALS};
|
||||
use crate::people::People;
|
||||
@ -1970,7 +1970,7 @@ impl Overlord {
|
||||
let people_search_results = People::fetch(Some(&clause)).await?;
|
||||
*GLOBALS.people_search_results.write() = people_search_results;
|
||||
|
||||
let note_search_results = DbEvent::search(&text).await?;
|
||||
let note_search_results = GLOBALS.storage.search_events(&text)?;
|
||||
*GLOBALS.note_search_results.write() = note_search_results;
|
||||
|
||||
Ok(())
|
||||
|
@ -454,6 +454,64 @@ impl Storage {
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
pub fn search_events(&self, text: &str) -> Result<Vec<Event>, Error> {
|
||||
let event_kinds = GLOBALS.settings.read().feed_displayable_event_kinds();
|
||||
|
||||
let needle = regex::escape(text.to_lowercase().as_str());
|
||||
let re = regex::RegexBuilder::new(needle.as_str())
|
||||
.unicode(true)
|
||||
.case_insensitive(true)
|
||||
.build()?;
|
||||
|
||||
let mut events = self.filter_events(|event| {
|
||||
// Only feed displayable events please
|
||||
if !event_kinds.contains(&event.kind) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Match contents
|
||||
if re.is_match(event.content.as_ref()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Match human readable tags
|
||||
for tag in &event.tags {
|
||||
match tag {
|
||||
Tag::Hashtag { hashtag, .. } => {
|
||||
if re.is_match(hashtag.as_ref()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Tag::Subject { subject, .. } => {
|
||||
if re.is_match(subject.as_ref()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Tag::Title { title, .. } => {
|
||||
if re.is_match(title.as_ref()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Tag::Other { tag, data } => {
|
||||
if tag == "summary" && !data.is_empty() && re.is_match(data[0].as_ref()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
})?;
|
||||
|
||||
events.sort_unstable_by(|a, b| {
|
||||
// ORDER created_at desc
|
||||
b.created_at.cmp(&a.created_at)
|
||||
});
|
||||
|
||||
Ok(events)
|
||||
}
|
||||
|
||||
// TBD: optimize this by storing better event indexes
|
||||
// currently we stupidly scan every event (just to get LMDB up and running first)
|
||||
pub fn fetch_contact_list(&self, pubkey: &PublicKey) -> Result<Option<Event>, Error> {
|
||||
|
Loading…
Reference in New Issue
Block a user