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