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