nickel_postgres/
middleware.rs1use std::error::Error;
2use std::result::Result;
3use nickel::{Request, Response, Middleware, Continue, MiddlewareResult};
4use nickel::status::StatusCode;
5use r2d2_postgres::{PostgresConnectionManager, SslMode};
6use r2d2::{Config, Pool, PooledConnection, GetTimeout};
7use typemap::Key;
8use plugin::Extensible;
9
10pub struct PostgresMiddleware {
11 pub pool: Pool<PostgresConnectionManager>,
12}
13
14impl PostgresMiddleware {
15 pub fn new(db_url: &str) -> Result<PostgresMiddleware, Box<Error>> {
19 let manager = try!(PostgresConnectionManager::new(db_url, SslMode::None));
20 let pool = try!(Pool::new(Config::default(), manager));
21
22 Ok(PostgresMiddleware { pool: pool })
23 }
24
25 pub fn with_pool(pool: Pool<PostgresConnectionManager>) -> PostgresMiddleware {
29 PostgresMiddleware { pool: pool }
30 }
31}
32
33impl Key for PostgresMiddleware { type Value = Pool<PostgresConnectionManager>; }
34
35impl<D> Middleware<D> for PostgresMiddleware {
36 fn invoke<'mw, 'conn>(&self, req: &mut Request<'mw, 'conn, D>, res: Response<'mw, D>) -> MiddlewareResult<'mw, D> {
37 req.extensions_mut().insert::<PostgresMiddleware>(self.pool.clone());
38
39 Ok(Continue(res))
40 }
41}
42
43pub trait PostgresRequestExtensions {
58 fn pg_conn(&self) -> Result<PooledConnection<PostgresConnectionManager>, (StatusCode, GetTimeout)>;
59}
60
61impl<'a, 'b, D> PostgresRequestExtensions for Request<'a, 'b, D> {
62 fn pg_conn(&self) -> Result<PooledConnection<PostgresConnectionManager>, (StatusCode, GetTimeout)> {
63 self.extensions()
64 .get::<PostgresMiddleware>()
65 .expect("PostgresMiddleware must be registered before using PostgresRequestExtensions::pg_conn()")
66 .get()
67 .or_else(|err| Err((StatusCode::InternalServerError, err)))
68 }
69}