Skip to main content

rusqlite/
statement.rs

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