parsql_postgres/
transaction_ops.rs

1use postgres::{types::FromSql, Error, Row, Transaction};
2use crate::traits::{SqlQuery, SqlParams, FromRow, UpdateParams, CrudOps};
3
4/// CrudOps trait implementasyonu Transaction<'_> için.
5/// Bu sayede transaction içinde tüm CRUD işlemleri extension metotları olarak kullanılabilir.
6impl<'a> CrudOps for Transaction<'a> {
7    fn insert<T: SqlQuery + SqlParams, P:for<'b> FromSql<'b> + Send + Sync>(&mut self, entity: T) -> Result<P, Error> {
8        let sql = T::query();
9        if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
10            println!("[PARSQL-POSTGRES] Execute SQL (Transaction): {}", sql);
11        }
12
13        let params = entity.params();
14        let row = self.query_one(&sql, &params)?;
15        row.try_get::<_, P>(0)
16    }
17
18    fn update<T: SqlQuery + UpdateParams>(&mut self, entity: T) -> Result<u64, Error> {
19        let sql = T::query();
20        if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
21            println!("[PARSQL-POSTGRES] Execute SQL (Transaction): {}", sql);
22        }
23
24        let params = entity.params();
25        self.execute(&sql, &params)
26    }
27
28    fn delete<T: SqlQuery + SqlParams>(&mut self, entity: T) -> Result<u64, Error> {
29        let sql = T::query();
30        if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
31            println!("[PARSQL-POSTGRES] Execute SQL (Transaction): {}", sql);
32        }
33
34        let params = entity.params();
35        self.execute(&sql, &params)
36    }
37
38    fn fetch<T: SqlQuery + FromRow + SqlParams>(&mut self, entity: &T) -> Result<T, Error> {
39        let sql = T::query();
40        if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
41            println!("[PARSQL-POSTGRES] Execute SQL (Transaction): {}", sql);
42        }
43        
44        let params = entity.params();
45        let row = self.query_one(&sql, &params)?;
46        T::from_row(&row)
47    }
48
49    fn fetch_all<T: SqlQuery + FromRow + SqlParams>(&mut self, entity: &T) -> Result<Vec<T>, Error> {
50        let sql = T::query();
51        if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
52            println!("[PARSQL-POSTGRES] Execute SQL (Transaction): {}", sql);
53        }
54        
55        let params = entity.params();
56        let rows = self.query(&sql, &params)?;
57        
58        rows.iter()
59            .map(|row| T::from_row(row))
60            .collect::<Result<Vec<_>, _>>()
61    }
62
63    fn select<T, F, R>(&mut self, entity: &T, to_model: F) -> Result<R, Error>
64    where
65        T: SqlQuery + SqlParams,
66        F: FnOnce(&Row) -> Result<R, Error>,
67    {
68        let sql = T::query();
69        if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
70            println!("[PARSQL-POSTGRES] Execute SQL (Transaction): {}", sql);
71        }
72
73        let params = entity.params();
74        let row = self.query_one(&sql, &params)?;
75        to_model(&row)
76    }
77
78    fn select_all<T, F, R>(&mut self, entity: &T, to_model: F) -> Result<Vec<R>, Error>
79    where
80        T: SqlQuery + SqlParams,
81        F: FnMut(&Row) -> Result<R, Error>,
82    {
83        let sql = T::query();
84        if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
85            println!("[PARSQL-POSTGRES] Execute SQL (Transaction): {}", sql);
86        }
87
88        let params = entity.params();
89        let rows = self.query(&sql, &params)?;
90        
91        rows.iter().map(to_model).collect()
92    }
93}
94
95/// # begin
96/// 
97/// Yeni bir transaction başlatır.
98/// 
99/// ## Parametreler
100/// - `client`: Veritabanı bağlantı istemcisi
101/// 
102/// ## Dönüş Değeri
103/// - `Result<Transaction<'_>, Error>`: Başarılı olursa, transaction nesnesini döner; hata durumunda Error döner
104/// 
105/// ## Örnek Kullanım
106/// ```rust,no_run
107/// use postgres::{Client, NoTls, Error};
108/// use parsql::postgres::transactional::begin;
109/// 
110/// fn main() -> Result<(), Error> {
111///     let mut client = Client::connect(
112///         "host=localhost user=postgres dbname=test",
113///         NoTls,
114///     )?;
115///     
116///     let tx = begin(&mut client)?;
117///     
118///     // İşlemler...
119///     
120///     // Transaction'ı tamamla
121///     tx.commit()?;
122///     Ok(())
123/// }
124/// ```
125pub fn begin<'a>(client: &'a mut postgres::Client) -> Result<Transaction<'a>, Error> {
126    client.transaction()
127}
128
129/// # tx_insert
130/// 
131/// Transaction içinde bir kaydı veritabanına ekler.
132/// 
133/// ## Parametreler
134/// - `tx`: Transaction nesnesi
135/// - `entity`: Eklenecek veri nesnesi (SqlQuery ve SqlParams trait'lerini implement etmeli)
136/// 
137/// ## Dönüş Değeri
138/// - `Result<(Transaction<'_>, P), Error>`: Başarılı olursa, transaction ve etkilenen kayıt sayısını döner; hata durumunda Error döner
139/// 
140/// ## Örnek Kullanım
141/// ```rust,no_run
142/// use postgres::{Client, NoTls, Error};
143/// use parsql::postgres::transactional::{begin, tx_insert};
144/// 
145/// #[derive(Insertable, SqlParams)]
146/// #[table("users")]
147/// pub struct InsertUser {
148///     pub name: String,
149///     pub email: String,
150/// }
151///
152/// fn main() -> Result<(), Error> {
153///     let mut client = Client::connect(
154///         "host=localhost user=postgres dbname=test",
155///         NoTls,
156///     )?;
157///     
158///     let mut tx = begin(&mut client)?;
159///     
160///     let insert_user = InsertUser {
161///         name: "John".to_string(),
162///         email: "[email protected]".to_string(),
163///     };
164///     
165///     let (tx, rows_affected) = tx_insert(tx, insert_user)?;
166///     
167///     // İşlemler devam edebilir...
168///     
169///     // Transaction'ı tamamla
170///     tx.commit()?;
171///     Ok(())
172/// }
173/// ```
174pub fn tx_insert<'a, T, P:for<'b> FromSql<'b> + Send + Sync>(mut tx: Transaction<'a>, entity: T) -> Result<(Transaction<'a>, P), Error>
175where
176    T: SqlQuery + SqlParams,
177{
178    let result = tx.insert::<T, P>(entity)?;
179    Ok((tx, result))
180}
181
182/// # tx_update
183/// 
184/// Transaction içinde bir kaydı günceller.
185/// 
186/// ## Parametreler
187/// - `tx`: Transaction nesnesi
188/// - `entity`: Güncellenecek veri nesnesi (SqlQuery ve UpdateParams trait'lerini implement etmeli)
189/// 
190/// ## Dönüş Değeri
191/// - `Result<(Transaction<'_>, u64), Error>`: Başarılı olursa, transaction ve etkilenen kayıt sayısını döner; hata durumunda Error döner
192/// 
193/// ## Örnek Kullanım
194/// ```rust,no_run
195/// use postgres::{Client, NoTls, Error};
196/// use parsql::postgres::transactional::{begin, tx_update};
197/// 
198/// #[derive(Updateable, UpdateParams)]
199/// #[table("users")]
200/// #[update("name, email")]
201/// #[where_clause("id = $")]
202/// pub struct UpdateUser {
203///     pub id: i32,
204///     pub name: String,
205///     pub email: String,
206/// }
207///
208/// fn main() -> Result<(), Error> {
209///     let mut client = Client::connect(
210///         "host=localhost user=postgres dbname=test",
211///         NoTls,
212///     )?;
213///     
214///     let mut tx = begin(&mut client)?;
215///     
216///     let update_user = UpdateUser {
217///         id: 1,
218///         name: "John Updated".to_string(),
219///         email: "[email protected]".to_string(),
220///     };
221///     
222///     let (tx, rows_affected) = tx_update(tx, update_user)?;
223///     
224///     // İşlemler devam edebilir...
225///     
226///     // Transaction'ı tamamla
227///     tx.commit()?;
228///     Ok(())
229/// }
230/// ```
231pub fn tx_update<'a, T>(mut tx: Transaction<'a>, entity: T) -> Result<(Transaction<'a>, u64), Error>
232where
233    T: SqlQuery + UpdateParams,
234{
235    let result = tx.update(entity)?;
236    Ok((tx, result))
237}
238
239/// # tx_delete
240/// 
241/// Transaction içinde bir kaydı siler.
242/// 
243/// ## Parametreler
244/// - `tx`: Transaction nesnesi
245/// - `entity`: Silinecek veri nesnesi (SqlQuery ve SqlParams trait'lerini implement etmeli)
246/// 
247/// ## Dönüş Değeri
248/// - `Result<(Transaction<'_>, u64), Error>`: Başarılı olursa, transaction ve etkilenen kayıt sayısını döner; hata durumunda Error döner
249/// 
250/// ## Örnek Kullanım
251/// ```rust,no_run
252/// use postgres::{Client, NoTls, Error};
253/// use parsql::postgres::transactional::{begin, tx_delete};
254/// 
255/// #[derive(Deletable, SqlParams)]
256/// #[table("users")]
257/// #[where_clause("id = $")]
258/// pub struct DeleteUser {
259///     pub id: i32,
260/// }
261///
262/// fn main() -> Result<(), Error> {
263///     let mut client = Client::connect(
264///         "host=localhost user=postgres dbname=test",
265///         NoTls,
266///     )?;
267///     
268///     let mut tx = begin(&mut client)?;
269///     
270///     let delete_user = DeleteUser { id: 1 };
271///     
272///     let (tx, rows_affected) = tx_delete(tx, delete_user)?;
273///     
274///     // İşlemler devam edebilir...
275///     
276///     // Transaction'ı tamamla
277///     tx.commit()?;
278///     Ok(())
279/// }
280/// ```
281pub fn tx_delete<'a, T>(mut tx: Transaction<'a>, entity: T) -> Result<(Transaction<'a>, u64), Error>
282where
283    T: SqlQuery + SqlParams,
284{
285    let result = tx.delete(entity)?;
286    Ok((tx, result))
287}
288
289/// # tx_fetch
290/// 
291/// Transaction içinde tek bir kaydı getirir.
292/// 
293/// ## Parametreler
294/// - `tx`: Transaction nesnesi
295/// - `entity`: Sorgu parametresi nesnesi (SqlQuery, FromRow ve SqlParams trait'lerini implement etmeli)
296/// 
297/// ## Dönüş Değeri
298/// - `Result<(Transaction<'_>, T), Error>`: Başarılı olursa, transaction ve bulunan kaydı döner; hata durumunda Error döner
299/// 
300/// ## Örnek Kullanım
301/// ```rust,no_run
302/// use postgres::{Client, NoTls, Error};
303/// use parsql::postgres::transactional::{begin, tx_fetch};
304/// 
305/// #[derive(Queryable, FromRow, SqlParams)]
306/// #[table("users")]
307/// #[where_clause("id = $")]
308/// pub struct GetUser {
309///     pub id: i32,
310///     pub name: String,
311///     pub email: String,
312/// }
313///
314/// fn main() -> Result<(), Error> {
315///     let mut client = Client::connect(
316///         "host=localhost user=postgres dbname=test",
317///         NoTls,
318///     )?;
319///     
320///     let mut tx = begin(&mut client)?;
321///     
322///     let get_user = GetUser {
323///         id: 1,
324///         name: String::new(),
325///         email: String::new(),
326///     };
327///     
328///     let (tx, user) = tx_fetch(tx, &get_user)?;
329///     
330///     // İşlemler devam edebilir...
331///     
332///     // Transaction'ı tamamla
333///     tx.commit()?;
334///     Ok(())
335/// }
336/// ```
337pub fn tx_fetch<'a, T>(mut tx: Transaction<'a>, entity: &T) -> Result<(Transaction<'a>, T), Error>
338where
339    T: SqlQuery + FromRow + SqlParams,
340{
341    let result = tx.fetch(entity)?;
342    Ok((tx, result))
343}
344
345/// # tx_fetch_all
346/// 
347/// Transaction içinde birden fazla kaydı getirir.
348/// 
349/// ## Parametreler
350/// - `tx`: Transaction nesnesi
351/// - `entity`: Sorgu parametresi nesnesi (SqlQuery, FromRow ve SqlParams trait'lerini implement etmeli)
352/// 
353/// ## Dönüş Değeri
354/// - `Result<(Transaction<'_>, Vec<T>), Error>`: Başarılı olursa, transaction ve bulunan kayıtların listesini döner; hata durumunda Error döner
355/// 
356/// ## Örnek Kullanım
357/// ```rust,no_run
358/// use postgres::{Client, NoTls, Error};
359/// use parsql::postgres::transactional::{begin, tx_fetch_all};
360/// 
361/// #[derive(Queryable, FromRow, SqlParams)]
362/// #[table("users")]
363/// #[where_clause("active = $")]
364/// pub struct GetUsers {
365///     pub active: bool,
366///     pub id: i32,
367///     pub name: String,
368///     pub email: String,
369/// }
370///
371/// fn main() -> Result<(), Error> {
372///     let mut client = Client::connect(
373///         "host=localhost user=postgres dbname=test",
374///         NoTls,
375///     )?;
376///     
377///     let mut tx = begin(&mut client)?;
378///     
379///     let get_users = GetUsers {
380///         active: true,
381///         id: 0,
382///         name: String::new(),
383///         email: String::new(),
384///     };
385///     
386///     let (tx, users) = tx_fetch_all(tx, &get_users)?;
387///     
388///     // İşlemler devam edebilir...
389///     
390///     // Transaction'ı tamamla
391///     tx.commit()?;
392///     Ok(())
393/// }
394/// ```
395pub fn tx_fetch_all<'a, T>(mut tx: Transaction<'a>, entity: &T) -> Result<(Transaction<'a>, Vec<T>), Error>
396where
397    T: SqlQuery + FromRow + SqlParams,
398{
399    let result = tx.fetch_all(entity)?;
400    Ok((tx, result))
401}
402
403/// # tx_select
404/// 
405/// Transaction içinde özel bir sorgu çalıştırır ve sonucu dönüştürür.
406/// 
407/// ## Parametreler
408/// - `tx`: Transaction nesnesi
409/// - `entity`: Sorgu parametresi nesnesi (SqlQuery ve SqlParams trait'lerini implement etmeli)
410/// - `to_model`: Row nesnesini hedef nesne tipine dönüştüren fonksiyon
411/// 
412/// ## Dönüş Değeri
413/// - `Result<(Transaction<'_>, R), Error>`: Başarılı olursa, transaction ve dönüştürülmüş nesneyi döner; hata durumunda Error döner
414pub fn tx_select<'a, T, F, R>(mut tx: Transaction<'a>, entity: &T, to_model: F) -> Result<(Transaction<'a>, R), Error>
415where
416    T: SqlQuery + SqlParams,
417    F: FnOnce(&Row) -> Result<R, Error>,
418{
419    let result = tx.select(entity, to_model)?;
420    Ok((tx, result))
421}
422
423/// # tx_select_all
424/// 
425/// Transaction içinde özel bir sorgu çalıştırır ve tüm sonuçları dönüştürür.
426/// 
427/// ## Parametreler
428/// - `tx`: Transaction nesnesi
429/// - `entity`: Sorgu parametresi nesnesi (SqlQuery ve SqlParams trait'lerini implement etmeli)
430/// - `to_model`: Row nesnesini hedef nesne tipine dönüştüren fonksiyon
431/// 
432/// ## Dönüş Değeri
433/// - `Result<(Transaction<'_>, Vec<R>), Error>`: Başarılı olursa, transaction ve dönüştürülmüş nesnelerin listesini döner; hata durumunda Error döner
434pub fn tx_select_all<'a, T, F, R>(mut tx: Transaction<'a>, entity: &T, to_model: F) -> Result<(Transaction<'a>, Vec<R>), Error>
435where
436    T: SqlQuery + SqlParams,
437    F: FnMut(&Row) -> Result<R, Error>,
438{
439    let result = tx.select_all(entity, to_model)?;
440    Ok((tx, result))
441}
442
443// Geriye dönük uyumluluk için eski tx_get fonksiyonunu koruyalım
444#[deprecated(
445    since = "0.2.0",
446    note = "Renamed to `tx_fetch`. Please use `tx_fetch` function instead."
447)]
448/// # tx_get
449/// 
450/// Transaction içinde tek bir kaydı getirir.
451/// 
452/// This function is deprecated. Please use `tx_fetch` instead.
453pub fn tx_get<'a, T>(mut tx: Transaction<'a>, entity: &T) -> Result<(Transaction<'a>, T), Error>
454where
455    T: SqlQuery + FromRow + SqlParams,
456{
457    let result = tx.fetch(entity)?;
458    Ok((tx, result))
459}
460
461// Geriye dönük uyumluluk için eski tx_get_all fonksiyonunu koruyalım
462#[deprecated(
463    since = "0.2.0",
464    note = "Renamed to `tx_fetch_all`. Please use `tx_fetch_all` function instead."
465)]
466/// # tx_get_all
467/// 
468/// Transaction içinde birden fazla kaydı getirir.
469/// 
470/// This function is deprecated. Please use `tx_fetch_all` instead.
471pub fn tx_get_all<'a, T>(mut tx: Transaction<'a>, entity: &T) -> Result<(Transaction<'a>, Vec<T>), Error>
472where
473    T: SqlQuery + FromRow + SqlParams,
474{
475    let result = tx.fetch_all(entity)?;
476    Ok((tx, result))
477}