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// }