Skip to content

Commit fa472cf

Browse files
committed
Restructure conn pool to RAII style
1 parent 3c7c5dc commit fa472cf

3 files changed

Lines changed: 70 additions & 36 deletions

File tree

src/lib.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ pub struct PostgresConnection {
158158
}
159159

160160
impl Drop for PostgresConnection {
161-
fn drop(&self) {
161+
fn drop(&mut self) {
162162
do io_error::cond.trap(|_| {}).inside {
163163
self.write_messages([&Terminate]);
164164
}
@@ -461,7 +461,7 @@ pub struct PostgresTransaction<'self> {
461461

462462
#[unsafe_destructor]
463463
impl<'self> Drop for PostgresTransaction<'self> {
464-
fn drop(&self) {
464+
fn drop(&mut self) {
465465
do io_error::cond.trap(|_| {}).inside {
466466
if task::failing() || !self.commit.take() {
467467
if self.nested {
@@ -568,7 +568,7 @@ impl ResultDescription {
568568

569569
#[unsafe_destructor]
570570
impl<'self> Drop for NormalPostgresStatement<'self> {
571-
fn drop(&self) {
571+
fn drop(&mut self) {
572572
do io_error::cond.trap(|_| {}).inside {
573573
self.conn.write_messages([
574574
&Close {
@@ -792,7 +792,7 @@ pub struct PostgresResult<'self> {
792792

793793
#[unsafe_destructor]
794794
impl<'self> Drop for PostgresResult<'self> {
795-
fn drop(&self) {
795+
fn drop(&mut self) {
796796
do io_error::cond.trap(|_| {}).inside {
797797
self.stmt.conn.write_messages([
798798
&Close {

src/pool/mod.rs

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
extern mod extra;
22

33
use extra::arc::MutexArc;
4-
use std::cell::Cell;
54

6-
use super::{PostgresConnection, PostgresConnectError};
5+
use super::{PostgresConnection,
6+
NormalPostgresStatement,
7+
PostgresDbError,
8+
PostgresConnectError,
9+
PostgresTransaction};
10+
use super::types::ToSql;
711

812
pub struct PostgresConnectionPoolConfig {
913
initial_size: uint,
@@ -75,37 +79,69 @@ impl PostgresConnectionPool {
7579
})
7680
}
7781

78-
pub fn try_with_connection<T>(&mut self,
79-
blk: &fn(&PostgresConnection) -> T)
80-
-> Result<T, PostgresConnectError> {
81-
// Can't use access_cond here since PostgresConnection uses Cell
82+
pub fn try_get_connection(&self) -> Result<PooledPostgresConnection,
83+
PostgresConnectError> {
8284
let conn = unsafe {
83-
do self.pool.unsafe_access_cond |pool, cond| {
85+
do self.pool.unsafe_access_cond |pool, cvar| {
8486
while pool.pool.is_empty() {
85-
cond.wait();
87+
cvar.wait();
8688
}
8789

8890
pool.pool.pop()
8991
}
9092
};
9193

92-
let ret = blk(&conn);
94+
Ok(PooledPostgresConnection {
95+
pool: self.clone(),
96+
conn: Some(conn)
97+
})
98+
}
9399

94-
let conn = Cell::new(conn);
100+
pub fn get_connection(&self) -> PooledPostgresConnection {
101+
match self.try_get_connection() {
102+
Ok(conn) => conn,
103+
Err(err) => fail!("Unable to get connection: %s", err.to_str())
104+
}
105+
}
106+
}
107+
108+
// Should be a newtype
109+
pub struct PooledPostgresConnection {
110+
priv pool: PostgresConnectionPool,
111+
// Todo remove the Option wrapper when drop takes self by value
112+
priv conn: Option<PostgresConnection>
113+
}
114+
115+
impl Drop for PooledPostgresConnection {
116+
fn drop(&mut self) {
95117
unsafe {
96-
do self.pool.unsafe_access |pool| {
97-
pool.pool.push(conn.take());
118+
do self.pool.pool.unsafe_access |pool| {
119+
pool.pool.push(self.conn.take_unwrap());
98120
}
99121
}
122+
}
123+
}
100124

101-
Ok(ret)
125+
impl PooledPostgresConnection {
126+
pub fn try_prepare<'a>(&'a self, query: &str)
127+
-> Result<NormalPostgresStatement<'a>, PostgresDbError> {
128+
self.conn.get_ref().try_prepare(query)
102129
}
103130

104-
pub fn with_connection<T>(&mut self, blk: &fn(&PostgresConnection) -> T)
105-
-> T {
106-
match self.try_with_connection(blk) {
107-
Ok(ret) => ret,
108-
Err(err) => fail!("Error getting connection: %s", err.to_str())
109-
}
131+
pub fn prepare<'a>(&'a self, query: &str) -> NormalPostgresStatement<'a> {
132+
self.conn.get_ref().prepare(query)
133+
}
134+
135+
pub fn try_update(&self, query: &str, params: &[&ToSql])
136+
-> Result<uint, PostgresDbError> {
137+
self.conn.get_ref().try_update(query, params)
138+
}
139+
140+
pub fn update(&self, query: &str, params: &[&ToSql]) -> uint {
141+
self.conn.get_ref().update(query, params)
142+
}
143+
144+
pub fn in_transaction<T>(&self, blk: &fn(&PostgresTransaction) -> T) -> T {
145+
self.conn.get_ref().in_transaction(blk)
110146
}
111147
}

src/pool/test.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,33 +15,31 @@ fn test_pool() {
1515
min_size: 2,
1616
max_size: 2
1717
};
18-
let mut pool = PostgresConnectionPool::new("postgres://postgres@localhost",
19-
config).unwrap();
18+
let pool = PostgresConnectionPool::new("postgres://postgres@localhost",
19+
config).unwrap();
2020

2121
let (stream1, stream2) = DuplexStream::<(), ()>();
2222

2323
let pool1 = Cell::new(pool.clone());
2424
let mut fut1 = do future::spawn {
25-
let mut pool = pool1.take();
25+
let pool = pool1.take();
2626

27-
do pool.with_connection |_conn| {
28-
stream1.send(());
29-
stream1.recv();
30-
}
27+
let _conn = pool.get_connection();
28+
stream1.send(());
29+
stream1.recv();
3130
};
3231

3332
let pool2 = Cell::new(pool.clone());
3433
let mut fut2 = do future::spawn {
35-
let mut pool = pool2.take();
34+
let pool = pool2.take();
3635

37-
do pool.with_connection |_conn| {
38-
stream2.send(());
39-
stream2.recv();
40-
}
36+
let _conn = pool.get_connection();
37+
stream2.send(());
38+
stream2.recv();
4139
};
4240

4341
fut1.get();
4442
fut2.get();
4543

46-
do pool.with_connection |_conn| { }
44+
pool.get_connection();
4745
}

0 commit comments

Comments
 (0)