parsql_postgres/
lib.rs

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