sqlx_scylladb_core/
row.rs

1use bytes::Bytes;
2use sqlx::{ColumnIndex, Error, Row};
3
4use crate::{ScyllaDB, ScyllaDBColumn, ScyllaDBValueRef, statement::ScyllaDBStatementMetadata};
5
6/// Implementation of [sqlx::Row] for ScyllaDB.
7#[derive(Debug)]
8pub struct ScyllaDBRow {
9    raw_columns: Vec<Option<Bytes>>,
10    metadata: ScyllaDBStatementMetadata,
11}
12
13impl ScyllaDBRow {
14    #[inline(always)]
15    pub(crate) fn new(
16        raw_columns: Vec<Option<Bytes>>,
17        metadata: ScyllaDBStatementMetadata,
18    ) -> Self {
19        Self {
20            raw_columns,
21            metadata,
22        }
23    }
24
25    #[cfg(feature = "any")]
26    #[inline(always)]
27    pub(crate) fn column_names(
28        &self,
29    ) -> std::sync::Arc<sqlx_core::HashMap<sqlx_core::ext::ustr::UStr, usize>> {
30        self.metadata.column_names.clone()
31    }
32}
33
34impl Row for ScyllaDBRow {
35    type Database = ScyllaDB;
36
37    fn columns(&self) -> &[ScyllaDBColumn] {
38        &self.metadata.columns
39    }
40
41    fn try_get_raw<I>(&self, index: I) -> Result<ScyllaDBValueRef<'_>, sqlx::Error>
42    where
43        I: sqlx::ColumnIndex<Self>,
44    {
45        let index = index.index(self)?;
46        let column_metadata =
47            self.metadata
48                .columns
49                .get(index)
50                .ok_or_else(|| Error::ColumnIndexOutOfBounds {
51                    index: index,
52                    len: self.metadata.columns.len(),
53                })?;
54        let column_name = column_metadata.name.clone();
55        let column_type = &column_metadata.column_type;
56        let type_info = column_metadata.type_info.clone();
57        if let Some(column) = self.raw_columns.get(index) {
58            if let Some(value) = column {
59                Ok(ScyllaDBValueRef::new(
60                    column_name,
61                    type_info,
62                    value,
63                    column_type,
64                ))
65            } else {
66                Ok(ScyllaDBValueRef::null(column_name, column_type))
67            }
68        } else {
69            Ok(ScyllaDBValueRef::null(column_name, column_type))
70        }
71    }
72}
73
74impl ColumnIndex<ScyllaDBRow> for &'_ str {
75    fn index(&self, row: &ScyllaDBRow) -> Result<usize, sqlx::Error> {
76        row.metadata
77            .column_names
78            .get(*self)
79            .ok_or_else(|| Error::ColumnNotFound((*self).into()))
80            .copied()
81    }
82}