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