|
@@ -8,9 +8,10 @@
|
|
//! let this crate build the needed indexes to find events quickly.
|
|
//! let this crate build the needed indexes to find events quickly.
|
|
#![deny(missing_docs, warnings)]
|
|
#![deny(missing_docs, warnings)]
|
|
mod error;
|
|
mod error;
|
|
|
|
+mod event_filter;
|
|
mod rocksdb;
|
|
mod rocksdb;
|
|
|
|
+mod secondary_index;
|
|
mod storage;
|
|
mod storage;
|
|
-mod util;
|
|
|
|
|
|
|
|
pub use crate::{error::Error, rocksdb::RocksDb, storage::Storage};
|
|
pub use crate::{error::Error, rocksdb::RocksDb, storage::Storage};
|
|
|
|
|
|
@@ -23,7 +24,11 @@ mod test {
|
|
io::{BufRead, BufReader},
|
|
io::{BufRead, BufReader},
|
|
};
|
|
};
|
|
|
|
|
|
- fn setup_db<T: Storage>(db: &T) {
|
|
|
|
|
|
+ fn setup_db<'a, T, I>(db: &'a T)
|
|
|
|
+ where
|
|
|
|
+ T: Storage<'a, I>,
|
|
|
|
+ I: Iterator<Item = Result<Event, Error>>,
|
|
|
|
+ {
|
|
let file = File::open("./tests/events.json").expect("file");
|
|
let file = File::open("./tests/events.json").expect("file");
|
|
let events = BufReader::new(file)
|
|
let events = BufReader::new(file)
|
|
.lines()
|
|
.lines()
|
|
@@ -35,7 +40,11 @@ mod test {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn store_and_get<T: Storage>(db: &T) {
|
|
|
|
|
|
+ pub fn store_and_get<'a, T, I>(db: &'a T)
|
|
|
|
+ where
|
|
|
|
+ T: Storage<'a, I>,
|
|
|
|
+ I: Iterator<Item = Result<Event, Error>>,
|
|
|
|
+ {
|
|
let json = "{\"content\":\"{\\\"lud06\\\":\\\"lnbc1p3a4wxvpp5x0pa6gr55fq5s9d3dxs0vz77mqxgdw63hhtgtlfz5zvm65847vnqdqqcqpjsp5402c8rtqxd4j97rnvuejuwl4sg473g6wg08d67fvn7qc4gtpkfks9q7sqqqqqqqqqqqqqqqqqqqsqqqqqysgqmqz9gxqyjw5qrzjqwryaup9lh50kkranzgcdnn2fgvx390wgj5jd07rwr3vxeje0glclleasn65surjcsqqqqlgqqqqqeqqjqyxj968tem9ps6ttm9ukv6ag4yc6qmgj2svrccfgp4n83fpktr3dsx6fq7grfzlqt982aaemahg9q29vzl9f627kh4j8h8xc2z2mtpdqqjlekah\\\",\\\"website\\\":\\\"\\\",\\\"nip05\\\":\\\"cesar@cesar.com.py\\\",\\\"picture\\\":\\\"https://pbs.twimg.com/profile_images/1175432935337537536/_Peu9vuJ_400x400.jpg\\\",\\\"display_name\\\":\\\"C\\\",\\\"about\\\":\\\"Rust and PHP\\\",\\\"name\\\":\\\"c\\\"}\",\"created_at\":1678476588,\"id\":\"3800c787a23288641c0b96cbcc87c26cbd3ea7bee53b7748422fdb100fb7b9f0\",\"kind\":0,\"pubkey\":\"b2815682cfc83fcd2c3add05785cf4573dd388457069974cc6d8cca06b3c3b78\",\"sig\":\"c8a12ce96833e4cd67bce0e9e50f831262ef0f0c0cff5e56c38a0c90867ed1a6621e9692948ef5e85a7ca3726c3f0f43fa7e1992536bc457317123bca8784f5f\",\"tags\":[]}";
|
|
let json = "{\"content\":\"{\\\"lud06\\\":\\\"lnbc1p3a4wxvpp5x0pa6gr55fq5s9d3dxs0vz77mqxgdw63hhtgtlfz5zvm65847vnqdqqcqpjsp5402c8rtqxd4j97rnvuejuwl4sg473g6wg08d67fvn7qc4gtpkfks9q7sqqqqqqqqqqqqqqqqqqqsqqqqqysgqmqz9gxqyjw5qrzjqwryaup9lh50kkranzgcdnn2fgvx390wgj5jd07rwr3vxeje0glclleasn65surjcsqqqqlgqqqqqeqqjqyxj968tem9ps6ttm9ukv6ag4yc6qmgj2svrccfgp4n83fpktr3dsx6fq7grfzlqt982aaemahg9q29vzl9f627kh4j8h8xc2z2mtpdqqjlekah\\\",\\\"website\\\":\\\"\\\",\\\"nip05\\\":\\\"cesar@cesar.com.py\\\",\\\"picture\\\":\\\"https://pbs.twimg.com/profile_images/1175432935337537536/_Peu9vuJ_400x400.jpg\\\",\\\"display_name\\\":\\\"C\\\",\\\"about\\\":\\\"Rust and PHP\\\",\\\"name\\\":\\\"c\\\"}\",\"created_at\":1678476588,\"id\":\"3800c787a23288641c0b96cbcc87c26cbd3ea7bee53b7748422fdb100fb7b9f0\",\"kind\":0,\"pubkey\":\"b2815682cfc83fcd2c3add05785cf4573dd388457069974cc6d8cca06b3c3b78\",\"sig\":\"c8a12ce96833e4cd67bce0e9e50f831262ef0f0c0cff5e56c38a0c90867ed1a6621e9692948ef5e85a7ca3726c3f0f43fa7e1992536bc457317123bca8784f5f\",\"tags\":[]}";
|
|
|
|
|
|
let event: Event = serde_json::from_str(json).expect("valid");
|
|
let event: Event = serde_json::from_str(json).expect("valid");
|
|
@@ -46,26 +55,26 @@ mod test {
|
|
assert_eq!(event1, Some(event));
|
|
assert_eq!(event1, Some(event));
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn records_are_sorted_by_date_desc<T: Storage>(db: &T) {
|
|
|
|
|
|
+ pub fn records_are_sorted_by_date_desc<'a, T, I>(db: &'a T)
|
|
|
|
+ where
|
|
|
|
+ T: Storage<'a, I>,
|
|
|
|
+ I: Iterator<Item = Result<Event, Error>>,
|
|
|
|
+ {
|
|
setup_db(db);
|
|
setup_db(db);
|
|
|
|
|
|
let pk: Addr = "7bdef7be22dd8e59f4600e044aa53a1cf975a9dc7d27df5833bc77db784a5805"
|
|
let pk: Addr = "7bdef7be22dd8e59f4600e044aa53a1cf975a9dc7d27df5833bc77db784a5805"
|
|
.try_into()
|
|
.try_into()
|
|
.expect("pk");
|
|
.expect("pk");
|
|
|
|
|
|
- let mut vec = vec![];
|
|
|
|
- db.get_by_filter(
|
|
|
|
- Filter {
|
|
|
|
|
|
+ let vec = db
|
|
|
|
+ .get_by_filter(Filter {
|
|
authors: vec![pk],
|
|
authors: vec![pk],
|
|
limit: 10,
|
|
limit: 10,
|
|
..Default::default()
|
|
..Default::default()
|
|
- },
|
|
|
|
- |event| {
|
|
|
|
- vec.push(event);
|
|
|
|
- Ok(())
|
|
|
|
- },
|
|
|
|
- )
|
|
|
|
- .expect("set of results");
|
|
|
|
|
|
+ })
|
|
|
|
+ .expect("set of results")
|
|
|
|
+ .collect::<Result<Vec<_>, _>>()
|
|
|
|
+ .expect("valid");
|
|
|
|
|
|
let dates = vec.iter().map(|e| e.created_at()).collect::<Vec<_>>();
|
|
let dates = vec.iter().map(|e| e.created_at()).collect::<Vec<_>>();
|
|
let mut sorted_dates = dates.clone();
|
|
let mut sorted_dates = dates.clone();
|
|
@@ -75,12 +84,15 @@ mod test {
|
|
assert_eq!(dates, sorted_dates);
|
|
assert_eq!(dates, sorted_dates);
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn filter_by_references<T: Storage>(db: &T) {
|
|
|
|
|
|
+ pub fn filter_by_references<'a, T, I>(db: &'a T)
|
|
|
|
+ where
|
|
|
|
+ T: Storage<'a, I>,
|
|
|
|
+ I: Iterator<Item = Result<Event, Error>>,
|
|
|
|
+ {
|
|
setup_db(db);
|
|
setup_db(db);
|
|
|
|
|
|
- let mut related_events = vec![];
|
|
|
|
- db.get_by_filter(
|
|
|
|
- Filter {
|
|
|
|
|
|
+ let related_events = db
|
|
|
|
+ .get_by_filter(Filter {
|
|
references_to_event: vec![
|
|
references_to_event: vec![
|
|
"f513f1422ee5dbf30f57118b6cc34e788746e589a9b07be767664a164c57b9b1"
|
|
"f513f1422ee5dbf30f57118b6cc34e788746e589a9b07be767664a164c57b9b1"
|
|
.try_into()
|
|
.try_into()
|
|
@@ -92,22 +104,22 @@ mod test {
|
|
.expect("pk"),
|
|
.expect("pk"),
|
|
],
|
|
],
|
|
..Default::default()
|
|
..Default::default()
|
|
- },
|
|
|
|
- |event| {
|
|
|
|
- related_events.push(event);
|
|
|
|
- Ok(())
|
|
|
|
- },
|
|
|
|
- )
|
|
|
|
- .expect("events");
|
|
|
|
|
|
+ })
|
|
|
|
+ .expect("valid")
|
|
|
|
+ .collect::<Result<Vec<_>, _>>()
|
|
|
|
+ .expect("valid");
|
|
assert_eq!(related_events.len(), 1);
|
|
assert_eq!(related_events.len(), 1);
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn filter_by_references_zero_match<T: Storage>(db: &T) {
|
|
|
|
|
|
+ pub fn filter_by_references_zero_match<'a, T, I>(db: &'a T)
|
|
|
|
+ where
|
|
|
|
+ T: Storage<'a, I>,
|
|
|
|
+ I: Iterator<Item = Result<Event, Error>>,
|
|
|
|
+ {
|
|
setup_db(db);
|
|
setup_db(db);
|
|
|
|
|
|
- let mut related_events = vec![];
|
|
|
|
- db.get_by_filter(
|
|
|
|
- Filter {
|
|
|
|
|
|
+ let related_events = db
|
|
|
|
+ .get_by_filter(Filter {
|
|
references_to_event: vec![
|
|
references_to_event: vec![
|
|
"42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5"
|
|
"42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5"
|
|
.try_into()
|
|
.try_into()
|
|
@@ -119,22 +131,22 @@ mod test {
|
|
.expect("pk"),
|
|
.expect("pk"),
|
|
],
|
|
],
|
|
..Default::default()
|
|
..Default::default()
|
|
- },
|
|
|
|
- |event| {
|
|
|
|
- related_events.push(event);
|
|
|
|
- Ok(())
|
|
|
|
- },
|
|
|
|
- )
|
|
|
|
- .expect("events");
|
|
|
|
|
|
+ })
|
|
|
|
+ .expect("valid")
|
|
|
|
+ .collect::<Result<Vec<_>, _>>()
|
|
|
|
+ .expect("valid");
|
|
assert_eq!(related_events.len(), 0);
|
|
assert_eq!(related_events.len(), 0);
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn filter_by_references_and_kind<T: Storage>(db: &T) {
|
|
|
|
|
|
+ pub fn filter_by_references_and_kind<'a, T, I>(db: &'a T)
|
|
|
|
+ where
|
|
|
|
+ T: Storage<'a, I>,
|
|
|
|
+ I: Iterator<Item = Result<Event, Error>>,
|
|
|
|
+ {
|
|
setup_db(db);
|
|
setup_db(db);
|
|
|
|
|
|
- let mut related_events = vec![];
|
|
|
|
- db.get_by_filter(
|
|
|
|
- Filter {
|
|
|
|
|
|
+ let related_events = db
|
|
|
|
+ .get_by_filter(Filter {
|
|
kinds: vec![Kind::Reaction, Kind::ShortTextNote],
|
|
kinds: vec![Kind::Reaction, Kind::ShortTextNote],
|
|
references_to_event: vec![
|
|
references_to_event: vec![
|
|
"42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5"
|
|
"42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5"
|
|
@@ -142,50 +154,43 @@ mod test {
|
|
.expect("pk"),
|
|
.expect("pk"),
|
|
],
|
|
],
|
|
..Default::default()
|
|
..Default::default()
|
|
- },
|
|
|
|
- |event| {
|
|
|
|
- related_events.push(event);
|
|
|
|
- Ok(())
|
|
|
|
- },
|
|
|
|
- )
|
|
|
|
- .expect("events");
|
|
|
|
|
|
+ })
|
|
|
|
+ .expect("valid")
|
|
|
|
+ .collect::<Result<Vec<_>, _>>()
|
|
|
|
+ .expect("valid");
|
|
assert_eq!(related_events.len(), 3);
|
|
assert_eq!(related_events.len(), 3);
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn get_event_and_related_events<T: Storage>(db: &T) {
|
|
|
|
|
|
+ pub fn get_event_and_related_events<'a, T, I>(db: &'a T)
|
|
|
|
+ where
|
|
|
|
+ T: Storage<'a, I>,
|
|
|
|
+ I: Iterator<Item = Result<Event, Error>>,
|
|
|
|
+ {
|
|
setup_db(db);
|
|
setup_db(db);
|
|
|
|
|
|
let id: Addr = "42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5"
|
|
let id: Addr = "42224859763652914db53052103f0b744df79dfc4efef7e950fc0802fc3df3c5"
|
|
.try_into()
|
|
.try_into()
|
|
.expect("pk");
|
|
.expect("pk");
|
|
|
|
|
|
- let mut events = vec![];
|
|
|
|
- db.get_by_filter(
|
|
|
|
- Filter {
|
|
|
|
|
|
+ let events = db
|
|
|
|
+ .get_by_filter(Filter {
|
|
ids: vec![id.clone()],
|
|
ids: vec![id.clone()],
|
|
..Default::default()
|
|
..Default::default()
|
|
- },
|
|
|
|
- |event| {
|
|
|
|
- events.push(event);
|
|
|
|
- Ok(())
|
|
|
|
- },
|
|
|
|
- )
|
|
|
|
- .expect("events");
|
|
|
|
|
|
+ })
|
|
|
|
+ .expect("events")
|
|
|
|
+ .collect::<Result<Vec<_>, _>>()
|
|
|
|
+ .expect("valid");
|
|
|
|
|
|
assert_eq!(events.len(), 1);
|
|
assert_eq!(events.len(), 1);
|
|
|
|
|
|
- let mut related_events = vec![];
|
|
|
|
- db.get_by_filter(
|
|
|
|
- Filter {
|
|
|
|
|
|
+ let related_events = db
|
|
|
|
+ .get_by_filter(Filter {
|
|
references_to_event: vec![id],
|
|
references_to_event: vec![id],
|
|
..Default::default()
|
|
..Default::default()
|
|
- },
|
|
|
|
- |event| {
|
|
|
|
- related_events.push(event);
|
|
|
|
- Ok(())
|
|
|
|
- },
|
|
|
|
- )
|
|
|
|
- .expect("events");
|
|
|
|
|
|
+ })
|
|
|
|
+ .expect("valid")
|
|
|
|
+ .collect::<Result<Vec<_>, _>>()
|
|
|
|
+ .expect("valid");
|
|
assert_eq!(related_events.len(), 2_538);
|
|
assert_eq!(related_events.len(), 2_538);
|
|
|
|
|
|
let mut kinds = related_events.iter().map(|x| x.kind()).collect::<Vec<_>>();
|
|
let mut kinds = related_events.iter().map(|x| x.kind()).collect::<Vec<_>>();
|
|
@@ -196,7 +201,11 @@ mod test {
|
|
assert_eq!(Kind::Unknown(42), kinds[1]);
|
|
assert_eq!(Kind::Unknown(42), kinds[1]);
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn filter_by_authors<T: Storage>(db: &T) {
|
|
|
|
|
|
+ pub fn filter_by_authors<'a, T, I>(db: &'a T)
|
|
|
|
+ where
|
|
|
|
+ T: Storage<'a, I>,
|
|
|
|
+ I: Iterator<Item = Result<Event, Error>>,
|
|
|
|
+ {
|
|
setup_db(db);
|
|
setup_db(db);
|
|
let query = Filter {
|
|
let query = Filter {
|
|
authors: vec![
|
|
authors: vec![
|
|
@@ -209,16 +218,19 @@ mod test {
|
|
],
|
|
],
|
|
..Default::default()
|
|
..Default::default()
|
|
};
|
|
};
|
|
- let mut records = vec![];
|
|
|
|
- db.get_by_filter(query, |event| {
|
|
|
|
- records.push(event);
|
|
|
|
- Ok(())
|
|
|
|
- })
|
|
|
|
- .expect("records");
|
|
|
|
|
|
+ let records = db
|
|
|
|
+ .get_by_filter(query)
|
|
|
|
+ .expect("valid")
|
|
|
|
+ .collect::<Result<Vec<_>, _>>()
|
|
|
|
+ .expect("valid");
|
|
assert_eq!(records.len(), 27);
|
|
assert_eq!(records.len(), 27);
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn filter_by_author<T: Storage>(db: &T) {
|
|
|
|
|
|
+ pub fn filter_by_author<'a, T, I>(db: &'a T)
|
|
|
|
+ where
|
|
|
|
+ T: Storage<'a, I>,
|
|
|
|
+ I: Iterator<Item = Result<Event, Error>>,
|
|
|
|
+ {
|
|
setup_db(db);
|
|
setup_db(db);
|
|
let query = Filter {
|
|
let query = Filter {
|
|
authors: vec![
|
|
authors: vec![
|
|
@@ -228,16 +240,19 @@ mod test {
|
|
],
|
|
],
|
|
..Default::default()
|
|
..Default::default()
|
|
};
|
|
};
|
|
- let mut records = vec![];
|
|
|
|
- db.get_by_filter(query, |event| {
|
|
|
|
- records.push(event);
|
|
|
|
- Ok(())
|
|
|
|
- })
|
|
|
|
- .expect("records");
|
|
|
|
|
|
+ let records = db
|
|
|
|
+ .get_by_filter(query)
|
|
|
|
+ .expect("valid")
|
|
|
|
+ .collect::<Result<Vec<_>, _>>()
|
|
|
|
+ .expect("valid");
|
|
assert_eq!(records.len(), 3);
|
|
assert_eq!(records.len(), 3);
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn filter_by_author_and_kinds<T: Storage>(db: &T) {
|
|
|
|
|
|
+ pub fn filter_by_author_and_kinds<'a, T, I>(db: &'a T)
|
|
|
|
+ where
|
|
|
|
+ T: Storage<'a, I>,
|
|
|
|
+ I: Iterator<Item = Result<Event, Error>>,
|
|
|
|
+ {
|
|
setup_db(db);
|
|
setup_db(db);
|
|
let query = Filter {
|
|
let query = Filter {
|
|
authors: vec![
|
|
authors: vec![
|
|
@@ -248,27 +263,29 @@ mod test {
|
|
kinds: vec![Kind::ShortTextNote, Kind::Reaction],
|
|
kinds: vec![Kind::ShortTextNote, Kind::Reaction],
|
|
..Default::default()
|
|
..Default::default()
|
|
};
|
|
};
|
|
- let mut records = vec![];
|
|
|
|
- db.get_by_filter(query, |event| {
|
|
|
|
- records.push(event);
|
|
|
|
- Ok(())
|
|
|
|
- })
|
|
|
|
- .expect("records");
|
|
|
|
|
|
+ let records = db
|
|
|
|
+ .get_by_filter(query)
|
|
|
|
+ .expect("iterator")
|
|
|
|
+ .collect::<Result<Vec<_>, _>>()
|
|
|
|
+ .expect("valid");
|
|
assert_eq!(records.len(), 2);
|
|
assert_eq!(records.len(), 2);
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn filter_kind<T: Storage>(db: &T) {
|
|
|
|
|
|
+ pub fn filter_kind<'a, T, I>(db: &'a T)
|
|
|
|
+ where
|
|
|
|
+ T: Storage<'a, I>,
|
|
|
|
+ I: Iterator<Item = Result<Event, Error>>,
|
|
|
|
+ {
|
|
setup_db(db);
|
|
setup_db(db);
|
|
let query = Filter {
|
|
let query = Filter {
|
|
kinds: vec![Kind::ShortTextNote],
|
|
kinds: vec![Kind::ShortTextNote],
|
|
..Default::default()
|
|
..Default::default()
|
|
};
|
|
};
|
|
- let mut records = vec![];
|
|
|
|
- db.get_by_filter(query, |event| {
|
|
|
|
- records.push(event);
|
|
|
|
- Ok(())
|
|
|
|
- })
|
|
|
|
- .expect("records");
|
|
|
|
|
|
+ let records = db
|
|
|
|
+ .get_by_filter(query)
|
|
|
|
+ .expect("valid")
|
|
|
|
+ .collect::<Result<Vec<_>, _>>()
|
|
|
|
+ .expect("valid");
|
|
assert_eq!(records.len(), 1_511);
|
|
assert_eq!(records.len(), 1_511);
|
|
records
|
|
records
|
|
.iter()
|
|
.iter()
|