@@ -14,7 +14,9 @@ use std::sync::atomic::{AtomicI64, AtomicU64, Ordering};
1414use std:: sync:: { Arc , Mutex } ;
1515
1616use lightning:: io;
17- use lightning:: util:: persist:: { KVStore , PageToken , PaginatedKVStore , PaginatedListResponse } ;
17+ use lightning:: util:: persist:: {
18+ KVStore , MigratableKVStore , PageToken , PaginatedKVStore , PaginatedListResponse ,
19+ } ;
1820use lightning_types:: string:: PrintableString ;
1921use rusqlite:: { named_params, Connection } ;
2022
@@ -202,6 +204,21 @@ impl PaginatedKVStore for SqliteStore {
202204 }
203205}
204206
207+ impl MigratableKVStore for SqliteStore {
208+ fn list_all_keys (
209+ & self ,
210+ ) -> impl Future < Output = Result < Vec < ( String , String , String ) > , io:: Error > > + ' static + Send {
211+ let inner = Arc :: clone ( & self . inner ) ;
212+ let fut = tokio:: task:: spawn_blocking ( move || inner. list_all_keys_internal ( ) ) ;
213+ async move {
214+ fut. await . unwrap_or_else ( |e| {
215+ let msg = format ! ( "Failed to IO operation due join error: {}" , e) ;
216+ Err ( io:: Error :: new ( io:: ErrorKind :: Other , msg) )
217+ } )
218+ }
219+ }
220+ }
221+
205222struct SqliteStoreInner {
206223 connection : Arc < Mutex < Connection > > ,
207224 data_dir : PathBuf ,
@@ -486,6 +503,35 @@ impl SqliteStoreInner {
486503 Ok ( keys)
487504 }
488505
506+ fn list_all_keys_internal ( & self ) -> io:: Result < Vec < ( String , String , String ) > > {
507+ let locked_conn = self . connection . lock ( ) . expect ( "lock" ) ;
508+
509+ let sql = format ! (
510+ "SELECT primary_namespace, secondary_namespace, key FROM {}" ,
511+ self . kv_table_name
512+ ) ;
513+ let mut stmt = locked_conn. prepare_cached ( & sql) . map_err ( |e| {
514+ let msg = format ! ( "Failed to prepare statement: {}" , e) ;
515+ io:: Error :: new ( io:: ErrorKind :: Other , msg)
516+ } ) ?;
517+
518+ let mut keys = Vec :: new ( ) ;
519+ let rows_iter =
520+ stmt. query_map ( [ ] , |row| Ok ( ( row. get ( 0 ) ?, row. get ( 1 ) ?, row. get ( 2 ) ?) ) ) . map_err ( |e| {
521+ let msg = format ! ( "Failed to retrieve queried rows: {}" , e) ;
522+ io:: Error :: new ( io:: ErrorKind :: Other , msg)
523+ } ) ?;
524+
525+ for key in rows_iter {
526+ keys. push ( key. map_err ( |e| {
527+ let msg = format ! ( "Failed to retrieve queried rows: {}" , e) ;
528+ io:: Error :: new ( io:: ErrorKind :: Other , msg)
529+ } ) ?) ;
530+ }
531+
532+ Ok ( keys)
533+ }
534+
489535 fn list_paginated_internal (
490536 & self , primary_namespace : & str , secondary_namespace : & str , page_token : Option < PageToken > ,
491537 ) -> io:: Result < PaginatedListResponse > {
@@ -679,6 +725,34 @@ mod tests {
679725 do_test_store ( & store_0, & store_1)
680726 }
681727
728+ #[ tokio:: test]
729+ async fn test_sqlite_store_list_all_keys ( ) {
730+ let mut temp_path = random_storage_path ( ) ;
731+ temp_path. push ( "test_sqlite_store_list_all_keys" ) ;
732+ let store = SqliteStore :: new (
733+ temp_path,
734+ Some ( "test_db" . to_string ( ) ) ,
735+ Some ( "test_table" . to_string ( ) ) ,
736+ )
737+ . unwrap ( ) ;
738+
739+ KVStore :: write ( & store, "ns_a" , "sub_a" , "key_a" , vec ! [ 1u8 ] ) . await . unwrap ( ) ;
740+ KVStore :: write ( & store, "ns_a" , "sub_b" , "key_b" , vec ! [ 2u8 ] ) . await . unwrap ( ) ;
741+ KVStore :: write ( & store, "ns_b" , "" , "key_c" , vec ! [ 3u8 ] ) . await . unwrap ( ) ;
742+
743+ let mut keys = MigratableKVStore :: list_all_keys ( & store) . await . unwrap ( ) ;
744+ keys. sort ( ) ;
745+
746+ assert_eq ! (
747+ keys,
748+ vec![
749+ ( "ns_a" . to_string( ) , "sub_a" . to_string( ) , "key_a" . to_string( ) ) ,
750+ ( "ns_a" . to_string( ) , "sub_b" . to_string( ) , "key_b" . to_string( ) ) ,
751+ ( "ns_b" . to_string( ) , "" . to_string( ) , "key_c" . to_string( ) ) ,
752+ ]
753+ ) ;
754+ }
755+
682756 #[ tokio:: test]
683757 async fn test_sqlite_store_paginated_listing ( ) {
684758 let mut temp_path = random_storage_path ( ) ;
0 commit comments