nodedb_lite/nodedb/core/ops/
indexed_crud.rs1use nodedb_types::error::{NodeDbError, NodeDbResult};
8
9use crate::nodedb::core::types::NodeDbLite;
10use crate::storage::engine::StorageEngine;
11
12impl<S: StorageEngine> NodeDbLite<S> {
13 pub async fn strict_insert(
20 &self,
21 collection: &str,
22 values: &[nodedb_types::value::Value],
23 ) -> NodeDbResult<()> {
24 let guard = self.fts_state.admit_mutation().await;
25 let result = async {
26 let schema = self.strict.schema(collection).ok_or_else(|| {
27 NodeDbError::storage(format!("strict collection '{collection}' not found"))
28 })?;
29
30 self.strict
32 .insert(collection, values)
33 .await
34 .map_err(NodeDbError::storage)?;
35
36 let row_id = crate::engine::index_integration::row_id(&schema.columns, values);
38
39 crate::engine::index_integration::index_row(
41 collection,
42 &row_id,
43 &schema.columns,
44 values,
45 &self.spatial,
46 &self.fts_state.manager,
47 )?;
48 crate::engine::index_integration::index_row_vectors(
49 &self.vector_state,
50 collection,
51 &row_id,
52 &schema.columns,
53 values,
54 )
55 .await?;
56
57 self.htap
59 .replicate_insert(collection, values, &self.columnar);
60
61 Ok(())
62 }
63 .await;
64 guard.finish(result)
65 }
66
67 pub async fn strict_delete(
69 &self,
70 collection: &str,
71 pk: &nodedb_types::value::Value,
72 ) -> NodeDbResult<bool> {
73 let guard = self.fts_state.admit_mutation().await;
74 let result = async {
75 let schema = self.strict.schema(collection).ok_or_else(|| {
76 NodeDbError::storage(format!("strict collection '{collection}' not found"))
77 })?;
78
79 let row_id = crate::engine::index_integration::pk_row_id(pk);
81
82 crate::engine::index_integration::deindex_row_text(
84 collection,
85 &row_id,
86 &self.fts_state.manager,
87 )?;
88 crate::engine::index_integration::deindex_row_vectors(
89 &self.vector_state,
90 collection,
91 &row_id,
92 &schema.columns,
93 )
94 .await?;
95
96 self.htap.replicate_delete(collection, pk, &self.columnar);
98
99 self.strict
100 .delete(collection, pk)
101 .await
102 .map_err(NodeDbError::storage)
103 }
104 .await;
105 guard.finish(result)
106 }
107
108 pub async fn columnar_insert(
110 &self,
111 collection: &str,
112 values: &[nodedb_types::value::Value],
113 ) -> NodeDbResult<()> {
114 let guard = self.fts_state.admit_mutation().await;
115 let result = async {
116 let schema = self.columnar.schema(collection).ok_or_else(|| {
117 NodeDbError::storage(format!("columnar collection '{collection}' not found"))
118 })?;
119
120 self.columnar
121 .insert(collection, values)
122 .map_err(NodeDbError::storage)?;
123
124 let row_id = crate::engine::index_integration::row_id(&schema.columns, values);
125
126 crate::engine::index_integration::index_row(
127 collection,
128 &row_id,
129 &schema.columns,
130 values,
131 &self.spatial,
132 &self.fts_state.manager,
133 )?;
134 crate::engine::index_integration::index_row_vectors(
135 &self.vector_state,
136 collection,
137 &row_id,
138 &schema.columns,
139 values,
140 )
141 .await?;
142
143 crate::engine::index_integration::index_geohash(
146 collection,
147 &row_id,
148 &schema,
149 self.columnar.profile(collection).as_ref(),
150 values,
151 &self.fts_state.manager,
152 )?;
153 Ok(())
154 }
155 .await;
156 guard.finish(result)
157 }
158
159 pub async fn strict_crdt_patch(
164 &self,
165 collection: &str,
166 pk: &nodedb_types::value::Value,
167 field_updates: &std::collections::HashMap<String, nodedb_types::value::Value>,
168 ) -> NodeDbResult<()> {
169 let guard = self.fts_state.admit_mutation().await;
170 let result = async {
171 let schema = self.strict.schema(collection).ok_or_else(|| {
172 NodeDbError::storage(format!("strict collection '{collection}' not found"))
173 })?;
174
175 let existing = self
177 .strict
178 .get(collection, pk)
179 .await
180 .map_err(NodeDbError::storage)?
181 .ok_or_else(|| NodeDbError::storage("row not found for CRDT patch"))?;
182
183 let encoder = nodedb_strict::TupleEncoder::new(&schema);
185 let tuple_bytes = encoder
186 .encode(&existing)
187 .map_err(|e| NodeDbError::storage(e.to_string()))?;
188
189 let patched = crate::engine::strict::crdt_adapter::apply_crdt_set(
191 &tuple_bytes,
192 &schema,
193 field_updates,
194 )
195 .map_err(NodeDbError::storage)?;
196
197 let decoder = nodedb_strict::TupleDecoder::new(&schema);
199 let new_values = decoder
200 .extract_all(&patched)
201 .map_err(|e| NodeDbError::storage(e.to_string()))?;
202
203 self.strict
205 .update_by_values(collection, pk, &new_values)
206 .await
207 .map_err(NodeDbError::storage)?;
208
209 crate::engine::index_integration::index_row_text(
211 collection,
212 &crate::engine::index_integration::row_id(&schema.columns, &new_values),
213 &schema.columns,
214 &new_values,
215 &self.fts_state.manager,
216 )?;
217
218 Ok(())
219 }
220 .await;
221 guard.finish(result)
222 }
223}