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}