rusqlite/
lib.rs

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