toolu_orm_connection/trait_def.rs
1//! DbConnection trait shared across all database backends.
2
3use crate::error::DbError;
4use toolu_orm_core::row::FromRow;
5use toolu_orm_core::value::Value;
6
7/// Trait abstracting over database connections for testability and driver swaps.
8///
9/// Query functions accept `&(impl DbConnection)` so callers can provide
10/// any backend (libsql, rusqlite, postgres) or a test double.
11///
12/// All methods are async. Sync backends (rusqlite) use `spawn_blocking`
13/// internally to satisfy the async interface.
14#[async_trait::async_trait]
15pub trait DbConnection: Send + Sync {
16 /// Execute a write statement (INSERT/UPDATE/DELETE) and return affected row count.
17 ///
18 /// Parameters are passed as `Vec<Value>` and converted to the driver's
19 /// native parameter type by each backend implementation.
20 ///
21 /// # Errors
22 ///
23 /// Returns `DbError::Query` if the SQL execution fails.
24 async fn execute_sql(&self, sql: &str, params: Vec<Value>) -> Result<u64, DbError>;
25
26 /// Execute a SELECT statement and map each row into `T` via `FromRow`.
27 ///
28 /// # Errors
29 ///
30 /// Returns `DbError::Query` if the SQL execution fails or `DbError::RowMapping`
31 /// if a row cannot be converted into `T`.
32 async fn query_map<T: FromRow + Send + 'static>(
33 &self,
34 sql: &str,
35 params: Vec<Value>,
36 ) -> Result<Vec<T>, DbError>;
37
38 /// Execute a batch of SQL statements (e.g., DDL, migrations).
39 ///
40 /// The batch is executed as a single string. Backends that require
41 /// statement-level execution must split internally.
42 ///
43 /// # Errors
44 ///
45 /// Returns `DbError::Query` if any statement in the batch fails.
46 async fn execute_batch(&self, sql: &str) -> Result<(), DbError>;
47}