parsql_tokio_postgres/
lib.rs

1//! # parsql-tokio-postgres
2//! 
3//! Asynchronous PostgreSQL integration for parsql using tokio-postgres.
4//! This crate provides async/await APIs for working with PostgreSQL databases.
5//! 
6//! ## Features
7//! 
8//! - Asynchronous PostgreSQL operations
9//! - Automatic SQL query generation
10//! - Secure parameter management
11//! - Generic CRUD operations
12//! - Deadpool connection pool support
13//! - SQL Injection protection
14//! - Detailed error reporting
15//! 
16//! ## Usage
17//! 
18//! ```rust,no_run
19//! use tokio_postgres::{NoTls, Error};
20//! use parsql::tokio_postgres::{CrudOps};
21//! use parsql::macros::{Insertable, Queryable, SqlParams, FromRow};
22//! 
23//! #[derive(Insertable, SqlParams)]
24//! #[table("users")]
25//! pub struct InsertUser {
26//!     pub name: String,
27//!     pub email: String,
28//! }
29//! 
30//! #[derive(Queryable, SqlParams, FromRow)]
31//! #[table("users")]
32//! #[where_clause("id = $")]
33//! pub struct GetUser {
34//!     pub id: i32,
35//!     pub name: String,
36//!     pub email: String,
37//! }
38//! 
39//! impl GetUser {
40//!     pub fn new(id: i32) -> Self {
41//!         Self {
42//!             id,
43//!             name: Default::default(),
44//!             email: Default::default(),
45//!         }
46//!     }
47//! }
48//! 
49//! #[tokio::main]
50//! async fn main() -> Result<(), Error> {
51//!     let (client, connection) = tokio_postgres::connect(
52//!         "host=localhost user=postgres dbname=test",
53//!         NoTls,
54//!     ).await?;
55//!     
56//!     tokio::spawn(async move {
57//!         if let Err(e) = connection.await {
58//!             eprintln!("Connection error: {}", e);
59//!         }
60//!     });
61//!     
62//!     // Insert a new user
63//!     let insert_user = InsertUser {
64//!         name: "John".to_string(),
65//!         email: "john@example.com".to_string(),
66//!     };
67//!     
68//!     // Extension method style
69//!     let id = client.insert(insert_user).await?;
70//!     
71//!     // Get the user back
72//!     let get_user = GetUser::new(id as i32);
73//!     let user = client.fetch(get_user).await?;
74//!     
75//!     println!("User: {:?}", user);
76//!     Ok(())
77//! }
78//! ```
79//!
80//! The trait-based extension methods can also be used with client objects from deadpool-postgres:
81//!
82//! ```rust,no_run
83//! use parsql::tokio_postgres::CrudOps;
84//! use deadpool_postgres::{Config, Pool};
85//! use tokio_postgres::NoTls;
86//!
87//! async fn example() -> Result<(), Box<dyn std::error::Error>> {
88//!     let mut cfg = Config::new();
89//!     cfg.host = Some("localhost".to_string());
90//!     cfg.user = Some("postgres".to_string());
91//!     
92//!     let pool = cfg.create_pool(None, NoTls)?;
93//!     
94//!     // Get client from pool
95//!     let client = pool.get().await?;
96//!     
97//!     // Use extension methods
98//!     let users = client.fetch_all(active_users_query).await?;
99//!     
100//!     Ok(())
101//! }
102//! ```
103
104pub mod crud_ops;
105
106/// Transaction support module 
107/// 
108/// This module provides support for database transactions, including:
109/// - Transaction management functions
110/// - Implementation of `CrudOps` trait for `Transaction` objects
111/// - Helper functions for working with transactions
112///
113/// There are two ways to use transactions:
114/// 1. Using the `CrudOps` trait methods directly on a `Transaction` object
115/// 2. Using the transaction helper functions from the `transactional` module
116///
117/// ```rust,no_run
118/// use tokio_postgres::{NoTls, Error};
119/// use parsql::tokio_postgres::{CrudOps, transactional};
120/// use parsql::macros::{Insertable, SqlParams};
121/// 
122/// #[derive(Insertable, SqlParams)]
123/// #[table("users")]
124/// struct InsertUser {
125///     name: String,
126///     email: String,
127/// }
128/// 
129/// #[tokio::main]
130/// async fn main() -> Result<(), Error> {
131///     let (mut client, connection) = tokio_postgres::connect("", NoTls).await?;
132///     tokio::spawn(async move { connection.await; });
133///     
134///     // Approach 1: CrudOps trait on Transaction
135///     let tx = client.transaction().await?;
136///     let rows = tx.insert(InsertUser {
137///         name: "John".to_string(),
138///         email: "john@example.com".to_string(),
139///     }).await?;
140///     tx.commit().await?;
141///     
142///     // Approach 2: Helper functions
143///     let tx = transactional::begin(&mut client).await?;
144///     let (tx, rows) = transactional::tx_insert(tx, InsertUser {
145///         name: "Jane".to_string(),
146///         email: "jane@example.com".to_string(),
147///     }).await?;
148///     tx.commit().await?;
149///     
150///     Ok(())
151/// }
152/// ```
153pub mod transaction_ops;
154
155// Re-export tokio-postgres types that might be needed
156pub use tokio_postgres::{types::ToSql, Row, Error, Client};
157
158// Re-export crud operations
159pub use crate::crud_ops::{
160    CrudOps,
161    insert,
162    update,
163    delete,
164    fetch,
165    fetch_all,
166    select,
167    select_all
168};
169
170// Geriye dönük uyumluluk için eski fonksiyonları deprecated olarak dışa aktaralım
171#[allow(deprecated)]
172pub use crate::crud_ops::{
173    get,
174    get_all
175};
176
177pub use parsql_macros as macros;
178
179/// Re-export transaction modules
180/// 
181/// This provides easy access to transaction functions via `transactional` namespace.
182/// Functions include:
183/// - `begin`: Begin a new transaction
184/// - `tx_insert`: Insert a record within a transaction
185/// - `tx_update`: Update records within a transaction
186/// - `tx_delete`: Delete records within a transaction
187/// - `tx_fetch`: Get a single record within a transaction  
188/// - `tx_fetch_all`: Get multiple records within a transaction
189/// - `tx_select`: Execute a custom query and transform a single result within a transaction
190/// - `tx_select_all`: Execute a custom query and transform multiple results within a transaction
191/// - `tx_get`: (Deprecated) Get a single record within a transaction
192/// - `tx_get_all`: (Deprecated) Get multiple records within a transaction
193pub use transaction_ops as transactional;
194
195/// Trait for generating SQL queries.
196/// This trait is implemented by the derive macro `Queryable`, `Insertable`, `Updateable`, and `Deletable`.
197pub trait SqlQuery {
198    /// Returns the SQL query string.
199    fn query() -> String;
200}
201
202/// Trait for providing SQL parameters.
203/// This trait is implemented by the derive macro `SqlParams`.
204pub trait SqlParams {
205    /// Returns a vector of references to SQL parameters.
206    fn params(&self) -> Vec<&(dyn ToSql + Sync)>;
207}
208
209/// Trait for providing UPDATE parameters.
210/// This trait is implemented by the derive macro `UpdateParams`.
211pub trait UpdateParams {
212    /// Returns a vector of references to SQL parameters for UPDATE operations.
213    fn params(&self) -> Vec<&(dyn ToSql + Sync)>;
214}
215
216/// Trait for converting database rows to Rust structs.
217/// This trait is implemented by the derive macro `FromRow`.
218pub trait FromRow {
219    /// Converts a database row to a Rust struct.
220    /// 
221    /// # Arguments
222    /// * `row` - A reference to a database row
223    /// 
224    /// # Returns
225    /// * `Result<Self, Error>` - The converted struct or an error
226    fn from_row(row: &Row) -> Result<Self, Error>
227    where
228        Self: Sized;
229}