rusqlite/
lib.rs

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