Skip to main content

uqa_storage/read_only_snapshot/
documents.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7use std::collections::BTreeMap;
8use std::sync::Arc;
9
10use uqa_core::{memory::BudgetedVec, DocId, PathSegment, Value};
11
12use crate::document_store::{Document, DocumentMetadata, SharedDocumentRow, StoredDocument};
13use crate::read_control::StorageReadControl;
14use crate::{DocumentStore, StorageBackendResult};
15
16use super::{read_only_error, ReadOnlySnapshot};
17
18impl DocumentStore for ReadOnlySnapshot<dyn DocumentStore> {
19    fn put_stored(
20        &mut self,
21        _doc_id: DocId,
22        _document: StoredDocument,
23    ) -> StorageBackendResult<()> {
24        Err(read_only_error())
25    }
26
27    fn get_stored(&self, doc_id: DocId) -> StorageBackendResult<Option<StoredDocument>> {
28        self.0.get_stored(doc_id)
29    }
30
31    fn get_stored_many_controlled(
32        &self,
33        ids: &[DocId],
34        control: &StorageReadControl,
35    ) -> StorageBackendResult<crate::RetainedDocumentPage> {
36        self.0.get_stored_many_controlled(ids, control)
37    }
38
39    fn with_field_ref_controlled(
40        &self,
41        id: DocId,
42        field: &str,
43        control: &StorageReadControl,
44        visitor: &mut dyn FnMut(Option<&Value>) -> StorageBackendResult<()>,
45    ) -> StorageBackendResult<()> {
46        if let Some(captured) = &self.2 {
47            captured.check()?;
48        }
49        self.0
50            .with_field_ref_controlled(id, field, control, visitor)?;
51        if let Some(captured) = &self.2 {
52            captured.check()?;
53        }
54        control.check()
55    }
56
57    fn field_presence_controlled(
58        &self,
59        ids: &[DocId],
60        fields: &[&str],
61        control: &StorageReadControl,
62    ) -> StorageBackendResult<BudgetedVec<bool>> {
63        if let Some(captured) = &self.2 {
64            captured.check()?;
65        }
66        let present =
67            crate::document_store::read_field_presence(self.0.as_ref(), ids, fields, control)?;
68        if let Some(captured) = &self.2 {
69            captured.check()?;
70        }
71        Ok(present)
72    }
73
74    fn put(&mut self, _doc_id: DocId, _document: Document) -> StorageBackendResult<()> {
75        Err(read_only_error())
76    }
77
78    fn get(&self, doc_id: DocId) -> StorageBackendResult<Option<Document>> {
79        self.0.get(doc_id)
80    }
81
82    fn get_stored_many(
83        &self,
84        doc_ids: &[DocId],
85    ) -> StorageBackendResult<BTreeMap<DocId, StoredDocument>> {
86        self.0.get_stored_many(doc_ids)
87    }
88
89    fn get_metadata(&self, doc_id: DocId) -> StorageBackendResult<Option<DocumentMetadata>> {
90        self.0.get_metadata(doc_id)
91    }
92
93    fn contains_doc_id(&self, doc_id: DocId) -> StorageBackendResult<bool> {
94        self.0.contains_doc_id(doc_id)
95    }
96
97    fn delete(&mut self, _doc_id: DocId) -> StorageBackendResult<()> {
98        Err(read_only_error())
99    }
100
101    fn clear(&mut self) -> StorageBackendResult<()> {
102        Err(read_only_error())
103    }
104
105    fn get_field(&self, doc_id: DocId, field: &str) -> StorageBackendResult<Option<Value>> {
106        self.0.get_field(doc_id, field)
107    }
108
109    fn find_doc_id_by_field(
110        &self,
111        field: &str,
112        value: &Value,
113    ) -> StorageBackendResult<Option<DocId>> {
114        self.0.find_doc_id_by_field(field, value)
115    }
116
117    fn patch_fields(
118        &mut self,
119        _doc_id: DocId,
120        _updates: &BTreeMap<String, Value>,
121    ) -> StorageBackendResult<bool> {
122        Err(read_only_error())
123    }
124
125    fn get_many(&self, doc_ids: &[DocId]) -> StorageBackendResult<BTreeMap<DocId, Document>> {
126        self.0.get_many(doc_ids)
127    }
128
129    fn get_fields_multi(
130        &self,
131        doc_ids: &[DocId],
132        fields: &[&str],
133    ) -> StorageBackendResult<BTreeMap<DocId, Vec<Value>>> {
134        self.0.get_fields_multi(doc_ids, fields)
135    }
136
137    fn for_each_fields_multi(
138        &self,
139        doc_ids: &[DocId],
140        fields: &[&str],
141        visitor: &mut dyn FnMut(DocId, Vec<Value>) -> bool,
142    ) -> StorageBackendResult<()> {
143        self.0.for_each_fields_multi(doc_ids, fields, visitor)
144    }
145
146    fn for_each_fields_multi_ref(
147        &self,
148        doc_ids: &[DocId],
149        fields: &[&str],
150        visitor: &mut dyn FnMut(DocId, &[&Value]) -> bool,
151    ) -> StorageBackendResult<()> {
152        self.0.for_each_fields_multi_ref(doc_ids, fields, visitor)
153    }
154
155    fn for_each_fields_multi_ref_with_presence(
156        &self,
157        doc_ids: &[DocId],
158        fields: &[&str],
159        visitor: &mut dyn FnMut(DocId, bool, &[&Value]) -> bool,
160    ) -> StorageBackendResult<()> {
161        self.0
162            .for_each_fields_multi_ref_with_presence(doc_ids, fields, visitor)
163    }
164
165    fn get_shared_fields(
166        &self,
167        doc_ids: &[DocId],
168        fields: &[&str],
169    ) -> StorageBackendResult<Option<Vec<Option<SharedDocumentRow>>>> {
170        self.0.get_shared_fields(doc_ids, fields)
171    }
172
173    fn get_fields_bulk(
174        &self,
175        doc_ids: &[DocId],
176        field: &str,
177    ) -> StorageBackendResult<BTreeMap<DocId, Value>> {
178        self.0.get_fields_bulk(doc_ids, field)
179    }
180
181    fn has_value(&self, field: &str, value: &Value) -> StorageBackendResult<bool> {
182        self.0.has_value(field, value)
183    }
184
185    fn find_doc_id_by_fields(
186        &self,
187        fields: &[String],
188        values: &[Value],
189    ) -> StorageBackendResult<Option<DocId>> {
190        self.0.find_doc_id_by_fields(fields, values)
191    }
192
193    fn eval_path(
194        &self,
195        doc_id: DocId,
196        path: &[PathSegment],
197    ) -> StorageBackendResult<Option<Value>> {
198        self.0.eval_path(doc_id, path)
199    }
200
201    fn doc_ids(&self) -> StorageBackendResult<Vec<DocId>> {
202        self.0.doc_ids()
203    }
204
205    fn next_doc_id(&self, after: Option<DocId>) -> StorageBackendResult<Option<DocId>> {
206        self.0.next_doc_id(after)
207    }
208
209    fn next_doc_ids(&self, after: Option<DocId>, limit: usize) -> StorageBackendResult<Vec<DocId>> {
210        self.0.next_doc_ids(after, limit)
211    }
212
213    fn next_doc_ids_controlled(
214        &self,
215        after: Option<DocId>,
216        limit: usize,
217        control: &StorageReadControl,
218    ) -> StorageBackendResult<BudgetedVec<DocId>> {
219        self.0.next_doc_ids_controlled(after, limit, control)
220    }
221
222    fn next_shared_fields(
223        &self,
224        after: Option<DocId>,
225        limit: usize,
226        fields: &[&str],
227    ) -> StorageBackendResult<Option<Vec<(DocId, SharedDocumentRow)>>> {
228        self.0.next_shared_fields(after, limit, fields)
229    }
230
231    fn for_each_next_fields(
232        &self,
233        after: Option<DocId>,
234        limit: usize,
235        fields: &[&str],
236        visitor: &mut dyn FnMut(DocId, &[&Value]) -> bool,
237    ) -> StorageBackendResult<Option<usize>> {
238        self.0.for_each_next_fields(after, limit, fields, visitor)
239    }
240
241    fn max_doc_id(&self) -> StorageBackendResult<DocId> {
242        self.0.max_doc_id()
243    }
244
245    fn for_each_next_fields_borrowed(
246        &self,
247        after: Option<DocId>,
248        limit: usize,
249        fields: &[&str],
250        visitor: &mut dyn FnMut(DocId, &[&Value]) -> bool,
251    ) -> StorageBackendResult<Option<usize>> {
252        if let Some(control) = &self.2 {
253            control.check()?;
254        }
255        let result = self
256            .0
257            .for_each_next_fields_borrowed(after, limit, fields, visitor)?;
258        if let Some(control) = &self.2 {
259            control.check()?;
260        }
261        Ok(result)
262    }
263
264    fn for_each_fields_multi_borrowed(
265        &self,
266        ids: &[DocId],
267        fields: &[&str],
268        visitor: &mut dyn FnMut(DocId, bool, &[&Value]) -> bool,
269    ) -> StorageBackendResult<Option<usize>> {
270        if let Some(control) = &self.2 {
271            control.check()?;
272        }
273        let result = self
274            .0
275            .for_each_fields_multi_borrowed(ids, fields, visitor)?;
276        if let Some(control) = &self.2 {
277            control.check()?;
278        }
279        Ok(result)
280    }
281
282    fn len(&self) -> StorageBackendResult<usize> {
283        self.0.len()
284    }
285
286    fn is_empty(&self) -> StorageBackendResult<bool> {
287        self.0.is_empty()
288    }
289
290    fn iter_all(&self) -> StorageBackendResult<Box<dyn Iterator<Item = (DocId, Document)> + '_>> {
291        self.0.iter_all()
292    }
293
294    fn snapshot(&self) -> StorageBackendResult<Arc<dyn DocumentStore>> {
295        Ok(Arc::new(self.clone()))
296    }
297
298    fn retained_snapshot(&self) -> StorageBackendResult<Option<Arc<dyn DocumentStore>>> {
299        if let Some(control) = &self.2 {
300            control.check()?;
301        }
302        Ok(self.0.retained_snapshot()?.map(|snapshot| {
303            Arc::new(Self(
304                snapshot,
305                self.1.as_ref().map(Arc::clone),
306                self.2.clone(),
307                None,
308            )) as Arc<dyn DocumentStore>
309        }))
310    }
311}