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