sql_middleware/
lib.rs

1/*!
2 * SQL Middleware - A unified interface for SQL databases
3 * 
4 * This crate provides a middleware layer for SQL database access,
5 * currently supporting SQLite and PostgreSQL backends. The main goal is to 
6 * provide a unified, async-compatible API that works across different database systems.
7 * 
8 * # Features
9 * 
10 * - Asynchronous database access with deadpool connection pooling
11 * - Support for SQLite and PostgreSQL backends
12 * - Unified parameter conversion system
13 * - Consistent result handling across database engines
14 * - Transaction support
15 * 
16 * # Example
17 * 
18 * ```rust,no_run
19 * use sql_middleware::prelude::*;
20 * 
21 * async fn example() -> Result<(), SqlMiddlewareDbError> {
22 *     // Create a SQLite connection pool
23 *     let config = ConfigAndPool::new_sqlite("my_database.db".to_string()).await?;
24 *     
25 *     // Get a connection from the pool
26 *     let pool = config.pool.get().await?;
27 *     let mut conn = MiddlewarePool::get_connection(&pool).await?;
28 *     
29 *     // Execute a query with parameters
30 *     let result = conn.execute_select(
31 *         "SELECT * FROM users WHERE id = ?",
32 *         &[RowValues::Int(1)]
33 *     ).await?;
34 *     
35 *     // Process the results
36 *     for row in result.results {
37 *         println!("User: {}", row.get("name").unwrap().as_text().unwrap());
38 *     }
39 *     
40 *     Ok(())
41 * }
42 * ```
43 */
44
45 #![forbid(unsafe_code)]
46
47// Re-export everything that should be part of the public API
48pub mod prelude {
49    //! Convenient imports for common functionality.
50    //! 
51    //! This module re-exports the most commonly used types and functions
52    //! to make it easier to get started with the library.
53    
54    pub use crate::middleware::{
55        ConfigAndPool, 
56        MiddlewarePool, 
57        MiddlewarePoolConnection,
58        AsyncDatabaseExecutor,
59        ResultSet, 
60        CustomDbRow,
61        RowValues,
62        SqlMiddlewareDbError,
63        DatabaseType,
64        ConversionMode,
65        QueryAndParams,
66        AnyConnWrapper,
67    };
68    
69    pub use crate::convert_sql_params;
70    pub use crate::postgres_build_result_set;
71    pub use crate::sqlite_build_result_set;
72    pub use crate::PostgresParams;
73    pub use crate::SqliteParamsExecute;
74    pub use crate::SqliteParamsQuery;
75}
76
77// Core modules
78pub mod middleware;
79
80// Private database-specific modules
81mod postgres;
82mod sqlite;
83
84// Direct exports of frequently used types and functions for simplicity
85pub use middleware::{
86    ConfigAndPool, 
87    MiddlewarePool, 
88    MiddlewarePoolConnection,
89    AsyncDatabaseExecutor,
90    ResultSet, 
91    CustomDbRow,
92    RowValues,
93    SqlMiddlewareDbError,
94    DatabaseType,
95    ConversionMode,
96    QueryAndParams,
97    AnyConnWrapper,
98    ParamConverter,
99};
100
101pub use postgres::Params as PostgresParams;
102pub use postgres::build_result_set as postgres_build_result_set;
103pub use sqlite::build_result_set as sqlite_build_result_set;
104pub use sqlite::SqliteParamsExecute;
105pub use sqlite::SqliteParamsQuery;
106
107// Module to help with testing - needed for existing tests
108pub mod test_helpers {
109    use std::sync::Arc;
110    use crate::middleware::{CustomDbRow, RowValues};
111    
112    pub fn create_test_row(column_names: Vec<String>, values: Vec<RowValues>) -> CustomDbRow {
113        CustomDbRow::new(Arc::new(column_names), values)
114    }
115}
116
117/// Convert a slice of generic RowValues into database-specific parameters.
118///
119/// This function uses the ParamConverter trait to convert a set of parameters
120/// into the format required by a specific database backend.
121///
122/// # Arguments
123///
124/// * `params` - The slice of RowValues to convert
125/// * `mode` - Whether the parameters will be used for a query or execution
126///
127/// # Returns
128///
129/// The converted parameters, or an error if conversion fails
130///
131/// # Example
132///
133/// ```rust,no_run
134/// use sql_middleware::prelude::*;
135/// use sql_middleware::PostgresParams;
136/// use sql_middleware::convert_sql_params;
137///
138/// fn convert_parameters<'a>(values: &'a [RowValues]) -> Result<PostgresParams<'a>, SqlMiddlewareDbError> {
139///     let mode = ConversionMode::Query;
140///     let postgres_params = convert_sql_params::<PostgresParams>(values, mode)?;
141///     Ok(postgres_params)
142/// }
143/// ```
144pub fn convert_sql_params<'a, T: ParamConverter<'a>>(
145    params: &'a [RowValues],
146    mode: ConversionMode,
147) -> Result<T::Converted, SqlMiddlewareDbError> {
148    // Check if the converter supports this mode
149    if !T::supports_mode(mode) {
150        return Err(SqlMiddlewareDbError::ParameterError(
151            format!("Converter doesn't support mode: {:?}", mode)
152        ));
153    }
154    T::convert_sql_params(params, mode)
155}