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