• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::iter::IntoIterator;
2 use std::os::raw::{c_int, c_void};
3 #[cfg(feature = "array")]
4 use std::rc::Rc;
5 use std::slice::from_raw_parts;
6 use std::{convert, fmt, mem, ptr, str};
7 
8 use super::ffi;
9 use super::{len_as_c_int, str_for_sqlite};
10 use super::{
11     AndThenRows, Connection, Error, MappedRows, Params, RawStatement, Result, Row, Rows, ValueRef,
12 };
13 use crate::types::{ToSql, ToSqlOutput};
14 #[cfg(feature = "array")]
15 use crate::vtab::array::{free_array, ARRAY_TYPE};
16 
17 /// A prepared statement.
18 pub struct Statement<'conn> {
19     conn: &'conn Connection,
20     pub(crate) stmt: RawStatement,
21 }
22 
23 impl 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]
execute<P: Params>(&mut self, params: P) -> Result<usize>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]
execute_named(&mut self, params: &[(&str, &dyn ToSql)]) -> Result<usize>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
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]
insert<P: Params>(&mut self, params: P) -> Result<i64>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 = ?")?;
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 [`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 = ?")?;
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]
query<P: Params>(&mut self, params: P) -> Result<Rows<'_>>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     /// 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."]
query_named(&mut self, params: &[(&str, &dyn ToSql)]) -> Result<Rows<'_>>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 transform 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.
query_map<T, P, F>(&mut self, params: P, f: F) -> Result<MappedRows<'_, F>> where P: Params, F: FnMut(&Row<'_>) -> Result<T>,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 transform 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."]
query_map_named<T, F>( &mut self, params: &[(&str, &dyn ToSql)], f: F, ) -> Result<MappedRows<'_, F>> where F: FnMut(&Row<'_>) -> Result<T>,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 })
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 = stmt.query_and_then(&[(":id", "one")], |row| name_to_person(row.get(0)?))?;
355     ///
356     ///     let mut persons = Vec::new();
357     ///     for person_result in rows {
358     ///         persons.push(person_result?);
359     ///     }
360     ///
361     ///     Ok(persons)
362     /// }
363     /// ```
364     ///
365     /// ### Use with positional params
366     ///
367     /// ```rust,no_run
368     /// # use rusqlite::{Connection, Result};
369     /// fn get_names(conn: &Connection) -> Result<Vec<String>> {
370     ///     let mut stmt = conn.prepare("SELECT name FROM people WHERE id = ?")?;
371     ///     let rows = stmt.query_and_then(["one"], |row| row.get::<_, String>(0))?;
372     ///
373     ///     let mut persons = Vec::new();
374     ///     for person_result in rows {
375     ///         persons.push(person_result?);
376     ///     }
377     ///
378     ///     Ok(persons)
379     /// }
380     /// ```
381     ///
382     /// # Failure
383     ///
384     /// Will return `Err` if binding parameters fails.
385     #[inline]
query_and_then<T, E, P, F>(&mut self, params: P, f: F) -> Result<AndThenRows<'_, F>> where P: Params, E: convert::From<Error>, F: FnMut(&Row<'_>) -> Result<T, E>,386     pub fn query_and_then<T, E, P, F>(&mut self, params: P, f: F) -> Result<AndThenRows<'_, F>>
387     where
388         P: Params,
389         E: convert::From<Error>,
390         F: FnMut(&Row<'_>) -> Result<T, E>,
391     {
392         self.query(params).map(|rows| rows.and_then(f))
393     }
394 
395     /// Execute the prepared statement with named parameter(s), returning an
396     /// iterator over the result of calling the mapping function over the
397     /// query's rows.
398     ///
399     /// Note: This function is deprecated in favor of
400     /// [`Statement::query_and_then`], which can now take named parameters
401     /// 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."]
query_and_then_named<T, E, F>( &mut self, params: &[(&str, &dyn ToSql)], f: F, ) -> Result<AndThenRows<'_, F>> where E: convert::From<Error>, F: FnMut(&Row<'_>) -> Result<T, E>,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]
exists<P: Params>(&mut self, params: P) -> Result<bool>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
441     /// [`.optional()`](crate::OptionalExtension::optional) on the result of
442     /// this to get a `Result<Option<T>>` (requires that the trait
443     /// `rusqlite::OptionalExtension` is imported).
444     ///
445     /// # Failure
446     ///
447     /// Will return `Err` if the underlying SQLite call fails.
query_row<T, P, F>(&mut self, params: P, f: F) -> Result<T> where P: Params, F: FnOnce(&Row<'_>) -> Result<T>,448     pub fn query_row<T, P, F>(&mut self, params: P, f: F) -> Result<T>
449     where
450         P: Params,
451         F: FnOnce(&Row<'_>) -> Result<T>,
452     {
453         let mut rows = self.query(params)?;
454 
455         rows.get_expected_row().and_then(f)
456     }
457 
458     /// Convenience method to execute a query with named parameter(s) that is
459     /// expected to return a single row.
460     ///
461     /// Note: This function is deprecated in favor of
462     /// [`Statement::query_and_then`], which can now take named parameters
463     /// directly.
464     ///
465     /// If the query returns more than one row, all rows except the first are
466     /// ignored.
467     ///
468     /// Returns `Err(QueryReturnedNoRows)` if no results are returned. If the
469     /// query truly is optional, you can call
470     /// [`.optional()`](crate::OptionalExtension::optional) on the result of
471     /// this to get a `Result<Option<T>>` (requires that the trait
472     /// `rusqlite::OptionalExtension` is imported).
473     ///
474     /// # Failure
475     ///
476     /// Will return `Err` if `sql` cannot be converted to a C-compatible string
477     /// or if the underlying SQLite call fails.
478     #[deprecated = "You can use `query_row` with named params now."]
query_row_named<T, F>(&mut self, params: &[(&str, &dyn ToSql)], f: F) -> Result<T> where F: FnOnce(&Row<'_>) -> Result<T>,479     pub fn query_row_named<T, F>(&mut self, params: &[(&str, &dyn ToSql)], f: F) -> Result<T>
480     where
481         F: FnOnce(&Row<'_>) -> Result<T>,
482     {
483         self.query_row(params, f)
484     }
485 
486     /// Consumes the statement.
487     ///
488     /// Functionally equivalent to the `Drop` implementation, but allows
489     /// callers to see any errors that occur.
490     ///
491     /// # Failure
492     ///
493     /// Will return `Err` if the underlying SQLite call fails.
494     #[inline]
finalize(mut self) -> Result<()>495     pub fn finalize(mut self) -> Result<()> {
496         self.finalize_()
497     }
498 
499     /// Return the (one-based) index of an SQL parameter given its name.
500     ///
501     /// Note that the initial ":" or "$" or "@" or "?" used to specify the
502     /// parameter is included as part of the name.
503     ///
504     /// ```rust,no_run
505     /// # use rusqlite::{Connection, Result};
506     /// fn example(conn: &Connection) -> Result<()> {
507     ///     let stmt = conn.prepare("SELECT * FROM test WHERE name = :example")?;
508     ///     let index = stmt.parameter_index(":example")?;
509     ///     assert_eq!(index, Some(1));
510     ///     Ok(())
511     /// }
512     /// ```
513     ///
514     /// # Failure
515     ///
516     /// Will return Err if `name` is invalid. Will return Ok(None) if the name
517     /// is valid but not a bound parameter of this statement.
518     #[inline]
parameter_index(&self, name: &str) -> Result<Option<usize>>519     pub fn parameter_index(&self, name: &str) -> Result<Option<usize>> {
520         Ok(self.stmt.bind_parameter_index(name))
521     }
522 
523     /// Return the SQL parameter name given its (one-based) index (the inverse
524     /// of [`Statement::parameter_index`]).
525     ///
526     /// ```rust,no_run
527     /// # use rusqlite::{Connection, Result};
528     /// fn example(conn: &Connection) -> Result<()> {
529     ///     let stmt = conn.prepare("SELECT * FROM test WHERE name = :example")?;
530     ///     let index = stmt.parameter_name(1);
531     ///     assert_eq!(index, Some(":example"));
532     ///     Ok(())
533     /// }
534     /// ```
535     ///
536     /// # Failure
537     ///
538     /// Will return `None` if the column index is out of bounds or if the
539     /// parameter is positional.
540     #[inline]
parameter_name(&self, index: usize) -> Option<&'_ str>541     pub fn parameter_name(&self, index: usize) -> Option<&'_ str> {
542         self.stmt.bind_parameter_name(index as i32).map(|name| {
543             str::from_utf8(name.to_bytes()).expect("Invalid UTF-8 sequence in parameter name")
544         })
545     }
546 
547     #[inline]
bind_parameters<P>(&mut self, params: P) -> Result<()> where P: IntoIterator, P::Item: ToSql,548     pub(crate) fn bind_parameters<P>(&mut self, params: P) -> Result<()>
549     where
550         P: IntoIterator,
551         P::Item: ToSql,
552     {
553         let expected = self.stmt.bind_parameter_count();
554         let mut index = 0;
555         for p in params.into_iter() {
556             index += 1; // The leftmost SQL parameter has an index of 1.
557             if index > expected {
558                 break;
559             }
560             self.bind_parameter(&p, index)?;
561         }
562         if index != expected {
563             Err(Error::InvalidParameterCount(index, expected))
564         } else {
565             Ok(())
566         }
567     }
568 
569     #[inline]
bind_parameters_named<T: ?Sized + ToSql>( &mut self, params: &[(&str, &T)], ) -> Result<()>570     pub(crate) fn bind_parameters_named<T: ?Sized + ToSql>(
571         &mut self,
572         params: &[(&str, &T)],
573     ) -> Result<()> {
574         for &(name, value) in params {
575             if let Some(i) = self.parameter_index(name)? {
576                 let ts: &dyn ToSql = &value;
577                 self.bind_parameter(ts, i)?;
578             } else {
579                 return Err(Error::InvalidParameterName(name.into()));
580             }
581         }
582         Ok(())
583     }
584 
585     /// Return the number of parameters that can be bound to this statement.
586     #[inline]
parameter_count(&self) -> usize587     pub fn parameter_count(&self) -> usize {
588         self.stmt.bind_parameter_count()
589     }
590 
591     /// Low level API to directly bind a parameter to a given index.
592     ///
593     /// Note that the index is one-based, that is, the first parameter index is
594     /// 1 and not 0. This is consistent with the SQLite API and the values given
595     /// to parameters bound as `?NNN`.
596     ///
597     /// The valid values for `one_based_col_index` begin at `1`, and end at
598     /// [`Statement::parameter_count`], inclusive.
599     ///
600     /// # Caveats
601     ///
602     /// This should not generally be used, but is available for special cases
603     /// such as:
604     ///
605     /// - binding parameters where a gap exists.
606     /// - binding named and positional parameters in the same query.
607     /// - separating parameter binding from query execution.
608     ///
609     /// Statements that have had their parameters bound this way should be
610     /// queried or executed by [`Statement::raw_query`] or
611     /// [`Statement::raw_execute`]. Other functions are not guaranteed to work.
612     ///
613     /// # Example
614     ///
615     /// ```rust,no_run
616     /// # use rusqlite::{Connection, Result};
617     /// fn query(conn: &Connection) -> Result<()> {
618     ///     let mut stmt = conn.prepare("SELECT * FROM test WHERE name = :name AND value > ?2")?;
619     ///     let name_index = stmt.parameter_index(":name")?.expect("No such parameter");
620     ///     stmt.raw_bind_parameter(name_index, "foo")?;
621     ///     stmt.raw_bind_parameter(2, 100)?;
622     ///     let mut rows = stmt.raw_query();
623     ///     while let Some(row) = rows.next()? {
624     ///         // ...
625     ///     }
626     ///     Ok(())
627     /// }
628     /// ```
629     #[inline]
raw_bind_parameter<T: ToSql>( &mut self, one_based_col_index: usize, param: T, ) -> Result<()>630     pub fn raw_bind_parameter<T: ToSql>(
631         &mut self,
632         one_based_col_index: usize,
633         param: T,
634     ) -> Result<()> {
635         // This is the same as `bind_parameter` but slightly more ergonomic and
636         // correctly takes `&mut self`.
637         self.bind_parameter(&param, one_based_col_index)
638     }
639 
640     /// Low level API to execute a statement given that all parameters were
641     /// bound explicitly with the [`Statement::raw_bind_parameter`] API.
642     ///
643     /// # Caveats
644     ///
645     /// Any unbound parameters will have `NULL` as their value.
646     ///
647     /// This should not generally be used outside of special cases, and
648     /// functions in the [`Statement::execute`] family should be preferred.
649     ///
650     /// # Failure
651     ///
652     /// Will return `Err` if the executed statement returns rows (in which case
653     /// `query` should be used instead), or the underlying SQLite call fails.
654     #[inline]
raw_execute(&mut self) -> Result<usize>655     pub fn raw_execute(&mut self) -> Result<usize> {
656         self.execute_with_bound_parameters()
657     }
658 
659     /// Low level API to get `Rows` for this query given that all parameters
660     /// were bound explicitly with the [`Statement::raw_bind_parameter`] API.
661     ///
662     /// # Caveats
663     ///
664     /// Any unbound parameters will have `NULL` as their value.
665     ///
666     /// This should not generally be used outside of special cases, and
667     /// functions in the [`Statement::query`] family should be preferred.
668     ///
669     /// Note that if the SQL does not return results, [`Statement::raw_execute`]
670     /// should be used instead.
671     #[inline]
raw_query(&mut self) -> Rows<'_>672     pub fn raw_query(&mut self) -> Rows<'_> {
673         Rows::new(self)
674     }
675 
676     // generic because many of these branches can constant fold away.
bind_parameter<P: ?Sized + ToSql>(&self, param: &P, col: usize) -> Result<()>677     fn bind_parameter<P: ?Sized + ToSql>(&self, param: &P, col: usize) -> Result<()> {
678         let value = param.to_sql()?;
679 
680         let ptr = unsafe { self.stmt.ptr() };
681         let value = match value {
682             ToSqlOutput::Borrowed(v) => v,
683             ToSqlOutput::Owned(ref v) => ValueRef::from(v),
684 
685             #[cfg(feature = "blob")]
686             ToSqlOutput::ZeroBlob(len) => {
687                 return self
688                     .conn
689                     .decode_result(unsafe { ffi::sqlite3_bind_zeroblob(ptr, col as c_int, len) });
690             }
691             #[cfg(feature = "array")]
692             ToSqlOutput::Array(a) => {
693                 return self.conn.decode_result(unsafe {
694                     ffi::sqlite3_bind_pointer(
695                         ptr,
696                         col as c_int,
697                         Rc::into_raw(a) as *mut c_void,
698                         ARRAY_TYPE,
699                         Some(free_array),
700                     )
701                 });
702             }
703         };
704         self.conn.decode_result(match value {
705             ValueRef::Null => unsafe { ffi::sqlite3_bind_null(ptr, col as c_int) },
706             ValueRef::Integer(i) => unsafe { ffi::sqlite3_bind_int64(ptr, col as c_int, i) },
707             ValueRef::Real(r) => unsafe { ffi::sqlite3_bind_double(ptr, col as c_int, r) },
708             ValueRef::Text(s) => unsafe {
709                 let (c_str, len, destructor) = str_for_sqlite(s)?;
710                 ffi::sqlite3_bind_text(ptr, col as c_int, c_str, len, destructor)
711             },
712             ValueRef::Blob(b) => unsafe {
713                 let length = len_as_c_int(b.len())?;
714                 if length == 0 {
715                     ffi::sqlite3_bind_zeroblob(ptr, col as c_int, 0)
716                 } else {
717                     ffi::sqlite3_bind_blob(
718                         ptr,
719                         col as c_int,
720                         b.as_ptr().cast::<c_void>(),
721                         length,
722                         ffi::SQLITE_TRANSIENT(),
723                     )
724                 }
725             },
726         })
727     }
728 
729     #[inline]
execute_with_bound_parameters(&mut self) -> Result<usize>730     fn execute_with_bound_parameters(&mut self) -> Result<usize> {
731         self.check_update()?;
732         let r = self.stmt.step();
733         self.stmt.reset();
734         match r {
735             ffi::SQLITE_DONE => Ok(self.conn.changes()),
736             ffi::SQLITE_ROW => Err(Error::ExecuteReturnedResults),
737             _ => Err(self.conn.decode_result(r).unwrap_err()),
738         }
739     }
740 
741     #[inline]
finalize_(&mut self) -> Result<()>742     fn finalize_(&mut self) -> Result<()> {
743         let mut stmt = unsafe { RawStatement::new(ptr::null_mut(), 0) };
744         mem::swap(&mut stmt, &mut self.stmt);
745         self.conn.decode_result(stmt.finalize())
746     }
747 
748     #[cfg(all(feature = "modern_sqlite", feature = "extra_check"))]
749     #[inline]
check_update(&self) -> Result<()>750     fn check_update(&self) -> Result<()> {
751         // sqlite3_column_count works for DML but not for DDL (ie ALTER)
752         if self.column_count() > 0 && self.stmt.readonly() {
753             return Err(Error::ExecuteReturnedResults);
754         }
755         Ok(())
756     }
757 
758     #[cfg(all(not(feature = "modern_sqlite"), feature = "extra_check"))]
759     #[inline]
check_update(&self) -> Result<()>760     fn check_update(&self) -> Result<()> {
761         // sqlite3_column_count works for DML but not for DDL (ie ALTER)
762         if self.column_count() > 0 {
763             return Err(Error::ExecuteReturnedResults);
764         }
765         Ok(())
766     }
767 
768     #[cfg(not(feature = "extra_check"))]
769     #[inline]
770     #[allow(clippy::unnecessary_wraps)]
check_update(&self) -> Result<()>771     fn check_update(&self) -> Result<()> {
772         Ok(())
773     }
774 
775     /// Returns a string containing the SQL text of prepared statement with
776     /// bound parameters expanded.
777     #[cfg(feature = "modern_sqlite")]
778     #[cfg_attr(docsrs, doc(cfg(feature = "modern_sqlite")))]
expanded_sql(&self) -> Option<String>779     pub fn expanded_sql(&self) -> Option<String> {
780         self.stmt
781             .expanded_sql()
782             .map(|s| s.to_string_lossy().to_string())
783     }
784 
785     /// Get the value for one of the status counters for this statement.
786     #[inline]
get_status(&self, status: StatementStatus) -> i32787     pub fn get_status(&self, status: StatementStatus) -> i32 {
788         self.stmt.get_status(status, false)
789     }
790 
791     /// Reset the value of one of the status counters for this statement,
792     #[inline]
793     /// returning the value it had before resetting.
reset_status(&self, status: StatementStatus) -> i32794     pub fn reset_status(&self, status: StatementStatus) -> i32 {
795         self.stmt.get_status(status, true)
796     }
797 
798     #[cfg(feature = "extra_check")]
799     #[inline]
check_no_tail(&self) -> Result<()>800     pub(crate) fn check_no_tail(&self) -> Result<()> {
801         if self.stmt.has_tail() {
802             Err(Error::MultipleStatement)
803         } else {
804             Ok(())
805         }
806     }
807 
808     #[cfg(not(feature = "extra_check"))]
809     #[inline]
810     #[allow(clippy::unnecessary_wraps)]
check_no_tail(&self) -> Result<()>811     pub(crate) fn check_no_tail(&self) -> Result<()> {
812         Ok(())
813     }
814 
815     /// Safety: This is unsafe, because using `sqlite3_stmt` after the
816     /// connection has closed is illegal, but `RawStatement` does not enforce
817     /// this, as it loses our protective `'conn` lifetime bound.
818     #[inline]
into_raw(mut self) -> RawStatement819     pub(crate) unsafe fn into_raw(mut self) -> RawStatement {
820         let mut stmt = RawStatement::new(ptr::null_mut(), 0);
821         mem::swap(&mut stmt, &mut self.stmt);
822         stmt
823     }
824 }
825 
826 impl fmt::Debug for Statement<'_> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result827     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
828         let sql = if self.stmt.is_null() {
829             Ok("")
830         } else {
831             str::from_utf8(self.stmt.sql().unwrap().to_bytes())
832         };
833         f.debug_struct("Statement")
834             .field("conn", self.conn)
835             .field("stmt", &self.stmt)
836             .field("sql", &sql)
837             .finish()
838     }
839 }
840 
841 impl Drop for Statement<'_> {
842     #[allow(unused_must_use)]
843     #[inline]
drop(&mut self)844     fn drop(&mut self) {
845         self.finalize_();
846     }
847 }
848 
849 impl Statement<'_> {
850     #[inline]
new(conn: &Connection, stmt: RawStatement) -> Statement<'_>851     pub(super) fn new(conn: &Connection, stmt: RawStatement) -> Statement<'_> {
852         Statement { conn, stmt }
853     }
854 
value_ref(&self, col: usize) -> ValueRef<'_>855     pub(super) fn value_ref(&self, col: usize) -> ValueRef<'_> {
856         let raw = unsafe { self.stmt.ptr() };
857 
858         match self.stmt.column_type(col) {
859             ffi::SQLITE_NULL => ValueRef::Null,
860             ffi::SQLITE_INTEGER => {
861                 ValueRef::Integer(unsafe { ffi::sqlite3_column_int64(raw, col as c_int) })
862             }
863             ffi::SQLITE_FLOAT => {
864                 ValueRef::Real(unsafe { ffi::sqlite3_column_double(raw, col as c_int) })
865             }
866             ffi::SQLITE_TEXT => {
867                 let s = unsafe {
868                     // Quoting from "Using SQLite" book:
869                     // To avoid problems, an application should first extract the desired type using
870                     // a sqlite3_column_xxx() function, and then call the
871                     // appropriate sqlite3_column_bytes() function.
872                     let text = ffi::sqlite3_column_text(raw, col as c_int);
873                     let len = ffi::sqlite3_column_bytes(raw, col as c_int);
874                     assert!(
875                         !text.is_null(),
876                         "unexpected SQLITE_TEXT column type with NULL data"
877                     );
878                     from_raw_parts(text.cast::<u8>(), len as usize)
879                 };
880 
881                 ValueRef::Text(s)
882             }
883             ffi::SQLITE_BLOB => {
884                 let (blob, len) = unsafe {
885                     (
886                         ffi::sqlite3_column_blob(raw, col as c_int),
887                         ffi::sqlite3_column_bytes(raw, col as c_int),
888                     )
889                 };
890 
891                 assert!(
892                     len >= 0,
893                     "unexpected negative return from sqlite3_column_bytes"
894                 );
895                 if len > 0 {
896                     assert!(
897                         !blob.is_null(),
898                         "unexpected SQLITE_BLOB column type with NULL data"
899                     );
900                     ValueRef::Blob(unsafe { from_raw_parts(blob.cast::<u8>(), len as usize) })
901                 } else {
902                     // The return value from sqlite3_column_blob() for a zero-length BLOB
903                     // is a NULL pointer.
904                     ValueRef::Blob(&[])
905                 }
906             }
907             _ => unreachable!("sqlite3_column_type returned invalid value"),
908         }
909     }
910 
911     #[inline]
step(&self) -> Result<bool>912     pub(super) fn step(&self) -> Result<bool> {
913         match self.stmt.step() {
914             ffi::SQLITE_ROW => Ok(true),
915             ffi::SQLITE_DONE => Ok(false),
916             code => Err(self.conn.decode_result(code).unwrap_err()),
917         }
918     }
919 
920     #[inline]
reset(&self) -> c_int921     pub(super) fn reset(&self) -> c_int {
922         self.stmt.reset()
923     }
924 }
925 
926 /// Prepared statement status counters.
927 ///
928 /// See `https://www.sqlite.org/c3ref/c_stmtstatus_counter.html`
929 /// for explanations of each.
930 ///
931 /// Note that depending on your version of SQLite, all of these
932 /// may not be available.
933 #[repr(i32)]
934 #[derive(Clone, Copy, PartialEq, Eq)]
935 #[non_exhaustive]
936 pub enum StatementStatus {
937     /// Equivalent to SQLITE_STMTSTATUS_FULLSCAN_STEP
938     FullscanStep = 1,
939     /// Equivalent to SQLITE_STMTSTATUS_SORT
940     Sort = 2,
941     /// Equivalent to SQLITE_STMTSTATUS_AUTOINDEX
942     AutoIndex = 3,
943     /// Equivalent to SQLITE_STMTSTATUS_VM_STEP
944     VmStep = 4,
945     /// Equivalent to SQLITE_STMTSTATUS_REPREPARE
946     RePrepare = 5,
947     /// Equivalent to SQLITE_STMTSTATUS_RUN
948     Run = 6,
949     /// Equivalent to SQLITE_STMTSTATUS_FILTER_MISS
950     FilterMiss = 7,
951     /// Equivalent to SQLITE_STMTSTATUS_FILTER_HIT
952     FilterHit = 8,
953     /// Equivalent to SQLITE_STMTSTATUS_MEMUSED
954     MemUsed = 99,
955 }
956 
957 #[cfg(test)]
958 mod test {
959     use crate::types::ToSql;
960     use crate::{params_from_iter, Connection, Error, Result};
961 
962     #[test]
963     #[allow(deprecated)]
test_execute_named() -> Result<()>964     fn test_execute_named() -> Result<()> {
965         let db = Connection::open_in_memory()?;
966         db.execute_batch("CREATE TABLE foo(x INTEGER)")?;
967 
968         assert_eq!(
969             db.execute_named("INSERT INTO foo(x) VALUES (:x)", &[(":x", &1i32)])?,
970             1
971         );
972         assert_eq!(
973             db.execute("INSERT INTO foo(x) VALUES (:x)", &[(":x", &2i32)])?,
974             1
975         );
976         assert_eq!(
977             db.execute(
978                 "INSERT INTO foo(x) VALUES (:x)",
979                 crate::named_params! {":x": 3i32}
980             )?,
981             1
982         );
983 
984         assert_eq!(
985             6i32,
986             db.query_row_named::<i32, _>(
987                 "SELECT SUM(x) FROM foo WHERE x > :x",
988                 &[(":x", &0i32)],
989                 |r| r.get(0)
990             )?
991         );
992         assert_eq!(
993             5i32,
994             db.query_row::<i32, _, _>(
995                 "SELECT SUM(x) FROM foo WHERE x > :x",
996                 &[(":x", &1i32)],
997                 |r| r.get(0)
998             )?
999         );
1000         Ok(())
1001     }
1002 
1003     #[test]
1004     #[allow(deprecated)]
test_stmt_execute_named() -> Result<()>1005     fn test_stmt_execute_named() -> Result<()> {
1006         let db = Connection::open_in_memory()?;
1007         let sql = "CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag \
1008                    INTEGER)";
1009         db.execute_batch(sql)?;
1010 
1011         let mut stmt = db.prepare("INSERT INTO test (name) VALUES (:name)")?;
1012         stmt.execute_named(&[(":name", &"one")])?;
1013 
1014         let mut stmt = db.prepare("SELECT COUNT(*) FROM test WHERE name = :name")?;
1015         assert_eq!(
1016             1i32,
1017             stmt.query_row_named::<i32, _>(&[(":name", &"one")], |r| r.get(0))?
1018         );
1019         assert_eq!(
1020             1i32,
1021             stmt.query_row::<i32, _, _>(&[(":name", "one")], |r| r.get(0))?
1022         );
1023         Ok(())
1024     }
1025 
1026     #[test]
1027     #[allow(deprecated)]
test_query_named() -> Result<()>1028     fn test_query_named() -> Result<()> {
1029         let db = Connection::open_in_memory()?;
1030         let sql = r#"
1031         CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag INTEGER);
1032         INSERT INTO test(id, name) VALUES (1, "one");
1033         "#;
1034         db.execute_batch(sql)?;
1035 
1036         let mut stmt = db.prepare("SELECT id FROM test where name = :name")?;
1037         // legacy `_named` api
1038         {
1039             let mut rows = stmt.query_named(&[(":name", &"one")])?;
1040             let id: Result<i32> = rows.next()?.unwrap().get(0);
1041             assert_eq!(Ok(1), id);
1042         }
1043 
1044         // plain api
1045         {
1046             let mut rows = stmt.query(&[(":name", "one")])?;
1047             let id: Result<i32> = rows.next()?.unwrap().get(0);
1048             assert_eq!(Ok(1), id);
1049         }
1050         Ok(())
1051     }
1052 
1053     #[test]
1054     #[allow(deprecated)]
test_query_map_named() -> Result<()>1055     fn test_query_map_named() -> Result<()> {
1056         let db = Connection::open_in_memory()?;
1057         let sql = r#"
1058         CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag INTEGER);
1059         INSERT INTO test(id, name) VALUES (1, "one");
1060         "#;
1061         db.execute_batch(sql)?;
1062 
1063         let mut stmt = db.prepare("SELECT id FROM test where name = :name")?;
1064         // legacy `_named` api
1065         {
1066             let mut rows = stmt.query_map_named(&[(":name", &"one")], |row| {
1067                 let id: Result<i32> = row.get(0);
1068                 id.map(|i| 2 * i)
1069             })?;
1070 
1071             let doubled_id: i32 = rows.next().unwrap()?;
1072             assert_eq!(2, doubled_id);
1073         }
1074         // plain api
1075         {
1076             let mut rows = stmt.query_map(&[(":name", "one")], |row| {
1077                 let id: Result<i32> = row.get(0);
1078                 id.map(|i| 2 * i)
1079             })?;
1080 
1081             let doubled_id: i32 = rows.next().unwrap()?;
1082             assert_eq!(2, doubled_id);
1083         }
1084         Ok(())
1085     }
1086 
1087     #[test]
1088     #[allow(deprecated)]
test_query_and_then_named() -> Result<()>1089     fn test_query_and_then_named() -> Result<()> {
1090         let db = Connection::open_in_memory()?;
1091         let sql = r#"
1092         CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag INTEGER);
1093         INSERT INTO test(id, name) VALUES (1, "one");
1094         INSERT INTO test(id, name) VALUES (2, "one");
1095         "#;
1096         db.execute_batch(sql)?;
1097 
1098         let mut stmt = db.prepare("SELECT id FROM test where name = :name ORDER BY id ASC")?;
1099         let mut rows = stmt.query_and_then_named(&[(":name", &"one")], |row| {
1100             let id: i32 = row.get(0)?;
1101             if id == 1 {
1102                 Ok(id)
1103             } else {
1104                 Err(Error::SqliteSingleThreadedMode)
1105             }
1106         })?;
1107 
1108         // first row should be Ok
1109         let doubled_id: i32 = rows.next().unwrap()?;
1110         assert_eq!(1, doubled_id);
1111 
1112         // second row should be Err
1113         #[allow(clippy::match_wild_err_arm)]
1114         match rows.next().unwrap() {
1115             Ok(_) => panic!("invalid Ok"),
1116             Err(Error::SqliteSingleThreadedMode) => (),
1117             Err(_) => panic!("invalid Err"),
1118         }
1119         Ok(())
1120     }
1121 
1122     #[test]
test_query_and_then_by_name() -> Result<()>1123     fn test_query_and_then_by_name() -> Result<()> {
1124         let db = Connection::open_in_memory()?;
1125         let sql = r#"
1126         CREATE TABLE test (id INTEGER PRIMARY KEY NOT NULL, name TEXT NOT NULL, flag INTEGER);
1127         INSERT INTO test(id, name) VALUES (1, "one");
1128         INSERT INTO test(id, name) VALUES (2, "one");
1129         "#;
1130         db.execute_batch(sql)?;
1131 
1132         let mut stmt = db.prepare("SELECT id FROM test where name = :name ORDER BY id ASC")?;
1133         let mut rows = stmt.query_and_then(&[(":name", "one")], |row| {
1134             let id: i32 = row.get(0)?;
1135             if id == 1 {
1136                 Ok(id)
1137             } else {
1138                 Err(Error::SqliteSingleThreadedMode)
1139             }
1140         })?;
1141 
1142         // first row should be Ok
1143         let doubled_id: i32 = rows.next().unwrap()?;
1144         assert_eq!(1, doubled_id);
1145 
1146         // second row should be Err
1147         #[allow(clippy::match_wild_err_arm)]
1148         match rows.next().unwrap() {
1149             Ok(_) => panic!("invalid Ok"),
1150             Err(Error::SqliteSingleThreadedMode) => (),
1151             Err(_) => panic!("invalid Err"),
1152         }
1153         Ok(())
1154     }
1155 
1156     #[test]
1157     #[allow(deprecated)]
test_unbound_parameters_are_null() -> Result<()>1158     fn test_unbound_parameters_are_null() -> Result<()> {
1159         let db = Connection::open_in_memory()?;
1160         let sql = "CREATE TABLE test (x TEXT, y TEXT)";
1161         db.execute_batch(sql)?;
1162 
1163         let mut stmt = db.prepare("INSERT INTO test (x, y) VALUES (:x, :y)")?;
1164         stmt.execute_named(&[(":x", &"one")])?;
1165 
1166         let result: Option<String> =
1167             db.query_row("SELECT y FROM test WHERE x = 'one'", [], |row| row.get(0))?;
1168         assert!(result.is_none());
1169         Ok(())
1170     }
1171 
1172     #[test]
test_raw_binding() -> Result<()>1173     fn test_raw_binding() -> Result<()> {
1174         let db = Connection::open_in_memory()?;
1175         db.execute_batch("CREATE TABLE test (name TEXT, value INTEGER)")?;
1176         {
1177             let mut stmt = db.prepare("INSERT INTO test (name, value) VALUES (:name, ?3)")?;
1178 
1179             let name_idx = stmt.parameter_index(":name")?.unwrap();
1180             stmt.raw_bind_parameter(name_idx, "example")?;
1181             stmt.raw_bind_parameter(3, 50i32)?;
1182             let n = stmt.raw_execute()?;
1183             assert_eq!(n, 1);
1184         }
1185 
1186         {
1187             let mut stmt = db.prepare("SELECT name, value FROM test WHERE value = ?2")?;
1188             stmt.raw_bind_parameter(2, 50)?;
1189             let mut rows = stmt.raw_query();
1190             {
1191                 let row = rows.next()?.unwrap();
1192                 let name: String = row.get(0)?;
1193                 assert_eq!(name, "example");
1194                 let value: i32 = row.get(1)?;
1195                 assert_eq!(value, 50);
1196             }
1197             assert!(rows.next()?.is_none());
1198         }
1199 
1200         Ok(())
1201     }
1202 
1203     #[test]
test_unbound_parameters_are_reused() -> Result<()>1204     fn test_unbound_parameters_are_reused() -> Result<()> {
1205         let db = Connection::open_in_memory()?;
1206         let sql = "CREATE TABLE test (x TEXT, y TEXT)";
1207         db.execute_batch(sql)?;
1208 
1209         let mut stmt = db.prepare("INSERT INTO test (x, y) VALUES (:x, :y)")?;
1210         stmt.execute(&[(":x", "one")])?;
1211         stmt.execute(&[(":y", "two")])?;
1212 
1213         let result: String =
1214             db.query_row("SELECT x FROM test WHERE y = 'two'", [], |row| row.get(0))?;
1215         assert_eq!(result, "one");
1216         Ok(())
1217     }
1218 
1219     #[test]
test_insert() -> Result<()>1220     fn test_insert() -> Result<()> {
1221         let db = Connection::open_in_memory()?;
1222         db.execute_batch("CREATE TABLE foo(x INTEGER UNIQUE)")?;
1223         let mut stmt = db.prepare("INSERT OR IGNORE INTO foo (x) VALUES (?)")?;
1224         assert_eq!(stmt.insert([1i32])?, 1);
1225         assert_eq!(stmt.insert([2i32])?, 2);
1226         match stmt.insert([1i32]).unwrap_err() {
1227             Error::StatementChangedRows(0) => (),
1228             err => panic!("Unexpected error {}", err),
1229         }
1230         let mut multi = db.prepare("INSERT INTO foo (x) SELECT 3 UNION ALL SELECT 4")?;
1231         match multi.insert([]).unwrap_err() {
1232             Error::StatementChangedRows(2) => (),
1233             err => panic!("Unexpected error {}", err),
1234         }
1235         Ok(())
1236     }
1237 
1238     #[test]
test_insert_different_tables() -> Result<()>1239     fn test_insert_different_tables() -> Result<()> {
1240         // Test for https://github.com/rusqlite/rusqlite/issues/171
1241         let db = Connection::open_in_memory()?;
1242         db.execute_batch(
1243             r"
1244             CREATE TABLE foo(x INTEGER);
1245             CREATE TABLE bar(x INTEGER);
1246         ",
1247         )?;
1248 
1249         assert_eq!(db.prepare("INSERT INTO foo VALUES (10)")?.insert([])?, 1);
1250         assert_eq!(db.prepare("INSERT INTO bar VALUES (10)")?.insert([])?, 1);
1251         Ok(())
1252     }
1253 
1254     #[test]
test_exists() -> Result<()>1255     fn test_exists() -> Result<()> {
1256         let db = Connection::open_in_memory()?;
1257         let sql = "BEGIN;
1258                    CREATE TABLE foo(x INTEGER);
1259                    INSERT INTO foo VALUES(1);
1260                    INSERT INTO foo VALUES(2);
1261                    END;";
1262         db.execute_batch(sql)?;
1263         let mut stmt = db.prepare("SELECT 1 FROM foo WHERE x = ?")?;
1264         assert!(stmt.exists([1i32])?);
1265         assert!(stmt.exists([2i32])?);
1266         assert!(!stmt.exists([0i32])?);
1267         Ok(())
1268     }
1269 
1270     #[test]
test_query_row() -> Result<()>1271     fn test_query_row() -> Result<()> {
1272         let db = Connection::open_in_memory()?;
1273         let sql = "BEGIN;
1274                    CREATE TABLE foo(x INTEGER, y INTEGER);
1275                    INSERT INTO foo VALUES(1, 3);
1276                    INSERT INTO foo VALUES(2, 4);
1277                    END;";
1278         db.execute_batch(sql)?;
1279         let mut stmt = db.prepare("SELECT y FROM foo WHERE x = ?")?;
1280         let y: Result<i64> = stmt.query_row([1i32], |r| r.get(0));
1281         assert_eq!(3i64, y?);
1282         Ok(())
1283     }
1284 
1285     #[test]
test_query_by_column_name() -> Result<()>1286     fn test_query_by_column_name() -> Result<()> {
1287         let db = Connection::open_in_memory()?;
1288         let sql = "BEGIN;
1289                    CREATE TABLE foo(x INTEGER, y INTEGER);
1290                    INSERT INTO foo VALUES(1, 3);
1291                    END;";
1292         db.execute_batch(sql)?;
1293         let mut stmt = db.prepare("SELECT y FROM foo")?;
1294         let y: Result<i64> = stmt.query_row([], |r| r.get("y"));
1295         assert_eq!(3i64, y?);
1296         Ok(())
1297     }
1298 
1299     #[test]
test_query_by_column_name_ignore_case() -> Result<()>1300     fn test_query_by_column_name_ignore_case() -> Result<()> {
1301         let db = Connection::open_in_memory()?;
1302         let sql = "BEGIN;
1303                    CREATE TABLE foo(x INTEGER, y INTEGER);
1304                    INSERT INTO foo VALUES(1, 3);
1305                    END;";
1306         db.execute_batch(sql)?;
1307         let mut stmt = db.prepare("SELECT y as Y FROM foo")?;
1308         let y: Result<i64> = stmt.query_row([], |r| r.get("y"));
1309         assert_eq!(3i64, y?);
1310         Ok(())
1311     }
1312 
1313     #[test]
1314     #[cfg(feature = "modern_sqlite")]
test_expanded_sql() -> Result<()>1315     fn test_expanded_sql() -> Result<()> {
1316         let db = Connection::open_in_memory()?;
1317         let stmt = db.prepare("SELECT ?")?;
1318         stmt.bind_parameter(&1, 1)?;
1319         assert_eq!(Some("SELECT 1".to_owned()), stmt.expanded_sql());
1320         Ok(())
1321     }
1322 
1323     #[test]
test_bind_parameters() -> Result<()>1324     fn test_bind_parameters() -> Result<()> {
1325         let db = Connection::open_in_memory()?;
1326         // dynamic slice:
1327         db.query_row(
1328             "SELECT ?1, ?2, ?3",
1329             &[&1u8 as &dyn ToSql, &"one", &Some("one")],
1330             |row| row.get::<_, u8>(0),
1331         )?;
1332         // existing collection:
1333         let data = vec![1, 2, 3];
1334         db.query_row("SELECT ?1, ?2, ?3", params_from_iter(&data), |row| {
1335             row.get::<_, u8>(0)
1336         })?;
1337         db.query_row(
1338             "SELECT ?1, ?2, ?3",
1339             params_from_iter(data.as_slice()),
1340             |row| row.get::<_, u8>(0),
1341         )?;
1342         db.query_row("SELECT ?1, ?2, ?3", params_from_iter(data), |row| {
1343             row.get::<_, u8>(0)
1344         })?;
1345 
1346         use std::collections::BTreeSet;
1347         let data: BTreeSet<String> = ["one", "two", "three"]
1348             .iter()
1349             .map(|s| (*s).to_string())
1350             .collect();
1351         db.query_row("SELECT ?1, ?2, ?3", params_from_iter(&data), |row| {
1352             row.get::<_, String>(0)
1353         })?;
1354 
1355         let data = [0; 3];
1356         db.query_row("SELECT ?1, ?2, ?3", params_from_iter(&data), |row| {
1357             row.get::<_, u8>(0)
1358         })?;
1359         db.query_row("SELECT ?1, ?2, ?3", params_from_iter(data.iter()), |row| {
1360             row.get::<_, u8>(0)
1361         })?;
1362         Ok(())
1363     }
1364 
1365     #[test]
test_parameter_name() -> Result<()>1366     fn test_parameter_name() -> Result<()> {
1367         let db = Connection::open_in_memory()?;
1368         db.execute_batch("CREATE TABLE test (name TEXT, value INTEGER)")?;
1369         let stmt = db.prepare("INSERT INTO test (name, value) VALUES (:name, ?3)")?;
1370         assert_eq!(stmt.parameter_name(0), None);
1371         assert_eq!(stmt.parameter_name(1), Some(":name"));
1372         assert_eq!(stmt.parameter_name(2), None);
1373         Ok(())
1374     }
1375 
1376     #[test]
test_empty_stmt() -> Result<()>1377     fn test_empty_stmt() -> Result<()> {
1378         let conn = Connection::open_in_memory()?;
1379         let mut stmt = conn.prepare("")?;
1380         assert_eq!(0, stmt.column_count());
1381         assert!(stmt.parameter_index("test").is_ok());
1382         assert!(stmt.step().is_err());
1383         stmt.reset();
1384         assert!(stmt.execute([]).is_err());
1385         Ok(())
1386     }
1387 
1388     #[test]
test_comment_stmt() -> Result<()>1389     fn test_comment_stmt() -> Result<()> {
1390         let conn = Connection::open_in_memory()?;
1391         conn.prepare("/*SELECT 1;*/")?;
1392         Ok(())
1393     }
1394 
1395     #[test]
test_comment_and_sql_stmt() -> Result<()>1396     fn test_comment_and_sql_stmt() -> Result<()> {
1397         let conn = Connection::open_in_memory()?;
1398         let stmt = conn.prepare("/*...*/ SELECT 1;")?;
1399         assert_eq!(1, stmt.column_count());
1400         Ok(())
1401     }
1402 
1403     #[test]
test_semi_colon_stmt() -> Result<()>1404     fn test_semi_colon_stmt() -> Result<()> {
1405         let conn = Connection::open_in_memory()?;
1406         let stmt = conn.prepare(";")?;
1407         assert_eq!(0, stmt.column_count());
1408         Ok(())
1409     }
1410 
1411     #[test]
test_utf16_conversion() -> Result<()>1412     fn test_utf16_conversion() -> Result<()> {
1413         let db = Connection::open_in_memory()?;
1414         db.pragma_update(None, "encoding", &"UTF-16le")?;
1415         let encoding: String = db.pragma_query_value(None, "encoding", |row| row.get(0))?;
1416         assert_eq!("UTF-16le", encoding);
1417         db.execute_batch("CREATE TABLE foo(x TEXT)")?;
1418         let expected = "テスト";
1419         db.execute("INSERT INTO foo(x) VALUES (?)", &[&expected])?;
1420         let actual: String = db.query_row("SELECT x FROM foo", [], |row| row.get(0))?;
1421         assert_eq!(expected, actual);
1422         Ok(())
1423     }
1424 
1425     #[test]
test_nul_byte() -> Result<()>1426     fn test_nul_byte() -> Result<()> {
1427         let db = Connection::open_in_memory()?;
1428         let expected = "a\x00b";
1429         let actual: String = db.query_row("SELECT ?", [expected], |row| row.get(0))?;
1430         assert_eq!(expected, actual);
1431         Ok(())
1432     }
1433 }
1434