Diff
Not logged in

Differences From Artifact [a3038ce20f]:

To Artifact [8d633e10bb]:


18
19
20
21
22
23
24
25






26
27
28
29
30
31
32
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code used to help verify the integrity of the
** the repository






*/
#include "config.h"
#include "verify.h"
#include <assert.h>

/*
** Load the record identify by rid.  Make sure we can reproduce it







|
>
>
>
>
>
>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code used to help verify the integrity of the
** the repository.
**
** This file primarily implements the verify_before_commit() interface.
** Any function can call verify_before_commit() with a record id (RID)
** as an argument.  Then before the next change to the database commits,
** this routine will reach in and check that the record can be extracted
** correctly from the BLOB table.
*/
#include "config.h"
#include "verify.h"
#include <assert.h>

/*
** Load the record identify by rid.  Make sure we can reproduce it
54
55
56
57
58
59
60


61





62
63
64
65

66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
100
101
102
103
104

105
106
107
108
109


110
111


112
    }
    blob_reset(&hash);
  }
  blob_reset(&uuid);
}

/*


**  





*/
static int verify_at_commit(void *notUsed){
  Stmt q;
  db_prepare(&q, "SELECT rid FROM toverify");

  while( db_step(&q)==SQLITE_ROW ){
    int rid = db_column_int(&q, 0);
    verify_rid(rid);

  }
  db_finalize(&q);
  db_multi_exec("DELETE FROM toverify");
  return 0;
}

/*
** Arrange to verify a particular record prior to committing.
** 
** If the record rid is less than 1, then just initialize the
** verification system but do not record anything as needing
** verification.
*/
void verify_before_commit(int rid){
  static int isInit = 0;
  if( !isInit ){
    db_multi_exec(
       "CREATE TEMP TABLE toverify(rid INTEGER PRIMARY KEY);"
    );
    sqlite3_commit_hook(g.db, verify_at_commit, 0);
    isInit = 1;
  }

  if( rid>0 ){
    db_multi_exec(
      "INSERT OR IGNORE INTO toverify VALUES(%d)", rid
    );
  }
}

/*
** COMMAND: test-verify-all
**
** Verify all records in the repository.
*/
void verify_all_cmd(void){
  Stmt q;

  db_must_be_within_tree();
  db_prepare(&q, "SELECT rid FROM blob");
  while( db_step(&q)==SQLITE_ROW ){
    int rid = db_column_int(&q, 0);
    verify_rid(rid);


  }
  db_finalize(&q);


}







>
>
|
>
>
>
>
>

|
|
|
>
|
<

>

|
|













<
<
<
|


>

<
<
|










>




|
>
>


>
>

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98



99
100
101
102
103


104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
    }
    blob_reset(&hash);
  }
  blob_reset(&uuid);
}

/*
** The following bag holds the rid for every record that needs
** to be verified.
*/
static Bag toVerify;
static int inFinalVerify = 0;

/*
** This routine is called just prior to each commit operation.  
*/
static int verify_at_commit(void){
  int rid;
  inFinalVerify = 1;
  rid = bag_first(&toVerify);
  while( rid>0 ){

    verify_rid(rid);
    rid = bag_next(&toVerify, rid);
  }
  bag_clear(&toVerify);
  inFinalVerify = 0;
  return 0;
}

/*
** Arrange to verify a particular record prior to committing.
** 
** If the record rid is less than 1, then just initialize the
** verification system but do not record anything as needing
** verification.
*/
void verify_before_commit(int rid){
  static int isInit = 0;
  if( !isInit ){



    db_commit_hook(verify_at_commit, 1000);
    isInit = 1;
  }
  assert( !inFinalVerify );
  if( rid>0 ){


    bag_insert(&toVerify, rid);
  }
}

/*
** COMMAND: test-verify-all
**
** Verify all records in the repository.
*/
void verify_all_cmd(void){
  Stmt q;
  int cnt = 0;
  db_must_be_within_tree();
  db_prepare(&q, "SELECT rid FROM blob");
  while( db_step(&q)==SQLITE_ROW ){
    int rid = db_column_int(&q, 0);
    verify_before_commit(rid);
    cnt++;
    assert( bag_count(&toVerify)==cnt );
  }
  db_finalize(&q);
  verify_at_commit();
  assert( bag_count(&toVerify)==0 );
}