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
use serde::{Deserialize, Serialize};
use crate::config::validation::require_nonzero;
use crate::errors::OrionError;
/// Page-size bounds applied to every `data_query` (the portable query handler).
///
/// A query that omits `limit` gets `default_limit`; a query asking for more than
/// `max_limit` is rejected (never silently clamped), so no query is ever
/// unbounded by accident. `max_skip` bounds the pagination offset the same way,
/// on every backend — Elasticsearch capped `skip` at its result window while
/// SQL and MongoDB scanned arbitrarily deep (W12). Documented under
/// Configuration in `docs/src/reference/data-dialect.md`.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(default, deny_unknown_fields)]
pub struct QueryConfig {
/// Page size applied when a `data_query` omits `limit`.
pub default_limit: u64,
/// Hard maximum page size. A query requesting more is rejected.
pub max_limit: u64,
/// Hard maximum `skip` offset. A query skipping more is rejected.
pub max_skip: u64,
}
impl Default for QueryConfig {
fn default() -> Self {
Self {
default_limit: 100,
max_limit: 1000,
max_skip: 10_000,
}
}
}
impl QueryConfig {
pub(crate) fn validate(&self) -> Result<(), OrionError> {
require_nonzero(self.default_limit, "query.default_limit")?;
require_nonzero(self.max_limit, "query.max_limit")?;
if self.default_limit > self.max_limit {
return Err(OrionError::Config {
message: format!(
"query.default_limit ({}) must not exceed query.max_limit ({})",
self.default_limit, self.max_limit
),
});
}
Ok(())
}
}