@@ -20,6 +20,7 @@ impl<W: Write> DumpState<W> {
2020 & mut self ,
2121 txn : & rusqlite:: Connection ,
2222 stmt : & str ,
23+ preserve_rowids : bool ,
2324 ) -> anyhow:: Result < ( ) > {
2425 let mut stmt = txn. prepare ( stmt) ?;
2526 let mut rows = stmt. query ( ( ) ) ?;
@@ -67,7 +68,8 @@ impl<W: Write> DumpState<W> {
6768
6869 if ty == b"table" {
6970 let table_str = std:: str:: from_utf8 ( table) ?;
70- let ( row_id_col, colss) = self . list_table_columns ( txn, table_str) ?;
71+ let ( row_id_col, colss) =
72+ self . list_table_columns ( txn, table_str, preserve_rowids) ?;
7173 let mut insert = String :: new ( ) ;
7274 write ! ( & mut insert, "INSERT INTO {}" , Quoted ( table_str) ) ?;
7375
@@ -146,11 +148,12 @@ impl<W: Write> DumpState<W> {
146148 & self ,
147149 txn : & rusqlite:: Connection ,
148150 table : & str ,
151+ preserve_rowids : bool ,
149152 ) -> anyhow:: Result < ( Option < String > , Vec < String > ) > {
150153 let mut cols = Vec :: new ( ) ;
151154 let mut num_primary_keys = 0 ;
152155 let mut is_integer_primary_key = false ;
153- let mut preserve_row_id = false ;
156+ let mut preserve_rowids = preserve_rowids ;
154157 let mut row_id_col = None ;
155158
156159 txn. pragma ( None , "table_info" , table, |row| {
@@ -186,14 +189,14 @@ impl<W: Write> DumpState<W> {
186189 [ table] ,
187190 |_| {
188191 // re-set preserve_row_id if there is a row
189- preserve_row_id = true ;
192+ preserve_rowids = true ;
190193 Ok ( ( ) )
191194 } ,
192195 )
193196 . optional ( ) ?;
194197 }
195198
196- if preserve_row_id {
199+ if preserve_rowids {
197200 const ROW_ID_NAMES : [ & str ; 3 ] = [ "rowid" , "_row_id_" , "oid" ] ;
198201
199202 for row_id_name in ROW_ID_NAMES {
@@ -430,7 +433,11 @@ fn find_unused_str(haystack: &str, needle1: &str, needle2: &str) -> String {
430433 }
431434}
432435
433- pub fn export_dump ( db : & mut rusqlite:: Connection , writer : impl Write ) -> anyhow:: Result < ( ) > {
436+ pub fn export_dump (
437+ db : & mut rusqlite:: Connection ,
438+ writer : impl Write ,
439+ preserve_rowids : bool ,
440+ ) -> anyhow:: Result < ( ) > {
434441 let mut txn = db. transaction ( ) ?;
435442 txn. execute ( "PRAGMA writable_schema=ON" , ( ) ) ?;
436443 let savepoint = txn. savepoint_with_name ( "dump" ) ?;
@@ -451,7 +458,7 @@ pub fn export_dump(db: &mut rusqlite::Connection, writer: impl Write) -> anyhow:
451458WHERE type=='table'
452459AND sql NOT NULL
453460ORDER BY tbl_name='sqlite_sequence', rowid" ;
454- state. run_schema_dump_query ( & savepoint, q) ?;
461+ state. run_schema_dump_query ( & savepoint, q, preserve_rowids ) ?;
455462
456463 let q = "SELECT sql FROM sqlite_schema AS o
457464WHERE sql NOT NULL
@@ -508,7 +515,24 @@ mod test {
508515 conn. execute ( r#"create table test ("limit")"# , ( ) ) . unwrap ( ) ;
509516
510517 let mut out = Vec :: new ( ) ;
511- export_dump ( & mut conn, & mut out) . unwrap ( ) ;
518+ export_dump ( & mut conn, & mut out, false ) . unwrap ( ) ;
519+
520+ insta:: assert_snapshot!( std:: str :: from_utf8( & out) . unwrap( ) ) ;
521+ }
522+
523+ #[ test]
524+ fn table_preserve_rowids ( ) {
525+ let tmp = tempdir ( ) . unwrap ( ) ;
526+ let mut conn = Connection :: open ( tmp. path ( ) . join ( "data" ) ) . unwrap ( ) ;
527+ conn. execute ( r#"create table test ( id TEXT PRIMARY KEY )"# , ( ) )
528+ . unwrap ( ) ;
529+ conn. execute ( r#"insert into test values ( 'a' ), ( 'b' ), ( 'c' )"# , ( ) )
530+ . unwrap ( ) ;
531+ conn. execute ( r#"delete from test where id = 'a'"# , ( ) )
532+ . unwrap ( ) ;
533+
534+ let mut out = Vec :: new ( ) ;
535+ export_dump ( & mut conn, & mut out, true ) . unwrap ( ) ;
512536
513537 insta:: assert_snapshot!( std:: str :: from_utf8( & out) . unwrap( ) ) ;
514538 }
0 commit comments