Merge pull request #475 from gwenn/db-config

Support for sqlite3_db_config #468
This commit is contained in:
gwenn 2019-02-08 21:38:01 +01:00 committed by GitHub
commit 7c5bfb7cc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 99 additions and 9 deletions

88
src/config.rs Normal file
View File

@ -0,0 +1,88 @@
//! Configure database connections
use std::os::raw::c_int;
use crate::ffi;
use crate::{Connection, Result};
/// Database Connection Configuration Options
#[repr(i32)]
#[allow(non_snake_case, non_camel_case_types)]
pub enum DbConfig {
//SQLITE_DBCONFIG_MAINDBNAME = 1000, /* const char* */
//SQLITE_DBCONFIG_LOOKASIDE = 1001, /* void* int int */
SQLITE_DBCONFIG_ENABLE_FKEY = 1002,
SQLITE_DBCONFIG_ENABLE_TRIGGER = 1003,
SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER = 1004, // 3.12.0
//SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION = 1005,
SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE = 1006,
SQLITE_DBCONFIG_ENABLE_QPSG = 1007, // 3.20.0
SQLITE_DBCONFIG_TRIGGER_EQP = 1008,
//SQLITE_DBCONFIG_RESET_DATABASE = 1009,
SQLITE_DBCONFIG_DEFENSIVE = 1010,
}
impl Connection {
/// Returns the current value of a `config`.
///
/// - SQLITE_DBCONFIG_ENABLE_FKEY: return `false` or `true` to indicate whether FK enforcement is off or on
/// - SQLITE_DBCONFIG_ENABLE_TRIGGER: return `false` or `true` to indicate whether triggers are disabled or enabled
/// - SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER: return `false` or `true` to indicate whether fts3_tokenizer are disabled or enabled
/// - SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE: return `false` to indicate checkpoints-on-close are not disabled or `true` if they are
/// - SQLITE_DBCONFIG_ENABLE_QPSG: return `false` or `true` to indicate whether the QPSG is disabled or enabled
/// - SQLITE_DBCONFIG_TRIGGER_EQP: return `false` to indicate output-for-trigger are not disabled or `true` if it is
pub fn db_config(&self, config: DbConfig) -> Result<bool> {
let c = self.db.borrow();
unsafe {
let mut val = 0;
check!(ffi::sqlite3_db_config(
c.db(),
config as c_int,
-1,
&mut val
));
Ok(val != 0)
}
}
/// Make configuration changes to a database connection
///
/// - SQLITE_DBCONFIG_ENABLE_FKEY: `false` to disable FK enforcement, `true` to enable FK enforcement
/// - SQLITE_DBCONFIG_ENABLE_TRIGGER: `false` to disable triggers, `true` to enable triggers
/// - SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER: `false` to disable fts3_tokenizer(), `true` to enable fts3_tokenizer()
/// - SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE: `false` (the default) to enable checkpoints-on-close, `true` to disable them
/// - SQLITE_DBCONFIG_ENABLE_QPSG: `false` to disable the QPSG, `true` to enable QPSG
/// - SQLITE_DBCONFIG_TRIGGER_EQP: `false` to disable output for trigger programs, `true` to enable it
pub fn set_db_config(&self, config: DbConfig, new_val: bool) -> Result<bool> {
let c = self.db.borrow_mut();
unsafe {
let mut val = 0;
check!(ffi::sqlite3_db_config(
c.db(),
config as c_int,
if new_val { 1 } else { 0 },
&mut val
));
Ok(val != 0)
}
}
}
#[cfg(test)]
mod test {
use super::DbConfig;
use crate::Connection;
#[test]
fn test_db_config() {
let db = Connection::open_in_memory().unwrap();
let opposite = !db.db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_FKEY).unwrap();
assert_eq!(db.set_db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_FKEY, opposite), Ok(opposite));
assert_eq!(db.db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_FKEY), Ok(opposite));
let opposite = !db.db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_TRIGGER).unwrap();
assert_eq!(db.set_db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_TRIGGER, opposite), Ok(opposite));
assert_eq!(db.db_config(DbConfig::SQLITE_DBCONFIG_ENABLE_TRIGGER), Ok(opposite));
}
}

View File

@ -98,16 +98,18 @@ pub use crate::transaction::{DropBehavior, Savepoint, Transaction, TransactionBe
pub use crate::types::ToSql; pub use crate::types::ToSql;
pub use crate::version::*; pub use crate::version::*;
#[macro_use]
mod error;
#[cfg(feature = "backup")] #[cfg(feature = "backup")]
pub mod backup; pub mod backup;
#[cfg(feature = "blob")] #[cfg(feature = "blob")]
pub mod blob; pub mod blob;
mod busy; mod busy;
mod cache; mod cache;
pub mod config;
#[cfg(any(feature = "functions", feature = "vtab"))] #[cfg(any(feature = "functions", feature = "vtab"))]
mod context; mod context;
#[macro_use]
mod error;
#[cfg(feature = "functions")] #[cfg(feature = "functions")]
pub mod functions; pub mod functions;
#[cfg(feature = "hooks")] #[cfg(feature = "hooks")]

View File

@ -139,11 +139,11 @@ impl<'a, 'stmt> Row<'a, 'stmt> {
/// Panics if calling `row.get_checked(idx)` would return an error, /// Panics if calling `row.get_checked(idx)` would return an error,
/// including: /// including:
/// ///
/// * If the underlying SQLite column type is not a valid type as a /// * If the underlying SQLite column type is not a valid type as a
/// source for `T` /// source for `T`
/// * If the underlying SQLite integral value is outside the range /// * If the underlying SQLite integral value is outside the range
/// representable by `T` /// representable by `T`
/// * If `idx` is outside the range of columns in the returned query /// * If `idx` is outside the range of columns in the returned query
pub fn get<I: RowIndex, T: FromSql>(&self, idx: I) -> T { pub fn get<I: RowIndex, T: FromSql>(&self, idx: I) -> T {
self.get_checked(idx).unwrap() self.get_checked(idx).unwrap()
} }
@ -215,8 +215,8 @@ impl<'a, 'stmt> Row<'a, 'stmt> {
/// Panics if calling `row.get_raw_checked(idx)` would return an error, /// Panics if calling `row.get_raw_checked(idx)` would return an error,
/// including: /// including:
/// ///
/// * If `idx` is outside the range of columns in the returned query. /// * If `idx` is outside the range of columns in the returned query.
/// * If `idx` is not a valid column name for this row. /// * If `idx` is not a valid column name for this row.
pub fn get_raw<I: RowIndex>(&self, idx: I) -> ValueRef<'a> { pub fn get_raw<I: RowIndex>(&self, idx: I) -> ValueRef<'a> {
self.get_raw_checked(idx).unwrap() self.get_raw_checked(idx).unwrap()
} }