From 359ec914d2435aac1c10410001891dfbfbdbe985 Mon Sep 17 00:00:00 2001 From: gwenn Date: Sat, 4 Feb 2017 11:01:38 +0100 Subject: [PATCH] Expose limits (#220) --- .travis.yml | 4 ++- Cargo.toml | 1 + appveyor.yml | 4 +-- libsqlite3-sys/src/lib.rs | 36 ++++++++++++++++++-- src/lib.rs | 1 + src/limits.rs | 70 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 110 insertions(+), 6 deletions(-) create mode 100644 src/limits.rs diff --git a/.travis.yml b/.travis.yml index 195a813..dc094e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,7 @@ script: - cargo test - cargo test --features backup - cargo test --features blob + - cargo test --features limits - cargo test --features load_extension - cargo test --features trace - cargo test --features functions @@ -14,4 +15,5 @@ script: - cargo test --features serde_json - cargo test --features bundled - cargo test --features "backup blob chrono functions load_extension serde_json trace" - - cargo test --features "backup blob chrono functions load_extension serde_json trace bundled" + - cargo test --features "backup blob chrono functions limits load_extension serde_json trace" + - cargo test --features "backup blob chrono functions limits load_extension serde_json trace bundled" diff --git a/Cargo.toml b/Cargo.toml index 1ef6c10..2696c1e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ blob = [] functions = [] trace = [] bundled = ["libsqlite3-sys/bundled"] +limits = [] [dependencies] time = "0.1.0" diff --git a/appveyor.yml b/appveyor.yml index 566b9ee..0ca27a4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,8 +17,8 @@ build: false test_script: - cargo test --lib --verbose - cargo test --lib --verbose --features bundled - - cargo test --lib --features "backup blob chrono functions load_extension serde_json trace" - - cargo test --lib --features "backup blob chrono functions load_extension serde_json trace bundled" + - cargo test --lib --features "backup blob chrono functions limits load_extension serde_json trace" + - cargo test --lib --features "backup blob chrono functions limits load_extension serde_json trace bundled" cache: - C:\Users\appveyor\.cargo diff --git a/libsqlite3-sys/src/lib.rs b/libsqlite3-sys/src/lib.rs index fb2e110..85c3b64 100644 --- a/libsqlite3-sys/src/lib.rs +++ b/libsqlite3-sys/src/lib.rs @@ -28,6 +28,36 @@ pub fn SQLITE_TRANSIENT() -> sqlite3_destructor_type { Some(unsafe { mem::transmute(-1isize) }) } -pub const SQLITE_CONFIG_LOG : c_int = 16; -pub const SQLITE_UTF8 : c_int = 1; -pub const SQLITE_DETERMINISTIC : c_int = 0x800; +pub const SQLITE_CONFIG_LOG: c_int = 16; +pub const SQLITE_UTF8: c_int = 1; +pub const SQLITE_DETERMINISTIC: c_int = 0x800; + +/// Run-Time Limit Categories +#[repr(C)] +pub enum Limit { + /// The maximum size of any string or BLOB or table row, in bytes. + SQLITE_LIMIT_LENGTH = 0, + /// The maximum length of an SQL statement, in bytes. + SQLITE_LIMIT_SQL_LENGTH = 1, + /// The maximum number of columns in a table definition or in the result set of a SELECT + /// or the maximum number of columns in an index or in an ORDER BY or GROUP BY clause. + SQLITE_LIMIT_COLUMN = 2, + /// The maximum depth of the parse tree on any expression. + SQLITE_LIMIT_EXPR_DEPTH = 3, + /// The maximum number of terms in a compound SELECT statement. + SQLITE_LIMIT_COMPOUND_SELECT = 4, + /// The maximum number of instructions in a virtual machine program used to implement an SQL statement. + SQLITE_LIMIT_VDBE_OP = 5, + /// The maximum number of arguments on a function. + SQLITE_LIMIT_FUNCTION_ARG = 6, + /// The maximum number of attached databases. + SQLITE_LIMIT_ATTACHED = 7, + /// The maximum length of the pattern argument to the LIKE or GLOB operators. + SQLITE_LIMIT_LIKE_PATTERN_LENGTH = 8, + /// The maximum index number of any parameter in an SQL statement. + SQLITE_LIMIT_VARIABLE_NUMBER = 9, + /// The maximum depth of recursion for triggers. + SQLITE_LIMIT_TRIGGER_DEPTH = 10, + /// The maximum number of auxiliary worker threads that a single prepared statement may start. + SQLITE_LIMIT_WORKER_THREADS = 11, +} diff --git a/src/lib.rs b/src/lib.rs index 1a10816..ced4487 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -105,6 +105,7 @@ mod raw_statement; #[cfg(feature = "backup")]pub mod backup; #[cfg(feature = "functions")]pub mod functions; #[cfg(feature = "blob")]pub mod blob; +#[cfg(feature = "limits")]pub mod limits; // Number of cached prepared statements we'll hold on to. const STATEMENT_CACHE_DEFAULT_CAPACITY: usize = 16; diff --git a/src/limits.rs b/src/limits.rs new file mode 100644 index 0000000..5bb9f67 --- /dev/null +++ b/src/limits.rs @@ -0,0 +1,70 @@ +//! Run-Time Limits + +use libc::c_int; + +use ffi; +pub use ffi::Limit; + +use Connection; + +impl Connection { + /// Returns the current value of a limit. + pub fn get_limit(&self, limit: Limit) -> i32 { + let c = self.db.borrow(); + unsafe { + ffi::sqlite3_limit(c.db(), limit as c_int, -1) + } + } + /// Changes the limit to `new_val`. + /// And returns the prior value of the limit. + pub fn set_limit(&self, limit: Limit, new_val: i32) -> i32 { + let c = self.db.borrow_mut(); + unsafe { + ffi::sqlite3_limit(c.db(), limit as c_int, new_val) + } + } +} + +#[cfg(test)] +mod test { + use ffi::Limit; + use Connection; + + #[test] + fn test_limit() { + let db = Connection::open_in_memory().unwrap(); + assert_eq!(2147483645, db.set_limit(Limit::SQLITE_LIMIT_LENGTH, 1024)); + assert_eq!(1024, db.get_limit(Limit::SQLITE_LIMIT_LENGTH)); + + db.set_limit(Limit::SQLITE_LIMIT_SQL_LENGTH, 1024); + assert_eq!(1024, db.get_limit(Limit::SQLITE_LIMIT_SQL_LENGTH)); + + assert_eq!(2000, db.set_limit(Limit::SQLITE_LIMIT_COLUMN, 64)); + assert_eq!(64, db.get_limit(Limit::SQLITE_LIMIT_COLUMN)); + + assert_eq!(1000, db.set_limit(Limit::SQLITE_LIMIT_EXPR_DEPTH, 256)); + assert_eq!(256, db.get_limit(Limit::SQLITE_LIMIT_EXPR_DEPTH)); + + assert_eq!(500, db.set_limit(Limit::SQLITE_LIMIT_COMPOUND_SELECT, 32)); + assert_eq!(32, db.get_limit(Limit::SQLITE_LIMIT_COMPOUND_SELECT)); + + assert_eq!(127, db.set_limit(Limit::SQLITE_LIMIT_FUNCTION_ARG, 32)); + assert_eq!(32, db.get_limit(Limit::SQLITE_LIMIT_FUNCTION_ARG)); + + assert_eq!(10, db.set_limit(Limit::SQLITE_LIMIT_ATTACHED, 2)); + assert_eq!(2, db.get_limit(Limit::SQLITE_LIMIT_ATTACHED)); + + assert_eq!(50000, db.set_limit(Limit::SQLITE_LIMIT_LIKE_PATTERN_LENGTH, 128)); + assert_eq!(128, db.get_limit(Limit::SQLITE_LIMIT_LIKE_PATTERN_LENGTH)); + + db.set_limit(Limit::SQLITE_LIMIT_VARIABLE_NUMBER, 99); + assert_eq!(99, db.get_limit(Limit::SQLITE_LIMIT_VARIABLE_NUMBER)); + + assert_eq!(1000, db.set_limit(Limit::SQLITE_LIMIT_TRIGGER_DEPTH, 32)); + assert_eq!(32, db.get_limit(Limit::SQLITE_LIMIT_TRIGGER_DEPTH)); + + assert_eq!(0, db.set_limit(Limit::SQLITE_LIMIT_WORKER_THREADS, 2)); + assert_eq!(2, db.get_limit(Limit::SQLITE_LIMIT_WORKER_THREADS)); + } +} + \ No newline at end of file