sqlx_core_oldapi/any/
row.rs

1use crate::any::{Any, AnyColumn, AnyColumnIndex};
2use crate::column::ColumnIndex;
3use crate::database::HasValueRef;
4use crate::decode::Decode;
5use crate::error::mismatched_types;
6use crate::error::Error;
7use crate::row::Row;
8use crate::type_info::TypeInfo;
9use crate::types::Type;
10use crate::value::ValueRef;
11
12#[cfg(feature = "postgres")]
13use crate::postgres::PgRow;
14
15#[cfg(feature = "mysql")]
16use crate::mysql::MySqlRow;
17
18#[cfg(feature = "sqlite")]
19use crate::sqlite::SqliteRow;
20
21#[cfg(feature = "mssql")]
22use crate::mssql::MssqlRow;
23
24#[cfg(feature = "odbc")]
25use crate::odbc::OdbcRow;
26
27pub struct AnyRow {
28    pub(crate) kind: AnyRowKind,
29    pub(crate) columns: Vec<AnyColumn>,
30}
31
32impl crate::row::private_row::Sealed for AnyRow {}
33
34pub(crate) enum AnyRowKind {
35    #[cfg(feature = "postgres")]
36    Postgres(PgRow),
37
38    #[cfg(feature = "mysql")]
39    MySql(MySqlRow),
40
41    #[cfg(feature = "sqlite")]
42    Sqlite(SqliteRow),
43
44    #[cfg(feature = "mssql")]
45    Mssql(MssqlRow),
46
47    #[cfg(feature = "odbc")]
48    Odbc(OdbcRow),
49}
50
51impl Row for AnyRow {
52    type Database = Any;
53
54    fn columns(&self) -> &[AnyColumn] {
55        &self.columns
56    }
57
58    fn try_get_raw<I>(
59        &self,
60        index: I,
61    ) -> Result<<Self::Database as HasValueRef<'_>>::ValueRef, Error>
62    where
63        I: ColumnIndex<Self>,
64    {
65        let index = index.index(self)?;
66
67        match &self.kind {
68            #[cfg(feature = "postgres")]
69            AnyRowKind::Postgres(row) => row.try_get_raw(index).map(Into::into),
70
71            #[cfg(feature = "mysql")]
72            AnyRowKind::MySql(row) => row.try_get_raw(index).map(Into::into),
73
74            #[cfg(feature = "sqlite")]
75            AnyRowKind::Sqlite(row) => row.try_get_raw(index).map(Into::into),
76
77            #[cfg(feature = "mssql")]
78            AnyRowKind::Mssql(row) => row.try_get_raw(index).map(Into::into),
79
80            #[cfg(feature = "odbc")]
81            AnyRowKind::Odbc(row) => row.try_get_raw(index).map(Into::into),
82        }
83    }
84
85    fn try_get<'r, T, I>(&'r self, index: I) -> Result<T, Error>
86    where
87        I: ColumnIndex<Self>,
88        T: Decode<'r, Self::Database> + Type<Self::Database>,
89    {
90        let value = self.try_get_raw(&index)?;
91        let ty = value.type_info();
92
93        if !value.is_null() && !ty.is_null() && !T::compatible(&ty) {
94            Err(mismatched_types::<Self::Database, T>(&ty))
95        } else {
96            T::decode(value)
97        }
98        .map_err(|source| Error::ColumnDecode {
99            index: format!("{:?}", index),
100            source,
101        })
102    }
103}
104
105impl<'i> ColumnIndex<AnyRow> for &'i str
106where
107    &'i str: AnyColumnIndex,
108{
109    fn index(&self, row: &AnyRow) -> Result<usize, Error> {
110        match &row.kind {
111            #[cfg(feature = "postgres")]
112            AnyRowKind::Postgres(row) => self.index(row),
113
114            #[cfg(feature = "mysql")]
115            AnyRowKind::MySql(row) => self.index(row),
116
117            #[cfg(feature = "sqlite")]
118            AnyRowKind::Sqlite(row) => self.index(row),
119
120            #[cfg(feature = "mssql")]
121            AnyRowKind::Mssql(row) => self.index(row),
122
123            #[cfg(feature = "odbc")]
124            AnyRowKind::Odbc(row) => self.index(row),
125        }
126    }
127}