1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
/*
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
*/
use directory::QueryBy;
use jmap_proto::{
method::query::{Filter, QueryRequest, QueryResponse, RequestArguments},
types::collection::Collection,
};
use store::{query::ResultSet, roaring::RoaringBitmap};
use crate::{api::http::HttpSessionData, JMAP};
impl JMAP {
pub async fn principal_query(
&self,
mut request: QueryRequest<RequestArguments>,
session: &HttpSessionData,
) -> trc::Result<QueryResponse> {
let account_id = request.account_id.document_id();
let mut result_set = ResultSet {
account_id,
collection: Collection::Principal.into(),
results: RoaringBitmap::new(),
};
let mut is_set = true;
for cond in std::mem::take(&mut request.filter) {
match cond {
Filter::Name(name) => {
if let Some(principal) = self
.core
.storage
.directory
.query(QueryBy::Name(name.as_str()), false)
.await?
{
if is_set || result_set.results.contains(principal.id()) {
result_set.results =
RoaringBitmap::from_sorted_iter([principal.id()]).unwrap();
} else {
result_set.results = RoaringBitmap::new();
}
} else {
result_set.results = RoaringBitmap::new();
}
is_set = false;
}
Filter::Email(email) => {
let mut ids = RoaringBitmap::new();
for id in self
.core
.email_to_ids(&self.core.storage.directory, &email, session.session_id)
.await?
{
ids.insert(id);
}
if is_set {
result_set.results = ids;
is_set = false;
} else {
result_set.results &= ids;
}
}
Filter::Type(_) => {}
other => {
return Err(trc::JmapEvent::UnsupportedFilter
.into_err()
.details(other.to_string()))
}
}
}
if is_set {
result_set.results = self
.get_document_ids(u32::MAX, Collection::Principal)
.await?
.unwrap_or_default();
}
let (response, paginate) = self.build_query_response(&result_set, &request).await?;
if let Some(paginate) = paginate {
self.sort(result_set, Vec::new(), paginate, response).await
} else {
Ok(response)
}
}
}
|