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