1#![allow(clippy::rc_buffer)]
2
3use crate::decode::Decode;
4use crate::statement::StatementHandle;
5use crate::{SqliteColumn, SqliteValue, SqliteValueRef};
6use rbdc::db::{MetaData, Row};
7use rbdc::error::Error;
8use rbdc::ext::ustr::UStr;
9use rbs::Value;
10use std::collections::HashMap;
11use std::fmt::Debug;
12use std::sync::Arc;
13
14#[derive(Debug)]
16pub struct SqliteRow {
17 pub(crate) values: Vec<SqliteValue>,
18 pub(crate) columns: Arc<Vec<SqliteColumn>>,
19 pub(crate) column_names: Arc<HashMap<UStr, usize>>,
20}
21
22unsafe impl Send for SqliteRow {}
29
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..columns.len() {
42 values.push(unsafe {
43 let raw = statement.column_value(i);
44 SqliteValue::new(raw, columns[i].type_info.clone())
45 });
46 }
47
48 Self {
49 values: values,
50 columns: Arc::clone(columns),
51 column_names: Arc::clone(column_names),
52 }
53 }
54}
55
56#[derive(Debug)]
57pub struct SqliteMetaData {
58 pub columns: Arc<Vec<SqliteColumn>>,
59}
60
61impl MetaData for SqliteMetaData {
62 fn column_len(&self) -> usize {
63 self.columns.len()
64 }
65
66 fn column_name(&self, i: usize) -> String {
67 self.columns[i].name.to_string()
68 }
69
70 fn column_type(&self, i: usize) -> String {
71 self.columns[i].type_info.to_string()
72 }
73}
74
75impl Row for SqliteRow {
76 fn meta_data(&self) -> Box<dyn MetaData> {
77 Box::new(SqliteMetaData {
78 columns: self.columns.clone(),
79 })
80 }
81
82 fn get(&mut self, i: usize) -> Result<Value, Error> {
83 match self.try_take(i) {
84 Err(e) => Err(Error::from(format!("get error index:{},error:{}", i, e))),
85 Ok(v) => Value::decode(v),
86 }
87 }
88}
89
90impl SqliteRow {
91 fn columns(&self) -> &[SqliteColumn] {
92 &self.columns
93 }
94
95 fn try_get_raw(&self, index: usize) -> Result<SqliteValueRef<'_>, Error> {
96 Ok(SqliteValueRef::value(&self.values[index]))
97 }
98
99 fn try_take(&mut self, index: usize) -> Result<SqliteValue, Error> {
100 if (index + 1) > self.values.len() {
101 return Err(Error::from("try_take out of range!"));
102 }
103 Ok(self.values.remove(index))
104 }
105}