sqlx_exasol/
statement.rs

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