Skip to main content

helios_persistence/search/
writer.rs

1//! Search Index Writer Trait.
2//!
3//! Defines the interface for writing extracted search values to a backend's
4//! search index. Each backend implements this trait according to its storage model.
5
6use async_trait::async_trait;
7
8use crate::error::StorageResult;
9
10use super::extractor::ExtractedValue;
11
12/// Trait for writing search parameter values to an index.
13///
14/// This trait abstracts the storage of extracted search values, allowing
15/// different backends to implement their own indexing strategies.
16#[async_trait]
17pub trait SearchIndexWriter: Send + Sync {
18    /// Writes extracted values for a resource to the search index.
19    ///
20    /// This typically inserts multiple rows in a search_index table,
21    /// one for each extracted value.
22    ///
23    /// # Arguments
24    ///
25    /// * `tenant_id` - The tenant identifier
26    /// * `resource_type` - The resource type (e.g., "Patient")
27    /// * `resource_id` - The resource's logical ID
28    /// * `values` - The extracted search values to index
29    ///
30    /// # Returns
31    ///
32    /// The number of index entries created.
33    async fn write_entries(
34        &self,
35        tenant_id: &str,
36        resource_type: &str,
37        resource_id: &str,
38        values: Vec<ExtractedValue>,
39    ) -> StorageResult<usize>;
40
41    /// Deletes all search index entries for a resource.
42    ///
43    /// Called when a resource is updated (before re-indexing) or deleted.
44    ///
45    /// # Arguments
46    ///
47    /// * `tenant_id` - The tenant identifier
48    /// * `resource_type` - The resource type
49    /// * `resource_id` - The resource's logical ID
50    ///
51    /// # Returns
52    ///
53    /// The number of index entries deleted.
54    async fn delete_entries(
55        &self,
56        tenant_id: &str,
57        resource_type: &str,
58        resource_id: &str,
59    ) -> StorageResult<usize>;
60
61    /// Deletes all search index entries for a specific parameter.
62    ///
63    /// Used when a SearchParameter is deleted or disabled.
64    ///
65    /// # Arguments
66    ///
67    /// * `tenant_id` - The tenant identifier
68    /// * `param_url` - The SearchParameter's canonical URL
69    ///
70    /// # Returns
71    ///
72    /// The number of index entries deleted.
73    async fn delete_entries_for_param(
74        &self,
75        tenant_id: &str,
76        param_url: &str,
77    ) -> StorageResult<usize>;
78
79    /// Clears all search index entries for a tenant.
80    ///
81    /// Used during full reindexing or tenant cleanup.
82    ///
83    /// # Arguments
84    ///
85    /// * `tenant_id` - The tenant identifier
86    ///
87    /// # Returns
88    ///
89    /// The number of index entries deleted.
90    async fn clear_all(&self, tenant_id: &str) -> StorageResult<usize>;
91
92    /// Returns the number of index entries for a tenant.
93    ///
94    /// # Arguments
95    ///
96    /// * `tenant_id` - The tenant identifier
97    ///
98    /// # Returns
99    ///
100    /// The total number of index entries.
101    async fn count_entries(&self, tenant_id: &str) -> StorageResult<u64>;
102
103    /// Returns the number of index entries for a specific resource.
104    ///
105    /// # Arguments
106    ///
107    /// * `tenant_id` - The tenant identifier
108    /// * `resource_type` - The resource type
109    /// * `resource_id` - The resource's logical ID
110    ///
111    /// # Returns
112    ///
113    /// The number of index entries for this resource.
114    async fn count_resource_entries(
115        &self,
116        tenant_id: &str,
117        resource_type: &str,
118        resource_id: &str,
119    ) -> StorageResult<u64>;
120}
121
122/// Options for index writing operations.
123#[derive(Debug, Clone, Default)]
124pub struct WriteOptions {
125    /// Whether to replace existing entries (vs. append).
126    pub replace: bool,
127
128    /// Whether to skip validation (for bulk operations).
129    pub skip_validation: bool,
130
131    /// Batch size for bulk operations.
132    pub batch_size: Option<usize>,
133}
134
135impl WriteOptions {
136    /// Creates new write options.
137    pub fn new() -> Self {
138        Self::default()
139    }
140
141    /// Sets the replace flag.
142    pub fn replace(mut self) -> Self {
143        self.replace = true;
144        self
145    }
146
147    /// Sets the skip_validation flag.
148    pub fn skip_validation(mut self) -> Self {
149        self.skip_validation = true;
150        self
151    }
152
153    /// Sets the batch size.
154    pub fn with_batch_size(mut self, size: usize) -> Self {
155        self.batch_size = Some(size);
156        self
157    }
158}
159
160#[cfg(test)]
161mod tests {
162    use super::*;
163
164    #[test]
165    fn test_write_options() {
166        let opts = WriteOptions::new().replace().with_batch_size(100);
167
168        assert!(opts.replace);
169        assert_eq!(opts.batch_size, Some(100));
170    }
171}