Skip to content

Commit d61692e

Browse files
committed
Do some sketchyness to make Connection Send
1 parent b498941 commit d61692e

File tree

2 files changed

+26
-11
lines changed

2 files changed

+26
-11
lines changed

src/lib.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,11 @@ impl StatementPoolingManager {
9696

9797
impl r2d2::PoolManager<Connection, Error> for StatementPoolingManager {
9898
fn connect(&self) -> Result<Connection, Error> {
99+
let cache = box RefCell::new(LruCache::<String, PostgresStatement<'static>>::new(
100+
self.config.statement_pool_size));
99101
Ok(Connection {
100102
conn: box try!(self.manager.connect()),
101-
stmts: RefCell::new(LruCache::new(self.config.statement_pool_size))
103+
stmts: unsafe { mem::transmute(cache) },
102104
})
103105
}
104106

@@ -133,21 +135,26 @@ pub trait GenericConnection {
133135

134136
pub struct Connection {
135137
conn: Box<PostgresConnection>,
136-
stmts: RefCell<LruCache<String, Rc<PostgresStatement<'static>>>>,
138+
stmts: *mut (),
137139
}
138140

139-
#[unsafe_destructor]
140141
impl Drop for Connection {
141-
// Just make sure that all the statements drop before the connection
142142
fn drop(&mut self) {
143-
self.stmts.borrow_mut().change_capacity(0);
143+
let _: Box<RefCell<LruCache<String, Rc<PostgresStatement<'static>>>>> =
144+
unsafe { mem::transmute(self.stmts) };
145+
}
146+
}
147+
148+
impl Connection {
149+
fn get_cache(&self) -> &RefCell<LruCache<String, Rc<PostgresStatement<'static>>>> {
150+
unsafe { mem::transmute(self.stmts) }
144151
}
145152
}
146153

147154
impl GenericConnection for Connection {
148155
fn prepare<'a>(&'a self, query: &str) -> PostgresResult<Rc<PostgresStatement<'a>>> {
149156
let query = query.into_string();
150-
let mut stmts = self.stmts.borrow_mut();
157+
let mut stmts = self.get_cache().borrow_mut();
151158

152159
if let Some(stmt) = stmts.get(&query) {
153160
return Ok(unsafe { mem::transmute(stmt.clone()) });
@@ -183,7 +190,7 @@ pub struct Transaction<'a> {
183190
impl<'a> GenericConnection for Transaction<'a> {
184191
fn prepare<'a>(&'a self, query: &str) -> PostgresResult<Rc<PostgresStatement<'a>>> {
185192
let query = query.into_string();
186-
let mut stmts = self.conn.stmts.borrow_mut();
193+
let mut stmts = self.conn.get_cache().borrow_mut();
187194

188195
if let Some(stmt) = stmts.get(&query) {
189196
return Ok(unsafe { mem::transmute(stmt.clone()) });

tests/test.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,24 @@ fn test_is_valid() {
5959
pool.get().unwrap();
6060
}
6161

62-
/*
6362
#[test]
6463
fn test_statement_pool() {
64+
let config = r2d2_postgres::Config { statement_pool_size: 1 };
6565
let manager = r2d2_postgres::StatementPoolingManager::new(
66-
"postgres://postgres@localhost", NoSsl, Default::default());
66+
"postgres://postgres@localhost", NoSsl, config);
6767
let pool = r2d2::Pool::new(Default::default(), manager, r2d2::NoopErrorHandler).unwrap();
6868

6969
let conn = pool.get().unwrap();
7070
let stmt = conn.prepare("SELECT 1::INT").unwrap();
7171
let stmt2 = conn.prepare("SELECT 1::INT").unwrap();
72-
assert_eq!(*stmt as *mut _, *stmt2 as *mut _);
72+
assert_eq!(&*stmt as *const _, &*stmt2 as *const _);
73+
assert_eq!(stmt.query([]).unwrap().next().unwrap().get::<_, i32>(0), 1i32);
74+
75+
let stmt3 = conn.prepare("SELECT 2::INT").unwrap();
76+
assert_eq!(stmt3.query([]).unwrap().next().unwrap().get::<_, i32>(0), 2i32);
77+
let stmt4 = conn.prepare("SELECT 1::INT").unwrap();
78+
let a = &*stmt as *const _;
79+
let b = &*stmt4 as *const _;
80+
assert!(a != b);
81+
assert_eq!(stmt4.query([]).unwrap().next().unwrap().get::<_, i32>(0), 1i32);
7382
}
74-
*/

0 commit comments

Comments
 (0)