22
33use super :: traits:: * ;
44use async_trait:: async_trait;
5+ use base64:: { engine:: general_purpose:: STANDARD as BASE64 , Engine } ;
56use bytes:: Bytes ;
67use chrono:: Utc ;
78use md5:: { Digest , Md5 } ;
@@ -289,13 +290,22 @@ impl ObjectStorage for PersistentStorage {
289290 bucket : & str ,
290291 prefix : Option < & str > ,
291292 delimiter : Option < & str > ,
292- _continuation_token : Option < & str > ,
293+ continuation_token : Option < & str > ,
293294 max_keys : i32 ,
294295 ) -> Result < ListObjectsResult , StorageError > {
295296 let conn = self . conn . lock ( ) ;
296297 let prefix = prefix. unwrap_or ( "" ) ;
297298 let max_keys = max_keys as usize ;
298299
300+ let mut skip_key: Option < String > = None ;
301+ if let Some ( token) = continuation_token {
302+ if let Ok ( decoded) = BASE64 . decode ( token) {
303+ if let Ok ( key) = String :: from_utf8 ( decoded) {
304+ skip_key = Some ( key) ;
305+ }
306+ }
307+ }
308+
299309 let mut stmt = conn
300310 . prepare (
301311 "SELECT key, etag, size, last_modified, storage_class FROM objects WHERE bucket = ?1 AND key LIKE ?2" ,
@@ -320,9 +330,18 @@ impl ObjectStorage for PersistentStorage {
320330
321331 let mut objects = Vec :: new ( ) ;
322332 let mut common_prefixes = std:: collections:: HashSet :: new ( ) ;
333+ let mut last_key: Option < String > = None ;
334+ let mut has_more = false ;
323335
324336 for row in rows. flatten ( ) {
325337 let key = & row. key ;
338+
339+ if let Some ( ref skip) = skip_key {
340+ if key <= skip {
341+ continue ;
342+ }
343+ }
344+
326345 let suffix = & key[ prefix. len ( ) ..] ;
327346
328347 if let Some ( delim) = delimiter {
@@ -334,19 +353,27 @@ impl ObjectStorage for PersistentStorage {
334353 }
335354
336355 if objects. len ( ) >= max_keys {
356+ has_more = true ;
337357 break ;
338358 }
339359
360+ last_key = Some ( key. clone ( ) ) ;
340361 objects. push ( row) ;
341362 }
342363
343364 objects. sort_by ( |a, b| a. key . cmp ( & b. key ) ) ;
344365
366+ let next_token = if has_more {
367+ last_key. map ( |k| BASE64 . encode ( k. as_bytes ( ) ) )
368+ } else {
369+ None
370+ } ;
371+
345372 Ok ( ListObjectsResult {
346373 objects,
347374 common_prefixes : common_prefixes. into_iter ( ) . collect ( ) ,
348- is_truncated : false ,
349- next_continuation_token : None ,
375+ is_truncated : has_more ,
376+ next_continuation_token : next_token ,
350377 } )
351378 }
352379
0 commit comments