• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Rusqlite is an ergonomic wrapper for using SQLite from Rust. It attempts to
2 //! expose an interface similar to [rust-postgres](https://github.com/sfackler/rust-postgres).
3 //!
4 //! ```rust
5 //! use rusqlite::{params, Connection, Result};
6 //!
7 //! #[derive(Debug)]
8 //! struct Person {
9 //!     id: i32,
10 //!     name: String,
11 //!     data: Option<Vec<u8>>,
12 //! }
13 //!
14 //! fn main() -> Result<()> {
15 //!     let conn = Connection::open_in_memory()?;
16 //!
17 //!     conn.execute(
18 //!         "CREATE TABLE person (
19 //!                   id              INTEGER PRIMARY KEY,
20 //!                   name            TEXT NOT NULL,
21 //!                   data            BLOB
22 //!                   )",
23 //!         [],
24 //!     )?;
25 //!     let me = Person {
26 //!         id: 0,
27 //!         name: "Steven".to_string(),
28 //!         data: None,
29 //!     };
30 //!     conn.execute(
31 //!         "INSERT INTO person (name, data) VALUES (?1, ?2)",
32 //!         params![me.name, me.data],
33 //!     )?;
34 //!
35 //!     let mut stmt = conn.prepare("SELECT id, name, data FROM person")?;
36 //!     let person_iter = stmt.query_map([], |row| {
37 //!         Ok(Person {
38 //!             id: row.get(0)?,
39 //!             name: row.get(1)?,
40 //!             data: row.get(2)?,
41 //!         })
42 //!     })?;
43 //!
44 //!     for person in person_iter {
45 //!         println!("Found person {:?}", person.unwrap());
46 //!     }
47 //!     Ok(())
48 //! }
49 //! ```
50 #![warn(missing_docs)]
51 #![cfg_attr(docsrs, feature(doc_cfg))]
52 
53 pub use libsqlite3_sys as ffi;
54 
55 use std::cell::RefCell;
56 use std::convert;
57 use std::default::Default;
58 use std::ffi::{CStr, CString};
59 use std::fmt;
60 use std::os::raw::{c_char, c_int};
61 
62 use std::path::{Path, PathBuf};
63 use std::result;
64 use std::str;
65 use std::sync::atomic::Ordering;
66 use std::sync::{Arc, Mutex};
67 
68 use crate::cache::StatementCache;
69 use crate::inner_connection::{InnerConnection, BYPASS_SQLITE_INIT};
70 use crate::raw_statement::RawStatement;
71 use crate::types::ValueRef;
72 
73 pub use crate::cache::CachedStatement;
74 pub use crate::column::Column;
75 pub use crate::error::Error;
76 pub use crate::ffi::ErrorCode;
77 #[cfg(feature = "load_extension")]
78 pub use crate::load_extension_guard::LoadExtensionGuard;
79 pub use crate::params::{params_from_iter, Params, ParamsFromIter};
80 pub use crate::row::{AndThenRows, Map, MappedRows, Row, RowIndex, Rows};
81 pub use crate::statement::{Statement, StatementStatus};
82 pub use crate::transaction::{DropBehavior, Savepoint, Transaction, TransactionBehavior};
83 pub use crate::types::ToSql;
84 pub use crate::version::*;
85 
86 mod error;
87 
88 #[cfg(feature = "backup")]
89 #[cfg_attr(docsrs, doc(cfg(feature = "backup")))]
90 pub mod backup;
91 #[cfg(feature = "blob")]
92 #[cfg_attr(docsrs, doc(cfg(feature = "blob")))]
93 pub mod blob;
94 mod busy;
95 mod cache;
96 #[cfg(feature = "collation")]
97 #[cfg_attr(docsrs, doc(cfg(feature = "collation")))]
98 mod collation;
99 mod column;
100 pub mod config;
101 #[cfg(any(feature = "functions", feature = "vtab"))]
102 mod context;
103 #[cfg(feature = "functions")]
104 #[cfg_attr(docsrs, doc(cfg(feature = "functions")))]
105 pub mod functions;
106 #[cfg(feature = "hooks")]
107 #[cfg_attr(docsrs, doc(cfg(feature = "hooks")))]
108 pub mod hooks;
109 mod inner_connection;
110 #[cfg(feature = "limits")]
111 #[cfg_attr(docsrs, doc(cfg(feature = "limits")))]
112 pub mod limits;
113 #[cfg(feature = "load_extension")]
114 mod load_extension_guard;
115 mod params;
116 mod pragma;
117 mod raw_statement;
118 mod row;
119 #[cfg(feature = "session")]
120 #[cfg_attr(docsrs, doc(cfg(feature = "session")))]
121 pub mod session;
122 mod statement;
123 #[cfg(feature = "trace")]
124 #[cfg_attr(docsrs, doc(cfg(feature = "trace")))]
125 pub mod trace;
126 mod transaction;
127 pub mod types;
128 #[cfg(feature = "unlock_notify")]
129 mod unlock_notify;
130 mod version;
131 #[cfg(feature = "vtab")]
132 #[cfg_attr(docsrs, doc(cfg(feature = "vtab")))]
133 pub mod vtab;
134 
135 pub(crate) mod util;
136 pub(crate) use util::SmallCString;
137 
138 // Number of cached prepared statements we'll hold on to.
139 const STATEMENT_CACHE_DEFAULT_CAPACITY: usize = 16;
140 /// To be used when your statement has no [parameter][sqlite-varparam].
141 ///
142 /// [sqlite-varparam]: https://sqlite.org/lang_expr.html#varparam
143 ///
144 /// This is deprecated in favor of using an empty array literal.
145 #[deprecated = "Use an empty array instead; `stmt.execute(NO_PARAMS)` => `stmt.execute([])`"]
146 pub const NO_PARAMS: &[&dyn ToSql] = &[];
147 
148 /// A macro making it more convenient to pass heterogeneous or long lists of
149 /// parameters as a `&[&dyn ToSql]`.
150 ///
151 /// # Example
152 ///
153 /// ```rust,no_run
154 /// # use rusqlite::{Result, Connection, params};
155 ///
156 /// struct Person {
157 ///     name: String,
158 ///     age_in_years: u8,
159 ///     data: Option<Vec<u8>>,
160 /// }
161 ///
162 /// fn add_person(conn: &Connection, person: &Person) -> Result<()> {
163 ///     conn.execute(
164 ///         "INSERT INTO person (name, age_in_years, data)
165 ///                   VALUES (?1, ?2, ?3)",
166 ///         params![person.name, person.age_in_years, person.data],
167 ///     )?;
168 ///     Ok(())
169 /// }
170 /// ```
171 #[macro_export]
172 macro_rules! params {
173     () => {
174         &[] as &[&dyn $crate::ToSql]
175     };
176     ($($param:expr),+ $(,)?) => {
177         &[$(&$param as &dyn $crate::ToSql),+] as &[&dyn $crate::ToSql]
178     };
179 }
180 
181 /// A macro making it more convenient to pass lists of named parameters
182 /// as a `&[(&str, &dyn ToSql)]`.
183 ///
184 /// # Example
185 ///
186 /// ```rust,no_run
187 /// # use rusqlite::{Result, Connection, named_params};
188 ///
189 /// struct Person {
190 ///     name: String,
191 ///     age_in_years: u8,
192 ///     data: Option<Vec<u8>>,
193 /// }
194 ///
195 /// fn add_person(conn: &Connection, person: &Person) -> Result<()> {
196 ///     conn.execute(
197 ///         "INSERT INTO person (name, age_in_years, data)
198 ///          VALUES (:name, :age, :data)",
199 ///         named_params! {
200 ///             ":name": person.name,
201 ///             ":age": person.age_in_years,
202 ///             ":data": person.data,
203 ///         },
204 ///     )?;
205 ///     Ok(())
206 /// }
207 /// ```
208 #[macro_export]
209 macro_rules! named_params {
210     () => {
211         &[] as &[(&str, &dyn $crate::ToSql)]
212     };
213     // Note: It's a lot more work to support this as part of the same macro as
214     // `params!`, unfortunately.
215     ($($param_name:literal: $param_val:expr),+ $(,)?) => {
216         &[$(($param_name, &$param_val as &dyn $crate::ToSql)),+] as &[(&str, &dyn $crate::ToSql)]
217     };
218 }
219 
220 /// A typedef of the result returned by many methods.
221 pub type Result<T, E = Error> = result::Result<T, E>;
222 
223 /// See the [method documentation](#tymethod.optional).
224 pub trait OptionalExtension<T> {
225     /// Converts a `Result<T>` into a `Result<Option<T>>`.
226     ///
227     /// By default, Rusqlite treats 0 rows being returned from a query that is
228     /// expected to return 1 row as an error. This method will
229     /// handle that error, and give you back an `Option<T>` instead.
optional(self) -> Result<Option<T>>230     fn optional(self) -> Result<Option<T>>;
231 }
232 
233 impl<T> OptionalExtension<T> for Result<T> {
optional(self) -> Result<Option<T>>234     fn optional(self) -> Result<Option<T>> {
235         match self {
236             Ok(value) => Ok(Some(value)),
237             Err(Error::QueryReturnedNoRows) => Ok(None),
238             Err(e) => Err(e),
239         }
240     }
241 }
242 
errmsg_to_string(errmsg: *const c_char) -> String243 unsafe fn errmsg_to_string(errmsg: *const c_char) -> String {
244     let c_slice = CStr::from_ptr(errmsg).to_bytes();
245     String::from_utf8_lossy(c_slice).into_owned()
246 }
247 
str_to_cstring(s: &str) -> Result<SmallCString>248 fn str_to_cstring(s: &str) -> Result<SmallCString> {
249     Ok(SmallCString::new(s)?)
250 }
251 
252 /// Returns `Ok((string ptr, len as c_int, SQLITE_STATIC | SQLITE_TRANSIENT))`
253 /// normally.
254 /// Returns error if the string is too large for sqlite.
255 /// The `sqlite3_destructor_type` item is always `SQLITE_TRANSIENT` unless
256 /// the string was empty (in which case it's `SQLITE_STATIC`, and the ptr is
257 /// static).
str_for_sqlite(s: &[u8]) -> Result<(*const c_char, c_int, ffi::sqlite3_destructor_type)>258 fn str_for_sqlite(s: &[u8]) -> Result<(*const c_char, c_int, ffi::sqlite3_destructor_type)> {
259     let len = len_as_c_int(s.len())?;
260     let (ptr, dtor_info) = if len != 0 {
261         (s.as_ptr().cast::<c_char>(), ffi::SQLITE_TRANSIENT())
262     } else {
263         // Return a pointer guaranteed to live forever
264         ("".as_ptr().cast::<c_char>(), ffi::SQLITE_STATIC())
265     };
266     Ok((ptr, len, dtor_info))
267 }
268 
269 // Helper to cast to c_int safely, returning the correct error type if the cast
270 // failed.
len_as_c_int(len: usize) -> Result<c_int>271 fn len_as_c_int(len: usize) -> Result<c_int> {
272     if len >= (c_int::max_value() as usize) {
273         Err(Error::SqliteFailure(
274             ffi::Error::new(ffi::SQLITE_TOOBIG),
275             None,
276         ))
277     } else {
278         Ok(len as c_int)
279     }
280 }
281 
282 #[cfg(unix)]
path_to_cstring(p: &Path) -> Result<CString>283 fn path_to_cstring(p: &Path) -> Result<CString> {
284     use std::os::unix::ffi::OsStrExt;
285     Ok(CString::new(p.as_os_str().as_bytes())?)
286 }
287 
288 #[cfg(not(unix))]
path_to_cstring(p: &Path) -> Result<CString>289 fn path_to_cstring(p: &Path) -> Result<CString> {
290     let s = p.to_str().ok_or_else(|| Error::InvalidPath(p.to_owned()))?;
291     Ok(CString::new(s)?)
292 }
293 
294 /// Name for a database within a SQLite connection.
295 #[derive(Copy, Clone, Debug)]
296 pub enum DatabaseName<'a> {
297     /// The main database.
298     Main,
299 
300     /// The temporary database (e.g., any "CREATE TEMPORARY TABLE" tables).
301     Temp,
302 
303     /// A database that has been attached via "ATTACH DATABASE ...".
304     Attached(&'a str),
305 }
306 
307 /// Shorthand for [`DatabaseName::Main`].
308 pub const MAIN_DB: DatabaseName<'static> = DatabaseName::Main;
309 
310 /// Shorthand for [`DatabaseName::Temp`].
311 pub const TEMP_DB: DatabaseName<'static> = DatabaseName::Temp;
312 
313 // Currently DatabaseName is only used by the backup and blob mods, so hide
314 // this (private) impl to avoid dead code warnings.
315 #[cfg(any(
316     feature = "backup",
317     feature = "blob",
318     feature = "session",
319     feature = "modern_sqlite"
320 ))]
321 impl DatabaseName<'_> {
322     #[inline]
as_cstring(&self) -> Result<util::SmallCString>323     fn as_cstring(&self) -> Result<util::SmallCString> {
324         use self::DatabaseName::{Attached, Main, Temp};
325         match *self {
326             Main => str_to_cstring("main"),
327             Temp => str_to_cstring("temp"),
328             Attached(s) => str_to_cstring(s),
329         }
330     }
331 }
332 
333 /// A connection to a SQLite database.
334 pub struct Connection {
335     db: RefCell<InnerConnection>,
336     cache: StatementCache,
337     path: Option<PathBuf>,
338 }
339 
340 unsafe impl Send for Connection {}
341 
342 impl Drop for Connection {
343     #[inline]
drop(&mut self)344     fn drop(&mut self) {
345         self.flush_prepared_statement_cache();
346     }
347 }
348 
349 impl Connection {
350     /// Open a new connection to a SQLite database.
351     ///
352     /// `Connection::open(path)` is equivalent to
353     /// `Connection::open_with_flags(path,
354     /// OpenFlags::SQLITE_OPEN_READ_WRITE |
355     /// OpenFlags::SQLITE_OPEN_CREATE)`.
356     ///
357     /// ```rust,no_run
358     /// # use rusqlite::{Connection, Result};
359     /// fn open_my_db() -> Result<()> {
360     ///     let path = "./my_db.db3";
361     ///     let db = Connection::open(&path)?;
362     ///     println!("{}", db.is_autocommit());
363     ///     Ok(())
364     /// }
365     /// ```
366     ///
367     /// # Failure
368     ///
369     /// Will return `Err` if `path` cannot be converted to a C-compatible
370     /// string or if the underlying SQLite open call fails.
371     #[inline]
open<P: AsRef<Path>>(path: P) -> Result<Connection>372     pub fn open<P: AsRef<Path>>(path: P) -> Result<Connection> {
373         let flags = OpenFlags::default();
374         Connection::open_with_flags(path, flags)
375     }
376 
377     /// Open a new connection to an in-memory SQLite database.
378     ///
379     /// # Failure
380     ///
381     /// Will return `Err` if the underlying SQLite open call fails.
382     #[inline]
open_in_memory() -> Result<Connection>383     pub fn open_in_memory() -> Result<Connection> {
384         let flags = OpenFlags::default();
385         Connection::open_in_memory_with_flags(flags)
386     }
387 
388     /// Open a new connection to a SQLite database.
389     ///
390     /// [Database Connection](http://www.sqlite.org/c3ref/open.html) for a description of valid
391     /// flag combinations.
392     ///
393     /// # Failure
394     ///
395     /// Will return `Err` if `path` cannot be converted to a C-compatible
396     /// string or if the underlying SQLite open call fails.
397     #[inline]
open_with_flags<P: AsRef<Path>>(path: P, flags: OpenFlags) -> Result<Connection>398     pub fn open_with_flags<P: AsRef<Path>>(path: P, flags: OpenFlags) -> Result<Connection> {
399         let c_path = path_to_cstring(path.as_ref())?;
400         InnerConnection::open_with_flags(&c_path, flags, None).map(|db| Connection {
401             db: RefCell::new(db),
402             cache: StatementCache::with_capacity(STATEMENT_CACHE_DEFAULT_CAPACITY),
403             path: Some(path.as_ref().to_path_buf()),
404         })
405     }
406 
407     /// Open a new connection to a SQLite database using the specific flags and
408     /// vfs name.
409     ///
410     /// [Database Connection](http://www.sqlite.org/c3ref/open.html) for a description of valid
411     /// flag combinations.
412     ///
413     /// # Failure
414     ///
415     /// Will return `Err` if either `path` or `vfs` cannot be converted to a
416     /// C-compatible string or if the underlying SQLite open call fails.
417     #[inline]
open_with_flags_and_vfs<P: AsRef<Path>>( path: P, flags: OpenFlags, vfs: &str, ) -> Result<Connection>418     pub fn open_with_flags_and_vfs<P: AsRef<Path>>(
419         path: P,
420         flags: OpenFlags,
421         vfs: &str,
422     ) -> Result<Connection> {
423         let c_path = path_to_cstring(path.as_ref())?;
424         let c_vfs = str_to_cstring(vfs)?;
425         InnerConnection::open_with_flags(&c_path, flags, Some(&c_vfs)).map(|db| Connection {
426             db: RefCell::new(db),
427             cache: StatementCache::with_capacity(STATEMENT_CACHE_DEFAULT_CAPACITY),
428             path: Some(path.as_ref().to_path_buf()),
429         })
430     }
431 
432     /// Open a new connection to an in-memory SQLite database.
433     ///
434     /// [Database Connection](http://www.sqlite.org/c3ref/open.html) for a description of valid
435     /// flag combinations.
436     ///
437     /// # Failure
438     ///
439     /// Will return `Err` if the underlying SQLite open call fails.
440     #[inline]
open_in_memory_with_flags(flags: OpenFlags) -> Result<Connection>441     pub fn open_in_memory_with_flags(flags: OpenFlags) -> Result<Connection> {
442         Connection::open_with_flags(":memory:", flags)
443     }
444 
445     /// Open a new connection to an in-memory SQLite database using the specific
446     /// flags and vfs name.
447     ///
448     /// [Database Connection](http://www.sqlite.org/c3ref/open.html) for a description of valid
449     /// flag combinations.
450     ///
451     /// # Failure
452     ///
453     /// Will return `Err` if `vfs` cannot be converted to a C-compatible
454     /// string or if the underlying SQLite open call fails.
455     #[inline]
open_in_memory_with_flags_and_vfs(flags: OpenFlags, vfs: &str) -> Result<Connection>456     pub fn open_in_memory_with_flags_and_vfs(flags: OpenFlags, vfs: &str) -> Result<Connection> {
457         Connection::open_with_flags_and_vfs(":memory:", flags, vfs)
458     }
459 
460     /// Convenience method to run multiple SQL statements (that cannot take any
461     /// parameters).
462     ///
463     /// ## Example
464     ///
465     /// ```rust,no_run
466     /// # use rusqlite::{Connection, Result};
467     /// fn create_tables(conn: &Connection) -> Result<()> {
468     ///     conn.execute_batch(
469     ///         "BEGIN;
470     ///          CREATE TABLE foo(x INTEGER);
471     ///          CREATE TABLE bar(y TEXT);
472     ///          COMMIT;",
473     ///     )
474     /// }
475     /// ```
476     ///
477     /// # Failure
478     ///
479     /// Will return `Err` if `sql` cannot be converted to a C-compatible string
480     /// or if the underlying SQLite call fails.
execute_batch(&self, sql: &str) -> Result<()>481     pub fn execute_batch(&self, sql: &str) -> Result<()> {
482         let mut sql = sql;
483         while !sql.is_empty() {
484             let stmt = self.prepare(sql)?;
485             if !stmt.stmt.is_null() && stmt.step()? && cfg!(feature = "extra_check") {
486                 // Some PRAGMA may return rows
487                 return Err(Error::ExecuteReturnedResults);
488             }
489             let tail = stmt.stmt.tail();
490             if tail == 0 || tail >= sql.len() {
491                 break;
492             }
493             sql = &sql[tail..];
494         }
495         Ok(())
496     }
497 
498     /// Convenience method to prepare and execute a single SQL statement.
499     ///
500     /// On success, returns the number of rows that were changed or inserted or
501     /// deleted (via `sqlite3_changes`).
502     ///
503     /// ## Example
504     ///
505     /// ### With positional params
506     ///
507     /// ```rust,no_run
508     /// # use rusqlite::{Connection};
509     /// fn update_rows(conn: &Connection) {
510     ///     match conn.execute("UPDATE foo SET bar = 'baz' WHERE qux = ?", [1i32]) {
511     ///         Ok(updated) => println!("{} rows were updated", updated),
512     ///         Err(err) => println!("update failed: {}", err),
513     ///     }
514     /// }
515     /// ```
516     ///
517     /// ### With positional params of varying types
518     ///
519     /// ```rust,no_run
520     /// # use rusqlite::{params, Connection};
521     /// fn update_rows(conn: &Connection) {
522     ///     match conn.execute(
523     ///         "UPDATE foo SET bar = 'baz' WHERE qux = ?1 AND quux = ?2",
524     ///         params![1i32, 1.5f64],
525     ///     ) {
526     ///         Ok(updated) => println!("{} rows were updated", updated),
527     ///         Err(err) => println!("update failed: {}", err),
528     ///     }
529     /// }
530     /// ```
531     ///
532     /// ### With named params
533     ///
534     /// ```rust,no_run
535     /// # use rusqlite::{Connection, Result};
536     /// fn insert(conn: &Connection) -> Result<usize> {
537     ///     conn.execute(
538     ///         "INSERT INTO test (name) VALUES (:name)",
539     ///         &[(":name", "one")],
540     ///     )
541     /// }
542     /// ```
543     ///
544     /// # Failure
545     ///
546     /// Will return `Err` if `sql` cannot be converted to a C-compatible string
547     /// or if the underlying SQLite call fails.
548     #[inline]
execute<P: Params>(&self, sql: &str, params: P) -> Result<usize>549     pub fn execute<P: Params>(&self, sql: &str, params: P) -> Result<usize> {
550         self.prepare(sql)
551             .and_then(|mut stmt| stmt.check_no_tail().and_then(|_| stmt.execute(params)))
552     }
553 
554     /// Returns the path to the database file, if one exists and is known.
555     ///
556     /// Note that in some cases [PRAGMA
557     /// database_list](https://sqlite.org/pragma.html#pragma_database_list) is
558     /// likely to be more robust.
559     #[inline]
path(&self) -> Option<&Path>560     pub fn path(&self) -> Option<&Path> {
561         self.path.as_deref()
562     }
563 
564     /// Convenience method to prepare and execute a single SQL statement with
565     /// named parameter(s).
566     ///
567     /// On success, returns the number of rows that were changed or inserted or
568     /// deleted (via `sqlite3_changes`).
569     ///
570     /// # Failure
571     ///
572     /// Will return `Err` if `sql` cannot be converted to a C-compatible string
573     /// or if the underlying SQLite call fails.
574     #[deprecated = "You can use `execute` with named params now."]
execute_named(&self, sql: &str, params: &[(&str, &dyn ToSql)]) -> Result<usize>575     pub fn execute_named(&self, sql: &str, params: &[(&str, &dyn ToSql)]) -> Result<usize> {
576         // This function itself is deprecated, so it's fine
577         #![allow(deprecated)]
578         self.prepare(sql).and_then(|mut stmt| {
579             stmt.check_no_tail()
580                 .and_then(|_| stmt.execute_named(params))
581         })
582     }
583 
584     /// Get the SQLite rowid of the most recent successful INSERT.
585     ///
586     /// Uses [sqlite3_last_insert_rowid](https://www.sqlite.org/c3ref/last_insert_rowid.html) under
587     /// the hood.
588     #[inline]
last_insert_rowid(&self) -> i64589     pub fn last_insert_rowid(&self) -> i64 {
590         self.db.borrow_mut().last_insert_rowid()
591     }
592 
593     /// Convenience method to execute a query that is expected to return a
594     /// single row.
595     ///
596     /// ## Example
597     ///
598     /// ```rust,no_run
599     /// # use rusqlite::{Result, Connection};
600     /// fn preferred_locale(conn: &Connection) -> Result<String> {
601     ///     conn.query_row(
602     ///         "SELECT value FROM preferences WHERE name='locale'",
603     ///         [],
604     ///         |row| row.get(0),
605     ///     )
606     /// }
607     /// ```
608     ///
609     /// If the query returns more than one row, all rows except the first are
610     /// ignored.
611     ///
612     /// Returns `Err(QueryReturnedNoRows)` if no results are returned. If the
613     /// query truly is optional, you can call `.optional()` on the result of
614     /// this to get a `Result<Option<T>>`.
615     ///
616     /// # Failure
617     ///
618     /// Will return `Err` if `sql` cannot be converted to a C-compatible string
619     /// or if the underlying SQLite call fails.
620     #[inline]
query_row<T, P, F>(&self, sql: &str, params: P, f: F) -> Result<T> where P: Params, F: FnOnce(&Row<'_>) -> Result<T>,621     pub fn query_row<T, P, F>(&self, sql: &str, params: P, f: F) -> Result<T>
622     where
623         P: Params,
624         F: FnOnce(&Row<'_>) -> Result<T>,
625     {
626         let mut stmt = self.prepare(sql)?;
627         stmt.check_no_tail()?;
628         stmt.query_row(params, f)
629     }
630 
631     /// Convenience method to execute a query with named parameter(s) that is
632     /// expected to return a single row.
633     ///
634     /// If the query returns more than one row, all rows except the first are
635     /// ignored.
636     ///
637     /// Returns `Err(QueryReturnedNoRows)` if no results are returned. If the
638     /// query truly is optional, you can call `.optional()` on the result of
639     /// this to get a `Result<Option<T>>`.
640     ///
641     /// # Failure
642     ///
643     /// Will return `Err` if `sql` cannot be converted to a C-compatible string
644     /// or if the underlying SQLite call fails.
645     #[deprecated = "You can use `query_row` with named params now."]
query_row_named<T, F>(&self, sql: &str, params: &[(&str, &dyn ToSql)], f: F) -> Result<T> where F: FnOnce(&Row<'_>) -> Result<T>,646     pub fn query_row_named<T, F>(&self, sql: &str, params: &[(&str, &dyn ToSql)], f: F) -> Result<T>
647     where
648         F: FnOnce(&Row<'_>) -> Result<T>,
649     {
650         self.query_row(sql, params, f)
651     }
652 
653     /// Convenience method to execute a query that is expected to return a
654     /// single row, and execute a mapping via `f` on that returned row with
655     /// the possibility of failure. The `Result` type of `f` must implement
656     /// `std::convert::From<Error>`.
657     ///
658     /// ## Example
659     ///
660     /// ```rust,no_run
661     /// # use rusqlite::{Result, Connection};
662     /// fn preferred_locale(conn: &Connection) -> Result<String> {
663     ///     conn.query_row_and_then(
664     ///         "SELECT value FROM preferences WHERE name='locale'",
665     ///         [],
666     ///         |row| row.get(0),
667     ///     )
668     /// }
669     /// ```
670     ///
671     /// If the query returns more than one row, all rows except the first are
672     /// ignored.
673     ///
674     /// # Failure
675     ///
676     /// Will return `Err` if `sql` cannot be converted to a C-compatible string
677     /// or if the underlying SQLite call fails.
678     #[inline]
query_row_and_then<T, E, P, F>(&self, sql: &str, params: P, f: F) -> Result<T, E> where P: Params, F: FnOnce(&Row<'_>) -> Result<T, E>, E: convert::From<Error>,679     pub fn query_row_and_then<T, E, P, F>(&self, sql: &str, params: P, f: F) -> Result<T, E>
680     where
681         P: Params,
682         F: FnOnce(&Row<'_>) -> Result<T, E>,
683         E: convert::From<Error>,
684     {
685         let mut stmt = self.prepare(sql)?;
686         stmt.check_no_tail()?;
687         let mut rows = stmt.query(params)?;
688 
689         rows.get_expected_row().map_err(E::from).and_then(f)
690     }
691 
692     /// Prepare a SQL statement for execution.
693     ///
694     /// ## Example
695     ///
696     /// ```rust,no_run
697     /// # use rusqlite::{Connection, Result};
698     /// fn insert_new_people(conn: &Connection) -> Result<()> {
699     ///     let mut stmt = conn.prepare("INSERT INTO People (name) VALUES (?)")?;
700     ///     stmt.execute(["Joe Smith"])?;
701     ///     stmt.execute(["Bob Jones"])?;
702     ///     Ok(())
703     /// }
704     /// ```
705     ///
706     /// # Failure
707     ///
708     /// Will return `Err` if `sql` cannot be converted to a C-compatible string
709     /// or if the underlying SQLite call fails.
710     #[inline]
prepare(&self, sql: &str) -> Result<Statement<'_>>711     pub fn prepare(&self, sql: &str) -> Result<Statement<'_>> {
712         self.db.borrow_mut().prepare(self, sql)
713     }
714 
715     /// Close the SQLite connection.
716     ///
717     /// This is functionally equivalent to the `Drop` implementation for
718     /// `Connection` except that on failure, it returns an error and the
719     /// connection itself (presumably so closing can be attempted again).
720     ///
721     /// # Failure
722     ///
723     /// Will return `Err` if the underlying SQLite call fails.
724     #[inline]
close(self) -> Result<(), (Connection, Error)>725     pub fn close(self) -> Result<(), (Connection, Error)> {
726         self.flush_prepared_statement_cache();
727         let r = self.db.borrow_mut().close();
728         r.map_err(move |err| (self, err))
729     }
730 
731     /// Enable loading of SQLite extensions from both SQL queries and Rust.
732     ///
733     /// You must call [`Connection::load_extension_disable`] when you're
734     /// finished loading extensions (failure to call it can lead to bad things,
735     /// see "Safety"), so you should strongly consider using
736     /// [`LoadExtensionGuard`] instead of this function, automatically disables
737     /// extension loading when it goes out of scope.
738     ///
739     /// # Example
740     ///
741     /// ```rust,no_run
742     /// # use rusqlite::{Connection, Result};
743     /// fn load_my_extension(conn: &Connection) -> Result<()> {
744     ///     // Safety: We fully trust the loaded extension and execute no untrusted SQL
745     ///     // while extension loading is enabled.
746     ///     unsafe {
747     ///         conn.load_extension_enable()?;
748     ///         let r = conn.load_extension("my/trusted/extension", None);
749     ///         conn.load_extension_disable()?;
750     ///         r
751     ///     }
752     /// }
753     /// ```
754     ///
755     /// # Failure
756     ///
757     /// Will return `Err` if the underlying SQLite call fails.
758     ///
759     /// # Safety
760     ///
761     /// TLDR: Don't execute any untrusted queries between this call and
762     /// [`Connection::load_extension_disable`].
763     ///
764     /// Perhaps surprisingly, this function does not only allow the use of
765     /// [`Connection::load_extension`] from Rust, but it also allows SQL queries
766     /// to perform [the same operation][loadext]. For example, in the period
767     /// between `load_extension_enable` and `load_extension_disable`, the
768     /// following operation will load and call some function in some dynamic
769     /// library:
770     ///
771     /// ```sql
772     /// SELECT load_extension('why_is_this_possible.dll', 'dubious_func');
773     /// ```
774     ///
775     /// This means that while this is enabled a carefully crafted SQL query can
776     /// be used to escalate a SQL injection attack into code execution.
777     ///
778     /// Safely using this function requires that you trust all SQL queries run
779     /// between when it is called, and when loading is disabled (by
780     /// [`Connection::load_extension_disable`]).
781     ///
782     /// [loadext]: https://www.sqlite.org/lang_corefunc.html#load_extension
783     #[cfg(feature = "load_extension")]
784     #[cfg_attr(docsrs, doc(cfg(feature = "load_extension")))]
785     #[inline]
load_extension_enable(&self) -> Result<()>786     pub unsafe fn load_extension_enable(&self) -> Result<()> {
787         self.db.borrow_mut().enable_load_extension(1)
788     }
789 
790     /// Disable loading of SQLite extensions.
791     ///
792     /// See [`Connection::load_extension_enable`] for an example.
793     ///
794     /// # Failure
795     ///
796     /// Will return `Err` if the underlying SQLite call fails.
797     #[cfg(feature = "load_extension")]
798     #[cfg_attr(docsrs, doc(cfg(feature = "load_extension")))]
799     #[inline]
load_extension_disable(&self) -> Result<()>800     pub fn load_extension_disable(&self) -> Result<()> {
801         // It's always safe to turn off extension loading.
802         unsafe { self.db.borrow_mut().enable_load_extension(0) }
803     }
804 
805     /// Load the SQLite extension at `dylib_path`. `dylib_path` is passed
806     /// through to `sqlite3_load_extension`, which may attempt OS-specific
807     /// modifications if the file cannot be loaded directly (for example
808     /// converting `"some/ext"` to `"some/ext.so"`, `"some\\ext.dll"`, ...).
809     ///
810     /// If `entry_point` is `None`, SQLite will attempt to find the entry point.
811     /// If it is not `None`, the entry point will be passed through to
812     /// `sqlite3_load_extension`.
813     ///
814     /// ## Example
815     ///
816     /// ```rust,no_run
817     /// # use rusqlite::{Connection, Result, LoadExtensionGuard};
818     /// fn load_my_extension(conn: &Connection) -> Result<()> {
819     ///     // Safety: we don't execute any SQL statements while
820     ///     // extension loading is enabled.
821     ///     let _guard = unsafe { LoadExtensionGuard::new(conn)? };
822     ///     // Safety: `my_sqlite_extension` is highly trustworthy.
823     ///     unsafe { conn.load_extension("my_sqlite_extension", None) }
824     /// }
825     /// ```
826     ///
827     /// # Failure
828     ///
829     /// Will return `Err` if the underlying SQLite call fails.
830     ///
831     /// # Safety
832     ///
833     /// This is equivalent to performing a `dlopen`/`LoadLibrary` on a shared
834     /// library, and calling a function inside, and thus requires that you trust
835     /// the library that you're loading.
836     ///
837     /// That is to say: to safely use this, the code in the extension must be
838     /// sound, trusted, correctly use the SQLite APIs, and not contain any
839     /// memory or thread safety errors.
840     #[cfg(feature = "load_extension")]
841     #[cfg_attr(docsrs, doc(cfg(feature = "load_extension")))]
842     #[inline]
load_extension<P: AsRef<Path>>( &self, dylib_path: P, entry_point: Option<&str>, ) -> Result<()>843     pub unsafe fn load_extension<P: AsRef<Path>>(
844         &self,
845         dylib_path: P,
846         entry_point: Option<&str>,
847     ) -> Result<()> {
848         self.db
849             .borrow_mut()
850             .load_extension(dylib_path.as_ref(), entry_point)
851     }
852 
853     /// Get access to the underlying SQLite database connection handle.
854     ///
855     /// # Warning
856     ///
857     /// You should not need to use this function. If you do need to, please
858     /// [open an issue on the rusqlite repository](https://github.com/rusqlite/rusqlite/issues) and describe
859     /// your use case.
860     ///
861     /// # Safety
862     ///
863     /// This function is unsafe because it gives you raw access
864     /// to the SQLite connection, and what you do with it could impact the
865     /// safety of this `Connection`.
866     #[inline]
handle(&self) -> *mut ffi::sqlite3867     pub unsafe fn handle(&self) -> *mut ffi::sqlite3 {
868         self.db.borrow().db()
869     }
870 
871     /// Create a `Connection` from a raw handle.
872     ///
873     /// The underlying SQLite database connection handle will not be closed when
874     /// the returned connection is dropped/closed.
875     ///
876     /// # Safety
877     ///
878     /// This function is unsafe because improper use may impact the Connection.
879     #[inline]
from_handle(db: *mut ffi::sqlite3) -> Result<Connection>880     pub unsafe fn from_handle(db: *mut ffi::sqlite3) -> Result<Connection> {
881         let db_path = db_filename(db);
882         let db = InnerConnection::new(db, false);
883         Ok(Connection {
884             db: RefCell::new(db),
885             cache: StatementCache::with_capacity(STATEMENT_CACHE_DEFAULT_CAPACITY),
886             path: db_path,
887         })
888     }
889 
890     /// Get access to a handle that can be used to interrupt long running
891     /// queries from another thread.
892     #[inline]
get_interrupt_handle(&self) -> InterruptHandle893     pub fn get_interrupt_handle(&self) -> InterruptHandle {
894         self.db.borrow().get_interrupt_handle()
895     }
896 
897     #[inline]
decode_result(&self, code: c_int) -> Result<()>898     fn decode_result(&self, code: c_int) -> Result<()> {
899         self.db.borrow().decode_result(code)
900     }
901 
902     /// Return the number of rows modified, inserted or deleted by the most
903     /// recently completed INSERT, UPDATE or DELETE statement on the database
904     /// connection.
905     #[inline]
changes(&self) -> usize906     fn changes(&self) -> usize {
907         self.db.borrow().changes()
908     }
909 
910     /// Test for auto-commit mode.
911     /// Autocommit mode is on by default.
912     #[inline]
is_autocommit(&self) -> bool913     pub fn is_autocommit(&self) -> bool {
914         self.db.borrow().is_autocommit()
915     }
916 
917     /// Determine if all associated prepared statements have been reset.
918     #[inline]
919     #[cfg(feature = "modern_sqlite")] // 3.8.6
920     #[cfg_attr(docsrs, doc(cfg(feature = "modern_sqlite")))]
is_busy(&self) -> bool921     pub fn is_busy(&self) -> bool {
922         self.db.borrow().is_busy()
923     }
924 
925     /// Flush caches to disk mid-transaction
926     #[cfg(feature = "modern_sqlite")] // 3.10.0
927     #[cfg_attr(docsrs, doc(cfg(feature = "modern_sqlite")))]
cache_flush(&self) -> Result<()>928     pub fn cache_flush(&self) -> Result<()> {
929         self.db.borrow_mut().cache_flush()
930     }
931 }
932 
933 impl fmt::Debug for Connection {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result934     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
935         f.debug_struct("Connection")
936             .field("path", &self.path)
937             .finish()
938     }
939 }
940 
941 /// Batch iterator
942 /// ```rust
943 /// use rusqlite::{Batch, Connection, Result};
944 ///
945 /// fn main() -> Result<()> {
946 ///     let conn = Connection::open_in_memory()?;
947 ///     let sql = r"
948 ///     CREATE TABLE tbl1 (col);
949 ///     CREATE TABLE tbl2 (col);
950 ///     ";
951 ///     let mut batch = Batch::new(&conn, sql);
952 ///     while let Some(mut stmt) = batch.next()? {
953 ///         stmt.execute([])?;
954 ///     }
955 ///     Ok(())
956 /// }
957 /// ```
958 #[derive(Debug)]
959 pub struct Batch<'conn, 'sql> {
960     conn: &'conn Connection,
961     sql: &'sql str,
962     tail: usize,
963 }
964 
965 impl<'conn, 'sql> Batch<'conn, 'sql> {
966     /// Constructor
new(conn: &'conn Connection, sql: &'sql str) -> Batch<'conn, 'sql>967     pub fn new(conn: &'conn Connection, sql: &'sql str) -> Batch<'conn, 'sql> {
968         Batch { conn, sql, tail: 0 }
969     }
970 
971     /// Iterates on each batch statements.
972     ///
973     /// Returns `Ok(None)` when batch is completed.
974     #[allow(clippy::should_implement_trait)] // fallible iterator
next(&mut self) -> Result<Option<Statement<'conn>>>975     pub fn next(&mut self) -> Result<Option<Statement<'conn>>> {
976         while self.tail < self.sql.len() {
977             let sql = &self.sql[self.tail..];
978             let next = self.conn.prepare(sql)?;
979             let tail = next.stmt.tail();
980             if tail == 0 {
981                 self.tail = self.sql.len();
982             } else {
983                 self.tail += tail;
984             }
985             if next.stmt.is_null() {
986                 continue;
987             }
988             return Ok(Some(next));
989         }
990         Ok(None)
991     }
992 }
993 
994 impl<'conn> Iterator for Batch<'conn, '_> {
995     type Item = Result<Statement<'conn>>;
996 
next(&mut self) -> Option<Result<Statement<'conn>>>997     fn next(&mut self) -> Option<Result<Statement<'conn>>> {
998         self.next().transpose()
999     }
1000 }
1001 
1002 bitflags::bitflags! {
1003     /// Flags for opening SQLite database connections.
1004     /// See [sqlite3_open_v2](http://www.sqlite.org/c3ref/open.html) for details.
1005     #[repr(C)]
1006     pub struct OpenFlags: ::std::os::raw::c_int {
1007         /// The database is opened in read-only mode.
1008         /// If the database does not already exist, an error is returned.
1009         const SQLITE_OPEN_READ_ONLY     = ffi::SQLITE_OPEN_READONLY;
1010         /// The database is opened for reading and writing if possible,
1011         /// or reading only if the file is write protected by the operating system.
1012         /// In either case the database must already exist, otherwise an error is returned.
1013         const SQLITE_OPEN_READ_WRITE    = ffi::SQLITE_OPEN_READWRITE;
1014         /// The database is created if it does not already exist
1015         const SQLITE_OPEN_CREATE        = ffi::SQLITE_OPEN_CREATE;
1016         /// The filename can be interpreted as a URI if this flag is set.
1017         const SQLITE_OPEN_URI           = 0x0000_0040;
1018         /// The database will be opened as an in-memory database.
1019         const SQLITE_OPEN_MEMORY        = 0x0000_0080;
1020         /// The new database connection will use the "multi-thread" threading mode.
1021         const SQLITE_OPEN_NO_MUTEX      = ffi::SQLITE_OPEN_NOMUTEX;
1022         /// The new database connection will use the "serialized" threading mode.
1023         const SQLITE_OPEN_FULL_MUTEX    = ffi::SQLITE_OPEN_FULLMUTEX;
1024         /// The database is opened shared cache enabled.
1025         const SQLITE_OPEN_SHARED_CACHE  = 0x0002_0000;
1026         /// The database is opened shared cache disabled.
1027         const SQLITE_OPEN_PRIVATE_CACHE = 0x0004_0000;
1028         /// The database filename is not allowed to be a symbolic link.
1029         const SQLITE_OPEN_NOFOLLOW = 0x0100_0000;
1030         /// Extended result codes.
1031         const SQLITE_OPEN_EXRESCODE = 0x0200_0000;
1032     }
1033 }
1034 
1035 impl Default for OpenFlags {
default() -> OpenFlags1036     fn default() -> OpenFlags {
1037         OpenFlags::SQLITE_OPEN_READ_WRITE
1038             | OpenFlags::SQLITE_OPEN_CREATE
1039             | OpenFlags::SQLITE_OPEN_NO_MUTEX
1040             | OpenFlags::SQLITE_OPEN_URI
1041     }
1042 }
1043 
1044 /// rusqlite's check for a safe SQLite threading mode requires SQLite 3.7.0 or
1045 /// later. If you are running against a SQLite older than that, rusqlite
1046 /// attempts to ensure safety by performing configuration and initialization of
1047 /// SQLite itself the first time you
1048 /// attempt to open a connection. By default, rusqlite panics if that
1049 /// initialization fails, since that could mean SQLite has been initialized in
1050 /// single-thread mode.
1051 ///
1052 /// If you are encountering that panic _and_ can ensure that SQLite has been
1053 /// initialized in either multi-thread or serialized mode, call this function
1054 /// prior to attempting to open a connection and rusqlite's initialization
1055 /// process will by skipped.
1056 ///
1057 /// # Safety
1058 ///
1059 /// This function is unsafe because if you call it and SQLite has actually been
1060 /// configured to run in single-thread mode,
1061 /// you may encounter memory errors or data corruption or any number of terrible
1062 /// things that should not be possible when you're using Rust.
bypass_sqlite_initialization()1063 pub unsafe fn bypass_sqlite_initialization() {
1064     BYPASS_SQLITE_INIT.store(true, Ordering::Relaxed);
1065 }
1066 
1067 /// Allows interrupting a long-running computation.
1068 pub struct InterruptHandle {
1069     db_lock: Arc<Mutex<*mut ffi::sqlite3>>,
1070 }
1071 
1072 unsafe impl Send for InterruptHandle {}
1073 unsafe impl Sync for InterruptHandle {}
1074 
1075 impl InterruptHandle {
1076     /// Interrupt the query currently executing on another thread. This will
1077     /// cause that query to fail with a `SQLITE3_INTERRUPT` error.
interrupt(&self)1078     pub fn interrupt(&self) {
1079         let db_handle = self.db_lock.lock().unwrap();
1080         if !db_handle.is_null() {
1081             unsafe { ffi::sqlite3_interrupt(*db_handle) }
1082         }
1083     }
1084 }
1085 
1086 #[cfg(feature = "modern_sqlite")] // 3.7.10
db_filename(db: *mut ffi::sqlite3) -> Option<PathBuf>1087 unsafe fn db_filename(db: *mut ffi::sqlite3) -> Option<PathBuf> {
1088     let db_name = DatabaseName::Main.as_cstring().unwrap();
1089     let db_filename = ffi::sqlite3_db_filename(db, db_name.as_ptr());
1090     if db_filename.is_null() {
1091         None
1092     } else {
1093         CStr::from_ptr(db_filename).to_str().ok().map(PathBuf::from)
1094     }
1095 }
1096 #[cfg(not(feature = "modern_sqlite"))]
db_filename(_: *mut ffi::sqlite3) -> Option<PathBuf>1097 unsafe fn db_filename(_: *mut ffi::sqlite3) -> Option<PathBuf> {
1098     None
1099 }
1100 
1101 #[cfg(doctest)]
1102 doc_comment::doctest!("../README.md");
1103 
1104 #[cfg(test)]
1105 mod test {
1106     use super::*;
1107     use crate::ffi;
1108     use fallible_iterator::FallibleIterator;
1109     use std::error::Error as StdError;
1110     use std::fmt;
1111 
1112     // this function is never called, but is still type checked; in
1113     // particular, calls with specific instantiations will require
1114     // that those types are `Send`.
1115     #[allow(dead_code, unconditional_recursion)]
ensure_send<T: Send>()1116     fn ensure_send<T: Send>() {
1117         ensure_send::<Connection>();
1118         ensure_send::<InterruptHandle>();
1119     }
1120 
1121     #[allow(dead_code, unconditional_recursion)]
ensure_sync<T: Sync>()1122     fn ensure_sync<T: Sync>() {
1123         ensure_sync::<InterruptHandle>();
1124     }
1125 
checked_memory_handle() -> Connection1126     fn checked_memory_handle() -> Connection {
1127         Connection::open_in_memory().unwrap()
1128     }
1129 
1130     #[test]
test_concurrent_transactions_busy_commit() -> Result<()>1131     fn test_concurrent_transactions_busy_commit() -> Result<()> {
1132         use std::time::Duration;
1133         let tmp = tempfile::tempdir().unwrap();
1134         let path = tmp.path().join("transactions.db3");
1135 
1136         Connection::open(&path)?.execute_batch(
1137             "
1138             BEGIN; CREATE TABLE foo(x INTEGER);
1139             INSERT INTO foo VALUES(42); END;",
1140         )?;
1141 
1142         let mut db1 = Connection::open_with_flags(&path, OpenFlags::SQLITE_OPEN_READ_WRITE)?;
1143         let mut db2 = Connection::open_with_flags(&path, OpenFlags::SQLITE_OPEN_READ_ONLY)?;
1144 
1145         db1.busy_timeout(Duration::from_millis(0))?;
1146         db2.busy_timeout(Duration::from_millis(0))?;
1147 
1148         {
1149             let tx1 = db1.transaction()?;
1150             let tx2 = db2.transaction()?;
1151 
1152             // SELECT first makes sqlite lock with a shared lock
1153             tx1.query_row("SELECT x FROM foo LIMIT 1", [], |_| Ok(()))?;
1154             tx2.query_row("SELECT x FROM foo LIMIT 1", [], |_| Ok(()))?;
1155 
1156             tx1.execute("INSERT INTO foo VALUES(?1)", [1])?;
1157             let _ = tx2.execute("INSERT INTO foo VALUES(?1)", [2]);
1158 
1159             let _ = tx1.commit();
1160             let _ = tx2.commit();
1161         }
1162 
1163         let _ = db1
1164             .transaction()
1165             .expect("commit should have closed transaction");
1166         let _ = db2
1167             .transaction()
1168             .expect("commit should have closed transaction");
1169         Ok(())
1170     }
1171 
1172     #[test]
test_persistence() -> Result<()>1173     fn test_persistence() -> Result<()> {
1174         let temp_dir = tempfile::tempdir().unwrap();
1175         let path = temp_dir.path().join("test.db3");
1176 
1177         {
1178             let db = Connection::open(&path)?;
1179             let sql = "BEGIN;
1180                    CREATE TABLE foo(x INTEGER);
1181                    INSERT INTO foo VALUES(42);
1182                    END;";
1183             db.execute_batch(sql)?;
1184         }
1185 
1186         let path_string = path.to_str().unwrap();
1187         let db = Connection::open(&path_string)?;
1188         let the_answer: Result<i64> = db.query_row("SELECT x FROM foo", [], |r| r.get(0));
1189 
1190         assert_eq!(42i64, the_answer?);
1191         Ok(())
1192     }
1193 
1194     #[test]
test_open()1195     fn test_open() {
1196         assert!(Connection::open_in_memory().is_ok());
1197 
1198         let db = checked_memory_handle();
1199         assert!(db.close().is_ok());
1200     }
1201 
1202     #[test]
test_open_failure()1203     fn test_open_failure() {
1204         let filename = "no_such_file.db";
1205         let result = Connection::open_with_flags(filename, OpenFlags::SQLITE_OPEN_READ_ONLY);
1206         assert!(result.is_err());
1207         let err = result.err().unwrap();
1208         if let Error::SqliteFailure(e, Some(msg)) = err {
1209             assert_eq!(ErrorCode::CannotOpen, e.code);
1210             assert_eq!(ffi::SQLITE_CANTOPEN, e.extended_code);
1211             assert!(
1212                 msg.contains(filename),
1213                 "error message '{}' does not contain '{}'",
1214                 msg,
1215                 filename
1216             );
1217         } else {
1218             panic!("SqliteFailure expected");
1219         }
1220     }
1221 
1222     #[cfg(unix)]
1223     #[test]
test_invalid_unicode_file_names() -> Result<()>1224     fn test_invalid_unicode_file_names() -> Result<()> {
1225         use std::ffi::OsStr;
1226         use std::fs::File;
1227         use std::os::unix::ffi::OsStrExt;
1228         let temp_dir = tempfile::tempdir().unwrap();
1229 
1230         let path = temp_dir.path();
1231         if File::create(path.join(OsStr::from_bytes(&[0xFE]))).is_err() {
1232             // Skip test, filesystem doesn't support invalid Unicode
1233             return Ok(());
1234         }
1235         let db_path = path.join(OsStr::from_bytes(&[0xFF]));
1236         {
1237             let db = Connection::open(&db_path)?;
1238             let sql = "BEGIN;
1239                    CREATE TABLE foo(x INTEGER);
1240                    INSERT INTO foo VALUES(42);
1241                    END;";
1242             db.execute_batch(sql)?;
1243         }
1244 
1245         let db = Connection::open(&db_path)?;
1246         let the_answer: Result<i64> = db.query_row("SELECT x FROM foo", [], |r| r.get(0));
1247 
1248         assert_eq!(42i64, the_answer?);
1249         Ok(())
1250     }
1251 
1252     #[test]
test_close_retry() -> Result<()>1253     fn test_close_retry() -> Result<()> {
1254         let db = Connection::open_in_memory()?;
1255 
1256         // force the DB to be busy by preparing a statement; this must be done at the
1257         // FFI level to allow us to call .close() without dropping the prepared
1258         // statement first.
1259         let raw_stmt = {
1260             use super::str_to_cstring;
1261             use std::os::raw::c_int;
1262             use std::ptr;
1263 
1264             let raw_db = db.db.borrow_mut().db;
1265             let sql = "SELECT 1";
1266             let mut raw_stmt: *mut ffi::sqlite3_stmt = ptr::null_mut();
1267             let cstring = str_to_cstring(sql)?;
1268             let rc = unsafe {
1269                 ffi::sqlite3_prepare_v2(
1270                     raw_db,
1271                     cstring.as_ptr(),
1272                     (sql.len() + 1) as c_int,
1273                     &mut raw_stmt,
1274                     ptr::null_mut(),
1275                 )
1276             };
1277             assert_eq!(rc, ffi::SQLITE_OK);
1278             raw_stmt
1279         };
1280 
1281         // now that we have an open statement, trying (and retrying) to close should
1282         // fail.
1283         let (db, _) = db.close().unwrap_err();
1284         let (db, _) = db.close().unwrap_err();
1285         let (db, _) = db.close().unwrap_err();
1286 
1287         // finalize the open statement so a final close will succeed
1288         assert_eq!(ffi::SQLITE_OK, unsafe { ffi::sqlite3_finalize(raw_stmt) });
1289 
1290         db.close().unwrap();
1291         Ok(())
1292     }
1293 
1294     #[test]
test_open_with_flags()1295     fn test_open_with_flags() {
1296         for bad_flags in &[
1297             OpenFlags::empty(),
1298             OpenFlags::SQLITE_OPEN_READ_ONLY | OpenFlags::SQLITE_OPEN_READ_WRITE,
1299             OpenFlags::SQLITE_OPEN_READ_ONLY | OpenFlags::SQLITE_OPEN_CREATE,
1300         ] {
1301             assert!(Connection::open_in_memory_with_flags(*bad_flags).is_err());
1302         }
1303     }
1304 
1305     #[test]
test_execute_batch() -> Result<()>1306     fn test_execute_batch() -> Result<()> {
1307         let db = Connection::open_in_memory()?;
1308         let sql = "BEGIN;
1309                    CREATE TABLE foo(x INTEGER);
1310                    INSERT INTO foo VALUES(1);
1311                    INSERT INTO foo VALUES(2);
1312                    INSERT INTO foo VALUES(3);
1313                    INSERT INTO foo VALUES(4);
1314                    END;";
1315         db.execute_batch(sql)?;
1316 
1317         db.execute_batch("UPDATE foo SET x = 3 WHERE x < 3")?;
1318 
1319         assert!(db.execute_batch("INVALID SQL").is_err());
1320         Ok(())
1321     }
1322 
1323     #[test]
test_execute() -> Result<()>1324     fn test_execute() -> Result<()> {
1325         let db = Connection::open_in_memory()?;
1326         db.execute_batch("CREATE TABLE foo(x INTEGER)")?;
1327 
1328         assert_eq!(1, db.execute("INSERT INTO foo(x) VALUES (?)", [1i32])?);
1329         assert_eq!(1, db.execute("INSERT INTO foo(x) VALUES (?)", [2i32])?);
1330 
1331         assert_eq!(
1332             3i32,
1333             db.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))?
1334         );
1335         Ok(())
1336     }
1337 
1338     #[test]
1339     #[cfg(feature = "extra_check")]
test_execute_select()1340     fn test_execute_select() {
1341         let db = checked_memory_handle();
1342         let err = db.execute("SELECT 1 WHERE 1 < ?", [1i32]).unwrap_err();
1343         assert!(
1344             err == Error::ExecuteReturnedResults,
1345             "Unexpected error: {}",
1346             err
1347         );
1348     }
1349 
1350     #[test]
1351     #[cfg(feature = "extra_check")]
test_execute_multiple()1352     fn test_execute_multiple() {
1353         let db = checked_memory_handle();
1354         let err = db
1355             .execute(
1356                 "CREATE TABLE foo(x INTEGER); CREATE TABLE foo(x INTEGER)",
1357                 [],
1358             )
1359             .unwrap_err();
1360         match err {
1361             Error::MultipleStatement => (),
1362             _ => panic!("Unexpected error: {}", err),
1363         }
1364     }
1365 
1366     #[test]
test_prepare_column_names() -> Result<()>1367     fn test_prepare_column_names() -> Result<()> {
1368         let db = Connection::open_in_memory()?;
1369         db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
1370 
1371         let stmt = db.prepare("SELECT * FROM foo")?;
1372         assert_eq!(stmt.column_count(), 1);
1373         assert_eq!(stmt.column_names(), vec!["x"]);
1374 
1375         let stmt = db.prepare("SELECT x AS a, x AS b FROM foo")?;
1376         assert_eq!(stmt.column_count(), 2);
1377         assert_eq!(stmt.column_names(), vec!["a", "b"]);
1378         Ok(())
1379     }
1380 
1381     #[test]
test_prepare_execute() -> Result<()>1382     fn test_prepare_execute() -> Result<()> {
1383         let db = Connection::open_in_memory()?;
1384         db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
1385 
1386         let mut insert_stmt = db.prepare("INSERT INTO foo(x) VALUES(?)")?;
1387         assert_eq!(insert_stmt.execute([1i32])?, 1);
1388         assert_eq!(insert_stmt.execute([2i32])?, 1);
1389         assert_eq!(insert_stmt.execute([3i32])?, 1);
1390 
1391         assert_eq!(insert_stmt.execute(["hello"])?, 1);
1392         assert_eq!(insert_stmt.execute(["goodbye"])?, 1);
1393         assert_eq!(insert_stmt.execute([types::Null])?, 1);
1394 
1395         let mut update_stmt = db.prepare("UPDATE foo SET x=? WHERE x<?")?;
1396         assert_eq!(update_stmt.execute([3i32, 3i32])?, 2);
1397         assert_eq!(update_stmt.execute([3i32, 3i32])?, 0);
1398         assert_eq!(update_stmt.execute([8i32, 8i32])?, 3);
1399         Ok(())
1400     }
1401 
1402     #[test]
test_prepare_query() -> Result<()>1403     fn test_prepare_query() -> Result<()> {
1404         let db = Connection::open_in_memory()?;
1405         db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
1406 
1407         let mut insert_stmt = db.prepare("INSERT INTO foo(x) VALUES(?)")?;
1408         assert_eq!(insert_stmt.execute([1i32])?, 1);
1409         assert_eq!(insert_stmt.execute([2i32])?, 1);
1410         assert_eq!(insert_stmt.execute([3i32])?, 1);
1411 
1412         let mut query = db.prepare("SELECT x FROM foo WHERE x < ? ORDER BY x DESC")?;
1413         {
1414             let mut rows = query.query([4i32])?;
1415             let mut v = Vec::<i32>::new();
1416 
1417             while let Some(row) = rows.next()? {
1418                 v.push(row.get(0)?);
1419             }
1420 
1421             assert_eq!(v, [3i32, 2, 1]);
1422         }
1423 
1424         {
1425             let mut rows = query.query([3i32])?;
1426             let mut v = Vec::<i32>::new();
1427 
1428             while let Some(row) = rows.next()? {
1429                 v.push(row.get(0)?);
1430             }
1431 
1432             assert_eq!(v, [2i32, 1]);
1433         }
1434         Ok(())
1435     }
1436 
1437     #[test]
test_query_map() -> Result<()>1438     fn test_query_map() -> Result<()> {
1439         let db = Connection::open_in_memory()?;
1440         let sql = "BEGIN;
1441                    CREATE TABLE foo(x INTEGER, y TEXT);
1442                    INSERT INTO foo VALUES(4, \"hello\");
1443                    INSERT INTO foo VALUES(3, \", \");
1444                    INSERT INTO foo VALUES(2, \"world\");
1445                    INSERT INTO foo VALUES(1, \"!\");
1446                    END;";
1447         db.execute_batch(sql)?;
1448 
1449         let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC")?;
1450         let results: Result<Vec<String>> = query.query([])?.map(|row| row.get(1)).collect();
1451 
1452         assert_eq!(results?.concat(), "hello, world!");
1453         Ok(())
1454     }
1455 
1456     #[test]
test_query_row() -> Result<()>1457     fn test_query_row() -> Result<()> {
1458         let db = Connection::open_in_memory()?;
1459         let sql = "BEGIN;
1460                    CREATE TABLE foo(x INTEGER);
1461                    INSERT INTO foo VALUES(1);
1462                    INSERT INTO foo VALUES(2);
1463                    INSERT INTO foo VALUES(3);
1464                    INSERT INTO foo VALUES(4);
1465                    END;";
1466         db.execute_batch(sql)?;
1467 
1468         assert_eq!(
1469             10i64,
1470             db.query_row::<i64, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))?
1471         );
1472 
1473         let result: Result<i64> = db.query_row("SELECT x FROM foo WHERE x > 5", [], |r| r.get(0));
1474         match result.unwrap_err() {
1475             Error::QueryReturnedNoRows => (),
1476             err => panic!("Unexpected error {}", err),
1477         }
1478 
1479         let bad_query_result = db.query_row("NOT A PROPER QUERY; test123", [], |_| Ok(()));
1480 
1481         assert!(bad_query_result.is_err());
1482         Ok(())
1483     }
1484 
1485     #[test]
test_optional() -> Result<()>1486     fn test_optional() -> Result<()> {
1487         let db = Connection::open_in_memory()?;
1488 
1489         let result: Result<i64> = db.query_row("SELECT 1 WHERE 0 <> 0", [], |r| r.get(0));
1490         let result = result.optional();
1491         match result? {
1492             None => (),
1493             _ => panic!("Unexpected result"),
1494         }
1495 
1496         let result: Result<i64> = db.query_row("SELECT 1 WHERE 0 == 0", [], |r| r.get(0));
1497         let result = result.optional();
1498         match result? {
1499             Some(1) => (),
1500             _ => panic!("Unexpected result"),
1501         }
1502 
1503         let bad_query_result: Result<i64> = db.query_row("NOT A PROPER QUERY", [], |r| r.get(0));
1504         let bad_query_result = bad_query_result.optional();
1505         assert!(bad_query_result.is_err());
1506         Ok(())
1507     }
1508 
1509     #[test]
test_pragma_query_row() -> Result<()>1510     fn test_pragma_query_row() -> Result<()> {
1511         let db = Connection::open_in_memory()?;
1512 
1513         assert_eq!(
1514             "memory",
1515             db.query_row::<String, _, _>("PRAGMA journal_mode", [], |r| r.get(0))?
1516         );
1517         assert_eq!(
1518             "off",
1519             db.query_row::<String, _, _>("PRAGMA journal_mode=off", [], |r| r.get(0))?
1520         );
1521         Ok(())
1522     }
1523 
1524     #[test]
test_prepare_failures() -> Result<()>1525     fn test_prepare_failures() -> Result<()> {
1526         let db = Connection::open_in_memory()?;
1527         db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
1528 
1529         let err = db.prepare("SELECT * FROM does_not_exist").unwrap_err();
1530         assert!(format!("{}", err).contains("does_not_exist"));
1531         Ok(())
1532     }
1533 
1534     #[test]
test_last_insert_rowid() -> Result<()>1535     fn test_last_insert_rowid() -> Result<()> {
1536         let db = Connection::open_in_memory()?;
1537         db.execute_batch("CREATE TABLE foo(x INTEGER PRIMARY KEY)")?;
1538         db.execute_batch("INSERT INTO foo DEFAULT VALUES")?;
1539 
1540         assert_eq!(db.last_insert_rowid(), 1);
1541 
1542         let mut stmt = db.prepare("INSERT INTO foo DEFAULT VALUES")?;
1543         for _ in 0i32..9 {
1544             stmt.execute([])?;
1545         }
1546         assert_eq!(db.last_insert_rowid(), 10);
1547         Ok(())
1548     }
1549 
1550     #[test]
test_is_autocommit() -> Result<()>1551     fn test_is_autocommit() -> Result<()> {
1552         let db = Connection::open_in_memory()?;
1553         assert!(
1554             db.is_autocommit(),
1555             "autocommit expected to be active by default"
1556         );
1557         Ok(())
1558     }
1559 
1560     #[test]
1561     #[cfg(feature = "modern_sqlite")]
test_is_busy() -> Result<()>1562     fn test_is_busy() -> Result<()> {
1563         let db = Connection::open_in_memory()?;
1564         assert!(!db.is_busy());
1565         let mut stmt = db.prepare("PRAGMA schema_version")?;
1566         assert!(!db.is_busy());
1567         {
1568             let mut rows = stmt.query([])?;
1569             assert!(!db.is_busy());
1570             let row = rows.next()?;
1571             assert!(db.is_busy());
1572             assert!(row.is_some());
1573         }
1574         assert!(!db.is_busy());
1575         Ok(())
1576     }
1577 
1578     #[test]
test_statement_debugging() -> Result<()>1579     fn test_statement_debugging() -> Result<()> {
1580         let db = Connection::open_in_memory()?;
1581         let query = "SELECT 12345";
1582         let stmt = db.prepare(query)?;
1583 
1584         assert!(format!("{:?}", stmt).contains(query));
1585         Ok(())
1586     }
1587 
1588     #[test]
test_notnull_constraint_error() -> Result<()>1589     fn test_notnull_constraint_error() -> Result<()> {
1590         // extended error codes for constraints were added in SQLite 3.7.16; if we're
1591         // running on our bundled version, we know the extended error code exists.
1592         #[cfg(feature = "modern_sqlite")]
1593         fn check_extended_code(extended_code: c_int) {
1594             assert_eq!(extended_code, ffi::SQLITE_CONSTRAINT_NOTNULL);
1595         }
1596         #[cfg(not(feature = "modern_sqlite"))]
1597         fn check_extended_code(_extended_code: c_int) {}
1598 
1599         let db = Connection::open_in_memory()?;
1600         db.execute_batch("CREATE TABLE foo(x NOT NULL)")?;
1601 
1602         let result = db.execute("INSERT INTO foo (x) VALUES (NULL)", []);
1603         assert!(result.is_err());
1604 
1605         match result.unwrap_err() {
1606             Error::SqliteFailure(err, _) => {
1607                 assert_eq!(err.code, ErrorCode::ConstraintViolation);
1608                 check_extended_code(err.extended_code);
1609             }
1610             err => panic!("Unexpected error {}", err),
1611         }
1612         Ok(())
1613     }
1614 
1615     #[test]
test_version_string()1616     fn test_version_string() {
1617         let n = version_number();
1618         let major = n / 1_000_000;
1619         let minor = (n % 1_000_000) / 1_000;
1620         let patch = n % 1_000;
1621 
1622         assert!(version().contains(&format!("{}.{}.{}", major, minor, patch)));
1623     }
1624 
1625     #[test]
1626     #[cfg(feature = "functions")]
test_interrupt() -> Result<()>1627     fn test_interrupt() -> Result<()> {
1628         let db = Connection::open_in_memory()?;
1629 
1630         let interrupt_handle = db.get_interrupt_handle();
1631 
1632         db.create_scalar_function(
1633             "interrupt",
1634             0,
1635             crate::functions::FunctionFlags::default(),
1636             move |_| {
1637                 interrupt_handle.interrupt();
1638                 Ok(0)
1639             },
1640         )?;
1641 
1642         let mut stmt =
1643             db.prepare("SELECT interrupt() FROM (SELECT 1 UNION SELECT 2 UNION SELECT 3)")?;
1644 
1645         let result: Result<Vec<i32>> = stmt.query([])?.map(|r| r.get(0)).collect();
1646 
1647         match result.unwrap_err() {
1648             Error::SqliteFailure(err, _) => {
1649                 assert_eq!(err.code, ErrorCode::OperationInterrupted);
1650             }
1651             err => {
1652                 panic!("Unexpected error {}", err);
1653             }
1654         }
1655         Ok(())
1656     }
1657 
1658     #[test]
test_interrupt_close()1659     fn test_interrupt_close() {
1660         let db = checked_memory_handle();
1661         let handle = db.get_interrupt_handle();
1662         handle.interrupt();
1663         db.close().unwrap();
1664         handle.interrupt();
1665 
1666         // Look at it's internals to see if we cleared it out properly.
1667         let db_guard = handle.db_lock.lock().unwrap();
1668         assert!(db_guard.is_null());
1669         // It would be nice to test that we properly handle close/interrupt
1670         // running at the same time, but it seems impossible to do with any
1671         // degree of reliability.
1672     }
1673 
1674     #[test]
test_get_raw() -> Result<()>1675     fn test_get_raw() -> Result<()> {
1676         let db = Connection::open_in_memory()?;
1677         db.execute_batch("CREATE TABLE foo(i, x);")?;
1678         let vals = ["foobar", "1234", "qwerty"];
1679         let mut insert_stmt = db.prepare("INSERT INTO foo(i, x) VALUES(?, ?)")?;
1680         for (i, v) in vals.iter().enumerate() {
1681             let i_to_insert = i as i64;
1682             assert_eq!(insert_stmt.execute(params![i_to_insert, v])?, 1);
1683         }
1684 
1685         let mut query = db.prepare("SELECT i, x FROM foo")?;
1686         let mut rows = query.query([])?;
1687 
1688         while let Some(row) = rows.next()? {
1689             let i = row.get_ref(0)?.as_i64()?;
1690             let expect = vals[i as usize];
1691             let x = row.get_ref("x")?.as_str()?;
1692             assert_eq!(x, expect);
1693         }
1694 
1695         let mut query = db.prepare("SELECT x FROM foo")?;
1696         let rows = query.query_map([], |row| {
1697             let x = row.get_ref(0)?.as_str()?; // check From<FromSqlError> for Error
1698             Ok(x[..].to_owned())
1699         })?;
1700 
1701         for (i, row) in rows.enumerate() {
1702             assert_eq!(row?, vals[i]);
1703         }
1704         Ok(())
1705     }
1706 
1707     #[test]
test_from_handle() -> Result<()>1708     fn test_from_handle() -> Result<()> {
1709         let db = Connection::open_in_memory()?;
1710         let handle = unsafe { db.handle() };
1711         {
1712             let db = unsafe { Connection::from_handle(handle) }?;
1713             db.execute_batch("PRAGMA VACUUM")?;
1714         }
1715         db.close().unwrap();
1716         Ok(())
1717     }
1718 
1719     mod query_and_then_tests {
1720 
1721         use super::*;
1722 
1723         #[derive(Debug)]
1724         enum CustomError {
1725             SomeError,
1726             Sqlite(Error),
1727         }
1728 
1729         impl fmt::Display for CustomError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error>1730             fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
1731                 match *self {
1732                     CustomError::SomeError => write!(f, "my custom error"),
1733                     CustomError::Sqlite(ref se) => write!(f, "my custom error: {}", se),
1734                 }
1735             }
1736         }
1737 
1738         impl StdError for CustomError {
description(&self) -> &str1739             fn description(&self) -> &str {
1740                 "my custom error"
1741             }
1742 
cause(&self) -> Option<&dyn StdError>1743             fn cause(&self) -> Option<&dyn StdError> {
1744                 match *self {
1745                     CustomError::SomeError => None,
1746                     CustomError::Sqlite(ref se) => Some(se),
1747                 }
1748             }
1749         }
1750 
1751         impl From<Error> for CustomError {
from(se: Error) -> CustomError1752             fn from(se: Error) -> CustomError {
1753                 CustomError::Sqlite(se)
1754             }
1755         }
1756 
1757         type CustomResult<T> = Result<T, CustomError>;
1758 
1759         #[test]
test_query_and_then() -> Result<()>1760         fn test_query_and_then() -> Result<()> {
1761             let db = Connection::open_in_memory()?;
1762             let sql = "BEGIN;
1763                        CREATE TABLE foo(x INTEGER, y TEXT);
1764                        INSERT INTO foo VALUES(4, \"hello\");
1765                        INSERT INTO foo VALUES(3, \", \");
1766                        INSERT INTO foo VALUES(2, \"world\");
1767                        INSERT INTO foo VALUES(1, \"!\");
1768                        END;";
1769             db.execute_batch(sql)?;
1770 
1771             let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC")?;
1772             let results: Result<Vec<String>> =
1773                 query.query_and_then([], |row| row.get(1))?.collect();
1774 
1775             assert_eq!(results?.concat(), "hello, world!");
1776             Ok(())
1777         }
1778 
1779         #[test]
test_query_and_then_fails() -> Result<()>1780         fn test_query_and_then_fails() -> Result<()> {
1781             let db = Connection::open_in_memory()?;
1782             let sql = "BEGIN;
1783                        CREATE TABLE foo(x INTEGER, y TEXT);
1784                        INSERT INTO foo VALUES(4, \"hello\");
1785                        INSERT INTO foo VALUES(3, \", \");
1786                        INSERT INTO foo VALUES(2, \"world\");
1787                        INSERT INTO foo VALUES(1, \"!\");
1788                        END;";
1789             db.execute_batch(sql)?;
1790 
1791             let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC")?;
1792             let bad_type: Result<Vec<f64>> = query.query_and_then([], |row| row.get(1))?.collect();
1793 
1794             match bad_type.unwrap_err() {
1795                 Error::InvalidColumnType(..) => (),
1796                 err => panic!("Unexpected error {}", err),
1797             }
1798 
1799             let bad_idx: Result<Vec<String>> =
1800                 query.query_and_then([], |row| row.get(3))?.collect();
1801 
1802             match bad_idx.unwrap_err() {
1803                 Error::InvalidColumnIndex(_) => (),
1804                 err => panic!("Unexpected error {}", err),
1805             }
1806             Ok(())
1807         }
1808 
1809         #[test]
test_query_and_then_custom_error() -> CustomResult<()>1810         fn test_query_and_then_custom_error() -> CustomResult<()> {
1811             let db = Connection::open_in_memory()?;
1812             let sql = "BEGIN;
1813                        CREATE TABLE foo(x INTEGER, y TEXT);
1814                        INSERT INTO foo VALUES(4, \"hello\");
1815                        INSERT INTO foo VALUES(3, \", \");
1816                        INSERT INTO foo VALUES(2, \"world\");
1817                        INSERT INTO foo VALUES(1, \"!\");
1818                        END;";
1819             db.execute_batch(sql)?;
1820 
1821             let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC")?;
1822             let results: CustomResult<Vec<String>> = query
1823                 .query_and_then([], |row| row.get(1).map_err(CustomError::Sqlite))?
1824                 .collect();
1825 
1826             assert_eq!(results?.concat(), "hello, world!");
1827             Ok(())
1828         }
1829 
1830         #[test]
test_query_and_then_custom_error_fails() -> Result<()>1831         fn test_query_and_then_custom_error_fails() -> Result<()> {
1832             let db = Connection::open_in_memory()?;
1833             let sql = "BEGIN;
1834                        CREATE TABLE foo(x INTEGER, y TEXT);
1835                        INSERT INTO foo VALUES(4, \"hello\");
1836                        INSERT INTO foo VALUES(3, \", \");
1837                        INSERT INTO foo VALUES(2, \"world\");
1838                        INSERT INTO foo VALUES(1, \"!\");
1839                        END;";
1840             db.execute_batch(sql)?;
1841 
1842             let mut query = db.prepare("SELECT x, y FROM foo ORDER BY x DESC")?;
1843             let bad_type: CustomResult<Vec<f64>> = query
1844                 .query_and_then([], |row| row.get(1).map_err(CustomError::Sqlite))?
1845                 .collect();
1846 
1847             match bad_type.unwrap_err() {
1848                 CustomError::Sqlite(Error::InvalidColumnType(..)) => (),
1849                 err => panic!("Unexpected error {}", err),
1850             }
1851 
1852             let bad_idx: CustomResult<Vec<String>> = query
1853                 .query_and_then([], |row| row.get(3).map_err(CustomError::Sqlite))?
1854                 .collect();
1855 
1856             match bad_idx.unwrap_err() {
1857                 CustomError::Sqlite(Error::InvalidColumnIndex(_)) => (),
1858                 err => panic!("Unexpected error {}", err),
1859             }
1860 
1861             let non_sqlite_err: CustomResult<Vec<String>> = query
1862                 .query_and_then([], |_| Err(CustomError::SomeError))?
1863                 .collect();
1864 
1865             match non_sqlite_err.unwrap_err() {
1866                 CustomError::SomeError => (),
1867                 err => panic!("Unexpected error {}", err),
1868             }
1869             Ok(())
1870         }
1871 
1872         #[test]
test_query_row_and_then_custom_error() -> CustomResult<()>1873         fn test_query_row_and_then_custom_error() -> CustomResult<()> {
1874             let db = Connection::open_in_memory()?;
1875             let sql = "BEGIN;
1876                        CREATE TABLE foo(x INTEGER, y TEXT);
1877                        INSERT INTO foo VALUES(4, \"hello\");
1878                        END;";
1879             db.execute_batch(sql)?;
1880 
1881             let query = "SELECT x, y FROM foo ORDER BY x DESC";
1882             let results: CustomResult<String> =
1883                 db.query_row_and_then(query, [], |row| row.get(1).map_err(CustomError::Sqlite));
1884 
1885             assert_eq!(results?, "hello");
1886             Ok(())
1887         }
1888 
1889         #[test]
test_query_row_and_then_custom_error_fails() -> Result<()>1890         fn test_query_row_and_then_custom_error_fails() -> Result<()> {
1891             let db = Connection::open_in_memory()?;
1892             let sql = "BEGIN;
1893                        CREATE TABLE foo(x INTEGER, y TEXT);
1894                        INSERT INTO foo VALUES(4, \"hello\");
1895                        END;";
1896             db.execute_batch(sql)?;
1897 
1898             let query = "SELECT x, y FROM foo ORDER BY x DESC";
1899             let bad_type: CustomResult<f64> =
1900                 db.query_row_and_then(query, [], |row| row.get(1).map_err(CustomError::Sqlite));
1901 
1902             match bad_type.unwrap_err() {
1903                 CustomError::Sqlite(Error::InvalidColumnType(..)) => (),
1904                 err => panic!("Unexpected error {}", err),
1905             }
1906 
1907             let bad_idx: CustomResult<String> =
1908                 db.query_row_and_then(query, [], |row| row.get(3).map_err(CustomError::Sqlite));
1909 
1910             match bad_idx.unwrap_err() {
1911                 CustomError::Sqlite(Error::InvalidColumnIndex(_)) => (),
1912                 err => panic!("Unexpected error {}", err),
1913             }
1914 
1915             let non_sqlite_err: CustomResult<String> =
1916                 db.query_row_and_then(query, [], |_| Err(CustomError::SomeError));
1917 
1918             match non_sqlite_err.unwrap_err() {
1919                 CustomError::SomeError => (),
1920                 err => panic!("Unexpected error {}", err),
1921             }
1922             Ok(())
1923         }
1924     }
1925 
1926     #[test]
test_dynamic() -> Result<()>1927     fn test_dynamic() -> Result<()> {
1928         let db = Connection::open_in_memory()?;
1929         let sql = "BEGIN;
1930                        CREATE TABLE foo(x INTEGER, y TEXT);
1931                        INSERT INTO foo VALUES(4, \"hello\");
1932                        END;";
1933         db.execute_batch(sql)?;
1934 
1935         db.query_row("SELECT * FROM foo", [], |r| {
1936             assert_eq!(2, r.as_ref().column_count());
1937             Ok(())
1938         })
1939     }
1940     #[test]
test_dyn_box() -> Result<()>1941     fn test_dyn_box() -> Result<()> {
1942         let db = Connection::open_in_memory()?;
1943         db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
1944         let b: Box<dyn ToSql> = Box::new(5);
1945         db.execute("INSERT INTO foo VALUES(?)", [b])?;
1946         db.query_row("SELECT x FROM foo", [], |r| {
1947             assert_eq!(5, r.get_unwrap::<_, i32>(0));
1948             Ok(())
1949         })
1950     }
1951 
1952     #[test]
test_params() -> Result<()>1953     fn test_params() -> Result<()> {
1954         let db = Connection::open_in_memory()?;
1955         db.query_row(
1956             "SELECT
1957             ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
1958             ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
1959             ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
1960             ?, ?, ?, ?;",
1961             params![
1962                 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1963                 1, 1, 1, 1, 1, 1,
1964             ],
1965             |r| {
1966                 assert_eq!(1, r.get_unwrap::<_, i32>(0));
1967                 Ok(())
1968             },
1969         )
1970     }
1971 
1972     #[test]
1973     #[cfg(not(feature = "extra_check"))]
test_alter_table() -> Result<()>1974     fn test_alter_table() -> Result<()> {
1975         let db = Connection::open_in_memory()?;
1976         db.execute_batch("CREATE TABLE x(t);")?;
1977         // `execute_batch` should be used but `execute` should also work
1978         db.execute("ALTER TABLE x RENAME TO y;", [])?;
1979         Ok(())
1980     }
1981 
1982     #[test]
test_batch() -> Result<()>1983     fn test_batch() -> Result<()> {
1984         let db = Connection::open_in_memory()?;
1985         let sql = r"
1986              CREATE TABLE tbl1 (col);
1987              CREATE TABLE tbl2 (col);
1988              ";
1989         let batch = Batch::new(&db, sql);
1990         for stmt in batch {
1991             let mut stmt = stmt?;
1992             stmt.execute([])?;
1993         }
1994         Ok(())
1995     }
1996 
1997     #[test]
1998     #[cfg(all(feature = "bundled", not(feature = "bundled-sqlcipher")))] // SQLite >= 3.35.0
test_returning() -> Result<()>1999     fn test_returning() -> Result<()> {
2000         let db = Connection::open_in_memory()?;
2001         db.execute_batch("CREATE TABLE foo(x INTEGER PRIMARY KEY)")?;
2002         let row_id =
2003             db.query_row::<i64, _, _>("INSERT INTO foo DEFAULT VALUES RETURNING ROWID", [], |r| {
2004                 r.get(0)
2005             })?;
2006         assert_eq!(row_id, 1);
2007         Ok(())
2008     }
2009 
2010     #[test]
2011     #[cfg(feature = "modern_sqlite")]
test_cache_flush() -> Result<()>2012     fn test_cache_flush() -> Result<()> {
2013         let db = Connection::open_in_memory()?;
2014         db.cache_flush()
2015     }
2016 }
2017