use crate::{
db::{
PagedLoadExecution, PagedLoadExecutionWithTrace, PersistedRow,
query::fluent::load::FluentLoadQuery,
query::{
intent::{IntentError, Query, QueryError},
read_intent::{ADMIN_BATCH_ROWS, AdminBatchRequest, PageRequest},
},
},
traits::{EntityKind, EntityValue},
};
pub struct PagedLoadQuery<'a, E>
where
E: EntityKind,
{
inner: FluentLoadQuery<'a, E>,
}
impl<'a, E> FluentLoadQuery<'a, E>
where
E: PersistedRow,
{
pub fn page(self, request: PageRequest) -> Result<PagedLoadQuery<'a, E>, QueryError> {
self.ensure_semantic_terminal_owns_limit(IntentError::raw_limit_before_page_terminal())?;
self.ensure_page_request_owns_cursor()?;
let limit = request.effective_limit();
let cursor = request.into_cursor();
let mut inner = self.map_query(|query| query.with_load_limit(limit));
if let Some(cursor) = cursor {
inner = inner.with_cursor_token(cursor);
}
inner.ensure_paged_mode_ready()?;
Ok(PagedLoadQuery { inner })
}
pub fn execute_paged(self, request: PageRequest) -> Result<PagedLoadExecution<E>, QueryError>
where
E: PersistedRow + EntityValue,
{
self.page(request)?.execute()
}
pub fn execute_paged_trusted(
self,
request: PageRequest,
) -> Result<PagedLoadExecution<E>, QueryError>
where
E: PersistedRow + EntityValue,
{
self.page(request)?.execute_trusted()
}
pub fn admin_batch(
self,
request: AdminBatchRequest,
) -> Result<PagedLoadExecution<E>, QueryError>
where
E: PersistedRow + EntityValue,
{
self.ensure_semantic_terminal_owns_limit(
IntentError::raw_limit_before_admin_batch_terminal(),
)?;
self.ensure_page_request_owns_cursor()?;
if !self.trusted_read_unchecked_enabled() {
return Err(QueryError::intent(
IntentError::admin_batch_requires_trusted_read(),
));
}
let cursor = request.into_cursor();
let mut inner = self.map_query(|query| query.with_load_limit(ADMIN_BATCH_ROWS));
if let Some(cursor) = cursor {
inner = inner.with_cursor_token(cursor);
}
inner.ensure_paged_mode_ready()?;
PagedLoadQuery { inner }.execute_trusted()
}
}
impl<E> PagedLoadQuery<'_, E>
where
E: PersistedRow,
{
#[must_use]
pub const fn query(&self) -> &Query<E> {
self.inner.query()
}
pub fn execute(self) -> Result<PagedLoadExecution<E>, QueryError>
where
E: PersistedRow + EntityValue,
{
self.execute_with_trace()
.map(PagedLoadExecutionWithTrace::into_execution)
}
pub fn execute_trusted(self) -> Result<PagedLoadExecution<E>, QueryError>
where
E: PersistedRow + EntityValue,
{
self.execute_with_trace_trusted()
.map(PagedLoadExecutionWithTrace::into_execution)
}
pub fn execute_with_trace(self) -> Result<PagedLoadExecutionWithTrace<E>, QueryError>
where
E: PersistedRow + EntityValue,
{
self.inner.ensure_default_read_admission()?;
self.execute_with_trace_trusted()
}
pub fn execute_with_trace_trusted(self) -> Result<PagedLoadExecutionWithTrace<E>, QueryError>
where
E: PersistedRow + EntityValue,
{
self.inner.session.execute_load_query_paged_with_trace(
self.inner.query(),
self.inner.cursor_token.as_deref(),
)
}
}