sqlx_postgres/
statement.rs

1use super::{PgColumn, PgTypeInfo};
2use crate::column::ColumnIndex;
3use crate::error::Error;
4use crate::ext::ustr::UStr;
5use crate::{PgArguments, Postgres};
6use std::borrow::Cow;
7use std::sync::Arc;
8
9pub(crate) use sqlx_core::statement::Statement;
10use sqlx_core::{Either, HashMap};
11
12#[derive(Debug, Clone)]
13pub struct PgStatement<'q> {
14    pub(crate) sql: Cow<'q, str>,
15    pub(crate) metadata: Arc<PgStatementMetadata>,
16}
17
18#[derive(Debug, Default)]
19pub(crate) struct PgStatementMetadata {
20    pub(crate) columns: Vec<PgColumn>,
21    // This `Arc` is not redundant; it's used to avoid deep-copying this map for the `Any` backend.
22    // See `sqlx-postgres/src/any.rs`
23    pub(crate) column_names: Arc<HashMap<UStr, usize>>,
24    pub(crate) parameters: Vec<PgTypeInfo>,
25}
26
27impl<'q> Statement<'q> for PgStatement<'q> {
28    type Database = Postgres;
29
30    fn to_owned(&self) -> PgStatement<'static> {
31        PgStatement::<'static> {
32            sql: Cow::Owned(self.sql.clone().into_owned()),
33            metadata: self.metadata.clone(),
34        }
35    }
36
37    fn sql(&self) -> &str {
38        &self.sql
39    }
40
41    fn parameters(&self) -> Option<Either<&[PgTypeInfo], usize>> {
42        Some(Either::Left(&self.metadata.parameters))
43    }
44
45    fn columns(&self) -> &[PgColumn] {
46        &self.metadata.columns
47    }
48
49    impl_statement_query!(PgArguments);
50}
51
52impl ColumnIndex<PgStatement<'_>> for &'_ str {
53    fn index(&self, statement: &PgStatement<'_>) -> Result<usize, Error> {
54        statement
55            .metadata
56            .column_names
57            .get(*self)
58            .ok_or_else(|| Error::ColumnNotFound((*self).into()))
59            .copied()
60    }
61}
62
63// #[cfg(feature = "any")]
64// impl<'q> From<PgStatement<'q>> for crate::any::AnyStatement<'q> {
65//     #[inline]
66//     fn from(statement: PgStatement<'q>) -> Self {
67//         crate::any::AnyStatement::<'q> {
68//             columns: statement
69//                 .metadata
70//                 .columns
71//                 .iter()
72//                 .map(|col| col.clone().into())
73//                 .collect(),
74//             column_names: statement.metadata.column_names.clone(),
75//             parameters: Some(Either::Left(
76//                 statement
77//                     .metadata
78//                     .parameters
79//                     .iter()
80//                     .map(|ty| ty.clone().into())
81//                     .collect(),
82//             )),
83//             sql: statement.sql,
84//         }
85//     }
86// }