From 85fb89b28079ba5bc52462f8ecdb10b47ecbd50f Mon Sep 17 00:00:00 2001 From: Gwenael Treguier Date: Thu, 17 Dec 2015 20:33:34 +0100 Subject: [PATCH] Fail to create a new CachedStatement. --- src/cache.rs | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/cache.rs b/src/cache.rs index e51ef2c..bee947a 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -2,6 +2,7 @@ use std::cell::RefCell; use std::collections::VecDeque; +use std::ops::{Deref, DerefMut}; use {Result, Connection, Statement}; /// Prepared statements cache. @@ -17,6 +18,20 @@ pub struct CachedStatement<'conn> { pub cacheable: bool, } +impl<'conn> Deref for CachedStatement<'conn> { + type Target = Statement<'conn>; + + fn deref(&self) -> &Statement<'conn> { + self.stmt.as_ref().unwrap() + } +} + +impl<'conn> DerefMut for CachedStatement<'conn> { + fn deref_mut(&mut self) -> &mut Statement<'conn> { + self.stmt.as_mut().unwrap() + } +} + impl<'conn> Drop for CachedStatement<'conn> { #[allow(unused_must_use)] fn drop(&mut self) { @@ -28,6 +43,18 @@ impl<'conn> Drop for CachedStatement<'conn> { } } +impl<'conn> CachedStatement<'conn> { + fn new(stmt: Statement<'conn>, + cache: RefCell>) + -> CachedStatement<'conn> { + CachedStatement { + stmt: Some(stmt), + cache: cache, + cacheable: true, + } + } +} + impl<'conn> StatementCache<'conn> { /// Create a statement cache. pub fn new(conn: &'conn Connection, capacity: usize) -> StatementCache<'conn> { @@ -43,11 +70,12 @@ impl<'conn> StatementCache<'conn> { /// # Failure /// /// Will return `Err` if no cached statement can be found and the underlying SQLite prepare call fails. - pub fn get(&mut self, sql: &str) -> Result> { - match self.cache.iter().rposition(|entry| entry.eq(sql)) { + pub fn get(&mut self, sql: &str) -> Result> { + let stmt = match self.cache.iter().rposition(|entry| entry.eq(sql)) { Some(index) => Ok(self.cache.swap_remove_front(index).unwrap()), // FIXME Not LRU compliant _ => self.conn.prepare(sql), - } + }; + stmt.map(|stmt| CachedStatement::new(stmt, RefCell::new(self))) } /// If `discard` is true, then the statement is deleted immediately. @@ -59,7 +87,8 @@ impl<'conn> StatementCache<'conn> { /// Will return `Err` if `stmt` (or the already cached statement implementing the same SQL) statement is `discard`ed /// and the underlying SQLite finalize call fails. fn release(&mut self, mut stmt: Statement<'conn>) { - if self.cache.capacity() == self.cache.len() { // is full + if self.cache.capacity() == self.cache.len() { + // is full self.cache.pop_back(); // LRU dropped } stmt.reset_if_needed();