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