parsql_deadpool_postgres/crud_ops.rs
1use deadpool_postgres::{Pool, PoolError};
2use postgres::types::FromSqlOwned;
3//use postgres::types::FromSql;
4use crate::traits::{CrudOps, FromRow, SqlCommand, SqlParams, SqlQuery, UpdateParams};
5use tokio_postgres::{types::FromSql, Error, Row};
6
7// Daha basit bir yaklaşım: PoolError'dan genel bir Error oluştur
8fn pool_err_to_io_err(e: PoolError) -> Error {
9 // Bu özel fonksiyon tokio_postgres'in sağladığı timeout hatasını döndürür
10 // Güzel bir çözüm değil, ama çalışır bir örnek için kullanılabilir
11 let err = Error::__private_api_timeout();
12
13 // Debug süreci için stderr'e hatayı yazdıralım
14 eprintln!("Pool bağlantı hatası: {}", e);
15
16 err
17}
18
19/// # insert
20///
21/// Deadpool bağlantı havuzunu kullanarak veritabanına yeni bir kayıt ekler.
22///
23/// ## Parametreler
24/// - `pool`: Deadpool bağlantı havuzu
25/// - `entity`: Eklenecek veri nesnesi (SqlQuery ve SqlParams trait'lerini uygulamalıdır)
26///
27/// ## Dönüş Değeri
28/// - `Result<i64, Error>`: Başarılı olursa, eklenen kayıt ID'sini döndürür; başarısız olursa, Error döndürür
29///
30/// ## Yapı Tanımı
31/// Bu fonksiyonla kullanılan yapılar aşağıdaki derive makrolarıyla işaretlenmelidir:
32///
33/// ```rust,no_run
34/// #[derive(Insertable, SqlParams)] // Gerekli makrolar
35/// #[table("tablo_adi")] // Ekleme yapılacak tablo adı
36/// pub struct VeriModeli {
37/// pub alan1: String,
38/// pub alan2: i32,
39/// // ...
40/// }
41/// ```
42///
43/// - `Insertable`: Otomatik olarak SQL INSERT ifadeleri oluşturur
44/// - `SqlParams`: Otomatik olarak SQL parametreleri oluşturur
45/// - `#[table("tablo_adi")]`: Ekleme yapılacak tablo adını belirtir
46///
47/// ## Kullanım Örneği
48/// ```rust,no_run
49/// use deadpool_postgres::{Config, Runtime, Pool};
50/// use tokio_postgres::{NoTls, Error};
51/// use parsql::tokio_postgres::pool_crud_ops::insert;
52///
53/// #[derive(Insertable, SqlParams)]
54/// #[table("users")]
55/// pub struct InsertUser {
56/// pub name: String,
57/// pub email: String,
58/// pub state: i16,
59/// }
60///
61/// #[tokio::main]
62/// async fn main() -> Result<(), Error> {
63/// let mut cfg = Config::new();
64/// cfg.host = Some("localhost".to_string());
65/// cfg.dbname = Some("test".to_string());
66///
67/// let pool = cfg.create_pool(Some(Runtime::Tokio1), NoTls).unwrap();
68///
69/// let insert_user = InsertUser {
70/// name: "John".to_string(),
71/// email: "john@example.com".to_string(),
72/// state: 1_i16,
73/// };
74///
75/// let insert_result = insert(&pool, insert_user).await?;
76/// println!("Insert result: {:?}", insert_result);
77/// Ok(())
78/// }
79/// ```
80// pub async fn insert<T: SqlQuery + SqlParams, P:for<'a> FromSql<'a> + Send + Sync>(
81// pool: &Pool,
82// entity: T,
83// ) -> Result<P, Error> {
84// let client = pool.get().await.map_err(pool_err_to_io_err)?;
85// let sql = T::query();
86
87// if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
88// println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
89// }
90
91// let params = entity.params();
92// let row = client.query_one(&sql, ¶ms).await?;
93// row.try_get::<_, P>(0)
94// }
95
96pub async fn insert<T, P>(pool: &Pool, entity: T) -> Result<P, Error>
97where
98 T: SqlCommand + SqlParams,
99 P: FromSqlOwned + Send + Sync,
100{
101 let client = pool.get().await.map_err(pool_err_to_io_err)?;
102 let sql = T::query();
103
104 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
105 println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
106 }
107
108 let params = entity.params();
109 let row = client.query_one(&sql, ¶ms).await?;
110 row.try_get::<_, P>(0)
111}
112
113/// # update
114///
115/// Deadpool bağlantı havuzunu kullanarak veritabanındaki mevcut bir kaydı günceller.
116///
117/// ## Parametreler
118/// - `pool`: Deadpool bağlantı havuzu
119/// - `entity`: Güncelleme bilgilerini içeren veri nesnesi (SqlQuery ve UpdateParams trait'lerini uygulamalıdır)
120///
121/// ## Dönüş Değeri
122/// - `Result<bool, Error>`: Başarılı olursa, true döndürür; başarısız olursa, Error döndürür
123///
124/// ## Yapı Tanımı
125/// Bu fonksiyonla kullanılan yapılar aşağıdaki derive makrolarıyla işaretlenmelidir:
126///
127/// ```rust,no_run
128/// #[derive(Updateable, UpdateParams)] // Gerekli makrolar
129/// #[table("tablo_adi")] // Güncellenecek tablo adı
130/// #[update("alan1, alan2")] // Güncellenecek alanlar (isteğe bağlı)
131/// #[where_clause("id = $")] // Güncelleme koşulu
132/// pub struct VeriModeli {
133/// pub id: i32, // Koşulda kullanılan alanlar
134/// pub alan1: String, // Güncellenecek alanlar
135/// pub alan2: i32, // Güncellenecek alanlar
136/// // ...
137/// }
138/// ```
139///
140/// - `Updateable`: Otomatik olarak SQL UPDATE ifadeleri oluşturur
141/// - `UpdateParams`: Otomatik olarak güncelleme parametreleri oluşturur
142/// - `#[table("tablo_adi")]`: Güncellenecek tablo adını belirtir
143/// - `#[update("alan1, alan2")]`: Hangi alanların güncelleneceğini belirtir (belirtilmezse, tüm alanlar güncellenir)
144/// - `#[where_clause("id = $")]`: Güncelleme koşulunu belirtir (`$` parametre değeri ile değiştirilir)
145///
146/// ## Kullanım Örneği
147/// ```rust,no_run
148/// use deadpool_postgres::{Config, Runtime, Pool};
149/// use tokio_postgres::{NoTls, Error};
150/// use parsql::tokio_postgres::pool_crud_ops::update;
151///
152/// #[derive(Updateable, UpdateParams)]
153/// #[table("users")]
154/// #[update("name, email")]
155/// #[where_clause("id = $")]
156/// pub struct UpdateUser {
157/// pub id: i32,
158/// pub name: String,
159/// pub email: String,
160/// pub state: i16, // update özniteliğinde belirtilmediği için bu alan güncellenmez
161/// }
162///
163/// #[tokio::main]
164/// async fn main() -> Result<(), Error> {
165/// let mut cfg = Config::new();
166/// cfg.host = Some("localhost".to_string());
167/// cfg.dbname = Some("test".to_string());
168///
169/// let pool = cfg.create_pool(Some(Runtime::Tokio1), NoTls).unwrap();
170///
171/// let update_user = UpdateUser {
172/// id: 1,
173/// name: String::from("John"),
174/// email: String::from("john@example.com"),
175/// state: 2,
176/// };
177///
178/// let update_result = update(&pool, update_user).await?;
179/// println!("Update result: {:?}", update_result);
180/// Ok(())
181/// }
182/// ```
183pub async fn update<T: SqlCommand + UpdateParams>(pool: &Pool, entity: T) -> Result<bool, Error> {
184 let client = pool.get().await.map_err(pool_err_to_io_err)?;
185 let sql = T::query();
186
187 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
188 println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
189 }
190
191 let params = entity.params();
192 match client.execute(&sql, ¶ms).await {
193 Ok(_) => Ok(true),
194 Err(e) => Err(e),
195 }
196}
197
198/// # delete
199///
200/// Deadpool bağlantı havuzunu kullanarak veritabanından bir kaydı siler.
201///
202/// ## Parametreler
203/// - `pool`: Deadpool bağlantı havuzu
204/// - `entity`: Silme bilgilerini içeren veri nesnesi (SqlQuery ve SqlParams trait'lerini uygulamalıdır)
205///
206/// ## Dönüş Değeri
207/// - `Result<u64, Error>`: Başarılı olursa, silinen kayıt sayısını döndürür; başarısız olursa, Error döndürür
208///
209/// ## Yapı Tanımı
210/// Bu fonksiyonla kullanılan yapılar aşağıdaki derive makrolarıyla işaretlenmelidir:
211///
212/// ```rust,no_run
213/// #[derive(Deletable, SqlParams)] // Gerekli makrolar
214/// #[table("tablo_adi")] // Silinecek tablo adı
215/// #[where_clause("id = $")] // Silme koşulu
216/// pub struct VeriModeli {
217/// pub id: i32, // Koşulda kullanılan alanlar
218/// // Diğer alanlar eklenebilir, ancak genellikle sadece koşul alanları gereklidir
219/// }
220/// ```
221///
222/// - `Deletable`: Otomatik olarak SQL DELETE ifadeleri oluşturur
223/// - `SqlParams`: Otomatik olarak SQL parametreleri oluşturur
224/// - `#[table("tablo_adi")]`: Silinecek tablo adını belirtir
225/// - `#[where_clause("id = $")]`: Silme koşulunu belirtir (`$` parametre değeri ile değiştirilir)
226///
227/// ## Kullanım Örneği
228/// ```rust,no_run
229/// use deadpool_postgres::{Config, Runtime, Pool};
230/// use tokio_postgres::{NoTls, Error};
231/// use parsql::tokio_postgres::pool_crud_ops::delete;
232///
233/// #[derive(Deletable, SqlParams)]
234/// #[table("users")]
235/// #[where_clause("id = $")]
236/// pub struct DeleteUser {
237/// pub id: i32,
238/// }
239///
240/// #[tokio::main]
241/// async fn main() -> Result<(), Error> {
242/// let mut cfg = Config::new();
243/// cfg.host = Some("localhost".to_string());
244/// cfg.dbname = Some("test".to_string());
245///
246/// let pool = cfg.create_pool(Some(Runtime::Tokio1), NoTls).unwrap();
247///
248/// let delete_user = DeleteUser { id: 6 };
249/// let delete_result = delete(&pool, delete_user).await?;
250///
251/// println!("Delete result: {:?}", delete_result);
252/// Ok(())
253/// }
254/// ```
255pub async fn delete<T: SqlCommand + SqlParams>(pool: &Pool, entity: T) -> Result<u64, Error> {
256 let client = pool.get().await.map_err(pool_err_to_io_err)?;
257 let sql = T::query();
258
259 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
260 println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
261 }
262
263 let params = entity.params();
264 client.execute(&sql, ¶ms).await
265}
266
267/// # fetch
268///
269/// Deadpool bağlantı havuzunu kullanarak veritabanından bir kaydı alır.
270///
271/// ## Parametreler
272/// - `pool`: Deadpool bağlantı havuzu
273/// - `params`: Sorgu parametrelerini içeren veri nesnesi (SqlQuery, FromRow ve SqlParams trait'lerini uygulamalıdır)
274///
275/// ## Dönüş Değeri
276/// - `Result<T, Error>`: Başarılı olursa, alınan kaydı döndürür; başarısız olursa, Error döndürür
277///
278/// ## Yapı Tanımı
279/// Bu fonksiyonla kullanılan yapılar aşağıdaki derive makrolarıyla işaretlenmelidir:
280///
281/// ```rust,no_run
282/// #[derive(Queryable, SqlParams, FromRow)] // Gerekli makrolar
283/// #[table("tablo_adi")] // Sorgulanacak tablo adı
284/// #[where_clause("id = $")] // Sorgu koşulu
285/// pub struct VeriModeli {
286/// pub id: i32, // Koşulda kullanılan alanlar
287/// pub alan1: String, // Getirilen veri alanları
288/// pub alan2: i32, // Getirilen veri alanları
289/// // ...
290/// }
291/// ```
292///
293/// - `Queryable`: Otomatik olarak SQL SELECT ifadeleri oluşturur
294/// - `SqlParams`: Otomatik olarak SQL parametreleri oluşturur
295/// - `FromRow`: Veritabanı satırını yapıya dönüştürür
296/// - `#[table("tablo_adi")]`: Sorgulanacak tablo adını belirtir
297/// - `#[where_clause("id = $")]`: Sorgu koşulunu belirtir (`$` parametre değeri ile değiştirilir)
298///
299/// ## Kullanım Örneği
300/// ```rust,no_run
301/// use deadpool_postgres::{Config, Runtime, Pool};
302/// use tokio_postgres::{NoTls, Error};
303/// use parsql::tokio_postgres::pool_crud_ops::fetch;
304///
305/// #[derive(Queryable, SqlParams, FromRow)]
306/// #[table("users")]
307/// #[where_clause("id = $")]
308/// pub struct GetUser {
309/// pub id: i32,
310/// pub name: String,
311/// pub email: String,
312/// pub state: i16,
313/// }
314///
315/// impl GetUser {
316/// pub fn new(id: i32) -> Self {
317/// Self {
318/// id,
319/// name: String::new(),
320/// email: String::new(),
321/// state: 0,
322/// }
323/// }
324/// }
325///
326/// #[tokio::main]
327/// async fn main() -> Result<(), Error> {
328/// let mut cfg = Config::new();
329/// cfg.host = Some("localhost".to_string());
330/// cfg.dbname = Some("test".to_string());
331///
332/// let pool = cfg.create_pool(Some(Runtime::Tokio1), NoTls).unwrap();
333///
334/// let user_params = GetUser::new(1);
335/// let user = fetch(&pool, &user_params).await?;
336///
337/// println!("User: {:?}", user);
338/// Ok(())
339/// }
340/// ```
341pub async fn fetch<P, R>(pool: &Pool, params: &P) -> Result<R, Error>
342where
343 P: SqlQuery<R> + SqlParams,
344 R: FromRow,
345{
346 let client = pool.get().await.map_err(pool_err_to_io_err)?;
347 let sql = P::query();
348
349 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
350 println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
351 }
352
353 let query_params = params.params();
354 let row = client.query_one(&sql, &query_params).await?;
355 R::from_row(&row)
356}
357
358/// # fetch_all
359///
360/// Deadpool bağlantı havuzunu kullanarak veritabanından birden fazla kaydı alır.
361///
362/// ## Parametreler
363/// - `pool`: Deadpool bağlantı havuzu
364/// - `params`: Sorgu parametrelerini içeren veri nesnesi (SqlQuery, FromRow ve SqlParams trait'lerini uygulamalıdır)
365///
366/// ## Dönüş Değeri
367/// - `Result<Vec<T>, Error>`: Başarılı olursa, alınan kayıtları içeren bir vektör döndürür; başarısız olursa, Error döndürür
368///
369/// ## Yapı Tanımı
370/// Bu fonksiyonla kullanılan yapılar aşağıdaki derive makrolarıyla işaretlenmelidir:
371///
372/// ```rust,no_run
373/// #[derive(Queryable, SqlParams, FromRow)] // Gerekli makrolar
374/// #[table("tablo_adi")] // Sorgulanacak tablo adı
375/// #[where_clause("state = $")] // Sorgu koşulu
376/// pub struct VeriModeli {
377/// pub id: i32, // Alınacak alanlar
378/// pub alan1: String, // Alınacak alanlar
379/// pub alan2: i32, // Alınacak alanlar
380/// pub state: i16, // Koşulda kullanılan alanlar
381/// // ...
382/// }
383/// ```
384///
385/// - `Queryable`: Otomatik olarak SQL SELECT ifadeleri oluşturur
386/// - `SqlParams`: Otomatik olarak SQL parametreleri oluşturur
387/// - `FromRow`: Veritabanı satırını yapıya dönüştürür
388/// - `#[table("tablo_adi")]`: Sorgulanacak tablo adını belirtir
389/// - `#[where_clause("state = $")]`: Sorgu koşulunu belirtir (`$` parametre değeri ile değiştirilir)
390///
391/// ## Kullanım Örneği
392/// ```rust,no_run
393/// use deadpool_postgres::{Config, Runtime, Pool};
394/// use tokio_postgres::{NoTls, Error};
395/// use parsql::tokio_postgres::pool_crud_ops::fetch_all;
396///
397/// #[derive(Queryable, SqlParams, FromRow)]
398/// #[table("users")]
399/// #[where_clause("state = $")]
400/// pub struct ListUsers {
401/// pub id: i32,
402/// pub name: String,
403/// pub email: String,
404/// pub state: i16,
405/// }
406///
407/// impl ListUsers {
408/// pub fn new(state: i16) -> Self {
409/// Self {
410/// id: 0,
411/// name: String::new(),
412/// email: String::new(),
413/// state,
414/// }
415/// }
416/// }
417///
418/// #[tokio::main]
419/// async fn main() -> Result<(), Error> {
420/// let mut cfg = Config::new();
421/// cfg.host = Some("localhost".to_string());
422/// cfg.dbname = Some("test".to_string());
423///
424/// let pool = cfg.create_pool(Some(Runtime::Tokio1), NoTls).unwrap();
425///
426/// let user_params = ListUsers::new(1);
427/// let users = fetch_all(&pool, &user_params).await?;
428///
429/// println!("Users: {:?}", users);
430/// Ok(())
431/// }
432/// ```
433pub async fn fetch_all<P, R>(pool: &Pool, params: &P) -> Result<Vec<R>, Error>
434where
435 P: SqlQuery<R> + SqlParams,
436 R: FromRow,
437{
438 let client = pool.get().await.map_err(pool_err_to_io_err)?;
439 let sql = P::query();
440
441 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
442 println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
443 }
444
445 let query_params = params.params();
446 let rows = client.query(&sql, &query_params).await?;
447
448 let mut results = Vec::with_capacity(rows.len());
449 for row in rows {
450 results.push(R::from_row(&row)?);
451 }
452
453 Ok(results)
454}
455
456/// # select
457///
458/// Deadpool bağlantı havuzunu kullanarak özel bir model dönüştürücü fonksiyon ile veritabanından bir kayıt seçer.
459///
460/// ## Parametreler
461/// - `pool`: Deadpool bağlantı havuzu
462/// - `entity`: Sorgu parametrelerini içeren veri nesnesi (SqlQuery ve SqlParams trait'lerini uygulamalıdır)
463/// - `to_model`: Satırı modele dönüştüren fonksiyon
464///
465/// ## Dönüş Değeri
466/// - `Result<R, Error>`: Başarılı olursa, dönüştürülen modeli döndürür; başarısız olursa, Error döndürür
467///
468/// ## Kullanım Örneği
469/// ```rust,no_run
470/// use deadpool_postgres::{Config, Runtime, Pool};
471/// use tokio_postgres::{NoTls, Error, Row};
472/// use parsql::tokio_postgres::pool_crud_ops::select;
473///
474/// #[derive(Queryable, SqlParams)]
475/// #[table("users")]
476/// #[where_clause("id = $")]
477/// pub struct UserQuery {
478/// pub id: i32,
479/// }
480///
481/// pub struct UserModel {
482/// pub id: i32,
483/// pub name: String,
484/// pub email: String,
485/// pub is_active: bool,
486/// }
487///
488/// impl UserQuery {
489/// pub fn new(id: i32) -> Self {
490/// Self { id }
491/// }
492/// }
493///
494/// fn row_to_user(row: &Row) -> Result<UserModel, Error> {
495/// Ok(UserModel {
496/// id: row.try_get("id")?,
497/// name: row.try_get("name")?,
498/// email: row.try_get("email")?,
499/// is_active: row.try_get::<_, i16>("state")? == 1,
500/// })
501/// }
502///
503/// #[tokio::main]
504/// async fn main() -> Result<(), Error> {
505/// let mut cfg = Config::new();
506/// cfg.host = Some("localhost".to_string());
507/// cfg.dbname = Some("test".to_string());
508///
509/// let pool = cfg.create_pool(Some(Runtime::Tokio1), NoTls).unwrap();
510///
511/// let query = UserQuery::new(1);
512/// let user = select(&pool, query, row_to_user).await?;
513///
514/// println!("User: {:?}", user);
515/// Ok(())
516/// }
517/// ```
518pub async fn select<T: SqlQuery<T> + SqlParams, R, F>(
519 pool: &Pool,
520 entity: T,
521 to_model: F,
522) -> Result<R, Error>
523where
524 F: Fn(&Row) -> Result<R, Error>,
525{
526 let client = pool.get().await.map_err(pool_err_to_io_err)?;
527 let sql = T::query();
528
529 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
530 println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
531 }
532
533 let params = entity.params();
534 let row = client.query_one(&sql, ¶ms).await?;
535 to_model(&row)
536}
537
538/// # select_all
539///
540/// Deadpool bağlantı havuzunu kullanarak özel bir model dönüştürücü fonksiyon ile veritabanından birden fazla kayıt seçer.
541///
542/// ## Parametreler
543/// - `pool`: Deadpool bağlantı havuzu
544/// - `entity`: Sorgu parametrelerini içeren veri nesnesi (SqlQuery ve SqlParams trait'lerini uygulamalıdır)
545/// - `to_model`: Satırı modele dönüştüren fonksiyon
546///
547/// ## Dönüş Değeri
548/// - `Result<Vec<R>, Error>`: Başarılı olursa, dönüştürülen modelleri içeren bir vektör döndürür; başarısız olursa, Error döndürür
549///
550/// ## Kullanım Örneği
551/// ```rust,no_run
552/// use deadpool_postgres::{Config, Runtime, Pool};
553/// use tokio_postgres::{NoTls, Error, Row};
554/// use parsql::tokio_postgres::pool_crud_ops::select_all;
555///
556/// #[derive(Queryable, SqlParams)]
557/// #[table("users")]
558/// #[where_clause("state = $")]
559/// pub struct UsersQuery {
560/// pub state: i16,
561/// }
562///
563/// pub struct UserModel {
564/// pub id: i32,
565/// pub name: String,
566/// pub email: String,
567/// pub is_active: bool,
568/// }
569///
570/// impl UsersQuery {
571/// pub fn new(state: i16) -> Self {
572/// Self { state }
573/// }
574/// }
575///
576/// fn row_to_user(row: &Row) -> UserModel {
577/// UserModel {
578/// id: row.get("id"),
579/// name: row.get("name"),
580/// email: row.get("email"),
581/// is_active: row.get::<_, i16>("state") == 1,
582/// }
583/// }
584///
585/// #[tokio::main]
586/// async fn main() -> Result<(), Error> {
587/// let mut cfg = Config::new();
588/// cfg.host = Some("localhost".to_string());
589/// cfg.dbname = Some("test".to_string());
590///
591/// let pool = cfg.create_pool(Some(Runtime::Tokio1), NoTls).unwrap();
592///
593/// let query = UsersQuery::new(1);
594/// let users = select_all(&pool, query, row_to_user).await?;
595///
596/// println!("Users: {:?}", users);
597/// Ok(())
598/// }
599/// ```
600pub async fn select_all<T: SqlQuery<T> + SqlParams, R, F>(
601 pool: &Pool,
602 entity: T,
603 to_model: F,
604) -> Result<Vec<R>, Error>
605where
606 F: Fn(&Row) -> R,
607{
608 let client = pool.get().await.map_err(pool_err_to_io_err)?;
609 let sql = T::query();
610
611 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
612 println!("[PARSQL-TOKIO-POSTGRES-POOL] Execute SQL: {}", sql);
613 }
614
615 let params = entity.params();
616 let rows = client.query(&sql, ¶ms).await?;
617
618 let mut results = Vec::with_capacity(rows.len());
619 for row in rows {
620 results.push(to_model(&row));
621 }
622
623 Ok(results)
624}
625
626// Deprecated functions for backward compatibility
627#[deprecated(
628 since = "0.2.0",
629 note = "Renamed to `fetch`. Please use `fetch` function instead."
630)]
631pub async fn get<T: SqlQuery<T> + FromRow + SqlParams>(
632 pool: &Pool,
633 params: &T,
634) -> Result<T, Error> {
635 fetch(pool, params).await
636}
637
638#[deprecated(
639 since = "0.2.0",
640 note = "Renamed to `fetch_all`. Please use `fetch_all` function instead."
641)]
642pub async fn get_all<T: SqlQuery<T> + FromRow + SqlParams>(
643 pool: &Pool,
644 params: &T,
645) -> Result<Vec<T>, Error> {
646 fetch_all(pool, params).await
647}
648
649/// CrudOps trait implementation for deadpool_postgres::Client
650#[async_trait::async_trait]
651impl CrudOps for Pool {
652 async fn insert<T, P: for<'a> FromSql<'a> + Send + Sync>(&self, entity: T) -> Result<P, Error>
653 where
654 T: SqlCommand + SqlParams + Send + Sync,
655 {
656 let client = self.get().await.map_err(pool_err_to_io_err)?;
657 let sql = T::query();
658
659 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
660 println!("[PARSQL-DEADPOOL-POSTGRES] Execute SQL: {}", sql);
661 }
662
663 let params = entity.params();
664 let row = client.query_one(&sql, ¶ms).await?;
665 row.try_get::<_, P>(0)
666 }
667
668 async fn update<T>(&self, entity: T) -> Result<u64, Error>
669 where
670 T: SqlCommand + UpdateParams + Send + Sync,
671 {
672 let client = self.get().await.map_err(pool_err_to_io_err)?;
673 let sql = T::query();
674
675 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
676 println!("[PARSQL-DEADPOOL-POSTGRES] Execute SQL: {}", sql);
677 }
678
679 let params = entity.params();
680 client.execute(&sql, ¶ms).await
681 }
682
683 async fn delete<T>(&self, entity: T) -> Result<u64, Error>
684 where
685 T: SqlCommand + SqlParams + Send + Sync,
686 {
687 let client = self.get().await.map_err(pool_err_to_io_err)?;
688 let sql = T::query();
689
690 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
691 println!("[PARSQL-DEADPOOL-POSTGRES] Execute SQL: {}", sql);
692 }
693
694 let params = entity.params();
695 client.execute(&sql, ¶ms).await
696 }
697
698 async fn fetch<P, R>(&self, params: &P) -> Result<R, Error>
699 where
700 P: SqlQuery<R> + SqlParams + Send + Sync,
701 R: FromRow + Send + Sync,
702 {
703 let client = self.get().await.map_err(pool_err_to_io_err)?;
704 let sql = P::query();
705
706 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
707 println!("[PARSQL-DEADPOOL-POSTGRES] Execute SQL: {}", sql);
708 }
709
710 let query_params = params.params();
711 let row = client.query_one(&sql, &query_params).await?;
712 R::from_row(&row)
713 }
714
715 async fn fetch_all<P, R>(&self, params: &P) -> Result<Vec<R>, Error>
716 where
717 P: SqlQuery<R> + SqlParams + Send + Sync,
718 R: FromRow + Send + Sync,
719 {
720 let client = self.get().await.map_err(pool_err_to_io_err)?;
721 let sql = P::query();
722
723 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
724 println!("[PARSQL-DEADPOOL-POSTGRES] Execute SQL: {}", sql);
725 }
726
727 let query_params = params.params();
728 let rows = client.query(&sql, &query_params).await?;
729
730 let mut results = Vec::with_capacity(rows.len());
731 for row in rows {
732 results.push(R::from_row(&row)?);
733 }
734
735 Ok(results)
736 }
737
738 async fn select<T, R, F>(&self, entity: T, to_model: F) -> Result<R, Error>
739 where
740 T: SqlQuery<T> + SqlParams + Send + Sync,
741 F: FnOnce(&Row) -> Result<R, Error> + Send + Sync,
742 {
743 let client = self.get().await.map_err(pool_err_to_io_err)?;
744 let sql = T::query();
745
746 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
747 println!("[PARSQL-DEADPOOL-POSTGRES] Execute SQL: {}", sql);
748 }
749
750 let params = entity.params();
751 let row = client.query_one(&sql, ¶ms).await?;
752 to_model(&row)
753 }
754
755 async fn select_all<T, R, F>(&self, entity: T, to_model: F) -> Result<Vec<R>, Error>
756 where
757 T: SqlQuery<T> + SqlParams + Send + Sync,
758 F: Fn(&Row) -> R + Send + Sync,
759 {
760 let client = self.get().await.map_err(pool_err_to_io_err)?;
761 let sql = T::query();
762
763 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
764 println!("[PARSQL-DEADPOOL-POSTGRES] Execute SQL: {}", sql);
765 }
766
767 let params = entity.params();
768 let rows = client.query(&sql, ¶ms).await?;
769
770 let mut results = Vec::with_capacity(rows.len());
771 for row in rows {
772 results.push(to_model(&row));
773 }
774
775 Ok(results)
776 }
777}