1use crate::{Error, Result};
8use async_trait::async_trait;
9use serde_json::Value;
10use sqlx::{Column, Row};
11use std::collections::HashMap;
12use std::sync::Arc;
13use tokio::sync::RwLock;
14
15#[async_trait]
20pub trait VirtualDatabase: Send + Sync {
21 async fn initialize(&mut self) -> Result<()>;
23
24 async fn query(&self, query: &str, params: &[Value]) -> Result<Vec<HashMap<String, Value>>>;
26
27 async fn execute(&self, query: &str, params: &[Value]) -> Result<u64>;
29
30 async fn execute_with_id(&self, query: &str, params: &[Value]) -> Result<String>;
32
33 async fn table_exists(&self, table_name: &str) -> Result<bool>;
35
36 async fn create_table(&self, create_statement: &str) -> Result<()>;
38
39 fn connection_info(&self) -> String;
41
42 async fn close(&mut self) -> Result<()>;
44}
45
46pub async fn create_database(
48 backend: &crate::config::StorageBackend,
49) -> Result<std::sync::Arc<dyn VirtualDatabase + Send + Sync>> {
50 use std::sync::Arc;
51 match backend {
52 crate::config::StorageBackend::Sqlite { path } => {
53 let mut db = SqliteDatabase::new(path.clone()).await?;
54 db.initialize().await?;
55 Ok(Arc::new(db))
56 }
57 crate::config::StorageBackend::Json { path } => {
58 let mut db = JsonDatabase::new(path.clone()).await?;
59 db.initialize().await?;
60 Ok(Arc::new(db))
61 }
62 crate::config::StorageBackend::Memory => {
63 let mut db = InMemoryDatabase::new().await?;
64 db.initialize().await?;
65 Ok(Arc::new(db))
66 }
67 }
68}
69
70pub struct SqliteDatabase {
72 pool: sqlx::SqlitePool,
73 path: std::path::PathBuf,
74}
75
76impl SqliteDatabase {
77 pub async fn new<P: AsRef<std::path::Path>>(path: P) -> Result<Self> {
79 let path = path.as_ref().to_path_buf();
80
81 if let Some(parent) = path.parent() {
83 tokio::fs::create_dir_all(parent).await.map_err(|e| {
84 Error::generic(format!("Failed to create database directory: {}", e))
85 })?;
86 }
87
88 let db_url = format!("sqlite://{}?mode=rwc", path.display());
89 let pool = sqlx::sqlite::SqlitePoolOptions::new()
90 .max_connections(10)
91 .connect(&db_url)
92 .await
93 .map_err(|e| Error::generic(format!("Failed to connect to SQLite database: {}", e)))?;
94
95 sqlx::query("PRAGMA journal_mode = WAL")
97 .execute(&pool)
98 .await
99 .map_err(|e| Error::generic(format!("Failed to enable WAL mode: {}", e)))?;
100
101 sqlx::query("PRAGMA foreign_keys = ON")
103 .execute(&pool)
104 .await
105 .map_err(|e| Error::generic(format!("Failed to enable foreign keys: {}", e)))?;
106
107 Ok(Self { pool, path })
108 }
109}
110
111#[async_trait]
112impl VirtualDatabase for SqliteDatabase {
113 async fn initialize(&mut self) -> Result<()> {
114 Ok(())
117 }
118
119 async fn query(&self, query: &str, params: &[Value]) -> Result<Vec<HashMap<String, Value>>> {
120 use sqlx::Row;
121
122 let mut query_builder = sqlx::query(query);
126
127 for param in params {
129 query_builder = match param {
130 Value::String(s) => query_builder.bind(s),
131 Value::Number(n) => {
132 if let Some(i) = n.as_i64() {
133 query_builder.bind(i)
134 } else if let Some(f) = n.as_f64() {
135 query_builder.bind(f)
136 } else {
137 query_builder.bind(n.to_string())
138 }
139 }
140 Value::Bool(b) => query_builder.bind(*b),
141 Value::Null => query_builder.bind::<Option<String>>(None),
142 Value::Array(_) | Value::Object(_) => {
143 let json_str = serde_json::to_string(param).unwrap_or_default();
144 query_builder.bind(json_str)
145 }
146 };
147 }
148
149 let rows = query_builder
150 .fetch_all(&self.pool)
151 .await
152 .map_err(|e| Error::generic(format!("Query execution failed: {}", e)))?;
153
154 let mut results = Vec::new();
156 for row in rows {
157 let mut map = HashMap::new();
158 let columns = row.columns();
159 for (idx, column) in columns.iter().enumerate() {
160 let value = row_value_to_json(&row, idx)?;
161 map.insert(column.name().to_string(), value);
162 }
163 results.push(map);
164 }
165
166 Ok(results)
167 }
168
169 async fn execute(&self, query: &str, params: &[Value]) -> Result<u64> {
170 let mut query_builder = sqlx::query(query);
172
173 for param in params {
175 query_builder = match param {
176 Value::String(s) => query_builder.bind(s),
177 Value::Number(n) => {
178 if let Some(i) = n.as_i64() {
179 query_builder.bind(i)
180 } else if let Some(f) = n.as_f64() {
181 query_builder.bind(f)
182 } else {
183 query_builder.bind(n.to_string())
184 }
185 }
186 Value::Bool(b) => query_builder.bind(*b),
187 Value::Null => query_builder.bind::<Option<String>>(None),
188 Value::Array(_) | Value::Object(_) => {
189 let json_str = serde_json::to_string(param).unwrap_or_default();
190 query_builder.bind(json_str)
191 }
192 };
193 }
194
195 let result = query_builder
196 .execute(&self.pool)
197 .await
198 .map_err(|e| Error::generic(format!("Execute failed: {}", e)))?;
199
200 Ok(result.rows_affected())
201 }
202
203 async fn execute_with_id(&self, query: &str, params: &[Value]) -> Result<String> {
204 let mut query_builder = sqlx::query(query);
206
207 for param in params {
209 query_builder = match param {
210 Value::String(s) => query_builder.bind(s),
211 Value::Number(n) => {
212 if let Some(i) = n.as_i64() {
213 query_builder.bind(i)
214 } else if let Some(f) = n.as_f64() {
215 query_builder.bind(f)
216 } else {
217 query_builder.bind(n.to_string())
218 }
219 }
220 Value::Bool(b) => query_builder.bind(*b),
221 Value::Null => query_builder.bind::<Option<String>>(None),
222 Value::Array(_) | Value::Object(_) => {
223 let json_str = serde_json::to_string(param).unwrap_or_default();
224 query_builder.bind(json_str)
225 }
226 };
227 }
228
229 let result = query_builder
230 .execute(&self.pool)
231 .await
232 .map_err(|e| Error::generic(format!("Execute failed: {}", e)))?;
233
234 let last_id = result.last_insert_rowid();
236 Ok(last_id.to_string())
237 }
238
239 async fn table_exists(&self, table_name: &str) -> Result<bool> {
240 let query = "SELECT name FROM sqlite_master WHERE type='table' AND name=?";
241 let result = sqlx::query_scalar::<_, String>(query)
242 .bind(table_name)
243 .fetch_optional(&self.pool)
244 .await
245 .map_err(|e| Error::generic(format!("Failed to check table existence: {}", e)))?;
246
247 Ok(result.is_some())
248 }
249
250 async fn create_table(&self, create_statement: &str) -> Result<()> {
251 sqlx::query(create_statement)
252 .execute(&self.pool)
253 .await
254 .map_err(|e| Error::generic(format!("Failed to create table: {}", e)))?;
255
256 Ok(())
257 }
258
259 fn connection_info(&self) -> String {
260 format!("SQLite: {}", self.path.display())
261 }
262
263 async fn close(&mut self) -> Result<()> {
264 self.pool.close().await;
265 Ok(())
266 }
267}
268
269fn row_value_to_json(row: &sqlx::sqlite::SqliteRow, idx: usize) -> Result<Value> {
271 use sqlx::Row;
272
273 if let Ok(value) = row.try_get::<String, _>(idx) {
275 return Ok(Value::String(value));
276 }
277 if let Ok(value) = row.try_get::<i64, _>(idx) {
278 return Ok(Value::Number(value.into()));
279 }
280 if let Ok(value) = row.try_get::<f64, _>(idx) {
281 if let Some(n) = serde_json::Number::from_f64(value) {
282 return Ok(Value::Number(n));
283 }
284 }
285 if let Ok(value) = row.try_get::<bool, _>(idx) {
286 return Ok(Value::Bool(value));
287 }
288 if let Ok(value) = row.try_get::<Option<String>, _>(idx) {
289 return Ok(value.map(Value::String).unwrap_or(Value::Null));
290 }
291
292 Ok(Value::String(row.get::<String, _>(idx)))
294}
295
296pub struct JsonDatabase {
298 path: std::path::PathBuf,
299 data: Arc<RwLock<HashMap<String, Vec<HashMap<String, Value>>>>>,
300}
301
302impl JsonDatabase {
303 pub async fn new<P: AsRef<std::path::Path>>(path: P) -> Result<Self> {
305 let path = path.as_ref().to_path_buf();
306
307 let data = if path.exists() {
309 let content = tokio::fs::read_to_string(&path)
310 .await
311 .map_err(|e| Error::generic(format!("Failed to read JSON database: {}", e)))?;
312 serde_json::from_str(&content).unwrap_or_default()
313 } else {
314 HashMap::new()
315 };
316
317 Ok(Self {
318 path,
319 data: Arc::new(RwLock::new(data)),
320 })
321 }
322
323 async fn save(&self) -> Result<()> {
325 let data = self.data.read().await;
326
327 if let Some(parent) = self.path.parent() {
329 tokio::fs::create_dir_all(parent).await.map_err(|e| {
330 Error::generic(format!("Failed to create database directory: {}", e))
331 })?;
332 }
333
334 let content = serde_json::to_string_pretty(&*data)
336 .map_err(|e| Error::generic(format!("Failed to serialize JSON database: {}", e)))?;
337
338 tokio::fs::write(&self.path, content)
339 .await
340 .map_err(|e| Error::generic(format!("Failed to write JSON database: {}", e)))?;
341
342 Ok(())
343 }
344}
345
346#[async_trait]
347impl VirtualDatabase for JsonDatabase {
348 async fn initialize(&mut self) -> Result<()> {
349 Ok(())
351 }
352
353 async fn query(&self, query: &str, params: &[Value]) -> Result<Vec<HashMap<String, Value>>> {
354 let data = self.data.read().await;
357 let query_upper = query.trim().to_uppercase();
358
359 if query_upper.contains("COUNT(*)") || query_upper.contains("COUNT( * )") {
361 let table_name = extract_table_name_from_select(query)?;
362 if let Some(records) = data.get(table_name) {
363 let count = if query.contains("WHERE") {
364 apply_json_where_clause(records, query, params)?.len()
365 } else {
366 records.len()
367 };
368 let mut result = HashMap::new();
369 result.insert("count".to_string(), Value::Number(count.into()));
371 return Ok(vec![result]);
372 }
373 } else if query_upper.starts_with("SELECT") {
374 let table_name = extract_table_name_from_select(query)?;
376
377 if let Some(records) = data.get(table_name) {
378 let filtered = if query.contains("WHERE") {
380 apply_json_where_clause(records, query, params)?
381 } else {
382 records.clone()
383 };
384
385 let result = apply_json_pagination(&filtered, query)?;
387 return Ok(result);
388 }
389 } else if query_upper.starts_with("COUNT") {
390 let table_name = extract_table_name_from_count(query)?;
392 if let Some(records) = data.get(table_name) {
393 let count = if query.contains("WHERE") {
394 apply_json_where_clause(records, query, params)?.len()
395 } else {
396 records.len()
397 };
398 let mut result = HashMap::new();
399 result.insert("total".to_string(), Value::Number(count.into()));
400 return Ok(vec![result]);
401 }
402 }
403
404 Ok(vec![])
405 }
406
407 async fn execute(&self, query: &str, params: &[Value]) -> Result<u64> {
408 let query_upper = query.trim().to_uppercase();
410
411 if query_upper.starts_with("INSERT") {
412 {
413 let mut data = self.data.write().await;
414 let (table_name, record) = parse_insert_query(query, params)?;
415 let records = data.entry(table_name).or_insert_with(Vec::new);
416 records.push(record);
417 } self.save().await?;
419 Ok(1)
420 } else if query_upper.starts_with("UPDATE") {
421 let updated = {
422 let mut data = self.data.write().await;
423 let (table_name, updates, where_clause, where_params) =
424 parse_update_query(query, params)?;
425 if let Some(records) = data.get_mut(&table_name) {
426 let mut updated = 0;
427 for record in records.iter_mut() {
428 if matches_json_where(record, &where_clause, &where_params)? {
429 record.extend(updates.clone());
430 updated += 1;
431 }
432 }
433 updated
434 } else {
435 0
436 }
437 }; if updated > 0 {
439 self.save().await?;
440 }
441 Ok(updated)
442 } else if query_upper.starts_with("DELETE") {
443 let deleted = {
444 let mut data = self.data.write().await;
445 let (table_name, where_clause, where_params) = parse_delete_query(query, params)?;
446 if let Some(records) = data.get_mut(&table_name) {
447 let initial_len = records.len();
448 records.retain(|record| {
449 !matches_json_where(record, &where_clause, &where_params).unwrap_or(false)
450 });
451 (initial_len - records.len()) as u64
452 } else {
453 0
454 }
455 }; if deleted > 0 {
457 self.save().await?;
458 }
459 Ok(deleted)
460 } else {
461 Ok(0)
462 }
463 }
464
465 async fn execute_with_id(&self, query: &str, params: &[Value]) -> Result<String> {
466 if query.trim().to_uppercase().starts_with("INSERT") {
468 let id = {
469 let mut data = self.data.write().await;
470 let (table_name, mut record) = parse_insert_query(query, params)?;
471
472 if !record.contains_key("id") {
474 use uuid::Uuid;
475 record.insert("id".to_string(), Value::String(Uuid::new_v4().to_string()));
476 }
477
478 let id = record.get("id").and_then(|v| v.as_str()).unwrap_or("").to_string();
479
480 let records = data.entry(table_name).or_insert_with(Vec::new);
481 records.push(record);
482 id
483 }; self.save().await?;
485 Ok(id)
486 } else {
487 self.execute(query, params).await?;
488 Ok(String::new())
489 }
490 }
491
492 async fn table_exists(&self, table_name: &str) -> Result<bool> {
493 let data = self.data.read().await;
494 Ok(data.contains_key(table_name))
495 }
496
497 async fn create_table(&self, _create_statement: &str) -> Result<()> {
498 Ok(())
500 }
501
502 fn connection_info(&self) -> String {
503 format!("JSON: {}", self.path.display())
504 }
505
506 async fn close(&mut self) -> Result<()> {
507 self.save().await
508 }
509}
510
511pub struct InMemoryDatabase {
513 data: Arc<RwLock<HashMap<String, Vec<HashMap<String, Value>>>>>,
514}
515
516impl InMemoryDatabase {
517 pub async fn new() -> Result<Self> {
519 Ok(Self {
520 data: Arc::new(RwLock::new(HashMap::new())),
521 })
522 }
523}
524
525#[async_trait]
526impl VirtualDatabase for InMemoryDatabase {
527 async fn initialize(&mut self) -> Result<()> {
528 Ok(())
530 }
531
532 async fn query(&self, query: &str, params: &[Value]) -> Result<Vec<HashMap<String, Value>>> {
533 let data = self.data.read().await;
535 let query_upper = query.trim().to_uppercase();
536
537 if query_upper.contains("COUNT(*)") || query_upper.contains("COUNT( * )") {
539 let table_name = extract_table_name_from_select(query)?;
540 let count = if let Some(records) = data.get(table_name) {
541 if query.contains("WHERE") {
542 apply_json_where_clause(records, query, params)?.len()
543 } else {
544 records.len()
545 }
546 } else {
547 0
549 };
550 let mut result = HashMap::new();
551 result.insert("count".to_string(), Value::Number(count.into()));
552 return Ok(vec![result]);
553 } else if query_upper.starts_with("SELECT") {
554 let table_name = extract_table_name_from_select(query)?;
555
556 if let Some(records) = data.get(table_name) {
557 let filtered = if query.contains("WHERE") {
558 apply_json_where_clause(records, query, params)?
559 } else {
560 records.clone()
561 };
562
563 let result = apply_json_pagination(&filtered, query)?;
564 return Ok(result);
565 }
566 } else if query_upper.starts_with("COUNT") {
567 let table_name = extract_table_name_from_count(query)?;
568 if let Some(records) = data.get(table_name) {
569 let count = if query.contains("WHERE") {
570 apply_json_where_clause(records, query, params)?.len()
571 } else {
572 records.len()
573 };
574 let mut result = HashMap::new();
575 result.insert("total".to_string(), Value::Number(count.into()));
576 return Ok(vec![result]);
577 }
578 }
579
580 Ok(vec![])
581 }
582
583 async fn execute(&self, query: &str, params: &[Value]) -> Result<u64> {
584 let mut data = self.data.write().await;
585
586 let query_upper = query.trim().to_uppercase();
587
588 if query_upper.starts_with("INSERT") {
589 let (table_name, record) = parse_insert_query(query, params)?;
590 let records = data.entry(table_name).or_insert_with(Vec::new);
591 records.push(record);
592 Ok(1)
593 } else if query_upper.starts_with("UPDATE") {
594 let (table_name, updates, where_clause, where_params) =
595 parse_update_query(query, params)?;
596 if let Some(records) = data.get_mut(&table_name) {
597 let mut updated = 0;
598 for record in records.iter_mut() {
599 if matches_json_where(record, &where_clause, &where_params)? {
600 record.extend(updates.clone());
601 updated += 1;
602 }
603 }
604 Ok(updated)
605 } else {
606 Ok(0)
607 }
608 } else if query_upper.starts_with("DELETE") {
609 let (table_name, where_clause, where_params) = parse_delete_query(query, params)?;
610 let records = data.entry(table_name.clone()).or_insert_with(Vec::new);
612 let initial_len = records.len();
613 records.retain(|record| {
614 !matches_json_where(record, &where_clause, &where_params).unwrap_or(false)
615 });
616 let deleted = initial_len - records.len();
617 Ok(deleted as u64)
618 } else {
619 Ok(0)
620 }
621 }
622
623 async fn execute_with_id(&self, query: &str, params: &[Value]) -> Result<String> {
624 let mut data = self.data.write().await;
625
626 if query.trim().to_uppercase().starts_with("INSERT") {
627 let (table_name, mut record) = parse_insert_query(query, params)?;
628
629 if !record.contains_key("id") {
630 use uuid::Uuid;
631 record.insert("id".to_string(), Value::String(Uuid::new_v4().to_string()));
632 }
633
634 let id = record.get("id").and_then(|v| v.as_str()).unwrap_or("").to_string();
635
636 let records = data.entry(table_name).or_insert_with(Vec::new);
637 records.push(record);
638 Ok(id)
639 } else {
640 self.execute(query, params).await?;
641 Ok(String::new())
642 }
643 }
644
645 async fn table_exists(&self, table_name: &str) -> Result<bool> {
646 let data = self.data.read().await;
647 Ok(data.contains_key(table_name))
648 }
649
650 async fn create_table(&self, create_statement: &str) -> Result<()> {
651 let query_upper = create_statement.to_uppercase();
656 if query_upper.contains("CREATE TABLE") {
657 let mut rest = create_statement;
658
659 if let Some(idx) = query_upper.find("CREATE TABLE") {
661 rest = &create_statement[idx + 12..];
662 }
663
664 let rest_upper = rest.to_uppercase();
666 if rest_upper.trim_start().starts_with("IF NOT EXISTS") {
667 if let Some(idx) = rest_upper.find("IF NOT EXISTS") {
668 rest = &rest[idx + 13..];
669 }
670 }
671
672 let table_name = rest
674 .trim_start()
675 .split(|c: char| c == '(' || c.is_whitespace())
676 .next()
677 .unwrap_or("")
678 .trim()
679 .to_string();
680
681 if !table_name.is_empty() {
682 let mut data = self.data.write().await;
683 data.entry(table_name).or_insert_with(Vec::new);
684 }
685 }
686 Ok(())
687 }
688
689 fn connection_info(&self) -> String {
690 "In-Memory".to_string()
691 }
692
693 async fn close(&mut self) -> Result<()> {
694 Ok(())
696 }
697}
698
699fn extract_table_name_from_select(query: &str) -> Result<&str> {
703 let parts: Vec<&str> = query.split_whitespace().collect();
705 if let Some(from_idx) = parts.iter().position(|&p| p.to_uppercase() == "FROM") {
706 if from_idx + 1 < parts.len() {
707 let table_name = parts[from_idx + 1].trim_end_matches(';');
708 return Ok(table_name);
709 }
710 }
711 Err(Error::generic("Invalid SELECT query: missing FROM clause".to_string()))
712}
713
714fn extract_table_name_from_count(query: &str) -> Result<&str> {
716 extract_table_name_from_select(query)
718}
719
720fn apply_json_where_clause(
722 records: &[HashMap<String, Value>],
723 query: &str,
724 params: &[Value],
725) -> Result<Vec<HashMap<String, Value>>> {
726 let mut result = Vec::new();
728
729 for record in records {
730 if matches_json_where(record, query, params)? {
731 result.push(record.clone());
732 }
733 }
734
735 Ok(result)
736}
737
738fn matches_json_where(
740 record: &HashMap<String, Value>,
741 query: &str,
742 params: &[Value],
743) -> Result<bool> {
744 if let Some(where_idx) = query.to_uppercase().find("WHERE") {
746 let where_clause = &query[where_idx + 5..];
747
748 let conditions: Vec<&str> = where_clause.split(" AND ").collect();
750 let mut param_index = 0;
751
752 for condition in conditions {
753 let parts: Vec<&str> = condition.split_whitespace().collect();
754
755 if parts.len() >= 3 {
756 let field = parts[0];
757 let operator = parts[1];
758
759 if parts.iter().any(|&p| p == "?") && param_index < params.len() {
760 let expected_value = ¶ms[param_index];
761 let actual_value = record.get(field);
762 param_index += 1;
763
764 let matches = match operator {
765 "=" => matches_value(actual_value, expected_value),
766 "!=" => !matches_value(actual_value, expected_value),
767 _ => true, };
769
770 if !matches {
771 return Ok(false);
772 }
773 }
774 }
775 }
776
777 return Ok(true); }
779
780 Ok(true) }
782
783fn matches_value(actual: Option<&Value>, expected: &Value) -> bool {
785 match (actual, expected) {
786 (Some(a), e) => a == e,
787 (None, Value::Null) => true,
788 _ => false,
789 }
790}
791
792fn apply_json_pagination(
794 records: &[HashMap<String, Value>],
795 query: &str,
796) -> Result<Vec<HashMap<String, Value>>> {
797 let mut result = records.to_vec();
798
799 if let Some(limit_idx) = query.to_uppercase().find("LIMIT") {
801 let limit_str = query[limit_idx + 5..]
802 .split_whitespace()
803 .next()
804 .unwrap_or("")
805 .trim_end_matches(';');
806
807 if let Ok(limit) = limit_str.parse::<usize>() {
808 let offset = if let Some(offset_idx) = query.to_uppercase().find("OFFSET") {
810 query[offset_idx + 6..]
811 .split_whitespace()
812 .next()
813 .unwrap_or("0")
814 .trim_end_matches(';')
815 .parse::<usize>()
816 .unwrap_or(0)
817 } else {
818 0
819 };
820
821 let start = offset.min(result.len());
822 let end = (start + limit).min(result.len());
823 result = result[start..end].to_vec();
824 }
825 }
826
827 Ok(result)
828}
829
830fn parse_insert_query(query: &str, params: &[Value]) -> Result<(String, HashMap<String, Value>)> {
832 let parts: Vec<&str> = query.split_whitespace().collect();
834
835 if let Some(into_idx) = parts.iter().position(|&p| p.to_uppercase() == "INTO") {
836 if into_idx + 1 < parts.len() {
837 let table_name = parts[into_idx + 1].to_string();
838
839 if let Some(fields_start) = query.find('(') {
841 if let Some(fields_end) = query[fields_start + 1..].find(')') {
842 let fields_str = &query[fields_start + 1..fields_start + 1 + fields_end];
843 let fields: Vec<&str> = fields_str.split(',').map(|s| s.trim()).collect();
844
845 let mut record = HashMap::new();
847 for (idx, field) in fields.iter().enumerate() {
848 if idx < params.len() {
849 record.insert(field.to_string(), params[idx].clone());
850 }
851 }
852
853 return Ok((table_name, record));
854 }
855 }
856 }
857 }
858
859 Err(Error::generic("Invalid INSERT query format".to_string()))
860}
861
862fn parse_update_query(
864 query: &str,
865 params: &[Value],
866) -> Result<(String, HashMap<String, Value>, String, Vec<Value>)> {
867 let parts: Vec<&str> = query.split_whitespace().collect();
869
870 if parts.len() < 4 || parts[0].to_uppercase() != "UPDATE" {
871 return Err(Error::generic("Invalid UPDATE query".to_string()));
872 }
873
874 let table_name = parts[1].to_string();
875
876 if let Some(set_idx) = parts.iter().position(|&p| p.to_uppercase() == "SET") {
878 let set_clause = &query[query.to_uppercase().find("SET").unwrap() + 3..];
879 let where_clause = if let Some(where_idx) = set_clause.to_uppercase().find("WHERE") {
880 &set_clause[..where_idx]
881 } else {
882 set_clause
883 };
884
885 let mut updates = HashMap::new();
887 let set_parts: Vec<&str> = where_clause.split(',').collect();
888 let mut param_idx = 0;
889
890 for part in set_parts {
891 let field_eq: Vec<&str> = part.split('=').map(|s| s.trim()).collect();
892 if field_eq.len() == 2 && field_eq[1] == "?" && param_idx < params.len() {
893 updates.insert(field_eq[0].to_string(), params[param_idx].clone());
894 param_idx += 1;
895 }
896 }
897
898 let (where_clause_str, where_params) =
900 if let Some(where_idx) = set_clause.to_uppercase().find("WHERE") {
901 let where_part = &set_clause[where_idx + 5..];
902 (where_part.to_string(), params[param_idx..].to_vec())
903 } else {
904 (String::new(), Vec::new())
905 };
906
907 return Ok((table_name, updates, where_clause_str, where_params));
908 }
909
910 Err(Error::generic("Invalid UPDATE query: missing SET clause".to_string()))
911}
912
913fn parse_delete_query(query: &str, params: &[Value]) -> Result<(String, String, Vec<Value>)> {
915 let parts: Vec<&str> = query.split_whitespace().collect();
917
918 if let Some(from_idx) = parts.iter().position(|&p| p.to_uppercase() == "FROM") {
919 if from_idx + 1 < parts.len() {
920 let table_name = parts[from_idx + 1].to_string();
921
922 if let Some(where_idx) = query.to_uppercase().find("WHERE") {
924 let where_clause = query[where_idx + 5..].to_string();
925 return Ok((table_name, where_clause, params.to_vec()));
926 } else {
927 return Ok((table_name, String::new(), Vec::new()));
928 }
929 }
930 }
931
932 Err(Error::generic("Invalid DELETE query".to_string()))
933}
934
935#[cfg(test)]
936mod tests {
937 use super::*;
938 use crate::config::StorageBackend;
939
940 async fn create_test_table(db: &dyn VirtualDatabase) -> Result<()> {
942 let create_sql = "CREATE TABLE IF NOT EXISTS test_users (
943 id TEXT PRIMARY KEY,
944 name TEXT NOT NULL,
945 email TEXT,
946 age INTEGER
947 )";
948 db.create_table(create_sql).await
949 }
950
951 #[tokio::test]
953 async fn test_sqlite_database_creation() {
954 let temp_dir = tempfile::tempdir().unwrap();
955 let db_path = temp_dir.path().join("test.db");
956 let result = SqliteDatabase::new(&db_path).await;
957 assert!(result.is_ok());
958 }
959
960 #[tokio::test]
961 async fn test_sqlite_database_connection_info() {
962 let temp_dir = tempfile::tempdir().unwrap();
963 let db_path = temp_dir.path().join("test.db");
964 let db = SqliteDatabase::new(&db_path).await.unwrap();
965 let info = db.connection_info();
966 assert!(info.contains("SQLite"));
967 assert!(info.contains("test.db"));
968 }
969
970 #[tokio::test]
971 async fn test_sqlite_database_initialize() {
972 let temp_dir = tempfile::tempdir().unwrap();
973 let db_path = temp_dir.path().join("test.db");
974 let mut db = SqliteDatabase::new(&db_path).await.unwrap();
975 let result = db.initialize().await;
976 assert!(result.is_ok());
977 }
978
979 #[tokio::test]
980 async fn test_sqlite_create_table() {
981 let temp_dir = tempfile::tempdir().unwrap();
982 let db_path = temp_dir.path().join("test.db");
983 let db = SqliteDatabase::new(&db_path).await.unwrap();
984 let result = create_test_table(&db).await;
985 assert!(result.is_ok());
986 }
987
988 #[tokio::test]
989 async fn test_sqlite_table_exists() {
990 let temp_dir = tempfile::tempdir().unwrap();
991 let db_path = temp_dir.path().join("test.db");
992 let db = SqliteDatabase::new(&db_path).await.unwrap();
993 create_test_table(&db).await.unwrap();
994
995 let exists = db.table_exists("test_users").await.unwrap();
996 assert!(exists);
997
998 let not_exists = db.table_exists("nonexistent_table").await.unwrap();
999 assert!(!not_exists);
1000 }
1001
1002 #[tokio::test]
1003 async fn test_sqlite_execute_insert() {
1004 let temp_dir = tempfile::tempdir().unwrap();
1005 let db_path = temp_dir.path().join("test.db");
1006 let db = SqliteDatabase::new(&db_path).await.unwrap();
1007 create_test_table(&db).await.unwrap();
1008
1009 let query = "INSERT INTO test_users (id, name, email, age) VALUES (?, ?, ?, ?)";
1010 let params = vec![
1011 Value::String("1".to_string()),
1012 Value::String("John Doe".to_string()),
1013 Value::String("john@example.com".to_string()),
1014 Value::Number(30.into()),
1015 ];
1016
1017 let result = db.execute(query, ¶ms).await;
1018 assert!(result.is_ok());
1019 assert_eq!(result.unwrap(), 1);
1020 }
1021
1022 #[tokio::test]
1023 async fn test_sqlite_execute_with_id() {
1024 let temp_dir = tempfile::tempdir().unwrap();
1025 let db_path = temp_dir.path().join("test.db");
1026 let db = SqliteDatabase::new(&db_path).await.unwrap();
1027 create_test_table(&db).await.unwrap();
1028
1029 let query = "INSERT INTO test_users (id, name, email) VALUES (?, ?, ?)";
1030 let params = vec![
1031 Value::String("test-id".to_string()),
1032 Value::String("Jane Doe".to_string()),
1033 Value::String("jane@example.com".to_string()),
1034 ];
1035
1036 let result = db.execute_with_id(query, ¶ms).await;
1037 assert!(result.is_ok());
1038 }
1039
1040 #[tokio::test]
1041 async fn test_sqlite_query_select() {
1042 let temp_dir = tempfile::tempdir().unwrap();
1043 let db_path = temp_dir.path().join("test.db");
1044 let db = SqliteDatabase::new(&db_path).await.unwrap();
1045 create_test_table(&db).await.unwrap();
1046
1047 let insert_query = "INSERT INTO test_users (id, name, email) VALUES (?, ?, ?)";
1049 db.execute(
1050 insert_query,
1051 &[
1052 Value::String("1".to_string()),
1053 Value::String("Test User".to_string()),
1054 Value::String("test@example.com".to_string()),
1055 ],
1056 )
1057 .await
1058 .unwrap();
1059
1060 let select_query = "SELECT * FROM test_users WHERE id = ?";
1062 let results = db.query(select_query, &[Value::String("1".to_string())]).await;
1063 assert!(results.is_ok());
1064 let rows = results.unwrap();
1065 assert_eq!(rows.len(), 1);
1066 assert_eq!(rows[0].get("id").unwrap().as_str().unwrap(), "1");
1067 assert_eq!(rows[0].get("name").unwrap().as_str().unwrap(), "Test User");
1068 }
1069
1070 #[tokio::test]
1071 async fn test_sqlite_execute_update() {
1072 let temp_dir = tempfile::tempdir().unwrap();
1073 let db_path = temp_dir.path().join("test.db");
1074 let db = SqliteDatabase::new(&db_path).await.unwrap();
1075 create_test_table(&db).await.unwrap();
1076
1077 db.execute(
1079 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1080 &[
1081 Value::String("1".to_string()),
1082 Value::String("Original Name".to_string()),
1083 ],
1084 )
1085 .await
1086 .unwrap();
1087
1088 let update_result = db
1090 .execute(
1091 "UPDATE test_users SET name = ? WHERE id = ?",
1092 &[
1093 Value::String("Updated Name".to_string()),
1094 Value::String("1".to_string()),
1095 ],
1096 )
1097 .await;
1098
1099 assert!(update_result.is_ok());
1100 assert_eq!(update_result.unwrap(), 1);
1101
1102 let rows = db
1104 .query("SELECT name FROM test_users WHERE id = ?", &[Value::String("1".to_string())])
1105 .await
1106 .unwrap();
1107 assert_eq!(rows[0].get("name").unwrap().as_str().unwrap(), "Updated Name");
1108 }
1109
1110 #[tokio::test]
1111 async fn test_sqlite_execute_delete() {
1112 let temp_dir = tempfile::tempdir().unwrap();
1113 let db_path = temp_dir.path().join("test.db");
1114 let db = SqliteDatabase::new(&db_path).await.unwrap();
1115 create_test_table(&db).await.unwrap();
1116
1117 db.execute(
1119 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1120 &[
1121 Value::String("1".to_string()),
1122 Value::String("Test".to_string()),
1123 ],
1124 )
1125 .await
1126 .unwrap();
1127
1128 let delete_result = db
1130 .execute("DELETE FROM test_users WHERE id = ?", &[Value::String("1".to_string())])
1131 .await;
1132 assert!(delete_result.is_ok());
1133 assert_eq!(delete_result.unwrap(), 1);
1134
1135 let rows = db
1137 .query("SELECT * FROM test_users WHERE id = ?", &[Value::String("1".to_string())])
1138 .await
1139 .unwrap();
1140 assert_eq!(rows.len(), 0);
1141 }
1142
1143 #[tokio::test]
1144 async fn test_sqlite_close() {
1145 let temp_dir = tempfile::tempdir().unwrap();
1146 let db_path = temp_dir.path().join("test.db");
1147 let mut db = SqliteDatabase::new(&db_path).await.unwrap();
1148 let result = db.close().await;
1149 assert!(result.is_ok());
1150 }
1151
1152 #[tokio::test]
1154 async fn test_json_database_creation() {
1155 let temp_dir = tempfile::tempdir().unwrap();
1156 let db_path = temp_dir.path().join("test.json");
1157 let result = JsonDatabase::new(&db_path).await;
1158 assert!(result.is_ok());
1159 }
1160
1161 #[tokio::test]
1162 async fn test_json_database_connection_info() {
1163 let temp_dir = tempfile::tempdir().unwrap();
1164 let db_path = temp_dir.path().join("test.json");
1165 let db = JsonDatabase::new(&db_path).await.unwrap();
1166 let info = db.connection_info();
1167 assert!(info.contains("JSON"));
1168 assert!(info.contains("test.json"));
1169 }
1170
1171 #[tokio::test]
1172 async fn test_json_database_initialize() {
1173 let temp_dir = tempfile::tempdir().unwrap();
1174 let db_path = temp_dir.path().join("test.json");
1175 let mut db = JsonDatabase::new(&db_path).await.unwrap();
1176 let result = db.initialize().await;
1177 assert!(result.is_ok());
1178 }
1179
1180 #[tokio::test]
1181 async fn test_json_create_table() {
1182 let temp_dir = tempfile::tempdir().unwrap();
1183 let db_path = temp_dir.path().join("test.json");
1184 let db = JsonDatabase::new(&db_path).await.unwrap();
1185 let result = db.create_table("CREATE TABLE test_users (id TEXT, name TEXT)").await;
1186 assert!(result.is_ok());
1187 }
1188
1189 #[tokio::test]
1190 async fn test_json_table_exists() {
1191 let temp_dir = tempfile::tempdir().unwrap();
1192 let db_path = temp_dir.path().join("test.json");
1193 let db = JsonDatabase::new(&db_path).await.unwrap();
1194
1195 assert!(!db.table_exists("test_users").await.unwrap());
1197
1198 db.execute(
1200 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1201 &[
1202 Value::String("1".to_string()),
1203 Value::String("Test".to_string()),
1204 ],
1205 )
1206 .await
1207 .unwrap();
1208
1209 assert!(db.table_exists("test_users").await.unwrap());
1211 }
1212
1213 #[tokio::test]
1214 async fn test_json_execute_insert() {
1215 let temp_dir = tempfile::tempdir().unwrap();
1216 let db_path = temp_dir.path().join("test.json");
1217 let db = JsonDatabase::new(&db_path).await.unwrap();
1218
1219 let query = "INSERT INTO test_users (id, name, email) VALUES (?, ?, ?)";
1220 let params = vec![
1221 Value::String("1".to_string()),
1222 Value::String("John Doe".to_string()),
1223 Value::String("john@example.com".to_string()),
1224 ];
1225
1226 let result = db.execute(query, ¶ms).await;
1227 assert!(result.is_ok());
1228 assert_eq!(result.unwrap(), 1);
1229 }
1230
1231 #[tokio::test]
1232 async fn test_json_execute_with_id() {
1233 let temp_dir = tempfile::tempdir().unwrap();
1234 let db_path = temp_dir.path().join("test.json");
1235 let db = JsonDatabase::new(&db_path).await.unwrap();
1236
1237 let query = "INSERT INTO test_users (name, email) VALUES (?, ?)";
1238 let params = vec![
1239 Value::String("Jane Doe".to_string()),
1240 Value::String("jane@example.com".to_string()),
1241 ];
1242
1243 let result = db.execute_with_id(query, ¶ms).await;
1244 assert!(result.is_ok());
1245 assert!(!result.unwrap().is_empty());
1247 }
1248
1249 #[tokio::test]
1250 async fn test_json_query_select() {
1251 let temp_dir = tempfile::tempdir().unwrap();
1252 let db_path = temp_dir.path().join("test.json");
1253 let db = JsonDatabase::new(&db_path).await.unwrap();
1254
1255 db.execute(
1257 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1258 &[
1259 Value::String("1".to_string()),
1260 Value::String("Test User".to_string()),
1261 ],
1262 )
1263 .await
1264 .unwrap();
1265
1266 let results = db
1268 .query("SELECT * FROM test_users WHERE id = ?", &[Value::String("1".to_string())])
1269 .await;
1270 assert!(results.is_ok());
1271 let rows = results.unwrap();
1272 assert_eq!(rows.len(), 1);
1273 assert_eq!(rows[0].get("id").unwrap().as_str().unwrap(), "1");
1274 }
1275
1276 #[tokio::test]
1277 async fn test_json_query_count() {
1278 let temp_dir = tempfile::tempdir().unwrap();
1279 let db_path = temp_dir.path().join("test.json");
1280 let db = JsonDatabase::new(&db_path).await.unwrap();
1281
1282 db.execute(
1284 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1285 &[
1286 Value::String("1".to_string()),
1287 Value::String("User 1".to_string()),
1288 ],
1289 )
1290 .await
1291 .unwrap();
1292 db.execute(
1293 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1294 &[
1295 Value::String("2".to_string()),
1296 Value::String("User 2".to_string()),
1297 ],
1298 )
1299 .await
1300 .unwrap();
1301
1302 let results = db.query("SELECT COUNT(*) FROM test_users", &[]).await;
1304 assert!(results.is_ok());
1305 let rows = results.unwrap();
1306 assert_eq!(rows.len(), 1);
1307 assert_eq!(rows[0].get("count").unwrap().as_u64().unwrap(), 2);
1308 }
1309
1310 #[tokio::test]
1311 async fn test_json_execute_update() {
1312 let temp_dir = tempfile::tempdir().unwrap();
1313 let db_path = temp_dir.path().join("test.json");
1314 let db = JsonDatabase::new(&db_path).await.unwrap();
1315
1316 db.execute(
1318 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1319 &[
1320 Value::String("1".to_string()),
1321 Value::String("Original".to_string()),
1322 ],
1323 )
1324 .await
1325 .unwrap();
1326
1327 let update_result = db
1329 .execute(
1330 "UPDATE test_users SET name = ? WHERE id = ?",
1331 &[
1332 Value::String("Updated".to_string()),
1333 Value::String("1".to_string()),
1334 ],
1335 )
1336 .await;
1337
1338 assert!(update_result.is_ok());
1339 assert_eq!(update_result.unwrap(), 1);
1340 }
1341
1342 #[tokio::test]
1343 async fn test_json_execute_delete() {
1344 let temp_dir = tempfile::tempdir().unwrap();
1345 let db_path = temp_dir.path().join("test.json");
1346 let db = JsonDatabase::new(&db_path).await.unwrap();
1347
1348 db.execute(
1350 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1351 &[
1352 Value::String("1".to_string()),
1353 Value::String("Test".to_string()),
1354 ],
1355 )
1356 .await
1357 .unwrap();
1358
1359 let delete_result = db
1361 .execute("DELETE FROM test_users WHERE id = ?", &[Value::String("1".to_string())])
1362 .await;
1363 assert!(delete_result.is_ok());
1364 assert_eq!(delete_result.unwrap(), 1);
1365 }
1366
1367 #[tokio::test]
1368 async fn test_json_close() {
1369 let temp_dir = tempfile::tempdir().unwrap();
1370 let db_path = temp_dir.path().join("test.json");
1371 let mut db = JsonDatabase::new(&db_path).await.unwrap();
1372 let result = db.close().await;
1373 assert!(result.is_ok());
1374 }
1375
1376 #[tokio::test]
1378 async fn test_inmemory_database_creation() {
1379 let result = InMemoryDatabase::new().await;
1380 assert!(result.is_ok());
1381 }
1382
1383 #[tokio::test]
1384 async fn test_inmemory_database_connection_info() {
1385 let db = InMemoryDatabase::new().await.unwrap();
1386 let info = db.connection_info();
1387 assert_eq!(info, "In-Memory");
1388 }
1389
1390 #[tokio::test]
1391 async fn test_inmemory_database_initialize() {
1392 let mut db = InMemoryDatabase::new().await.unwrap();
1393 let result = db.initialize().await;
1394 assert!(result.is_ok());
1395 }
1396
1397 #[tokio::test]
1398 async fn test_inmemory_create_table() {
1399 let db = InMemoryDatabase::new().await.unwrap();
1400 let result = db.create_table("CREATE TABLE test_users (id TEXT, name TEXT)").await;
1401 assert!(result.is_ok());
1402 }
1403
1404 #[tokio::test]
1405 async fn test_inmemory_table_exists() {
1406 let db = InMemoryDatabase::new().await.unwrap();
1407
1408 db.create_table("CREATE TABLE test_users (id TEXT)").await.unwrap();
1410
1411 assert!(db.table_exists("test_users").await.unwrap());
1413 assert!(!db.table_exists("nonexistent").await.unwrap());
1414 }
1415
1416 #[tokio::test]
1417 async fn test_inmemory_execute_insert() {
1418 let db = InMemoryDatabase::new().await.unwrap();
1419
1420 let query = "INSERT INTO test_users (id, name) VALUES (?, ?)";
1421 let params = vec![
1422 Value::String("1".to_string()),
1423 Value::String("John Doe".to_string()),
1424 ];
1425
1426 let result = db.execute(query, ¶ms).await;
1427 assert!(result.is_ok());
1428 assert_eq!(result.unwrap(), 1);
1429 }
1430
1431 #[tokio::test]
1432 async fn test_inmemory_execute_with_id() {
1433 let db = InMemoryDatabase::new().await.unwrap();
1434
1435 let query = "INSERT INTO test_users (name) VALUES (?)";
1436 let params = vec![Value::String("Jane Doe".to_string())];
1437
1438 let result = db.execute_with_id(query, ¶ms).await;
1439 assert!(result.is_ok());
1440 assert!(!result.unwrap().is_empty());
1441 }
1442
1443 #[tokio::test]
1444 async fn test_inmemory_query_select() {
1445 let db = InMemoryDatabase::new().await.unwrap();
1446
1447 db.execute(
1449 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1450 &[
1451 Value::String("1".to_string()),
1452 Value::String("Test User".to_string()),
1453 ],
1454 )
1455 .await
1456 .unwrap();
1457
1458 let results = db
1460 .query("SELECT * FROM test_users WHERE id = ?", &[Value::String("1".to_string())])
1461 .await;
1462 assert!(results.is_ok());
1463 let rows = results.unwrap();
1464 assert_eq!(rows.len(), 1);
1465 }
1466
1467 #[tokio::test]
1468 async fn test_inmemory_query_count() {
1469 let db = InMemoryDatabase::new().await.unwrap();
1470
1471 db.execute(
1473 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1474 &[
1475 Value::String("1".to_string()),
1476 Value::String("User 1".to_string()),
1477 ],
1478 )
1479 .await
1480 .unwrap();
1481 db.execute(
1482 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1483 &[
1484 Value::String("2".to_string()),
1485 Value::String("User 2".to_string()),
1486 ],
1487 )
1488 .await
1489 .unwrap();
1490
1491 let results = db.query("SELECT COUNT(*) FROM test_users", &[]).await;
1493 assert!(results.is_ok());
1494 let rows = results.unwrap();
1495 assert_eq!(rows[0].get("count").unwrap().as_u64().unwrap(), 2);
1496 }
1497
1498 #[tokio::test]
1499 async fn test_inmemory_execute_update() {
1500 let db = InMemoryDatabase::new().await.unwrap();
1501
1502 db.execute(
1504 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1505 &[
1506 Value::String("1".to_string()),
1507 Value::String("Original".to_string()),
1508 ],
1509 )
1510 .await
1511 .unwrap();
1512
1513 let result = db
1515 .execute(
1516 "UPDATE test_users SET name = ? WHERE id = ?",
1517 &[
1518 Value::String("Updated".to_string()),
1519 Value::String("1".to_string()),
1520 ],
1521 )
1522 .await;
1523
1524 assert!(result.is_ok());
1525 assert_eq!(result.unwrap(), 1);
1526 }
1527
1528 #[tokio::test]
1529 async fn test_inmemory_execute_delete() {
1530 let db = InMemoryDatabase::new().await.unwrap();
1531
1532 db.execute(
1534 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1535 &[
1536 Value::String("1".to_string()),
1537 Value::String("Test".to_string()),
1538 ],
1539 )
1540 .await
1541 .unwrap();
1542
1543 let result = db
1545 .execute("DELETE FROM test_users WHERE id = ?", &[Value::String("1".to_string())])
1546 .await;
1547 assert!(result.is_ok());
1548 assert_eq!(result.unwrap(), 1);
1549 }
1550
1551 #[tokio::test]
1552 async fn test_inmemory_close() {
1553 let mut db = InMemoryDatabase::new().await.unwrap();
1554 let result = db.close().await;
1555 assert!(result.is_ok());
1556 }
1557
1558 #[tokio::test]
1560 async fn test_create_database_sqlite() {
1561 let temp_dir = tempfile::tempdir().unwrap();
1562 let db_path = temp_dir.path().join("test.db");
1563 let backend = StorageBackend::Sqlite {
1564 path: db_path.clone(),
1565 };
1566 let result = create_database(&backend).await;
1567 assert!(result.is_ok());
1568 let db = result.unwrap();
1569 assert!(db.connection_info().contains("SQLite"));
1570 }
1571
1572 #[tokio::test]
1573 async fn test_create_database_json() {
1574 let temp_dir = tempfile::tempdir().unwrap();
1575 let db_path = temp_dir.path().join("test.json");
1576 let backend = StorageBackend::Json {
1577 path: db_path.clone(),
1578 };
1579 let result = create_database(&backend).await;
1580 assert!(result.is_ok());
1581 let db = result.unwrap();
1582 assert!(db.connection_info().contains("JSON"));
1583 }
1584
1585 #[tokio::test]
1586 async fn test_create_database_memory() {
1587 let backend = StorageBackend::Memory;
1588 let result = create_database(&backend).await;
1589 assert!(result.is_ok());
1590 let db = result.unwrap();
1591 assert_eq!(db.connection_info(), "In-Memory");
1592 }
1593
1594 #[test]
1596 fn test_extract_table_name_from_select() {
1597 let query = "SELECT * FROM users";
1598 let result = extract_table_name_from_select(query);
1599 assert!(result.is_ok());
1600 assert_eq!(result.unwrap(), "users");
1601 }
1602
1603 #[test]
1604 fn test_extract_table_name_from_select_with_where() {
1605 let query = "SELECT * FROM products WHERE price > 10";
1606 let result = extract_table_name_from_select(query);
1607 assert!(result.is_ok());
1608 assert_eq!(result.unwrap(), "products");
1609 }
1610
1611 #[test]
1612 fn test_extract_table_name_from_select_invalid() {
1613 let query = "SELECT * users";
1614 let result = extract_table_name_from_select(query);
1615 assert!(result.is_err());
1616 }
1617
1618 #[test]
1619 fn test_parse_insert_query() {
1620 let query = "INSERT INTO users (id, name) VALUES (?, ?)";
1621 let params = vec![
1622 Value::String("1".to_string()),
1623 Value::String("John".to_string()),
1624 ];
1625 let result = parse_insert_query(query, ¶ms);
1626 assert!(result.is_ok());
1627 let (table_name, record) = result.unwrap();
1628 assert_eq!(table_name, "users");
1629 assert_eq!(record.len(), 2);
1630 assert_eq!(record.get("id").unwrap().as_str().unwrap(), "1");
1631 }
1632
1633 #[test]
1634 fn test_parse_insert_query_invalid() {
1635 let query = "INSERT users VALUES (?)";
1636 let params = vec![Value::String("1".to_string())];
1637 let result = parse_insert_query(query, ¶ms);
1638 assert!(result.is_err());
1639 }
1640
1641 #[test]
1642 fn test_parse_update_query() {
1643 let query = "UPDATE users SET name = ? WHERE id = ?";
1644 let params = vec![
1645 Value::String("John".to_string()),
1646 Value::String("1".to_string()),
1647 ];
1648 let result = parse_update_query(query, ¶ms);
1649 assert!(result.is_ok());
1650 let (table_name, updates, _where_clause, _where_params) = result.unwrap();
1651 assert_eq!(table_name, "users");
1652 assert_eq!(updates.len(), 1);
1653 }
1654
1655 #[test]
1656 fn test_parse_delete_query() {
1657 let query = "DELETE FROM users WHERE id = ?";
1658 let params = vec![Value::String("1".to_string())];
1659 let result = parse_delete_query(query, ¶ms);
1660 assert!(result.is_ok());
1661 let (table_name, _where_clause, where_params) = result.unwrap();
1662 assert_eq!(table_name, "users");
1663 assert_eq!(where_params.len(), 1);
1664 }
1665
1666 #[test]
1667 fn test_matches_value() {
1668 assert!(matches_value(
1669 Some(&Value::String("test".to_string())),
1670 &Value::String("test".to_string())
1671 ));
1672 assert!(!matches_value(
1673 Some(&Value::String("test".to_string())),
1674 &Value::String("other".to_string())
1675 ));
1676 assert!(matches_value(None, &Value::Null));
1677 assert!(!matches_value(None, &Value::String("test".to_string())));
1678 }
1679
1680 #[tokio::test]
1681 async fn test_json_pagination() {
1682 let temp_dir = tempfile::tempdir().unwrap();
1683 let db_path = temp_dir.path().join("test.json");
1684 let db = JsonDatabase::new(&db_path).await.unwrap();
1685
1686 for i in 1..=5 {
1688 db.execute(
1689 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1690 &[
1691 Value::String(i.to_string()),
1692 Value::String(format!("User {}", i)),
1693 ],
1694 )
1695 .await
1696 .unwrap();
1697 }
1698
1699 let results = db.query("SELECT * FROM test_users LIMIT 2", &[]).await.unwrap();
1701 assert_eq!(results.len(), 2);
1702
1703 let results = db.query("SELECT * FROM test_users LIMIT 2 OFFSET 2", &[]).await.unwrap();
1705 assert_eq!(results.len(), 2);
1706 }
1707
1708 #[tokio::test]
1709 async fn test_inmemory_pagination() {
1710 let db = InMemoryDatabase::new().await.unwrap();
1711
1712 for i in 1..=5 {
1714 db.execute(
1715 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1716 &[
1717 Value::String(i.to_string()),
1718 Value::String(format!("User {}", i)),
1719 ],
1720 )
1721 .await
1722 .unwrap();
1723 }
1724
1725 let results = db.query("SELECT * FROM test_users LIMIT 2", &[]).await.unwrap();
1727 assert_eq!(results.len(), 2);
1728
1729 let results = db.query("SELECT * FROM test_users LIMIT 2 OFFSET 2", &[]).await.unwrap();
1731 assert_eq!(results.len(), 2);
1732 }
1733}