Skip to main content

OpenOptions

Struct OpenOptions 

Source
pub struct OpenOptions { /* private fields */ }
Expand description

Opening an SQLite connection.

When using new by default only the extended_result_codes option is set. There is currently no known reason to disable the default options, but if you really want to you can use empty instead.

§Thread safety

To support Connection::into_send and similar methods, either no_mutex or full_mutex has to be set.

Typically you should just set no_mutex, which will allow you to send database objects across threads but still require synchronization.

When full_mutex is set, each individual database object can be used without synchronization but might block with respect to other threads accessing the database simultaenously.

By default a Connection is not not be thread safe. And therefore it does not implement Send. Because thread safety is a configuration option in sqlite you have to make use of the unsafe Connection::into_send and Statement::into_send functions to convert the objects into ones which can be sent across threads.

§Asynchronous usage

A SQLite connection is synchronous. There is no getting away from that. What that means for use in asynchronous contexts is that you must make use of mechanisms such as Tokio’s spawn_blocking to ensure any database operations are run on dedicated worker threads.

For examples on how to do this, see into_send.

§Database locking

Certain operations over the database require that it is exclusively held. This can manifest itself as errors when performing certain operations like dropping a table that has a prepared statement associated with it.

use sqll::{Connection, Code};

let c = Connection::open_in_memory()?;

c.execute(r#"
   CREATE TABLE users (name TEXT);

   INSERT INTO users (name) VALUES ('Alice'), ('Bob');
"#)?;

let mut stmt = c.prepare("SELECT name FROM users")?;
assert!(stmt.step()?.is_row());

let e = c.execute("DROP TABLE users").unwrap_err();
assert_eq!(e.code(), Code::LOCKED);

drop(stmt);
c.execute("DROP TABLE users")?;

§Using sqlite3_config is not supported

The sqlite3_config function is a way that allows for users of sqlite to globally configure the library. Any use of this mechanism is out of scope of this library. In particular it can be used to forcibly disable the effect of full_mutex by setting the the SQLITE_CONFIG_SINGLETHREAD option.

We cannot guard against this. Any use of the sqlite3_config mechanism is considered to be the responsibility of the user of this library.

Implementations§

Source§

impl OpenOptions

Source

pub fn new() -> Self

Create flags for opening a database connection with default safe options.

§Examples
use sqll::OpenOptions;

let c = OpenOptions::new()
    .read_write()
    .create()
    .open_in_memory()?;
Source

pub fn empty() -> Self

Create flags for opening a database connection with no options set.

Normally you want to use new unless you have to exclude the default options for some reason.

§Examples
use sqll::OpenOptions;

let c = OpenOptions::empty()
    .read_write()
    .create()
    .open_in_memory()?;
Source

pub fn read_only(&mut self) -> &mut Self

The database is opened in read-only mode. If the database does not already exist, an error is returned.

§Examples
use sqll::OpenOptions;

let c = OpenOptions::new()
    .read_only()
    .open_in_memory()?;

assert!(c.database_read_only(c"main")?);
Source

pub fn read_write(&mut self) -> &mut Self

The database is opened for reading and writing if possible, or reading only if the file is write protected by the operating system.

In either case the database must already exist, otherwise an error is returned. For historical reasons, if opening in read-write mode fails due to OS-level permissions, an attempt is made to open it in read-only mode. Connection::database_read_only can be used to determine whether the database is actually read-write.

§Examples
use sqll::OpenOptions;

let c = OpenOptions::new()
    .read_write()
    .open_in_memory()?;

assert!(!c.database_read_only(c"main")?);
Source

pub fn create(&mut self) -> &mut Self

The database is opened for reading and writing, and is created if it does not already exist.

§Errors

Note that a mode option like read_write must be set, otherwise this will cause an error when opening.

use sqll::{OpenOptions, Code};

let e = OpenOptions::new()
    .create()
    .open_in_memory()
    .unwrap_err();

assert_eq!(e.code(), Code::MISUSE);

let c = OpenOptions::new()
    .create()
    .read_write()
    .open_in_memory()?;
§Examples
use sqll::OpenOptions;

let c = OpenOptions::new()
    .read_write()
    .create()
    .open_in_memory()?;

assert!(!c.database_read_only(c"main")?);
Source

pub fn uri(&mut self) -> &mut Self

The filename can be interpreted as a URI if this flag is set.

§Examples
use sqll::OpenOptions;

let c = OpenOptions::new()
    .read_write()
    .create()
    .uri()
    .open("file:memorydb?mode=memory")?;
Source

pub fn memory(&mut self) -> &mut Self

The database will be opened as an in-memory database. The database is named by the “filename” argument for the purposes of cache-sharing, if shared cache mode is enabled, but the “filename” is otherwise ignored.

§Examples
use sqll::{OpenOptions, Code};

let c1 = OpenOptions::new()
    .read_write()
    .memory()
    .open("database")?;

let c2 = OpenOptions::new()
    .read_write()
    .memory()
    .open("database")?;
Source

pub fn no_mutex(&mut self) -> &mut Self

The new database connection will use the “multi-thread” threading mode. This means that separate threads are allowed to use SQLite at the same time, as long as each thread is using a different database connection.

§Examples
use sqll::OpenOptions;

let c = OpenOptions::new()
    .read_write()
    .create()
    .no_mutex()
    .open_in_memory()?;
Source

pub fn full_mutex(&mut self) -> &mut Self

The new database connection will use the “serialized” threading mode. This means the multiple threads can safely attempt to use the same database connection at the same time. Mutexes will block any actual concurrency, but in this mode there is no harm in trying.

§Examples
use sqll::OpenOptions;

let c = OpenOptions::new()
    .full_mutex()
    .read_write()
    .create()
    .open_in_memory()?;
Source

pub fn shared_cache(&mut self) -> &mut Self

The database is opened with shared cache enabled, overriding the default shared cache setting provided. The use of shared cache mode is discouraged and hence shared cache capabilities may be omitted from many builds of SQLite. In such cases, this option is a no-op.

Source

pub fn private_cache(&mut self) -> &mut Self

The database is opened with shared cache disabled, overriding the default shared cache setting provided.

Source

pub fn no_follow(&mut self) -> &mut Self

The database filename is not allowed to contain a symbolic link.

Source

pub fn extended_result_codes(&mut self) -> &mut Self

The database connection comes up in “extended result code mode”. In other words, the database behaves as if Connection::extended_result_codes were called on the database connection as soon as the connection is created. In addition to setting the extended result code mode.

§Examples
use sqll::{OpenOptions, Code};

let mut c = unsafe {
    OpenOptions::empty()
        .extended_result_codes()
        .create()
        .read_write()
        .open_in_memory()?
};

let e = c.execute("
    CREATE TABLE users (name TEXT);
    CREATE UNIQUE INDEX idx_users_name ON users (name);

    INSERT INTO users VALUES ('Bob');
");

let e = c.execute("INSERT INTO users VALUES ('Bob')").unwrap_err();
assert_eq!(e.code(), Code::CONSTRAINT_UNIQUE);
assert_eq!(c.error_message(), "UNIQUE constraint failed: users.name");

c.extended_result_codes(false)?;
let e = c.execute("INSERT INTO users VALUES ('Bob')").unwrap_err();
assert_eq!(e.code(), Code::CONSTRAINT);
assert_eq!(c.error_message(), "UNIQUE constraint failed: users.name");
Source

pub fn open(&self, path: impl AsRef<Path>) -> Result<Connection>

Available on crate feature std only.

Open a database to the given path.

Note that it is possible to open an in-memory database by passing ":memory:" here, this call might require allocating depending on the platform, so it should be avoided in favor of using open_in_memory. To avoid allocating for regular paths, you can use open_c_str, however you are responsible for ensuring the c-string is a valid path.

Source

pub fn open_c_str(&self, name: &CStr) -> Result<Connection>

Open a database connection with a raw c-string.

This can be used to open in-memory databases by passing c":memory:" or a regular open call with a filesystem path like c"/path/to/database.sql".

Source

pub fn open_in_memory(&self) -> Result<Connection>

Open an in-memory database.

Trait Implementations§

Source§

impl Clone for OpenOptions

Source§

fn clone(&self) -> OpenOptions

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for OpenOptions

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Copy for OpenOptions

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.