]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Added option to dump pages.
authorshaneh <shaneh@noemail.net>
Fri, 8 Jan 2010 04:50:22 +0000 (04:50 +0000)
committershaneh <shaneh@noemail.net>
Fri, 8 Jan 2010 04:50:22 +0000 (04:50 +0000)
FossilOrigin-Name: 08c545f03082421166a21274b39e07bb348c17e6

manifest
manifest.uuid
tool/restore_jrnl.tcl

index 8721c808871cd5de367dcd041c330dd63316120e..484deaaa1ba31ae8fe932454b53a282a2cdebb9f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Minor\stweaks\sto\srestore_jrnl.tcl\sutility\sscript.
-D 2010-01-07T22:02:35
+C Added\soption\sto\sdump\spages.
+D 2010-01-08T04:50:22
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in c5827ead754ab32b9585487177c93bb00b9497b3
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -770,7 +770,7 @@ F tool/mksqlite3h.tcl eb100dce83f24b501b325b340f8b5eb8e5106b3b
 F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87
 F tool/omittest.tcl 27d6f6e3b1e95aeb26a1c140e6eb57771c6d794a
 F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
-F tool/restore_jrnl.tcl 81dabc8951580e0983ea867631be855dc93358ce
+F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a
 F tool/shell1.test ef08a3e738b9fee4fc228920956950bc35db0575
 F tool/shell2.test 91824fff77514b6b00227744c475c09c34134a4e
 F tool/shell3.test ff663e83100670a295d473515c12beb8103a78b6
@@ -785,7 +785,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 05b18b5f6a38f513ff49656faada725eb44715b7
-R 99c2a9dd26b7b50e819f5bcbbba2a04f
+P b97aca1200d959a1e7c08dd4e9dbce4724342119
+R 954d1ee5bc4e8dbfdb8e25f58c6f3247
 U shaneh
-Z 2f756cb564fe45590ccd32f9d897b68c
+Z 6999a75f8e62879e0ec4ab88e2a317f7
index ecfbe66b435f3c485fbfe2a6749ab064438ecb7c..d3a6f52e199db3afa3e5eb767f0282a58ce2ac2d 100644 (file)
@@ -1 +1 @@
-b97aca1200d959a1e7c08dd4e9dbce4724342119
\ No newline at end of file
+08c545f03082421166a21274b39e07bb348c17e6
\ No newline at end of file
index 66ec279dab76b8e1e7655f0f464992cc13414afc..05af4f9a2a8b9ddc0d81041e6976546a9ca1735c 100644 (file)
 # This may be useful for rolling-back the last committed 
 # transaction from a recovered journal.
 #
-# $Id: restore_jrnl.tcl,v 1.14 2009/07/11 06:55:34 danielk1977 Exp $
 
 package require sqlite3
 
-if { $argc != 2 } {\r
-  puts "USAGE: restore_jrnl.tcl db_name jrnl_name"\r
-  puts "Example: restore_jrnl.tcl foo.sqlite foo.sqlite-journal"\r
-  return\r
-} else {\r
-  set db_name [lindex $argv 0]
-  set jrnl_name [lindex $argv 1]
+set parm_error 0
+set fix_chksums 0
+set dump_pages 0
+set db_name ""
+
+for {set i 0} {$i<$argc} {incr i} {
+  if {[lindex $argv $i] == "-fix_chksums"} {
+    set fix_chksums -1
+  } elseif {[lindex $argv $i] == "-dump_pages"} {
+    set dump_pages -1
+  } elseif {$db_name == ""} {
+    set db_name [lindex $argv $i]
+    set jrnl_name $db_name-journal
+  } else {
+    set parm_error -1
+  }
+}
+if {$parm_error || $db_name == ""} {
+  puts "USAGE: restore_jrnl.tcl \[-fix_chksums\] \[-dump_pages\] db_name"
+  puts "Example: restore_jrnl.tcl foo.sqlite"
+  return
 }
 
 # is there a way to determine this?
@@ -57,6 +70,86 @@ proc do_test {name cmd expected} {
   }
 }
 
+# Calc checksum nonce from journal page data.
+#
+proc calc_nonce {jrnl_pgno} {
+  global sectsz
+  global db_pgsz
+  global jrnl_name
+  set jrnl_pg_offset [expr $sectsz+((4+$db_pgsz+4)*$jrnl_pgno)]
+  set nonce [hexio_get_int [hexio_read $jrnl_name [expr $jrnl_pg_offset+4+$db_pgsz] 4]]
+  for {set i [expr $db_pgsz-200]} {$i>0} {set i [expr $i-200]} {
+    set byte [hexio_get_int [hexio_read $jrnl_name [expr $jrnl_pg_offset+4+$i] 1]]
+    set nonce [expr $nonce-$byte]
+  }
+  return $nonce
+}
+
+# Calc checksum from journal page data.
+#
+proc calc_chksum {jrnl_pgno} {
+  global sectsz
+  global db_pgsz
+  global jrnl_name
+  global nonce
+  set jrnl_pg_offset [expr $sectsz+((4+$db_pgsz+4)*$jrnl_pgno)]
+  set chksum $nonce
+  for {set i [expr $db_pgsz-200]} {$i>0} {set i [expr $i-200]} {
+    set byte [hexio_get_int [hexio_read $jrnl_name [expr $jrnl_pg_offset+4+$i] 1]]
+    set chksum [expr $chksum+$byte]
+  }
+  return $chksum
+}
+
+# Print journal page data in hex dump form
+#
+proc dump_jrnl_page {jrnl_pgno} {
+  global sectsz
+  global db_pgsz
+  global jrnl_name
+
+  # print a header block for the page
+  puts [string repeat "-" 79]
+  set jrnl_pg_offset [expr $sectsz+((4+$db_pgsz+4)*$jrnl_pgno)]
+  set db_pgno [hexio_get_int [hexio_read $jrnl_name [expr $jrnl_pg_offset] 4]]
+  set chksum [hexio_get_int [hexio_read $jrnl_name [expr $jrnl_pg_offset+4+$db_pgsz] 4]]
+  set nonce [calc_nonce $jrnl_pgno]
+  puts [ format {jrnl_pg_offset: %08x (%d)  jrnl_pgno: %d  db_pgno: %d} \\r
+      $jrnl_pg_offset $jrnl_pg_offset \\r
+      $jrnl_pgno $db_pgno]\r
+  puts [ format {nonce: %08x chksum: %08x} \\r
+      $nonce $chksum]\r
+
+  # now hex dump the data
+  # This is derived from the Tcler's WIKI\r
+  set fid [open $jrnl_name r]\r
+  fconfigure $fid -translation binary -encoding binary\r
+  seek $fid [expr $jrnl_pg_offset+4]\r
+  set data [read $fid $db_pgsz]\r
+  close $fid\r
+  for {set addr 0} {$addr<$db_pgsz} {set addr [expr $addr+16]} {
+    # get 16 bytes of data\r
+    set s [string range $data $addr [expr $addr+16]]\r
+    \r
+    # Convert the data to hex and to characters.\r
+    binary scan $s H*@0a* hex ascii\r
+\r
+    # Replace non-printing characters in the data.\r
+    regsub -all -- {[^[:graph:] ]} $ascii {.} ascii\r
+\r
+    # Split the 16 bytes into two 8-byte chunks\r
+    regexp -- {(.{16})(.{0,16})} $hex -> hex1 hex2\r
+\r
+    # Convert the hex to pairs of hex digits\r
+    regsub -all -- {..} $hex1 {& } hex1\r
+    regsub -all -- {..} $hex2 {& } hex2\r
+\r
+    # Print the hex and ascii data\r
+    puts [ format {%08x %-24s %-24s %-16s} \\r
+        $addr $hex1 $hex2 $ascii ]\r
+  }\r
+}
+
 # Setup for the tests.  Make a backup copy of the files.
 #
 if [file exist $db_name.org] {
@@ -71,32 +164,56 @@ copy_file $db_name $db_name.org
 copy_file $jrnl_name $jrnl_name.org
 
 set db_fsize [file size $db_name]
-sqlite3 db $db_name
-set db_pgsz [db eval {PRAGMA page_size}]
-db close
+set db_pgsz [hexio_get_int [hexio_read $db_name 16 2]]
 set db_npage [expr {$db_fsize / $db_pgsz}]
 
-# restore in case get the page_size above changed things
-copy_file $db_name.org $db_name
-copy_file $jrnl_name.org $jrnl_name
-
-# calculate checksum nonce
-set pgno 0
-set pg_offset [expr $sectsz+((4+$db_pgsz+4)*$pgno)]
-set nonce [hexio_get_int [hexio_read $jrnl_name [expr $pg_offset+4+$db_pgsz] 4]]
-for {set i [expr $db_pgsz-200]} {$i>0} {set i [expr $i-200]} {
-  set byte [hexio_get_int [hexio_read $jrnl_name [expr $pg_offset+4+$i] 1]]
-  set nonce [expr $nonce-$byte]
+set jrnl_fsize [file size $jrnl_name]
+set jrnl_npage [expr {($jrnl_fsize - $sectsz) / (4 + $db_pgsz + 4)}]
+
+# calculate checksum nonce for first page
+set nonce [calc_nonce 0]
+
+# verify all the pages in the journal use the same nonce
+for {set i 1} {$i<$jrnl_npage} {incr i} {
+  set tnonce [calc_nonce $i]
+  if {$tnonce != $nonce} {
+    puts "WARNING: different nonces: 0=$nonce $i=$tnonce"
+    if {$fix_chksums } {
+      set jrnl_pg_offset [expr $sectsz+((4+$db_pgsz+4)*$i)]
+      set tchksum [calc_chksum $i]
+      hexio_write $jrnl_name [expr $jrnl_pg_offset+4+$db_pgsz] [format %08x $tchksum]
+      puts "INFO: fixing chksum: $i=$tchksum"
+    }
+  }
+}
+
+# verify all the page numbers in the journal
+for {set i 0} {$i<$jrnl_npage} {incr i} {
+  set jrnl_pg_offset [expr $sectsz+((4+$db_pgsz+4)*$i)]
+  set db_pgno [hexio_get_int [hexio_read $jrnl_name $jrnl_pg_offset 4]]
+  if {$db_pgno < 1} {
+    puts "WARNING: page number < 1: $i=$db_pgno"
+  }
+  if {$db_pgno >= $db_npage} {
+    puts "WARNING: page number >= $db_npage: $i=$db_pgno"
+  }
+}
+
+# dump page data
+if {$dump_pages} {
+  for {set i 0} {$i<$jrnl_npage} {incr i} {
+    dump_jrnl_page $i
+  }
 }
 
 # write the 8 byte magic string
-hexio_write $jrnl_name 0 d9d505f920a163d7\r
-\r
-# write -1 for number of records\r
-hexio_write $jrnl_name 8 ffffffff\r
-\r
-# write 00 for checksum nonce\r
-hexio_write $jrnl_name 12 [format %08x $nonce]\r
+hexio_write $jrnl_name 0 d9d505f920a163d7
+
+# write -1 for number of records
+hexio_write $jrnl_name 8 ffffffff
+
+# write 00 for checksum nonce
+hexio_write $jrnl_name 12 [format %08x $nonce]
 
 # write page count
 hexio_write $jrnl_name 16 [format %08x $db_npage]
@@ -107,10 +224,10 @@ hexio_write $jrnl_name 20 [format %08x $sectsz]
 # write page size
 hexio_write $jrnl_name 24 [format %08x $db_pgsz]
 
-# check the integrity of the database.
+# check the integrity of the database with the patched journal
 sqlite3 db $db_name
 do_test restore_jrnl-1.0 {
   catchsql {PRAGMA integrity_check}
 } {0 ok}
-
 db close
+