1use crate::error::Result;
2use crate::types::{Document, Value};
3use crate::search::FullTextIndex;
4use dashmap::DashMap;
5use serde::{Deserialize, Serialize};
6use std::sync::Arc;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub enum IndexType {
10 BTree,
11 Hash,
12 FullText,
13 Custom(String),
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct IndexDefinition {
18 pub name: String,
19 pub collection: String,
20 pub fields: Vec<String>,
21 pub index_type: IndexType,
22 pub unique: bool,
23}
24
25pub struct Index {
26 definition: IndexDefinition,
27 data: Arc<DashMap<Value, Vec<String>>>, full_text: Option<Arc<FullTextIndex>>,
29}
30
31impl Index {
32 pub fn new(definition: IndexDefinition) -> Self {
33 let full_text = if matches!(definition.index_type, IndexType::FullText) {
34 Some(Arc::new(FullTextIndex::new(
35 &definition.collection,
36 &definition.fields[0],
37 )))
38 } else {
39 None
40 };
41
42 Self {
43 definition,
44 data: Arc::new(DashMap::new()),
45 full_text,
46 }
47 }
48
49 pub fn insert(&self, doc: &Document) -> Result<()> {
50 let key = self.extract_key(doc)?;
51 let doc_id = doc.id.clone();
52
53 match self.data.get_mut(&key) {
54 Some(mut ids) => {
55 if self.definition.unique && !ids.is_empty() {
56 return Err(crate::error::AuroraError::InvalidOperation(
57 "Unique constraint violation".into(),
58 ));
59 }
60 ids.push(doc_id.clone());
61 }
62 None => {
63 self.data.insert(key, vec![doc_id.clone()]);
64 }
65 }
66
67 if let Some(ft_index) = &self.full_text {
68 ft_index.index_document(doc)?;
69 }
70
71 Ok(())
72 }
73
74 pub fn search(&self, value: &Value) -> Option<Vec<String>> {
75 self.data.get(value).map(|ids| ids.clone())
76 }
77
78 pub fn search_text(&self, query: &str) -> Option<Vec<(String, f32)>> {
79 self.full_text.as_ref().map(|ft| ft.search(query))
80 }
81
82 fn extract_key(&self, doc: &Document) -> Result<Value> {
83 if self.definition.fields.len() == 1 {
84 Ok(doc.data
85 .get(&self.definition.fields[0])
86 .cloned()
87 .unwrap_or(Value::Null))
88 } else {
89 let values: Vec<Value> = self
90 .definition
91 .fields
92 .iter()
93 .map(|f| doc.data.get(f).cloned().unwrap_or(Value::Null))
94 .collect();
95 Ok(Value::Array(values))
96 }
97 }
98
99 #[allow(dead_code)]
100 pub fn full_text(&self) -> Option<Arc<FullTextIndex>> {
101 self.full_text.clone()
102 }
103}