feat(sqlite): enable configuration of journal_mode and foreign_keys and default to WAL and ON

This commit is contained in:
Ryan Leckey 2020-07-02 23:18:14 -07:00
parent 20229ea2b9
commit 222cd688a4
5 changed files with 96 additions and 17 deletions

View File

@ -43,15 +43,17 @@ impl FromStr for MySqlSslMode {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Error> {
Ok(match s {
"DISABLED" => MySqlSslMode::Disabled,
"PREFERRED" => MySqlSslMode::Preferred,
"REQUIRED" => MySqlSslMode::Required,
"VERIFY_CA" => MySqlSslMode::VerifyCa,
"VERIFY_IDENTITY" => MySqlSslMode::VerifyIdentity,
Ok(match &*s.to_ascii_lowercase() {
"disabled" => MySqlSslMode::Disabled,
"preferred" => MySqlSslMode::Preferred,
"required" => MySqlSslMode::Required,
"verify_ca" => MySqlSslMode::VerifyCa,
"verify_identity" => MySqlSslMode::VerifyIdentity,
_ => {
return Err(err_protocol!("unknown SSL mode value: {:?}", s));
return Err(Error::ParseConnectOptions(
format!("unknown value {:?} for `ssl_mode`", s).into(),
));
}
})
}

View File

@ -43,7 +43,7 @@ impl FromStr for PgSslMode {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Error> {
Ok(match s {
Ok(match &*s.to_ascii_lowercase() {
"disable" => PgSslMode::Disable,
"allow" => PgSslMode::Allow,
"prefer" => PgSslMode::Prefer,
@ -52,7 +52,9 @@ impl FromStr for PgSslMode {
"verify-full" => PgSslMode::VerifyFull,
_ => {
return Err(err_protocol!("unknown SSL mode value: {:?}", s));
return Err(Error::ParseConnectOptions(
format!("unknown value {:?} for `ssl_mode`", s).into(),
));
}
})
}

View File

@ -10,6 +10,7 @@ use crate::common::StatementCache;
use crate::connection::{Connect, Connection};
use crate::error::Error;
use crate::ext::ustr::UStr;
use crate::executor::Executor;
use crate::sqlite::connection::establish::establish;
use crate::sqlite::statement::{SqliteStatement, StatementWorker};
use crate::sqlite::{Sqlite, SqliteConnectOptions};
@ -100,9 +101,16 @@ impl Connect for SqliteConnection {
#[inline]
fn connect_with(options: &Self::Options) -> BoxFuture<'_, Result<Self, Error>> {
Box::pin(async move {
let conn = establish(options).await?;
let mut conn = establish(options).await?;
// TODO: Apply any connection options once we have them defined
// send an initial sql statement comprised of options
let init = format!(
"PRAGMA journal_mode = {}; PRAGMA foreign_keys = {};",
options.journal_mode.as_str(),
if options.foreign_keys { "ON" } else { "OFF" }
);
conn.execute(&*init).await?;
Ok(conn)
})

View File

@ -1,15 +1,67 @@
use std::path::PathBuf;
use std::str::FromStr;
use crate::error::BoxDynError;
use crate::error::{BoxDynError, Error};
// TODO: Look at go-sqlite for option ideas
// TODO: journal_mode
#[derive(Debug)]
pub enum SqliteJournalMode {
Delete,
Truncate,
Persist,
Memory,
Wal,
Off,
}
impl SqliteJournalMode {
pub(crate) fn as_str(&self) -> &'static str {
match self {
SqliteJournalMode::Delete => "DELETE",
SqliteJournalMode::Truncate => "TRUNCATE",
SqliteJournalMode::Persist => "PERSIST",
SqliteJournalMode::Memory => "MEMORY",
SqliteJournalMode::Wal => "WAL",
SqliteJournalMode::Off => "OFF",
}
}
}
impl Default for SqliteJournalMode {
fn default() -> Self {
SqliteJournalMode::Wal
}
}
impl FromStr for SqliteJournalMode {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Error> {
Ok(match &*s.to_ascii_lowercase() {
"delete" => SqliteJournalMode::Delete,
"truncate" => SqliteJournalMode::Truncate,
"persist" => SqliteJournalMode::Persist,
"memory" => SqliteJournalMode::Memory,
"wal" => SqliteJournalMode::Wal,
"off" => SqliteJournalMode::Off,
_ => {
return Err(Error::ParseConnectOptions(
format!("unknown value {:?} for `journal_mode`", s).into(),
));
}
})
}
}
/// Options and flags which can be used to configure a SQLite connection.
pub struct SqliteConnectOptions {
pub(crate) filename: PathBuf,
pub(crate) in_memory: bool,
pub(crate) journal_mode: SqliteJournalMode,
pub(crate) foreign_keys: bool,
pub(crate) statement_cache_capacity: usize,
}
@ -24,10 +76,29 @@ impl SqliteConnectOptions {
Self {
filename: PathBuf::from(":memory:"),
in_memory: false,
foreign_keys: true,
statement_cache_capacity: 100,
journal_mode: SqliteJournalMode::Wal,
}
}
/// Set the enforcement of [foreign key constriants](https://www.sqlite.org/pragma.html#pragma_foreign_keys).
///
/// By default, this is enabled.
pub fn foreign_keys(mut self, on: bool) -> Self {
self.foreign_keys = on;
self
}
/// Sets the [journal mode](https://www.sqlite.org/pragma.html#pragma_journal_mode) for the database connection.
///
/// The default journal mode is WAL. For most use cases this can be significantly faster but
/// there are [disadvantages](https://www.sqlite.org/wal.html).
pub fn journal_mode(mut self, mode: SqliteJournalMode) -> Self {
self.journal_mode = mode;
self
}
/// Sets the capacity of the connection's statement cache in a number of stored
/// distinct statements. Caching is handled using LRU, meaning when the
/// amount of queries hits the defined limit, the oldest statement will get
@ -44,11 +115,7 @@ impl FromStr for SqliteConnectOptions {
type Err = BoxDynError;
fn from_str(mut s: &str) -> Result<Self, Self::Err> {
let mut options = Self {
filename: PathBuf::new(),
in_memory: false,
statement_cache_capacity: 100,
};
let mut options = Self::new();
// remove scheme
s = s

Binary file not shown.