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