toolu_orm_connection/blocking_trait_def.rs
1//! DbConnectionBlocking trait for backends that are natively synchronous.
2
3use crate::error::DbError;
4use toolu_orm_core::row::FromRow;
5use toolu_orm_core::value::Value;
6
7/// Synchronous counterpart to [`DbConnection`](crate::trait_def::DbConnection),
8/// for in-process drivers that are natively blocking.
9///
10/// Only `RusqliteConnection` implements it: SQLite runs in the calling process and
11/// never yields, so nothing is gained by going through a runtime. libsql and
12/// Postgres talk to a server and are genuinely async; a blocking wrapper there
13/// would only hide a `block_on`.
14///
15/// Reach for this when the consumer has no async of its own -- a CLI that would
16/// otherwise build a runtime per invocation -- or when it already runs its database
17/// work on a blocking thread and does not want a second thread hop underneath.
18///
19/// `RusqliteConnection` implements this *and* `DbConnection`, and the two traits
20/// share method names. With both in scope a plain `conn.execute_sql(..)` is
21/// ambiguous (`E0034`); name the trait to pick a path:
22///
23/// ```ignore
24/// DbConnectionBlocking::execute_sql(&conn, sql, params)?;
25/// DbConnection::execute_sql(&conn, sql, params).await?;
26/// ```
27pub trait DbConnectionBlocking: Send + Sync {
28 /// Execute a write statement (INSERT/UPDATE/DELETE) and return affected row count.
29 ///
30 /// # Errors
31 ///
32 /// Returns `DbError::Query` if the SQL execution fails.
33 fn execute_sql(&self, sql: &str, params: Vec<Value>) -> Result<u64, DbError>;
34
35 /// Execute a SELECT statement and map each row into `T` via `FromRow`.
36 ///
37 /// Unlike the async trait, `T` needs no `Send + 'static` bound: rows are
38 /// decoded and returned on the caller's own thread.
39 ///
40 /// # Errors
41 ///
42 /// Returns `DbError::Query` if the SQL execution fails or `DbError::RowMapping`
43 /// if a row cannot be converted into `T`.
44 fn query_map<T: FromRow>(&self, sql: &str, params: Vec<Value>) -> Result<Vec<T>, DbError>;
45
46 /// Execute a batch of SQL statements (e.g., DDL, migrations).
47 ///
48 /// # Errors
49 ///
50 /// Returns `DbError::Query` if any statement in the batch fails.
51 fn execute_batch(&self, sql: &str) -> Result<(), DbError>;
52}