rusqlite/
lib.rs

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