1use crate::Database;
6use crate::error::Result;
7use crate::types::{QueryResult, Row, Value};
8use async_trait::async_trait;
9use chrono::{DateTime, Utc};
10use uuid::Uuid;
11
12#[async_trait]
37pub trait QueryExecutor {
38 type Output;
40
41 async fn execute(&self, db: &Database) -> Result<Self::Output>;
43}
44
45pub trait FromRow: Sized {
70 fn from_row(row: Row) -> Result<Self>;
72
73 fn from_rows(result: QueryResult) -> Result<Vec<Self>> {
75 result.into_iter().map(|row| Self::from_row(row)).collect()
76 }
77
78 fn from_single_row(result: QueryResult) -> Result<Self> {
80 let row = result.one()?;
81 Self::from_row(row)
82 }
83
84 fn from_optional_row(result: QueryResult) -> Result<Option<Self>> {
86 match result.optional()? {
87 Some(row) => Ok(Some(Self::from_row(row)?)),
88 None => Ok(None),
89 }
90 }
91}
92
93impl FromRow for bool {
96 fn from_row(row: Row) -> Result<Self> {
97 row.get_required("value")?.as_bool()
99 }
100}
101
102impl FromRow for i64 {
103 fn from_row(row: Row) -> Result<Self> {
104 row.get_required("value")?.as_i64()
105 }
106}
107
108impl FromRow for f64 {
109 fn from_row(row: Row) -> Result<Self> {
110 row.get_required("value")?.as_f64()
111 }
112}
113
114impl FromRow for String {
115 fn from_row(row: Row) -> Result<Self> {
116 Ok(row.get_required("value")?.as_str()?.to_string())
117 }
118}
119
120impl FromRow for Uuid {
121 fn from_row(row: Row) -> Result<Self> {
122 row.get_required("value")?.as_uuid()
123 }
124}
125
126impl FromRow for DateTime<Utc> {
127 fn from_row(row: Row) -> Result<Self> {
128 row.get_required("value")?.as_timestamp()
129 }
130}
131
132impl<T: FromRow> FromRow for Option<T> {
134 fn from_row(row: Row) -> Result<Self> {
135 if row.is_empty() {
136 return Ok(None);
137 }
138 Ok(Some(T::from_row(row)?))
139 }
140}
141
142pub trait FromValue: Sized {
146 fn from_value(value: &Value) -> Result<Self>;
148}
149
150impl FromValue for bool {
151 fn from_value(value: &Value) -> Result<Self> {
152 value.as_bool()
153 }
154}
155
156impl FromValue for i64 {
157 fn from_value(value: &Value) -> Result<Self> {
158 value.as_i64()
159 }
160}
161
162impl FromValue for f64 {
163 fn from_value(value: &Value) -> Result<Self> {
164 value.as_f64()
165 }
166}
167
168impl FromValue for String {
169 fn from_value(value: &Value) -> Result<Self> {
170 Ok(value.as_str()?.to_string())
171 }
172}
173
174impl FromValue for Uuid {
175 fn from_value(value: &Value) -> Result<Self> {
176 value.as_uuid()
177 }
178}
179
180impl FromValue for DateTime<Utc> {
181 fn from_value(value: &Value) -> Result<Self> {
182 value.as_timestamp()
183 }
184}
185
186impl<T: FromValue> FromValue for Option<T> {
187 fn from_value(value: &Value) -> Result<Self> {
188 if value.is_null() {
189 return Ok(None);
190 }
191 Ok(Some(T::from_value(value)?))
192 }
193}
194
195impl<T: FromValue> FromValue for Vec<T> {
196 fn from_value(value: &Value) -> Result<Self> {
197 let array = value.as_array()?;
198 array.iter().map(|v| T::from_value(v)).collect()
199 }
200}
201
202#[cfg(test)]
203mod tests {
204 use super::*;
205
206 #[test]
207 fn test_from_row_primitives() {
208 let mut row = Row::new();
209 row.insert("value".to_string(), Value::Bool(true));
210 assert_eq!(bool::from_row(row).unwrap(), true);
211
212 let mut row = Row::new();
213 row.insert("value".to_string(), Value::Integer(42));
214 assert_eq!(i64::from_row(row).unwrap(), 42);
215
216 let mut row = Row::new();
217 row.insert("value".to_string(), Value::Float(3.14));
218 assert!((f64::from_row(row).unwrap() - 3.14).abs() < 0.01);
219
220 let mut row = Row::new();
221 row.insert("value".to_string(), Value::String("hello".to_string()));
222 assert_eq!(String::from_row(row).unwrap(), "hello");
223 }
224
225 #[test]
226 fn test_from_row_uuid() {
227 let uuid = Uuid::new_v4();
228 let mut row = Row::new();
229 row.insert("value".to_string(), Value::Uuid(uuid));
230 assert_eq!(Uuid::from_row(row).unwrap(), uuid);
231 }
232
233 #[test]
234 fn test_from_row_timestamp() {
235 let now = Utc::now();
236 let mut row = Row::new();
237 row.insert("value".to_string(), Value::Timestamp(now));
238 assert_eq!(DateTime::<Utc>::from_row(row).unwrap(), now);
239 }
240
241 #[test]
242 fn test_from_row_option() {
243 let empty_row = Row::new();
244 let result: Option<String> = Option::from_row(empty_row).unwrap();
245 assert_eq!(result, None);
246
247 let mut row = Row::new();
248 row.insert("value".to_string(), Value::String("hello".to_string()));
249 let result: Option<String> = Option::from_row(row).unwrap();
250 assert_eq!(result, Some("hello".to_string()));
251 }
252
253 #[test]
254 fn test_from_rows() {
255 let mut row1 = Row::new();
256 row1.insert("value".to_string(), Value::Integer(1));
257 let mut row2 = Row::new();
258 row2.insert("value".to_string(), Value::Integer(2));
259
260 let result = QueryResult::with_rows(vec![row1, row2]);
261 let values = i64::from_rows(result).unwrap();
262 assert_eq!(values, vec![1, 2]);
263 }
264
265 #[test]
266 fn test_from_single_row() {
267 let mut row = Row::new();
268 row.insert("value".to_string(), Value::Integer(42));
269
270 let result = QueryResult::with_rows(vec![row]);
271 let value = i64::from_single_row(result).unwrap();
272 assert_eq!(value, 42);
273
274 let empty = QueryResult::new();
276 assert!(i64::from_single_row(empty).is_err());
277
278 let mut row1 = Row::new();
279 row1.insert("value".to_string(), Value::Integer(1));
280 let mut row2 = Row::new();
281 row2.insert("value".to_string(), Value::Integer(2));
282 let multiple = QueryResult::with_rows(vec![row1, row2]);
283 assert!(i64::from_single_row(multiple).is_err());
284 }
285
286 #[test]
287 fn test_from_optional_row() {
288 let empty = QueryResult::new();
289 let result: Option<i64> = i64::from_optional_row(empty).unwrap();
290 assert_eq!(result, None);
291
292 let mut row = Row::new();
293 row.insert("value".to_string(), Value::Integer(42));
294 let single = QueryResult::with_rows(vec![row]);
295 let result: Option<i64> = i64::from_optional_row(single).unwrap();
296 assert_eq!(result, Some(42));
297 }
298
299 #[test]
300 fn test_from_value_primitives() {
301 assert_eq!(bool::from_value(&Value::Bool(true)).unwrap(), true);
302 assert_eq!(i64::from_value(&Value::Integer(42)).unwrap(), 42);
303 assert_eq!(
304 String::from_value(&Value::String("hi".to_string())).unwrap(),
305 "hi"
306 );
307 }
308
309 #[test]
310 fn test_from_value_option() {
311 let null = Value::Null;
312 let result: Option<i64> = Option::from_value(&null).unwrap();
313 assert_eq!(result, None);
314
315 let value = Value::Integer(42);
316 let result: Option<i64> = Option::from_value(&value).unwrap();
317 assert_eq!(result, Some(42));
318 }
319
320 #[test]
321 fn test_from_value_vec() {
322 let array = Value::Array(vec![
323 Value::Integer(1),
324 Value::Integer(2),
325 Value::Integer(3),
326 ]);
327 let result: Vec<i64> = Vec::from_value(&array).unwrap();
328 assert_eq!(result, vec![1, 2, 3]);
329 }
330
331 #[test]
332 fn test_from_value_type_mismatch() {
333 let value = Value::Integer(42);
334 assert!(bool::from_value(&value).is_err());
335 assert!(String::from_value(&value).is_err());
336 }
337
338 #[derive(Debug, PartialEq)]
340 struct TestUser {
341 id: i64,
342 name: String,
343 active: bool,
344 }
345
346 impl FromRow for TestUser {
347 fn from_row(row: Row) -> Result<Self> {
348 Ok(TestUser {
349 id: row.get_required("id")?.as_i64()?,
350 name: row.get_required("name")?.as_str()?.to_string(),
351 active: row.get_required("active")?.as_bool()?,
352 })
353 }
354 }
355
356 #[test]
357 fn test_custom_from_row() {
358 let mut row = Row::new();
359 row.insert("id".to_string(), Value::Integer(1));
360 row.insert("name".to_string(), Value::String("Alice".to_string()));
361 row.insert("active".to_string(), Value::Bool(true));
362
363 let user = TestUser::from_row(row).unwrap();
364 assert_eq!(
365 user,
366 TestUser {
367 id: 1,
368 name: "Alice".to_string(),
369 active: true,
370 }
371 );
372 }
373
374 #[test]
375 fn test_custom_from_rows() {
376 let mut row1 = Row::new();
377 row1.insert("id".to_string(), Value::Integer(1));
378 row1.insert("name".to_string(), Value::String("Alice".to_string()));
379 row1.insert("active".to_string(), Value::Bool(true));
380
381 let mut row2 = Row::new();
382 row2.insert("id".to_string(), Value::Integer(2));
383 row2.insert("name".to_string(), Value::String("Bob".to_string()));
384 row2.insert("active".to_string(), Value::Bool(false));
385
386 let result = QueryResult::with_rows(vec![row1, row2]);
387 let users = TestUser::from_rows(result).unwrap();
388
389 assert_eq!(users.len(), 2);
390 assert_eq!(users[0].name, "Alice");
391 assert_eq!(users[1].name, "Bob");
392 }
393}