sqlx_sqlite/
row.rs

1#![allow(clippy::rc_buffer)]
2
3use std::sync::Arc;
4
5use sqlx_core::column::ColumnIndex;
6use sqlx_core::error::Error;
7use sqlx_core::ext::ustr::UStr;
8use sqlx_core::row::Row;
9use sqlx_core::HashMap;
10
11use crate::statement::StatementHandle;
12use crate::{Sqlite, SqliteColumn, SqliteValue, SqliteValueRef};
13
14/// Implementation of [`Row`] for SQLite.
15pub struct SqliteRow {
16    pub(crate) values: Box<[SqliteValue]>,
17    pub(crate) columns: Arc<Vec<SqliteColumn>>,
18    pub(crate) column_names: Arc<HashMap<UStr, usize>>,
19}
20
21// Accessing values from the statement object is
22// safe across threads as long as we don't call [sqlite3_step]
23
24// we block ourselves from doing that by only exposing
25// a set interface on [StatementHandle]
26
27unsafe impl Send for SqliteRow {}
28unsafe impl Sync for SqliteRow {}
29
30impl SqliteRow {
31    pub(crate) fn current(
32        statement: &StatementHandle,
33        columns: &Arc<Vec<SqliteColumn>>,
34        column_names: &Arc<HashMap<UStr, usize>>,
35    ) -> Self {
36        let size = statement.column_count();
37        let mut values = Vec::with_capacity(size);
38
39        for i in 0..size {
40            values.push(unsafe {
41                let raw = statement.column_value(i);
42
43                SqliteValue::new(raw, columns[i].type_info.clone())
44            });
45        }
46
47        Self {
48            values: values.into_boxed_slice(),
49            columns: Arc::clone(columns),
50            column_names: Arc::clone(column_names),
51        }
52    }
53}
54
55impl Row for SqliteRow {
56    type Database = Sqlite;
57
58    fn columns(&self) -> &[SqliteColumn] {
59        &self.columns
60    }
61
62    fn try_get_raw<I>(&self, index: I) -> Result<SqliteValueRef<'_>, Error>
63    where
64        I: ColumnIndex<Self>,
65    {
66        let index = index.index(self)?;
67        Ok(SqliteValueRef::value(&self.values[index]))
68    }
69}
70
71impl ColumnIndex<SqliteRow> for &'_ str {
72    fn index(&self, row: &SqliteRow) -> Result<usize, Error> {
73        row.column_names
74            .get(*self)
75            .ok_or_else(|| Error::ColumnNotFound((*self).into()))
76            .copied()
77    }
78}
79
80// #[cfg(feature = "any")]
81// impl From<SqliteRow> for crate::any::AnyRow {
82//     #[inline]
83//     fn from(row: SqliteRow) -> Self {
84//         crate::any::AnyRow {
85//             columns: row.columns.iter().map(|col| col.clone().into()).collect(),
86//             kind: crate::any::row::AnyRowKind::Sqlite(row),
87//         }
88//     }
89// }