@@ -435,9 +435,9 @@ pub unsafe fn string_ptr_len(
435435 str : * mut rm:: ffi:: RedisModuleString ,
436436) -> & ' static str {
437437 let mut len = 0 ;
438- let base = rm :: ffi :: RedisModule_StringPtrLen . unwrap ( ) (
439- str, & mut len,
440- ) as * mut u8 ;
438+ let base =
439+ rm :: ffi :: RedisModule_StringPtrLen . unwrap ( ) ( str, & mut len)
440+ as * mut u8 ;
441441 let slice = slice:: from_raw_parts ( base, len) ;
442442 str:: from_utf8_unchecked ( slice)
443443}
@@ -489,9 +489,9 @@ pub enum Command {
489489 arguments : Vec < & ' static str > ,
490490 client : BlockedClient ,
491491 } ,
492- Copy {
493- source : Arc < Mutex < sql :: RawConnection > > ,
494- destination : Arc < Mutex < sql :: RawConnection > > ,
492+ MakeCopy {
493+ source : DBKey ,
494+ destination : DBKey ,
495495 client : BlockedClient ,
496496 } ,
497497}
@@ -545,6 +545,32 @@ pub fn do_query(
545545 }
546546}
547547
548+ /// implements the copy of the source database into the destination one
549+ /// it also leak the two DBKeys
550+ pub fn do_copy (
551+ source : DBKey ,
552+ destination : DBKey ,
553+ ) -> Result < QueryResult , err:: RediSQLError > {
554+ let source_connection = source. loop_data . get_db ( ) ;
555+ let destination_connection = destination. loop_data . get_db ( ) ;
556+
557+ let backup_result = {
558+ let source_db = source_connection. lock ( ) . unwrap ( ) ;
559+ let destination_db = destination_connection. lock ( ) . unwrap ( ) ;
560+ match make_backup ( & source_db, & destination_db) {
561+ Err ( e) => Err ( RediSQLError :: from ( e) ) ,
562+ Ok ( _) => Ok ( QueryResult :: OK { } ) ,
563+ }
564+ } ;
565+
566+ restore_previous_statements ( & destination. loop_data ) ;
567+
568+ std:: mem:: forget ( source) ;
569+ std:: mem:: forget ( destination) ;
570+
571+ backup_result
572+ }
573+
548574fn bind_statement < ' a > (
549575 stmt : & ' a MultiStatement ,
550576 arguments : & [ & str ] ,
@@ -577,6 +603,13 @@ impl error::Error for RedisError {
577603 }
578604}
579605
606+ /// restore_previous_statements wread the statements written in the database and add them to the
607+ /// loopdata datastructure.
608+ /// At the moment this function returns `()` no matter if there are errors or not.
609+ /// Errors are pretty unlikely, especially if nobody touched manually the metadata database, but
610+ /// still they may happens.
611+ /// I am not sure if it is a good idea or if I should upgrade the code to return an error, and
612+ /// maybe just ignore the error to keep the whole flow as it is now.
580613fn restore_previous_statements < ' a , L : ' a + LoopData > (
581614 loopdata : & L ,
582615) -> ( ) {
@@ -726,18 +759,13 @@ pub fn listen_and_execute<'a, L: 'a + LoopData>(
726759 } ,
727760 ) ;
728761 }
729- Ok ( Command :: Copy {
762+ Ok ( Command :: MakeCopy {
730763 source,
731764 destination,
732765 client,
733766 } ) => {
734- let source = source. lock ( ) . unwrap ( ) ;
735- let destination = destination. lock ( ) . unwrap ( ) ;
736- let result = match make_backup ( & source, & destination)
737- {
738- Err ( e) => Err ( RediSQLError :: from ( e) ) ,
739- Ok ( _) => Ok ( QueryResult :: OK { } ) ,
740- } ;
767+ // The DBKeys MUST be leaked, they are leaked by do_copy
768+ let result = do_copy ( source, destination) ;
741769 return_value ( & client, result) ;
742770 }
743771 Ok ( Command :: Stop ) => {
@@ -819,7 +847,7 @@ impl Drop for DBKey {
819847pub fn create_metadata_table (
820848 db : Arc < Mutex < sql:: RawConnection > > ,
821849) -> Result < ( ) , sql:: SQLite3Error > {
822- let statement = "CREATE TABLE RediSQLMetadata(data_type TEXT, key TEXT, value TEXT);" ;
850+ let statement = "CREATE TABLE IF NOT EXISTS RediSQLMetadata(data_type TEXT, key TEXT, value TEXT);" ;
823851
824852 let stmt = MultiStatement :: new ( db, statement) ?;
825853 stmt. execute ( ) ?;
@@ -1018,10 +1046,8 @@ pub fn get_dbkeyptr_from_name(
10181046 rm:: ffi:: RedisModule_KeyType . unwrap ( ) ( safe_key. key )
10191047 } ;
10201048 if unsafe {
1021- rm:: ffi:: DBType
1022- == rm:: ffi:: RedisModule_ModuleTypeGetType . unwrap ( ) (
1023- safe_key. key ,
1024- )
1049+ rm:: ffi:: DBType == rm:: ffi:: RedisModule_ModuleTypeGetType
1050+ . unwrap ( ) ( safe_key. key )
10251051 } {
10261052 let db_ptr = unsafe {
10271053 rm:: ffi:: RedisModule_ModuleTypeGetValue . unwrap ( ) (
0 commit comments