1pub use crate::introspection::*;
8pub use crate::optimizer::*;
9pub use crate::validation::*;
10
11pub mod components {
13 pub mod optimization {
16 pub use crate::optimizer::*;
17 }
18
19 pub mod introspection {
21 pub use crate::introspection::*;
22 }
23
24 pub mod validation {
26 pub use crate::validation::*;
27 }
28}
29
30pub mod performance {
32 use std::collections::HashMap;
33 use std::time::{Duration, Instant};
34
35 #[derive(Debug, Clone)]
37 pub struct QueryMetrics {
38 pub query_hash: String,
39 pub execution_time: Duration,
40 pub complexity_score: usize,
41 pub depth: usize,
42 pub cache_hit: bool,
43 pub timestamp: Instant,
44 }
45
46 impl QueryMetrics {
47 pub fn new(
48 query_hash: String,
49 execution_time: Duration,
50 complexity_score: usize,
51 depth: usize,
52 cache_hit: bool,
53 ) -> Self {
54 Self {
55 query_hash,
56 execution_time,
57 complexity_score,
58 depth,
59 cache_hit,
60 timestamp: Instant::now(),
61 }
62 }
63 }
64
65 #[derive(Debug, Default)]
67 pub struct PerformanceTracker {
68 metrics: Vec<QueryMetrics>,
69 slow_queries: Vec<QueryMetrics>,
70 slow_query_threshold: Duration,
71 }
72
73 impl PerformanceTracker {
74 pub fn new() -> Self {
75 Self {
76 metrics: Vec::new(),
77 slow_queries: Vec::new(),
78 slow_query_threshold: Duration::from_millis(1000), }
80 }
81
82 pub fn with_slow_query_threshold(mut self, threshold: Duration) -> Self {
83 self.slow_query_threshold = threshold;
84 self
85 }
86
87 pub fn record_query(&mut self, metrics: QueryMetrics) {
88 if metrics.execution_time > self.slow_query_threshold {
89 self.slow_queries.push(metrics.clone());
90 }
91 self.metrics.push(metrics);
92 }
93
94 pub fn get_average_execution_time(&self) -> Option<Duration> {
95 if self.metrics.is_empty() {
96 return None;
97 }
98
99 let total: Duration = self.metrics.iter().map(|m| m.execution_time).sum();
100 Some(total / self.metrics.len() as u32)
101 }
102
103 pub fn get_cache_hit_rate(&self) -> f64 {
104 if self.metrics.is_empty() {
105 return 0.0;
106 }
107
108 let cache_hits = self.metrics.iter().filter(|m| m.cache_hit).count();
109 cache_hits as f64 / self.metrics.len() as f64
110 }
111
112 pub fn get_slow_queries(&self) -> &[QueryMetrics] {
113 &self.slow_queries
114 }
115
116 pub fn get_complexity_distribution(&self) -> HashMap<usize, usize> {
117 let mut distribution = HashMap::new();
118
119 for metric in &self.metrics {
120 let bucket = (metric.complexity_score / 100) * 100; *distribution.entry(bucket).or_insert(0) += 1;
122 }
123
124 distribution
125 }
126 }
127}
128
129pub mod security {
131
132 pub struct SecurityPatterns;
134
135 impl SecurityPatterns {
136 pub fn has_dangerous_patterns(query: &str) -> bool {
138 let dangerous_keywords = [
139 "__schema",
140 "__type",
141 "mutation",
142 "subscription",
143 "introspection",
144 ];
145
146 let query_lower = query.to_lowercase();
147 dangerous_keywords
148 .iter()
149 .any(|&keyword| query_lower.contains(keyword))
150 }
151
152 pub fn extract_operation_names(query: &str) -> Vec<String> {
154 let mut operations = Vec::new();
157
158 for line in query.lines() {
159 let line = line.trim();
160 if line.starts_with("query ")
161 || line.starts_with("mutation ")
162 || line.starts_with("subscription ")
163 {
164 if let Some(name_start) = line.find(' ') {
165 if let Some(name_end) = line[name_start + 1..].find([' ', '(', '{']) {
166 let name = &line[name_start + 1..name_start + 1 + name_end];
167 if !name.is_empty() {
168 operations.push(name.to_string());
169 }
170 }
171 }
172 }
173 }
174
175 operations
176 }
177
178 pub fn recommended_validation_config(
180 environment: Environment,
181 ) -> crate::validation::ValidationConfig {
182 match environment {
183 Environment::Development => crate::validation::ValidationConfig {
184 max_depth: 15,
185 max_complexity: 2000,
186 max_aliases: 100,
187 max_root_fields: 50,
188 disable_introspection: false,
189 max_fragments: 100,
190 ..Default::default()
191 },
192 Environment::Production => crate::validation::ValidationConfig {
193 max_depth: 8,
194 max_complexity: 1000,
195 max_aliases: 20,
196 max_root_fields: 15,
197 disable_introspection: true,
198 max_fragments: 25,
199 ..Default::default()
200 },
201 Environment::Testing => crate::validation::ValidationConfig {
202 max_depth: 20,
203 max_complexity: 5000,
204 max_aliases: 200,
205 max_root_fields: 100,
206 disable_introspection: false,
207 max_fragments: 200,
208 ..Default::default()
209 },
210 }
211 }
212 }
213
214 #[derive(Debug, Clone, Copy)]
216 pub enum Environment {
217 Development,
218 Production,
219 Testing,
220 }
221}