diesel/sqlite/connection/
bind_collector.rs1use crate::QueryResult;
2use crate::query_builder::{BindCollector, MoveableBindCollector};
3use crate::serialize::{IsNull, Output};
4use crate::sql_types::HasSqlType;
5use crate::sqlite::{Sqlite, SqliteType};
6use alloc::boxed::Box;
7use alloc::string::String;
8use alloc::vec::Vec;
9#[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
10use libsqlite3_sys as ffi;
11#[cfg(all(target_family = "wasm", target_os = "unknown"))]
12use sqlite_wasm_rs as ffi;
13
14#[derive(#[automatically_derived]
impl<'a> ::core::fmt::Debug for SqliteBindCollector<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"SqliteBindCollector", "binds", &&self.binds)
}
}Debug, #[automatically_derived]
impl<'a> ::core::default::Default for SqliteBindCollector<'a> {
#[inline]
fn default() -> SqliteBindCollector<'a> {
SqliteBindCollector { binds: ::core::default::Default::default() }
}
}Default)]
15pub struct SqliteBindCollector<'a> {
16 pub(in crate::sqlite) binds: Vec<(InternalSqliteBindValue<'a>, SqliteType)>,
17}
18
19impl SqliteBindCollector<'_> {
20 pub(in crate::sqlite) fn new() -> Self {
21 Self { binds: Vec::new() }
22 }
23}
24
25#[derive(#[automatically_derived]
impl<'a> ::core::fmt::Debug for SqliteBindValue<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"SqliteBindValue", "inner", &&self.inner)
}
}Debug)]
30pub struct SqliteBindValue<'a> {
31 pub(in crate::sqlite) inner: InternalSqliteBindValue<'a>,
32}
33
34impl From<i32> for SqliteBindValue<'_> {
35 fn from(i: i32) -> Self {
36 Self {
37 inner: InternalSqliteBindValue::I32(i),
38 }
39 }
40}
41
42impl From<i64> for SqliteBindValue<'_> {
43 fn from(i: i64) -> Self {
44 Self {
45 inner: InternalSqliteBindValue::I64(i),
46 }
47 }
48}
49
50impl From<f64> for SqliteBindValue<'_> {
51 fn from(f: f64) -> Self {
52 Self {
53 inner: InternalSqliteBindValue::F64(f),
54 }
55 }
56}
57
58impl<'a, T> From<Option<T>> for SqliteBindValue<'a>
59where
60 T: Into<SqliteBindValue<'a>>,
61{
62 fn from(o: Option<T>) -> Self {
63 match o {
64 Some(v) => v.into(),
65 None => Self {
66 inner: InternalSqliteBindValue::Null,
67 },
68 }
69 }
70}
71
72impl<'a> From<&'a str> for SqliteBindValue<'a> {
73 fn from(s: &'a str) -> Self {
74 Self {
75 inner: InternalSqliteBindValue::BorrowedString(s),
76 }
77 }
78}
79
80impl From<String> for SqliteBindValue<'_> {
81 fn from(s: String) -> Self {
82 Self {
83 inner: InternalSqliteBindValue::String(s.into_boxed_str()),
84 }
85 }
86}
87
88impl From<Vec<u8>> for SqliteBindValue<'_> {
89 fn from(b: Vec<u8>) -> Self {
90 Self {
91 inner: InternalSqliteBindValue::Binary(b.into_boxed_slice()),
92 }
93 }
94}
95
96impl<'a> From<&'a [u8]> for SqliteBindValue<'a> {
97 fn from(b: &'a [u8]) -> Self {
98 Self {
99 inner: InternalSqliteBindValue::BorrowedBinary(b),
100 }
101 }
102}
103
104#[derive(#[automatically_derived]
impl<'a> ::core::fmt::Debug for InternalSqliteBindValue<'a> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
InternalSqliteBindValue::BorrowedString(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"BorrowedString", &__self_0),
InternalSqliteBindValue::String(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "String",
&__self_0),
InternalSqliteBindValue::BorrowedBinary(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"BorrowedBinary", &__self_0),
InternalSqliteBindValue::Binary(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Binary",
&__self_0),
InternalSqliteBindValue::I32(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "I32",
&__self_0),
InternalSqliteBindValue::I64(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "I64",
&__self_0),
InternalSqliteBindValue::F64(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "F64",
&__self_0),
InternalSqliteBindValue::Null =>
::core::fmt::Formatter::write_str(f, "Null"),
}
}
}Debug)]
105pub(crate) enum InternalSqliteBindValue<'a> {
106 BorrowedString(&'a str),
107 String(Box<str>),
108 BorrowedBinary(&'a [u8]),
109 Binary(Box<[u8]>),
110 I32(i32),
111 I64(i64),
112 F64(f64),
113 Null,
114}
115
116impl core::fmt::Display for InternalSqliteBindValue<'_> {
117 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
118 let n = match self {
119 InternalSqliteBindValue::BorrowedString(_) | InternalSqliteBindValue::String(_) => {
120 "Text"
121 }
122 InternalSqliteBindValue::BorrowedBinary(_) | InternalSqliteBindValue::Binary(_) => {
123 "Binary"
124 }
125 InternalSqliteBindValue::I32(_) | InternalSqliteBindValue::I64(_) => "Integer",
126 InternalSqliteBindValue::F64(_) => "Float",
127 InternalSqliteBindValue::Null => "Null",
128 };
129 f.write_str(n)
130 }
131}
132
133impl InternalSqliteBindValue<'_> {
134 #[allow(unsafe_code)] pub(in crate::sqlite) fn result_of(
136 self,
137 ctx: &mut ffi::sqlite3_context,
138 ) -> Result<(), core::num::TryFromIntError> {
139 use core::ffi as libc;
140 unsafe {
144 match self {
145 InternalSqliteBindValue::BorrowedString(s) => ffi::sqlite3_result_text(
146 ctx,
147 s.as_ptr() as *const libc::c_char,
148 s.len().try_into()?,
149 ffi::SQLITE_TRANSIENT(),
150 ),
151 InternalSqliteBindValue::String(s) => ffi::sqlite3_result_text(
152 ctx,
153 s.as_ptr() as *const libc::c_char,
154 s.len().try_into()?,
155 ffi::SQLITE_TRANSIENT(),
156 ),
157 InternalSqliteBindValue::Binary(b) => ffi::sqlite3_result_blob(
158 ctx,
159 b.as_ptr() as *const libc::c_void,
160 b.len().try_into()?,
161 ffi::SQLITE_TRANSIENT(),
162 ),
163 InternalSqliteBindValue::BorrowedBinary(b) => ffi::sqlite3_result_blob(
164 ctx,
165 b.as_ptr() as *const libc::c_void,
166 b.len().try_into()?,
167 ffi::SQLITE_TRANSIENT(),
168 ),
169 InternalSqliteBindValue::I32(i) => ffi::sqlite3_result_int(ctx, i as libc::c_int),
170 InternalSqliteBindValue::I64(l) => ffi::sqlite3_result_int64(ctx, l),
171 InternalSqliteBindValue::F64(d) => {
172 ffi::sqlite3_result_double(ctx, d as libc::c_double)
173 }
174 InternalSqliteBindValue::Null => ffi::sqlite3_result_null(ctx),
175 }
176 }
177 Ok(())
178 }
179}
180
181impl<'a> BindCollector<'a, Sqlite> for SqliteBindCollector<'a> {
182 type Buffer = SqliteBindValue<'a>;
183
184 fn push_bound_value<T, U>(&mut self, bind: &'a U, metadata_lookup: &mut ()) -> QueryResult<()>
185 where
186 Sqlite: crate::sql_types::HasSqlType<T>,
187 U: crate::serialize::ToSql<T, Sqlite> + ?Sized,
188 {
189 let value = SqliteBindValue {
190 inner: InternalSqliteBindValue::Null,
191 };
192 let mut to_sql_output = Output::new(value, metadata_lookup);
193 let is_null = bind
194 .to_sql(&mut to_sql_output)
195 .map_err(crate::result::Error::SerializationError)?;
196 let bind = to_sql_output.into_inner();
197 let metadata = Sqlite::metadata(metadata_lookup);
198 self.binds.push((
199 match is_null {
200 IsNull::No => bind.inner,
201 IsNull::Yes => InternalSqliteBindValue::Null,
202 },
203 metadata,
204 ));
205 Ok(())
206 }
207
208 fn push_null_value(&mut self, metadata: SqliteType) -> QueryResult<()> {
209 self.binds.push((InternalSqliteBindValue::Null, metadata));
210 Ok(())
211 }
212}
213
214#[derive(#[automatically_derived]
impl ::core::fmt::Debug for OwnedSqliteBindValue {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
OwnedSqliteBindValue::String(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "String",
&__self_0),
OwnedSqliteBindValue::Binary(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Binary",
&__self_0),
OwnedSqliteBindValue::I32(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "I32",
&__self_0),
OwnedSqliteBindValue::I64(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "I64",
&__self_0),
OwnedSqliteBindValue::F64(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "F64",
&__self_0),
OwnedSqliteBindValue::Null =>
::core::fmt::Formatter::write_str(f, "Null"),
}
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for OwnedSqliteBindValue {
#[inline]
fn clone(&self) -> OwnedSqliteBindValue {
match self {
OwnedSqliteBindValue::String(__self_0) =>
OwnedSqliteBindValue::String(::core::clone::Clone::clone(__self_0)),
OwnedSqliteBindValue::Binary(__self_0) =>
OwnedSqliteBindValue::Binary(::core::clone::Clone::clone(__self_0)),
OwnedSqliteBindValue::I32(__self_0) =>
OwnedSqliteBindValue::I32(::core::clone::Clone::clone(__self_0)),
OwnedSqliteBindValue::I64(__self_0) =>
OwnedSqliteBindValue::I64(::core::clone::Clone::clone(__self_0)),
OwnedSqliteBindValue::F64(__self_0) =>
OwnedSqliteBindValue::F64(::core::clone::Clone::clone(__self_0)),
OwnedSqliteBindValue::Null => OwnedSqliteBindValue::Null,
}
}
}Clone)]
215enum OwnedSqliteBindValue {
216 String(Box<str>),
217 Binary(Box<[u8]>),
218 I32(i32),
219 I64(i64),
220 F64(f64),
221 Null,
222}
223
224impl<'a> core::convert::From<&InternalSqliteBindValue<'a>> for OwnedSqliteBindValue {
225 fn from(value: &InternalSqliteBindValue<'a>) -> Self {
226 match value {
227 InternalSqliteBindValue::String(s) => Self::String(s.clone()),
228 InternalSqliteBindValue::BorrowedString(s) => {
229 Self::String(String::from(*s).into_boxed_str())
230 }
231 InternalSqliteBindValue::Binary(b) => Self::Binary(b.clone()),
232 InternalSqliteBindValue::BorrowedBinary(s) => {
233 Self::Binary(Vec::from(*s).into_boxed_slice())
234 }
235 InternalSqliteBindValue::I32(val) => Self::I32(*val),
236 InternalSqliteBindValue::I64(val) => Self::I64(*val),
237 InternalSqliteBindValue::F64(val) => Self::F64(*val),
238 InternalSqliteBindValue::Null => Self::Null,
239 }
240 }
241}
242
243impl core::convert::From<&OwnedSqliteBindValue> for InternalSqliteBindValue<'_> {
244 fn from(value: &OwnedSqliteBindValue) -> Self {
245 match value {
246 OwnedSqliteBindValue::String(s) => Self::String(s.clone()),
247 OwnedSqliteBindValue::Binary(b) => Self::Binary(b.clone()),
248 OwnedSqliteBindValue::I32(val) => Self::I32(*val),
249 OwnedSqliteBindValue::I64(val) => Self::I64(*val),
250 OwnedSqliteBindValue::F64(val) => Self::F64(*val),
251 OwnedSqliteBindValue::Null => Self::Null,
252 }
253 }
254}
255
256#[derive(#[automatically_derived]
impl ::core::fmt::Debug for SqliteBindCollectorData {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field1_finish(f,
"SqliteBindCollectorData", "binds", &&self.binds)
}
}Debug)]
257pub struct SqliteBindCollectorData {
259 binds: Vec<(OwnedSqliteBindValue, SqliteType)>,
260}
261
262impl MoveableBindCollector<Sqlite> for SqliteBindCollector<'_> {
263 type BindData = SqliteBindCollectorData;
264
265 fn moveable(&self) -> Self::BindData {
266 let mut binds = Vec::with_capacity(self.binds.len());
267 for b in self
268 .binds
269 .iter()
270 .map(|(bind, tpe)| (OwnedSqliteBindValue::from(bind), *tpe))
271 {
272 binds.push(b);
273 }
274 SqliteBindCollectorData { binds }
275 }
276
277 fn append_bind_data(&mut self, from: &Self::BindData) {
278 self.binds.reserve_exact(from.binds.len());
279 self.binds.extend(
280 from.binds
281 .iter()
282 .map(|(bind, tpe)| (InternalSqliteBindValue::from(bind), *tpe)),
283 );
284 }
285
286 fn push_debug_binds<'a, 'b>(
287 bind_data: &Self::BindData,
288 f: &'a mut Vec<Box<dyn core::fmt::Debug + 'b>>,
289 ) {
290 f.extend(
291 bind_data
292 .binds
293 .iter()
294 .map(|(b, _)| Box::new(b.clone()) as Box<dyn core::fmt::Debug>),
295 );
296 }
297}