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