Improve the docs for opening the connection a bit

This commit is contained in:
Thom Chiovoloni 2022-04-03 18:11:38 -07:00
parent af8cd1caec
commit 46def6d67e
2 changed files with 100 additions and 22 deletions

View File

@ -350,27 +350,59 @@ impl Drop for Connection {
} }
impl Connection { impl Connection {
/// Open a new connection to a SQLite database. /// Open a new connection to a SQLite database. If a database does not exist
/// /// at the path, one is created.
/// `Connection::open(path)` is equivalent to
/// `Connection::open_with_flags(path,
/// OpenFlags::SQLITE_OPEN_READ_WRITE |
/// OpenFlags::SQLITE_OPEN_CREATE)`.
/// ///
/// ```rust,no_run /// ```rust,no_run
/// # use rusqlite::{Connection, Result}; /// # use rusqlite::{Connection, Result};
/// fn open_my_db() -> Result<()> { /// fn open_my_db() -> Result<()> {
/// let path = "./my_db.db3"; /// let path = "./my_db.db3";
/// let db = Connection::open(&path)?; /// let db = Connection::open(path)?;
/// // Use the database somehow...
/// println!("{}", db.is_autocommit()); /// println!("{}", db.is_autocommit());
/// Ok(()) /// Ok(())
/// } /// }
/// ``` /// ```
/// ///
/// # Flags
///
/// `Connection::open(path)` is equivalent to using
/// [`Connection::open_with_flags`] with the default [`OpenFlags`]. That is,
/// it's equivalent to:
///
/// ```ignore
/// Connection::open_with_flags(
/// path,
/// OpenFlags::SQLITE_OPEN_READ_WRITE
/// | OpenFlags::SQLITE_OPEN_CREATE
/// | OpenFlags::SQLITE_OPEN_URI
/// | OpenFlags::SQLITE_OPEN_NO_MUTEX,
/// )
/// ```
///
/// These flags have the following effects:
///
/// - Open the database for both reading or writing.
/// - Create the database if one does not exist at the path.
/// - Allow the filename to be interpreted as a URI (see
/// <https://www.sqlite.org/uri.html#uri_filenames_in_sqlite> for
/// details).
/// - Disables the use of a per-connection mutex.
///
/// Rusqlite enforces thread-safety at compile time, so additional
/// locking is not needed and provides no benefit. (See the
/// documentation on [`OpenFlags::SQLITE_OPEN_FULL_MUTEX`] for some
/// additional discussion about this).
///
/// Most of these are also the default settings for the C API, although
/// technically the default locking behavior is controlled by the flags used
/// when compiling SQLite -- rather than let it vary, we choose `NO_MUTEX`
/// because it's a fairly clear best choice for users this library.
///
/// # Failure /// # Failure
/// ///
/// Will return `Err` if `path` cannot be converted to a C-compatible /// Will return `Err` if `path` cannot be converted to a C-compatible string
/// string or if the underlying SQLite open call fails. /// or if the underlying SQLite open call fails.
#[inline] #[inline]
pub fn open<P: AsRef<Path>>(path: P) -> Result<Connection> { pub fn open<P: AsRef<Path>>(path: P) -> Result<Connection> {
let flags = OpenFlags::default(); let flags = OpenFlags::default();
@ -1012,8 +1044,12 @@ impl<'conn> Iterator for Batch<'conn, '_> {
} }
bitflags::bitflags! { bitflags::bitflags! {
/// Flags for opening SQLite database connections. /// Flags for opening SQLite database connections. See
/// See [sqlite3_open_v2](http://www.sqlite.org/c3ref/open.html) for details. /// [sqlite3_open_v2](http://www.sqlite.org/c3ref/open.html) for details.
///
/// The default open flags are `SQLITE_OPEN_READ_WRITE | SQLITE_OPEN_CREATE
/// | SQLITE_OPEN_URI | SQLITE_OPEN_NO_MUTEX`. See [`Connection::open`] for
/// some discussion about these flags.
#[repr(C)] #[repr(C)]
pub struct OpenFlags: ::std::os::raw::c_int { pub struct OpenFlags: ::std::os::raw::c_int {
/// The database is opened in read-only mode. /// The database is opened in read-only mode.
@ -1029,11 +1065,45 @@ bitflags::bitflags! {
const SQLITE_OPEN_URI = 0x0000_0040; const SQLITE_OPEN_URI = 0x0000_0040;
/// The database will be opened as an in-memory database. /// The database will be opened as an in-memory database.
const SQLITE_OPEN_MEMORY = 0x0000_0080; const SQLITE_OPEN_MEMORY = 0x0000_0080;
/// The new database connection will use the "multi-thread" threading mode. /// The new database connection will not use a per-connection mutex (the
/// connection will use the "multi-thread" threading mode, in SQLite
/// parlance).
///
/// This is used by default, as proper `Send`/`Sync` usage (in
/// particular, the fact that [`Connection`] does not implement `Sync`)
/// ensures thread-safety without the need to perform locking around all
/// calls.
const SQLITE_OPEN_NO_MUTEX = ffi::SQLITE_OPEN_NOMUTEX; const SQLITE_OPEN_NO_MUTEX = ffi::SQLITE_OPEN_NOMUTEX;
/// The new database connection will use the "serialized" threading mode. /// The new database connection will use a per-connection mutex -- the
/// "serialized" threading mode, in SQLite parlance.
///
/// # Caveats
///
/// This flag should probably never be used with `rusqlite`, as we
/// ensure thread-safety statically (we implement [`Send`] and not
/// [`Sync`]). That said
///
/// Critically, even if this flag is used, the [`Connection`] is not
/// safe to use across multiple threads simultaneously. To access a
/// database from multiple threads, you should either create multiple
/// connections, one for each thread (if you have very many threads,
/// wrapping the `rusqlite::Connection` in a mutex is also reasonable).
///
/// This is both because of the additional per-connection state stored
/// by `rusqlite` (for example, the prepared statement cache), and
/// because not all of SQLites functions are fully thread safe, even in
/// serialized/`SQLITE_OPEN_FULLMUTEX` mode.
///
/// All that said, it's fairly harmless to enable this flag with
/// `rusqlite`, it will just slow things down while providing no
/// benefit.
const SQLITE_OPEN_FULL_MUTEX = ffi::SQLITE_OPEN_FULLMUTEX; const SQLITE_OPEN_FULL_MUTEX = ffi::SQLITE_OPEN_FULLMUTEX;
/// The database is opened shared cache enabled. /// The database is opened with shared cache enabled.
///
/// This is frequently useful for in-memory connections, but note that
/// broadly speaking it's discouraged by SQLite itself, which states
/// "Any use of shared cache is discouraged" in the official
/// [documentation](https://www.sqlite.org/c3ref/enable_shared_cache.html).
const SQLITE_OPEN_SHARED_CACHE = 0x0002_0000; const SQLITE_OPEN_SHARED_CACHE = 0x0002_0000;
/// The database is opened shared cache disabled. /// The database is opened shared cache disabled.
const SQLITE_OPEN_PRIVATE_CACHE = 0x0004_0000; const SQLITE_OPEN_PRIVATE_CACHE = 0x0004_0000;
@ -1045,7 +1115,10 @@ bitflags::bitflags! {
} }
impl Default for OpenFlags { impl Default for OpenFlags {
#[inline]
fn default() -> OpenFlags { fn default() -> OpenFlags {
// Note: update the `Connection::open` and top-level `OpenFlags` docs if
// you change these.
OpenFlags::SQLITE_OPEN_READ_WRITE OpenFlags::SQLITE_OPEN_READ_WRITE
| OpenFlags::SQLITE_OPEN_CREATE | OpenFlags::SQLITE_OPEN_CREATE
| OpenFlags::SQLITE_OPEN_NO_MUTEX | OpenFlags::SQLITE_OPEN_NO_MUTEX

View File

@ -132,6 +132,7 @@ impl Statement<'_> {
/// Will return `Err` if binding parameters fails, the executed statement /// Will return `Err` if binding parameters fails, the executed statement
/// returns rows (in which case `query` should be used instead), or the /// returns rows (in which case `query` should be used instead), or the
/// underlying SQLite call fails. /// underlying SQLite call fails.
#[doc(hidden)]
#[deprecated = "You can use `execute` with named params now."] #[deprecated = "You can use `execute` with named params now."]
#[inline] #[inline]
pub fn execute_named(&mut self, params: &[(&str, &dyn ToSql)]) -> Result<usize> { pub fn execute_named(&mut self, params: &[(&str, &dyn ToSql)]) -> Result<usize> {
@ -267,6 +268,7 @@ impl Statement<'_> {
/// # Failure /// # Failure
/// ///
/// Will return `Err` if binding parameters fails. /// Will return `Err` if binding parameters fails.
#[doc(hidden)]
#[deprecated = "You can use `query` with named params now."] #[deprecated = "You can use `query` with named params now."]
pub fn query_named(&mut self, params: &[(&str, &dyn ToSql)]) -> Result<Rows<'_>> { pub fn query_named(&mut self, params: &[(&str, &dyn ToSql)]) -> Result<Rows<'_>> {
self.query(params) self.query(params)
@ -344,6 +346,7 @@ impl Statement<'_> {
/// ## Failure /// ## Failure
/// ///
/// Will return `Err` if binding parameters fails. /// Will return `Err` if binding parameters fails.
#[doc(hidden)]
#[deprecated = "You can use `query_map` with named params now."] #[deprecated = "You can use `query_map` with named params now."]
pub fn query_map_named<T, F>( pub fn query_map_named<T, F>(
&mut self, &mut self,
@ -436,6 +439,7 @@ impl Statement<'_> {
/// ## Failure /// ## Failure
/// ///
/// Will return `Err` if binding parameters fails. /// Will return `Err` if binding parameters fails.
#[doc(hidden)]
#[deprecated = "You can use `query_and_then` with named params now."] #[deprecated = "You can use `query_and_then` with named params now."]
pub fn query_and_then_named<T, E, F>( pub fn query_and_then_named<T, E, F>(
&mut self, &mut self,
@ -503,6 +507,7 @@ impl Statement<'_> {
/// ///
/// Will return `Err` if `sql` cannot be converted to a C-compatible string /// Will return `Err` if `sql` cannot be converted to a C-compatible string
/// or if the underlying SQLite call fails. /// or if the underlying SQLite call fails.
#[doc(hidden)]
#[deprecated = "You can use `query_row` with named params now."] #[deprecated = "You can use `query_row` with named params now."]
pub fn query_row_named<T, F>(&mut self, params: &[(&str, &dyn ToSql)], f: F) -> Result<T> pub fn query_row_named<T, F>(&mut self, params: &[(&str, &dyn ToSql)], f: F) -> Result<T>
where where