mirror of
https://github.com/mikedilger/chorus.git
synced 2026-05-03 06:51:42 +00:00
Store.find_events()
This commit is contained in:
parent
8ae3bc2b6b
commit
88f609c962
@ -59,6 +59,10 @@ pub enum Error {
|
|||||||
#[error("LMDB: {0}")]
|
#[error("LMDB: {0}")]
|
||||||
Lmdb(#[from] heed::Error),
|
Lmdb(#[from] heed::Error),
|
||||||
|
|
||||||
|
// Filter is underspecified
|
||||||
|
#[error("Filter is underspecified. Scrapers are not allowed")]
|
||||||
|
Scraper,
|
||||||
|
|
||||||
// UTF-8
|
// UTF-8
|
||||||
#[error("UTF-8: {0}")]
|
#[error("UTF-8: {0}")]
|
||||||
Utf8(#[from] std::str::Utf8Error),
|
Utf8(#[from] std::str::Utf8Error),
|
||||||
|
|||||||
149
src/store/mod.rs
149
src/store/mod.rs
@ -2,10 +2,11 @@ pub mod event_store;
|
|||||||
pub use event_store::EventStore;
|
pub use event_store::EventStore;
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::types::{Event, Id, Kind, Pubkey, Time};
|
use crate::types::{Event, Filter, Id, Kind, Pubkey, Time};
|
||||||
use heed::types::{OwnedType, UnalignedSlice};
|
use heed::types::{OwnedType, UnalignedSlice};
|
||||||
use heed::{Database, Env, EnvFlags, EnvOpenOptions};
|
use heed::{Database, Env, EnvFlags, EnvOpenOptions};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::ops::Bound;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Store {
|
pub struct Store {
|
||||||
@ -153,6 +154,152 @@ impl Store {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn find_events(&self, filter: Filter) -> Result<Vec<Event>, Error> {
|
||||||
|
let mut output: Vec<Event> = Vec::new();
|
||||||
|
|
||||||
|
if filter.num_ids() > 0 {
|
||||||
|
// Fetch by id
|
||||||
|
for id in filter.ids() {
|
||||||
|
if let Some(event) = self.get_event_by_id(id)? {
|
||||||
|
// and check each against the rest of the filter
|
||||||
|
if filter.event_matches(&event)? {
|
||||||
|
output.push(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Stop if limited
|
||||||
|
if output.len() >= filter.limit() as usize {
|
||||||
|
return Ok(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if filter.num_authors() > 0 && filter.num_kinds() > 0 {
|
||||||
|
for author in filter.authors() {
|
||||||
|
for kind in filter.kinds() {
|
||||||
|
let start_prefix = Self::key_akci(
|
||||||
|
author,
|
||||||
|
kind,
|
||||||
|
filter.until(), // scan goes backwards in time
|
||||||
|
Id([0; 32]),
|
||||||
|
);
|
||||||
|
let end_prefix = Self::key_akci(
|
||||||
|
author,
|
||||||
|
kind,
|
||||||
|
filter.since(), // scan goes backwards in time
|
||||||
|
Id([255; 32]),
|
||||||
|
);
|
||||||
|
let range = (
|
||||||
|
Bound::Included(&*start_prefix),
|
||||||
|
Bound::Excluded(&*end_prefix),
|
||||||
|
);
|
||||||
|
let txn = self.env.read_txn()?;
|
||||||
|
let iter = self.akci.range(&txn, &range)?;
|
||||||
|
for result in iter {
|
||||||
|
let (_key, offset) = result?;
|
||||||
|
if let Some(event) = self.events.get_event_by_offset(offset)? {
|
||||||
|
// check against the rest of the filter
|
||||||
|
if filter.event_matches(&event)? {
|
||||||
|
output.push(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Stop if limited
|
||||||
|
if output.len() >= filter.limit() as usize {
|
||||||
|
return Ok(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if filter.num_authors() > 0 && !filter.tags()?.is_empty() {
|
||||||
|
for author in filter.authors() {
|
||||||
|
let tags = filter.tags()?;
|
||||||
|
for mut tag in tags.iter() {
|
||||||
|
if let Some(tag0) = tag.next() {
|
||||||
|
if let Some(tagvalue) = tag.next() {
|
||||||
|
let start_prefix = Self::key_atci(
|
||||||
|
author,
|
||||||
|
tag0[0],
|
||||||
|
tagvalue,
|
||||||
|
filter.until(), // scan goes backwards in time
|
||||||
|
Id([0; 32]),
|
||||||
|
);
|
||||||
|
let end_prefix = Self::key_atci(
|
||||||
|
author,
|
||||||
|
tag0[0],
|
||||||
|
tagvalue,
|
||||||
|
filter.since(), // scan goes backwards in time
|
||||||
|
Id([255; 32]),
|
||||||
|
);
|
||||||
|
let range = (
|
||||||
|
Bound::Included(&*start_prefix),
|
||||||
|
Bound::Excluded(&*end_prefix),
|
||||||
|
);
|
||||||
|
let txn = self.env.read_txn()?;
|
||||||
|
let iter = self.akci.range(&txn, &range)?;
|
||||||
|
for result in iter {
|
||||||
|
let (_key, offset) = result?;
|
||||||
|
if let Some(event) = self.events.get_event_by_offset(offset)? {
|
||||||
|
// check against the rest of the filter
|
||||||
|
if filter.event_matches(&event)? {
|
||||||
|
output.push(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Stop if limited
|
||||||
|
if output.len() >= filter.limit() as usize {
|
||||||
|
return Ok(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if filter.num_kinds() > 0 && !filter.tags()?.is_empty() {
|
||||||
|
for kind in filter.kinds() {
|
||||||
|
let tags = filter.tags()?;
|
||||||
|
for mut tag in tags.iter() {
|
||||||
|
if let Some(tag0) = tag.next() {
|
||||||
|
if let Some(tagvalue) = tag.next() {
|
||||||
|
let start_prefix = Self::key_ktci(
|
||||||
|
kind,
|
||||||
|
tag0[0],
|
||||||
|
tagvalue,
|
||||||
|
filter.until(), // scan goes backwards in time
|
||||||
|
Id([0; 32]),
|
||||||
|
);
|
||||||
|
let end_prefix = Self::key_ktci(
|
||||||
|
kind,
|
||||||
|
tag0[0],
|
||||||
|
tagvalue,
|
||||||
|
filter.since(), // scan goes backwards in time
|
||||||
|
Id([255; 32]),
|
||||||
|
);
|
||||||
|
let range = (
|
||||||
|
Bound::Included(&*start_prefix),
|
||||||
|
Bound::Excluded(&*end_prefix),
|
||||||
|
);
|
||||||
|
let txn = self.env.read_txn()?;
|
||||||
|
let iter = self.akci.range(&txn, &range)?;
|
||||||
|
for result in iter {
|
||||||
|
let (_key, offset) = result?;
|
||||||
|
if let Some(event) = self.events.get_event_by_offset(offset)? {
|
||||||
|
// check against the rest of the filter
|
||||||
|
if filter.event_matches(&event)? {
|
||||||
|
output.push(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Stop if limited
|
||||||
|
if output.len() >= filter.limit() as usize {
|
||||||
|
return Ok(output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(Error::Scraper);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(output)
|
||||||
|
}
|
||||||
|
|
||||||
// For looking up event by Author and Kind
|
// For looking up event by Author and Kind
|
||||||
// author(32) + kind(2) + reversecreatedat(8) + id(32)
|
// author(32) + kind(2) + reversecreatedat(8) + id(32)
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user