1use crate::{Error, Result};
8use async_trait::async_trait;
9use serde_json::Value;
10use sqlx::Column;
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<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 needs_save;
409 let result;
410
411 {
412 let mut data = self.data.write().await;
413
414 let query_upper = query.trim().to_uppercase();
416
417 if query_upper.starts_with("INSERT") {
418 let (table_name, record) = parse_insert_query(query, params)?;
419 let records = data.entry(table_name).or_insert_with(Vec::new);
420 records.push(record);
421 needs_save = true;
422 result = 1;
423 } else if query_upper.starts_with("UPDATE") {
424 let (table_name, updates, where_clause, where_params) =
425 parse_update_query(query, params)?;
426 if let Some(records) = data.get_mut(&table_name) {
427 let mut updated = 0;
428 for record in records.iter_mut() {
429 if matches_json_where(record, &where_clause, &where_params)? {
430 record.extend(updates.clone());
431 updated += 1;
432 }
433 }
434 needs_save = true;
435 result = updated;
436 } else {
437 needs_save = false;
438 result = 0;
439 }
440 } else if query_upper.starts_with("DELETE") {
441 let (table_name, where_clause, where_params) = parse_delete_query(query, params)?;
442 if let Some(records) = data.get_mut(&table_name) {
443 let initial_len = records.len();
444 records.retain(|record| {
445 !matches_json_where(record, &where_clause, &where_params).unwrap_or(false)
446 });
447 let deleted = initial_len - records.len();
448 needs_save = true;
449 result = deleted as u64;
450 } else {
451 needs_save = false;
452 result = 0;
453 }
454 } else {
455 needs_save = false;
456 result = 0;
457 }
458 } if needs_save {
461 self.save().await?;
462 }
463
464 Ok(result)
465 }
466
467 async fn execute_with_id(&self, query: &str, params: &[Value]) -> Result<String> {
468 if query.trim().to_uppercase().starts_with("INSERT") {
469 let id;
470 {
471 let mut data = self.data.write().await;
473 let (table_name, mut record) = parse_insert_query(query, params)?;
474
475 if !record.contains_key("id") {
477 use uuid::Uuid;
478 record.insert("id".to_string(), Value::String(Uuid::new_v4().to_string()));
479 }
480
481 id = record.get("id").and_then(|v| v.as_str()).unwrap_or("").to_string();
482
483 let records = data.entry(table_name).or_insert_with(Vec::new);
484 records.push(record);
485 } self.save().await?;
488 Ok(id)
489 } else {
490 self.execute(query, params).await?;
491 Ok(String::new())
492 }
493 }
494
495 async fn table_exists(&self, table_name: &str) -> Result<bool> {
496 let data = self.data.read().await;
497 Ok(data.contains_key(table_name))
498 }
499
500 async fn create_table(&self, _create_statement: &str) -> Result<()> {
501 Ok(())
503 }
504
505 fn connection_info(&self) -> String {
506 format!("JSON: {}", self.path.display())
507 }
508
509 async fn close(&mut self) -> Result<()> {
510 self.save().await
511 }
512}
513
514pub struct InMemoryDatabase {
516 data: Arc<RwLock<HashMap<String, Vec<HashMap<String, Value>>>>>,
517}
518
519impl InMemoryDatabase {
520 pub async fn new() -> Result<Self> {
522 Ok(Self {
523 data: Arc::new(RwLock::new(HashMap::new())),
524 })
525 }
526}
527
528#[async_trait]
529impl VirtualDatabase for InMemoryDatabase {
530 async fn initialize(&mut self) -> Result<()> {
531 Ok(())
533 }
534
535 async fn query(&self, query: &str, params: &[Value]) -> Result<Vec<HashMap<String, Value>>> {
536 let data = self.data.read().await;
538 let query_upper = query.trim().to_uppercase();
539
540 if query_upper.contains("COUNT(*)") || query_upper.contains("COUNT( * )") {
542 let table_name = extract_table_name_from_select(query)?;
543 let count = if let Some(records) = data.get(table_name) {
544 if query.contains("WHERE") {
545 apply_json_where_clause(records, query, params)?.len()
546 } else {
547 records.len()
548 }
549 } else {
550 0
552 };
553 let mut result = HashMap::new();
554 result.insert("count".to_string(), Value::Number(count.into()));
555 return Ok(vec![result]);
556 } else if query_upper.starts_with("SELECT") {
557 let table_name = extract_table_name_from_select(query)?;
558
559 if let Some(records) = data.get(table_name) {
560 let filtered = if query.contains("WHERE") {
561 apply_json_where_clause(records, query, params)?
562 } else {
563 records.clone()
564 };
565
566 let result = apply_json_pagination(&filtered, query)?;
567 return Ok(result);
568 }
569 } else if query_upper.starts_with("COUNT") {
570 let table_name = extract_table_name_from_count(query)?;
571 if let Some(records) = data.get(table_name) {
572 let count = if query.contains("WHERE") {
573 apply_json_where_clause(records, query, params)?.len()
574 } else {
575 records.len()
576 };
577 let mut result = HashMap::new();
578 result.insert("total".to_string(), Value::Number(count.into()));
579 return Ok(vec![result]);
580 }
581 }
582
583 Ok(vec![])
584 }
585
586 async fn execute(&self, query: &str, params: &[Value]) -> Result<u64> {
587 let mut data = self.data.write().await;
588
589 let query_upper = query.trim().to_uppercase();
590
591 if query_upper.starts_with("INSERT") {
592 let (table_name, record) = parse_insert_query(query, params)?;
593 let records = data.entry(table_name).or_insert_with(Vec::new);
594 records.push(record);
595 Ok(1)
596 } else if query_upper.starts_with("UPDATE") {
597 let (table_name, updates, where_clause, where_params) =
598 parse_update_query(query, params)?;
599 if let Some(records) = data.get_mut(&table_name) {
600 let mut updated = 0;
601 for record in records.iter_mut() {
602 if matches_json_where(record, &where_clause, &where_params)? {
603 record.extend(updates.clone());
604 updated += 1;
605 }
606 }
607 Ok(updated)
608 } else {
609 Ok(0)
610 }
611 } else if query_upper.starts_with("DELETE") {
612 let (table_name, where_clause, where_params) = parse_delete_query(query, params)?;
613 let records = data.entry(table_name.clone()).or_insert_with(Vec::new);
615 let initial_len = records.len();
616 records.retain(|record| {
617 !matches_json_where(record, &where_clause, &where_params).unwrap_or(false)
618 });
619 let deleted = initial_len - records.len();
620 Ok(deleted as u64)
621 } else {
622 Ok(0)
623 }
624 }
625
626 async fn execute_with_id(&self, query: &str, params: &[Value]) -> Result<String> {
627 let mut data = self.data.write().await;
628
629 if query.trim().to_uppercase().starts_with("INSERT") {
630 let (table_name, mut record) = parse_insert_query(query, params)?;
631
632 if !record.contains_key("id") {
633 use uuid::Uuid;
634 record.insert("id".to_string(), Value::String(Uuid::new_v4().to_string()));
635 }
636
637 let id = record.get("id").and_then(|v| v.as_str()).unwrap_or("").to_string();
638
639 let records = data.entry(table_name).or_insert_with(Vec::new);
640 records.push(record);
641 Ok(id)
642 } else {
643 self.execute(query, params).await?;
644 Ok(String::new())
645 }
646 }
647
648 async fn table_exists(&self, table_name: &str) -> Result<bool> {
649 let data = self.data.read().await;
650 Ok(data.contains_key(table_name))
651 }
652
653 async fn create_table(&self, create_statement: &str) -> Result<()> {
654 let query_upper = create_statement.to_uppercase();
659 if query_upper.contains("CREATE TABLE") {
660 let mut rest = create_statement;
661
662 if let Some(idx) = query_upper.find("CREATE TABLE") {
664 rest = &create_statement[idx + 12..];
665 }
666
667 let rest_upper = rest.to_uppercase();
669 if rest_upper.trim_start().starts_with("IF NOT EXISTS") {
670 if let Some(idx) = rest_upper.find("IF NOT EXISTS") {
671 rest = &rest[idx + 13..];
672 }
673 }
674
675 let table_name = rest
677 .trim_start()
678 .split(|c: char| c == '(' || c.is_whitespace())
679 .next()
680 .unwrap_or("")
681 .trim()
682 .to_string();
683
684 if !table_name.is_empty() {
685 let mut data = self.data.write().await;
686 data.entry(table_name).or_insert_with(Vec::new);
687 }
688 }
689 Ok(())
690 }
691
692 fn connection_info(&self) -> String {
693 "In-Memory".to_string()
694 }
695
696 async fn close(&mut self) -> Result<()> {
697 Ok(())
699 }
700}
701
702fn extract_table_name_from_select(query: &str) -> Result<&str> {
706 let parts: Vec<&str> = query.split_whitespace().collect();
708 if let Some(from_idx) = parts.iter().position(|&p| p.to_uppercase() == "FROM") {
709 if from_idx + 1 < parts.len() {
710 let table_name = parts[from_idx + 1].trim_end_matches(';');
711 return Ok(table_name);
712 }
713 }
714 Err(Error::generic("Invalid SELECT query: missing FROM clause".to_string()))
715}
716
717fn extract_table_name_from_count(query: &str) -> Result<&str> {
719 extract_table_name_from_select(query)
721}
722
723fn apply_json_where_clause(
725 records: &[HashMap<String, Value>],
726 query: &str,
727 params: &[Value],
728) -> Result<Vec<HashMap<String, Value>>> {
729 let mut result = Vec::new();
731
732 for record in records {
733 if matches_json_where(record, query, params)? {
734 result.push(record.clone());
735 }
736 }
737
738 Ok(result)
739}
740
741fn matches_json_where(
743 record: &HashMap<String, Value>,
744 query: &str,
745 params: &[Value],
746) -> Result<bool> {
747 let query_upper = query.to_uppercase();
749 if let Some(where_idx) = query_upper.find("WHERE") {
750 let where_clause = &query[where_idx + 5..];
751
752 let where_upper = where_clause.to_uppercase();
754 let mut condition_strs = Vec::new();
755 let mut last = 0;
756 for (idx, _) in where_upper.match_indices(" AND ") {
757 condition_strs.push(where_clause[last..idx].trim());
758 last = idx + 5; }
760 condition_strs.push(where_clause[last..].trim());
761
762 let mut param_idx = 0;
763 for condition in &condition_strs {
764 let parts: Vec<&str> = condition.split_whitespace().collect();
765 if parts.len() >= 3 {
766 let field = parts[0];
767 let op = parts[1];
768
769 let has_placeholder = parts.iter().any(|&p| p == "?" || p.contains('?'));
771
772 if has_placeholder && param_idx < params.len() {
773 let expected_value = ¶ms[param_idx];
774 let actual_value = record.get(field);
775 param_idx += 1;
776
777 match op {
778 "=" => {
779 if !matches_value(actual_value, expected_value) {
780 return Ok(false);
781 }
782 }
783 "!=" | "<>" => {
784 if matches_value(actual_value, expected_value) {
785 return Ok(false);
786 }
787 }
788 _ => {
789 }
791 }
792 }
793 }
794 }
795
796 return Ok(true); }
798
799 Ok(true) }
801
802fn matches_value(actual: Option<&Value>, expected: &Value) -> bool {
804 match (actual, expected) {
805 (Some(a), e) => a == e,
806 (None, Value::Null) => true,
807 _ => false,
808 }
809}
810
811fn apply_json_pagination(
813 records: &[HashMap<String, Value>],
814 query: &str,
815) -> Result<Vec<HashMap<String, Value>>> {
816 let mut result = records.to_vec();
817
818 if let Some(limit_idx) = query.to_uppercase().find("LIMIT") {
820 let limit_str = query[limit_idx + 5..]
821 .split_whitespace()
822 .next()
823 .unwrap_or("")
824 .trim_end_matches(';');
825
826 if let Ok(limit) = limit_str.parse::<usize>() {
827 let offset = if let Some(offset_idx) = query.to_uppercase().find("OFFSET") {
829 query[offset_idx + 6..]
830 .split_whitespace()
831 .next()
832 .unwrap_or("0")
833 .trim_end_matches(';')
834 .parse::<usize>()
835 .unwrap_or(0)
836 } else {
837 0
838 };
839
840 let start = offset.min(result.len());
841 let end = (start + limit).min(result.len());
842 result = result[start..end].to_vec();
843 }
844 }
845
846 Ok(result)
847}
848
849fn parse_insert_query(query: &str, params: &[Value]) -> Result<(String, HashMap<String, Value>)> {
851 let parts: Vec<&str> = query.split_whitespace().collect();
853
854 if let Some(into_idx) = parts.iter().position(|&p| p.to_uppercase() == "INTO") {
855 if into_idx + 1 < parts.len() {
856 let table_name = parts[into_idx + 1].to_string();
857
858 if let Some(fields_start) = query.find('(') {
860 if let Some(fields_end) = query[fields_start + 1..].find(')') {
861 let fields_str = &query[fields_start + 1..fields_start + 1 + fields_end];
862 let fields: Vec<&str> = fields_str.split(',').map(|s| s.trim()).collect();
863
864 let mut record = HashMap::new();
866 for (idx, field) in fields.iter().enumerate() {
867 if idx < params.len() {
868 record.insert(field.to_string(), params[idx].clone());
869 }
870 }
871
872 return Ok((table_name, record));
873 }
874 }
875 }
876 }
877
878 Err(Error::generic("Invalid INSERT query format".to_string()))
879}
880
881fn parse_update_query(
883 query: &str,
884 params: &[Value],
885) -> Result<(String, HashMap<String, Value>, String, Vec<Value>)> {
886 let parts: Vec<&str> = query.split_whitespace().collect();
888
889 if parts.len() < 4 || parts[0].to_uppercase() != "UPDATE" {
890 return Err(Error::generic("Invalid UPDATE query".to_string()));
891 }
892
893 let table_name = parts[1].to_string();
894
895 if let Some(_set_idx) = parts.iter().position(|&p| p.to_uppercase() == "SET") {
897 let set_clause = &query[query.to_uppercase().find("SET").unwrap() + 3..];
898 let where_clause = if let Some(where_idx) = set_clause.to_uppercase().find("WHERE") {
899 &set_clause[..where_idx]
900 } else {
901 set_clause
902 };
903
904 let mut updates = HashMap::new();
906 let set_parts: Vec<&str> = where_clause.split(',').collect();
907 let mut param_idx = 0;
908
909 for part in set_parts {
910 let field_eq: Vec<&str> = part.split('=').map(|s| s.trim()).collect();
911 if field_eq.len() == 2 && field_eq[1] == "?" && param_idx < params.len() {
912 updates.insert(field_eq[0].to_string(), params[param_idx].clone());
913 param_idx += 1;
914 }
915 }
916
917 let (where_clause_str, where_params) =
919 if let Some(where_idx) = set_clause.to_uppercase().find("WHERE") {
920 let where_part = &set_clause[where_idx + 5..];
921 (where_part.to_string(), params[param_idx..].to_vec())
922 } else {
923 (String::new(), Vec::new())
924 };
925
926 return Ok((table_name, updates, where_clause_str, where_params));
927 }
928
929 Err(Error::generic("Invalid UPDATE query: missing SET clause".to_string()))
930}
931
932fn parse_delete_query(query: &str, params: &[Value]) -> Result<(String, String, Vec<Value>)> {
934 let parts: Vec<&str> = query.split_whitespace().collect();
936
937 if let Some(from_idx) = parts.iter().position(|&p| p.to_uppercase() == "FROM") {
938 if from_idx + 1 < parts.len() {
939 let table_name = parts[from_idx + 1].to_string();
940
941 if let Some(where_idx) = query.to_uppercase().find("WHERE") {
943 let where_clause = query[where_idx + 5..].to_string();
944 return Ok((table_name, where_clause, params.to_vec()));
945 } else {
946 return Ok((table_name, String::new(), Vec::new()));
947 }
948 }
949 }
950
951 Err(Error::generic("Invalid DELETE query".to_string()))
952}
953
954#[cfg(test)]
955mod tests {
956 use super::*;
957 use crate::config::StorageBackend;
958
959 async fn create_test_table(db: &dyn VirtualDatabase) -> Result<()> {
961 let create_sql = "CREATE TABLE IF NOT EXISTS test_users (
962 id TEXT PRIMARY KEY,
963 name TEXT NOT NULL,
964 email TEXT,
965 age INTEGER
966 )";
967 db.create_table(create_sql).await
968 }
969
970 #[tokio::test]
972 async fn test_sqlite_database_creation() {
973 let temp_dir = tempfile::tempdir().unwrap();
974 let db_path = temp_dir.path().join("test.db");
975 let result = SqliteDatabase::new(&db_path).await;
976 assert!(result.is_ok());
977 }
978
979 #[tokio::test]
980 async fn test_sqlite_database_connection_info() {
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 info = db.connection_info();
985 assert!(info.contains("SQLite"));
986 assert!(info.contains("test.db"));
987 }
988
989 #[tokio::test]
990 async fn test_sqlite_database_initialize() {
991 let temp_dir = tempfile::tempdir().unwrap();
992 let db_path = temp_dir.path().join("test.db");
993 let mut db = SqliteDatabase::new(&db_path).await.unwrap();
994 let result = db.initialize().await;
995 assert!(result.is_ok());
996 }
997
998 #[tokio::test]
999 async fn test_sqlite_create_table() {
1000 let temp_dir = tempfile::tempdir().unwrap();
1001 let db_path = temp_dir.path().join("test.db");
1002 let db = SqliteDatabase::new(&db_path).await.unwrap();
1003 let result = create_test_table(&db).await;
1004 assert!(result.is_ok());
1005 }
1006
1007 #[tokio::test]
1008 async fn test_sqlite_table_exists() {
1009 let temp_dir = tempfile::tempdir().unwrap();
1010 let db_path = temp_dir.path().join("test.db");
1011 let db = SqliteDatabase::new(&db_path).await.unwrap();
1012 create_test_table(&db).await.unwrap();
1013
1014 let exists = db.table_exists("test_users").await.unwrap();
1015 assert!(exists);
1016
1017 let not_exists = db.table_exists("nonexistent_table").await.unwrap();
1018 assert!(!not_exists);
1019 }
1020
1021 #[tokio::test]
1022 async fn test_sqlite_execute_insert() {
1023 let temp_dir = tempfile::tempdir().unwrap();
1024 let db_path = temp_dir.path().join("test.db");
1025 let db = SqliteDatabase::new(&db_path).await.unwrap();
1026 create_test_table(&db).await.unwrap();
1027
1028 let query = "INSERT INTO test_users (id, name, email, age) VALUES (?, ?, ?, ?)";
1029 let params = vec![
1030 Value::String("1".to_string()),
1031 Value::String("John Doe".to_string()),
1032 Value::String("john@example.com".to_string()),
1033 Value::Number(30.into()),
1034 ];
1035
1036 let result = db.execute(query, ¶ms).await;
1037 assert!(result.is_ok());
1038 assert_eq!(result.unwrap(), 1);
1039 }
1040
1041 #[tokio::test]
1042 async fn test_sqlite_execute_with_id() {
1043 let temp_dir = tempfile::tempdir().unwrap();
1044 let db_path = temp_dir.path().join("test.db");
1045 let db = SqliteDatabase::new(&db_path).await.unwrap();
1046 create_test_table(&db).await.unwrap();
1047
1048 let query = "INSERT INTO test_users (id, name, email) VALUES (?, ?, ?)";
1049 let params = vec![
1050 Value::String("test-id".to_string()),
1051 Value::String("Jane Doe".to_string()),
1052 Value::String("jane@example.com".to_string()),
1053 ];
1054
1055 let result = db.execute_with_id(query, ¶ms).await;
1056 assert!(result.is_ok());
1057 }
1058
1059 #[tokio::test]
1060 async fn test_sqlite_query_select() {
1061 let temp_dir = tempfile::tempdir().unwrap();
1062 let db_path = temp_dir.path().join("test.db");
1063 let db = SqliteDatabase::new(&db_path).await.unwrap();
1064 create_test_table(&db).await.unwrap();
1065
1066 let insert_query = "INSERT INTO test_users (id, name, email) VALUES (?, ?, ?)";
1068 db.execute(
1069 insert_query,
1070 &[
1071 Value::String("1".to_string()),
1072 Value::String("Test User".to_string()),
1073 Value::String("test@example.com".to_string()),
1074 ],
1075 )
1076 .await
1077 .unwrap();
1078
1079 let select_query = "SELECT * FROM test_users WHERE id = ?";
1081 let results = db.query(select_query, &[Value::String("1".to_string())]).await;
1082 assert!(results.is_ok());
1083 let rows = results.unwrap();
1084 assert_eq!(rows.len(), 1);
1085 assert_eq!(rows[0].get("id").unwrap().as_str().unwrap(), "1");
1086 assert_eq!(rows[0].get("name").unwrap().as_str().unwrap(), "Test User");
1087 }
1088
1089 #[tokio::test]
1090 async fn test_sqlite_execute_update() {
1091 let temp_dir = tempfile::tempdir().unwrap();
1092 let db_path = temp_dir.path().join("test.db");
1093 let db = SqliteDatabase::new(&db_path).await.unwrap();
1094 create_test_table(&db).await.unwrap();
1095
1096 db.execute(
1098 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1099 &[
1100 Value::String("1".to_string()),
1101 Value::String("Original Name".to_string()),
1102 ],
1103 )
1104 .await
1105 .unwrap();
1106
1107 let update_result = db
1109 .execute(
1110 "UPDATE test_users SET name = ? WHERE id = ?",
1111 &[
1112 Value::String("Updated Name".to_string()),
1113 Value::String("1".to_string()),
1114 ],
1115 )
1116 .await;
1117
1118 assert!(update_result.is_ok());
1119 assert_eq!(update_result.unwrap(), 1);
1120
1121 let rows = db
1123 .query("SELECT name FROM test_users WHERE id = ?", &[Value::String("1".to_string())])
1124 .await
1125 .unwrap();
1126 assert_eq!(rows[0].get("name").unwrap().as_str().unwrap(), "Updated Name");
1127 }
1128
1129 #[tokio::test]
1130 async fn test_sqlite_execute_delete() {
1131 let temp_dir = tempfile::tempdir().unwrap();
1132 let db_path = temp_dir.path().join("test.db");
1133 let db = SqliteDatabase::new(&db_path).await.unwrap();
1134 create_test_table(&db).await.unwrap();
1135
1136 db.execute(
1138 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1139 &[
1140 Value::String("1".to_string()),
1141 Value::String("Test".to_string()),
1142 ],
1143 )
1144 .await
1145 .unwrap();
1146
1147 let delete_result = db
1149 .execute("DELETE FROM test_users WHERE id = ?", &[Value::String("1".to_string())])
1150 .await;
1151 assert!(delete_result.is_ok());
1152 assert_eq!(delete_result.unwrap(), 1);
1153
1154 let rows = db
1156 .query("SELECT * FROM test_users WHERE id = ?", &[Value::String("1".to_string())])
1157 .await
1158 .unwrap();
1159 assert_eq!(rows.len(), 0);
1160 }
1161
1162 #[tokio::test]
1163 async fn test_sqlite_close() {
1164 let temp_dir = tempfile::tempdir().unwrap();
1165 let db_path = temp_dir.path().join("test.db");
1166 let mut db = SqliteDatabase::new(&db_path).await.unwrap();
1167 let result = db.close().await;
1168 assert!(result.is_ok());
1169 }
1170
1171 #[tokio::test]
1173 async fn test_json_database_creation() {
1174 let temp_dir = tempfile::tempdir().unwrap();
1175 let db_path = temp_dir.path().join("test.json");
1176 let result = JsonDatabase::new(&db_path).await;
1177 assert!(result.is_ok());
1178 }
1179
1180 #[tokio::test]
1181 async fn test_json_database_connection_info() {
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 info = db.connection_info();
1186 assert!(info.contains("JSON"));
1187 assert!(info.contains("test.json"));
1188 }
1189
1190 #[tokio::test]
1191 async fn test_json_database_initialize() {
1192 let temp_dir = tempfile::tempdir().unwrap();
1193 let db_path = temp_dir.path().join("test.json");
1194 let mut db = JsonDatabase::new(&db_path).await.unwrap();
1195 let result = db.initialize().await;
1196 assert!(result.is_ok());
1197 }
1198
1199 #[tokio::test]
1200 async fn test_json_create_table() {
1201 let temp_dir = tempfile::tempdir().unwrap();
1202 let db_path = temp_dir.path().join("test.json");
1203 let db = JsonDatabase::new(&db_path).await.unwrap();
1204 let result = db.create_table("CREATE TABLE test_users (id TEXT, name TEXT)").await;
1205 assert!(result.is_ok());
1206 }
1207
1208 #[tokio::test]
1209 async fn test_json_table_exists() {
1210 let temp_dir = tempfile::tempdir().unwrap();
1211 let db_path = temp_dir.path().join("test.json");
1212 let db = JsonDatabase::new(&db_path).await.unwrap();
1213
1214 assert!(!db.table_exists("test_users").await.unwrap());
1216
1217 db.execute(
1219 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1220 &[
1221 Value::String("1".to_string()),
1222 Value::String("Test".to_string()),
1223 ],
1224 )
1225 .await
1226 .unwrap();
1227
1228 assert!(db.table_exists("test_users").await.unwrap());
1230 }
1231
1232 #[tokio::test]
1233 async fn test_json_execute_insert() {
1234 let temp_dir = tempfile::tempdir().unwrap();
1235 let db_path = temp_dir.path().join("test.json");
1236 let db = JsonDatabase::new(&db_path).await.unwrap();
1237
1238 let query = "INSERT INTO test_users (id, name, email) VALUES (?, ?, ?)";
1239 let params = vec![
1240 Value::String("1".to_string()),
1241 Value::String("John Doe".to_string()),
1242 Value::String("john@example.com".to_string()),
1243 ];
1244
1245 let result = db.execute(query, ¶ms).await;
1246 assert!(result.is_ok());
1247 assert_eq!(result.unwrap(), 1);
1248 }
1249
1250 #[tokio::test]
1251 async fn test_json_execute_with_id() {
1252 let temp_dir = tempfile::tempdir().unwrap();
1253 let db_path = temp_dir.path().join("test.json");
1254 let db = JsonDatabase::new(&db_path).await.unwrap();
1255
1256 let query = "INSERT INTO test_users (name, email) VALUES (?, ?)";
1257 let params = vec![
1258 Value::String("Jane Doe".to_string()),
1259 Value::String("jane@example.com".to_string()),
1260 ];
1261
1262 let result = db.execute_with_id(query, ¶ms).await;
1263 assert!(result.is_ok());
1264 assert!(!result.unwrap().is_empty());
1266 }
1267
1268 #[tokio::test]
1269 async fn test_json_query_select() {
1270 let temp_dir = tempfile::tempdir().unwrap();
1271 let db_path = temp_dir.path().join("test.json");
1272 let db = JsonDatabase::new(&db_path).await.unwrap();
1273
1274 db.execute(
1276 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1277 &[
1278 Value::String("1".to_string()),
1279 Value::String("Test User".to_string()),
1280 ],
1281 )
1282 .await
1283 .unwrap();
1284
1285 let results = db
1287 .query("SELECT * FROM test_users WHERE id = ?", &[Value::String("1".to_string())])
1288 .await;
1289 assert!(results.is_ok());
1290 let rows = results.unwrap();
1291 assert_eq!(rows.len(), 1);
1292 assert_eq!(rows[0].get("id").unwrap().as_str().unwrap(), "1");
1293 }
1294
1295 #[tokio::test]
1296 async fn test_json_query_count() {
1297 let temp_dir = tempfile::tempdir().unwrap();
1298 let db_path = temp_dir.path().join("test.json");
1299 let db = JsonDatabase::new(&db_path).await.unwrap();
1300
1301 db.execute(
1303 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1304 &[
1305 Value::String("1".to_string()),
1306 Value::String("User 1".to_string()),
1307 ],
1308 )
1309 .await
1310 .unwrap();
1311 db.execute(
1312 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1313 &[
1314 Value::String("2".to_string()),
1315 Value::String("User 2".to_string()),
1316 ],
1317 )
1318 .await
1319 .unwrap();
1320
1321 let results = db.query("SELECT COUNT(*) FROM test_users", &[]).await;
1323 assert!(results.is_ok());
1324 let rows = results.unwrap();
1325 assert_eq!(rows.len(), 1);
1326 assert_eq!(rows[0].get("count").unwrap().as_u64().unwrap(), 2);
1327 }
1328
1329 #[tokio::test]
1330 async fn test_json_execute_update() {
1331 let temp_dir = tempfile::tempdir().unwrap();
1332 let db_path = temp_dir.path().join("test.json");
1333 let db = JsonDatabase::new(&db_path).await.unwrap();
1334
1335 db.execute(
1337 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1338 &[
1339 Value::String("1".to_string()),
1340 Value::String("Original".to_string()),
1341 ],
1342 )
1343 .await
1344 .unwrap();
1345
1346 let update_result = db
1348 .execute(
1349 "UPDATE test_users SET name = ? WHERE id = ?",
1350 &[
1351 Value::String("Updated".to_string()),
1352 Value::String("1".to_string()),
1353 ],
1354 )
1355 .await;
1356
1357 assert!(update_result.is_ok());
1358 assert_eq!(update_result.unwrap(), 1);
1359 }
1360
1361 #[tokio::test]
1362 async fn test_json_execute_delete() {
1363 let temp_dir = tempfile::tempdir().unwrap();
1364 let db_path = temp_dir.path().join("test.json");
1365 let db = JsonDatabase::new(&db_path).await.unwrap();
1366
1367 db.execute(
1369 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1370 &[
1371 Value::String("1".to_string()),
1372 Value::String("Test".to_string()),
1373 ],
1374 )
1375 .await
1376 .unwrap();
1377
1378 let delete_result = db
1380 .execute("DELETE FROM test_users WHERE id = ?", &[Value::String("1".to_string())])
1381 .await;
1382 assert!(delete_result.is_ok());
1383 assert_eq!(delete_result.unwrap(), 1);
1384 }
1385
1386 #[tokio::test]
1387 async fn test_json_close() {
1388 let temp_dir = tempfile::tempdir().unwrap();
1389 let db_path = temp_dir.path().join("test.json");
1390 let mut db = JsonDatabase::new(&db_path).await.unwrap();
1391 let result = db.close().await;
1392 assert!(result.is_ok());
1393 }
1394
1395 #[tokio::test]
1397 async fn test_inmemory_database_creation() {
1398 let result = InMemoryDatabase::new().await;
1399 assert!(result.is_ok());
1400 }
1401
1402 #[tokio::test]
1403 async fn test_inmemory_database_connection_info() {
1404 let db = InMemoryDatabase::new().await.unwrap();
1405 let info = db.connection_info();
1406 assert_eq!(info, "In-Memory");
1407 }
1408
1409 #[tokio::test]
1410 async fn test_inmemory_database_initialize() {
1411 let mut db = InMemoryDatabase::new().await.unwrap();
1412 let result = db.initialize().await;
1413 assert!(result.is_ok());
1414 }
1415
1416 #[tokio::test]
1417 async fn test_inmemory_create_table() {
1418 let db = InMemoryDatabase::new().await.unwrap();
1419 let result = db.create_table("CREATE TABLE test_users (id TEXT, name TEXT)").await;
1420 assert!(result.is_ok());
1421 }
1422
1423 #[tokio::test]
1424 async fn test_inmemory_table_exists() {
1425 let db = InMemoryDatabase::new().await.unwrap();
1426
1427 db.create_table("CREATE TABLE test_users (id TEXT)").await.unwrap();
1429
1430 assert!(db.table_exists("test_users").await.unwrap());
1432 assert!(!db.table_exists("nonexistent").await.unwrap());
1433 }
1434
1435 #[tokio::test]
1436 async fn test_inmemory_execute_insert() {
1437 let db = InMemoryDatabase::new().await.unwrap();
1438
1439 let query = "INSERT INTO test_users (id, name) VALUES (?, ?)";
1440 let params = vec![
1441 Value::String("1".to_string()),
1442 Value::String("John Doe".to_string()),
1443 ];
1444
1445 let result = db.execute(query, ¶ms).await;
1446 assert!(result.is_ok());
1447 assert_eq!(result.unwrap(), 1);
1448 }
1449
1450 #[tokio::test]
1451 async fn test_inmemory_execute_with_id() {
1452 let db = InMemoryDatabase::new().await.unwrap();
1453
1454 let query = "INSERT INTO test_users (name) VALUES (?)";
1455 let params = vec![Value::String("Jane Doe".to_string())];
1456
1457 let result = db.execute_with_id(query, ¶ms).await;
1458 assert!(result.is_ok());
1459 assert!(!result.unwrap().is_empty());
1460 }
1461
1462 #[tokio::test]
1463 async fn test_inmemory_query_select() {
1464 let db = InMemoryDatabase::new().await.unwrap();
1465
1466 db.execute(
1468 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1469 &[
1470 Value::String("1".to_string()),
1471 Value::String("Test User".to_string()),
1472 ],
1473 )
1474 .await
1475 .unwrap();
1476
1477 let results = db
1479 .query("SELECT * FROM test_users WHERE id = ?", &[Value::String("1".to_string())])
1480 .await;
1481 assert!(results.is_ok());
1482 let rows = results.unwrap();
1483 assert_eq!(rows.len(), 1);
1484 }
1485
1486 #[tokio::test]
1487 async fn test_inmemory_query_count() {
1488 let db = InMemoryDatabase::new().await.unwrap();
1489
1490 db.execute(
1492 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1493 &[
1494 Value::String("1".to_string()),
1495 Value::String("User 1".to_string()),
1496 ],
1497 )
1498 .await
1499 .unwrap();
1500 db.execute(
1501 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1502 &[
1503 Value::String("2".to_string()),
1504 Value::String("User 2".to_string()),
1505 ],
1506 )
1507 .await
1508 .unwrap();
1509
1510 let results = db.query("SELECT COUNT(*) FROM test_users", &[]).await;
1512 assert!(results.is_ok());
1513 let rows = results.unwrap();
1514 assert_eq!(rows[0].get("count").unwrap().as_u64().unwrap(), 2);
1515 }
1516
1517 #[tokio::test]
1518 async fn test_inmemory_execute_update() {
1519 let db = InMemoryDatabase::new().await.unwrap();
1520
1521 db.execute(
1523 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1524 &[
1525 Value::String("1".to_string()),
1526 Value::String("Original".to_string()),
1527 ],
1528 )
1529 .await
1530 .unwrap();
1531
1532 let result = db
1534 .execute(
1535 "UPDATE test_users SET name = ? WHERE id = ?",
1536 &[
1537 Value::String("Updated".to_string()),
1538 Value::String("1".to_string()),
1539 ],
1540 )
1541 .await;
1542
1543 assert!(result.is_ok());
1544 assert_eq!(result.unwrap(), 1);
1545 }
1546
1547 #[tokio::test]
1548 async fn test_inmemory_execute_delete() {
1549 let db = InMemoryDatabase::new().await.unwrap();
1550
1551 db.execute(
1553 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1554 &[
1555 Value::String("1".to_string()),
1556 Value::String("Test".to_string()),
1557 ],
1558 )
1559 .await
1560 .unwrap();
1561
1562 let result = db
1564 .execute("DELETE FROM test_users WHERE id = ?", &[Value::String("1".to_string())])
1565 .await;
1566 assert!(result.is_ok());
1567 assert_eq!(result.unwrap(), 1);
1568 }
1569
1570 #[tokio::test]
1571 async fn test_inmemory_close() {
1572 let mut db = InMemoryDatabase::new().await.unwrap();
1573 let result = db.close().await;
1574 assert!(result.is_ok());
1575 }
1576
1577 #[tokio::test]
1579 async fn test_create_database_sqlite() {
1580 let temp_dir = tempfile::tempdir().unwrap();
1581 let db_path = temp_dir.path().join("test.db");
1582 let backend = StorageBackend::Sqlite {
1583 path: db_path.clone(),
1584 };
1585 let result = create_database(&backend).await;
1586 assert!(result.is_ok(), "create_database failed: {:?}", result.err());
1587 let db = result.unwrap();
1588 assert!(db.connection_info().contains("SQLite"));
1589 }
1590
1591 #[tokio::test]
1592 async fn test_create_database_json() {
1593 let temp_dir = tempfile::tempdir().unwrap();
1594 let db_path = temp_dir.path().join("test.json");
1595 let backend = StorageBackend::Json {
1596 path: db_path.clone(),
1597 };
1598 let result = create_database(&backend).await;
1599 assert!(result.is_ok());
1600 let db = result.unwrap();
1601 assert!(db.connection_info().contains("JSON"));
1602 }
1603
1604 #[tokio::test]
1605 async fn test_create_database_memory() {
1606 let backend = StorageBackend::Memory;
1607 let result = create_database(&backend).await;
1608 assert!(result.is_ok());
1609 let db = result.unwrap();
1610 assert_eq!(db.connection_info(), "In-Memory");
1611 }
1612
1613 #[test]
1615 fn test_extract_table_name_from_select() {
1616 let query = "SELECT * FROM users";
1617 let result = extract_table_name_from_select(query);
1618 assert!(result.is_ok());
1619 assert_eq!(result.unwrap(), "users");
1620 }
1621
1622 #[test]
1623 fn test_extract_table_name_from_select_with_where() {
1624 let query = "SELECT * FROM products WHERE price > 10";
1625 let result = extract_table_name_from_select(query);
1626 assert!(result.is_ok());
1627 assert_eq!(result.unwrap(), "products");
1628 }
1629
1630 #[test]
1631 fn test_extract_table_name_from_select_invalid() {
1632 let query = "SELECT * users";
1633 let result = extract_table_name_from_select(query);
1634 assert!(result.is_err());
1635 }
1636
1637 #[test]
1638 fn test_parse_insert_query() {
1639 let query = "INSERT INTO users (id, name) VALUES (?, ?)";
1640 let params = vec![
1641 Value::String("1".to_string()),
1642 Value::String("John".to_string()),
1643 ];
1644 let result = parse_insert_query(query, ¶ms);
1645 assert!(result.is_ok());
1646 let (table_name, record) = result.unwrap();
1647 assert_eq!(table_name, "users");
1648 assert_eq!(record.len(), 2);
1649 assert_eq!(record.get("id").unwrap().as_str().unwrap(), "1");
1650 }
1651
1652 #[test]
1653 fn test_parse_insert_query_invalid() {
1654 let query = "INSERT users VALUES (?)";
1655 let params = vec![Value::String("1".to_string())];
1656 let result = parse_insert_query(query, ¶ms);
1657 assert!(result.is_err());
1658 }
1659
1660 #[test]
1661 fn test_parse_update_query() {
1662 let query = "UPDATE users SET name = ? WHERE id = ?";
1663 let params = vec![
1664 Value::String("John".to_string()),
1665 Value::String("1".to_string()),
1666 ];
1667 let result = parse_update_query(query, ¶ms);
1668 assert!(result.is_ok());
1669 let (table_name, updates, _where_clause, _where_params) = result.unwrap();
1670 assert_eq!(table_name, "users");
1671 assert_eq!(updates.len(), 1);
1672 }
1673
1674 #[test]
1675 fn test_parse_delete_query() {
1676 let query = "DELETE FROM users WHERE id = ?";
1677 let params = vec![Value::String("1".to_string())];
1678 let result = parse_delete_query(query, ¶ms);
1679 assert!(result.is_ok());
1680 let (table_name, _where_clause, where_params) = result.unwrap();
1681 assert_eq!(table_name, "users");
1682 assert_eq!(where_params.len(), 1);
1683 }
1684
1685 #[test]
1686 fn test_matches_value() {
1687 assert!(matches_value(
1688 Some(&Value::String("test".to_string())),
1689 &Value::String("test".to_string())
1690 ));
1691 assert!(!matches_value(
1692 Some(&Value::String("test".to_string())),
1693 &Value::String("other".to_string())
1694 ));
1695 assert!(matches_value(None, &Value::Null));
1696 assert!(!matches_value(None, &Value::String("test".to_string())));
1697 }
1698
1699 #[tokio::test]
1700 async fn test_json_pagination() {
1701 let temp_dir = tempfile::tempdir().unwrap();
1702 let db_path = temp_dir.path().join("test.json");
1703 let db = JsonDatabase::new(&db_path).await.unwrap();
1704
1705 for i in 1..=5 {
1707 db.execute(
1708 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1709 &[
1710 Value::String(i.to_string()),
1711 Value::String(format!("User {}", i)),
1712 ],
1713 )
1714 .await
1715 .unwrap();
1716 }
1717
1718 let results = db.query("SELECT * FROM test_users LIMIT 2", &[]).await.unwrap();
1720 assert_eq!(results.len(), 2);
1721
1722 let results = db.query("SELECT * FROM test_users LIMIT 2 OFFSET 2", &[]).await.unwrap();
1724 assert_eq!(results.len(), 2);
1725 }
1726
1727 #[tokio::test]
1728 async fn test_inmemory_pagination() {
1729 let db = InMemoryDatabase::new().await.unwrap();
1730
1731 for i in 1..=5 {
1733 db.execute(
1734 "INSERT INTO test_users (id, name) VALUES (?, ?)",
1735 &[
1736 Value::String(i.to_string()),
1737 Value::String(format!("User {}", i)),
1738 ],
1739 )
1740 .await
1741 .unwrap();
1742 }
1743
1744 let results = db.query("SELECT * FROM test_users LIMIT 2", &[]).await.unwrap();
1746 assert_eq!(results.len(), 2);
1747
1748 let results = db.query("SELECT * FROM test_users LIMIT 2 OFFSET 2", &[]).await.unwrap();
1750 assert_eq!(results.len(), 2);
1751 }
1752}