use crate::{
db::{
cursor::{ContinuationSignature, GroupedContinuationToken},
direction::Direction,
executor::{
GroupedContinuationCapabilities, GroupedPaginationWindow,
pipeline::contracts::PageCursor,
},
},
error::InternalError,
value::Value,
};
pub(in crate::db::executor) struct GroupedContinuationContext {
capabilities: GroupedContinuationCapabilities,
continuation_signature: ContinuationSignature,
continuation_boundary_arity: usize,
grouped_pagination_window: GroupedPaginationWindow,
}
impl GroupedContinuationContext {
#[must_use]
pub(in crate::db::executor) const fn new(
capabilities: GroupedContinuationCapabilities,
continuation_signature: ContinuationSignature,
continuation_boundary_arity: usize,
grouped_pagination_window: GroupedPaginationWindow,
) -> Self {
Self {
capabilities,
continuation_signature,
continuation_boundary_arity,
grouped_pagination_window,
}
}
#[must_use]
pub(in crate::db::executor) const fn capabilities(&self) -> GroupedContinuationCapabilities {
self.capabilities
}
#[must_use]
pub(in crate::db::executor) const fn grouped_pagination_window(
&self,
) -> &GroupedPaginationWindow {
&self.grouped_pagination_window
}
pub(in crate::db::executor) fn grouped_next_cursor(
&self,
last_group_key: Vec<Value>,
) -> Result<PageCursor, InternalError> {
if last_group_key.len() != self.continuation_boundary_arity {
return Err(InternalError::query_executor_invariant(format!(
"grouped continuation boundary arity mismatch: expected {}, found {}",
self.continuation_boundary_arity,
last_group_key.len()
)));
}
Ok(PageCursor::Grouped(
GroupedContinuationToken::new_with_direction(
self.continuation_signature,
last_group_key,
Direction::Asc,
self.grouped_pagination_window.resume_initial_offset(),
),
))
}
}