15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# 2010 January 7
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# The author disclaims copyright to this source code.  In place of
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# a legal notice, here is a blessing:
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    May you do good and not evil.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    May you find forgiveness for yourself and forgive others.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#    May you share freely, never taking more than you give.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#***********************************************************************
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This file implements utility functions for SQLite library.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This file attempts to restore the header of a journal.
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This may be useful for rolling-back the last committed
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# transaction from a recovered journal.
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package require sqlite3
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set parm_error 0
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set fix_chksums 0
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set dump_pages 0
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set db_name ""
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)for {set i 0} {$i<$argc} {incr i} {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if {[lindex $argv $i] == "-fix_chksums"} {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set fix_chksums -1
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } elseif {[lindex $argv $i] == "-dump_pages"} {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set dump_pages -1
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } elseif {$db_name == ""} {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set db_name [lindex $argv $i]
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set jrnl_name $db_name-journal
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set parm_error -1
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if {$parm_error || $db_name == ""} {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  puts "USAGE: restore_jrnl.tcl \[-fix_chksums\] \[-dump_pages\] db_name"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  puts "Example: restore_jrnl.tcl foo.sqlite"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# is there a way to determine this?
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set sectsz 512
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copy file $from into $to
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc copy_file {from to} {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  file copy -force $from $to
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Execute some SQL
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc catchsql {sql} {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set rc [catch {uplevel [list db eval $sql]} msg]
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  list $rc $msg
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Perform a test
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc do_test {name cmd expected} {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  puts -nonewline "$name ..."
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set res [uplevel $cmd]
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if {$res eq $expected} {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    puts Ok
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    puts Error
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    puts "  Got: $res"
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    puts "  Expected: $expected"
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Calc checksum nonce from journal page data.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc calc_nonce {jrnl_pgno} {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global sectsz
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global db_pgsz
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global jrnl_name
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set jrnl_pg_offset [expr $sectsz+((4+$db_pgsz+4)*$jrnl_pgno)]
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set nonce [hexio_get_int [hexio_read $jrnl_name [expr $jrnl_pg_offset+4+$db_pgsz] 4]]
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for {set i [expr $db_pgsz-200]} {$i>0} {set i [expr $i-200]} {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set byte [hexio_get_int [hexio_read $jrnl_name [expr $jrnl_pg_offset+4+$i] 1]]
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set nonce [expr $nonce-$byte]
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return $nonce
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Calc checksum from journal page data.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc calc_chksum {jrnl_pgno} {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global sectsz
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global db_pgsz
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global jrnl_name
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global nonce
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set jrnl_pg_offset [expr $sectsz+((4+$db_pgsz+4)*$jrnl_pgno)]
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set chksum $nonce
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for {set i [expr $db_pgsz-200]} {$i>0} {set i [expr $i-200]} {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set byte [hexio_get_int [hexio_read $jrnl_name [expr $jrnl_pg_offset+4+$i] 1]]
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set chksum [expr $chksum+$byte]
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return $chksum
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Print journal page data in hex dump form
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)proc dump_jrnl_page {jrnl_pgno} {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global sectsz
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global db_pgsz
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  global jrnl_name
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # print a header block for the page
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  puts [string repeat "-" 79]
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set jrnl_pg_offset [expr $sectsz+((4+$db_pgsz+4)*$jrnl_pgno)]
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set db_pgno [hexio_get_int [hexio_read $jrnl_name [expr $jrnl_pg_offset] 4]]
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set chksum [hexio_get_int [hexio_read $jrnl_name [expr $jrnl_pg_offset+4+$db_pgsz] 4]]
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set nonce [calc_nonce $jrnl_pgno]
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  puts [ format {jrnl_pg_offset: %08x (%d)  jrnl_pgno: %d  db_pgno: %d} \
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      $jrnl_pg_offset $jrnl_pg_offset \
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      $jrnl_pgno $db_pgno]
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  puts [ format {nonce: %08x chksum: %08x} \
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      $nonce $chksum]
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # now hex dump the data
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  # This is derived from the Tcler's WIKI
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set fid [open $jrnl_name r]
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fconfigure $fid -translation binary -encoding binary
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  seek $fid [expr $jrnl_pg_offset+4]
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set data [read $fid $db_pgsz]
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  close $fid
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for {set addr 0} {$addr<$db_pgsz} {set addr [expr $addr+16]} {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # get 16 bytes of data
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set s [string range $data $addr [expr $addr+16]]
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Convert the data to hex and to characters.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    binary scan $s H*@0a* hex ascii
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Replace non-printing characters in the data.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    regsub -all -- {[^[:graph:] ]} $ascii {.} ascii
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Split the 16 bytes into two 8-byte chunks
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    regexp -- {(.{16})(.{0,16})} $hex -> hex1 hex2
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Convert the hex to pairs of hex digits
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    regsub -all -- {..} $hex1 {& } hex1
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    regsub -all -- {..} $hex2 {& } hex2
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Print the hex and ascii data
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    puts [ format {%08x %-24s %-24s %-16s} \
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        $addr $hex1 $hex2 $ascii ]
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Setup for the tests.  Make a backup copy of the files.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [file exist $db_name.org] {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  puts "ERROR: during back-up: $db_name.org exists already."
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if [file exist $jrnl_name.org] {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  puts "ERROR: during back-up: $jrnl_name.org exists already."
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)copy_file $db_name $db_name.org
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)copy_file $jrnl_name $jrnl_name.org
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set db_fsize [file size $db_name]
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set db_pgsz [hexio_get_int [hexio_read $db_name 16 2]]
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set db_npage [expr {$db_fsize / $db_pgsz}]
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set jrnl_fsize [file size $jrnl_name]
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set jrnl_npage [expr {($jrnl_fsize - $sectsz) / (4 + $db_pgsz + 4)}]
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# calculate checksum nonce for first page
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)set nonce [calc_nonce 0]
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# verify all the pages in the journal use the same nonce
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)for {set i 1} {$i<$jrnl_npage} {incr i} {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set tnonce [calc_nonce $i]
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if {$tnonce != $nonce} {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    puts "WARNING: different nonces: 0=$nonce $i=$tnonce"
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if {$fix_chksums } {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      set jrnl_pg_offset [expr $sectsz+((4+$db_pgsz+4)*$i)]
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      set tchksum [calc_chksum $i]
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      hexio_write $jrnl_name [expr $jrnl_pg_offset+4+$db_pgsz] [format %08x $tchksum]
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      puts "INFO: fixing chksum: $i=$tchksum"
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# verify all the page numbers in the journal
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)for {set i 0} {$i<$jrnl_npage} {incr i} {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set jrnl_pg_offset [expr $sectsz+((4+$db_pgsz+4)*$i)]
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set db_pgno [hexio_get_int [hexio_read $jrnl_name $jrnl_pg_offset 4]]
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if {$db_pgno < 1} {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    puts "WARNING: page number < 1: $i=$db_pgno"
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if {$db_pgno >= $db_npage} {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    puts "WARNING: page number >= $db_npage: $i=$db_pgno"
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# dump page data
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if {$dump_pages} {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for {set i 0} {$i<$jrnl_npage} {incr i} {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dump_jrnl_page $i
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write the 8 byte magic string
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hexio_write $jrnl_name 0 d9d505f920a163d7
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write -1 for number of records
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hexio_write $jrnl_name 8 ffffffff
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write 00 for checksum nonce
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hexio_write $jrnl_name 12 [format %08x $nonce]
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write page count
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hexio_write $jrnl_name 16 [format %08x $db_npage]
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write sector size
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hexio_write $jrnl_name 20 [format %08x $sectsz]
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# write page size
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)hexio_write $jrnl_name 24 [format %08x $db_pgsz]
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# check the integrity of the database with the patched journal
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)sqlite3 db $db_name
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)do_test restore_jrnl-1.0 {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  catchsql {PRAGMA integrity_check}
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} {0 ok}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)db close
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
234