1use std::collections::HashSet;
11
12use async_trait::async_trait;
13
14use nodedb_client::NodeDb;
15use nodedb_types::document::Document;
16use nodedb_types::dropped_collection::DroppedCollection;
17use nodedb_types::error::NodeDbResult;
18use nodedb_types::filter::{EdgeFilter, MetadataFilter};
19use nodedb_types::graph::{Direction, GraphStats};
20use nodedb_types::id::{EdgeId, NodeId};
21use nodedb_types::result::{QueryResult, SearchResult, SubGraph};
22use nodedb_types::text_search::TextSearchParams;
23use nodedb_types::value::Value;
24
25use crate::nodedb::NodeDbLite;
26use crate::storage::engine::StorageEngine;
27
28use super::vector::{INTERNAL_FIELDS_BASE, INTERNAL_FIELDS_NAMED, TraitVectorSearch};
29
30#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
31#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
32impl<S: StorageEngine> NodeDb for NodeDbLite<S> {
33 async fn vector_search(
36 &self,
37 collection: &str,
38 query: &[f32],
39 k: usize,
40 filter: Option<&MetadataFilter>,
41 allowed_ids: Option<&HashSet<String>>,
42 ) -> NodeDbResult<Vec<SearchResult>> {
43 self.vector_search_internal(TraitVectorSearch {
44 index_key: collection,
45 collection,
46 query,
47 k,
48 filter,
49 exclude_fields: INTERNAL_FIELDS_BASE,
50 allowed_ids,
51 })
52 .await
53 }
54
55 async fn vector_insert(
56 &self,
57 collection: &str,
58 id: &str,
59 embedding: &[f32],
60 metadata: Option<Document>,
61 ) -> NodeDbResult<()> {
62 self.vector_insert_impl(collection, id, embedding, metadata)
63 .await
64 }
65
66 async fn vector_delete(&self, collection: &str, id: &str) -> NodeDbResult<()> {
67 self.vector_delete_impl(collection, id).await
68 }
69
70 async fn vector_insert_field(
71 &self,
72 collection: &str,
73 field_name: &str,
74 id: &str,
75 embedding: &[f32],
76 metadata: Option<Document>,
77 ) -> NodeDbResult<()> {
78 self.vector_insert_field_impl(collection, field_name, id, embedding, metadata)
79 .await
80 }
81
82 async fn vector_search_field(
83 &self,
84 collection: &str,
85 field_name: &str,
86 query: &[f32],
87 k: usize,
88 filter: Option<&MetadataFilter>,
89 ) -> NodeDbResult<Vec<SearchResult>> {
90 let index_key = if field_name.is_empty() {
91 collection.to_string()
92 } else {
93 format!("{collection}:{field_name}")
94 };
95 self.vector_search_internal(TraitVectorSearch {
96 index_key: &index_key,
97 collection,
98 query,
99 k,
100 filter,
101 exclude_fields: INTERNAL_FIELDS_NAMED,
102 allowed_ids: None,
103 })
104 .await
105 }
106
107 async fn graph_traverse(
110 &self,
111 collection: &str,
112 start: &NodeId,
113 depth: u8,
114 direction: Direction,
115 edge_filter: Option<&EdgeFilter>,
116 ) -> NodeDbResult<SubGraph> {
117 self.graph_traverse_impl(collection, start, depth, direction, edge_filter)
118 .await
119 }
120
121 async fn graph_insert_edge(
122 &self,
123 collection: &str,
124 from: &NodeId,
125 to: &NodeId,
126 edge_type: &str,
127 properties: Option<Document>,
128 ) -> NodeDbResult<EdgeId> {
129 self.graph_insert_edge_impl(collection, from, to, edge_type, properties)
130 .await
131 }
132
133 async fn graph_delete_edge(&self, collection: &str, edge_id: &EdgeId) -> NodeDbResult<()> {
134 self.graph_delete_edge_impl(collection, edge_id).await
135 }
136
137 async fn graph_stats(
138 &self,
139 collection: Option<&str>,
140 as_of: Option<i64>,
141 ) -> NodeDbResult<Vec<GraphStats>> {
142 self.graph_stats_impl(collection, as_of).await
143 }
144
145 async fn graph_pagerank(
146 &self,
147 collection: &str,
148 personalization: Option<std::collections::HashMap<String, f64>>,
149 damping: Option<f64>,
150 max_iterations: Option<u32>,
151 ) -> NodeDbResult<Vec<(String, f64)>> {
152 self.graph_pagerank_impl(collection, personalization, damping, max_iterations)
153 .await
154 }
155
156 async fn graph_shortest_path(
157 &self,
158 collection: &str,
159 from: &NodeId,
160 to: &NodeId,
161 max_depth: u8,
162 edge_filter: Option<&EdgeFilter>,
163 ) -> NodeDbResult<Option<Vec<NodeId>>> {
164 self.graph_shortest_path_impl(collection, from, to, max_depth, edge_filter)
165 .await
166 }
167
168 async fn batch_graph_insert_edges(
174 &self,
175 collection: &str,
176 edges: &[(&str, &str, &str)],
177 ) -> NodeDbResult<()> {
178 let owned: Vec<(NodeId, NodeId, &str, Option<Document>)> = edges
179 .iter()
180 .map(|&(src, dst, label)| {
181 (
182 NodeId::from_validated(src.to_string()),
183 NodeId::from_validated(dst.to_string()),
184 label,
185 None,
186 )
187 })
188 .collect();
189 self.batch_graph_insert_edges(collection, &owned).await?;
190 Ok(())
191 }
192
193 async fn list_insert(
196 &self,
197 collection: &str,
198 document_id: &str,
199 list_path: &str,
200 index: usize,
201 fields: &Value,
202 ) -> NodeDbResult<()> {
203 self.list_insert_impl(collection, document_id, list_path, index, fields)
204 .await
205 }
206
207 async fn list_delete(
208 &self,
209 collection: &str,
210 document_id: &str,
211 list_path: &str,
212 index: usize,
213 ) -> NodeDbResult<()> {
214 self.list_delete_impl(collection, document_id, list_path, index)
215 .await
216 }
217
218 async fn list_move(
219 &self,
220 collection: &str,
221 document_id: &str,
222 list_path: &str,
223 from_index: usize,
224 to_index: usize,
225 ) -> NodeDbResult<()> {
226 self.list_move_impl(collection, document_id, list_path, from_index, to_index)
227 .await
228 }
229
230 async fn document_get(&self, collection: &str, id: &str) -> NodeDbResult<Option<Document>> {
233 self.document_get_impl(collection, id).await
234 }
235
236 async fn document_put(&self, collection: &str, doc: Document) -> NodeDbResult<()> {
237 self.document_put_impl(collection, doc).await
238 }
239
240 async fn document_delete(&self, collection: &str, id: &str) -> NodeDbResult<()> {
241 self.document_delete_impl(collection, id).await
242 }
243
244 async fn document_put_with_vector(
245 &self,
246 doc_collection: &str,
247 doc: Document,
248 vector_collection: &str,
249 id: &str,
250 embedding: &[f32],
251 ) -> NodeDbResult<()> {
252 self.document_put_with_vector_impl(doc_collection, doc, vector_collection, id, embedding)
253 .await
254 }
255
256 async fn document_get_as_of(
257 &self,
258 collection: &str,
259 id: &str,
260 as_of_ms: Option<i64>,
261 valid_time_ms: Option<i64>,
262 ) -> NodeDbResult<Option<Document>> {
263 self.document_get_as_of_impl(collection, id, as_of_ms, valid_time_ms)
264 .await
265 }
266
267 async fn document_put_with_valid_time(
268 &self,
269 collection: &str,
270 doc: Document,
271 valid_from_ms: Option<i64>,
272 valid_until_ms: Option<i64>,
273 ) -> NodeDbResult<()> {
274 self.document_put_with_valid_time_impl(collection, doc, valid_from_ms, valid_until_ms)
275 .await
276 }
277
278 async fn execute_sql(&self, query: &str, params: &[Value]) -> NodeDbResult<QueryResult> {
281 self.execute_sql_impl(query, params).await
282 }
283
284 async fn text_search(
285 &self,
286 collection: &str,
287 field: &str,
288 query: &str,
289 top_k: usize,
290 params: TextSearchParams,
291 allowed_ids: Option<&HashSet<String>>,
292 ) -> NodeDbResult<Vec<SearchResult>> {
293 self.text_search_impl(collection, field, query, top_k, params, allowed_ids)
294 .await
295 }
296
297 async fn list_dropped_collections(&self) -> NodeDbResult<Vec<DroppedCollection>> {
300 Ok(Vec::new())
305 }
306}