File Annotation
Not logged in
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** Copyright (c) 2007 D. Richard Hipp
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** This program is free software; you can redistribute it and/or
dbda8d6ce9 2007-07-21       drh: ** modify it under the terms of the GNU General Public
dbda8d6ce9 2007-07-21       drh: ** License version 2 as published by the Free Software Foundation.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** This program is distributed in the hope that it will be useful,
dbda8d6ce9 2007-07-21       drh: ** but WITHOUT ANY WARRANTY; without even the implied warranty of
dbda8d6ce9 2007-07-21       drh: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
dbda8d6ce9 2007-07-21       drh: ** General Public License for more details.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** You should have received a copy of the GNU General Public
dbda8d6ce9 2007-07-21       drh: ** License along with this library; if not, write to the
dbda8d6ce9 2007-07-21       drh: ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
dbda8d6ce9 2007-07-21       drh: ** Boston, MA  02111-1307, USA.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** Author contact information:
dbda8d6ce9 2007-07-21       drh: **   drh@hwaci.com
dbda8d6ce9 2007-07-21       drh: **   http://www.hwaci.com/drh/
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: *******************************************************************************
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** This file contains code used to help verify the integrity of the
dbda8d6ce9 2007-07-21       drh: ** the repository
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: #include "config.h"
dbda8d6ce9 2007-07-21       drh: #include "verify.h"
dbda8d6ce9 2007-07-21       drh: #include <assert.h>
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** Load the record identify by rid.  Make sure we can reproduce it
dbda8d6ce9 2007-07-21       drh: ** without error.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** Panic if anything goes wrong.  If this procedure returns it means
dbda8d6ce9 2007-07-21       drh: ** that everything is OK.
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: static void verify_rid(int rid){
dbda8d6ce9 2007-07-21       drh:   Blob uuid, hash, content;
dbda8d6ce9 2007-07-21       drh:   blob_zero(&uuid);
dbda8d6ce9 2007-07-21       drh:   db_blob(&uuid, "SELECT uuid FROM blob WHERE rid=%d", rid);
dbda8d6ce9 2007-07-21       drh:   if( blob_size(&uuid)!=UUID_SIZE ){
dbda8d6ce9 2007-07-21       drh:     fossil_panic("not a valid rid: %d", rid);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   content_get(rid, &content);
dbda8d6ce9 2007-07-21       drh:   sha1sum_blob(&content, &hash);
75c476ccd1 2007-07-23       drh: /*  blob_reset(&content); */
dbda8d6ce9 2007-07-21       drh:   if( blob_compare(&uuid, &hash) ){
75c476ccd1 2007-07-23       drh: printf("content=[%s]\n", blob_str(&content));
75c476ccd1 2007-07-23       drh:     fossil_panic("hash of rid %d (%b) does not match its uuid (%b)",
75c476ccd1 2007-07-23       drh:                   rid, &hash, &uuid);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   blob_reset(&uuid);
dbda8d6ce9 2007-07-21       drh:   blob_reset(&hash);
dbda8d6ce9 2007-07-21       drh: }
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: static int verify_at_commit(void *notUsed){
dbda8d6ce9 2007-07-21       drh:   Stmt q;
dbda8d6ce9 2007-07-21       drh:   db_prepare(&q, "SELECT rid FROM toverify");
dbda8d6ce9 2007-07-21       drh:   while( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:     int rid = db_column_int(&q, 0);
dbda8d6ce9 2007-07-21       drh:     verify_rid(rid);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_finalize(&q);
dbda8d6ce9 2007-07-21       drh:   db_multi_exec("DELETE FROM toverify");
dbda8d6ce9 2007-07-21       drh:   return 0;
dbda8d6ce9 2007-07-21       drh: }
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** Arrange to verify a particular record prior to committing.
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** If the record rid is less than 1, then just initialize the
dbda8d6ce9 2007-07-21       drh: ** verification system but do not record anything as needing
dbda8d6ce9 2007-07-21       drh: ** verification.
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: void verify_before_commit(int rid){
dbda8d6ce9 2007-07-21       drh:   static int isInit = 0;
dbda8d6ce9 2007-07-21       drh:   if( !isInit ){
dbda8d6ce9 2007-07-21       drh:     db_multi_exec(
dbda8d6ce9 2007-07-21       drh:        "CREATE TEMP TABLE toverify(rid INTEGER PRIMARY KEY);"
dbda8d6ce9 2007-07-21       drh:     );
dbda8d6ce9 2007-07-21       drh:     sqlite3_commit_hook(g.db, verify_at_commit, 0);
dbda8d6ce9 2007-07-21       drh:     isInit = 1;
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   if( rid>0 ){
dbda8d6ce9 2007-07-21       drh:     db_multi_exec(
dbda8d6ce9 2007-07-21       drh:       "INSERT OR IGNORE INTO toverify VALUES(%d)", rid
dbda8d6ce9 2007-07-21       drh:     );
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh: }
dbda8d6ce9 2007-07-21       drh: 
dbda8d6ce9 2007-07-21       drh: /*
dbda8d6ce9 2007-07-21       drh: ** COMMAND: test-verify-all
dbda8d6ce9 2007-07-21       drh: **
dbda8d6ce9 2007-07-21       drh: ** Verify all records in the repository.
dbda8d6ce9 2007-07-21       drh: */
dbda8d6ce9 2007-07-21       drh: void verify_all_cmd(void){
dbda8d6ce9 2007-07-21       drh:   Stmt q;
dbda8d6ce9 2007-07-21       drh:   db_must_be_within_tree();
dbda8d6ce9 2007-07-21       drh:   db_prepare(&q, "SELECT rid FROM blob");
dbda8d6ce9 2007-07-21       drh:   while( db_step(&q)==SQLITE_ROW ){
dbda8d6ce9 2007-07-21       drh:     int rid = db_column_int(&q, 0);
dbda8d6ce9 2007-07-21       drh:     verify_rid(rid);
dbda8d6ce9 2007-07-21       drh:   }
dbda8d6ce9 2007-07-21       drh:   db_finalize(&q);
dbda8d6ce9 2007-07-21       drh: }