Skip to main content

linkrs_query/metadata/
context.rs

1//! Metadata Context
2//!
3//! This module provides a context for storing and accessing metadata during query planning.
4//! Similar to PostgreSQL's fdw_private mechanism.
5
6use super::types::{EdgeTypeMetadata, IndexMetadata, TagMetadata};
7use std::collections::HashMap;
8
9/// Metadata context
10///
11/// Stores pre-resolved metadata during the planning phase, similar to PostgreSQL's fdw_private.
12#[derive(Debug, Default, Clone)]
13pub struct MetadataContext {
14    /// Index metadata cache
15    index_metadata: HashMap<String, IndexMetadata>,
16    /// Tag metadata cache
17    tag_metadata: HashMap<String, TagMetadata>,
18    /// Edge type metadata cache
19    edge_type_metadata: HashMap<String, EdgeTypeMetadata>,
20}
21
22impl MetadataContext {
23    /// Create a new empty metadata context
24    pub fn new() -> Self {
25        Self {
26            index_metadata: HashMap::new(),
27            tag_metadata: HashMap::new(),
28            edge_type_metadata: HashMap::new(),
29        }
30    }
31
32    /// Set index metadata
33    pub fn set_index_metadata(&mut self, index_name: String, metadata: IndexMetadata) {
34        self.index_metadata.insert(index_name, metadata);
35    }
36
37    /// Set tag metadata
38    pub fn set_tag_metadata(&mut self, tag_name: String, metadata: TagMetadata) {
39        self.tag_metadata.insert(tag_name, metadata);
40    }
41
42    /// Set edge type metadata
43    pub fn set_edge_type_metadata(&mut self, edge_type: String, metadata: EdgeTypeMetadata) {
44        self.edge_type_metadata.insert(edge_type, metadata);
45    }
46
47    /// Get index metadata
48    pub fn get_index_metadata(&self, index_name: &str) -> Option<&IndexMetadata> {
49        self.index_metadata.get(index_name)
50    }
51
52    /// Get tag metadata
53    pub fn get_tag_metadata(&self, tag_name: &str) -> Option<&TagMetadata> {
54        self.tag_metadata.get(tag_name)
55    }
56
57    /// Get tag metadata (mutable)
58    pub fn get_tag_metadata_mut(&mut self, tag_name: &str) -> Option<&mut TagMetadata> {
59        self.tag_metadata.get_mut(tag_name)
60    }
61
62    /// Get edge type metadata
63    pub fn get_edge_type_metadata(&self, edge_type: &str) -> Option<&EdgeTypeMetadata> {
64        self.edge_type_metadata.get(edge_type)
65    }
66
67    /// Get edge type metadata (mutable)
68    pub fn get_edge_type_metadata_mut(&mut self, edge_type: &str) -> Option<&mut EdgeTypeMetadata> {
69        self.edge_type_metadata.get_mut(edge_type)
70    }
71
72    /// Check if index metadata exists
73    pub fn has_index_metadata(&self, index_name: &str) -> bool {
74        self.index_metadata.contains_key(index_name)
75    }
76
77    /// Check if tag metadata exists
78    pub fn has_tag_metadata(&self, tag_name: &str) -> bool {
79        self.tag_metadata.contains_key(tag_name)
80    }
81
82    /// Check if edge type metadata exists
83    pub fn has_edge_type_metadata(&self, edge_type: &str) -> bool {
84        self.edge_type_metadata.contains_key(edge_type)
85    }
86
87    /// Get all index metadata
88    pub fn get_all_indexes(&self) -> impl Iterator<Item = &IndexMetadata> {
89        self.index_metadata.values()
90    }
91
92    /// Get all tag metadata
93    pub fn get_all_tags(&self) -> impl Iterator<Item = &TagMetadata> {
94        self.tag_metadata.values()
95    }
96
97    /// Get all edge type metadata
98    pub fn get_all_edge_types(&self) -> impl Iterator<Item = &EdgeTypeMetadata> {
99        self.edge_type_metadata.values()
100    }
101
102    /// Clear all metadata
103    pub fn clear(&mut self) {
104        self.index_metadata.clear();
105        self.tag_metadata.clear();
106        self.edge_type_metadata.clear();
107    }
108
109    /// Merge another metadata context into this one
110    pub fn merge(&mut self, other: MetadataContext) {
111        self.index_metadata.extend(other.index_metadata);
112        self.tag_metadata.extend(other.tag_metadata);
113        self.edge_type_metadata.extend(other.edge_type_metadata);
114    }
115
116    /// Find a vector index by space_id and field name
117    pub fn find_vector_index_by_field(
118        &self,
119        space_id: u64,
120        field_name: &str,
121    ) -> Option<&IndexMetadata> {
122        self.index_metadata.values().find(|index| {
123            index.space_id == space_id
124                && index.field_name == field_name
125                && index.index_type == super::types::IndexType::Vector
126        })
127    }
128
129    /// Find a fulltext index by space_id and field name
130    pub fn find_fulltext_index_by_field(
131        &self,
132        space_id: u64,
133        field_name: &str,
134    ) -> Option<&IndexMetadata> {
135        self.index_metadata.values().find(|index| {
136            index.space_id == space_id
137                && index.field_name == field_name
138                && index.index_type == super::types::IndexType::Fulltext
139        })
140    }
141
142    /// Find an index by name and optional type filter
143    pub fn find_index_by_name(
144        &self,
145        index_name: &str,
146        index_type: Option<super::types::IndexType>,
147    ) -> Option<&IndexMetadata> {
148        self.index_metadata.values().find(|index| {
149            index.index_name == index_name && index_type.is_none_or(|t| index.index_type == t)
150        })
151    }
152}