sqlx_core_oldapi/any/
row.rs1use 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}