parsql_sqlite/
traits.rs

1use rusqlite::{
2    types::{FromSql, ToSql},
3    Error, Row,
4};
5
6/// Trait for generating SQL queries (for SELECT operations).
7/// This trait is implemented by the derive macro `Queryable`.
8pub trait SqlQuery<R> {
9    /// Returns the SQL query string.
10    fn query() -> String;
11}
12
13/// Trait for generating SQL commands (for INSERT/UPDATE/DELETE operations).
14/// This trait is implemented by the derive macros `Insertable`, `Updateable`, and `Deletable`.
15pub trait SqlCommand {
16    /// Returns the SQL command string.
17    fn query() -> String;
18}
19
20/// Trait for providing SQL parameters.
21/// This trait is implemented by the derive macro `SqlParams`.
22pub trait SqlParams {
23    /// Returns a vector of references to SQL parameters.
24    fn params(&self) -> Vec<&(dyn ToSql + Sync)>;
25}
26
27/// Trait for providing UPDATE parameters.
28/// This trait is implemented by the derive macro `UpdateParams`.
29pub trait UpdateParams {
30    /// Returns a vector of references to SQL parameters for UPDATE operations.
31    fn params(&self) -> Vec<&(dyn ToSql + Sync)>;
32}
33
34/// Trait for converting database rows to Rust structs.
35/// This trait is implemented by the derive macro `FromRow`.
36pub trait FromRow {
37    /// Converts a database row to a Rust struct.
38    ///
39    /// # Arguments
40    /// * `row` - A reference to a database row
41    ///
42    /// # Returns
43    /// * `Result<Self, Error>` - The converted struct or an error
44    fn from_row(row: &Row) -> Result<Self, Error>
45    where
46        Self: Sized;
47}
48
49/// CrudOps trait defines the CRUD (Create, Read, Update, Delete) operations
50/// that can be performed on a SQLite database.
51///
52/// This trait is implemented for the `rusqlite::Connection` struct, allowing
53/// CRUD operations to be called as extension methods on a connection.
54///
55/// # Example
56///
57/// ```rust,no_run
58/// use rusqlite::{Connection, Result};
59/// use parsql::sqlite::CrudOps;
60/// use parsql::sqlite::macros::{Insertable, SqlParams, Queryable, FromRow};
61///
62/// #[derive(Insertable, SqlParams)]
63/// #[table("users")]
64/// struct InsertUser {
65///     name: String,
66///     email: String,
67/// }
68///
69/// #[derive(Queryable, FromRow, SqlParams)]
70/// #[table("users")]
71/// #[where_clause("id = ?")]
72/// struct GetUser {
73///     id: i64,
74///     name: String,
75///     email: String,
76/// }
77///
78/// fn main() -> Result<()> {
79///     let conn = Connection::open("test.db")?;
80///    
81///     // Extension method for insert
82///     let insert_user = InsertUser {
83///         name: "John".to_string(),
84///         email: "john@example.com".to_string(),
85///     };
86///     let rows_affected = conn.insert(insert_user)?;
87///    
88///     // Extension method for get
89///     let get_user = GetUser {
90///         id: 1,
91///         name: String::new(),
92///         email: String::new(),
93///     };
94///     let user = conn.get(&get_user)?;
95///    
96///     println!("User: {:?}", user);
97///     Ok(())
98/// }
99/// ```
100pub trait CrudOps {
101    /// Inserts a new record into the SQLite database.
102    ///
103    /// # Arguments
104    /// * `entity` - Data object to be inserted (must implement SqlCommand and SqlParams traits)
105    ///
106    /// # Returns
107    /// * `Result<P, Error>` - On success, returns the inserted ID or return value; on failure, returns Error
108    fn insert<T: SqlCommand + SqlParams, P: for<'a> FromSql + Send + Sync>(
109        &self,
110        entity: T,
111    ) -> Result<P, Error>;
112
113    /// Updates records in the SQLite database.
114    ///
115    /// # Arguments
116    /// * `entity` - Data object containing the update information (must implement SqlCommand and UpdateParams traits)
117    ///
118    /// # Returns
119    /// * `Result<usize, Error>` - On success, returns the number of updated records; on failure, returns Error
120    fn update<T: SqlCommand + UpdateParams>(&self, entity: T) -> Result<usize, Error>;
121
122    /// Deletes records from the SQLite database.
123    ///
124    /// # Arguments
125    /// * `entity` - Data object containing delete conditions (must implement SqlCommand and SqlParams traits)
126    ///
127    /// # Returns
128    /// * `Result<usize, Error>` - On success, returns the number of deleted records; on failure, returns Error
129    fn delete<T: SqlCommand + SqlParams>(&self, entity: T) -> Result<usize, Error>;
130
131    /// Retrieves a single record from the SQLite database.
132    ///
133    /// # Arguments
134    /// * `params` - Query parameters (must implement SqlQuery and SqlParams traits)
135    ///
136    /// # Returns
137    /// * `Result<R, Error>` - On success, returns the retrieved record; on failure, returns Error
138    fn fetch<P, R>(&self, params: &P) -> Result<R, Error>
139    where
140        P: SqlQuery<R> + SqlParams,
141        R: FromRow;
142
143    /// Retrieves multiple records from the SQLite database.
144    ///
145    /// # Arguments
146    /// * `params` - Query parameters (must implement SqlQuery and SqlParams traits)
147    ///
148    /// # Returns
149    /// * `Result<Vec<R>, Error>` - On success, returns a vector of records; on failure, returns Error
150    fn fetch_all<P, R>(&self, params: &P) -> Result<Vec<R>, Error>
151    where
152        P: SqlQuery<R> + SqlParams,
153        R: FromRow;
154
155    /// Retrieves a single record from the SQLite database.
156    ///
157    /// # Deprecated
158    /// This function has been renamed to `fetch`. Please use `fetch` instead.
159    ///
160    /// # Arguments
161    /// * `entity` - Data object containing query parameters (must implement SqlQuery, FromRow, and SqlParams traits)
162    ///
163    /// # Returns
164    /// * `Result<T, Error>` - On success, returns the retrieved record; on failure, returns Error
165    #[deprecated(
166        since = "0.3.7",
167        note = "Renamed to `fetch`. Please use `fetch` function instead."
168    )]
169    fn get<T: SqlQuery<T> + FromRow + SqlParams>(&self, entity: &T) -> Result<T, Error> {
170        self.fetch(entity)
171    }
172
173    /// Retrieves multiple records from the SQLite database.
174    ///
175    /// # Deprecated
176    /// This function has been renamed to `fetch_all`. Please use `fetch_all` instead.
177    ///
178    /// # Arguments
179    /// * `entity` - Data object containing query parameters (must implement SqlQuery, FromRow, and SqlParams traits)
180    ///
181    /// # Returns
182    /// * `Result<Vec<T>, Error>` - A vector of retrieved records or an error
183    #[deprecated(
184        since = "0.3.7",
185        note = "Renamed to `fetch_all`. Please use `fetch_all` function instead."
186    )]
187    fn get_all<T: SqlQuery<T> + FromRow + SqlParams>(&self, entity: &T) -> Result<Vec<T>, Error> {
188        self.fetch_all(entity)
189    }
190
191    /// Executes a custom query and transforms the result using the provided function.
192    ///
193    /// # Arguments
194    /// * `entity` - Data object containing query parameters (must implement SqlQuery and SqlParams traits)
195    /// * `to_model` - Function to transform the database row into the desired type
196    ///
197    /// # Returns
198    /// * `Result<R, Error>` - On success, returns the transformed result; on failure, returns Error
199    fn select<T: SqlQuery<T> + SqlParams, F, R>(&self, entity: &T, to_model: F) -> Result<R, Error>
200    where
201        F: Fn(&Row) -> Result<R, Error>;
202
203    /// Executes a custom query and transforms all results using the provided function.
204    ///
205    /// # Arguments
206    /// * `entity` - Data object containing query parameters (must implement SqlQuery and SqlParams traits)
207    /// * `to_model` - Function to transform database rows into the desired type
208    ///
209    /// # Returns
210    /// * `Result<Vec<R>, Error>` - On success, returns a vector of transformed results; on failure, returns Error
211    fn select_all<T: SqlQuery<T> + SqlParams, F, R>(
212        &self,
213        entity: &T,
214        to_model: F,
215    ) -> Result<Vec<R>, Error>
216    where
217        F: Fn(&Row) -> Result<R, Error>;
218}