diff options
Diffstat (limited to 'src/cache.rs')
-rw-r--r-- | src/cache.rs | 150 |
1 files changed, 70 insertions, 80 deletions
diff --git a/src/cache.rs b/src/cache.rs index 7dc9d23..c80a708 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -11,20 +11,20 @@ impl Connection { /// Prepare a SQL statement for execution, returning a previously prepared /// (but not currently in-use) statement if one is available. The /// returned statement will be cached for reuse by future calls to - /// `prepare_cached` once it is dropped. + /// [`prepare_cached`](Connection::prepare_cached) once it is dropped. /// /// ```rust,no_run /// # use rusqlite::{Connection, Result}; /// fn insert_new_people(conn: &Connection) -> Result<()> { /// { /// let mut stmt = conn.prepare_cached("INSERT INTO People (name) VALUES (?)")?; - /// stmt.execute(&["Joe Smith"])?; + /// stmt.execute(["Joe Smith"])?; /// } /// { /// // This will return the same underlying SQLite statement handle without /// // having to prepare it again. /// let mut stmt = conn.prepare_cached("INSERT INTO People (name) VALUES (?)")?; - /// stmt.execute(&["Bob Jones"])?; + /// stmt.execute(["Bob Jones"])?; /// } /// Ok(()) /// } @@ -34,6 +34,7 @@ impl Connection { /// /// Will return `Err` if `sql` cannot be converted to a C-compatible string /// or if the underlying SQLite call fails. + #[inline] pub fn prepare_cached(&self, sql: &str) -> Result<CachedStatement<'_>> { self.cache.get(self, sql) } @@ -43,13 +44,15 @@ impl Connection { /// number of cached statements. If you need more, or know that you /// will not use cached statements, you /// can set the capacity manually using this method. + #[inline] pub fn set_prepared_statement_cache_capacity(&self, capacity: usize) { - self.cache.set_capacity(capacity) + self.cache.set_capacity(capacity); } /// Remove/finalize all prepared statements currently in the cache. + #[inline] pub fn flush_prepared_statement_cache(&self) { - self.cache.flush() + self.cache.flush(); } } @@ -57,10 +60,14 @@ impl Connection { // #[derive(Debug)] // FIXME: https://github.com/kyren/hashlink/pull/4 pub struct StatementCache(RefCell<LruCache<Arc<str>, RawStatement>>); +#[allow(clippy::non_send_fields_in_send_ty)] +unsafe impl Send for StatementCache {} + /// Cacheable statement. /// /// Statement will return automatically to the cache by default. -/// If you want the statement to be discarded, call `discard()` on it. +/// If you want the statement to be discarded, call +/// [`discard()`](CachedStatement::discard) on it. pub struct CachedStatement<'conn> { stmt: Option<Statement<'conn>>, cache: &'conn StatementCache, @@ -69,12 +76,14 @@ pub struct CachedStatement<'conn> { impl<'conn> Deref for CachedStatement<'conn> { type Target = Statement<'conn>; + #[inline] fn deref(&self) -> &Statement<'conn> { self.stmt.as_ref().unwrap() } } impl<'conn> DerefMut for CachedStatement<'conn> { + #[inline] fn deref_mut(&mut self) -> &mut Statement<'conn> { self.stmt.as_mut().unwrap() } @@ -82,6 +91,7 @@ impl<'conn> DerefMut for CachedStatement<'conn> { impl Drop for CachedStatement<'_> { #[allow(unused_must_use)] + #[inline] fn drop(&mut self) { if let Some(stmt) = self.stmt.take() { self.cache.cache_stmt(unsafe { stmt.into_raw() }); @@ -90,6 +100,7 @@ impl Drop for CachedStatement<'_> { } impl CachedStatement<'_> { + #[inline] fn new<'conn>(stmt: Statement<'conn>, cache: &'conn StatementCache) -> CachedStatement<'conn> { CachedStatement { stmt: Some(stmt), @@ -98,7 +109,8 @@ impl CachedStatement<'_> { } /// Discard the statement, preventing it from being returned to its - /// `Connection`'s collection of cached statements. + /// [`Connection`]'s collection of cached statements. + #[inline] pub fn discard(mut self) { self.stmt = None; } @@ -106,12 +118,14 @@ impl CachedStatement<'_> { impl StatementCache { /// Create a statement cache. + #[inline] pub fn with_capacity(capacity: usize) -> StatementCache { StatementCache(RefCell::new(LruCache::new(capacity))) } + #[inline] fn set_capacity(&self, capacity: usize) { - self.0.borrow_mut().set_capacity(capacity) + self.0.borrow_mut().set_capacity(capacity); } // Search the cache for a prepared-statement object that implements `sql`. @@ -155,16 +169,17 @@ impl StatementCache { } } + #[inline] fn flush(&self) { let mut cache = self.0.borrow_mut(); - cache.clear() + cache.clear(); } } #[cfg(test)] mod test { use super::StatementCache; - use crate::{Connection, NO_PARAMS}; + use crate::{Connection, Result}; use fallible_iterator::FallibleIterator; impl StatementCache { @@ -182,8 +197,8 @@ mod test { } #[test] - fn test_cache() { - let db = Connection::open_in_memory().unwrap(); + fn test_cache() -> Result<()> { + let db = Connection::open_in_memory()?; let cache = &db.cache; let initial_capacity = cache.capacity(); assert_eq!(0, cache.len()); @@ -191,43 +206,35 @@ mod test { let sql = "PRAGMA schema_version"; { - let mut stmt = db.prepare_cached(sql).unwrap(); + let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!( - 0, - stmt.query_row(NO_PARAMS, |r| r.get::<_, i64>(0)).unwrap() - ); + assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); } assert_eq!(1, cache.len()); { - let mut stmt = db.prepare_cached(sql).unwrap(); + let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!( - 0, - stmt.query_row(NO_PARAMS, |r| r.get::<_, i64>(0)).unwrap() - ); + assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); } assert_eq!(1, cache.len()); cache.clear(); assert_eq!(0, cache.len()); assert_eq!(initial_capacity, cache.capacity()); + Ok(()) } #[test] - fn test_set_capacity() { - let db = Connection::open_in_memory().unwrap(); + fn test_set_capacity() -> Result<()> { + let db = Connection::open_in_memory()?; let cache = &db.cache; let sql = "PRAGMA schema_version"; { - let mut stmt = db.prepare_cached(sql).unwrap(); + let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!( - 0, - stmt.query_row(NO_PARAMS, |r| r.get::<_, i64>(0)).unwrap() - ); + assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); } assert_eq!(1, cache.len()); @@ -235,64 +242,53 @@ mod test { assert_eq!(0, cache.len()); { - let mut stmt = db.prepare_cached(sql).unwrap(); + let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!( - 0, - stmt.query_row(NO_PARAMS, |r| r.get::<_, i64>(0)).unwrap() - ); + assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); } assert_eq!(0, cache.len()); db.set_prepared_statement_cache_capacity(8); { - let mut stmt = db.prepare_cached(sql).unwrap(); + let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!( - 0, - stmt.query_row(NO_PARAMS, |r| r.get::<_, i64>(0)).unwrap() - ); + assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); } assert_eq!(1, cache.len()); + Ok(()) } #[test] - fn test_discard() { - let db = Connection::open_in_memory().unwrap(); + fn test_discard() -> Result<()> { + let db = Connection::open_in_memory()?; let cache = &db.cache; let sql = "PRAGMA schema_version"; { - let mut stmt = db.prepare_cached(sql).unwrap(); + let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!( - 0, - stmt.query_row(NO_PARAMS, |r| r.get::<_, i64>(0)).unwrap() - ); + assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); stmt.discard(); } assert_eq!(0, cache.len()); + Ok(()) } #[test] - fn test_ddl() { - let db = Connection::open_in_memory().unwrap(); + fn test_ddl() -> Result<()> { + let db = Connection::open_in_memory()?; db.execute_batch( r#" CREATE TABLE foo (x INT); INSERT INTO foo VALUES (1); "#, - ) - .unwrap(); + )?; let sql = "SELECT * FROM foo"; { - let mut stmt = db.prepare_cached(sql).unwrap(); - assert_eq!( - Ok(Some(1i32)), - stmt.query(NO_PARAMS).unwrap().map(|r| r.get(0)).next() - ); + let mut stmt = db.prepare_cached(sql)?; + assert_eq!(Ok(Some(1i32)), stmt.query([])?.map(|r| r.get(0)).next()); } db.execute_batch( @@ -300,61 +296,55 @@ mod test { ALTER TABLE foo ADD COLUMN y INT; UPDATE foo SET y = 2; "#, - ) - .unwrap(); + )?; { - let mut stmt = db.prepare_cached(sql).unwrap(); + let mut stmt = db.prepare_cached(sql)?; assert_eq!( Ok(Some((1i32, 2i32))), - stmt.query(NO_PARAMS) - .unwrap() - .map(|r| Ok((r.get(0)?, r.get(1)?))) - .next() + stmt.query([])?.map(|r| Ok((r.get(0)?, r.get(1)?))).next() ); } + Ok(()) } #[test] - fn test_connection_close() { - let conn = Connection::open_in_memory().unwrap(); - conn.prepare_cached("SELECT * FROM sqlite_master;").unwrap(); + fn test_connection_close() -> Result<()> { + let conn = Connection::open_in_memory()?; + conn.prepare_cached("SELECT * FROM sqlite_master;")?; conn.close().expect("connection not closed"); + Ok(()) } #[test] - fn test_cache_key() { - let db = Connection::open_in_memory().unwrap(); + fn test_cache_key() -> Result<()> { + let db = Connection::open_in_memory()?; let cache = &db.cache; assert_eq!(0, cache.len()); //let sql = " PRAGMA schema_version; -- comment"; let sql = "PRAGMA schema_version; "; { - let mut stmt = db.prepare_cached(sql).unwrap(); + let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!( - 0, - stmt.query_row(NO_PARAMS, |r| r.get::<_, i64>(0)).unwrap() - ); + assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); } assert_eq!(1, cache.len()); { - let mut stmt = db.prepare_cached(sql).unwrap(); + let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!( - 0, - stmt.query_row(NO_PARAMS, |r| r.get::<_, i64>(0)).unwrap() - ); + assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); } assert_eq!(1, cache.len()); + Ok(()) } #[test] - fn test_empty_stmt() { - let conn = Connection::open_in_memory().unwrap(); - conn.prepare_cached("").unwrap(); + fn test_empty_stmt() -> Result<()> { + let conn = Connection::open_in_memory()?; + conn.prepare_cached("")?; + Ok(()) } } |