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