Skip to content

Commit 7caf449

Browse files
committed
Update for new r2d2 and postgres versions
The caching pool's gone because postgres::Connection::prepare_cached should cover its use case.
1 parent 5cca857 commit 7caf449

File tree

3 files changed

+28
-216
lines changed

3 files changed

+28
-216
lines changed

Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,5 @@ name = "test"
1818
path = "tests/test.rs"
1919

2020
[dependencies]
21-
r2d2 = "0.2"
22-
postgres = "0.4"
23-
collect = "~0.0"
21+
r2d2 = "0.3"
22+
postgres = "0.5"

src/lib.rs

Lines changed: 23 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,24 @@
44
#![allow(unstable)]
55
extern crate r2d2;
66
extern crate postgres;
7-
extern crate collect;
87

9-
use collect::LruCache;
10-
use std::borrow::ToOwned;
11-
use std::cell::RefCell;
12-
use std::default::Default;
138
use std::error;
149
use std::error::Error as _StdError;
1510
use std::fmt;
16-
use std::mem;
17-
use std::rc::Rc;
1811
use postgres::{IntoConnectParams, SslMode};
19-
use postgres::types::ToSql;
2012

2113
/// A unified enum of errors returned by postgres::Connection
22-
#[derive(Clone, Show)]
14+
#[derive(Clone, Debug)]
2315
pub enum Error {
2416
/// A postgres::ConnectError
2517
Connect(postgres::ConnectError),
2618
/// An postgres::Error
2719
Other(postgres::Error),
2820
}
2921

30-
impl fmt::String for Error {
22+
impl fmt::Display for Error {
3123
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
32-
write!(fmt, "{}", self.description())
24+
write!(fmt, "{}: {}", self.description(), self.cause().unwrap())
3325
}
3426
}
3527

@@ -49,7 +41,7 @@ impl error::Error for Error {
4941
}
5042
}
5143

52-
/// An `r2d2::PoolManager` for `postgres::Connection`s.
44+
/// An `r2d2::ConnectionManager` for `postgres::Connection`s.
5345
///
5446
/// ## Example
5547
///
@@ -63,12 +55,12 @@ impl error::Error for Error {
6355
/// use std::default::Default;
6456
/// use std::thread::Thread;
6557
/// use postgres::SslMode;
66-
/// use r2d2_postgres::PostgresPoolManager;
58+
/// use r2d2_postgres::PostgresConnectionManager;
6759
///
6860
/// fn main() {
6961
/// let config = Default::default();
70-
/// let manager = PostgresPoolManager::new("postgres://postgres@localhost",
71-
/// SslMode::None);
62+
/// let manager = PostgresConnectionManager::new("postgres://postgres@localhost",
63+
/// SslMode::None);
7264
/// let error_handler = r2d2::LoggingErrorHandler;
7365
/// let pool = Arc::new(r2d2::Pool::new(config, manager, error_handler).unwrap());
7466
///
@@ -81,25 +73,35 @@ impl error::Error for Error {
8173
/// }
8274
/// }
8375
/// ```
84-
pub struct PostgresPoolManager {
76+
pub struct PostgresConnectionManager {
8577
params: Result<postgres::ConnectParams, postgres::ConnectError>,
8678
ssl_mode: SslMode,
8779
}
8880

89-
impl PostgresPoolManager {
90-
/// Creates a new `PostgresPoolManager`.
81+
impl fmt::Debug for PostgresConnectionManager {
82+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
83+
write!(fmt, "PostgresConnectionManager {{ parameters: {:?}, ssl_mode: {:?} }}",
84+
self.params, self.ssl_mode)
85+
}
86+
}
87+
88+
impl PostgresConnectionManager {
89+
/// Creates a new `PostgresConnectionManager`.
9190
///
9291
/// See `postgres::Connection::connect` for a description of the parameter
9392
/// types.
94-
pub fn new<T: IntoConnectParams>(params: T, ssl_mode: SslMode) -> PostgresPoolManager {
95-
PostgresPoolManager {
93+
pub fn new<T: IntoConnectParams>(params: T, ssl_mode: SslMode) -> PostgresConnectionManager {
94+
PostgresConnectionManager {
9695
params: params.into_connect_params(),
9796
ssl_mode: ssl_mode,
9897
}
9998
}
10099
}
101100

102-
impl r2d2::PoolManager<postgres::Connection, Error> for PostgresPoolManager {
101+
impl r2d2::ConnectionManager for PostgresConnectionManager {
102+
type Connection = postgres::Connection;
103+
type Error = Error;
104+
103105
fn connect(&self) -> Result<postgres::Connection, Error> {
104106
match self.params {
105107
Ok(ref p) => {
@@ -117,169 +119,3 @@ impl r2d2::PoolManager<postgres::Connection, Error> for PostgresPoolManager {
117119
conn.is_desynchronized()
118120
}
119121
}
120-
121-
/// Configuration options for the `CachingStatementManager`.
122-
#[derive(Copy, Clone)]
123-
pub struct Config {
124-
/// The number of `postgres::Statement`s that will be internally cached.
125-
///
126-
/// Defaults to 10
127-
pub statement_pool_size: u32,
128-
}
129-
130-
impl Default for Config {
131-
fn default() -> Config {
132-
Config {
133-
statement_pool_size: 10,
134-
}
135-
}
136-
}
137-
138-
/// An `r2d2::PoolManager` for `Connection`s, which cache prepared statements.
139-
pub struct StatementCachingManager {
140-
manager: PostgresPoolManager,
141-
config: Config,
142-
}
143-
144-
impl StatementCachingManager {
145-
/// Creates a new `StatementCachingManager`.
146-
///
147-
/// See `postgres::Connection::Connect` for details of the first two
148-
/// parameter types.
149-
pub fn new<T>(params: T, ssl_mode: SslMode, config: Config) -> StatementCachingManager
150-
where T: IntoConnectParams {
151-
StatementCachingManager {
152-
manager: PostgresPoolManager::new(params, ssl_mode),
153-
config: config
154-
}
155-
}
156-
}
157-
158-
impl r2d2::PoolManager<Connection, Error> for StatementCachingManager {
159-
fn connect(&self) -> Result<Connection, Error> {
160-
let cache = Box::new(RefCell::new(LruCache::<String, postgres::Statement<'static>>::new(
161-
self.config.statement_pool_size as usize)));
162-
Ok(Connection {
163-
conn: Box::new(try!(self.manager.connect())),
164-
stmts: unsafe { mem::transmute(cache) },
165-
})
166-
}
167-
168-
fn is_valid(&self, conn: &mut Connection) -> Result<(), Error> {
169-
self.manager.is_valid(&mut *conn.conn)
170-
}
171-
172-
fn has_broken(&self, conn: &mut Connection) -> bool {
173-
self.manager.has_broken(&mut *conn.conn)
174-
}
175-
}
176-
177-
/// A trait abstracting over functionality provided by `Connection`s and
178-
/// `Transaction`s.
179-
pub trait GenericConnection {
180-
/// Like `postgres::Connection::prepare`.
181-
fn prepare<'a>(&'a self, query: &str) -> postgres::Result<Rc<postgres::Statement<'a>>>;
182-
183-
/// Like `postgres::Connection::execute`.
184-
fn execute(&self, query: &str, params: &[&ToSql]) -> postgres::Result<usize> {
185-
self.prepare(query).and_then(|s| s.execute(params))
186-
}
187-
188-
/// Like `postgres::Connection::prepare_copy_in`.
189-
fn prepare_copy_in<'a>(&'a self, table: &str, columns: &[&str])
190-
-> postgres::Result<postgres::CopyInStatement<'a>>;
191-
192-
/// Like `postgres::Connection::transaction`.
193-
fn transaction<'a>(&'a self) -> postgres::Result<Transaction<'a>>;
194-
195-
/// Like `postgres::Connection::batch_execute`.
196-
fn batch_execute(&self, query: &str) -> postgres::Result<()>;
197-
}
198-
199-
/// Like a `postgres::Connection`, but maintains a cache of
200-
/// `postgres::Statement`s.
201-
pub struct Connection {
202-
conn: Box<postgres::Connection>,
203-
stmts: *mut (),
204-
}
205-
206-
unsafe impl Send for Connection {}
207-
208-
impl Drop for Connection {
209-
fn drop(&mut self) {
210-
let _: Box<RefCell<LruCache<String, Rc<postgres::Statement<'static>>>>> =
211-
unsafe { mem::transmute(self.stmts) };
212-
}
213-
}
214-
215-
impl Connection {
216-
fn get_cache<'a>(&'a self) -> &'a RefCell<LruCache<String, Rc<postgres::Statement<'a>>>> {
217-
unsafe { mem::transmute(self.stmts) }
218-
}
219-
}
220-
221-
impl GenericConnection for Connection {
222-
fn prepare<'a>(&'a self, query: &str) -> postgres::Result<Rc<postgres::Statement<'a>>> {
223-
let query = query.to_owned();
224-
let mut stmts = self.get_cache().borrow_mut();
225-
226-
if let Some(stmt) = stmts.get(&query) {
227-
return Ok(stmt.clone());
228-
}
229-
230-
let stmt = Rc::new(try!(self.conn.prepare(&*query)));
231-
stmts.insert(query, stmt.clone());
232-
Ok(stmt)
233-
}
234-
235-
fn prepare_copy_in<'a>(&'a self, table: &str, columns: &[&str])
236-
-> postgres::Result<postgres::CopyInStatement<'a>> {
237-
self.conn.prepare_copy_in(table, columns)
238-
}
239-
240-
fn transaction<'a>(&'a self) -> postgres::Result<Transaction<'a>> {
241-
Ok(Transaction {
242-
conn: self,
243-
trans: try!(self.conn.transaction())
244-
})
245-
}
246-
247-
fn batch_execute(&self, query: &str) -> postgres::Result<()> {
248-
self.conn.batch_execute(query)
249-
}
250-
}
251-
252-
/// Like `postgres::Transaction`.
253-
pub struct Transaction<'a> {
254-
conn: &'a Connection,
255-
trans: postgres::Transaction<'a>
256-
}
257-
258-
impl<'a> GenericConnection for Transaction<'a> {
259-
fn prepare<'b>(&'b self, query: &str) -> postgres::Result<Rc<postgres::Statement<'b>>> {
260-
let query = query.to_owned();
261-
let mut stmts = self.conn.get_cache().borrow_mut();
262-
263-
if let Some(stmt) = stmts.get(&query) {
264-
return Ok(stmt.clone());
265-
}
266-
267-
Ok(Rc::new(try!(self.trans.prepare(&*query))))
268-
}
269-
270-
fn prepare_copy_in<'b>(&'b self, table: &str, columns: &[&str])
271-
-> postgres::Result<postgres::CopyInStatement<'b>> {
272-
self.trans.prepare_copy_in(table, columns)
273-
}
274-
275-
fn transaction<'b>(&'b self) -> postgres::Result<Transaction<'b>> {
276-
Ok(Transaction {
277-
conn: self.conn,
278-
trans: try!(self.trans.transaction())
279-
})
280-
}
281-
282-
fn batch_execute(&self, query: &str) -> postgres::Result<()> {
283-
self.trans.batch_execute(query)
284-
}
285-
}

tests/test.rs

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@ use std::sync::{Arc, Future};
88
use std::sync::mpsc;
99

1010
use postgres::SslMode;
11-
use r2d2_postgres::PostgresPoolManager;
12-
use r2d2_postgres::GenericConnection;
11+
use r2d2_postgres::PostgresConnectionManager;
1312

1413
#[test]
1514
fn test_basic() {
16-
let manager = PostgresPoolManager::new("postgres://postgres@localhost", SslMode::None);
15+
let manager = PostgresConnectionManager::new("postgres://postgres@localhost", SslMode::None);
1716
let config = r2d2::Config {
1817
pool_size: 2,
1918
..Default::default()
@@ -48,7 +47,7 @@ fn test_basic() {
4847

4948
#[test]
5049
fn test_is_valid() {
51-
let manager = PostgresPoolManager::new("postgres://postgres@localhost", SslMode::None);
50+
let manager = PostgresConnectionManager::new("postgres://postgres@localhost", SslMode::None);
5251
let config = r2d2::Config {
5352
pool_size: 1,
5453
test_on_check_out: true,
@@ -59,25 +58,3 @@ fn test_is_valid() {
5958

6059
pool.get().unwrap();
6160
}
62-
63-
#[test]
64-
fn test_statement_pool() {
65-
let config = r2d2_postgres::Config { statement_pool_size: 1 };
66-
let manager = r2d2_postgres::StatementCachingManager::new(
67-
"postgres://postgres@localhost", SslMode::None, config);
68-
let pool = r2d2::Pool::new(Default::default(), manager, r2d2::NoopErrorHandler).unwrap();
69-
70-
let conn = pool.get().unwrap();
71-
let stmt = conn.prepare("SELECT 1::INT").unwrap();
72-
let stmt2 = conn.prepare("SELECT 1::INT").unwrap();
73-
assert_eq!(&*stmt as *const _, &*stmt2 as *const _);
74-
assert_eq!(stmt.query(&[]).unwrap().next().unwrap().get::<_, i32>(0), 1i32);
75-
76-
let stmt3 = conn.prepare("SELECT 2::INT").unwrap();
77-
assert_eq!(stmt3.query(&[]).unwrap().next().unwrap().get::<_, i32>(0), 2i32);
78-
let stmt4 = conn.prepare("SELECT 1::INT").unwrap();
79-
let a = &*stmt as *const _;
80-
let b = &*stmt4 as *const _;
81-
assert!(a != b);
82-
assert_eq!(stmt4.query(&[]).unwrap().next().unwrap().get::<_, i32>(0), 1i32);
83-
}

0 commit comments

Comments
 (0)