1use crate::any::error::mismatched_types;
2use crate::any::{Any, AnyColumn, AnyTypeInfo, AnyTypeInfoKind, AnyValue, AnyValueKind};
3use crate::column::{Column, ColumnIndex};
4use crate::database::Database;
5use crate::decode::Decode;
6use crate::error::Error;
7use crate::ext::ustr::UStr;
8use crate::row::Row;
9use crate::type_info::TypeInfo;
10use crate::types::Type;
11use crate::value::{Value, ValueRef};
12use std::sync::Arc;
13
14#[derive(Clone)]
15pub struct AnyRow {
16 #[doc(hidden)]
17 pub column_names: Arc<crate::HashMap<UStr, usize>>,
18 #[doc(hidden)]
19 pub columns: Vec<AnyColumn>,
20 #[doc(hidden)]
21 pub values: Vec<AnyValue>,
22}
23
24impl Row for AnyRow {
25 type Database = Any;
26
27 fn columns(&self) -> &[AnyColumn] {
28 &self.columns
29 }
30
31 fn try_get_raw<I>(&self, index: I) -> Result<<Self::Database as Database>::ValueRef<'_>, Error>
32 where
33 I: ColumnIndex<Self>,
34 {
35 let index = index.index(self)?;
36 Ok(self
37 .values
38 .get(index)
39 .ok_or_else(|| Error::ColumnIndexOutOfBounds {
40 index,
41 len: self.columns.len(),
42 })?
43 .as_ref())
44 }
45
46 fn try_get<'r, T, I>(&'r self, index: I) -> Result<T, Error>
47 where
48 I: ColumnIndex<Self>,
49 T: Decode<'r, Self::Database> + Type<Self::Database>,
50 {
51 let value = self.try_get_raw(&index)?;
52 let ty = value.type_info();
53
54 if !value.is_null() && !ty.is_null() && !T::compatible(&ty) {
55 Err(mismatched_types::<T>(&ty))
56 } else {
57 T::decode(value)
58 }
59 .map_err(|source| Error::ColumnDecode {
60 index: format!("{index:?}"),
61 source,
62 })
63 }
64}
65
66impl<'i> ColumnIndex<AnyRow> for &'i str {
67 fn index(&self, row: &AnyRow) -> Result<usize, Error> {
68 row.column_names
69 .get(*self)
70 .copied()
71 .ok_or_else(|| Error::ColumnNotFound(self.to_string()))
72 }
73}
74
75impl AnyRow {
76 #[doc(hidden)]
82 pub fn map_from<'a, R: Row>(
83 row: &'a R,
84 column_names: Arc<crate::HashMap<UStr, usize>>,
85 ) -> Result<Self, Error>
86 where
87 usize: ColumnIndex<R>,
88 AnyTypeInfo: for<'b> TryFrom<&'b <R::Database as Database>::TypeInfo, Error = Error>,
89 AnyColumn: for<'b> TryFrom<&'b <R::Database as Database>::Column, Error = Error>,
90 bool: Type<R::Database> + Decode<'a, R::Database>,
91 i16: Type<R::Database> + Decode<'a, R::Database>,
92 i32: Type<R::Database> + Decode<'a, R::Database>,
93 i64: Type<R::Database> + Decode<'a, R::Database>,
94 f32: Type<R::Database> + Decode<'a, R::Database>,
95 f64: Type<R::Database> + Decode<'a, R::Database>,
96 String: Type<R::Database> + Decode<'a, R::Database>,
97 Vec<u8>: Type<R::Database> + Decode<'a, R::Database>,
98 {
99 let mut row_out = AnyRow {
100 column_names,
101 columns: Vec::with_capacity(row.columns().len()),
102 values: Vec::with_capacity(row.columns().len()),
103 };
104
105 for col in row.columns() {
106 let i = col.ordinal();
107
108 let any_col = AnyColumn::try_from(col)?;
109
110 let value = row.try_get_raw(i)?;
111
112 let type_info =
114 AnyTypeInfo::try_from(&value.type_info()).map_err(|e| Error::ColumnDecode {
115 index: col.ordinal().to_string(),
116 source: e.into(),
117 })?;
118
119 let value_kind = match type_info.kind {
120 k if value.is_null() => AnyValueKind::Null(k),
121 AnyTypeInfoKind::Null => AnyValueKind::Null(AnyTypeInfoKind::Null),
122 AnyTypeInfoKind::Bool => AnyValueKind::Bool(decode(value)?),
123 AnyTypeInfoKind::SmallInt => AnyValueKind::SmallInt(decode(value)?),
124 AnyTypeInfoKind::Integer => AnyValueKind::Integer(decode(value)?),
125 AnyTypeInfoKind::BigInt => AnyValueKind::BigInt(decode(value)?),
126 AnyTypeInfoKind::Real => AnyValueKind::Real(decode(value)?),
127 AnyTypeInfoKind::Double => AnyValueKind::Double(decode(value)?),
128 AnyTypeInfoKind::Blob => AnyValueKind::Blob(decode::<_, Vec<u8>>(value)?.into()),
129 AnyTypeInfoKind::Text => AnyValueKind::Text(decode::<_, String>(value)?.into()),
130 };
131
132 row_out.columns.push(any_col);
133 row_out.values.push(AnyValue { kind: value_kind });
134 }
135
136 Ok(row_out)
137 }
138}
139
140fn decode<'r, DB: Database, T: Decode<'r, DB>>(
141 valueref: <DB as Database>::ValueRef<'r>,
142) -> crate::Result<T> {
143 Decode::decode(valueref).map_err(Error::decode)
144}