linkrs_query/executor/base/
traits.rs1use std::fmt::Debug;
14#[cfg(any(feature = "fulltext", feature = "vector"))]
15use std::sync::Arc;
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
19pub enum SearchProviderType {
20 Fulltext,
21 Vector,
22}
23
24impl std::fmt::Display for SearchProviderType {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 match self {
27 SearchProviderType::Fulltext => write!(f, "FULLTEXT"),
28 SearchProviderType::Vector => write!(f, "VECTOR"),
29 }
30 }
31}
32
33#[derive(Debug, Clone)]
36pub struct IndexInfo {
37 pub space_id: u64,
38 pub tag_name: String,
39 pub field_name: String,
40 pub index_name: Option<String>,
41 pub status: String,
42}
43
44pub trait SearchProvider: Send + Sync + Debug + 'static {
56 fn name(&self) -> &str;
58
59 fn provider_type(&self) -> SearchProviderType;
61
62 fn description(&self) -> String {
64 format!("{} search provider: {}", self.provider_type(), self.name())
65 }
66
67 fn list_indexes(&self, space_id: u64) -> Vec<IndexInfo>;
72
73 fn drop_index(&self, space_id: u64, tag_name: &str, field_name: &str) -> Result<(), String>;
80}
81
82#[cfg(feature = "fulltext")]
84pub struct FulltextProvider {
85 manager: Arc<linkrs_fulltext::manager::FulltextIndexManager>,
86}
87
88#[cfg(feature = "fulltext")]
89impl FulltextProvider {
90 pub fn new(manager: Arc<linkrs_fulltext::manager::FulltextIndexManager>) -> Self {
91 Self { manager }
92 }
93
94 pub fn manager(&self) -> &Arc<linkrs_fulltext::manager::FulltextIndexManager> {
95 &self.manager
96 }
97}
98
99#[cfg(feature = "fulltext")]
100impl Debug for FulltextProvider {
101 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102 f.debug_struct("FulltextProvider")
103 .field("index_count", &self.manager.list_indexes().len())
104 .finish()
105 }
106}
107
108#[cfg(feature = "fulltext")]
109impl SearchProvider for FulltextProvider {
110 fn name(&self) -> &str {
111 "fulltext"
112 }
113
114 fn provider_type(&self) -> SearchProviderType {
115 SearchProviderType::Fulltext
116 }
117
118 fn description(&self) -> String {
119 format!(
120 "Fulltext search provider ({} indexes)",
121 self.manager.list_indexes().len()
122 )
123 }
124
125 fn list_indexes(&self, space_id: u64) -> Vec<IndexInfo> {
126 self.manager
127 .list_indexes()
128 .into_iter()
129 .filter(|m| space_id == 0 || m.space_id == space_id)
130 .map(|m| IndexInfo {
131 space_id: m.space_id,
132 tag_name: m.tag_name,
133 field_name: m.field_name,
134 index_name: Some(m.index_name.clone()),
135 status: format!("{:?}", m.status),
136 })
137 .collect()
138 }
139
140 fn drop_index(&self, space_id: u64, tag_name: &str, field_name: &str) -> Result<(), String> {
141 let manager = self.manager.clone();
143 let tag = tag_name.to_string();
144 let field = field_name.to_string();
145 tokio::task::block_in_place(|| {
146 tokio::runtime::Handle::current()
147 .block_on(async move { manager.drop_index(space_id, &tag, &field).await })
148 })
149 .map_err(|e| e.to_string())
150 }
151}
152
153#[cfg(feature = "vector")]
155pub struct VectorProvider {
156 coordinator: Arc<linkrs_sync::vector_sync::VectorSyncCoordinator>,
157}
158
159#[cfg(feature = "vector")]
160impl VectorProvider {
161 pub fn new(coordinator: Arc<linkrs_sync::vector_sync::VectorSyncCoordinator>) -> Self {
162 Self { coordinator }
163 }
164
165 pub fn coordinator(&self) -> &Arc<linkrs_sync::vector_sync::VectorSyncCoordinator> {
166 &self.coordinator
167 }
168}
169
170#[cfg(feature = "vector")]
171impl Debug for VectorProvider {
172 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
173 f.debug_struct("VectorProvider")
174 .field("index_count", &self.coordinator.list_indexes().len())
175 .finish()
176 }
177}
178
179#[cfg(feature = "vector")]
180impl SearchProvider for VectorProvider {
181 fn name(&self) -> &str {
182 "vector"
183 }
184
185 fn provider_type(&self) -> SearchProviderType {
186 SearchProviderType::Vector
187 }
188
189 fn description(&self) -> String {
190 format!(
191 "Vector search provider ({} indexes)",
192 self.coordinator.list_indexes().len()
193 )
194 }
195
196 fn list_indexes(&self, space_id: u64) -> Vec<IndexInfo> {
197 self.coordinator
198 .list_indexes()
199 .into_iter()
200 .filter(|m| space_id == 0 || m.space_id == space_id)
201 .map(|m| IndexInfo {
202 space_id: m.space_id,
203 tag_name: m.tag_name,
204 field_name: m.field_name,
205 index_name: m.index_name.clone(),
206 status: "Active".to_string(),
207 })
208 .collect()
209 }
210
211 fn drop_index(&self, space_id: u64, tag_name: &str, field_name: &str) -> Result<(), String> {
212 let coordinator = self.coordinator.clone();
213 let tag = tag_name.to_string();
214 let field = field_name.to_string();
215 tokio::task::block_in_place(|| {
216 tokio::runtime::Handle::current().block_on(async move {
217 coordinator.drop_vector_index(space_id, &tag, &field).await
218 })
219 })
220 .map_err(|e| e.to_string())
221 }
222}