parsql_deadpool_postgres/
pool_extensions.rs

1use deadpool_postgres::Pool;
2use tokio_postgres::{Error, Row};
3use crate::{SqlQuery, SqlParams, UpdateParams, FromRow};
4
5// Daha basit bir yaklaşım: PoolError'dan genel bir Error oluştur
6fn pool_err_to_io_err(e: deadpool_postgres::PoolError) -> Error {
7    // Bu özel fonksiyon tokio_postgres'in sağladığı timeout hatasını döndürür
8    // Güzel bir çözüm değil, ama çalışır bir örnek için kullanılabilir
9    let err = Error::__private_api_timeout();
10    
11    // Debug süreci için stderr'e hatayı yazdıralım
12    eprintln!("Pool bağlantı hatası: {}", e);
13    
14    err
15}
16
17/// CrudOps trait'i, Pool nesnesi için CRUD işlemlerini extension method olarak sağlar.
18/// Bu trait, Pool üzerinde doğrudan CRUD işlemlerini çağırmayı mümkün kılar.
19#[async_trait::async_trait]
20pub trait CrudOps {
21    /// Veritabanına yeni bir kayıt ekler.
22    /// 
23    /// # Parametreler
24    /// * `entity` - Eklenecek veri nesnesi (SqlQuery ve SqlParams trait'lerini uygulamalıdır)
25    /// 
26    /// # Dönüş Değeri
27    /// * `Result<u64, Error>` - Eklenen kayıt sayısı veya hata
28    async fn insert<T>(&self, entity: T) -> Result<u64, Error>
29    where
30        T: SqlQuery + SqlParams + Send + Sync;
31    
32    /// Veritabanındaki mevcut bir kaydı günceller.
33    /// 
34    /// # Parametreler
35    /// * `entity` - Güncelleme bilgilerini içeren veri nesnesi (SqlQuery ve UpdateParams trait'lerini uygulamalıdır)
36    /// 
37    /// # Dönüş Değeri
38    /// * `Result<u64, Error>` - Güncellenen kayıt sayısı veya hata
39    async fn update<T>(&self, entity: T) -> Result<u64, Error>
40    where
41        T: SqlQuery + UpdateParams + Send + Sync;
42    
43    /// Veritabanından bir kaydı siler.
44    /// 
45    /// # Parametreler
46    /// * `entity` - Silinecek kaydın bilgilerini içeren veri nesnesi (SqlQuery ve SqlParams trait'lerini uygulamalıdır)
47    /// 
48    /// # Dönüş Değeri
49    /// * `Result<u64, Error>` - Silinen kayıt sayısı veya hata
50    async fn delete<T>(&self, entity: T) -> Result<u64, Error>
51    where
52        T: SqlQuery + SqlParams + Send + Sync;
53    
54    /// Belirtilen kriterlere uygun tek bir kaydı getirir.
55    /// 
56    /// # Parametreler
57    /// * `params` - Sorgu parametreleri (SqlQuery, FromRow ve SqlParams trait'lerini uygulamalıdır)
58    /// 
59    /// # Dönüş Değeri
60    /// * `Result<T, Error>` - Getirilen kayıt veya hata
61    async fn get<T>(&self, params: &T) -> Result<T, Error>
62    where
63        T: SqlQuery + FromRow + SqlParams + Send + Sync;
64    
65    /// Belirtilen kriterlere uygun tüm kayıtları getirir.
66    /// 
67    /// # Parametreler
68    /// * `params` - Sorgu parametreleri (SqlQuery, FromRow ve SqlParams trait'lerini uygulamalıdır)
69    /// 
70    /// # Dönüş Değeri
71    /// * `Result<Vec<T>, Error>` - Getirilen kayıtlar veya hata
72    async fn get_all<T>(&self, params: &T) -> Result<Vec<T>, Error>
73    where
74        T: SqlQuery + FromRow + SqlParams + Send + Sync;
75    
76    /// Belirtilen özel dönüşüm fonksiyonunu kullanarak tek bir kaydı getirir.
77    /// 
78    /// # Parametreler
79    /// * `entity` - Sorgu parametreleri (SqlQuery ve SqlParams trait'lerini uygulamalıdır)
80    /// * `to_model` - Row -> R dönüşümünü gerçekleştiren fonksiyon
81    /// 
82    /// # Dönüş Değeri
83    /// * `Result<R, Error>` - Dönüştürülen kayıt veya hata
84    async fn select<T, R, F>(&self, entity: T, to_model: F) -> Result<R, Error>
85    where
86        T: SqlQuery + SqlParams + Send + Sync,
87        F: FnOnce(&Row) -> Result<R, Error> + Send + Sync;
88    
89    /// Belirtilen özel dönüşüm fonksiyonunu kullanarak tüm kayıtları getirir.
90    /// 
91    /// # Parametreler
92    /// * `entity` - Sorgu parametreleri (SqlQuery ve SqlParams trait'lerini uygulamalıdır)
93    /// * `to_model` - Row -> R dönüşümünü gerçekleştiren fonksiyon
94    /// 
95    /// # Dönüş Değeri
96    /// * `Result<Vec<R>, Error>` - Dönüştürülen kayıtlar veya hata
97    async fn select_all<T, R, F>(&self, entity: T, to_model: F) -> Result<Vec<R>, Error>
98    where
99        T: SqlQuery + SqlParams + Send + Sync,
100        F: Fn(&Row) -> R + Send + Sync;
101}
102
103/// Pool nesnesi için CrudOps trait'inin implementasyonu
104#[async_trait::async_trait]
105impl CrudOps for Pool {
106    async fn insert<T>(&self, entity: T) -> Result<u64, Error>
107    where
108        T: SqlQuery + SqlParams + Send + Sync
109    {
110        let client = self.get().await.map_err(pool_err_to_io_err)?;
111        let sql = T::query();
112        
113        if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
114            println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
115        }
116
117        let params = entity.params();
118        client.execute(&sql, &params).await
119    }
120
121    async fn update<T>(&self, entity: T) -> Result<u64, Error>
122    where
123        T: SqlQuery + UpdateParams + Send + Sync
124    {
125        let client = self.get().await.map_err(pool_err_to_io_err)?;
126        let sql = T::query();
127        
128        if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
129            println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
130        }
131
132        let params = entity.params();
133        client.execute(&sql, &params).await
134    }
135
136    async fn delete<T>(&self, entity: T) -> Result<u64, Error>
137    where
138        T: SqlQuery + SqlParams + Send + Sync
139    {
140        let client = self.get().await.map_err(pool_err_to_io_err)?;
141        let sql = T::query();
142        
143        if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
144            println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
145        }
146
147        let params = entity.params();
148        client.execute(&sql, &params).await
149    }
150
151    async fn get<T>(&self, params: &T) -> Result<T, Error>
152    where
153        T: SqlQuery + FromRow + SqlParams + Send + Sync
154    {
155        let client = self.get().await.map_err(pool_err_to_io_err)?;
156        let sql = T::query();
157        
158        if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
159            println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
160        }
161
162        let query_params = params.params();
163        let row = client.query_one(&sql, &query_params).await?;
164        T::from_row(&row)
165    }
166
167    async fn get_all<T>(&self, params: &T) -> Result<Vec<T>, Error>
168    where
169        T: SqlQuery + FromRow + SqlParams + Send + Sync
170    {
171        let client = self.get().await.map_err(pool_err_to_io_err)?;
172        let sql = T::query();
173        
174        if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
175            println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
176        }
177
178        let query_params = params.params();
179        let rows = client.query(&sql, &query_params).await?;
180        
181        let mut results = Vec::with_capacity(rows.len());
182        for row in rows {
183            results.push(T::from_row(&row)?);
184        }
185        
186        Ok(results)
187    }
188
189    async fn select<T, R, F>(&self, entity: T, to_model: F) -> Result<R, Error>
190    where
191        T: SqlQuery + SqlParams + Send + Sync,
192        F: FnOnce(&Row) -> Result<R, Error> + Send + Sync
193    {
194        let client = self.get().await.map_err(pool_err_to_io_err)?;
195        let sql = T::query();
196        
197        if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
198            println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
199        }
200
201        let params = entity.params();
202        let row = client.query_one(&sql, &params).await?;
203        to_model(&row)
204    }
205
206    async fn select_all<T, R, F>(&self, entity: T, to_model: F) -> Result<Vec<R>, Error>
207    where
208        T: SqlQuery + SqlParams + Send + Sync,
209        F: Fn(&Row) -> R + Send + Sync
210    {
211        let client = self.get().await.map_err(pool_err_to_io_err)?;
212        let sql = T::query();
213        
214        if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
215            println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
216        }
217
218        let params = entity.params();
219        let rows = client.query(&sql, &params).await?;
220        
221        let mut results = Vec::with_capacity(rows.len());
222        for row in rows {
223            results.push(to_model(&row));
224        }
225        
226        Ok(results)
227    }
228}