1#![allow(clippy::rc_buffer)]
2
3use std::ptr::null_mut;
4use std::slice;
5use std::sync::atomic::{AtomicPtr, Ordering};
6use std::sync::{Arc, Weak};
7
8use cdbc::HashMap;
9
10use cdbc::column::ColumnIndex;
11use cdbc::error::Error;
12use cdbc::utils::ustr::UStr;
13use cdbc::row::Row;
14use crate::statement::{StatementHandle};
15use crate::{Sqlite, SqliteColumn, SqliteValue, SqliteValueRef};
16pub struct SqliteRow {
18 pub values: Box<[SqliteValue]>,
19 pub columns: Arc<Vec<SqliteColumn>>,
20 pub column_names: Arc<HashMap<UStr, usize>>,
21}
22
23unsafe impl Send for SqliteRow {}
30unsafe impl Sync for SqliteRow {}
31
32impl SqliteRow {
33 pub 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}