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