13
13
14
14
#![ forbid( unsafe_code, future_incompatible, rust_2018_idioms) ]
15
15
#![ deny( missing_debug_implementations, nonstandard_style) ]
16
- #![ warn( missing_docs, missing_doc_code_examples, unreachable_pub) ]
16
+ #![ warn( missing_docs, rustdoc :: missing_doc_code_examples, unreachable_pub) ]
17
17
18
18
use async_session:: chrono:: { Duration , Utc } ;
19
19
use async_session:: { async_trait, Result , Session , SessionStore } ;
20
- use mongodb:: { bson, Collection } ;
21
- use mongodb:: bson:: { doc, Bson , Document } ;
20
+ use mongodb:: bson:: { self , doc, Bson , Document } ;
22
21
use mongodb:: options:: { ReplaceOptions , SelectionCriteria } ;
23
22
use mongodb:: Client ;
24
23
25
24
/// A MongoDB session store.
26
25
#[ derive( Debug , Clone ) ]
27
26
pub struct MongodbSessionStore {
28
- client : mongodb:: Client ,
29
- db : String ,
30
- coll_name : String ,
27
+ collection : mongodb:: Collection < Document > ,
28
+ database : mongodb:: Database ,
31
29
}
32
30
33
31
impl MongodbSessionStore {
@@ -40,9 +38,9 @@ impl MongodbSessionStore {
40
38
/// .await?;
41
39
/// # Ok(()) }) }
42
40
/// ```
43
- pub async fn new ( uri : & str , db : & str , coll_name : & str ) -> mongodb:: error:: Result < Self > {
41
+ pub async fn new ( uri : & str , db_name : & str , coll_name : & str ) -> mongodb:: error:: Result < Self > {
44
42
let client = Client :: with_uri_str ( uri) . await ?;
45
- let middleware = Self :: from_client ( client, db , coll_name) ;
43
+ let middleware = Self :: from_client ( client, db_name , coll_name) ;
46
44
middleware. create_expire_index ( "expireAt" , 0 ) . await ?;
47
45
Ok ( middleware)
48
46
}
@@ -66,16 +64,17 @@ impl MongodbSessionStore {
66
64
/// let store = MongodbSessionStore::from_client(client, "db_name", "collection");
67
65
/// # Ok(()) }) }
68
66
/// ```
69
- pub fn from_client ( client : Client , db : & str , coll_name : & str ) -> Self {
67
+ pub fn from_client ( client : Client , db_name : & str , coll_name : & str ) -> Self {
68
+ let database = client. database ( db_name) ;
69
+ let collection = database. collection ( coll_name) ;
70
70
Self {
71
- client,
72
- db : db. to_string ( ) ,
73
- coll_name : coll_name. to_string ( ) ,
71
+ database,
72
+ collection,
74
73
}
75
74
}
76
75
77
76
/// Initialize the default expiration mechanism, based on the document expiration
78
- /// that mongodb provides https://docs.mongodb.com/manual/tutorial/expire-data/#expire-documents-at-a-specific-clock-time.
77
+ /// that mongodb provides < https://docs.mongodb.com/manual/tutorial/expire-data/#expire-documents-at-a-specific-clock-time> .
79
78
/// The default ttl applyed to sessions without expiry is 20 minutes.
80
79
/// If the `expireAt` date field contains a date in the past, mongodb considers the document expired and will be deleted.
81
80
/// Note: mongodb runs the expiration logic every 60 seconds.
@@ -89,8 +88,7 @@ impl MongodbSessionStore {
89
88
/// # Ok(()) }) }
90
89
/// ```
91
90
pub async fn initialize ( & self ) -> Result {
92
- let _ = & self . index_on_expiry_at ( ) . await ?;
93
- Ok ( ( ) )
91
+ self . index_on_expiry_at ( ) . await
94
92
}
95
93
96
94
/// private associated function
@@ -102,7 +100,7 @@ impl MongodbSessionStore {
102
100
expire_after_seconds : u32 ,
103
101
) -> mongodb:: error:: Result < ( ) > {
104
102
let create_index = doc ! {
105
- "createIndexes" : & self . coll_name ,
103
+ "createIndexes" : self . collection . name ( ) ,
106
104
"indexes" : [
107
105
{
108
106
"key" : { field_name: 1 } ,
@@ -111,8 +109,7 @@ impl MongodbSessionStore {
111
109
}
112
110
]
113
111
} ;
114
- self . client
115
- . database ( & self . db )
112
+ self . database
116
113
. run_command (
117
114
create_index,
118
115
SelectionCriteria :: ReadPreference ( mongodb:: options:: ReadPreference :: Primary ) ,
@@ -123,7 +120,7 @@ impl MongodbSessionStore {
123
120
124
121
/// Create a new index for the `expireAt` property, allowing to expire sessions at a specific clock time.
125
122
/// If the `expireAt` date field contains a date in the past, mongodb considers the document expired and will be deleted.
126
- /// https://docs.mongodb.com/manual/tutorial/expire-data/#expire-documents-at-a-specific-clock-time
123
+ /// < https://docs.mongodb.com/manual/tutorial/expire-data/#expire-documents-at-a-specific-clock-time>
127
124
/// ```rust
128
125
/// # fn main() -> async_session::Result { async_std::task::block_on(async {
129
126
/// # use async_mongodb_session::MongodbSessionStore;
@@ -142,14 +139,13 @@ impl MongodbSessionStore {
142
139
#[ async_trait]
143
140
impl SessionStore for MongodbSessionStore {
144
141
async fn store_session ( & self , session : Session ) -> Result < Option < String > > {
145
- let coll = self . client . database ( & self . db ) . collection ( & self . coll_name ) ;
142
+ let coll = & self . collection ;
146
143
147
144
let value = bson:: to_bson ( & session) ?;
148
145
let id = session. id ( ) ;
149
146
let query = doc ! { "session_id" : id } ;
150
147
let expire_at = match session. expiry ( ) {
151
148
None => Utc :: now ( ) + Duration :: from_std ( std:: time:: Duration :: from_secs ( 1200 ) ) . unwrap ( ) ,
152
-
153
149
Some ( expiry) => * { expiry } ,
154
150
} ;
155
151
let replacement = doc ! { "session_id" : id, "session" : value, "expireAt" : expire_at, "created" : Utc :: now( ) } ;
@@ -162,7 +158,7 @@ impl SessionStore for MongodbSessionStore {
162
158
163
159
async fn load_session ( & self , cookie_value : String ) -> Result < Option < Session > > {
164
160
let id = Session :: id_from_cookie_value ( & cookie_value) ?;
165
- let coll: Collection < Document > = self . client . database ( & self . db ) . collection ( & self . coll_name ) ;
161
+ let coll = & self . collection ;
166
162
let filter = doc ! { "session_id" : id } ;
167
163
match coll. find_one ( filter, None ) . await ? {
168
164
None => Ok ( None ) ,
@@ -175,7 +171,7 @@ impl SessionStore for MongodbSessionStore {
175
171
// https://docs.mongodb.com/manual/core/index-ttl/#timing-of-the-delete-operation
176
172
// This prevents those documents being returned
177
173
if let Some ( expiry_at) = doc. get ( "expireAt" ) . and_then ( Bson :: as_datetime) {
178
- if expiry_at < & Utc :: now ( ) . into ( ) {
174
+ if expiry_at. to_chrono ( ) < Utc :: now ( ) {
179
175
return Ok ( None ) ;
180
176
}
181
177
}
@@ -185,14 +181,14 @@ impl SessionStore for MongodbSessionStore {
185
181
}
186
182
187
183
async fn destroy_session ( & self , session : Session ) -> Result {
188
- let coll: Collection < Document > = self . client . database ( & self . db ) . collection ( & self . coll_name ) ;
184
+ let coll = & self . collection ;
189
185
coll. delete_one ( doc ! { "session_id" : session. id( ) } , None )
190
186
. await ?;
191
187
Ok ( ( ) )
192
188
}
193
189
194
190
async fn clear_store ( & self ) -> Result {
195
- let coll: Collection < Document > = self . client . database ( & self . db ) . collection ( & self . coll_name ) ;
191
+ let coll = & self . collection ;
196
192
coll. drop ( None ) . await ?;
197
193
self . initialize ( ) . await ?;
198
194
Ok ( ( ) )
0 commit comments