elif_orm/query/
performance_optimized.rs1use std::collections::HashMap;
7use std::sync::{RwLock, Arc};
8use once_cell::sync::Lazy;
9use super::builder::QueryBuilder;
10
11static QUERY_TEMPLATE_CACHE: Lazy<RwLock<HashMap<String, String>>> = Lazy::new(|| {
13 RwLock::new(HashMap::new())
14});
15
16static PLACEHOLDER_CACHE: Lazy<RwLock<HashMap<usize, String>>> = Lazy::new(|| {
18 RwLock::new(HashMap::new())
19});
20
21impl<M> QueryBuilder<M> {
23 pub fn generate_placeholders_cached(count: usize) -> String {
25 if let Ok(cache) = PLACEHOLDER_CACHE.read() {
27 if let Some(cached) = cache.get(&count) {
28 return cached.clone();
29 }
30 }
31
32 let placeholders = (1..=count)
34 .map(|i| format!("${}", i))
35 .collect::<Vec<_>>()
36 .join(", ");
37
38 if let Ok(mut cache) = PLACEHOLDER_CACHE.write() {
40 cache.insert(count, placeholders.clone());
41 }
42
43 placeholders
44 }
45
46 pub fn generate_sequential_placeholders(start_index: usize, count: usize) -> String {
49 if count == 0 {
50 return String::new();
51 }
52
53 let placeholders = (start_index..start_index + count)
54 .map(|i| format!("${}", i))
55 .collect::<Vec<_>>()
56 .join(", ");
57
58 placeholders
59 }
60
61 pub fn to_sql_optimized(&self) -> String {
63 let estimated_length = self.estimate_sql_length();
65 let mut sql = String::with_capacity(estimated_length);
66
67 match self.query_type {
68 super::types::QueryType::Select => {
69 self.build_select_sql_optimized(&mut sql);
70 },
71 _ => {
72 return self.to_sql();
74 }
75 }
76
77 sql
78 }
79
80 fn estimate_sql_length(&self) -> usize {
82 let mut length = 100; for field in &self.select_fields {
86 length += field.len() + 2; }
88
89 for table in &self.from_tables {
91 length += table.len() + 10; }
93
94 for condition in &self.where_conditions {
96 length += condition.column.len() + 20; }
98
99 for join in &self.joins {
101 length += join.table.len() + 30; }
103
104 length
105 }
106
107 fn build_select_sql_optimized(&self, sql: &mut String) {
109 let mut param_counter = 1usize;
110 if self.distinct {
112 sql.push_str("SELECT DISTINCT ");
113 } else {
114 sql.push_str("SELECT ");
115 }
116
117 if self.select_fields.is_empty() {
119 sql.push('*');
120 } else {
121 for (i, field) in self.select_fields.iter().enumerate() {
122 if i > 0 {
123 sql.push_str(", ");
124 }
125 sql.push_str(field);
126 }
127 }
128
129 if !self.from_tables.is_empty() {
131 sql.push_str(" FROM ");
132 for (i, table) in self.from_tables.iter().enumerate() {
133 if i > 0 {
134 sql.push_str(", ");
135 }
136 sql.push_str(table);
137 }
138 }
139
140 for join in &self.joins {
142 sql.push(' ');
143 match join.join_type {
144 super::types::JoinType::Inner => sql.push_str("INNER JOIN"),
145 super::types::JoinType::Left => sql.push_str("LEFT JOIN"),
146 super::types::JoinType::Right => sql.push_str("RIGHT JOIN"),
147 super::types::JoinType::Full => sql.push_str("FULL JOIN"),
148 }
149 sql.push(' ');
150 sql.push_str(&join.table);
151 sql.push_str(" ON ");
152
153 for (i, (left_col, right_col)) in join.on_conditions.iter().enumerate() {
155 if i > 0 {
156 sql.push_str(" AND ");
157 }
158 sql.push_str(left_col);
159 sql.push_str(" = ");
160 sql.push_str(right_col);
161 }
162 }
163
164 if !self.where_conditions.is_empty() {
166 sql.push_str(" WHERE ");
167 for (i, condition) in self.where_conditions.iter().enumerate() {
168 if i > 0 {
169 sql.push_str(" AND ");
170 }
171
172 if condition.column == "RAW" {
174 if let Some(ref value) = condition.value {
175 if let serde_json::Value::String(raw_sql) = value {
176 sql.push_str(raw_sql);
177 }
178 }
179 } else if condition.column == "EXISTS" || condition.column == "NOT EXISTS" {
180 sql.push_str(&condition.column);
181 sql.push(' ');
182 if let Some(ref value) = condition.value {
183 if let serde_json::Value::String(subquery) = value {
184 sql.push_str(subquery);
185 }
186 }
187 } else {
188 sql.push_str(&condition.column);
190
191 match condition.operator {
192 super::types::QueryOperator::Equal => sql.push_str(" = "),
193 super::types::QueryOperator::NotEqual => sql.push_str(" != "),
194 super::types::QueryOperator::GreaterThan => sql.push_str(" > "),
195 super::types::QueryOperator::LessThan => sql.push_str(" < "),
196 super::types::QueryOperator::GreaterThanOrEqual => sql.push_str(" >= "),
197 super::types::QueryOperator::LessThanOrEqual => sql.push_str(" <= "),
198 super::types::QueryOperator::Like => sql.push_str(" LIKE "),
199 super::types::QueryOperator::NotLike => sql.push_str(" NOT LIKE "),
200 super::types::QueryOperator::In => {
201 sql.push_str(" IN (");
202 let placeholder_count = condition.values.len();
203 if placeholder_count > 0 {
204 let placeholders = Self::generate_sequential_placeholders(param_counter, placeholder_count);
205 sql.push_str(&placeholders);
206 param_counter += placeholder_count;
207 }
208 sql.push(')');
209 continue; },
211 super::types::QueryOperator::NotIn => {
212 sql.push_str(" NOT IN (");
213 let placeholder_count = condition.values.len();
214 if placeholder_count > 0 {
215 let placeholders = Self::generate_sequential_placeholders(param_counter, placeholder_count);
216 sql.push_str(&placeholders);
217 param_counter += placeholder_count;
218 }
219 sql.push(')');
220 continue; },
222 super::types::QueryOperator::IsNull => {
223 sql.push_str(" IS NULL");
224 continue;
225 },
226 super::types::QueryOperator::IsNotNull => {
227 sql.push_str(" IS NOT NULL");
228 continue;
229 },
230 super::types::QueryOperator::Between => {
231 sql.push_str(&format!(" BETWEEN ${} AND ${}", param_counter, param_counter + 1));
232 param_counter += 2;
233 continue;
234 },
235 super::types::QueryOperator::Raw => {
236 if let Some(ref value) = condition.value {
238 if let serde_json::Value::String(raw_expr) = value {
239 sql.push(' ');
240 sql.push_str(raw_expr);
241 }
242 }
243 continue;
244 },
245 }
246
247 sql.push_str(&format!("${}", param_counter));
249 param_counter += 1;
250 }
251 }
252 }
253
254 if !self.group_by.is_empty() {
256 sql.push_str(" GROUP BY ");
257 for (i, column) in self.group_by.iter().enumerate() {
258 if i > 0 {
259 sql.push_str(", ");
260 }
261 sql.push_str(column);
262 }
263 }
264
265 if !self.having_conditions.is_empty() {
267 sql.push_str(" HAVING ");
268 for (i, condition) in self.having_conditions.iter().enumerate() {
269 if i > 0 {
270 sql.push_str(" AND ");
271 }
272 sql.push_str(&condition.column);
273
274 match condition.operator {
276 super::types::QueryOperator::Equal => sql.push_str(" = "),
277 super::types::QueryOperator::GreaterThan => sql.push_str(" > "),
278 super::types::QueryOperator::LessThan => sql.push_str(" < "),
279 _ => sql.push_str(" = "), }
281
282 sql.push_str(&format!("${}", param_counter));
283 param_counter += 1;
284 }
285 }
286
287 if !self.order_by.is_empty() {
289 sql.push_str(" ORDER BY ");
290 for (i, (column, direction)) in self.order_by.iter().enumerate() {
291 if i > 0 {
292 sql.push_str(", ");
293 }
294 sql.push_str(column);
295 match direction {
296 super::types::OrderDirection::Asc => sql.push_str(" ASC"),
297 super::types::OrderDirection::Desc => sql.push_str(" DESC"),
298 }
299 }
300 }
301
302 if let Some(limit) = self.limit_count {
304 sql.push_str(" LIMIT ");
305 sql.push_str(&limit.to_string());
306 }
307
308 if let Some(offset) = self.offset_value {
310 sql.push_str(" OFFSET ");
311 sql.push_str(&offset.to_string());
312 }
313 }
314}
315
316pub struct QueryBuilderPool {
318 pool: Arc<RwLock<Vec<QueryBuilder<()>>>>,
319 max_size: usize,
320}
321
322impl QueryBuilderPool {
323 pub fn new(max_size: usize) -> Self {
324 Self {
325 pool: Arc::new(RwLock::new(Vec::with_capacity(max_size))),
326 max_size,
327 }
328 }
329
330 pub fn acquire(&self) -> QueryBuilder<()> {
332 if let Ok(mut pool) = self.pool.write() {
333 if let Some(mut builder) = pool.pop() {
334 builder.reset();
336 return builder;
337 }
338 }
339
340 QueryBuilder::new()
342 }
343
344 pub fn release(&self, builder: QueryBuilder<()>) {
346 if let Ok(mut pool) = self.pool.write() {
347 if pool.len() < self.max_size {
348 pool.push(builder);
349 }
350 }
352 }
353}
354
355impl<M> QueryBuilder<M> {
356 pub fn reset(&mut self) {
358 self.query_type = super::types::QueryType::Select;
359 self.select_fields.clear();
360 self.from_tables.clear();
361 self.insert_table = None;
362 self.update_table = None;
363 self.delete_table = None;
364 self.set_clauses.clear();
365 self.where_conditions.clear();
366 self.joins.clear();
367 self.order_by.clear();
368 self.group_by.clear();
369 self.having_conditions.clear();
370 self.limit_count = None;
371 self.offset_value = None;
372 self.distinct = false;
373 }
374}
375
376static GLOBAL_QUERY_POOL: Lazy<QueryBuilderPool> = Lazy::new(|| {
378 QueryBuilderPool::new(100) });
380
381pub fn acquire_query_builder() -> QueryBuilder<()> {
383 GLOBAL_QUERY_POOL.acquire()
384}
385
386pub fn release_query_builder(builder: QueryBuilder<()>) {
388 GLOBAL_QUERY_POOL.release(builder);
389}
390
391#[cfg(test)]
392mod tests {
393 use super::*;
394
395 #[test]
396 fn test_placeholder_caching() {
397 let placeholders1 = QueryBuilder::<()>::generate_placeholders_cached(3);
398 let placeholders2 = QueryBuilder::<()>::generate_placeholders_cached(3);
399
400 assert_eq!(placeholders1, "$1, $2, $3");
401 assert_eq!(placeholders1, placeholders2);
402 }
403
404 #[test]
405 fn test_query_builder_pool() {
406 let pool = QueryBuilderPool::new(2);
407
408 let builder1 = pool.acquire();
409 let builder2 = pool.acquire();
410
411 pool.release(builder1);
412 pool.release(builder2);
413
414 let builder3 = pool.acquire(); assert!(!builder3.from_tables.is_empty() || builder3.from_tables.is_empty()); }
417
418 #[test]
419 fn test_optimized_sql_generation() {
420 let query: QueryBuilder<()> = QueryBuilder::new()
421 .from("users")
422 .select("id, name, email")
423 .where_eq("active", "true");
424
425 let sql = query.to_sql_optimized();
426 assert!(sql.contains("SELECT"));
427 assert!(sql.contains("FROM users"));
428 assert!(sql.contains("WHERE"));
429 }
430}