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