icydb_core/db/query/fluent/load/
pagination.rs1use crate::{
7 db::{
8 PagedLoadExecution, PagedLoadExecutionWithTrace, PersistedRow,
9 query::fluent::load::FluentLoadQuery,
10 query::{
11 intent::{IntentError, QueryError},
12 read_intent::{ADMIN_BATCH_ROWS, AdminBatchRequest, PageRequest, ReadIntentKind},
13 },
14 },
15 traits::{EntityKind, EntityValue},
16};
17
18struct PagedLoadQuery<'a, E>
19where
20 E: EntityKind,
21{
22 inner: FluentLoadQuery<'a, E>,
23}
24
25impl<'a, E> FluentLoadQuery<'a, E>
26where
27 E: PersistedRow,
28{
29 pub fn page(self, limit: u32) -> Result<PagedLoadExecution<E>, QueryError>
40 where
41 E: EntityValue,
42 {
43 self.page_request(PageRequest::first(limit))?.execute()
44 }
45
46 pub fn next_page(
51 self,
52 limit: u32,
53 cursor: impl Into<String>,
54 ) -> Result<PagedLoadExecution<E>, QueryError>
55 where
56 E: EntityValue,
57 {
58 self.page_request(PageRequest::next(limit, cursor))?
59 .execute()
60 }
61
62 fn page_request(self, request: PageRequest) -> Result<PagedLoadQuery<'a, E>, QueryError> {
63 self.ensure_semantic_terminal_owns_limit(IntentError::raw_limit_before_page_terminal())?;
64 self.ensure_page_request_owns_cursor()?;
65
66 let limit = request.effective_limit();
67 let cursor = request.into_cursor();
68 let mut inner = self.map_query(|query| query.with_load_limit(limit));
69 if let Some(cursor) = cursor {
70 inner = inner.with_cursor_token(cursor);
71 }
72
73 inner.ensure_paged_mode_ready()?;
74
75 Ok(PagedLoadQuery { inner })
76 }
77
78 pub fn admin_batch(
85 self,
86 request: AdminBatchRequest,
87 ) -> Result<PagedLoadExecution<E>, QueryError>
88 where
89 E: PersistedRow + EntityValue,
90 {
91 self.ensure_semantic_terminal_owns_limit(
92 IntentError::raw_limit_before_admin_batch_terminal(),
93 )?;
94 self.ensure_page_request_owns_cursor()?;
95
96 if !self.trusted_read_unchecked_enabled() {
97 return Err(QueryError::intent(
98 IntentError::admin_batch_requires_trusted_read(),
99 ));
100 }
101
102 let cursor = request.into_cursor();
103 let mut inner = self.map_query(|query| query.with_load_limit(ADMIN_BATCH_ROWS));
104 if let Some(cursor) = cursor {
105 inner = inner.with_cursor_token(cursor);
106 }
107
108 inner.ensure_paged_mode_ready()?;
109
110 PagedLoadQuery { inner }
111 .execute()
112 .map(|execution| execution.with_read_intent(ReadIntentKind::TrustedAdminBatch))
113 }
114}
115
116impl<E> PagedLoadQuery<'_, E>
117where
118 E: PersistedRow,
119{
120 fn execute(self) -> Result<PagedLoadExecution<E>, QueryError>
126 where
127 E: PersistedRow + EntityValue,
128 {
129 self.execute_with_trace()
130 .map(PagedLoadExecutionWithTrace::into_execution)
131 }
132
133 fn execute_with_trace(self) -> Result<PagedLoadExecutionWithTrace<E>, QueryError>
139 where
140 E: PersistedRow + EntityValue,
141 {
142 self.inner.ensure_default_read_admission()?;
143 self.execute_with_trace_unchecked()
144 }
145
146 fn execute_with_trace_unchecked(self) -> Result<PagedLoadExecutionWithTrace<E>, QueryError>
147 where
148 E: PersistedRow + EntityValue,
149 {
150 self.inner
153 .session
154 .execute_load_query_paged_with_trace(
155 self.inner.query(),
156 self.inner.cursor_token.as_deref(),
157 )
158 .map(|execution| execution.with_read_intent(ReadIntentKind::PublicPage))
159 }
160}