1use crate::connection::config::DatabaseResult;
4use wae_types::{ValidationErrorKind, WaeError};
5
6pub trait FromDatabaseValue: Sized {
8 #[cfg(feature = "turso")]
10 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self>;
11
12 #[cfg(feature = "postgres")]
14 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self>;
15
16 #[cfg(feature = "mysql")]
18 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self>;
19}
20
21#[cfg(all(feature = "turso", not(feature = "postgres"), not(feature = "mysql")))]
22mod database_value_impl {
23 use super::*;
24
25 macro_rules! impl_from_value {
26 ($type:ty, $pattern:pat => $expr:expr) => {
27 impl FromDatabaseValue for $type {
28 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
29 match value {
30 $pattern => Ok($expr),
31 _ => Err(WaeError::validation(ValidationErrorKind::InvalidFormat {
32 field: stringify!($type).to_string(),
33 expected: format!("{:?}", value),
34 })),
35 }
36 }
37 }
38 };
39 }
40
41 impl_from_value!(i64, turso::Value::Integer(i) => i);
42 impl_from_value!(i32, turso::Value::Integer(i) => i as i32);
43 impl_from_value!(i16, turso::Value::Integer(i) => i as i16);
44 impl_from_value!(u64, turso::Value::Integer(i) => i as u64);
45 impl_from_value!(u32, turso::Value::Integer(i) => i as u32);
46 impl_from_value!(Vec<u8>, turso::Value::Blob(b) => b);
47
48 impl FromDatabaseValue for f64 {
49 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
50 match value {
51 turso::Value::Integer(i) => Ok(i as f64),
52 turso::Value::Text(s) => s.parse().map_err(|_| {
53 WaeError::validation(ValidationErrorKind::InvalidFormat {
54 field: "f64".to_string(),
55 expected: format!("Cannot parse '{}' as float", s),
56 })
57 }),
58 _ => Err(WaeError::validation(ValidationErrorKind::InvalidFormat {
59 field: "f64".to_string(),
60 expected: format!("{:?}", value),
61 })),
62 }
63 }
64 }
65
66 impl FromDatabaseValue for String {
67 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
68 match value {
69 turso::Value::Text(s) => Ok(s),
70 turso::Value::Integer(i) => Ok(i.to_string()),
71 _ => Err(WaeError::validation(ValidationErrorKind::InvalidFormat {
72 field: "String".to_string(),
73 expected: format!("{:?}", value),
74 })),
75 }
76 }
77 }
78
79 impl FromDatabaseValue for bool {
80 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
81 match value {
82 turso::Value::Integer(i) => Ok(i != 0),
83 _ => Err(WaeError::validation(ValidationErrorKind::InvalidFormat {
84 field: "bool".to_string(),
85 expected: format!("{:?}", value),
86 })),
87 }
88 }
89 }
90
91 impl<T: FromDatabaseValue> FromDatabaseValue for Option<T> {
92 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
93 match value {
94 turso::Value::Null => Ok(None),
95 v => T::from_turso_value(v).map(Some),
96 }
97 }
98 }
99}
100
101#[cfg(all(feature = "postgres", not(feature = "turso"), not(feature = "mysql")))]
102mod database_value_impl {
103 use super::*;
104
105 macro_rules! impl_from_value {
106 ($type:ty) => {
107 impl FromDatabaseValue for $type {
108 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
109 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
110 }
111 }
112 };
113 }
114
115 impl_from_value!(i64);
116 impl_from_value!(i32);
117 impl_from_value!(i16);
118 impl_from_value!(f64);
119 impl_from_value!(String);
120 impl_from_value!(Vec<u8>);
121 impl_from_value!(bool);
122
123 impl FromDatabaseValue for u64 {
124 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
125 let i: i64 =
126 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))?;
127 Ok(i as u64)
128 }
129 }
130
131 impl FromDatabaseValue for u32 {
132 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
133 let i: i32 =
134 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))?;
135 Ok(i as u32)
136 }
137 }
138
139 impl FromDatabaseValue for Option<i64> {
140 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
141 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
142 }
143 }
144
145 impl FromDatabaseValue for Option<i32> {
146 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
147 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
148 }
149 }
150
151 impl FromDatabaseValue for Option<i16> {
152 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
153 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
154 }
155 }
156
157 impl FromDatabaseValue for Option<u64> {
158 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
159 let opt: Option<i64> =
160 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))?;
161 Ok(opt.map(|i| i as u64))
162 }
163 }
164
165 impl FromDatabaseValue for Option<u32> {
166 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
167 let opt: Option<i32> =
168 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))?;
169 Ok(opt.map(|i| i as u32))
170 }
171 }
172
173 impl FromDatabaseValue for Option<f64> {
174 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
175 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
176 }
177 }
178
179 impl FromDatabaseValue for Option<String> {
180 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
181 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
182 }
183 }
184
185 impl FromDatabaseValue for Option<Vec<u8>> {
186 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
187 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
188 }
189 }
190
191 impl FromDatabaseValue for Option<bool> {
192 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
193 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
194 }
195 }
196}
197
198#[cfg(all(feature = "mysql", not(feature = "turso"), not(feature = "postgres")))]
199mod database_value_impl {
200 use super::*;
201 use mysql_async::prelude::FromValue;
202
203 macro_rules! impl_from_value {
204 ($type:ty) => {
205 impl FromDatabaseValue for $type {
206 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
207 row.get_opt(index)
208 .transpose()
209 .map_err(|e| WaeError::internal(format!("Failed to get column {}: {:?}", index, e)))?
210 .ok_or_else(|| WaeError::internal(format!("Column {} is NULL", index)))
211 }
212 }
213 };
214 }
215
216 impl_from_value!(i64);
217 impl_from_value!(i32);
218 impl_from_value!(i16);
219 impl_from_value!(f64);
220 impl_from_value!(String);
221 impl_from_value!(Vec<u8>);
222 impl_from_value!(bool);
223
224 impl FromDatabaseValue for u64 {
225 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
226 let i: i64 = row
227 .get_opt(index)
228 .transpose()
229 .map_err(|e| WaeError::internal(format!("Failed to get column {}: {:?}", index, e)))?
230 .ok_or_else(|| WaeError::internal(format!("Column {} is NULL", index)))?;
231 Ok(i as u64)
232 }
233 }
234
235 impl FromDatabaseValue for u32 {
236 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
237 let i: i32 = row
238 .get_opt(index)
239 .transpose()
240 .map_err(|e| WaeError::internal(format!("Failed to get column {}: {:?}", index, e)))?
241 .ok_or_else(|| WaeError::internal(format!("Column {} is NULL", index)))?;
242 Ok(i as u32)
243 }
244 }
245
246 impl<T: FromDatabaseValue + FromValue> FromDatabaseValue for Option<T> {
247 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
248 match row.get_opt::<Option<T>, usize>(index) {
249 Some(Ok(val)) => Ok(val),
250 Some(Err(e)) => Err(WaeError::internal(format!("Failed to get column {}: {:?}", index, e))),
251 None => Ok(None),
252 }
253 }
254 }
255}
256
257#[cfg(any(
258 all(feature = "turso", feature = "postgres"),
259 all(feature = "turso", feature = "mysql"),
260 all(feature = "postgres", feature = "mysql"),
261 all(feature = "turso", feature = "postgres", feature = "mysql")
262))]
263mod database_value_impl {
264 use super::*;
265
266 macro_rules! impl_from_value_multi {
267 ($type:ty) => {
268 impl FromDatabaseValue for $type {
269 #[cfg(feature = "turso")]
270 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
271 match value {
272 turso::Value::Integer(i) => Ok(i as $type),
273 turso::Value::Text(s) => s.parse().map_err(|_| {
274 WaeError::validation(ValidationErrorKind::InvalidFormat {
275 field: stringify!($type).to_string(),
276 expected: format!("Cannot parse as {}", stringify!($type)),
277 })
278 }),
279 _ => Err(WaeError::validation(ValidationErrorKind::InvalidFormat {
280 field: stringify!($type).to_string(),
281 expected: format!("{:?}", value),
282 })),
283 }
284 }
285
286 #[cfg(feature = "postgres")]
287 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
288 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
289 }
290
291 #[cfg(feature = "mysql")]
292 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
293 row.get_opt(index)
294 .transpose()
295 .map_err(|e| WaeError::internal(format!("Failed to get column {}: {:?}", index, e)))?
296 .ok_or_else(|| WaeError::internal(format!("Column {} is NULL", index)))
297 }
298 }
299 };
300 }
301
302 impl_from_value_multi!(i64);
303 impl_from_value_multi!(i32);
304 impl_from_value_multi!(i16);
305 impl_from_value_multi!(f64);
306
307 impl FromDatabaseValue for String {
308 #[cfg(feature = "turso")]
309 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
310 match value {
311 turso::Value::Text(s) => Ok(s),
312 turso::Value::Integer(i) => Ok(i.to_string()),
313 _ => Err(WaeError::validation(ValidationErrorKind::InvalidFormat {
314 field: "String".to_string(),
315 expected: format!("{:?}", value),
316 })),
317 }
318 }
319
320 #[cfg(feature = "postgres")]
321 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
322 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
323 }
324
325 #[cfg(feature = "mysql")]
326 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
327 row.get_opt(index)
328 .transpose()
329 .map_err(|e| WaeError::internal(format!("Failed to get column {}: {:?}", index, e)))?
330 .ok_or_else(|| WaeError::internal(format!("Column {} is NULL", index)))
331 }
332 }
333
334 impl FromDatabaseValue for Vec<u8> {
335 #[cfg(feature = "turso")]
336 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
337 match value {
338 turso::Value::Blob(b) => Ok(b),
339 _ => Err(WaeError::validation(ValidationErrorKind::InvalidFormat {
340 field: "Vec<u8>".to_string(),
341 expected: format!("{:?}", value),
342 })),
343 }
344 }
345
346 #[cfg(feature = "postgres")]
347 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
348 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
349 }
350
351 #[cfg(feature = "mysql")]
352 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
353 row.get_opt(index)
354 .transpose()
355 .map_err(|e| WaeError::internal(format!("Failed to get column {}: {:?}", index, e)))?
356 .ok_or_else(|| WaeError::internal(format!("Column {} is NULL", index)))
357 }
358 }
359
360 impl FromDatabaseValue for bool {
361 #[cfg(feature = "turso")]
362 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
363 match value {
364 turso::Value::Integer(i) => Ok(i != 0),
365 _ => Err(WaeError::validation(ValidationErrorKind::InvalidFormat {
366 field: "bool".to_string(),
367 expected: format!("{:?}", value),
368 })),
369 }
370 }
371
372 #[cfg(feature = "postgres")]
373 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
374 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
375 }
376
377 #[cfg(feature = "mysql")]
378 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
379 row.get_opt(index)
380 .transpose()
381 .map_err(|e| WaeError::internal(format!("Failed to get column {}: {:?}", index, e)))?
382 .ok_or_else(|| WaeError::internal(format!("Column {} is NULL", index)))
383 }
384 }
385
386 impl FromDatabaseValue for u64 {
387 #[cfg(feature = "turso")]
388 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
389 match value {
390 turso::Value::Integer(i) => Ok(i as u64),
391 _ => Err(WaeError::validation(ValidationErrorKind::InvalidFormat {
392 field: "u64".to_string(),
393 expected: format!("{:?}", value),
394 })),
395 }
396 }
397
398 #[cfg(feature = "postgres")]
399 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
400 let i: i64 =
401 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))?;
402 Ok(i as u64)
403 }
404
405 #[cfg(feature = "mysql")]
406 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
407 let i: i64 = row
408 .get_opt(index)
409 .transpose()
410 .map_err(|e| WaeError::internal(format!("Failed to get column {}: {:?}", index, e)))?
411 .ok_or_else(|| WaeError::internal(format!("Column {} is NULL", index)))?;
412 Ok(i as u64)
413 }
414 }
415
416 impl FromDatabaseValue for u32 {
417 #[cfg(feature = "turso")]
418 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
419 match value {
420 turso::Value::Integer(i) => Ok(i as u32),
421 _ => Err(WaeError::validation(ValidationErrorKind::InvalidFormat {
422 field: "u32".to_string(),
423 expected: format!("{:?}", value),
424 })),
425 }
426 }
427
428 #[cfg(feature = "postgres")]
429 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
430 let i: i32 =
431 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))?;
432 Ok(i as u32)
433 }
434
435 #[cfg(feature = "mysql")]
436 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
437 let i: i32 = row
438 .get_opt(index)
439 .transpose()
440 .map_err(|e| WaeError::internal(format!("Failed to get column {}: {:?}", index, e)))?
441 .ok_or_else(|| WaeError::internal(format!("Column {} is NULL", index)))?;
442 Ok(i as u32)
443 }
444 }
445
446 impl FromDatabaseValue for Option<i64> {
447 #[cfg(feature = "turso")]
448 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
449 match value {
450 turso::Value::Null => Ok(None),
451 v => i64::from_turso_value(v).map(Some),
452 }
453 }
454
455 #[cfg(feature = "postgres")]
456 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
457 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
458 }
459
460 #[cfg(feature = "mysql")]
461 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
462 match row.get_opt::<Option<i64>, usize>(index) {
463 Some(Ok(val)) => Ok(val),
464 Some(Err(_)) => Ok(None),
465 None => Ok(None),
466 }
467 }
468 }
469
470 impl FromDatabaseValue for Option<i32> {
471 #[cfg(feature = "turso")]
472 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
473 match value {
474 turso::Value::Null => Ok(None),
475 v => i32::from_turso_value(v).map(Some),
476 }
477 }
478
479 #[cfg(feature = "postgres")]
480 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
481 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
482 }
483
484 #[cfg(feature = "mysql")]
485 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
486 match row.get_opt::<Option<i32>, usize>(index) {
487 Some(Ok(val)) => Ok(val),
488 Some(Err(_)) => Ok(None),
489 None => Ok(None),
490 }
491 }
492 }
493
494 impl FromDatabaseValue for Option<i16> {
495 #[cfg(feature = "turso")]
496 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
497 match value {
498 turso::Value::Null => Ok(None),
499 v => i16::from_turso_value(v).map(Some),
500 }
501 }
502
503 #[cfg(feature = "postgres")]
504 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
505 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
506 }
507
508 #[cfg(feature = "mysql")]
509 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
510 match row.get_opt::<Option<i16>, usize>(index) {
511 Some(Ok(val)) => Ok(val),
512 Some(Err(_)) => Ok(None),
513 None => Ok(None),
514 }
515 }
516 }
517
518 impl FromDatabaseValue for Option<u64> {
519 #[cfg(feature = "turso")]
520 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
521 match value {
522 turso::Value::Null => Ok(None),
523 v => u64::from_turso_value(v).map(Some),
524 }
525 }
526
527 #[cfg(feature = "postgres")]
528 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
529 let opt: Option<i64> =
530 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))?;
531 Ok(opt.map(|i| i as u64))
532 }
533
534 #[cfg(feature = "mysql")]
535 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
536 match row.get_opt::<Option<i64>, usize>(index) {
537 Some(Ok(val)) => Ok(val.map(|i| i as u64)),
538 Some(Err(_)) => Ok(None),
539 None => Ok(None),
540 }
541 }
542 }
543
544 impl FromDatabaseValue for Option<u32> {
545 #[cfg(feature = "turso")]
546 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
547 match value {
548 turso::Value::Null => Ok(None),
549 v => u32::from_turso_value(v).map(Some),
550 }
551 }
552
553 #[cfg(feature = "postgres")]
554 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
555 let opt: Option<i32> =
556 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))?;
557 Ok(opt.map(|i| i as u32))
558 }
559
560 #[cfg(feature = "mysql")]
561 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
562 match row.get_opt::<Option<i32>, usize>(index) {
563 Some(Ok(val)) => Ok(val.map(|i| i as u32)),
564 Some(Err(_)) => Ok(None),
565 None => Ok(None),
566 }
567 }
568 }
569
570 impl FromDatabaseValue for Option<f64> {
571 #[cfg(feature = "turso")]
572 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
573 match value {
574 turso::Value::Null => Ok(None),
575 v => f64::from_turso_value(v).map(Some),
576 }
577 }
578
579 #[cfg(feature = "postgres")]
580 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
581 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
582 }
583
584 #[cfg(feature = "mysql")]
585 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
586 match row.get_opt::<Option<f64>, usize>(index) {
587 Some(Ok(val)) => Ok(val),
588 Some(Err(_)) => Ok(None),
589 None => Ok(None),
590 }
591 }
592 }
593
594 impl FromDatabaseValue for Option<String> {
595 #[cfg(feature = "turso")]
596 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
597 match value {
598 turso::Value::Null => Ok(None),
599 v => String::from_turso_value(v).map(Some),
600 }
601 }
602
603 #[cfg(feature = "postgres")]
604 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
605 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
606 }
607
608 #[cfg(feature = "mysql")]
609 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
610 match row.get_opt::<Option<String>, usize>(index) {
611 Some(Ok(val)) => Ok(val),
612 Some(Err(_)) => Ok(None),
613 None => Ok(None),
614 }
615 }
616 }
617
618 impl FromDatabaseValue for Option<Vec<u8>> {
619 #[cfg(feature = "turso")]
620 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
621 match value {
622 turso::Value::Null => Ok(None),
623 v => Vec::<u8>::from_turso_value(v).map(Some),
624 }
625 }
626
627 #[cfg(feature = "postgres")]
628 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
629 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
630 }
631
632 #[cfg(feature = "mysql")]
633 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
634 match row.get_opt::<Option<Vec<u8>>, usize>(index) {
635 Some(Ok(val)) => Ok(val),
636 Some(Err(_)) => Ok(None),
637 None => Ok(None),
638 }
639 }
640 }
641
642 impl FromDatabaseValue for Option<bool> {
643 #[cfg(feature = "turso")]
644 fn from_turso_value(value: turso::Value) -> DatabaseResult<Self> {
645 match value {
646 turso::Value::Null => Ok(None),
647 v => bool::from_turso_value(v).map(Some),
648 }
649 }
650
651 #[cfg(feature = "postgres")]
652 fn from_postgres_row(row: &tokio_postgres::Row, index: usize) -> DatabaseResult<Self> {
653 row.try_get(index).map_err(|e| WaeError::internal(format!("Failed to get column {}: {}", index, e)))
654 }
655
656 #[cfg(feature = "mysql")]
657 fn from_mysql_row(row: &mysql_async::Row, index: usize) -> DatabaseResult<Self> {
658 match row.get_opt::<Option<bool>, usize>(index) {
659 Some(Ok(val)) => Ok(val),
660 Some(Err(_)) => Ok(None),
661 None => Ok(None),
662 }
663 }
664 }
665}