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}