Skip to content

Commit

Permalink
feat(sqlite): enable configuration of journal_mode and foreign_keys a…
Browse files Browse the repository at this point in the history
…nd default to WAL and ON
  • Loading branch information
mehcode committed Jul 3, 2020
1 parent 20229ea commit 222cd68
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 17 deletions.
16 changes: 9 additions & 7 deletions sqlx-core/src/mysql/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
));
}
})
}
Expand Down
6 changes: 4 additions & 2 deletions sqlx-core/src/postgres/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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(),
));
}
})
}
Expand Down
12 changes: 10 additions & 2 deletions sqlx-core/src/sqlite/connection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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)
})
Expand Down
79 changes: 73 additions & 6 deletions sqlx-core/src/sqlite/options.rs
Original file line number Diff line number Diff line change
@@ -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,
}

Expand All @@ -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
Expand All @@ -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
Expand Down
Binary file modified tests/sqlite/sqlite.db
Binary file not shown.

0 comments on commit 222cd68

Please sign in to comment.