44#![ allow( unstable) ]
55extern crate r2d2;
66extern 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 ;
138use std:: error;
149use std:: error:: Error as _StdError;
1510use std:: fmt;
16- use std:: mem;
17- use std:: rc:: Rc ;
1811use 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 ) ]
2315pub 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- }
0 commit comments