@@ -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,42 @@ 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 count_sql = format ! ( "SELECT COUNT(*) FROM {}" , self . kv_table_name) ;
514+ let count: usize =
515+ locked_conn. query_row ( & count_sql, [ ] , |row| row. get ( 0 ) ) . map_err ( |e| {
516+ let msg = format ! ( "Failed to count rows: {}" , e) ;
517+ io:: Error :: new ( io:: ErrorKind :: Other , msg)
518+ } ) ?;
519+
520+ let mut stmt = locked_conn. prepare_cached ( & sql) . map_err ( |e| {
521+ let msg = format ! ( "Failed to prepare statement: {}" , e) ;
522+ io:: Error :: new ( io:: ErrorKind :: Other , msg)
523+ } ) ?;
524+
525+ let mut keys = Vec :: with_capacity ( count) ;
526+ let rows_iter =
527+ stmt. query_map ( [ ] , |row| Ok ( ( row. get ( 0 ) ?, row. get ( 1 ) ?, row. get ( 2 ) ?) ) ) . map_err ( |e| {
528+ let msg = format ! ( "Failed to retrieve queried rows: {}" , e) ;
529+ io:: Error :: new ( io:: ErrorKind :: Other , msg)
530+ } ) ?;
531+
532+ for key in rows_iter {
533+ keys. push ( key. map_err ( |e| {
534+ let msg = format ! ( "Failed to retrieve queried rows: {}" , e) ;
535+ io:: Error :: new ( io:: ErrorKind :: Other , msg)
536+ } ) ?) ;
537+ }
538+
539+ Ok ( keys)
540+ }
541+
489542 fn list_paginated_internal (
490543 & self , primary_namespace : & str , secondary_namespace : & str , page_token : Option < PageToken > ,
491544 ) -> io:: Result < PaginatedListResponse > {
@@ -679,6 +732,34 @@ mod tests {
679732 do_test_store ( & store_0, & store_1)
680733 }
681734
735+ #[ tokio:: test]
736+ async fn test_sqlite_store_list_all_keys ( ) {
737+ let mut temp_path = random_storage_path ( ) ;
738+ temp_path. push ( "test_sqlite_store_list_all_keys" ) ;
739+ let store = SqliteStore :: new (
740+ temp_path,
741+ Some ( "test_db" . to_string ( ) ) ,
742+ Some ( "test_table" . to_string ( ) ) ,
743+ )
744+ . unwrap ( ) ;
745+
746+ KVStore :: write ( & store, "ns_a" , "sub_a" , "key_a" , vec ! [ 1u8 ] ) . await . unwrap ( ) ;
747+ KVStore :: write ( & store, "ns_a" , "sub_b" , "key_b" , vec ! [ 2u8 ] ) . await . unwrap ( ) ;
748+ KVStore :: write ( & store, "ns_b" , "" , "key_c" , vec ! [ 3u8 ] ) . await . unwrap ( ) ;
749+
750+ let mut keys = MigratableKVStore :: list_all_keys ( & store) . await . unwrap ( ) ;
751+ keys. sort ( ) ;
752+
753+ assert_eq ! (
754+ keys,
755+ vec![
756+ ( "ns_a" . to_string( ) , "sub_a" . to_string( ) , "key_a" . to_string( ) ) ,
757+ ( "ns_a" . to_string( ) , "sub_b" . to_string( ) , "key_b" . to_string( ) ) ,
758+ ( "ns_b" . to_string( ) , "" . to_string( ) , "key_c" . to_string( ) ) ,
759+ ]
760+ ) ;
761+ }
762+
682763 #[ tokio:: test]
683764 async fn test_sqlite_store_paginated_listing ( ) {
684765 let mut temp_path = random_storage_path ( ) ;
0 commit comments