parsql_sqlite/crud_ops.rs
1use rusqlite::{Error, Row, ToSql};
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 SQLite database.
6///
7/// This trait is implemented for the `rusqlite::Connection` struct, allowing
8/// CRUD operations to be called as extension methods on a connection.
9///
10/// # Example
11///
12/// ```rust,no_run
13/// use rusqlite::{Connection, Result};
14/// use parsql::sqlite::CrudOps;
15/// use parsql::sqlite::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 = ?")]
27/// struct GetUser {
28/// id: i64,
29/// name: String,
30/// email: String,
31/// }
32///
33/// fn main() -> Result<()> {
34/// let conn = Connection::open("test.db")?;
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 = conn.insert(insert_user)?;
42///
43/// // Extension method for get
44/// let get_user = GetUser {
45/// id: 1,
46/// name: String::new(),
47/// email: String::new(),
48/// };
49/// let user = conn.get(&get_user)?;
50///
51/// println!("User: {:?}", user);
52/// Ok(())
53/// }
54/// ```
55pub trait CrudOps {
56 /// Inserts a new record into the SQLite database.
57 ///
58 /// # Arguments
59 /// * `entity` - Data object to be inserted (must implement SqlQuery and SqlParams traits)
60 ///
61 /// # Returns
62 /// * `Result<usize, Error>` - On success, returns the number of inserted records; on failure, returns Error
63 fn insert<T: SqlQuery + SqlParams>(&self, entity: T) -> Result<usize, Error>;
64
65 /// Updates records in the SQLite database.
66 ///
67 /// # Arguments
68 /// * `entity` - Data object containing the update information (must implement SqlQuery and UpdateParams traits)
69 ///
70 /// # Returns
71 /// * `Result<usize, Error>` - On success, returns the number of updated records; on failure, returns Error
72 fn update<T: SqlQuery + UpdateParams>(&self, entity: T) -> Result<usize, Error>;
73
74 /// Deletes records from the SQLite database.
75 ///
76 /// # Arguments
77 /// * `entity` - Data object containing delete conditions (must implement SqlQuery and SqlParams traits)
78 ///
79 /// # Returns
80 /// * `Result<usize, Error>` - On success, returns the number of deleted records; on failure, returns Error
81 fn delete<T: SqlQuery + SqlParams>(&self, entity: T) -> Result<usize, Error>;
82
83 /// Retrieves a single record from the SQLite 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>(&self, entity: &T) -> Result<T, Error>;
91
92 /// Retrieves multiple records from the SQLite 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>(&self, entity: &T) -> Result<Vec<T>, Error>;
100
101 /// Retrieves a single record from the SQLite database.
102 ///
103 /// # Deprecated
104 /// This function has been renamed to `fetch`. Please use `fetch` instead.
105 ///
106 /// # Arguments
107 /// * `entity` - Data object containing query parameters (must implement SqlQuery, FromRow, and SqlParams traits)
108 ///
109 /// # Returns
110 /// * `Result<T, Error>` - On success, returns the retrieved record; on failure, returns Error
111 #[deprecated(
112 since = "0.3.7",
113 note = "Renamed to `fetch`. Please use `fetch` function instead."
114 )]
115 fn get<T: SqlQuery + FromRow + SqlParams>(&self, entity: &T) -> Result<T, Error> {
116 self.fetch(entity)
117 }
118
119 /// Retrieves multiple records from the SQLite database.
120 ///
121 /// # Deprecated
122 /// This function has been renamed to `fetch_all`. Please use `fetch_all` instead.
123 ///
124 /// # Arguments
125 /// * `entity` - Data object containing query parameters (must implement SqlQuery, FromRow, and SqlParams traits)
126 ///
127 /// # Returns
128 /// * `Result<Vec<T>, Error>` - A vector of retrieved records or an error
129 #[deprecated(
130 since = "0.3.7",
131 note = "Renamed to `fetch_all`. Please use `fetch_all` function instead."
132 )]
133 fn get_all<T: SqlQuery + FromRow + SqlParams>(&self, entity: &T) -> Result<Vec<T>, Error> {
134 self.fetch_all(entity)
135 }
136
137 /// Executes a custom query and transforms the result using the provided function.
138 ///
139 /// # Arguments
140 /// * `entity` - Data object containing query parameters (must implement SqlQuery and SqlParams traits)
141 /// * `to_model` - Function to transform the database row into the desired type
142 ///
143 /// # Returns
144 /// * `Result<R, Error>` - On success, returns the transformed result; on failure, returns Error
145 fn select<T: SqlQuery + SqlParams, F, R>(&self, entity: &T, to_model: F) -> Result<R, Error>
146 where
147 F: Fn(&Row) -> Result<R, Error>;
148
149 /// Executes a custom query and transforms all results using the provided function.
150 ///
151 /// # Arguments
152 /// * `entity` - Data object containing query parameters (must implement SqlQuery and SqlParams traits)
153 /// * `to_model` - Function to transform database rows into the desired type
154 ///
155 /// # Returns
156 /// * `Result<Vec<R>, Error>` - On success, returns a vector of transformed results; on failure, returns Error
157 fn select_all<T: SqlQuery + SqlParams, F, R>(&self, entity: &T, to_model: F) -> Result<Vec<R>, Error>
158 where
159 F: Fn(&Row) -> Result<R, Error>;
160}
161
162// CrudOps trait implementasyonu rusqlite::Connection için
163impl CrudOps for rusqlite::Connection {
164 fn insert<T: SqlQuery + SqlParams>(&self, entity: T) -> Result<usize, Error> {
165 let sql = T::query();
166
167 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
168 println!("[PARSQL-SQLITE] Execute SQL: {}", sql);
169 }
170
171 let params = entity.params();
172 let param_refs: Vec<&dyn ToSql> = params.iter().map(|p| *p as &dyn ToSql).collect();
173
174 self.execute(&sql, param_refs.as_slice())
175 }
176
177 fn update<T: SqlQuery + UpdateParams>(&self, entity: T) -> Result<usize, Error> {
178 let sql = T::query();
179
180 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
181 println!("[PARSQL-SQLITE] Execute SQL: {}", sql);
182 }
183
184 let params = entity.params();
185 let param_refs: Vec<&dyn ToSql> = params.iter().map(|p| *p as &dyn ToSql).collect();
186
187 self.execute(&sql, param_refs.as_slice())
188 }
189
190 fn delete<T: SqlQuery + SqlParams>(&self, entity: T) -> Result<usize, Error> {
191 let sql = T::query();
192
193 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
194 println!("[PARSQL-SQLITE] Execute SQL: {}", sql);
195 }
196
197 let params = entity.params();
198 let param_refs: Vec<&dyn ToSql> = params.iter().map(|p| *p as &dyn ToSql).collect();
199
200 self.execute(&sql, param_refs.as_slice())
201 }
202
203 fn fetch<T: SqlQuery + FromRow + SqlParams>(&self, entity: &T) -> Result<T, Error> {
204 let sql = T::query();
205
206 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
207 println!("[PARSQL-SQLITE] Execute SQL: {}", sql);
208 }
209
210 let params = entity.params();
211 let param_refs: Vec<&dyn ToSql> = params.iter().map(|p| *p as &dyn ToSql).collect();
212
213 let mut stmt = self.prepare(&sql)?;
214 let mut rows = stmt.query(param_refs.as_slice())?;
215
216 if let Some(row) = rows.next()? {
217 let result = T::from_row(row)?;
218 Ok(result)
219 } else {
220 Err(Error::QueryReturnedNoRows)
221 }
222 }
223
224 fn fetch_all<T: SqlQuery + FromRow + SqlParams>(&self, entity: &T) -> Result<Vec<T>, Error> {
225 let sql = T::query();
226
227 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
228 println!("[PARSQL-SQLITE] Execute SQL: {}", sql);
229 }
230
231 let params = entity.params();
232 let param_refs: Vec<&dyn ToSql> = params.iter().map(|p| *p as &dyn ToSql).collect();
233
234 let mut stmt = self.prepare(&sql)?;
235 let rows = stmt.query_map(param_refs.as_slice(), |row| T::from_row(row))?;
236
237 let mut results = Vec::new();
238 for row_result in rows {
239 results.push(row_result?);
240 }
241
242 Ok(results)
243 }
244
245 fn select<T: SqlQuery + SqlParams, F, R>(&self, entity: &T, to_model: F) -> Result<R, Error>
246 where
247 F: Fn(&Row) -> Result<R, Error>,
248 {
249 let sql = T::query();
250
251 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
252 println!("[PARSQL-SQLITE] Execute SQL: {}", sql);
253 }
254
255 let params = entity.params();
256 let param_refs: Vec<&dyn ToSql> = params.iter().map(|p| *p as &dyn ToSql).collect();
257
258 let mut stmt = self.prepare(&sql)?;
259 stmt.query_row(param_refs.as_slice(), to_model)
260 }
261
262 fn select_all<T: SqlQuery + SqlParams, F, R>(&self, entity: &T, to_model: F) -> Result<Vec<R>, Error>
263 where
264 F: Fn(&Row) -> Result<R, Error>,
265 {
266 let sql = T::query();
267
268 if std::env::var("PARSQL_TRACE").unwrap_or_default() == "1" {
269 println!("[PARSQL-SQLITE] Execute SQL: {}", sql);
270 }
271
272 let params = entity.params();
273 let param_refs: Vec<&dyn ToSql> = params.iter().map(|p| *p as &dyn ToSql).collect();
274
275 let mut stmt = self.prepare(&sql)?;
276 let rows = stmt.query_map(param_refs.as_slice(), to_model)?;
277
278 let mut results = Vec::new();
279 for row in rows {
280 results.push(row?);
281 }
282
283 Ok(results)
284 }
285}
286
287/// # insert
288///
289/// Inserts a new record into the SQLite database.
290///
291/// ## Parameters
292/// - `conn`: SQLite database connection
293/// - `entity`: Data object to be inserted (must implement SqlQuery and SqlParams traits)
294///
295/// ## Return Value
296/// - `Result<usize, rusqlite::Error>`: On success, returns the number of inserted records; on failure, returns Error
297///
298/// ## Struct Definition
299/// Structs used with this function should be annotated with the following derive macros:
300///
301/// ```rust,no_run
302/// #[derive(Insertable, SqlParams)] // Required macros
303/// #[table("table_name")] // Table name to insert into
304/// pub struct MyEntity {
305/// pub field1: String,
306/// pub field2: i32,
307/// // ...
308/// }
309/// ```
310///
311/// - `Insertable`: Automatically generates SQL INSERT statements
312/// - `SqlParams`: Automatically generates SQL parameters
313/// - `#[table("table_name")]`: Specifies the table name for the insertion
314///
315/// ## Example Usage
316///
317/// ```rust,no_run
318/// use rusqlite::{Connection, Result};
319/// use parsql_macros::{Insertable, SqlParams};
320/// use parsql_sqlite::insert;
321///
322/// fn main() -> Result<()> {
323/// // Create a database connection
324/// let conn = Connection::open("test.db")?;
325///
326/// // Create the table
327/// conn.execute("CREATE TABLE users (name TEXT, email TEXT, state INTEGER)", [])?;
328///
329/// // Define your entity with appropriate macros
330/// #[derive(Insertable, SqlParams)]
331/// #[table("users")]
332/// pub struct InsertUser {
333/// pub name: String,
334/// pub email: String,
335/// pub state: i16,
336/// }
337///
338/// // Create a new instance of your entity
339/// let insert_user = InsertUser {
340/// name: "John".to_string(),
341/// email: "john@example.com".to_string(),
342/// state: 1,
343/// };
344///
345/// // Insert into database
346/// let insert_result = insert(&conn, insert_user)?;
347/// println!("Insert result: {:?}", insert_result);
348/// Ok(())
349/// }
350/// ```
351pub fn insert<T: SqlQuery + SqlParams>(
352 conn: &rusqlite::Connection,
353 entity: T,
354) -> Result<usize, rusqlite::Error> {
355 conn.insert(entity)
356}
357
358/// # update
359///
360/// Updates a record in the database.
361///
362/// ## Parameters
363/// - `conn`: SQLite database connection
364/// - `entity`: The entity to update (must implement SqlQuery and UpdateParams traits)
365///
366/// ## Return Value
367/// - `Result<usize, Error>`: On success, returns the number of rows affected; on failure, returns Error
368///
369/// ## Struct Definition
370/// Structs used with this function should be annotated with the following derive macros:
371///
372/// ```rust,no_run
373/// use parsql_macros::{Updateable, UpdateParams};
374///
375/// #[derive(Updateable, UpdateParams)] // Required macros
376/// #[table("table_name")] // Table name to update
377/// #[update("field1, field2")] // Fields to update
378/// #[where_clause("id = ?")] // Update condition
379/// pub struct MyEntity {
380/// pub id: i64, // Field used in the where clause
381/// pub field1: String, // Fields to update
382/// pub field2: i32,
383/// }
384/// ```
385///
386/// ## Example Usage
387///
388/// ```rust,no_run
389/// use rusqlite::{Connection, Result};
390/// use parsql_macros::{Updateable, UpdateParams};
391/// use parsql_sqlite::update;
392///
393/// fn main() -> Result<()> {
394/// // Create database connection
395/// let conn = Connection::open("test.db")?;
396/// conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, state INTEGER)", [])?;
397/// conn.execute("INSERT INTO users (id, name, email, state) VALUES (1, 'Old Name', 'old@example.com', 0)", [])?;
398///
399/// // Define an entity for updating
400/// #[derive(Updateable, UpdateParams)]
401/// #[table("users")]
402/// #[update("name, email")]
403/// #[where_clause("id = ?")]
404/// pub struct UpdateUser {
405/// pub id: i64,
406/// pub name: String,
407/// pub email: String,
408/// pub state: i16, // Not included in the update
409/// }
410///
411/// // Create an update object
412/// let update_user = UpdateUser {
413/// id: 1, // User ID to update
414/// name: "New Name".to_string(),
415/// email: "new@example.com".to_string(),
416/// state: 1,
417/// };
418///
419/// // Execute the update
420/// let update_result = update(&conn, update_user)?;
421/// println!("Update result: {:?}", update_result);
422/// Ok(())
423/// }
424/// ```
425pub fn update<T: SqlQuery + UpdateParams>(
426 conn: &rusqlite::Connection,
427 entity: T,
428) -> Result<usize, Error> {
429 conn.update(entity)
430}
431
432/// # delete
433///
434/// Deletes records from the database based on a specific condition.
435///
436/// ## Parameters
437/// - `conn`: SQLite database connection
438/// - `entity`: Query parameter object (must implement SqlQuery and SqlParams traits)
439///
440/// ## Return Value
441/// - `Result<usize, Error>`: On success, returns the number of deleted records; on failure, returns Error
442///
443/// ## Struct Definition
444/// Structs used with this function should be annotated with the following derive macros:
445///
446/// ```rust,no_run
447/// use parsql_macros::{Deletable, SqlParams};
448///
449/// #[derive(Deletable, SqlParams)] // Required macros
450/// #[table("table_name")] // Table name to delete from
451/// #[where_clause("id = ?")] // Delete condition
452/// pub struct MyEntity {
453/// pub id: i64, // Field used in the condition
454/// }
455/// ```
456///
457/// ## Example Usage
458///
459/// ```rust,no_run
460/// use rusqlite::{Connection, Result};
461/// use parsql_macros::{Deletable, SqlParams};
462/// use parsql_sqlite::delete;
463///
464/// fn main() -> Result<()> {
465/// // Create database connection
466/// let conn = Connection::open("test.db")?;
467/// conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)", [])?;
468/// conn.execute("INSERT INTO users (id, name, email) VALUES (1, 'John', 'john@example.com')", [])?;
469///
470/// // Define a delete query
471/// #[derive(Deletable, SqlParams)]
472/// #[table("users")]
473/// #[where_clause("id = ?")]
474/// pub struct DeleteUser {
475/// pub id: i64,
476/// }
477///
478/// // Create delete parameters (delete user with ID 1)
479/// let delete_query = DeleteUser { id: 1 };
480///
481/// // Execute delete
482/// let delete_result = delete(&conn, delete_query)?;
483/// println!("Delete result: {:?}", delete_result);
484/// Ok(())
485/// }
486/// ```
487pub fn delete<T: SqlQuery + SqlParams>(
488 conn: &rusqlite::Connection,
489 entity: T,
490) -> Result<usize, Error> {
491 conn.delete(entity)
492}
493
494/// # fetch
495///
496/// Retrieves a single record from the database based on a specific condition.
497///
498/// ## Parameters
499/// - `conn`: SQLite database connection
500/// - `entity`: Query parameter object (must implement SqlQuery, FromRow, and SqlParams traits)
501///
502/// ## Return Value
503/// - `Result<T, Error>`: On success, returns the queried record; on failure, returns Error
504///
505/// ## Struct Definition
506/// Structs used with this function should be annotated with the following derive macros:
507///
508/// ```rust,no_run
509/// #[derive(Queryable, FromRow, SqlParams)] // Required macros
510/// #[table("table_name")] // Table name to query
511/// #[where_clause("id = ?")] // Query condition
512/// pub struct MyEntity {
513/// pub id: i64, // Field used in the condition
514/// pub field1: String, // Fields to retrieve
515/// pub field2: i32,
516/// }
517/// ```
518///
519/// ## Example Usage
520///
521/// ```rust,no_run
522/// use rusqlite::{Connection, Result};
523/// use parsql_macros::{Queryable, FromRow, SqlParams};
524/// use parsql_sqlite::fetch;
525///
526/// fn main() -> Result<()> {
527/// // Create database connection
528/// let conn = Connection::open("test.db")?;
529/// conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)", [])?;
530/// conn.execute("INSERT INTO users (id, name, email) VALUES (1, 'John', 'john@example.com')", [])?;
531///
532/// // Define a query
533/// #[derive(Queryable, FromRow, SqlParams)]
534/// #[table("users")]
535/// #[where_clause("id = ?")]
536/// pub struct GetUser {
537/// pub id: i64,
538/// pub name: String,
539/// pub email: String,
540/// }
541///
542/// // Create query parameters (get user with ID 1)
543/// let get_query = GetUser {
544/// id: 1,
545/// name: String::new(),
546/// email: String::new(),
547/// };
548///
549/// // Execute query
550/// let user = fetch(&conn, &get_query)?;
551/// println!("User: {:?}", user);
552/// Ok(())
553/// }
554/// ```
555pub fn fetch<T: SqlQuery + FromRow + SqlParams>(
556 conn: &rusqlite::Connection,
557 entity: &T,
558) -> Result<T, Error> {
559 conn.fetch(entity)
560}
561
562/// # fetch_all
563///
564/// Retrieves multiple records from the database based on a specific condition.
565///
566/// ## Parameters
567/// - `conn`: SQLite database connection
568/// - `entity`: Query parameter object (must implement SqlQuery, FromRow, and SqlParams traits)
569///
570/// ## Return Value
571/// - `Result<Vec<T>, Error>`: On success, returns a vector of records; on failure, returns Error
572///
573/// ## Example Usage
574///
575/// ```rust,no_run
576/// use rusqlite::{Connection, Result};
577/// use parsql_macros::{Queryable, FromRow, SqlParams};
578/// use parsql_sqlite::fetch_all;
579///
580/// fn main() -> Result<()> {
581/// // Create database connection
582/// let conn = Connection::open("test.db")?;
583/// conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, active INTEGER)", [])?;
584/// conn.execute("INSERT INTO users (id, name, email, active) VALUES (1, 'John', 'john@example.com', 1)", [])?;
585/// conn.execute("INSERT INTO users (id, name, email, active) VALUES (2, 'Jane', 'jane@example.com', 1)", [])?;
586///
587/// // Define a query
588/// #[derive(Queryable, FromRow, SqlParams)]
589/// #[table("users")]
590/// #[where_clause("active = ?")]
591/// pub struct GetActiveUsers {
592/// pub id: i64,
593/// pub name: String,
594/// pub email: String,
595/// pub active: i32,
596/// }
597///
598/// // Create query parameters (get all active users)
599/// let query = GetActiveUsers {
600/// id: 0,
601/// name: String::new(),
602/// email: String::new(),
603/// active: 1,
604/// };
605///
606/// // Execute query
607/// let users = fetch_all(&conn, &query)?;
608/// println!("Active users: {:?}", users);
609/// Ok(())
610/// }
611/// ```
612pub fn fetch_all<T: SqlQuery + FromRow + SqlParams>(
613 conn: &rusqlite::Connection,
614 entity: &T,
615) -> Result<Vec<T>, Error> {
616 conn.fetch_all(entity)
617}
618
619/// # get
620///
621/// Retrieves a single record from the database based on a specific condition.
622///
623/// # Deprecated
624/// This function has been renamed to `fetch`. Please use `fetch` instead.
625///
626/// ## Parameters
627/// - `conn`: SQLite database connection
628/// - `entity`: Query parameter object (must implement SqlQuery, FromRow, and SqlParams traits)
629///
630/// ## Return Value
631/// - `Result<T, Error>`: On success, returns the queried record; on failure, returns Error
632#[deprecated(
633 since = "0.3.7",
634 note = "Renamed to `fetch`. Please use `fetch` function instead."
635)]
636pub fn get<T: SqlQuery + FromRow + SqlParams>(
637 conn: &rusqlite::Connection,
638 entity: &T,
639) -> Result<T, Error> {
640 fetch(conn, entity)
641}
642
643/// # get_all
644///
645/// Retrieves multiple records from the database based on a specific condition.
646///
647/// # Deprecated
648/// This function has been renamed to `fetch_all`. Please use `fetch_all` instead.
649///
650/// ## Parameters
651/// - `conn`: SQLite database connection
652/// - `entity`: Query parameter object (must implement SqlQuery, FromRow, and SqlParams traits)
653///
654/// ## Return Value
655/// - `Result<Vec<T>, Error>`: On success, returns a vector of records; on failure, returns Error
656#[deprecated(
657 since = "0.3.7",
658 note = "Renamed to `fetch_all`. Please use `fetch_all` function instead."
659)]
660pub fn get_all<T: SqlQuery + FromRow + SqlParams>(
661 conn: &rusqlite::Connection,
662 entity: &T,
663) -> Result<Vec<T>, Error> {
664 fetch_all(conn, entity)
665}
666
667/// # select
668///
669/// Executes a custom SELECT query and maps the result to a model using a provided mapping function.
670///
671/// ## Parameters
672/// - `conn`: SQLite database connection
673/// - `entity`: Query parameter object (must implement SqlQuery and SqlParams traits)
674/// - `to_model`: Function to map a database row to your model type
675///
676/// ## Return Value
677/// - `Result<T, Error>`: On success, returns the mapped model; on failure, returns Error
678///
679/// ## Example Usage
680///
681/// ```rust,no_run
682/// use rusqlite::{Connection, Result, Row};
683/// use parsql_macros::{Queryable, SqlParams};
684/// use parsql_sqlite::select;
685///
686/// fn main() -> Result<()> {
687/// // Create database connection
688/// let conn = Connection::open("test.db")?;
689/// conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)", [])?;
690/// conn.execute("INSERT INTO users (id, name, email) VALUES (1, 'John', 'john@example.com')", [])?;
691///
692/// // Define your model
693/// #[derive(Debug)]
694/// pub struct User {
695/// pub id: i64,
696/// pub name: String,
697/// pub email: String,
698/// }
699///
700/// // Define a query
701/// #[derive(Queryable, SqlParams)]
702/// #[table("users")]
703/// #[where_clause("id = ?")]
704/// pub struct GetUser {
705/// pub id: i64,
706/// }
707///
708/// // Create query parameters
709/// let get_query = GetUser { id: 1 };
710///
711/// // Define row mapping function
712/// let to_user = |row: &Row| -> Result<User> {
713/// Ok(User {
714/// id: row.get(0)?,
715/// name: row.get(1)?,
716/// email: row.get(2)?,
717/// })
718/// };
719///
720/// // Execute query with custom mapping
721/// let user = select(&conn, &get_query, to_user)?;
722/// println!("User: {:?}", user);
723/// Ok(())
724/// }
725/// ```
726pub fn select<T: SqlQuery + SqlParams, F, R>(
727 conn: &rusqlite::Connection,
728 entity: &T,
729 to_model: F,
730) -> Result<R, Error>
731where
732 F: Fn(&Row) -> Result<R, Error>,
733{
734 conn.select(entity, to_model)
735}
736
737/// # select_all
738///
739/// Executes a custom SELECT query and maps multiple results to models using a provided mapping function.
740///
741/// ## Parameters
742/// - `conn`: SQLite database connection
743/// - `entity`: Query parameter object (must implement SqlQuery and SqlParams traits)
744/// - `to_model`: Function to map a database row to your model type
745///
746/// ## Return Value
747/// - `Result<Vec<T>, Error>`: On success, returns a vector of mapped models; on failure, returns Error
748///
749/// ## Example Usage
750///
751/// ```rust,no_run
752/// use rusqlite::{Connection, Result, Row};
753/// use parsql_macros::{Queryable, SqlParams};
754/// use parsql_sqlite::select_all;
755///
756/// fn main() -> Result<()> {
757/// // Create database connection
758/// let conn = Connection::open("test.db")?;
759/// conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, state INTEGER)", [])?;
760/// conn.execute("INSERT INTO users (name, email, state) VALUES ('John', 'john@example.com', 1)", [])?;
761/// conn.execute("INSERT INTO users (name, email, state) VALUES ('Jane', 'jane@example.com', 1)", [])?;
762///
763/// // Define your model
764/// #[derive(Debug)]
765/// pub struct User {
766/// pub id: i64,
767/// pub name: String,
768/// pub email: String,
769/// pub state: i16,
770/// }
771///
772/// // Define a query
773/// #[derive(Queryable, SqlParams)]
774/// #[table("users")]
775/// #[where_clause("state = ?")]
776/// pub struct GetActiveUsers {
777/// pub state: i16,
778/// }
779///
780/// // Create query parameters
781/// let get_query = GetActiveUsers { state: 1 };
782///
783/// // Define row mapping function
784/// let to_user = |row: &Row| -> Result<User> {
785/// Ok(User {
786/// id: row.get(0)?,
787/// name: row.get(1)?,
788/// email: row.get(2)?,
789/// state: row.get(3)?,
790/// })
791/// };
792///
793/// // Execute query with custom mapping
794/// let users = select_all(&conn, &get_query, to_user)?;
795/// println!("Active users: {:?}", users);
796/// Ok(())
797/// }
798/// ```
799pub fn select_all<T: SqlQuery + SqlParams, F, R>(
800 conn: &rusqlite::Connection,
801 entity: &T,
802 to_model: F,
803) -> Result<Vec<R>, Error>
804where
805 F: Fn(&Row) -> Result<R, Error>,
806{
807 conn.select_all(entity, to_model)
808}