1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#![allow(clippy::rc_buffer)]
use crate::decode::Decode;
use crate::statement::StatementHandle;
use crate::{Sqlite, SqliteColumn, SqliteTypeInfo, SqliteValue, SqliteValueRef};
use rbdc::db::{MetaData, Row};
use rbdc::error::Error;
use rbdc::ext::ustr::UStr;
use rbs::Value;
use std::collections::HashMap;
use std::fmt::{Debug, Formatter};
use std::ops::Deref;
use std::sync::Arc;
#[derive(Debug)]
pub struct SqliteRow {
pub(crate) values: Vec<SqliteValue>,
pub(crate) columns: Arc<Vec<SqliteColumn>>,
pub(crate) column_names: Arc<HashMap<UStr, usize>>,
}
unsafe impl Send for SqliteRow {}
unsafe impl Sync for SqliteRow {}
impl SqliteRow {
pub(crate) fn current(
statement: &StatementHandle,
columns: &Arc<Vec<SqliteColumn>>,
column_names: &Arc<HashMap<UStr, usize>>,
) -> Self {
let size = statement.column_count();
let mut values = Vec::with_capacity(size);
for i in 0..size {
values.push(unsafe {
let raw = statement.column_value(i);
SqliteValue::new(raw, columns[i].type_info.clone())
});
}
Self {
values: values,
columns: Arc::clone(columns),
column_names: Arc::clone(column_names),
}
}
}
#[derive(Debug)]
pub struct SqliteMetaData {
pub columns: Arc<Vec<SqliteColumn>>,
}
impl MetaData for SqliteMetaData {
fn column_len(&self) -> usize {
self.columns.len()
}
fn column_name(&self, i: usize) -> String {
self.columns[i].name.to_string()
}
fn column_type(&self, i: usize) -> String {
self.columns[i].type_info.to_string()
}
}
impl Row for SqliteRow {
fn meta_data(&self) -> Box<dyn MetaData> {
Box::new(SqliteMetaData {
columns: self.columns.clone(),
})
}
fn get(&mut self, i: usize) -> Option<Value> {
match self.try_take(i) {
Err(e) => {
log::error!("get error:{}", e);
None
}
Ok(v) => match Value::decode(v) {
Ok(v) => Some(v),
Err(e) => {
log::error!("get error:{}", e);
None
}
},
}
}
}
impl SqliteRow {
fn columns(&self) -> &[SqliteColumn] {
&self.columns
}
fn try_get_raw(&self, index: usize) -> Result<SqliteValueRef<'_>, Error> {
Ok(SqliteValueRef::value(&self.values[index]))
}
fn try_take(&mut self, index: usize) -> Result<SqliteValue, Error> {
if (index + 1) > self.values.len() {
return Err(Error::from("try_take out of range!"));
}
Ok(self.values.remove(index))
}
}