nodedb_lite/query/spatial_ops/
writes.rs1use nodedb_types::Surrogate;
5use nodedb_types::geometry::Geometry;
6use nodedb_types::result::QueryResult;
7
8use crate::error::LiteError;
9use crate::query::engine::LiteQueryEngine;
10use crate::storage::engine::StorageEngine;
11
12pub fn spatial_insert<S: StorageEngine>(
18 engine: &LiteQueryEngine<S>,
19 collection: &str,
20 field: &str,
21 surrogate: Surrogate,
22 geometry: &Geometry,
23) -> Result<QueryResult, LiteError> {
24 let doc_id = surrogate.0.to_string();
25 engine
26 .spatial
27 .lock()
28 .map_err(|_| LiteError::LockPoisoned)?
29 .index_document(collection, field, &doc_id, geometry);
30 #[cfg(not(target_arch = "wasm32"))]
32 if let Some(q) = &engine.spatial_outbound {
33 q.stage_insert(collection, field, &doc_id, geometry);
34 }
35 Ok(QueryResult {
36 columns: vec![],
37 rows: vec![],
38 rows_affected: 1,
39 command: None,
40 })
41}
42
43pub fn spatial_delete<S: StorageEngine>(
45 engine: &LiteQueryEngine<S>,
46 collection: &str,
47 field: &str,
48 surrogate: Option<Surrogate>,
49) -> Result<QueryResult, LiteError> {
50 let Some(surrogate) = surrogate else {
52 return Ok(QueryResult {
53 columns: vec![],
54 rows: vec![],
55 rows_affected: 0,
56 command: None,
57 });
58 };
59 let doc_id = surrogate.0.to_string();
60 engine
61 .spatial
62 .lock()
63 .map_err(|_| LiteError::LockPoisoned)?
64 .remove_document(collection, field, &doc_id);
65 #[cfg(not(target_arch = "wasm32"))]
67 if let Some(q) = &engine.spatial_outbound {
68 q.stage_delete(collection, field, &doc_id);
69 }
70 Ok(QueryResult {
71 columns: vec![],
72 rows: vec![],
73 rows_affected: 1,
74 command: None,
75 })
76}
77
78#[cfg(test)]
79mod tests {
80 use std::sync::{Arc, Mutex};
81
82 use nodedb_types::BoundingBox;
83 use nodedb_types::Surrogate;
84 use nodedb_types::geometry::Geometry;
85
86 use crate::engine::spatial::SpatialIndexManager;
87
88 fn make_mgr() -> Arc<Mutex<SpatialIndexManager>> {
89 let governor = crate::query::engine::test_governor();
90 Arc::new(Mutex::new(SpatialIndexManager::new(
91 crate::query::engine::test_scoped_memory(&governor, nodedb_mem::EngineId::Spatial),
92 )))
93 }
94
95 #[test]
96 fn insert_indexes_geometry() {
97 let mgr = make_mgr();
98 let doc_id = Surrogate(42).0.to_string();
99 mgr.lock()
100 .unwrap()
101 .index_document("col", "geom", &doc_id, &Geometry::point(10.0, 20.0));
102 let guard = mgr.lock().unwrap();
103 let hits = guard.search("col", "geom", &BoundingBox::new(9.0, 19.0, 11.0, 21.0));
104 assert_eq!(hits.len(), 1);
105 }
106
107 #[test]
108 fn delete_removes_geometry() {
109 let mgr = make_mgr();
110 let doc_id = Surrogate(7).0.to_string();
111 mgr.lock()
112 .unwrap()
113 .index_document("col", "geom", &doc_id, &Geometry::point(10.0, 20.0));
114 mgr.lock().unwrap().remove_document("col", "geom", &doc_id);
115 let guard = mgr.lock().unwrap();
116 let hits = guard.search("col", "geom", &BoundingBox::new(0.0, 0.0, 180.0, 90.0));
117 assert!(hits.is_empty());
118 }
119}