From 8e990ff3c66bc95951fa368fa364caba89f79125 Mon Sep 17 00:00:00 2001 From: Ivan Ukhov Date: Sat, 8 Jun 2019 19:50:27 +0200 Subject: [PATCH 1/6] Introduce connection flags --- src/connection.rs | 53 +++++++++++++++++++++++++++++++---------------- src/lib.rs | 12 +++++++---- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/connection.rs b/src/connection.rs index b956477..579e2dd 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -12,35 +12,26 @@ pub struct Connection { phantom: PhantomData, } +/// A set of connection flags. +#[derive(Clone, Copy, Debug)] +pub struct ConnectionFlags(c_int); + unsafe impl Send for Connection {} impl Connection { - /// Open a connection to a new or existing database. + /// Open a read-write connection to a new or existing database. pub fn open>(path: T) -> Result { - let mut raw = 0 as *mut _; - unsafe { - ok!(ffi::sqlite3_open_v2( - path_to_cstr!(path.as_ref()).as_ptr(), - &mut raw, - ffi::SQLITE_OPEN_CREATE | ffi::SQLITE_OPEN_READWRITE, - 0 as *const _, - )); - } - Ok(Connection { - raw: raw, - busy_callback: None, - phantom: PhantomData, - }) + Connection::open_with_flags(path, ConnectionFlags::new().set_create().set_read_write()) } - /// Open a read-only connection to an existing database. - pub fn open_readonly>(path: T) -> Result { + /// Open a database connection with a specific set of connection flags. + pub fn open_with_flags>(path: T, flags: ConnectionFlags) -> Result { let mut raw = 0 as *mut _; unsafe { ok!(ffi::sqlite3_open_v2( path_to_cstr!(path.as_ref()).as_ptr(), &mut raw, - ffi::SQLITE_OPEN_READONLY, + flags.0, 0 as *const _, )); } @@ -166,6 +157,32 @@ impl Drop for Connection { } } +impl ConnectionFlags { + /// Create a set of connection flags. + #[inline] + pub fn new() -> Self { + ConnectionFlags(0) + } + + /// Create the database if it does not already exist. + pub fn set_create(mut self) -> Self { + self.0 |= ffi::SQLITE_OPEN_CREATE; + self + } + + /// Open the database for reading only. + pub fn set_read_only(mut self) -> Self { + self.0 |= ffi::SQLITE_OPEN_READWRITE; + self + } + + /// Open the database for reading and writing. + pub fn set_read_write(mut self) -> Self { + self.0 |= ffi::SQLITE_OPEN_READWRITE; + self + } +} + extern "C" fn busy_callback(callback: *mut c_void, attempts: c_int) -> c_int where F: FnMut(usize) -> bool, diff --git a/src/lib.rs b/src/lib.rs index 84dcb5d..70b9dd6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -294,19 +294,23 @@ mod cursor; mod statement; pub use connection::Connection; +pub use connection::ConnectionFlags; pub use cursor::Cursor; pub use statement::{Bindable, Readable, State, Statement}; -/// Open a connection to a new or existing database. +/// Open a read-write connection to a new or existing database. #[inline] pub fn open>(path: T) -> Result { Connection::open(path) } -/// Open a read-only connection to an existing database. +/// Open a connection to a database with a specific set of connection flags. #[inline] -pub fn open_readonly>(path: T) -> Result { - Connection::open_readonly(path) +pub fn open_with_flags>( + path: T, + flags: ConnectionFlags, +) -> Result { + Connection::open_with_flags(path, flags) } /// Return the version number of SQLite. From 9328fa0897907df10c81b95d292515a191651fe5 Mon Sep 17 00:00:00 2001 From: Ivan Ukhov Date: Sat, 8 Jun 2019 20:15:44 +0200 Subject: [PATCH 2/6] Add the two mutex-related flags --- src/connection.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/connection.rs b/src/connection.rs index 579e2dd..6d2d21f 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -170,6 +170,22 @@ impl ConnectionFlags { self } + /// Open the database in the serialized [threading mode][1]. + /// + /// [1]: https://www.sqlite.org/threadsafe.html + pub fn set_full_mutex(mut self) -> Self { + self.0 |= ffi::SQLITE_OPEN_FULLMUTEX; + self + } + + /// Opens the database in the multi-thread [threading mode][1]. + /// + /// [1]: https://www.sqlite.org/threadsafe.html + pub fn set_no_mutex(mut self) -> Self { + self.0 |= ffi::SQLITE_OPEN_NOMUTEX; + self + } + /// Open the database for reading only. pub fn set_read_only(mut self) -> Self { self.0 |= ffi::SQLITE_OPEN_READWRITE; From d1e9f8fd3eec1c36b392327ccd93f08656864def Mon Sep 17 00:00:00 2001 From: Ivan Ukhov Date: Sat, 8 Jun 2019 20:42:31 +0200 Subject: [PATCH 3/6] Test opening a read-only connection --- src/connection.rs | 2 +- tests/lib.rs | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/connection.rs b/src/connection.rs index 6d2d21f..b577da6 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -188,7 +188,7 @@ impl ConnectionFlags { /// Open the database for reading only. pub fn set_read_only(mut self) -> Self { - self.0 |= ffi::SQLITE_OPEN_READWRITE; + self.0 |= ffi::SQLITE_OPEN_READONLY; self } diff --git a/tests/lib.rs b/tests/lib.rs index 0c38b03..9e46bee 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1,7 +1,7 @@ extern crate sqlite; extern crate temporary; -use sqlite::{Connection, State, Type, Value}; +use sqlite::{Connection, ConnectionFlags, State, Type, Value}; use std::path::Path; macro_rules! ok(($result:expr) => ($result.unwrap())); @@ -40,6 +40,22 @@ fn connection_iterate() { assert!(done); } +#[test] +fn connection_open_with_flags() { + use temporary::Directory; + + let directory = ok!(Directory::new("sqlite")); + let path = directory.path().join("database.sqlite3"); + setup_users(&path); + + let flags = ConnectionFlags::new().set_read_only(); + let connection = ok!(sqlite::open_with_flags(path, flags)); + match connection.execute("INSERT INTO users VALUES (2, 'Bob', NULL, NULL)") { + Err(_) => {}, + _ => unreachable!(), + } +} + #[test] fn connection_set_busy_handler() { use std::thread; From 039bf4c67e83a5b5c75afb790738daf471ac4c98 Mon Sep 17 00:00:00 2001 From: Ivan Ukhov Date: Sun, 9 Jun 2019 07:15:34 +0200 Subject: [PATCH 4/6] Rename ConnectionFlags to OpenFlags --- src/connection.rs | 12 ++++++------ src/lib.rs | 9 +++------ tests/lib.rs | 6 +++--- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/connection.rs b/src/connection.rs index b577da6..3c12d09 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -14,18 +14,18 @@ pub struct Connection { /// A set of connection flags. #[derive(Clone, Copy, Debug)] -pub struct ConnectionFlags(c_int); +pub struct OpenFlags(c_int); unsafe impl Send for Connection {} impl Connection { /// Open a read-write connection to a new or existing database. pub fn open>(path: T) -> Result { - Connection::open_with_flags(path, ConnectionFlags::new().set_create().set_read_write()) + Connection::open_with_flags(path, OpenFlags::new().set_create().set_read_write()) } - /// Open a database connection with a specific set of connection flags. - pub fn open_with_flags>(path: T, flags: ConnectionFlags) -> Result { + /// Open a database connection with a specific set of flags. + pub fn open_with_flags>(path: T, flags: OpenFlags) -> Result { let mut raw = 0 as *mut _; unsafe { ok!(ffi::sqlite3_open_v2( @@ -157,11 +157,11 @@ impl Drop for Connection { } } -impl ConnectionFlags { +impl OpenFlags { /// Create a set of connection flags. #[inline] pub fn new() -> Self { - ConnectionFlags(0) + OpenFlags(0) } /// Create the database if it does not already exist. diff --git a/src/lib.rs b/src/lib.rs index 70b9dd6..fd3ebbf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -294,7 +294,7 @@ mod cursor; mod statement; pub use connection::Connection; -pub use connection::ConnectionFlags; +pub use connection::OpenFlags; pub use cursor::Cursor; pub use statement::{Bindable, Readable, State, Statement}; @@ -304,12 +304,9 @@ pub fn open>(path: T) -> Result { Connection::open(path) } -/// Open a connection to a database with a specific set of connection flags. +/// Open a connection to a database with a specific set of flags. #[inline] -pub fn open_with_flags>( - path: T, - flags: ConnectionFlags, -) -> Result { +pub fn open_with_flags>(path: T, flags: OpenFlags) -> Result { Connection::open_with_flags(path, flags) } diff --git a/tests/lib.rs b/tests/lib.rs index 9e46bee..212edfa 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1,7 +1,7 @@ extern crate sqlite; extern crate temporary; -use sqlite::{Connection, ConnectionFlags, State, Type, Value}; +use sqlite::{Connection, OpenFlags, State, Type, Value}; use std::path::Path; macro_rules! ok(($result:expr) => ($result.unwrap())); @@ -48,10 +48,10 @@ fn connection_open_with_flags() { let path = directory.path().join("database.sqlite3"); setup_users(&path); - let flags = ConnectionFlags::new().set_read_only(); + let flags = OpenFlags::new().set_read_only(); let connection = ok!(sqlite::open_with_flags(path, flags)); match connection.execute("INSERT INTO users VALUES (2, 'Bob', NULL, NULL)") { - Err(_) => {}, + Err(_) => {} _ => unreachable!(), } } From 64c2c7f2df5f54c40adbd077261ef30fdad2e9ef Mon Sep 17 00:00:00 2001 From: Ivan Ukhov Date: Sun, 9 Jun 2019 07:35:27 +0200 Subject: [PATCH 5/6] Do not re-export open_with_flags --- src/lib.rs | 6 ------ tests/lib.rs | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index fd3ebbf..662cc08 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -304,12 +304,6 @@ pub fn open>(path: T) -> Result { Connection::open(path) } -/// Open a connection to a database with a specific set of flags. -#[inline] -pub fn open_with_flags>(path: T, flags: OpenFlags) -> Result { - Connection::open_with_flags(path, flags) -} - /// Return the version number of SQLite. /// /// For instance, the version `3.8.11.1` corresponds to the integer `3008011`. diff --git a/tests/lib.rs b/tests/lib.rs index 212edfa..28827d5 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -49,7 +49,7 @@ fn connection_open_with_flags() { setup_users(&path); let flags = OpenFlags::new().set_read_only(); - let connection = ok!(sqlite::open_with_flags(path, flags)); + let connection = ok!(Connection::open_with_flags(path, flags)); match connection.execute("INSERT INTO users VALUES (2, 'Bob', NULL, NULL)") { Err(_) => {} _ => unreachable!(), From b9747f216dfa4dae3c4ad2a368d204ee8404d920 Mon Sep 17 00:00:00 2001 From: Ivan Ukhov Date: Mon, 10 Jun 2019 20:29:34 +0200 Subject: [PATCH 6/6] Adjust a few descriptions --- src/connection.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/connection.rs b/src/connection.rs index 3c12d09..d0798d2 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -12,7 +12,7 @@ pub struct Connection { phantom: PhantomData, } -/// A set of connection flags. +/// Flags for opening a database connection. #[derive(Clone, Copy, Debug)] pub struct OpenFlags(c_int); @@ -24,7 +24,7 @@ impl Connection { Connection::open_with_flags(path, OpenFlags::new().set_create().set_read_write()) } - /// Open a database connection with a specific set of flags. + /// Open a database connection with specific flags. pub fn open_with_flags>(path: T, flags: OpenFlags) -> Result { let mut raw = 0 as *mut _; unsafe { @@ -158,7 +158,7 @@ impl Drop for Connection { } impl OpenFlags { - /// Create a set of connection flags. + /// Create flags for opening a database connection. #[inline] pub fn new() -> Self { OpenFlags(0)