trailbase_sqlite/
params.rs1use rusqlite::types::ToSqlOutput;
2use rusqlite::{types, Result, Statement};
3use std::borrow::Cow;
4
5pub type NamedParams = Vec<(Cow<'static, str>, types::Value)>;
6pub type NamedParamRef<'a> = (Cow<'static, str>, types::ToSqlOutput<'a>);
7pub type NamedParamsRef<'a> = &'a [NamedParamRef<'a>];
8
9#[allow(missing_debug_implementations)]
11pub enum ToSqlType {
12 Borrowed(types::ValueRef<'static>),
14
15 Owned(types::Value),
17}
18
19impl rusqlite::ToSql for ToSqlType {
20 #[inline]
21 fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
22 Ok(match *self {
23 ToSqlType::Borrowed(v) => ToSqlOutput::Borrowed(v),
24 ToSqlType::Owned(ref v) => ToSqlOutput::Borrowed(types::ValueRef::from(v)),
25 })
26 }
27}
28
29impl<T: ?Sized> From<&'static T> for ToSqlType
30where
31 &'static T: Into<types::ValueRef<'static>>,
32{
33 #[inline]
34 fn from(t: &'static T) -> Self {
35 ToSqlType::Borrowed(t.into())
36 }
37}
38
39macro_rules! from_value(
40 ($t:ty) => (
41 impl From<$t> for ToSqlType {
42 #[inline]
43 fn from(t: $t) -> Self { ToSqlType::Owned(t.into())}
44 }
45 impl From<Option<$t>> for ToSqlType {
46 #[inline]
47 fn from(t: Option<$t>) -> Self {
48 match t {
49 Some(t) => ToSqlType::Owned(t.into()),
50 None => ToSqlType::Owned(types::Value::Null),
51 }
52 }
53 }
54 )
55);
56
57from_value!(String);
58from_value!(bool);
59from_value!(i64);
60from_value!(f64);
61from_value!(Vec<u8>);
62from_value!(types::Value);
63
64impl<const N: usize> From<[u8; N]> for ToSqlType {
65 fn from(t: [u8; N]) -> Self {
66 ToSqlType::Owned(types::Value::Blob(t.into()))
67 }
68}
69
70pub trait Params {
71 fn bind(self, stmt: &mut Statement<'_>) -> rusqlite::Result<()>;
72}
73
74impl Params for () {
75 fn bind(self, _stmt: &mut Statement<'_>) -> rusqlite::Result<()> {
76 Ok(())
77 }
78}
79
80impl Params for Vec<(String, types::Value)> {
81 fn bind(self, stmt: &mut Statement<'_>) -> rusqlite::Result<()> {
82 for (name, v) in self {
83 if let Some(idx) = stmt.parameter_index(&name)? {
84 stmt.raw_bind_parameter(idx, v)?;
85 };
86 }
87 return Ok(());
88 }
89}
90
91impl Params for NamedParams {
92 fn bind(self, stmt: &mut Statement<'_>) -> rusqlite::Result<()> {
93 for (name, v) in self {
94 let Some(idx) = stmt.parameter_index(&name)? else {
95 continue;
96 };
97 stmt.raw_bind_parameter(idx, v)?;
98 }
99 return Ok(());
100 }
101}
102
103impl Params for Vec<(&str, types::Value)> {
104 fn bind(self, stmt: &mut Statement<'_>) -> rusqlite::Result<()> {
105 for (name, v) in self {
106 let Some(idx) = stmt.parameter_index(name)? else {
107 continue;
108 };
109 stmt.raw_bind_parameter(idx, v)?;
110 }
111 return Ok(());
112 }
113}
114
115impl Params for &[(&str, types::Value)] {
116 fn bind(self, stmt: &mut Statement<'_>) -> rusqlite::Result<()> {
117 for (name, v) in self {
118 let Some(idx) = stmt.parameter_index(name)? else {
119 continue;
120 };
121 stmt.raw_bind_parameter(idx, v)?;
122 }
123 return Ok(());
124 }
125}
126
127impl Params for NamedParamsRef<'_> {
128 fn bind(self, stmt: &mut Statement<'_>) -> rusqlite::Result<()> {
129 for (name, v) in self {
130 let Some(idx) = stmt.parameter_index(name)? else {
131 continue;
132 };
133 stmt.raw_bind_parameter(idx, v)?;
134 }
135 return Ok(());
136 }
137}
138
139impl<const N: usize> Params for [(&str, types::Value); N] {
140 fn bind(self, stmt: &mut Statement<'_>) -> rusqlite::Result<()> {
141 for (name, v) in self {
142 let Some(idx) = stmt.parameter_index(name)? else {
143 continue;
144 };
145 stmt.raw_bind_parameter(idx, v)?;
146 }
147 return Ok(());
148 }
149}
150
151impl<const N: usize> Params for [(&str, ToSqlType); N] {
152 fn bind(self, stmt: &mut Statement<'_>) -> rusqlite::Result<()> {
153 for (name, v) in self {
154 let Some(idx) = stmt.parameter_index(name)? else {
155 continue;
156 };
157 stmt.raw_bind_parameter(idx, v)?;
158 }
159 return Ok(());
160 }
161}
162
163impl Params for Vec<types::Value> {
164 fn bind(self, stmt: &mut Statement<'_>) -> rusqlite::Result<()> {
165 for (idx, p) in self.into_iter().enumerate() {
166 stmt.raw_bind_parameter(idx + 1, p)?;
167 }
168 return Ok(());
169 }
170}
171
172impl Params for &[types::Value] {
173 fn bind(self, stmt: &mut Statement<'_>) -> rusqlite::Result<()> {
174 for (idx, p) in self.iter().enumerate() {
175 stmt.raw_bind_parameter(idx + 1, p)?;
176 }
177 return Ok(());
178 }
179}
180
181impl<const N: usize> Params for [ToSqlType; N] {
182 fn bind(self, stmt: &mut Statement<'_>) -> rusqlite::Result<()> {
183 for (idx, p) in self.into_iter().enumerate() {
184 stmt.raw_bind_parameter(idx + 1, p)?;
185 }
186 return Ok(());
187 }
188}
189
190impl<T, const N: usize> Params for &[T; N]
191where
192 T: rusqlite::ToSql + Send + Sync,
193{
194 fn bind(self, stmt: &mut Statement<'_>) -> rusqlite::Result<()> {
195 for (idx, p) in self.iter().enumerate() {
196 stmt.raw_bind_parameter(idx + 1, p)?;
197 }
198 return Ok(());
199 }
200}
201
202impl<T> Params for (T,)
203where
204 T: rusqlite::ToSql + Send + Sync,
205{
206 fn bind(self, stmt: &mut Statement<'_>) -> rusqlite::Result<()> {
207 return stmt.raw_bind_parameter(1, self.0);
208 }
209}
210
211impl<const N: usize> Params for [types::Value; N] {
212 fn bind(self, stmt: &mut Statement<'_>) -> rusqlite::Result<()> {
213 for (idx, p) in self.into_iter().enumerate() {
214 stmt.raw_bind_parameter(idx + 1, p)?;
215 }
216 return Ok(());
217 }
218}