sqlx_core_oldapi/sqlite/
row.rs

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