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}