parsql_postgres/crud_ops.rs
1use postgres::{types::ToSql, Client, Error, Row};
2use crate::{SqlQuery, SqlParams, UpdateParams, FromRow};
3
4/// CrudOps trait defines the CRUD (Create, Read, Update, Delete) operations
5/// that can be performed on a PostgreSQL database.
6///
7/// This trait is implemented for the `postgres::Client` struct, allowing
8/// CRUD operations to be called as extension methods on a client.
9///
10/// # Example
11///
12/// ```rust,no_run
13/// use postgres::{Client, NoTls, Error};
14/// use parsql::postgres::CrudOps;
15/// use parsql::macros::{Insertable, SqlParams, Queryable, FromRow};
16///
17/// #[derive(Insertable, SqlParams)]
18/// #[table("users")]
19/// struct InsertUser {
20/// name: String,
21/// email: String,
22/// }
23///
24/// #[derive(Queryable, FromRow, SqlParams)]
25/// #[table("users")]
26/// #[where_clause("id = $1")]
27/// struct GetUser {
28/// id: i32,
29/// name: String,
30/// email: String,
31/// }
32///
33/// fn main() -> Result<(), Error> {
34/// let mut client = Client::connect("host=localhost user=postgres", NoTls)?;
35///
36/// // Extension method for insert
37/// let insert_user = InsertUser {
38/// name: "John".to_string(),
39/// email: "john@example.com".to_string(),
40/// };
41/// let rows_affected = client.insert(insert_user)?;
42///
43/// // Extension method for fetch
44/// let get_user = GetUser {
45/// id: 1,
46/// name: String::new(),
47/// email: String::new(),
48/// };
49/// let user = client.fetch(&get_user)?;
50///
51/// println!("User: {:?}", user);
52/// Ok(())
53/// }
54/// ```
55pub trait CrudOps {
56 /// Inserts a new record into the PostgreSQL database.
57 ///
58 /// # Arguments
59 /// * `entity` - Data object to be inserted (must implement SqlQuery and SqlParams traits)
60 ///
61 /// # Returns
62 /// * `Result<u64, Error>` - On success, returns the number of inserted records; on failure, returns Error
63 fn insert<T: SqlQuery + SqlParams>(&mut self, entity: T) -> Result<u64, Error>;
64
65 /// Updates records in the PostgreSQL database.
66 ///
67 /// # Arguments
68 /// * `entity` - Data object containing the update information (must implement SqlQuery and UpdateParams traits)
69 ///
70 /// # Returns
71 /// * `Result<u64, Error>` - On success, returns the number of updated records; on failure, returns Error
72 fn update<T: SqlQuery + UpdateParams>(&mut self, entity: T) -> Result<u64, Error>;
73
74 /// Deletes records from the PostgreSQL database.
75 ///
76 /// # Arguments
77 /// * `entity` - Data object containing delete conditions (must implement SqlQuery and SqlParams traits)
78 ///
79 /// # Returns
80 /// * `Result<u64, Error>` - On success, returns the number of deleted records; on failure, returns Error
81 fn delete<T: SqlQuery + SqlParams>(&mut self, entity: T) -> Result<u64, Error>;
82
83 /// Retrieves a single record from the PostgreSQL database.
84 ///
85 /// # Arguments
86 /// * `entity` - Data object containing query parameters (must implement SqlQuery, FromRow, and SqlParams traits)
87 ///
88 /// # Returns
89 /// * `Result<T, Error>` - On success, returns the retrieved record; on failure, returns Error
90 fn fetch<T: SqlQuery + FromRow + SqlParams>(&mut self, entity: &T) -> Result<T, Error>;
91
92 /// Retrieves multiple records from the PostgreSQL database.
93 ///
94 /// # Arguments
95 /// * `entity` - Data object containing query parameters (must implement SqlQuery, FromRow, and SqlParams traits)
96 ///
97 /// # Returns
98 /// * `Result<Vec<T>, Error>` - On success, returns a vector of records; on failure, returns Error
99 fn fetch_all<T: SqlQuery + FromRow + SqlParams>(&mut self, entity: &T) -> Result<Vec<T>, Error>;
100
101 /// Executes a custom query and transforms the result using the provided function.
102 ///
103 /// # Arguments
104 /// * `entity` - Data object containing query parameters (must implement SqlQuery and SqlParams traits)
105 /// * `to_model` - Function to transform the database row into the desired type
106 ///
107 /// # Returns
108 /// * `Result<R, Error>` - On success, returns the transformed result; on failure, returns Error
109 fn select<T, F, R>(&mut self, entity: &T, to_model: F) -> Result<R, Error>
110 where
111 T: SqlQuery + SqlParams,
112 F: FnOnce(&Row) -> Result<R, Error>;
113
114 /// Executes a custom query and transforms all results using the provided function.
115 ///
116 /// # Arguments
117 /// * `entity` - Data object containing query parameters (must implement SqlQuery and SqlParams traits)
118 /// * `to_model` - Function to transform database rows into the desired type
119 ///
120 /// # Returns
121 /// * `Result<Vec<R>, Error>` - On success, returns a vector of transformed results; on failure, returns Error
122 fn select_all<T, F, R>(&mut self, entity: &T, to_model: F) -> Result<Vec<R>, Error>
123 where
124 T: SqlQuery + SqlParams,
125 F: FnMut(&Row) -> Result<R, Error>;
126}
127
128// CrudOps trait implementasyonu postgres::Client için
129impl CrudOps for Client {
130 fn insert<T: SqlQuery + SqlParams>(&mut self, entity: T) -> Result<u64, Error> {
131 insert(self, entity)
132 }
133
134 fn update<T: SqlQuery + UpdateParams>(&mut self, entity: T) -> Result<u64, Error> {
135 update(self, entity)
136 }
137
138 fn delete<T: SqlQuery + SqlParams>(&mut self, entity: T) -> Result<u64, Error> {
139 delete(self, entity)
140 }
141
142 fn fetch<T: SqlQuery + FromRow + SqlParams>(&mut self, entity: &T) -> Result<T, Error> {
143 fetch(self, entity)
144 }
145
146 fn fetch_all<T: SqlQuery + FromRow + SqlParams>(&mut self, entity: &T) -> Result<Vec<T>, Error> {
147 fetch_all(self, entity)
148 }
149
150 fn select<T, F, R>(&mut self, entity: &T, to_model: F) -> Result<R, Error>
151 where
152 T: SqlQuery + SqlParams,
153 F: FnOnce(&Row) -> Result<R, Error>,
154 {
155 let sql = T::query();
156
157 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
158 println!("[PARSQL-POSTGRES] Execute SQL: {}", sql);
159 }
160
161 let params = entity.params();
162 let row = self.query_one(&sql, ¶ms)?;
163 to_model(&row)
164 }
165
166 fn select_all<T, F, R>(&mut self, entity: &T, to_model: F) -> Result<Vec<R>, Error>
167 where
168 T: SqlQuery + SqlParams,
169 F: FnMut(&Row) -> Result<R, Error>,
170 {
171 let sql = T::query();
172
173 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
174 println!("[PARSQL-POSTGRES] Execute SQL: {}", sql);
175 }
176
177 let params = entity.params();
178 let rows = self.query(&sql, ¶ms)?;
179
180 rows.iter().map(to_model).collect()
181 }
182}
183
184/// # insert
185///
186/// Inserts a new record into the database.
187///
188/// ## Parameters
189/// - `client`: Database connection client
190/// - `entity`: Data object to be inserted (must implement SqlQuery and SqlParams traits)
191///
192/// ## Return Value
193/// - `Result<u64, Error>`: On success, returns the number of inserted records; on failure, returns Error
194///
195/// ## Struct Definition
196/// Structs used with this function should be annotated with the following derive macros:
197///
198/// ```rust,no_run
199/// #[derive(Insertable, SqlParams)] // Required macros
200/// #[table("table_name")] // Table name to insert into
201/// pub struct MyEntity {
202/// pub field1: String,
203/// pub field2: i32,
204/// // ...
205/// }
206/// ```
207///
208/// - `Insertable`: Automatically generates SQL INSERT statements
209/// - `SqlParams`: Automatically generates SQL parameters
210/// - `#[table("table_name")]`: Specifies the table name for the insertion
211///
212/// ## Example Usage
213/// ```rust,no_run
214/// use postgres::{Client, NoTls, Error};
215/// use parsql::postgres::insert;
216///
217/// #[derive(Insertable, SqlParams)]
218/// #[table("users")]
219/// pub struct InsertUser {
220/// pub name: String,
221/// pub email: String,
222/// pub state: i16,
223/// }
224///
225/// fn main() -> Result<(), Error> {
226/// let mut client = Client::connect(
227/// "host=localhost user=postgres dbname=test",
228/// NoTls,
229/// )?;
230///
231/// let insert_user = InsertUser {
232/// name: "John".to_string(),
233/// email: "john@example.com".to_string(),
234/// state: 1_i16,
235/// };
236///
237/// let insert_result = insert(&mut client, insert_user)?;
238/// println!("Insert result: {:?}", insert_result);
239/// Ok(())
240/// }
241/// ```
242pub fn insert<T: SqlQuery + SqlParams>(client: &mut Client, entity: T) -> Result<u64, Error> {
243 let sql = T::query();
244 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
245 println!("[PARSQL-POSTGRES] Execute SQL: {}", sql);
246 }
247
248 let params = entity.params();
249 client.execute(&sql, ¶ms)
250}
251
252/// # update
253///
254/// Updates an existing record in the database.
255///
256/// ## Parameters
257/// - `client`: Database connection client
258/// - `entity`: Data object containing the update information (must implement SqlQuery and UpdateParams traits)
259///
260/// ## Return Value
261/// - `Result<u64, Error>`: On success, returns the number of updated records; on failure, returns Error
262///
263/// ## Struct Definition
264/// Structs used with this function should be annotated with the following derive macros:
265///
266/// ```rust,no_run
267/// #[derive(Updateable, UpdateParams)] // Required macros
268/// #[table("table_name")] // Table name to update
269/// #[update("field1, field2")] // Fields to update (optional)
270/// #[where_clause("id = $")] // Update condition
271/// pub struct MyEntity {
272/// pub id: i32, // Fields used in the condition
273/// pub field1: String, // Fields to be updated
274/// pub field2: i32, // Fields to be updated
275/// // ...
276/// }
277/// ```
278///
279/// - `Updateable`: Automatically generates SQL UPDATE statements
280/// - `UpdateParams`: Automatically generates update parameters
281/// - `#[table("table_name")]`: Specifies the table name for the update
282/// - `#[update("field1, field2")]`: Specifies which fields should be updated (if omitted, all fields will be updated)
283/// - `#[where_clause("id = $")]`: Specifies the update condition (`$` will be replaced with parameter value)
284///
285/// ## Example Usage
286/// ```rust,no_run
287/// use postgres::{Client, NoTls, Error};
288/// use parsql::postgres::update;
289///
290/// #[derive(Updateable, UpdateParams)]
291/// #[table("users")]
292/// #[update("name, email")]
293/// #[where_clause("id = $")]
294/// pub struct UpdateUser {
295/// pub id: i32,
296/// pub name: String,
297/// pub email: String,
298/// pub state: i16, // This field won't be updated as it's not specified in the update attribute
299/// }
300///
301/// fn main() -> Result<(), Error> {
302/// let mut client = Client::connect(
303/// "host=localhost user=postgres dbname=test",
304/// NoTls,
305/// )?;
306///
307/// let update_user = UpdateUser {
308/// id: 1,
309/// name: String::from("John"),
310/// email: String::from("john@example.com"),
311/// state: 2,
312/// };
313///
314/// let update_result = update(&mut client, update_user)?;
315/// println!("Update result: {:?}", update_result);
316/// Ok(())
317/// }
318/// ```
319pub fn update<T: SqlQuery + UpdateParams>(
320 client: &mut postgres::Client,
321 entity: T,
322) -> Result<u64, Error> {
323 let sql = T::query();
324 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
325 println!("[PARSQL-POSTGRES] Execute SQL: {}", sql);
326 }
327
328 let params = entity.params();
329 match client.execute(&sql, ¶ms) {
330 Ok(rows_affected) => Ok(rows_affected),
331 Err(e) => Err(e),
332 }
333}
334
335/// # delete
336///
337/// Deletes a record from the database.
338///
339/// ## Parameters
340/// - `client`: Database connection client
341/// - `entity`: Data object containing the deletion information (must implement SqlQuery and SqlParams traits)
342///
343/// ## Return Value
344/// - `Result<u64, Error>`: On success, returns the number of deleted records; on failure, returns Error
345///
346/// ## Struct Definition
347/// Structs used with this function should be annotated with the following derive macros:
348///
349/// ```rust,no_run
350/// #[derive(Deletable, SqlParams)] // Required macros
351/// #[table("table_name")] // Table name to delete from
352/// #[where_clause("id = $")] // Delete condition
353/// pub struct MyEntity {
354/// pub id: i32, // Fields used in the condition
355/// // Other fields can be added, but typically only condition fields are necessary
356/// }
357/// ```
358///
359/// - `Deletable`: Automatically generates SQL DELETE statements
360/// - `SqlParams`: Automatically generates SQL parameters
361/// - `#[table("table_name")]`: Specifies the table name for the deletion
362/// - `#[where_clause("id = $")]`: Specifies the delete condition (`$` will be replaced with parameter value)
363///
364/// ## Example Usage
365/// ```rust,no_run
366/// use postgres::{Client, NoTls, Error};
367/// use parsql::postgres::delete;
368///
369/// #[derive(Deletable, SqlParams)]
370/// #[table("users")]
371/// #[where_clause("id = $")]
372/// pub struct DeleteUser {
373/// pub id: i32,
374/// }
375///
376/// fn main() -> Result<(), Error> {
377/// let mut client = Client::connect(
378/// "host=localhost user=postgres dbname=test",
379/// NoTls,
380/// )?;
381///
382/// let delete_user = DeleteUser { id: 6 };
383/// let delete_result = delete(&mut client, delete_user)?;
384///
385/// println!("Delete result: {:?}", delete_result);
386/// Ok(())
387/// }
388/// ```
389pub fn delete<T: SqlQuery + SqlParams>(
390 client: &mut postgres::Client,
391 entity: T,
392) -> Result<u64, Error> {
393 let sql = T::query();
394 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
395 println!("[PARSQL-POSTGRES] Execute SQL: {}", sql);
396 }
397
398 let params = entity.params();
399 match client.execute(&sql, ¶ms) {
400 Ok(rows_affected) => Ok(rows_affected),
401 Err(e) => Err(e),
402 }
403}
404
405/// # fetch
406///
407/// Retrieves a single record from the database.
408///
409/// ## Parameters
410/// - `client`: Database connection client
411/// - `params`: Query parameters (must implement SqlQuery, FromRow, and SqlParams traits)
412///
413/// ## Return Value
414/// - `Result<T, Error>`: On success, returns the retrieved record; on failure, returns Error
415///
416/// ## Struct Definition
417/// Structs used with this function should be annotated with the following derive macros:
418///
419/// ```rust,no_run
420/// #[derive(Queryable, FromRow, SqlParams)] // Required macros
421/// #[table("table_name")] // Table name to query
422/// #[where_clause("id = $1")] // WHERE clause with parameter placeholders
423/// struct GetUser {
424/// id: i32, // Parameter for the WHERE clause
425/// name: String, // Field to retrieve
426/// email: String, // Field to retrieve
427/// }
428/// ```
429pub fn fetch<T: SqlQuery + FromRow + SqlParams>(
430 client: &mut Client,
431 params: &T,
432) -> Result<T, Error> {
433 let sql = T::query();
434
435 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
436 println!("[PARSQL-POSTGRES] Execute SQL: {}", sql);
437 }
438
439 let query_params = params.params();
440 let row = client.query_one(&sql, &query_params)?;
441 T::from_row(&row)
442}
443
444/// # fetch_all
445///
446/// Retrieves multiple records from the database.
447///
448/// ## Parameters
449/// - `client`: Database connection client
450/// - `params`: Query parameters (must implement SqlQuery, FromRow, and SqlParams traits)
451///
452/// ## Return Value
453/// - `Result<Vec<T>, Error>`: On success, returns a vector of records; on failure, returns Error
454///
455/// ## Struct Definition
456/// Structs used with this function should be annotated with the following derive macros:
457///
458/// ```rust,no_run
459/// #[derive(Queryable, FromRow, SqlParams)] // Required macros
460/// #[table("users")] // Table name to query
461/// #[where_clause("active = $1")] // WHERE clause with parameter placeholders
462/// struct GetUsers {
463/// active: bool, // Parameter for the WHERE clause
464/// id: i32, // Field to retrieve
465/// name: String, // Field to retrieve
466/// email: String, // Field to retrieve
467/// }
468/// ```
469pub fn fetch_all<T: SqlQuery + FromRow + SqlParams>(
470 client: &mut Client,
471 params: &T,
472) -> Result<Vec<T>, Error> {
473 let sql = T::query();
474
475 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
476 println!("[PARSQL-POSTGRES] Execute SQL: {}", sql);
477 }
478
479 let query_params = params.params();
480 let rows = client.query(&sql, &query_params)?;
481
482 let mut results = Vec::with_capacity(rows.len());
483 for row in &rows {
484 results.push(T::from_row(row)?);
485 }
486
487 Ok(results)
488}
489
490/// # get_by_query
491///
492/// Retrieves multiple records from the database using a custom SQL query.
493///
494/// ## Parameters
495/// - `client`: Database connection client
496/// - `query`: Custom SQL query string
497/// - `params`: Array of query parameters
498///
499/// ## Return Value
500/// - `Result<Vec<T>, Error>`: On success, returns the list of found records; on failure, returns Error
501///
502/// ## Example Usage
503/// ```rust,no_run
504/// use postgres::{Client, NoTls, Error};
505/// use parsql::postgres::get_by_query;
506///
507/// #[derive(FromRow, Debug)]
508/// pub struct UserStats {
509/// pub state: i16,
510/// pub user_count: i64,
511/// }
512///
513/// fn main() -> Result<(), Error> {
514/// let mut client = Client::connect(
515/// "host=localhost user=postgres dbname=test",
516/// NoTls,
517/// )?;
518///
519/// let query = "SELECT state, COUNT(*) as user_count FROM users GROUP BY state HAVING COUNT(*) > $1";
520/// let min_count = 5;
521///
522/// let stats = get_by_query::<UserStats>(&mut client, query, &[&min_count])?;
523/// println!("User stats: {:?}", stats);
524/// Ok(())
525/// }
526/// ```
527pub fn get_by_query<T: FromRow>(
528 client: &mut Client,
529 query: &str,
530 params: &[&(dyn ToSql + Sync)],
531) -> Result<Vec<T>, Error> {
532 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
533 println!("[PARSQL-POSTGRES] Execute SQL: {}", query);
534 }
535
536 let rows = client.query(query, params)?;
537 rows.iter()
538 .map(|row| T::from_row(row))
539 .collect::<Result<Vec<_>, _>>()
540}
541
542/// # select
543///
544/// Retrieves a single record from the database using a custom transformation function.
545/// This is useful when you want to use a custom transformation function instead of the FromRow trait.
546///
547/// ## Parameters
548/// - `client`: Database connection client
549/// - `entity`: Query parameter object (must implement SqlQuery and SqlParams traits)
550/// - `to_model`: Function to convert a Row object to the target object type
551///
552/// ## Return Value
553/// - `Result<T, Error>`: On success, returns the transformed object; on failure, returns Error
554///
555/// ## Struct Definition
556/// Structs used with this function should be annotated with the following derive macros:
557///
558/// ```rust,no_run
559/// #[derive(Queryable, SqlParams)] // Required macros (FromRow is not needed)
560/// #[table("table_name")] // Table name to query
561/// #[where_clause("id = $")] // Query condition
562/// pub struct MyQueryEntity {
563/// pub id: i32, // Field used in the query condition
564/// // Other fields can be added if necessary for the query condition
565/// }
566///
567/// // A separate struct can be used for the return value
568/// pub struct MyResultEntity {
569/// pub id: i32,
570/// pub name: String,
571/// pub count: i64,
572/// }
573/// ```
574///
575/// - `Queryable`: Automatically generates SQL SELECT statements
576/// - `SqlParams`: Automatically generates SQL parameters
577/// - `#[table("table_name")]`: Specifies the table name for the query
578/// - `#[where_clause("id = $")]`: Specifies the query condition (`$` will be replaced with parameter value)
579///
580/// ## Example Usage
581/// ```rust,no_run
582/// use postgres::{Client, NoTls, Error};
583/// use parsql::postgres::select;
584///
585/// #[derive(Queryable, SqlParams)]
586/// #[table("users")]
587/// #[where_clause("id = $")]
588/// pub struct UserQuery {
589/// pub id: i32,
590/// }
591///
592/// impl UserQuery {
593/// pub fn new(id: i32) -> Self {
594/// Self { id }
595/// }
596/// }
597///
598/// // Different return structure
599/// pub struct User {
600/// pub id: i32,
601/// pub name: String,
602/// }
603///
604/// fn main() -> Result<(), Error> {
605/// let mut client = Client::connect(
606/// "host=localhost user=postgres dbname=test",
607/// NoTls,
608/// )?;
609///
610/// // A custom model transformation function is required
611/// let user_query = UserQuery::new(1);
612/// let user = select(&mut client, user_query, |row| {
613/// let id: i32 = row.get("id");
614/// let name: String = row.get("name");
615/// Ok(User { id, name })
616/// })?;
617///
618/// println!("User: {:?}", user);
619/// Ok(())
620/// }
621/// ```
622pub fn select<T: SqlQuery + SqlParams, F>(
623 client: &mut postgres::Client,
624 entity: T,
625 to_model: F,
626) -> Result<T, Error>
627where
628 F: Fn(&Row) -> Result<T, Error>,
629{
630 let sql = T::query();
631 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
632 println!("[PARSQL-POSTGRES] Execute SQL: {}", sql);
633 }
634
635 let params = entity.params();
636
637 match client.query_one(&sql, ¶ms) {
638 Ok(_row) => to_model(&_row),
639 Err(e) => Err(e),
640 }
641}
642
643/// # select_all
644///
645/// Retrieves multiple records from the database using a custom transformation function.
646/// This is useful when you want to use a custom transformation function instead of the FromRow trait.
647///
648/// ## Parameters
649/// - `client`: Database connection client
650/// - `entity`: Query parameter object (must implement SqlQuery and SqlParams traits)
651/// - `to_model`: Function to convert a Row object to the target object type
652///
653/// ## Return Value
654/// - `Result<Vec<T>, Error>`: On success, returns the list of transformed objects; on failure, returns Error
655///
656/// ## Struct Definition
657/// Structs used with this function should be annotated with the following derive macros:
658///
659/// ```rust,no_run
660/// #[derive(Queryable, SqlParams)] // Required macros (FromRow is not needed)
661/// #[table("table_name")] // Table name to query
662/// #[select("id, name, COUNT(*) as count")] // Custom SELECT statement (optional)
663/// #[where_clause("active = $")] // Query condition
664/// pub struct MyQueryEntity {
665/// pub active: bool, // Field used in the query condition
666/// // Other fields can be added if necessary for the query condition
667/// }
668///
669/// // A separate struct can be used for the return value
670/// pub struct MyResultEntity {
671/// pub id: i32,
672/// pub name: String,
673/// pub count: i64,
674/// }
675/// ```
676///
677/// - `Queryable`: Automatically generates SQL SELECT statements
678/// - `SqlParams`: Automatically generates SQL parameters
679/// - `#[table("table_name")]`: Specifies the table name for the query
680/// - `#[select("...")]`: Creates a custom SELECT statement (if omitted, all fields will be selected)
681/// - `#[where_clause("active = $")]`: Specifies the query condition (`$` will be replaced with parameter value)
682///
683/// ## Example Usage
684/// ```rust,no_run
685/// use postgres::{Client, NoTls, Error};
686/// use parsql::postgres::select_all;
687///
688/// #[derive(Queryable, SqlParams)]
689/// #[table("users")]
690/// #[select("id, name, email")]
691/// pub struct UsersQuery {
692/// // Can be empty for a parameterless query
693/// }
694///
695/// impl UsersQuery {
696/// pub fn new() -> Self {
697/// Self {}
698/// }
699/// }
700///
701/// // Different return structure
702/// pub struct User {
703/// pub id: i32,
704/// pub name: String,
705/// }
706///
707/// fn main() -> Result<(), Error> {
708/// let mut client = Client::connect(
709/// "host=localhost user=postgres dbname=test",
710/// NoTls,
711/// )?;
712///
713/// // A custom model transformation function is required
714/// let users_query = UsersQuery::new();
715/// let users = select_all(&mut client, users_query, |row| {
716/// let id: i32 = row.get("id");
717/// let name: String = row.get("name");
718/// User { id, name }
719/// })?;
720///
721/// println!("Users: {:?}", users);
722/// Ok(())
723/// }
724/// ```
725pub fn select_all<T: SqlQuery + SqlParams, F>(
726 client: &mut postgres::Client,
727 entity: T,
728 to_model: F,
729) -> Result<Vec<T>, Error>
730where
731 F: Fn(&Row) -> Result<T, Error>,
732{
733 let sql = T::query();
734 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
735 println!("[PARSQL-POSTGRES] Execute SQL: {}", sql);
736 }
737
738 let params = entity.params();
739
740 let rows = client.query(&sql, ¶ms)?;
741
742 rows.iter()
743 .map(|row| to_model(row))
744 .collect::<Result<Vec<_>, _>>()
745}
746
747// Geriye dönük uyumluluk için eski get fonksiyonunu koruyalım
748#[deprecated(
749 since = "0.2.0",
750 note = "Renamed to `fetch`. Please use `fetch` function instead."
751)]
752/// # get
753///
754/// Retrieves a single record from the database.
755///
756/// This function is deprecated. Please use `fetch` instead.
757pub fn get<T: SqlQuery + FromRow + SqlParams>(
758 client: &mut Client,
759 params: &T,
760) -> Result<T, Error> {
761 fetch(client, params)
762}
763
764// Geriye dönük uyumluluk için eski get_all fonksiyonunu koruyalım
765#[deprecated(
766 since = "0.2.0",
767 note = "Renamed to `fetch_all`. Please use `fetch_all` function instead."
768)]
769/// # get_all
770///
771/// Retrieves multiple records from the database.
772///
773/// This function is deprecated. Please use `fetch_all` instead.
774pub fn get_all<T: SqlQuery + FromRow + SqlParams>(
775 client: &mut Client,
776 params: &T,
777) -> Result<Vec<T>, Error> {
778 fetch_all(client, params)
779}