sqlx_exasol_impl/
statement.rs

1use std::sync::Arc;
2
3use sqlx_core::{
4    column::ColumnIndex, database::Database, ext::ustr::UStr, impl_statement_query,
5    sql_str::SqlStr, statement::Statement, Either, HashMap,
6};
7
8use crate::{
9    arguments::ExaArguments, column::ExaColumn, database::Exasol, type_info::ExaTypeInfo,
10    SqlxError, SqlxResult,
11};
12
13/// Implementor of [`Statement`].
14#[derive(Debug, Clone)]
15pub struct ExaStatement {
16    pub(crate) sql: SqlStr,
17    pub(crate) metadata: ExaStatementMetadata,
18}
19
20#[derive(Debug, Clone)]
21pub struct ExaStatementMetadata {
22    pub columns: Arc<[ExaColumn]>,
23    pub column_names: Arc<HashMap<UStr, usize>>,
24    pub parameters: Arc<[ExaTypeInfo]>,
25}
26
27impl ExaStatementMetadata {
28    pub fn new(columns: Arc<[ExaColumn]>, parameters: Arc<[ExaTypeInfo]>) -> Self {
29        let column_names = columns
30            .as_ref()
31            .iter()
32            .enumerate()
33            .map(|(idx, col)| (col.name.clone(), idx))
34            .collect();
35
36        Self {
37            columns,
38            column_names: Arc::new(column_names),
39            parameters,
40        }
41    }
42}
43
44impl Statement for ExaStatement {
45    type Database = Exasol;
46
47    fn into_sql(self) -> SqlStr {
48        self.sql
49    }
50
51    fn sql(&self) -> &SqlStr {
52        &self.sql
53    }
54
55    fn parameters(&self) -> Option<Either<&[<Self::Database as Database>::TypeInfo], usize>> {
56        Some(Either::Left(&self.metadata.parameters))
57    }
58
59    fn columns(&self) -> &[<Self::Database as Database>::Column] {
60        &self.metadata.columns
61    }
62
63    impl_statement_query!(ExaArguments);
64}
65
66impl ColumnIndex<ExaStatement> for &str {
67    fn index(&self, statement: &ExaStatement) -> SqlxResult<usize> {
68        statement
69            .metadata
70            .column_names
71            .get(*self)
72            .ok_or_else(|| SqlxError::ColumnNotFound((*self).into()))
73            .copied()
74    }
75}