sqlx_core/any/
statement.rs1use crate::any::{Any, AnyArguments, AnyColumn, AnyTypeInfo};
2use crate::column::ColumnIndex;
3use crate::database::Database;
4use crate::error::Error;
5use crate::ext::ustr::UStr;
6use crate::statement::Statement;
7use crate::HashMap;
8use either::Either;
9use std::borrow::Cow;
10use std::sync::Arc;
11
12pub struct AnyStatement<'q> {
13 #[doc(hidden)]
14 pub sql: Cow<'q, str>,
15 #[doc(hidden)]
16 pub parameters: Option<Either<Vec<AnyTypeInfo>, usize>>,
17 #[doc(hidden)]
18 pub column_names: Arc<HashMap<UStr, usize>>,
19 #[doc(hidden)]
20 pub columns: Vec<AnyColumn>,
21}
22
23impl<'q> Statement<'q> for AnyStatement<'q> {
24 type Database = Any;
25
26 fn to_owned(&self) -> AnyStatement<'static> {
27 AnyStatement::<'static> {
28 sql: Cow::Owned(self.sql.clone().into_owned()),
29 column_names: self.column_names.clone(),
30 parameters: self.parameters.clone(),
31 columns: self.columns.clone(),
32 }
33 }
34
35 fn sql(&self) -> &str {
36 &self.sql
37 }
38
39 fn parameters(&self) -> Option<Either<&[AnyTypeInfo], usize>> {
40 match &self.parameters {
41 Some(Either::Left(types)) => Some(Either::Left(types)),
42 Some(Either::Right(count)) => Some(Either::Right(*count)),
43 None => None,
44 }
45 }
46
47 fn columns(&self) -> &[AnyColumn] {
48 &self.columns
49 }
50
51 impl_statement_query!(AnyArguments<'_>);
52}
53
54impl<'i> ColumnIndex<AnyStatement<'_>> for &'i str {
55 fn index(&self, statement: &AnyStatement<'_>) -> Result<usize, Error> {
56 statement
57 .column_names
58 .get(*self)
59 .ok_or_else(|| Error::ColumnNotFound((*self).into()))
60 .copied()
61 }
62}
63
64impl<'q> AnyStatement<'q> {
65 #[doc(hidden)]
66 pub fn try_from_statement<S>(
67 query: &'q str,
68 statement: &S,
69 column_names: Arc<HashMap<UStr, usize>>,
70 ) -> crate::Result<Self>
71 where
72 S: Statement<'q>,
73 AnyTypeInfo: for<'a> TryFrom<&'a <S::Database as Database>::TypeInfo, Error = Error>,
74 AnyColumn: for<'a> TryFrom<&'a <S::Database as Database>::Column, Error = Error>,
75 {
76 let parameters = match statement.parameters() {
77 Some(Either::Left(parameters)) => Some(Either::Left(
78 parameters
79 .iter()
80 .map(AnyTypeInfo::try_from)
81 .collect::<Result<Vec<_>, _>>()?,
82 )),
83 Some(Either::Right(count)) => Some(Either::Right(count)),
84 None => None,
85 };
86
87 let columns = statement
88 .columns()
89 .iter()
90 .map(AnyColumn::try_from)
91 .collect::<Result<Vec<_>, _>>()?;
92
93 Ok(Self {
94 sql: query.into(),
95 columns,
96 column_names,
97 parameters,
98 })
99 }
100}