Skip to main content

rusqlite/
statement.rs

1use std::iter::IntoIterator;
2use std::os::raw::{c_int, c_void};
3#[cfg(feature = "array")]
4use std::rc::Rc;
5use std::slice::from_raw_parts;
6use std::{convert, fmt, mem, ptr, str};
7
8use super::ffi;
9use super::{len_as_c_int, str_for_sqlite};
10use super::{
11    AndThenRows, Connection, Error, MappedRows, Params, RawStatement, Result, Row, Rows, ValueRef,
12};
13use crate::types::{ToSql, ToSqlOutput};
14#[cfg(feature = "array")]
15use crate::vtab::array::{free_array, ARRAY_TYPE};
16
17/// A prepared statement.
18pub struct Statement<'conn> {
19    conn: &'conn Connection,
20    pub(crate) stmt: RawStatement,
21}
22
23impl Statement<'_> {
24    /// Execute the prepared statement.
25    ///
26    /// On success, returns the number of rows that were changed or inserted or
27    /// deleted (via `sqlite3_changes`).
28    ///
29    /// ## Example
30    ///
31    /// ### Use with positional parameters
32    ///
33    /// ```rust,no_run
34    /// # use rusqlite::{Connection, Result, params};
35    /// fn update_rows(conn: &Connection) -> Result<()> {
36    ///     let mut stmt = conn.prepare("UPDATE foo SET bar = 'baz' WHERE qux = ?")?;
37    ///     // The `rusqlite::params!` macro is mostly useful when the parameters do not
38    ///     // all have the same type, or if there are more than 32 parameters
39    ///     // at once.
40    ///     stmt.execute(params![1i32])?;
41    ///     // However, it's not required, many cases are fine as:
42    ///     stmt.execute(&[&2i32])?;
43    ///     // Or even:
44    ///     stmt.execute([2i32])?;
45    ///     Ok(())
46    /// }
47    /// ```
48    ///
49    /// ### Use with named parameters
50    ///
51    /// ```rust,no_run
52    /// # use rusqlite::{Connection, Result, named_params};
53    /// fn insert(conn: &Connection) -> Result<()> {
54    ///     let mut stmt = conn.prepare("INSERT INTO test (key, value) VALUES (:key, :value)")?;
55    ///     // The `rusqlite::named_params!` macro (like `params!`) is useful for heterogeneous
56    ///     // sets of parameters (where all parameters are not the same type), or for queries
57    ///     // with many (more than 32) statically known parameters.
58    ///     stmt.execute(named_params!{ ":key": "one", ":val": 2 })?;
59    ///     // However, named parameters can also be passed like:
60    ///     stmt.execute(&[(":key", "three"), (":val", "four")])?;
61    ///     // Or even: (note that a &T is required for the value type, currently)
62    ///     stmt.execute(&[(":key", &100), (":val", &200)])?;
63    ///     Ok(())
64    /// }
65    /// ```
66    ///
67    /// ### Use without parameters
68    ///
69    /// ```rust,no_run
70    /// # use rusqlite::{Connection, Result, params};
71    /// fn delete_all(conn: &Connection) -> Result<()> {
72    ///     let mut stmt = conn.prepare("DELETE FROM users")?;
73    ///     stmt.execute([])?;
74    ///     Ok(())
75    /// }
76    /// ```
77    ///
78    /// # Failure
79    ///
80    /// Will return `Err` if binding parameters fails, the executed statement
81    /// returns rows (in which case `query` should be used instead), or the
82    /// underlying SQLite call fails.
83    #[inline]
84    pub fn execute<P: Params>(&mut self, params: P) -> Result<usize> {
85        params.bind_in(self)?;
86        self.execute_with_bound_parameters()
87    }
88
89    /// Execute the prepared statement with named parameter(s).
90    ///
91    /// Note: This function is deprecated in favor of [`Statement::execute`],
92    /// which can now take named parameters directly.
93    ///
94    /// If any parameters that were in the prepared statement are not included
95    /// in `params`, they will continue to use the most-recently bound value
96    /// from a previous call to `execute_named`, or `NULL` if they have never
97    /// been bound.
98    ///
99    /// On success, returns the number of rows that were changed or inserted or
100    /// deleted (via `sqlite3_changes`).
101    ///
102    /// # Failure
103    ///
104    /// Will return `Err` if binding parameters fails, the executed statement
105    /// returns rows (in which case `query` should be used instead), or the
106    /// underlying SQLite call fails.
107    #[deprecated = "You can use `execute` with named params now."]
108    #[inline]
109    pub fn execute_named(&mut self, params: &[(&str, &dyn ToSql)]) -> Result<usize> {
110        self.execute(params)
111    }
112
113    /// Execute an INSERT and return the ROWID.
114    ///
115    /// # Note
116    ///
117    /// This function is a convenience wrapper around [`execute()`](Statement::execute) intended for
118    /// queries that insert a single item. It is possible to misuse this
119    /// function in a way that it cannot detect, such as by calling it on a
120    /// statement which _updates_ a single
121    /// item rather than inserting one. Please don't do that.
122    ///
123    /// # Failure
124    ///
125    /// Will return `Err` if no row is inserted or many rows are inserted.
126    #[inline]
127    pub fn insert<P: Params>(&mut self, params: P) -> Result<i64> {
128        let changes = self.execute(params)?;
129        match changes {
130            1 => Ok(self.conn.last_insert_rowid()),
131            _ => Err(Error::StatementChangedRows(changes)),
132        }
133    }
134
135    /// Execute the prepared statement, returning a handle to the resulting
136    /// rows.
137    ///
138    /// Due to lifetime restricts, the rows handle returned by `query` does not
139    /// implement the `Iterator` trait. Consider using [`query_map`](Statement::query_map) or
140    /// [`query_and_then`](Statement::query_and_then) instead, which do.
141    ///
142    /// ## Example
143    ///
144    /// ### Use without parameters
145    ///
146    /// ```rust,no_run
147    /// # use rusqlite::{Connection, Result};
148    /// fn get_names(conn: &Connection) -> Result<Vec<String>> {
149    ///     let mut stmt = conn.prepare("SELECT name FROM people")?;
150    ///     let mut rows = stmt.query([])?;
151    ///
152    ///     let mut names = Vec::new();
153    ///     while let Some(row) = rows.next()? {
154    ///         names.push(row.get(0)?);
155    ///     }
156    ///
157    ///     Ok(names)
158    /// }
159    /// ```
160    ///
161    /// ### Use with positional parameters
162    ///
163    /// ```rust,no_run
164    /// # use rusqlite::{Connection, Result};
165    /// fn query(conn: &Connection, name: &str) -> Result<()> {
166    ///     let mut stmt = conn.prepare("SELECT * FROM test where name = ?")?;
167    ///     let mut rows = stmt.query(rusqlite::params![name])?;
168    ///     while let Some(row) = rows.next()? {
169    ///         // ...
170    ///     }
171    ///     Ok(())
172    /// }
173    /// ```
174    ///
175    /// Or, equivalently (but without the [`params!`] macro).
176    ///
177    /// ```rust,no_run
178    /// # use rusqlite::{Connection, Result};
179    /// fn query(conn: &Connection, name: &str) -> Result<()> {
180    ///     let mut stmt = conn.prepare("SELECT * FROM test where name = ?")?;
181    ///     let mut rows = stmt.query(&[name])?;
182    ///     while let Some(row) = rows.next()? {
183    ///         // ...
184    ///     }
185    ///     Ok(())
186    /// }
187    /// ```
188    ///
189    /// ### Use with named parameters
190    ///
191    /// ```rust,no_run
192    /// # use rusqlite::{Connection, Result};
193    /// fn query(conn: &Connection) -> Result<()> {
194    ///     let mut stmt = conn.prepare("SELECT * FROM test where name = :name")?;
195    ///     let mut rows = stmt.query(&[(":name", &"one")])?;
196    ///     while let Some(row) = rows.next()? {
197    ///         // ...
198    ///     }
199    ///     Ok(())
200    /// }
201    /// ```
202    ///
203    /// Note, the `named_params!` macro is provided for syntactic convenience,
204    /// and so the above example could also be written as:
205    ///
206    /// ```rust,no_run
207    /// # use rusqlite::{Connection, Result, named_params};
208    /// fn query(conn: &Connection) -> Result<()> {
209    ///     let mut stmt = conn.prepare("SELECT * FROM test where name = :name")?;
210    ///     let mut rows = stmt.query(named_params!{ ":name": "one" })?;
211    ///     while let Some(row) = rows.next()? {
212    ///         // ...
213    ///     }
214    ///     Ok(())
215    /// }
216    /// ```
217    ///
218    /// ## Failure
219    ///
220    /// Will return `Err` if binding parameters fails.
221    #[inline]
222    pub fn query<P: Params>(&mut self, params: P) -> Result<Rows<'_>> {
223        self.check_readonly()?;
224        params.bind_in(self)?;
225        Ok(Rows::new(self))
226    }
227
228    /// Execute the prepared statement with named parameter(s), returning a
229    /// handle for the resulting rows.
230    ///
231    /// Note: This function is deprecated in favor of [`Statement::query`],
232    /// which can now take named parameters directly.
233    ///
234    /// If any parameters that were in the prepared statement are not included
235    /// in `params`, they will continue to use the most-recently bound value
236    /// from a previous call to `query_named`, or `NULL` if they have never been
237    /// bound.
238    ///
239    /// # Failure
240    ///
241    /// Will return `Err` if binding parameters fails.
242    #[deprecated = "You can use `query` with named params now."]
243    pub fn query_named(&mut self, params: &[(&str, &dyn ToSql)]) -> Result<Rows<'_>> {
244        self.query(params)
245    }
246
247    /// Executes the prepared statement and maps a function over the resulting
248    /// rows, returning an iterator over the mapped function results.
249    ///
250    /// `f` is used to tranform the _streaming_ iterator into a _standard_
251    /// iterator.
252    ///
253    /// This is equivalent to `stmt.query(params)?.mapped(f)`.
254    ///
255    /// ## Example
256    ///
257    /// ### Use with positional params
258    ///
259    /// ```rust,no_run
260    /// # use rusqlite::{Connection, Result};
261    /// fn get_names(conn: &Connection) -> Result<Vec<String>> {
262    ///     let mut stmt = conn.prepare("SELECT name FROM people")?;
263    ///     let rows = stmt.query_map([], |row| row.get(0))?;
264    ///
265    ///     let mut names = Vec::new();
266    ///     for name_result in rows {
267    ///         names.push(name_result?);
268    ///     }
269    ///
270    ///     Ok(names)
271    /// }
272    /// ```
273    ///
274    /// ### Use with named params
275    ///
276    /// ```rust,no_run
277    /// # use rusqlite::{Connection, Result};
278    /// fn get_names(conn: &Connection) -> Result<Vec<String>> {
279    ///     let mut stmt = conn.prepare("SELECT name FROM people WHERE id = :id")?;
280    ///     let rows = stmt.query_map(&[(":id", &"one")], |row| row.get(0))?;
281    ///
282    ///     let mut names = Vec::new();
283    ///     for name_result in rows {
284    ///         names.push(name_result?);
285    ///     }
286    ///
287    ///     Ok(names)
288    /// }
289    /// ```
290    /// ## Failure
291    ///
292    /// Will return `Err` if binding parameters fails.
293    pub fn query_map<T, P, F>(&mut self, params: P, f: F) -> Result<MappedRows<'_, F>>
294    where
295        P: Params,
296        F: FnMut(&Row<'_>) -> Result<T>,
297    {
298        self.query(params).map(|rows| rows.mapped(f))
299    }
300
301    /// Execute the prepared statement with named parameter(s), returning an
302    /// iterator over the result of calling the mapping function over the
303    /// query's rows.
304    ///
305    /// Note: This function is deprecated in favor of [`Statement::query_map`],
306    /// which can now take named parameters directly.
307    ///
308    /// If any parameters that were in the prepared statement
309    /// are not included in `params`, they will continue to use the
310    /// most-recently bound value from a previous call to `query_named`,
311    /// or `NULL` if they have never been bound.
312    ///
313    /// `f` is used to tranform the _streaming_ iterator into a _standard_
314    /// iterator.
315    ///
316    /// ## Failure
317    ///
318    /// Will return `Err` if binding parameters fails.
319    #[deprecated = "You can use `query_map` with named params now."]
320    pub fn query_map_named<T, F>(
321        &mut self,
322        params: &[(&str, &dyn ToSql)],
323        f: F,
324    ) -> Result<MappedRows<'_, F>>
325    where
326        F: FnMut(&Row<'_>) -> Result<T>,
327    {
328        self.query_map(params, f)
329    }
330
331    /// Executes the prepared statement and maps a function over the resulting
332    /// rows, where the function returns a `Result` with `Error` type
333    /// implementing `std::convert::From<Error>` (so errors can be unified).
334    ///
335    /// This is equivalent to `stmt.query(params)?.and_then(f)`.
336    ///
337    /// ## Example
338    ///
339    /// ### Use with named params
340    ///
341    /// ```rust,no_run
342    /// # use rusqlite::{Connection, Result};
343    /// struct Person {
344    ///     name: String,
345    /// };
346    ///
347    /// fn name_to_person(name: String) -> Result<Person> {
348    ///     // ... check for valid name
349    ///     Ok(Person { name: name })
350    /// }
351    ///
352    /// fn get_names(conn: &Connection) -> Result<Vec<Person>> {
353    ///     let mut stmt = conn.prepare("SELECT name FROM people WHERE id = :id")?;
354    ///     let rows =
355    ///         stmt.query_and_then(&[(":id", &"one")], |row| name_to_person(row.get(0)?))?;
356    ///
357    ///     let mut persons = Vec::new();
358    ///     for person_result in rows {
359    ///         persons.push(person_result?);
360    ///     }
361    ///
362    ///     Ok(persons)
363    /// }
364    /// ```
365    ///
366    /// ### Use with positional params
367    ///
368    /// ```rust,no_run
369    /// # use rusqlite::{Connection, Result};
370    /// fn get_names(conn: &Connection) -> Result<Vec<String>> {
371    ///     let mut stmt = conn.prepare("SELECT name FROM people WHERE id = ?")?;
372    ///     let rows = stmt.query_and_then(&["one"], |row| row.get::<_, String>(0))?;
373    ///
374    ///     let mut persons = Vec::new();
375    ///     for person_result in rows {
376    ///         persons.push(person_result?);
377    ///     }
378    ///
379    ///     Ok(persons)
380    /// }
381    /// ```
382    ///
383    /// # Failure
384    ///
385    /// Will return `Err` if binding parameters fails.
386    #[inline]
387    pub fn query_and_then<T, E, P, F>(&mut self, params: P, f: F) -> Result<AndThenRows<'_, F>>
388    where
389        P: Params,
390        E: convert::From<Error>,
391        F: FnMut(&Row<'_>) -> Result<T, E>,
392    {
393        self.query(params).map(|rows| rows.and_then(f))
394    }
395
396    /// Execute the prepared statement with named parameter(s), returning an
397    /// iterator over the result of calling the mapping function over the
398    /// query's rows.
399    ///
400    /// Note: This function is deprecated in favor of [`Statement::query_and_then`],
401    /// which can now take named parameters directly.
402    ///
403    /// If any parameters that were in the prepared statement are not included
404    /// in `params`, they will continue to use the most-recently bound value
405    /// from a previous call to `query_named`, or `NULL` if they have never been
406    /// bound.
407    ///
408    /// ## Failure
409    ///
410    /// Will return `Err` if binding parameters fails.
411    #[deprecated = "You can use `query_and_then` with named params now."]
412    pub fn query_and_then_named<T, E, F>(
413        &mut self,
414        params: &[(&str, &dyn ToSql)],
415        f: F,
416    ) -> Result<AndThenRows<'_, F>>
417    where
418        E: convert::From<Error>,
419        F: FnMut(&Row<'_>) -> Result<T, E>,
420    {
421        self.query_and_then(params, f)
422    }
423
424    /// Return `true` if a query in the SQL statement it executes returns one
425    /// or more rows and `false` if the SQL returns an empty set.
426    #[inline]
427    pub fn exists<P: Params>(&mut self, params: P) -> Result<bool> {
428        let mut rows = self.query(params)?;
429        let exists = rows.next()?.is_some();
430        Ok(exists)
431    }
432
433    /// Convenience method to execute a query that is expected to return a
434    /// single row.
435    ///
436    /// If the query returns more than one row, all rows except the first are
437    /// ignored.
438    ///
439    /// Returns `Err(QueryReturnedNoRows)` if no results are returned. If the
440    /// query truly is optional, you can call [`.optional()`](crate::OptionalExtension::optional) on the result of
441    /// this to get a `Result<Option<T>>` (requires that the trait `rusqlite::OptionalExtension`
442    /// is imported).
443    ///
444    /// # Failure
445    ///
446    /// Will return `Err` if the underlying SQLite call fails.
447    pub fn query_row<T, P, F>(&mut self, params: P, f: F) -> Result<T>
448    where
449        P: Params,
450        F: FnOnce(&Row<'_>) -> Result<T>,
451    {
452        let mut rows = self.query(params)?;
453
454        rows.get_expected_row().and_then(|r| f(&r))
455    }
456
457    /// Convenience method to execute a query with named parameter(s) that is
458    /// expected to return a single row.
459    ///
460    /// Note: This function is deprecated in favor of [`Statement::query_and_then`],
461    /// which can now take named parameters directly.
462    ///
463    /// If the query returns more than one row, all rows except the first are
464    /// ignored.
465    ///
466    /// Returns `Err(QueryReturnedNoRows)` if no results are returned. If the
467    /// query truly is optional, you can call [`.optional()`](crate::OptionalExtension::optional) on the result of
468    /// this to get a `Result<Option<T>>` (requires that the trait `rusqlite::OptionalExtension`
469    /// is imported).
470    ///
471    /// # Failure
472    ///
473    /// Will return `Err` if `sql` cannot be converted to a C-compatible string
474    /// or if the underlying SQLite call fails.
475    #[deprecated = "You can use `query_row` with named params now."]
476    pub fn query_row_named<T, F>(&mut self, params: &[(&str, &dyn ToSql)], f: F) -> Result<T>
477    where
478        F: FnOnce(&Row<'_>) -> Result<T>,
479    {
480        self.query_row(params, f)
481    }
482
483    /// Consumes the statement.
484    ///
485    /// Functionally equivalent to the `Drop` implementation, but allows
486    /// callers to see any errors that occur.
487    ///
488    /// # Failure
489    ///
490    /// Will return `Err` if the underlying SQLite call fails.
491    #[inline]
492    pub fn finalize(mut self) -> Result<()> {
493        self.finalize_()
494    }
495
496    /// Return the (one-based) index of an SQL parameter given its name.
497    ///
498    /// Note that the initial ":" or "$" or "@" or "?" used to specify the
499    /// parameter is included as part of the name.
500    ///
501    /// ```rust,no_run
502    /// # use rusqlite::{Connection, Result};
503    /// fn example(conn: &Connection) -> Result<()> {
504    ///     let stmt = conn.prepare("SELECT * FROM test WHERE name = :example")?;
505    ///     let index = stmt.parameter_index(":example")?;
506    ///     assert_eq!(index, Some(1));
507    ///     Ok(())
508    /// }
509    /// ```
510    ///
511    /// # Failure
512    ///
513    /// Will return Err if `name` is invalid. Will return Ok(None) if the name
514    /// is valid but not a bound parameter of this statement.
515    #[inline]
516    pub fn parameter_index(&self, name: &str) -> Result<Option<usize>> {
517        Ok(self.stmt.bind_parameter_index(name))
518    }
519
520    #[inline]
521    pub(crate) fn bind_parameters<P>(&mut self, params: P) -> Result<()>
522    where
523        P: IntoIterator,
524        P::Item: ToSql,
525    {
526        let expected = self.stmt.bind_parameter_count();
527        let mut index = 0;
528        for p in params.into_iter() {
529            index += 1; // The leftmost SQL parameter has an index of 1.
530            if index > expected {
531                break;
532            }
533            self.bind_parameter(&p, index)?;
534        }
535        if index != expected {
536            Err(Error::InvalidParameterCount(index, expected))
537        } else {
538            Ok(())
539        }
540    }
541
542    #[inline]
543    pub(crate) fn bind_parameters_named<T: ?Sized + ToSql>(
544        &mut self,
545        params: &[(&str, &T)],
546    ) -> Result<()> {
547        for &(name, value) in params {
548            if let Some(i) = self.parameter_index(name)? {
549                let ts: &dyn ToSql = &value;
550                self.bind_parameter(ts, i)?;
551            } else {
552                return Err(Error::InvalidParameterName(name.into()));
553            }
554        }
555        Ok(())
556    }
557
558    /// Return the number of parameters that can be bound to this statement.
559    #[inline]
560    pub fn parameter_count(&self) -> usize {
561        self.stmt.bind_parameter_count()
562    }
563
564    /// Low level API to directly bind a parameter to a given index.
565    ///
566    /// Note that the index is one-based, that is, the first parameter index is
567    /// 1 and not 0. This is consistent with the SQLite API and the values given
568    /// to parameters bound as `?NNN`.
569    ///
570    /// The valid values for `one_based_col_index` begin at `1`, and end at
571    /// [`Statement::parameter_count`], inclusive.
572    ///
573    /// # Caveats
574    ///
575    /// This should not generally be used, but is available for special cases
576    /// such as:
577    ///
578    /// - binding parameters where a gap exists.
579    /// - binding named and positional parameters in the same query.
580    /// - separating parameter binding from query execution.
581    ///
582    /// Statements that have had their parameters bound this way should be
583    /// queried or executed by [`Statement::raw_query`] or
584    /// [`Statement::raw_execute`]. Other functions are not guaranteed to work.
585    ///
586    /// # Example
587    ///
588    /// ```rust,no_run
589    /// # use rusqlite::{Connection, Result};
590    /// fn query(conn: &Connection) -> Result<()> {
591    ///     let mut stmt = conn.prepare("SELECT * FROM test WHERE name = :name AND value > ?2")?;
592    ///     let name_index = stmt.parameter_index(":name")?.expect("No such parameter");
593    ///     stmt.raw_bind_parameter(name_index, "foo")?;
594    ///     stmt.raw_bind_parameter(2, 100)?;
595    ///     let mut rows = stmt.raw_query();
596    ///     while let Some(row) = rows.next()? {
597    ///         // ...
598    ///     }
599    ///     Ok(())
600    /// }
601    /// ```
602    #[inline]
603    pub fn raw_bind_parameter<T: ToSql>(
604        &mut self,
605        one_based_col_index: usize,
606        param: T,
607    ) -> Result<()> {
608        // This is the same as `bind_parameter` but slightly more ergonomic and
609        // correctly takes `&mut self`.
610        self.bind_parameter(&param, one_based_col_index)
611    }
612
613    /// Low level API to execute a statement given that all parameters were
614    /// bound explicitly with the [`Statement::raw_bind_parameter`] API.
615    ///
616    /// # Caveats
617    ///
618    /// Any unbound parameters will have `NULL` as their value.
619    ///
620    /// This should not generally be used outside of special cases, and
621    /// functions in the [`Statement::execute`] family should be preferred.
622    ///
623    /// # Failure
624    ///
625    /// Will return `Err` if the executed statement returns rows (in which case
626    /// `query` should be used instead), or the underlying SQLite call fails.
627    #[inline]
628    pub fn raw_execute(&mut self) -> Result<usize> {
629        self.execute_with_bound_parameters()
630    }
631
632    /// Low level API to get `Rows` for this query given that all parameters
633    /// were bound explicitly with the [`Statement::raw_bind_parameter`] API.
634    ///
635    /// # Caveats
636    ///
637    /// Any unbound parameters will have `NULL` as their value.
638    ///
639    /// This should not generally be used outside of special cases, and
640    /// functions in the [`Statement::query`] family should be preferred.
641    ///
642    /// Note that if the SQL does not return results, [`Statement::raw_execute`]
643    /// should be used instead.
644    #[inline]
645    pub fn raw_query(&mut self) -> Rows<'_> {
646        Rows::new(self)
647    }
648
649    // generic because many of these branches can constant fold away.
650    fn bind_parameter<P: ?Sized + ToSql>(&self, param: &P, col: usize) -> Result<()> {
651        let value = param.to_sql()?;
652
653        let ptr = unsafe { self.stmt.ptr() };
654        let value = match value {
655            ToSqlOutput::Borrowed(v) => v,
656            ToSqlOutput::Owned(ref v) => ValueRef::from(v),
657
658            #[cfg(feature = "blob")]
659            ToSqlOutput::ZeroBlob(len) => {
660                return self
661                    .conn
662                    .decode_result(unsafe { ffi::sqlite3_bind_zeroblob(ptr, col as c_int, len) });
663            }
664            #[cfg(feature = "array")]
665            ToSqlOutput::Array(a) => {
666                return self.conn.decode_result(unsafe {
667                    ffi::sqlite3_bind_pointer(
668                        ptr,
669                        col as c_int,
670                        Rc::into_raw(a) as *mut c_void,
671                        ARRAY_TYPE,
672                        Some(free_array),
673                    )
674                });
675            }
676        };
677        self.conn.decode_result(match value {
678            ValueRef::Null => unsafe { ffi::sqlite3_bind_null(ptr, col as c_int) },
679            ValueRef::Integer(i) => unsafe { ffi::sqlite3_bind_int64(ptr, col as c_int, i) },
680            ValueRef::Real(r) => unsafe { ffi::sqlite3_bind_double(ptr, col as c_int, r) },
681            ValueRef::Text(s) => unsafe {
682                let (c_str, len, destructor) = str_for_sqlite(s)?;
683                ffi::sqlite3_bind_text(ptr, col as c_int, c_str, len, destructor)
684            },
685            ValueRef::Blob(b) => unsafe {
686                let length = len_as_c_int(b.len())?;
687                if length == 0 {
688                    ffi::sqlite3_bind_zeroblob(ptr, col as c_int, 0)
689                } else {
690                    ffi::sqlite3_bind_blob(
691                        ptr,
692                        col as c_int,
693                        b.as_ptr() as *const c_void,
694                        length,
695                        ffi::SQLITE_TRANSIENT(),
696                    )
697                }
698            },
699        })
700    }
701
702    #[inline]
703    fn execute_with_bound_parameters(&mut self) -> Result<usize> {
704        self.check_update()?;
705        let r = self.stmt.step();
706        self.stmt.reset();
707        match r {
708            ffi::SQLITE_DONE => Ok(self.conn.changes()),
709            ffi::SQLITE_ROW => Err(Error::ExecuteReturnedResults),
710            _ => Err(self.conn.decode_result(r).unwrap_err()),
711        }
712    }
713
714    #[inline]
715    fn finalize_(&mut self) -> Result<()> {
716        let mut stmt = unsafe { RawStatement::new(ptr::null_mut(), 0) };
717        mem::swap(&mut stmt, &mut self.stmt);
718        self.conn.decode_result(stmt.finalize())
719    }
720
721    #[cfg(not(feature = "modern_sqlite"))]
722    #[inline]
723    fn check_readonly(&self) -> Result<()> {
724        Ok(())
725    }
726
727    #[cfg(feature = "modern_sqlite")]
728    #[inline]
729    fn check_readonly(&self) -> Result<()> {
730        /*if !self.stmt.readonly() { does not work for PRAGMA
731            return Err(Error::InvalidQuery);
732        }*/
733        Ok(())
734    }
735
736    #[cfg(all(feature = "modern_sqlite", feature = "extra_check"))]
737    #[inline]
738    fn check_update(&self) -> Result<()> {
739        // sqlite3_column_count works for DML but not for DDL (ie ALTER)
740        if self.column_count() > 0 && self.stmt.readonly() {
741            return Err(Error::ExecuteReturnedResults);
742        }
743        Ok(())
744    }
745
746    #[cfg(all(not(feature = "modern_sqlite"), feature = "extra_check"))]
747    #[inline]
748    fn check_update(&self) -> Result<()> {
749        // sqlite3_column_count works for DML but not for DDL (ie ALTER)
750        if self.column_count() > 0 {
751            return Err(Error::ExecuteReturnedResults);
752        }
753        Ok(())
754    }
755
756    #[cfg(not(feature = "extra_check"))]
757    #[inline]
758    fn check_update(&self) -> Result<()> {
759        Ok(())
760    }
761
762    /// Returns a string containing the SQL text of prepared statement with
763    /// bound parameters expanded.
764    #[cfg(feature = "modern_sqlite")]
765    pub fn expanded_sql(&self) -> Option<String> {
766        self.stmt
767            .expanded_sql()
768            .map(|s| s.to_string_lossy().to_string())
769    }
770
771    /// Get the value for one of the status counters for this statement.
772    #[inline]
773    #[cfg(not(any(
774        feature = "loadable_extension",
775        feature = "loadable_extension_embedded"
776    )))]
777    pub fn get_status(&self, status: StatementStatus) -> i32 {
778        self.stmt.get_status(status, false)
779    }
780
781    /// Reset the value of one of the status counters for this statement,
782    #[inline]
783    /// returning the value it had before resetting.
784    #[cfg(not(any(
785        feature = "loadable_extension",
786        feature = "loadable_extension_embedded"
787    )))]
788    pub fn reset_status(&self, status: StatementStatus) -> i32 {
789        self.stmt.get_status(status, true)
790    }
791
792    #[cfg(feature = "extra_check")]
793    #[inline]
794    pub(crate) fn check_no_tail(&self) -> Result<()> {
795        if self.stmt.has_tail() {
796            Err(Error::MultipleStatement)
797        } else {
798            Ok(())
799        }
800    }
801
802    #[cfg(not(feature = "extra_check"))]
803    #[inline]
804    pub(crate) fn check_no_tail(&self) -> Result<()> {
805        Ok(())
806    }
807
808    /// Safety: This is unsafe, because using `sqlite3_stmt` after the
809    /// connection has closed is illegal, but `RawStatement` does not enforce
810    /// this, as it loses our protective `'conn` lifetime bound.
811    #[inline]
812    pub(crate) unsafe fn into_raw(mut self) -> RawStatement {
813        let mut stmt = RawStatement::new(ptr::null_mut(), 0);
814        mem::swap(&mut stmt, &mut self.stmt);
815        stmt
816    }
817}
818
819impl fmt::Debug for Statement<'_> {
820    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
821        let sql = if self.stmt.is_null() {
822            Ok("")
823        } else {
824            str::from_utf8(self.stmt.sql().unwrap().to_bytes())
825        };
826        f.debug_struct("Statement")
827            .field("conn", self.conn)
828            .field("stmt", &self.stmt)
829            .field("sql", &sql)
830            .finish()
831    }
832}
833
834impl Drop for Statement<'_> {
835    #[allow(unused_must_use)]
836    #[inline]
837    fn drop(&mut self) {
838        self.finalize_();
839    }
840}
841
842impl Statement<'_> {
843    #[inline]
844    pub(super) fn new(conn: &Connection, stmt: RawStatement) -> Statement<'_> {
845        Statement { conn, stmt }
846    }
847
848    pub(super) fn value_ref(&self, col: usize) -> ValueRef<'_> {
849        let raw = unsafe { self.stmt.ptr() };
850
851        match self.stmt.column_type(col) {
852            ffi::SQLITE_NULL => ValueRef::Null,
853            ffi::SQLITE_INTEGER => {
854                ValueRef::Integer(unsafe { ffi::sqlite3_column_int64(raw, col as c_int) })
855            }
856            ffi::SQLITE_FLOAT => {
857                ValueRef::Real(unsafe { ffi::sqlite3_column_double(raw, col as c_int) })
858            }
859            ffi::SQLITE_TEXT => {
860                let s = unsafe {
861                    // Quoting from "Using SQLite" book:
862                    // To avoid problems, an application should first extract the desired type using
863                    // a sqlite3_column_xxx() function, and then call the
864                    // appropriate sqlite3_column_bytes() function.
865                    let text = ffi::sqlite3_column_text(raw, col as c_int);
866                    let len = ffi::sqlite3_column_bytes(raw, col as c_int);
867                    assert!(
868                        !text.is_null(),
869                        "unexpected SQLITE_TEXT column type with NULL data"
870                    );
871                    from_raw_parts(text as *const u8, len as usize)
872                };
873
874                ValueRef::Text(s)
875            }
876            ffi::SQLITE_BLOB => {
877                let (blob, len) = unsafe {
878                    (
879                        ffi::sqlite3_column_blob(raw, col as c_int),
880                        ffi::sqlite3_column_bytes(raw, col as c_int),
881                    )
882                };
883
884                assert!(
885                    len >= 0,
886                    "unexpected negative return from sqlite3_column_bytes"
887                );
888                if len > 0 {
889                    assert!(
890                        !blob.is_null(),
891                        "unexpected SQLITE_BLOB column type with NULL data"
892                    );
893                    ValueRef::Blob(unsafe { from_raw_parts(blob as *const u8, len as usize) })
894                } else {
895                    // The return value from sqlite3_column_blob() for a zero-length BLOB
896                    // is a NULL pointer.
897                    ValueRef::Blob(&[])
898                }
899            }
900            _ => unreachable!("sqlite3_column_type returned invalid value"),
901        }
902    }
903
904    #[inline]
905    pub(super) fn step(&self) -> Result<bool> {
906        match self.stmt.step() {
907            ffi::SQLITE_ROW => Ok(true),
908            ffi::SQLITE_DONE => Ok(false),
909            code => Err(self.conn.decode_result(code).unwrap_err()),
910        }
911    }
912
913    #[inline]
914    pub(super) fn reset(&self) -> c_int {
915        self.stmt.reset()
916    }
917}
918
919/// Prepared statement status counters.
920///
921/// See `https://www.sqlite.org/c3ref/c_stmtstatus_counter.html`
922/// for explanations of each.
923///
924/// Note that depending on your version of SQLite, all of these
925/// may not be available.
926#[repr(i32)]
927#[derive(Clone, Copy, PartialEq, Eq)]
928#[non_exhaustive]
929pub enum StatementStatus {
930    /// Equivalent to SQLITE_STMTSTATUS_FULLSCAN_STEP
931    FullscanStep = 1,
932    /// Equivalent to SQLITE_STMTSTATUS_SORT
933    Sort = 2,
934    /// Equivalent to SQLITE_STMTSTATUS_AUTOINDEX
935    AutoIndex = 3,
936    /// Equivalent to SQLITE_STMTSTATUS_VM_STEP
937    VmStep = 4,
938    /// Equivalent to SQLITE_STMTSTATUS_REPREPARE
939    RePrepare = 5,
940    /// Equivalent to SQLITE_STMTSTATUS_RUN
941    Run = 6,
942    /// Equivalent to SQLITE_STMTSTATUS_MEMUSED
943    MemUsed = 99,
944}
945
946#[cfg(test)]
947mod test {
948    use crate::types::ToSql;
949    use crate::{params_from_iter, Connection, Error, Result};
950
951    #[test]
952    #[allow(deprecated)]
953    fn test_execute_named() -> Result<()> {
954        let db = Connection::open_in_memory()?;
955        db.execute_batch("CREATE TABLE foo(x INTEGER)")?;
956
957        assert_eq!(
958            db.execute_named("INSERT INTO foo(x) VALUES (:x)", &[(":x", &1i32)])?,
959            1
960        );
961        assert_eq!(
962            db.execute("INSERT INTO foo(x) VALUES (:x)", &[(":x", &2i32)])?,
963            1
964        );
965        assert_eq!(
966            db.execute(
967                "INSERT INTO foo(x) VALUES (:x)",
968                crate::named_params! {":x": 3i32}
969            )?,
970            1
971        );
972
973        assert_eq!(
974            6i32,
975            db.query_row_named::<i32, _>(
976                "SELECT SUM(x) FROM foo WHERE x > :x",
977                &[(":x", &0i32)],
978                |r| r.get(0)
979            )?
980        );
981        assert_eq!(
982            5i32,
983            db.query_row::<i32, _, _>(
984                "SELECT SUM(x) FROM foo WHERE x > :x",
985                &[(":x", &1i32)],
986                |r| r.get(0)
987            )?
988        );
989        Ok(())
990    }
991
992    #[test]
993    #[allow(deprecated)]
994    fn test_stmt_execute_named() -> Result<()> {
995        let db = Connection::open_in_memory()?;
996        let sql = "CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag \
997                   INTEGER)";
998        db.execute_batch(sql)?;
999
1000        let mut stmt = db.prepare("INSERT INTO test (name) VALUES (:name)")?;
1001        stmt.execute_named(&[(":name", &"one")])?;
1002
1003        let mut stmt = db.prepare("SELECT COUNT(*) FROM test WHERE name = :name")?;
1004        assert_eq!(
1005            1i32,
1006            stmt.query_row_named::<i32, _>(&[(":name", &"one")], |r| r.get(0))?
1007        );
1008        assert_eq!(
1009            1i32,
1010            stmt.query_row::<i32, _, _>(&[(":name", &"one")], |r| r.get(0))?
1011        );
1012        Ok(())
1013    }
1014
1015    #[test]
1016    #[allow(deprecated)]
1017    fn test_query_named() -> Result<()> {
1018        let db = Connection::open_in_memory()?;
1019        let sql = r#"
1020        CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag INTEGER);
1021        INSERT INTO test(id, name) VALUES (1, "one");
1022        "#;
1023        db.execute_batch(sql)?;
1024
1025        let mut stmt = db.prepare("SELECT id FROM test where name = :name")?;
1026        // legacy `_named` api
1027        {
1028            let mut rows = stmt.query_named(&[(":name", &"one")])?;
1029            let id: Result<i32> = rows.next()?.unwrap().get(0);
1030            assert_eq!(Ok(1), id);
1031        }
1032
1033        // plain api
1034        {
1035            let mut rows = stmt.query(&[(":name", &"one")])?;
1036            let id: Result<i32> = rows.next()?.unwrap().get(0);
1037            assert_eq!(Ok(1), id);
1038        }
1039        Ok(())
1040    }
1041
1042    #[test]
1043    #[allow(deprecated)]
1044    fn test_query_map_named() -> Result<()> {
1045        let db = Connection::open_in_memory()?;
1046        let sql = r#"
1047        CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag INTEGER);
1048        INSERT INTO test(id, name) VALUES (1, "one");
1049        "#;
1050        db.execute_batch(sql)?;
1051
1052        let mut stmt = db.prepare("SELECT id FROM test where name = :name")?;
1053        // legacy `_named` api
1054        {
1055            let mut rows = stmt.query_map_named(&[(":name", &"one")], |row| {
1056                let id: Result<i32> = row.get(0);
1057                id.map(|i| 2 * i)
1058            })?;
1059
1060            let doubled_id: i32 = rows.next().unwrap()?;
1061            assert_eq!(2, doubled_id);
1062        }
1063        // plain api
1064        {
1065            let mut rows = stmt.query_map(&[(":name", &"one")], |row| {
1066                let id: Result<i32> = row.get(0);
1067                id.map(|i| 2 * i)
1068            })?;
1069
1070            let doubled_id: i32 = rows.next().unwrap()?;
1071            assert_eq!(2, doubled_id);
1072        }
1073        Ok(())
1074    }
1075
1076    #[test]
1077    #[allow(deprecated)]
1078    fn test_query_and_then_named() -> Result<()> {
1079        let db = Connection::open_in_memory()?;
1080        let sql = r#"
1081        CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag INTEGER);
1082        INSERT INTO test(id, name) VALUES (1, "one");
1083        INSERT INTO test(id, name) VALUES (2, "one");
1084        "#;
1085        db.execute_batch(sql)?;
1086
1087        let mut stmt = db.prepare("SELECT id FROM test where name = :name ORDER BY id ASC")?;
1088        let mut rows = stmt.query_and_then_named(&[(":name", &"one")], |row| {
1089            let id: i32 = row.get(0)?;
1090            if id == 1 {
1091                Ok(id)
1092            } else {
1093                Err(Error::SqliteSingleThreadedMode)
1094            }
1095        })?;
1096
1097        // first row should be Ok
1098        let doubled_id: i32 = rows.next().unwrap()?;
1099        assert_eq!(1, doubled_id);
1100
1101        // second row should be Err
1102        #[allow(clippy::match_wild_err_arm)]
1103        match rows.next().unwrap() {
1104            Ok(_) => panic!("invalid Ok"),
1105            Err(Error::SqliteSingleThreadedMode) => (),
1106            Err(_) => panic!("invalid Err"),
1107        }
1108        Ok(())
1109    }
1110
1111    #[test]
1112    fn test_query_and_then_by_name() -> Result<()> {
1113        let db = Connection::open_in_memory()?;
1114        let sql = r#"
1115        CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag INTEGER);
1116        INSERT INTO test(id, name) VALUES (1, "one");
1117        INSERT INTO test(id, name) VALUES (2, "one");
1118        "#;
1119        db.execute_batch(sql)?;
1120
1121        let mut stmt = db.prepare("SELECT id FROM test where name = :name ORDER BY id ASC")?;
1122        let mut rows = stmt.query_and_then(&[(":name", &"one")], |row| {
1123            let id: i32 = row.get(0)?;
1124            if id == 1 {
1125                Ok(id)
1126            } else {
1127                Err(Error::SqliteSingleThreadedMode)
1128            }
1129        })?;
1130
1131        // first row should be Ok
1132        let doubled_id: i32 = rows.next().unwrap()?;
1133        assert_eq!(1, doubled_id);
1134
1135        // second row should be Err
1136        #[allow(clippy::match_wild_err_arm)]
1137        match rows.next().unwrap() {
1138            Ok(_) => panic!("invalid Ok"),
1139            Err(Error::SqliteSingleThreadedMode) => (),
1140            Err(_) => panic!("invalid Err"),
1141        }
1142        Ok(())
1143    }
1144
1145    #[test]
1146    #[allow(deprecated)]
1147    fn test_unbound_parameters_are_null() -> Result<()> {
1148        let db = Connection::open_in_memory()?;
1149        let sql = "CREATE TABLE test (x TEXT, y TEXT)";
1150        db.execute_batch(sql)?;
1151
1152        let mut stmt = db.prepare("INSERT INTO test (x, y) VALUES (:x, :y)")?;
1153        stmt.execute_named(&[(":x", &"one")])?;
1154
1155        let result: Option<String> =
1156            db.query_row("SELECT y FROM test WHERE x = 'one'", [], |row| row.get(0))?;
1157        assert!(result.is_none());
1158        Ok(())
1159    }
1160
1161    #[test]
1162    fn test_raw_binding() -> Result<()> {
1163        let db = Connection::open_in_memory()?;
1164        db.execute_batch("CREATE TABLE test (name TEXT, value INTEGER)")?;
1165        {
1166            let mut stmt = db.prepare("INSERT INTO test (name, value) VALUES (:name, ?3)")?;
1167
1168            let name_idx = stmt.parameter_index(":name")?.unwrap();
1169            stmt.raw_bind_parameter(name_idx, "example")?;
1170            stmt.raw_bind_parameter(3, 50i32)?;
1171            let n = stmt.raw_execute()?;
1172            assert_eq!(n, 1);
1173        }
1174
1175        {
1176            let mut stmt = db.prepare("SELECT name, value FROM test WHERE value = ?2")?;
1177            stmt.raw_bind_parameter(2, 50)?;
1178            let mut rows = stmt.raw_query();
1179            {
1180                let row = rows.next()?.unwrap();
1181                let name: String = row.get(0)?;
1182                assert_eq!(name, "example");
1183                let value: i32 = row.get(1)?;
1184                assert_eq!(value, 50);
1185            }
1186            assert!(rows.next()?.is_none());
1187        }
1188
1189        Ok(())
1190    }
1191
1192    #[test]
1193    fn test_unbound_parameters_are_reused() -> Result<()> {
1194        let db = Connection::open_in_memory()?;
1195        let sql = "CREATE TABLE test (x TEXT, y TEXT)";
1196        db.execute_batch(sql)?;
1197
1198        let mut stmt = db.prepare("INSERT INTO test (x, y) VALUES (:x, :y)")?;
1199        stmt.execute(&[(":x", &"one")])?;
1200        stmt.execute(&[(":y", &"two")])?;
1201
1202        let result: String =
1203            db.query_row("SELECT x FROM test WHERE y = 'two'", [], |row| row.get(0))?;
1204        assert_eq!(result, "one");
1205        Ok(())
1206    }
1207
1208    #[test]
1209    fn test_insert() -> Result<()> {
1210        let db = Connection::open_in_memory()?;
1211        db.execute_batch("CREATE TABLE foo(x INTEGER UNIQUE)")?;
1212        let mut stmt = db.prepare("INSERT OR IGNORE INTO foo (x) VALUES (?)")?;
1213        assert_eq!(stmt.insert(&[&1i32])?, 1);
1214        assert_eq!(stmt.insert(&[&2i32])?, 2);
1215        match stmt.insert(&[&1i32]).unwrap_err() {
1216            Error::StatementChangedRows(0) => (),
1217            err => panic!("Unexpected error {}", err),
1218        }
1219        let mut multi = db.prepare("INSERT INTO foo (x) SELECT 3 UNION ALL SELECT 4")?;
1220        match multi.insert([]).unwrap_err() {
1221            Error::StatementChangedRows(2) => (),
1222            err => panic!("Unexpected error {}", err),
1223        }
1224        Ok(())
1225    }
1226
1227    #[test]
1228    fn test_insert_different_tables() -> Result<()> {
1229        // Test for https://github.com/rusqlite/rusqlite/issues/171
1230        let db = Connection::open_in_memory()?;
1231        db.execute_batch(
1232            r"
1233            CREATE TABLE foo(x INTEGER);
1234            CREATE TABLE bar(x INTEGER);
1235        ",
1236        )?;
1237
1238        assert_eq!(db.prepare("INSERT INTO foo VALUES (10)")?.insert([])?, 1);
1239        assert_eq!(db.prepare("INSERT INTO bar VALUES (10)")?.insert([])?, 1);
1240        Ok(())
1241    }
1242
1243    #[test]
1244    fn test_exists() -> Result<()> {
1245        let db = Connection::open_in_memory()?;
1246        let sql = "BEGIN;
1247                   CREATE TABLE foo(x INTEGER);
1248                   INSERT INTO foo VALUES(1);
1249                   INSERT INTO foo VALUES(2);
1250                   END;";
1251        db.execute_batch(sql)?;
1252        let mut stmt = db.prepare("SELECT 1 FROM foo WHERE x = ?")?;
1253        assert!(stmt.exists([1i32])?);
1254        assert!(stmt.exists(&[&2i32])?);
1255        assert!(!stmt.exists([&0i32])?);
1256        Ok(())
1257    }
1258
1259    #[test]
1260    fn test_query_row() -> Result<()> {
1261        let db = Connection::open_in_memory()?;
1262        let sql = "BEGIN;
1263                   CREATE TABLE foo(x INTEGER, y INTEGER);
1264                   INSERT INTO foo VALUES(1, 3);
1265                   INSERT INTO foo VALUES(2, 4);
1266                   END;";
1267        db.execute_batch(sql)?;
1268        let mut stmt = db.prepare("SELECT y FROM foo WHERE x = ?")?;
1269        let y: Result<i64> = stmt.query_row([1i32], |r| r.get(0));
1270        assert_eq!(3i64, y?);
1271        Ok(())
1272    }
1273
1274    #[test]
1275    fn test_query_by_column_name() -> Result<()> {
1276        let db = Connection::open_in_memory()?;
1277        let sql = "BEGIN;
1278                   CREATE TABLE foo(x INTEGER, y INTEGER);
1279                   INSERT INTO foo VALUES(1, 3);
1280                   END;";
1281        db.execute_batch(sql)?;
1282        let mut stmt = db.prepare("SELECT y FROM foo")?;
1283        let y: Result<i64> = stmt.query_row([], |r| r.get("y"));
1284        assert_eq!(3i64, y?);
1285        Ok(())
1286    }
1287
1288    #[test]
1289    fn test_query_by_column_name_ignore_case() -> Result<()> {
1290        let db = Connection::open_in_memory()?;
1291        let sql = "BEGIN;
1292                   CREATE TABLE foo(x INTEGER, y INTEGER);
1293                   INSERT INTO foo VALUES(1, 3);
1294                   END;";
1295        db.execute_batch(sql)?;
1296        let mut stmt = db.prepare("SELECT y as Y FROM foo")?;
1297        let y: Result<i64> = stmt.query_row([], |r| r.get("y"));
1298        assert_eq!(3i64, y?);
1299        Ok(())
1300    }
1301
1302    #[test]
1303    #[cfg(feature = "modern_sqlite")]
1304    fn test_expanded_sql() -> Result<()> {
1305        let db = Connection::open_in_memory()?;
1306        let stmt = db.prepare("SELECT ?")?;
1307        stmt.bind_parameter(&1, 1)?;
1308        assert_eq!(Some("SELECT 1".to_owned()), stmt.expanded_sql());
1309        Ok(())
1310    }
1311
1312    #[test]
1313    fn test_bind_parameters() -> Result<()> {
1314        let db = Connection::open_in_memory()?;
1315        // dynamic slice:
1316        db.query_row(
1317            "SELECT ?1, ?2, ?3",
1318            &[&1u8 as &dyn ToSql, &"one", &Some("one")],
1319            |row| row.get::<_, u8>(0),
1320        )?;
1321        // existing collection:
1322        let data = vec![1, 2, 3];
1323        db.query_row("SELECT ?1, ?2, ?3", params_from_iter(&data), |row| {
1324            row.get::<_, u8>(0)
1325        })?;
1326        db.query_row(
1327            "SELECT ?1, ?2, ?3",
1328            params_from_iter(data.as_slice()),
1329            |row| row.get::<_, u8>(0),
1330        )?;
1331        db.query_row("SELECT ?1, ?2, ?3", params_from_iter(data), |row| {
1332            row.get::<_, u8>(0)
1333        })?;
1334
1335        use std::collections::BTreeSet;
1336        let data: BTreeSet<String> = ["one", "two", "three"]
1337            .iter()
1338            .map(|s| (*s).to_string())
1339            .collect();
1340        db.query_row("SELECT ?1, ?2, ?3", params_from_iter(&data), |row| {
1341            row.get::<_, String>(0)
1342        })?;
1343
1344        let data = [0; 3];
1345        db.query_row("SELECT ?1, ?2, ?3", params_from_iter(&data), |row| {
1346            row.get::<_, u8>(0)
1347        })?;
1348        db.query_row("SELECT ?1, ?2, ?3", params_from_iter(data.iter()), |row| {
1349            row.get::<_, u8>(0)
1350        })?;
1351        Ok(())
1352    }
1353
1354    #[test]
1355    fn test_empty_stmt() -> Result<()> {
1356        let conn = Connection::open_in_memory()?;
1357        let mut stmt = conn.prepare("")?;
1358        assert_eq!(0, stmt.column_count());
1359        assert!(stmt.parameter_index("test").is_ok());
1360        assert!(stmt.step().is_err());
1361        stmt.reset();
1362        assert!(stmt.execute([]).is_err());
1363        Ok(())
1364    }
1365
1366    #[test]
1367    fn test_comment_stmt() -> Result<()> {
1368        let conn = Connection::open_in_memory()?;
1369        conn.prepare("/*SELECT 1;*/")?;
1370        Ok(())
1371    }
1372
1373    #[test]
1374    fn test_comment_and_sql_stmt() -> Result<()> {
1375        let conn = Connection::open_in_memory()?;
1376        let stmt = conn.prepare("/*...*/ SELECT 1;")?;
1377        assert_eq!(1, stmt.column_count());
1378        Ok(())
1379    }
1380
1381    #[test]
1382    fn test_semi_colon_stmt() -> Result<()> {
1383        let conn = Connection::open_in_memory()?;
1384        let stmt = conn.prepare(";")?;
1385        assert_eq!(0, stmt.column_count());
1386        Ok(())
1387    }
1388
1389    #[test]
1390    fn test_utf16_conversion() -> Result<()> {
1391        let db = Connection::open_in_memory()?;
1392        db.pragma_update(None, "encoding", &"UTF-16le")?;
1393        let encoding: String = db.pragma_query_value(None, "encoding", |row| row.get(0))?;
1394        assert_eq!("UTF-16le", encoding);
1395        db.execute_batch("CREATE TABLE foo(x TEXT)")?;
1396        let expected = "ใƒ†ใ‚นใƒˆ";
1397        db.execute("INSERT INTO foo(x) VALUES (?)", &[&expected])?;
1398        let actual: String = db.query_row("SELECT x FROM foo", [], |row| row.get(0))?;
1399        assert_eq!(expected, actual);
1400        Ok(())
1401    }
1402
1403    #[test]
1404    fn test_nul_byte() -> Result<()> {
1405        let db = Connection::open_in_memory()?;
1406        let expected = "a\x00b";
1407        let actual: String = db.query_row("SELECT ?", [expected], |row| row.get(0))?;
1408        assert_eq!(expected, actual);
1409        Ok(())
1410    }
1411}