1 use crate::{Result, Statement, ToSql};
2 
3 mod sealed {
4     /// This trait exists just to ensure that the only impls of `trait Params`
5     /// that are allowed are ones in this crate.
6     pub trait Sealed {}
7 }
8 use sealed::Sealed;
9 
10 /// Trait used for [sets of parameter][params] passed into SQL
11 /// statements/queries.
12 ///
13 /// [params]: https://www.sqlite.org/c3ref/bind_blob.html
14 ///
15 /// Note: Currently, this trait can only be implemented inside this crate.
16 /// Additionally, it's methods (which are `doc(hidden)`) should currently not be
17 /// considered part of the stable API, although it's possible they will
18 /// stabilize in the future.
19 ///
20 /// # Passing parameters to SQLite
21 ///
22 /// Many functions in this library let you pass parameters to SQLite. Doing this
23 /// lets you avoid any risk of SQL injection, and is simpler than escaping
24 /// things manually. Aside from deprecated functions and a few helpers, this is
25 /// indicated by the function taking a generic argument that implements `Params`
26 /// (this trait).
27 ///
28 /// ## Positional parameters
29 ///
30 /// For cases where you want to pass a list of parameters where the number of
31 /// parameters is known at compile time, this can be done in one of the
32 /// following ways:
33 ///
34 /// - For small lists of parameters up to 16 items, they may alternatively be
35 ///   passed as a tuple, as in `thing.query((1, "foo"))`.
36 ///
37 ///     This is somewhat inconvenient for a single item, since you need a
38 ///     weird-looking trailing comma: `thing.query(("example",))`. That case is
39 ///     perhaps more cleanly expressed as `thing.query(["example"])`.
40 ///
41 /// - Using the [`rusqlite::params!`](crate::params!) macro, e.g.
42 ///   `thing.query(rusqlite::params![1, "foo", bar])`. This is mostly useful for
43 ///   heterogeneous lists where the number of parameters greater than 16, or
44 ///   homogenous lists of parameters where the number of parameters exceeds 32.
45 ///
46 /// - For small homogeneous lists of parameters, they can either be passed as:
47 ///
48 ///     - an array, as in `thing.query([1i32, 2, 3, 4])` or `thing.query(["foo",
49 ///       "bar", "baz"])`.
50 ///
51 ///     - a reference to an array of references, as in `thing.query(&["foo",
52 ///       "bar", "baz"])` or `thing.query(&[&1i32, &2, &3])`.
53 ///
54 ///         (Note: in this case we don't implement this for slices for coherence
55 ///         reasons, so it really is only for the "reference to array" types —
56 ///         hence why the number of parameters must be <= 32 or you need to
57 ///         reach for `rusqlite::params!`)
58 ///
59 ///     Unfortunately, in the current design it's not possible to allow this for
60 ///     references to arrays of non-references (e.g. `&[1i32, 2, 3]`). Code like
61 ///     this should instead either use `params!`, an array literal, a `&[&dyn
62 ///     ToSql]` or if none of those work, [`ParamsFromIter`].
63 ///
64 /// - As a slice of `ToSql` trait object references, e.g. `&[&dyn ToSql]`. This
65 ///   is mostly useful for passing parameter lists around as arguments without
66 ///   having every function take a generic `P: Params`.
67 ///
68 /// ### Example (positional)
69 ///
70 /// ```rust,no_run
71 /// # use rusqlite::{Connection, Result, params};
72 /// fn update_rows(conn: &Connection) -> Result<()> {
73 ///     let mut stmt = conn.prepare("INSERT INTO test (a, b) VALUES (?1, ?2)")?;
74 ///
75 ///     // Using a tuple:
76 ///     stmt.execute((0, "foobar"))?;
77 ///
78 ///     // Using `rusqlite::params!`:
79 ///     stmt.execute(params![1i32, "blah"])?;
80 ///
81 ///     // array literal — non-references
82 ///     stmt.execute([2i32, 3i32])?;
83 ///
84 ///     // array literal — references
85 ///     stmt.execute(["foo", "bar"])?;
86 ///
87 ///     // Slice literal, references:
88 ///     stmt.execute(&[&2i32, &3i32])?;
89 ///
90 ///     // Note: The types behind the references don't have to be `Sized`
91 ///     stmt.execute(&["foo", "bar"])?;
92 ///
93 ///     // However, this doesn't work (see above):
94 ///     // stmt.execute(&[1i32, 2i32])?;
95 ///     Ok(())
96 /// }
97 /// ```
98 ///
99 /// ## Named parameters
100 ///
101 /// SQLite lets you name parameters using a number of conventions (":foo",
102 /// "@foo", "$foo"). You can pass named parameters in to SQLite using rusqlite
103 /// in a few ways:
104 ///
105 /// - Using the [`rusqlite::named_params!`](crate::named_params!) macro, as in
106 ///   `stmt.execute(named_params!{ ":name": "foo", ":age": 99 })`. Similar to
107 ///   the `params` macro, this is most useful for heterogeneous lists of
108 ///   parameters, or lists where the number of parameters exceeds 32.
109 ///
110 /// - As a slice of `&[(&str, &dyn ToSql)]`. This is what essentially all of
111 ///   these boil down to in the end, conceptually at least. In theory you can
112 ///   pass this as `stmt`.
113 ///
114 /// - As array references, similar to the positional params. This looks like
115 ///   `thing.query(&[(":foo", &1i32), (":bar", &2i32)])` or
116 ///   `thing.query(&[(":foo", "abc"), (":bar", "def")])`.
117 ///
118 /// Note: Unbound named parameters will be left to the value they previously
119 /// were bound with, falling back to `NULL` for parameters which have never been
120 /// bound.
121 ///
122 /// ### Example (named)
123 ///
124 /// ```rust,no_run
125 /// # use rusqlite::{Connection, Result, named_params};
126 /// fn insert(conn: &Connection) -> Result<()> {
127 ///     let mut stmt = conn.prepare("INSERT INTO test (key, value) VALUES (:key, :value)")?;
128 ///     // Using `rusqlite::params!`:
129 ///     stmt.execute(named_params! { ":key": "one", ":val": 2 })?;
130 ///     // Alternatively:
131 ///     stmt.execute(&[(":key", "three"), (":val", "four")])?;
132 ///     // Or:
133 ///     stmt.execute(&[(":key", &100), (":val", &200)])?;
134 ///     Ok(())
135 /// }
136 /// ```
137 ///
138 /// ## No parameters
139 ///
140 /// You can just use an empty tuple or the empty array literal to run a query
141 /// that accepts no parameters.
142 ///
143 /// ### Example (no parameters)
144 ///
145 /// The empty tuple:
146 ///
147 /// ```rust,no_run
148 /// # use rusqlite::{Connection, Result, params};
149 /// fn delete_all_users(conn: &Connection) -> Result<()> {
150 ///     // You may also use `()`.
151 ///     conn.execute("DELETE FROM users", ())?;
152 ///     Ok(())
153 /// }
154 /// ```
155 ///
156 /// The empty array:
157 ///
158 /// ```rust,no_run
159 /// # use rusqlite::{Connection, Result, params};
160 /// fn delete_all_users(conn: &Connection) -> Result<()> {
161 ///     // Just use an empty array (e.g. `[]`) for no params.
162 ///     conn.execute("DELETE FROM users", [])?;
163 ///     Ok(())
164 /// }
165 /// ```
166 ///
167 /// ## Dynamic parameter list
168 ///
169 /// If you have a number of parameters which is unknown at compile time (for
170 /// example, building a dynamic query at runtime), you have two choices:
171 ///
172 /// - Use a `&[&dyn ToSql]`. This is often annoying to construct if you don't
173 ///   already have this type on-hand.
174 /// - Use the [`ParamsFromIter`] type. This essentially lets you wrap an
175 ///   iterator some `T: ToSql` with something that implements `Params`. The
176 ///   usage of this looks like `rusqlite::params_from_iter(something)`.
177 ///
178 /// A lot of the considerations here are similar either way, so you should see
179 /// the [`ParamsFromIter`] documentation for more info / examples.
180 pub trait Params: Sealed {
181     // XXX not public api, might not need to expose.
182     //
183     // Binds the parameters to the statement. It is unlikely calling this
184     // explicitly will do what you want. Please use `Statement::query` or
185     // similar directly.
186     //
187     // For now, just hide the function in the docs...
188     #[doc(hidden)]
__bind_in(self, stmt: &mut Statement<'_>) -> Result<()>189     fn __bind_in(self, stmt: &mut Statement<'_>) -> Result<()>;
190 }
191 
192 // Explicitly impl for empty array. Critically, for `conn.execute([])` to be
193 // unambiguous, this must be the *only* implementation for an empty array.
194 //
195 // This sadly prevents `impl<T: ToSql, const N: usize> Params for [T; N]`, which
196 // forces people to use `params![...]` or `rusqlite::params_from_iter` for long
197 // homogenous lists of parameters. This is not that big of a deal, but is
198 // unfortunate, especially because I mostly did it because I wanted a simple
199 // syntax for no-params that didnt require importing -- the empty tuple fits
200 // that nicely, but I didn't think of it until much later.
201 //
202 // Admittedly, if we did have the generic impl, then we *wouldn't* support the
203 // empty array literal as a parameter, since the `T` there would fail to be
204 // inferred. The error message here would probably be quite bad, and so on
205 // further thought, probably would end up causing *more* surprises, not less.
206 impl Sealed for [&(dyn ToSql + Send + Sync); 0] {}
207 impl Params for [&(dyn ToSql + Send + Sync); 0] {
208     #[inline]
__bind_in(self, stmt: &mut Statement<'_>) -> Result<()>209     fn __bind_in(self, stmt: &mut Statement<'_>) -> Result<()> {
210         stmt.ensure_parameter_count(0)
211     }
212 }
213 
214 impl Sealed for &[&dyn ToSql] {}
215 impl Params for &[&dyn ToSql] {
216     #[inline]
__bind_in(self, stmt: &mut Statement<'_>) -> Result<()>217     fn __bind_in(self, stmt: &mut Statement<'_>) -> Result<()> {
218         stmt.bind_parameters(self)
219     }
220 }
221 
222 impl Sealed for &[(&str, &dyn ToSql)] {}
223 impl Params for &[(&str, &dyn ToSql)] {
224     #[inline]
__bind_in(self, stmt: &mut Statement<'_>) -> Result<()>225     fn __bind_in(self, stmt: &mut Statement<'_>) -> Result<()> {
226         stmt.bind_parameters_named(self)
227     }
228 }
229 
230 // Manual impls for the empty and singleton tuple, although the rest are covered
231 // by macros.
232 impl Sealed for () {}
233 impl Params for () {
234     #[inline]
__bind_in(self, stmt: &mut Statement<'_>) -> Result<()>235     fn __bind_in(self, stmt: &mut Statement<'_>) -> Result<()> {
236         stmt.ensure_parameter_count(0)
237     }
238 }
239 
240 // I'm pretty sure you could tweak the `single_tuple_impl` to accept this.
241 impl<T: ToSql> Sealed for (T,) {}
242 impl<T: ToSql> Params for (T,) {
243     #[inline]
__bind_in(self, stmt: &mut Statement<'_>) -> Result<()>244     fn __bind_in(self, stmt: &mut Statement<'_>) -> Result<()> {
245         stmt.ensure_parameter_count(1)?;
246         stmt.raw_bind_parameter(1, self.0)?;
247         Ok(())
248     }
249 }
250 
251 macro_rules! single_tuple_impl {
252     ($count:literal : $(($field:tt $ftype:ident)),* $(,)?) => {
253         impl<$($ftype,)*> Sealed for ($($ftype,)*) where $($ftype: ToSql,)* {}
254         impl<$($ftype,)*> Params for ($($ftype,)*) where $($ftype: ToSql,)* {
255             fn __bind_in(self, stmt: &mut Statement<'_>) -> Result<()> {
256                 stmt.ensure_parameter_count($count)?;
257                 $({
258                     debug_assert!($field < $count);
259                     stmt.raw_bind_parameter($field + 1, self.$field)?;
260                 })+
261                 Ok(())
262             }
263         }
264     }
265 }
266 
267 // We use a the macro for the rest, but don't bother with trying to implement it
268 // in a single invocation (it's possible to do, but my attempts were almost the
269 // same amount of code as just writing it out this way, and much more dense --
270 // it is a more complicated case than the TryFrom macro we have for row->tuple).
271 //
272 // Note that going up to 16 (rather than the 12 that the impls in the stdlib
273 // usually support) is just because we did the same in the `TryFrom<Row>` impl.
274 // I didn't catch that then, but there's no reason to remove it, and it seems
275 // nice to be consistent here; this way putting data in the database and getting
276 // data out of the database are more symmetric in a (mostly superficial) sense.
277 single_tuple_impl!(2: (0 A), (1 B));
278 single_tuple_impl!(3: (0 A), (1 B), (2 C));
279 single_tuple_impl!(4: (0 A), (1 B), (2 C), (3 D));
280 single_tuple_impl!(5: (0 A), (1 B), (2 C), (3 D), (4 E));
281 single_tuple_impl!(6: (0 A), (1 B), (2 C), (3 D), (4 E), (5 F));
282 single_tuple_impl!(7: (0 A), (1 B), (2 C), (3 D), (4 E), (5 F), (6 G));
283 single_tuple_impl!(8: (0 A), (1 B), (2 C), (3 D), (4 E), (5 F), (6 G), (7 H));
284 single_tuple_impl!(9: (0 A), (1 B), (2 C), (3 D), (4 E), (5 F), (6 G), (7 H), (8 I));
285 single_tuple_impl!(10: (0 A), (1 B), (2 C), (3 D), (4 E), (5 F), (6 G), (7 H), (8 I), (9 J));
286 single_tuple_impl!(11: (0 A), (1 B), (2 C), (3 D), (4 E), (5 F), (6 G), (7 H), (8 I), (9 J), (10 K));
287 single_tuple_impl!(12: (0 A), (1 B), (2 C), (3 D), (4 E), (5 F), (6 G), (7 H), (8 I), (9 J), (10 K), (11 L));
288 single_tuple_impl!(13: (0 A), (1 B), (2 C), (3 D), (4 E), (5 F), (6 G), (7 H), (8 I), (9 J), (10 K), (11 L), (12 M));
289 single_tuple_impl!(14: (0 A), (1 B), (2 C), (3 D), (4 E), (5 F), (6 G), (7 H), (8 I), (9 J), (10 K), (11 L), (12 M), (13 N));
290 single_tuple_impl!(15: (0 A), (1 B), (2 C), (3 D), (4 E), (5 F), (6 G), (7 H), (8 I), (9 J), (10 K), (11 L), (12 M), (13 N), (14 O));
291 single_tuple_impl!(16: (0 A), (1 B), (2 C), (3 D), (4 E), (5 F), (6 G), (7 H), (8 I), (9 J), (10 K), (11 L), (12 M), (13 N), (14 O), (15 P));
292 
293 macro_rules! impl_for_array_ref {
294     ($($N:literal)+) => {$(
295         // These are already generic, and there's a shedload of them, so lets
296         // avoid the compile time hit from making them all inline for now.
297         impl<T: ToSql + ?Sized> Sealed for &[&T; $N] {}
298         impl<T: ToSql + ?Sized> Params for &[&T; $N] {
299             fn __bind_in(self, stmt: &mut Statement<'_>) -> Result<()> {
300                 stmt.bind_parameters(self)
301             }
302         }
303         impl<T: ToSql + ?Sized> Sealed for &[(&str, &T); $N] {}
304         impl<T: ToSql + ?Sized> Params for &[(&str, &T); $N] {
305             fn __bind_in(self, stmt: &mut Statement<'_>) -> Result<()> {
306                 stmt.bind_parameters_named(self)
307             }
308         }
309         impl<T: ToSql> Sealed for [T; $N] {}
310         impl<T: ToSql> Params for [T; $N] {
311             #[inline]
312             fn __bind_in(self, stmt: &mut Statement<'_>) -> Result<()> {
313                 stmt.bind_parameters(&self)
314             }
315         }
316     )+};
317 }
318 
319 // Following libstd/libcore's (old) lead, implement this for arrays up to `[_;
320 // 32]`. Note `[_; 0]` is intentionally omitted for coherence reasons, see the
321 // note above the impl of `[&dyn ToSql; 0]` for more information.
322 //
323 // Note that this unfortunately means we can't use const generics here, but I
324 // don't really think it matters -- users who hit that can use `params!` anyway.
325 impl_for_array_ref!(
326     1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
327     18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
328 );
329 
330 /// Adapter type which allows any iterator over [`ToSql`] values to implement
331 /// [`Params`].
332 ///
333 /// This struct is created by the [`params_from_iter`] function.
334 ///
335 /// This can be useful if you have something like an `&[String]` (of unknown
336 /// length), and you want to use them with an API that wants something
337 /// implementing `Params`. This way, you can avoid having to allocate storage
338 /// for something like a `&[&dyn ToSql]`.
339 ///
340 /// This essentially is only ever actually needed when dynamically generating
341 /// SQL — static SQL (by definition) has the number of parameters known
342 /// statically. As dynamically generating SQL is itself pretty advanced, this
343 /// API is itself for advanced use cases (See "Realistic use case" in the
344 /// examples).
345 ///
346 /// # Example
347 ///
348 /// ## Basic usage
349 ///
350 /// ```rust,no_run
351 /// use rusqlite::{params_from_iter, Connection, Result};
352 /// use std::collections::BTreeSet;
353 ///
354 /// fn query(conn: &Connection, ids: &BTreeSet<String>) -> Result<()> {
355 ///     assert_eq!(ids.len(), 3, "Unrealistic sample code");
356 ///
357 ///     let mut stmt = conn.prepare("SELECT * FROM users WHERE id IN (?1, ?2, ?3)")?;
358 ///     let _rows = stmt.query(params_from_iter(ids.iter()))?;
359 ///
360 ///     // use _rows...
361 ///     Ok(())
362 /// }
363 /// ```
364 ///
365 /// ## Realistic use case
366 ///
367 /// Here's how you'd use `ParamsFromIter` to call [`Statement::exists`] with a
368 /// dynamic number of parameters.
369 ///
370 /// ```rust,no_run
371 /// use rusqlite::{Connection, Result};
372 ///
373 /// pub fn any_active_users(conn: &Connection, usernames: &[String]) -> Result<bool> {
374 ///     if usernames.is_empty() {
375 ///         return Ok(false);
376 ///     }
377 ///
378 ///     // Note: `repeat_vars` never returns anything attacker-controlled, so
379 ///     // it's fine to use it in a dynamically-built SQL string.
380 ///     let vars = repeat_vars(usernames.len());
381 ///
382 ///     let sql = format!(
383 ///         // In practice this would probably be better as an `EXISTS` query.
384 ///         "SELECT 1 FROM user WHERE is_active AND name IN ({}) LIMIT 1",
385 ///         vars,
386 ///     );
387 ///     let mut stmt = conn.prepare(&sql)?;
388 ///     stmt.exists(rusqlite::params_from_iter(usernames))
389 /// }
390 ///
391 /// // Helper function to return a comma-separated sequence of `?`.
392 /// // - `repeat_vars(0) => panic!(...)`
393 /// // - `repeat_vars(1) => "?"`
394 /// // - `repeat_vars(2) => "?,?"`
395 /// // - `repeat_vars(3) => "?,?,?"`
396 /// // - ...
397 /// fn repeat_vars(count: usize) -> String {
398 ///     assert_ne!(count, 0);
399 ///     let mut s = "?,".repeat(count);
400 ///     // Remove trailing comma
401 ///     s.pop();
402 ///     s
403 /// }
404 /// ```
405 ///
406 /// That is fairly complex, and even so would need even more work to be fully
407 /// production-ready:
408 ///
409 /// - production code should ensure `usernames` isn't so large that it will
410 ///   surpass [`conn.limit(Limit::SQLITE_LIMIT_VARIABLE_NUMBER)`][limits]),
411 ///   chunking if too large. (Note that the limits api requires rusqlite to have
412 ///   the "limits" feature).
413 ///
414 /// - `repeat_vars` can be implemented in a way that avoids needing to allocate
415 ///   a String.
416 ///
417 /// - Etc...
418 ///
419 /// [limits]: crate::Connection::limit
420 ///
421 /// This complexity reflects the fact that `ParamsFromIter` is mainly intended
422 /// for advanced use cases — most of the time you should know how many
423 /// parameters you have statically (and if you don't, you're either doing
424 /// something tricky, or should take a moment to think about the design).
425 #[derive(Clone, Debug)]
426 pub struct ParamsFromIter<I>(I);
427 
428 /// Constructor function for a [`ParamsFromIter`]. See its documentation for
429 /// more.
430 #[inline]
params_from_iter<I>(iter: I) -> ParamsFromIter<I> where I: IntoIterator, I::Item: ToSql,431 pub fn params_from_iter<I>(iter: I) -> ParamsFromIter<I>
432 where
433     I: IntoIterator,
434     I::Item: ToSql,
435 {
436     ParamsFromIter(iter)
437 }
438 
439 impl<I> Sealed for ParamsFromIter<I>
440 where
441     I: IntoIterator,
442     I::Item: ToSql,
443 {
444 }
445 
446 impl<I> Params for ParamsFromIter<I>
447 where
448     I: IntoIterator,
449     I::Item: ToSql,
450 {
451     #[inline]
__bind_in(self, stmt: &mut Statement<'_>) -> Result<()>452     fn __bind_in(self, stmt: &mut Statement<'_>) -> Result<()> {
453         stmt.bind_parameters(self.0)
454     }
455 }
456