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