Skip to main content

rusqlite/
lib.rs

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