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, ¶ms)?;
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, ¶ms)
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, ¶ms)
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, ¶ms)?;
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, ¶ms)?;
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, ¶ms)?;
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, ¶ms)?;
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}