sqlx_core_oldapi/any/
row.rs

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