sqlx_rxqlite/value.rs
1use std::borrow::Cow;
2//use std::ptr::NonNull;
3//use std::slice::from_raw_parts;
4//use std::str::from_utf8;
5use std::sync::Arc;
6//use rxqlite::types::FromJsonValue;
7use crate::RXQLite;
8//use rxqlite::types::FromJsonValueRef;
9use rxqlite_common::FromValueRef;
10
11use sqlx_core::type_info::TypeInfo;
12
13/*
14use libsqlite3_sys::{
15 sqlite3_value, sqlite3_value_blob, sqlite3_value_bytes, sqlite3_value_double,
16 sqlite3_value_dup, sqlite3_value_free, sqlite3_value_int, sqlite3_value_int64,
17 sqlite3_value_type, SQLITE_NULL,
18};
19*/
20pub(crate) use sqlx_core::value::{Value, ValueRef};
21
22use crate::error::BoxDynError;
23//use crate::type_info::DataType;
24use crate::{/*Sqlite,*/ RXQLiteTypeInfo};
25
26pub(crate) enum RXQLiteValueData<'r> {
27 Value(&'r RXQLiteValue),
28}
29
30pub struct RXQLiteValueRef<'r>(pub(crate) RXQLiteValueData<'r>);
31
32impl<'r> RXQLiteValueRef<'r> {
33 pub(crate) fn value(value: &'r RXQLiteValue) -> Self {
34 Self(RXQLiteValueData::Value(value))
35 }
36
37 pub(super) fn int(&self) -> Result<i32, BoxDynError> {
38 match self.0 {
39 RXQLiteValueData::Value(v) => Ok(i32::from_value_ref(&v.handle)),
40 }
41 }
42
43 pub(super) fn int64(&self) -> Result<i64, BoxDynError> {
44 match self.0 {
45 RXQLiteValueData::Value(v) => Ok(i64::from_value_ref(&v.handle)),
46 }
47 }
48
49 pub(super) fn double(&self) -> Result<f64, BoxDynError> {
50 match self.0 {
51 RXQLiteValueData::Value(v) => Ok(f64::from_value_ref(&v.handle)),
52 }
53 }
54 /*
55 pub(super) fn blob(&self) -> Result<&'r [u8],BoxDynError> {
56 Err(std::io::Error::new(std::io::ErrorKind::Other , "blob not supported yet").into())
57 }
58 */
59 pub(super) fn text(&self) -> Result<String, BoxDynError> {
60 match self.0 {
61 RXQLiteValueData::Value(v) => Ok(String::from_value_ref(&v.handle)),
62 }
63 }
64}
65
66impl<'r> ValueRef<'r> for RXQLiteValueRef<'r> {
67 type Database = RXQLite;
68
69 fn to_owned(&self) -> RXQLiteValue {
70 match self.0 {
71 RXQLiteValueData::Value(v) => v.clone(),
72 }
73 }
74
75 fn type_info(&self) -> Cow<'_, RXQLiteTypeInfo> {
76 match self.0 {
77 RXQLiteValueData::Value(v) => v.type_info(),
78 }
79 }
80
81 fn is_null(&self) -> bool {
82 match self.0 {
83 RXQLiteValueData::Value(v) => v.is_null(),
84 }
85 }
86}
87
88#[derive(Clone)]
89pub struct RXQLiteValue {
90 pub(crate) handle: Arc<rxqlite_common::Value>,
91 pub(crate) type_info: RXQLiteTypeInfo,
92}
93
94//pub(crate) struct ValueHandle(NonNull<sqlite3_value>);
95
96// SAFE: only protected value objects are stored in RXQLiteValue
97/*
98unsafe impl Send for ValueHandle {}
99unsafe impl Sync for ValueHandle {}
100*/
101impl RXQLiteValue {
102 /*
103 pub(crate) unsafe fn new(value: *mut sqlite3_value, type_info: RXQLiteTypeInfo) -> Self {
104 debug_assert!(!value.is_null());
105
106 Self {
107 type_info,
108 handle: Arc::new(ValueHandle(NonNull::new_unchecked(sqlite3_value_dup(
109 value,
110 )))),
111 }
112 }
113 */
114 pub(crate) fn new(value: rxqlite_common::Value, type_info: RXQLiteTypeInfo) -> Self {
115 Self {
116 type_info,
117 handle: Arc::new(value),
118 }
119 }
120 fn type_info_opt(&self) -> Option<RXQLiteTypeInfo> {
121 /*
122 let dt = DataType::from_code(unsafe { sqlite3_value_type(self.handle.0.as_ptr()) });
123
124 if let DataType::Null = dt {
125 None
126 } else {
127 Some(RXQLiteTypeInfo(dt))
128 }
129 */
130 Some(self.type_info.clone())
131 }
132 /*
133 fn int(&self) -> i32 {
134 //unsafe { sqlite3_value_int(self.handle.0.as_ptr()) }
135 }
136
137 fn int64(&self) -> i64 {
138 //unsafe { sqlite3_value_int64(self.handle.0.as_ptr()) }
139 }
140
141 fn double(&self) -> f64 {
142 unsafe { sqlite3_value_double(self.handle.0.as_ptr()) }
143 }
144
145 fn blob(&self) -> &[u8] {
146 let len = unsafe { sqlite3_value_bytes(self.handle.0.as_ptr()) } as usize;
147
148 if len == 0 {
149 // empty blobs are NULL so just return an empty slice
150 return &[];
151 }
152
153 let ptr = unsafe { sqlite3_value_blob(self.handle.0.as_ptr()) } as *const u8;
154 debug_assert!(!ptr.is_null());
155
156 unsafe { from_raw_parts(ptr, len) }
157 }
158
159 fn text(&self) -> Result<&str, BoxDynError> {
160 Ok(from_utf8(self.blob())?)
161 }
162 */
163}
164
165impl Value for RXQLiteValue {
166 type Database = RXQLite;
167
168 fn as_ref(&self) -> RXQLiteValueRef<'_> {
169 RXQLiteValueRef::value(self)
170 }
171
172 fn type_info(&self) -> Cow<'_, RXQLiteTypeInfo> {
173 self.type_info_opt()
174 .map(Cow::Owned)
175 .unwrap_or(Cow::Borrowed(&self.type_info))
176 }
177
178 fn is_null(&self) -> bool {
179 self.type_info.is_null()
180 }
181}
182/*
183impl Drop for ValueHandle {
184 fn drop(&mut self) {
185 /*
186 unsafe {
187 sqlite3_value_free(self.0.as_ptr());
188 }
189 */
190 }
191}
192*/
193// #[cfg(feature = "any")]
194// impl<'r> From<RXQLiteValueRef<'r>> for crate::any::AnyValueRef<'r> {
195// #[inline]
196// fn from(value: RXQLiteValueRef<'r>) -> Self {
197// crate::any::AnyValueRef {
198// type_info: value.type_info().clone().into_owned().into(),
199// kind: crate::any::value::AnyValueRefKind::RXQLite(value),
200// }
201// }
202// }
203//
204// #[cfg(feature = "any")]
205// impl From<RXQLiteValue> for crate::any::AnyValue {
206// #[inline]
207// fn from(value: RXQLiteValue) -> Self {
208// crate::any::AnyValue {
209// type_info: value.type_info().clone().into_owned().into(),
210// kind: crate::any::value::AnyValueKind::RXQLite(value),
211// }
212// }
213// }