@@ -158,9 +158,19 @@ export class Database<T = unknown, PAR = unknown> extends TypedEmitter<QmEvents<
158158 */
159159 public async getRaw ( key : string ) : Promise < DocType < T > > {
160160 this . __readyCheck ( ) ;
161- return await this . model . findOne ( {
161+ const doc = await this . model . findOne ( {
162162 ID : Util . getKey ( key )
163163 } ) ;
164+
165+ // return null if the doc has expired
166+ // mongodb task runs every 60 seconds therefore expired docs may exist during that timeout
167+ // this check fixes that issue and returns null if the doc has expired
168+ // letting mongodb take care of data deletion in the background
169+ if ( ! doc || ( doc . expireAt && doc . expireAt . getTime ( ) - Date . now ( ) <= 0 ) ) {
170+ return null ;
171+ }
172+
173+ return doc ;
164174 }
165175
166176 /**
@@ -187,16 +197,33 @@ export class Database<T = unknown, PAR = unknown> extends TypedEmitter<QmEvents<
187197 * Set item in the database
188198 * @param {string } key The key
189199 * @param {any } value The value
200+ * @param {?number } [expireAfterSeconds=-1] if specified, quickmongo deletes this data after specified seconds.
201+ * Leave it blank or set it to `-1` to make it permanent.
202+ * <warn>Data may still persist for a minute even after the data is supposed to be expired!</warn>
203+ * Data may persist for a minute even after expiration due to the nature of mongodb. QuickMongo makes sure to never return expired
204+ * documents even if it's not deleted.
190205 * @returns {Promise<any> }
206+ * @example // permanent
207+ * await db.set("foo", "bar");
208+ *
209+ * // delete the record after 1 minute
210+ * await db.set("foo", "bar", 60); // time in seconds (60 seconds = 1 minute)
191211 */
192- public async set ( key : string , value : T | unknown ) : Promise < T > {
212+ public async set ( key : string , value : T | unknown , expireAfterSeconds = - 1 ) : Promise < T > {
193213 this . __readyCheck ( ) ;
194214 if ( ! key . includes ( "." ) ) {
195215 await this . model . findOneAndUpdate (
196216 {
197217 ID : key
198218 } ,
199- { $set : { data : value } } ,
219+ {
220+ $set : Util . shouldExpire ( expireAfterSeconds )
221+ ? {
222+ data : value ,
223+ expireAt : Util . createDuration ( expireAfterSeconds * 1000 )
224+ }
225+ : { data : value }
226+ } ,
200227 { upsert : true }
201228 ) ;
202229
@@ -205,10 +232,18 @@ export class Database<T = unknown, PAR = unknown> extends TypedEmitter<QmEvents<
205232 const keyMetadata = Util . getKeyMetadata ( key ) ;
206233 const existing = await this . model . findOne ( { ID : keyMetadata . master } ) ;
207234 if ( ! existing ) {
208- await this . model . create ( {
209- ID : keyMetadata . master ,
210- data : _ . set ( { } , keyMetadata . target , value )
211- } ) ;
235+ await this . model . create (
236+ Util . shouldExpire ( expireAfterSeconds )
237+ ? {
238+ ID : keyMetadata . master ,
239+ data : _ . set ( { } , keyMetadata . target , value ) ,
240+ expireAt : Util . createDuration ( expireAfterSeconds * 1000 )
241+ }
242+ : {
243+ ID : keyMetadata . master ,
244+ data : _ . set ( { } , keyMetadata . target , value )
245+ }
246+ ) ;
212247
213248 return await this . get ( key ) ;
214249 }
@@ -219,9 +254,14 @@ export class Database<T = unknown, PAR = unknown> extends TypedEmitter<QmEvents<
219254 const newData = _ . set ( prev , keyMetadata . target , value ) ;
220255
221256 await existing . updateOne ( {
222- $set : {
223- data : newData
224- }
257+ $set : Util . shouldExpire ( expireAfterSeconds )
258+ ? {
259+ data : newData ,
260+ expireAt : Util . createDuration ( expireAfterSeconds * 1000 )
261+ }
262+ : {
263+ data : newData
264+ }
225265 } ) ;
226266
227267 return await this . get ( keyMetadata . master ) ;
@@ -364,12 +404,13 @@ export class Database<T = unknown, PAR = unknown> extends TypedEmitter<QmEvents<
364404 this . __readyCheck ( ) ;
365405 const everything = await this . model . find ( ) ;
366406 let arb = everything
407+ . filter ( ( x ) => ! ( x . expireAt && x . expireAt . getTime ( ) - Date . now ( ) <= 0 ) )
367408 . map ( ( m ) => ( {
368409 ID : m . ID ,
369410 data : this . __formatData ( m )
370411 } ) )
371412 . filter ( ( doc , idx ) => {
372- if ( options ?. filter ) return options . filter ( { ID : doc . ID , data : doc . data } , idx ) ;
413+ if ( options ?. filter ) return options . filter ( doc , idx ) ;
373414 return true ;
374415 } ) as AllData < T > [ ] ;
375416
0 commit comments