Skip to main content

sqlx_sqlserver/
statement.rs

1use sqlx_core::column::{Column, ColumnIndex};
2use sqlx_core::error::Error;
3use sqlx_core::sql_str::SqlStr;
4use sqlx_core::statement::Statement;
5use sqlx_core::Either;
6
7use crate::{Mssql, MssqlArguments, MssqlColumn, MssqlTypeInfo};
8
9/// SQL Server prepared statement metadata skeleton.
10#[derive(Debug, Clone)]
11pub struct MssqlStatement {
12    sql: SqlStr,
13    columns: Vec<MssqlColumn>,
14    parameters: Option<Either<Vec<MssqlTypeInfo>, usize>>,
15}
16
17impl MssqlStatement {
18    /// Creates statement metadata for tests and future prepare support.
19    pub fn new(sql: SqlStr, columns: Vec<MssqlColumn>) -> Self {
20        Self {
21            sql,
22            columns,
23            parameters: None,
24        }
25    }
26
27    pub(crate) fn with_parameters(
28        sql: SqlStr,
29        columns: Vec<MssqlColumn>,
30        parameters: Option<Either<Vec<MssqlTypeInfo>, usize>>,
31    ) -> Self {
32        Self {
33            sql,
34            columns,
35            parameters,
36        }
37    }
38}
39
40impl Statement for MssqlStatement {
41    type Database = Mssql;
42
43    fn into_sql(self) -> SqlStr {
44        self.sql
45    }
46
47    fn sql(&self) -> &SqlStr {
48        &self.sql
49    }
50
51    fn parameters(&self) -> Option<Either<&[MssqlTypeInfo], usize>> {
52        match &self.parameters {
53            Some(Either::Left(parameters)) => Some(Either::Left(parameters)),
54            Some(Either::Right(count)) => Some(Either::Right(*count)),
55            None => None,
56        }
57    }
58
59    fn columns(&self) -> &[MssqlColumn] {
60        &self.columns
61    }
62
63    sqlx_core::impl_statement_query!(MssqlArguments);
64}
65
66impl ColumnIndex<MssqlStatement> for usize {
67    fn index(&self, statement: &MssqlStatement) -> Result<usize, Error> {
68        if *self >= statement.columns.len() {
69            return Err(Error::ColumnIndexOutOfBounds {
70                index: *self,
71                len: statement.columns.len(),
72            });
73        }
74
75        Ok(*self)
76    }
77}
78
79impl ColumnIndex<MssqlStatement> for &'_ str {
80    fn index(&self, statement: &MssqlStatement) -> Result<usize, Error> {
81        statement
82            .columns
83            .iter()
84            .position(|column| column.name() == *self)
85            .ok_or_else(|| Error::ColumnNotFound((*self).to_owned()))
86    }
87}