improvement: /search works for multiple rooms

This commit is contained in:
Timo Kösters 2021-06-21 15:20:37 +02:00
parent fee7d3d2e3
commit dcac1361ec
No known key found for this signature in database
GPG key ID: 24DA7517711A2BA4

View file

@ -20,12 +20,20 @@ pub async fn search_events_route(
let sender_user = body.sender_user.as_ref().expect("user is authenticated"); let sender_user = body.sender_user.as_ref().expect("user is authenticated");
let search_criteria = body.search_categories.room_events.as_ref().unwrap(); let search_criteria = body.search_categories.room_events.as_ref().unwrap();
let filter = search_criteria.filter.as_ref().unwrap(); let filter = search_criteria.filter.clone().unwrap_or_default();
let room_id = filter.rooms.as_ref().unwrap().first().unwrap(); let room_ids = filter.rooms.clone().unwrap_or_else(|| {
db.rooms
.rooms_joined(&sender_user)
.filter_map(|r| r.ok())
.collect()
});
let limit = filter.limit.map_or(10, |l| u64::from(l) as usize); let limit = filter.limit.map_or(10, |l| u64::from(l) as usize);
let mut searches = Vec::new();
for room_id in room_ids {
if !db.rooms.is_joined(sender_user, &room_id)? { if !db.rooms.is_joined(sender_user, &room_id)? {
return Err(Error::BadRequest( return Err(Error::BadRequest(
ErrorKind::Forbidden, ErrorKind::Forbidden,
@ -33,6 +41,13 @@ pub async fn search_events_route(
)); ));
} }
let search = db
.rooms
.search_pdus(&room_id, &search_criteria.search_term)?;
searches.push(search.0.peekable());
}
let skip = match body.next_batch.as_ref().map(|s| s.parse()) { let skip = match body.next_batch.as_ref().map(|s| s.parse()) {
Some(Ok(s)) => s, Some(Ok(s)) => s,
Some(Err(_)) => { Some(Err(_)) => {
@ -44,12 +59,20 @@ pub async fn search_events_route(
None => 0, // Default to the start None => 0, // Default to the start
}; };
let search = db let mut results = Vec::new();
.rooms for _ in 0..skip + limit {
.search_pdus(&room_id, &search_criteria.search_term)?; if let Some(s) = searches
.iter_mut()
.map(|s| (s.peek().cloned(), s))
.max_by_key(|(peek, _)| peek.clone())
.and_then(|(_, i)| i.next())
{
results.push(s);
}
}
let results = search let results = results
.0 .iter()
.map(|result| { .map(|result| {
Ok::<_, Error>(SearchResult { Ok::<_, Error>(SearchResult {
context: EventContextResult { context: EventContextResult {
@ -84,7 +107,11 @@ pub async fn search_events_route(
next_batch, next_batch,
results, results,
state: BTreeMap::new(), // TODO state: BTreeMap::new(), // TODO
highlights: search.1, highlights: search_criteria
.search_term
.split_terminator(|c: char| !c.is_alphanumeric())
.map(str::to_lowercase)
.collect::<Vec<_>>(),
}, },
}) })
.into()) .into())