khive_runtime/
note_read.rs1use khive_storage::note::{Note, NoteFilter};
4use khive_storage::{PageRequest, SeekCursor};
5use uuid::Uuid;
6
7use crate::{KhiveRuntime, MailboxView, NamespaceToken, RuntimeError, RuntimeResult};
8
9impl KhiveRuntime {
10 pub async fn list_notes_filtered(
11 &self,
12 token: &NamespaceToken,
13 mut filter: NoteFilter,
14 limit: u32,
15 offset: u32,
16 ) -> RuntimeResult<Vec<Note>> {
17 filter.namespaces = token
18 .visible_namespace_strs()
19 .into_iter()
20 .map(str::to_owned)
21 .collect();
22 Ok(self
23 .notes(token)?
24 .query_notes_filtered_count_free(
25 token.namespace().as_str(),
26 &filter,
27 PageRequest {
28 limit,
29 offset: offset.into(),
30 },
31 )
32 .await?
33 .items)
34 }
35
36 pub async fn list_notes_filtered_after(
37 &self,
38 token: &NamespaceToken,
39 mut filter: NoteFilter,
40 after: Option<Uuid>,
41 limit: u32,
42 ) -> RuntimeResult<(Vec<Note>, Option<Uuid>)> {
43 let store = self.notes(token)?;
44 let after = match after {
45 None => None,
46 Some(id) => {
47 let note = self
48 .get_note_including_deleted(token, id)
49 .await?
50 .ok_or_else(|| RuntimeError::NotFound(format!("note cursor {id}")))?;
51 Self::ensure_namespace_visible(¬e.namespace, token)?;
52 if filter
56 .mailbox
57 .as_ref()
58 .is_some_and(|scope| !MailboxView::scope_permits_message_note(scope, ¬e))
59 {
60 return Err(RuntimeError::NotFound(format!("note cursor {id}")));
61 }
62 let sequence = store.note_sequence(id).await?.ok_or_else(|| {
63 RuntimeError::Internal(format!(
64 "note cursor {id} has no insertion-sequence ledger row"
65 ))
66 })?;
67 Some(SeekCursor { sequence, id })
68 }
69 };
70 filter.namespaces = token
71 .visible_namespace_strs()
72 .into_iter()
73 .map(str::to_owned)
74 .collect();
75 let page = store
76 .query_notes_filtered_after(token.namespace().as_str(), &filter, after, limit)
77 .await?;
78 Ok((page.items, page.next_after.map(|cursor| cursor.id)))
79 }
80}