@@ -7,6 +7,7 @@ use sqlx::postgres::PgPoolOptions;
77use rand:: { distributions:: Alphanumeric , rngs:: OsRng , Rng as _} ;
88use time:: Duration ;
99use serde_json;
10+ use crate :: ConnectionData :: { ConnectionPool , ConnectionString } ;
1011
1112/// Use Postgres via Sqlx as session storage backend.
1213///
@@ -39,8 +40,39 @@ use serde_json;
3940/// .run()
4041/// .await
4142/// }
42-
43-
43+ /// ```
44+ /// If you already have a connection pool, you can use something like
45+ /*/// ```no_run
46+ /// use actix_web::{web, App, HttpServer, HttpResponse, Error};
47+ /// use actix_session_sqlx::SqlxPostgresqlSessionStore;
48+ /// use actix_session::SessionMiddleware;
49+ /// use actix_web::cookie::Key;
50+ ///
51+ /// // The secret key would usually be read from a configuration file/environment variables.
52+ /// fn get_secret_key() -> Key {
53+ /// # todo!()
54+ /// // [...]
55+ /// }
56+ /// #[actix_web::main]
57+ /// async fn main() -> std::io::Result<()> {
58+ /// use sqlx::postgres::PgPoolOptions;
59+ /// let secret_key = get_secret_key();
60+ /// let pool = PgPoolOptions::find_some_way_to_build_your_pool(psql_connection_string);
61+ /// let store = SqlxPostgresqlSessionStore::from_pool(pool).await.expect("Could not build session store");
62+ ///
63+ /// HttpServer::new(move ||
64+ /// App::new()
65+ /// .wrap(SessionMiddleware::new(
66+ /// store.clone(),
67+ /// secret_key.clone()
68+ /// ))
69+ /// .default_service(web::to(|| HttpResponse::Ok())))
70+ /// .bind(("127.0.0.1", 8080))?
71+ /// .run()
72+ /// .await
73+ /// }
74+ /// ```
75+ */
4476#[ derive( Clone ) ]
4577struct CacheConfiguration {
4678 cache_keygen : Arc < dyn Fn ( & str ) -> String + Send + Sync > ,
@@ -74,35 +106,54 @@ fn generate_session_key() -> SessionKey {
74106impl SqlxPostgresqlSessionStore {
75107 pub fn builder < S : Into < String > > ( connection_string : S ) -> SqlxPostgresqlSessionStoreBuilder {
76108 SqlxPostgresqlSessionStoreBuilder {
77- connection_string : connection_string. into ( ) ,
109+ connection_data : ConnectionString ( connection_string. into ( ) ) ,
78110 configuration : CacheConfiguration :: default ( )
79111 }
80112 }
81113
82114 pub async fn new < S : Into < String > > ( connection_string : S ) -> Result < SqlxPostgresqlSessionStore , anyhow:: Error > {
83115 Self :: builder ( connection_string) . build ( ) . await
84116 }
117+
118+ pub async fn from_pool ( pool : Pool < Postgres > ) -> SqlxPostgresqlSessionStoreBuilder {
119+ SqlxPostgresqlSessionStoreBuilder {
120+ connection_data : ConnectionPool ( pool. clone ( ) ) ,
121+ configuration : CacheConfiguration :: default ( )
122+ }
123+ }
124+ }
125+
126+ pub enum ConnectionData {
127+ ConnectionString ( String ) ,
128+ ConnectionPool ( Pool < Postgres > )
85129}
86130
87131#[ must_use]
88132pub struct SqlxPostgresqlSessionStoreBuilder {
89- connection_string : String ,
133+ connection_data : ConnectionData ,
90134 configuration : CacheConfiguration ,
91135}
92136
93137impl SqlxPostgresqlSessionStoreBuilder {
94138 pub async fn build ( self ) -> Result < SqlxPostgresqlSessionStore , anyhow:: Error > {
95- PgPoolOptions :: new ( )
96- . max_connections ( 1 )
97- . connect ( self . connection_string . as_str ( ) )
98- . await
99- . map_err ( Into :: into)
100- . map ( |pool| {
101- SqlxPostgresqlSessionStore {
102- client_pool : pool,
103- configuration : self . configuration
104- }
139+ match self . connection_data {
140+ ConnectionString ( conn_string) => {
141+ PgPoolOptions :: new ( )
142+ . max_connections ( 1 )
143+ . connect ( conn_string. as_str ( ) )
144+ . await
145+ . map_err ( Into :: into)
146+ . map ( |pool| {
147+ SqlxPostgresqlSessionStore {
148+ client_pool : pool,
149+ configuration : self . configuration
150+ }
151+ } )
152+ } ,
153+ ConnectionPool ( pool) => Ok ( SqlxPostgresqlSessionStore {
154+ client_pool : pool, configuration : self . configuration
105155 } )
156+ }
106157 }
107158}
108159pub ( crate ) type SessionState = HashMap < String , String > ;
0 commit comments