Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Side by Side Diff: third_party/sqlite/sqlite-src-3080704/tool/showwal.c

Issue 883353008: [sql] Import reference version of SQLite 3.8.7.4. (Closed) Base URL: http://chromium.googlesource.com/chromium/src.git@master
Patch Set: Hold back encoding change which is messing up patch. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 ** A utility for printing all or part of an SQLite database file. 2 ** A utility for printing content from a write-ahead log file.
3 */ 3 */
4 #include <stdio.h> 4 #include <stdio.h>
5 #include <ctype.h> 5 #include <ctype.h>
6 #include <sys/types.h> 6 #include <sys/types.h>
7 #include <sys/stat.h> 7 #include <sys/stat.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9
10 #if !defined(_MSC_VER)
9 #include <unistd.h> 11 #include <unistd.h>
12 #else
13 #include <io.h>
14 #endif
15
10 #include <stdlib.h> 16 #include <stdlib.h>
11 #include <string.h> 17 #include <string.h>
12 18
13 19
14 static int pagesize = 1024; /* Size of a database page */ 20 static int pagesize = 1024; /* Size of a database page */
15 static int db = -1; /* File descriptor for reading the DB */ 21 static int fd = -1; /* File descriptor for reading the WAL file */
16 static int mxPage = 0; /* Last page number */ 22 static int mxFrame = 0; /* Last frame */
17 static int perLine = 16; /* HEX elements to print per line */ 23 static int perLine = 16; /* HEX elements to print per line */
18 24
19 typedef long long int i64; /* Datatype for 64-bit integers */ 25 typedef long long int i64; /* Datatype for 64-bit integers */
20 26
27 /* Information for computing the checksum */
28 typedef struct Cksum Cksum;
29 struct Cksum {
30 int bSwap; /* True to do byte swapping on 32-bit words */
31 unsigned s0, s1; /* Current checksum value */
32 };
33
34 /*
35 ** extract a 32-bit big-endian integer
36 */
37 static unsigned int getInt32(const unsigned char *a){
38 unsigned int x = (a[0]<<24) + (a[1]<<16) + (a[2]<<8) + a[3];
39 return x;
40 }
41
42 /*
43 ** Swap bytes on a 32-bit unsigned integer
44 */
45 static unsigned int swab32(unsigned int x){
46 return (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8)
47 + (((x)&0x00FF0000)>>8) + (((x)&0xFF000000)>>24);
48 }
49
50 /* Extend the checksum. Reinitialize the checksum if bInit is true.
51 */
52 static void extendCksum(
53 Cksum *pCksum,
54 unsigned char *aData,
55 unsigned int nByte,
56 int bInit
57 ){
58 unsigned int *a32;
59 if( bInit ){
60 int a = 0;
61 *((char*)&a) = 1;
62 if( a==1 ){
63 /* Host is little-endian */
64 pCksum->bSwap = getInt32(aData)!=0x377f0682;
65 }else{
66 /* Host is big-endian */
67 pCksum->bSwap = getInt32(aData)!=0x377f0683;
68 }
69 pCksum->s0 = 0;
70 pCksum->s1 = 0;
71 }
72 a32 = (unsigned int*)aData;
73 while( nByte>0 ){
74 unsigned int x0 = a32[0];
75 unsigned int x1 = a32[1];
76 if( pCksum->bSwap ){
77 x0 = swab32(x0);
78 x1 = swab32(x1);
79 }
80 pCksum->s0 += x0 + pCksum->s1;
81 pCksum->s1 += x1 + pCksum->s0;
82 nByte -= 8;
83 a32 += 2;
84 }
85 }
21 86
22 /* 87 /*
23 ** Convert the var-int format into i64. Return the number of bytes 88 ** Convert the var-int format into i64. Return the number of bytes
24 ** in the var-int. Write the var-int value into *pVal. 89 ** in the var-int. Write the var-int value into *pVal.
25 */ 90 */
26 static int decodeVarint(const unsigned char *z, i64 *pVal){ 91 static int decodeVarint(const unsigned char *z, i64 *pVal){
27 i64 v = 0; 92 i64 v = 0;
28 int i; 93 int i;
29 for(i=0; i<8; i++){ 94 for(i=0; i<8; i++){
30 v = (v<<7) + (z[i]&0x7f); 95 v = (v<<7) + (z[i]&0x7f);
31 if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; } 96 if( (z[i]&0x80)==0 ){ *pVal = v; return i+1; }
32 } 97 }
33 v = (v<<8) + (z[i]&0xff); 98 v = (v<<8) + (z[i]&0xff);
34 *pVal = v; 99 *pVal = v;
35 return 9; 100 return 9;
36 } 101 }
37 102
38 /*
39 ** Extract a big-endian 32-bit integer
40 */
41 static unsigned int decodeInt32(const unsigned char *z){
42 return (z[0]<<24) + (z[1]<<16) + (z[2]<<8) + z[3];
43 }
44
45 /* Report an out-of-memory error and die. 103 /* Report an out-of-memory error and die.
46 */ 104 */
47 static void out_of_memory(void){ 105 static void out_of_memory(void){
48 fprintf(stderr,"Out of memory...\n"); 106 fprintf(stderr,"Out of memory...\n");
49 exit(1); 107 exit(1);
50 } 108 }
51 109
52 /* 110 /*
53 ** Read content from the file. 111 ** Read content from the file.
54 ** 112 **
55 ** Space to hold the content is obtained from malloc() and needs to be 113 ** Space to hold the content is obtained from malloc() and needs to be
56 ** freed by the caller. 114 ** freed by the caller.
57 */ 115 */
58 static unsigned char *getContent(int ofst, int nByte){ 116 static unsigned char *getContent(int ofst, int nByte){
59 unsigned char *aData; 117 unsigned char *aData;
60 aData = malloc(nByte+32); 118 aData = malloc(nByte);
61 if( aData==0 ) out_of_memory(); 119 if( aData==0 ) out_of_memory();
62 memset(aData, 0, nByte+32); 120 lseek(fd, ofst, SEEK_SET);
63 lseek(db, ofst, SEEK_SET); 121 read(fd, aData, nByte);
64 read(db, aData, nByte);
65 return aData; 122 return aData;
66 } 123 }
67 124
68 /* 125 /*
69 ** Print a range of bytes as hex and as ascii. 126 ** Print a range of bytes as hex and as ascii.
70 */ 127 */
71 static unsigned char *print_byte_range( 128 static void print_byte_range(
72 int ofst, /* First byte in the range of bytes to print */ 129 int ofst, /* First byte in the range of bytes to print */
73 int nByte, /* Number of bytes to print */ 130 int nByte, /* Number of bytes to print */
74 int printOfst /* Add this amount to the index on the left column */ 131 unsigned char *aData, /* Content to print */
132 int printOfst /* Add this amount to the index on the left column */
75 ){ 133 ){
76 unsigned char *aData;
77 int i, j; 134 int i, j;
78 const char *zOfstFmt; 135 const char *zOfstFmt;
79 136
80 if( ((printOfst+nByte)&~0xfff)==0 ){ 137 if( ((printOfst+nByte)&~0xfff)==0 ){
81 zOfstFmt = " %03x: "; 138 zOfstFmt = " %03x: ";
82 }else if( ((printOfst+nByte)&~0xffff)==0 ){ 139 }else if( ((printOfst+nByte)&~0xffff)==0 ){
83 zOfstFmt = " %04x: "; 140 zOfstFmt = " %04x: ";
84 }else if( ((printOfst+nByte)&~0xfffff)==0 ){ 141 }else if( ((printOfst+nByte)&~0xfffff)==0 ){
85 zOfstFmt = " %05x: "; 142 zOfstFmt = " %05x: ";
86 }else if( ((printOfst+nByte)&~0xffffff)==0 ){ 143 }else if( ((printOfst+nByte)&~0xffffff)==0 ){
87 zOfstFmt = " %06x: "; 144 zOfstFmt = " %06x: ";
88 }else{ 145 }else{
89 zOfstFmt = " %08x: "; 146 zOfstFmt = " %08x: ";
90 } 147 }
91 148
92 aData = getContent(ofst, nByte);
93 for(i=0; i<nByte; i += perLine){ 149 for(i=0; i<nByte; i += perLine){
94 fprintf(stdout, zOfstFmt, i+printOfst); 150 fprintf(stdout, zOfstFmt, i+printOfst);
95 for(j=0; j<perLine; j++){ 151 for(j=0; j<perLine; j++){
96 if( i+j>nByte ){ 152 if( i+j>nByte ){
97 fprintf(stdout, " "); 153 fprintf(stdout, " ");
98 }else{ 154 }else{
99 fprintf(stdout,"%02x ", aData[i+j]); 155 fprintf(stdout,"%02x ", aData[i+j]);
100 } 156 }
101 } 157 }
102 for(j=0; j<perLine; j++){ 158 for(j=0; j<perLine; j++){
103 if( i+j>nByte ){ 159 if( i+j>nByte ){
104 fprintf(stdout, " "); 160 fprintf(stdout, " ");
105 }else{ 161 }else{
106 fprintf(stdout,"%c", isprint(aData[i+j]) ? aData[i+j] : '.'); 162 fprintf(stdout,"%c", isprint(aData[i+j]) ? aData[i+j] : '.');
107 } 163 }
108 } 164 }
109 fprintf(stdout,"\n"); 165 fprintf(stdout,"\n");
110 } 166 }
111 return aData;
112 }
113
114 /*
115 ** Print an entire page of content as hex
116 */
117 static print_page(int iPg){
118 int iStart;
119 unsigned char *aData;
120 iStart = (iPg-1)*pagesize;
121 fprintf(stdout, "Page %d: (offsets 0x%x..0x%x)\n",
122 iPg, iStart, iStart+pagesize-1);
123 aData = print_byte_range(iStart, pagesize, 0);
124 free(aData);
125 } 167 }
126 168
127 /* Print a line of decode output showing a 4-byte integer. 169 /* Print a line of decode output showing a 4-byte integer.
128 */ 170 */
129 static print_decode_line( 171 static void print_decode_line(
130 unsigned char *aData, /* Content being decoded */ 172 unsigned char *aData, /* Content being decoded */
131 int ofst, int nByte, /* Start and size of decode */ 173 int ofst, int nByte, /* Start and size of decode */
174 int asHex, /* If true, output value as hex */
132 const char *zMsg /* Message to append */ 175 const char *zMsg /* Message to append */
133 ){ 176 ){
134 int i, j; 177 int i, j;
135 int val = aData[ofst]; 178 int val = aData[ofst];
136 char zBuf[100]; 179 char zBuf[100];
137 sprintf(zBuf, " %03x: %02x", ofst, aData[ofst]); 180 sprintf(zBuf, " %03x: %02x", ofst, aData[ofst]);
138 i = strlen(zBuf); 181 i = (int)strlen(zBuf);
139 for(j=1; j<4; j++){ 182 for(j=1; j<4; j++){
140 if( j>=nByte ){ 183 if( j>=nByte ){
141 sprintf(&zBuf[i], " "); 184 sprintf(&zBuf[i], " ");
142 }else{ 185 }else{
143 sprintf(&zBuf[i], " %02x", aData[ofst+j]); 186 sprintf(&zBuf[i], " %02x", aData[ofst+j]);
144 val = val*256 + aData[ofst+j]; 187 val = val*256 + aData[ofst+j];
145 } 188 }
146 i += strlen(&zBuf[i]); 189 i += (int)strlen(&zBuf[i]);
147 } 190 }
148 sprintf(&zBuf[i], " %9d", val); 191 if( asHex ){
192 sprintf(&zBuf[i], " 0x%08x", val);
193 }else{
194 sprintf(&zBuf[i], " %9d", val);
195 }
149 printf("%s %s\n", zBuf, zMsg); 196 printf("%s %s\n", zBuf, zMsg);
150 } 197 }
151 198
152 /* 199 /*
153 ** Decode the database header. 200 ** Print an entire page of content as hex
154 */ 201 */
155 static void print_db_header(void){ 202 static void print_frame(int iFrame){
203 int iStart;
156 unsigned char *aData; 204 unsigned char *aData;
157 aData = print_byte_range(0, 100, 0); 205 iStart = 32 + (iFrame-1)*(pagesize+24);
158 printf("Decoded:\n"); 206 fprintf(stdout, "Frame %d: (offsets 0x%x..0x%x)\n",
159 print_decode_line(aData, 16, 2, "Database page size"); 207 iFrame, iStart, iStart+pagesize+24);
160 print_decode_line(aData, 18, 1, "File format write version"); 208 aData = getContent(iStart, pagesize+24);
161 print_decode_line(aData, 19, 1, "File format read version"); 209 print_decode_line(aData, 0, 4, 0, "Page number");
162 print_decode_line(aData, 20, 1, "Reserved space at end of page"); 210 print_decode_line(aData, 4, 4, 0, "DB size, or 0 for non-commit");
163 print_decode_line(aData, 24, 4, "File change counter"); 211 print_decode_line(aData, 8, 4, 1, "Salt-1");
164 print_decode_line(aData, 28, 4, "Size of database in pages"); 212 print_decode_line(aData,12, 4, 1, "Salt-2");
165 print_decode_line(aData, 32, 4, "Page number of first freelist page"); 213 print_decode_line(aData,16, 4, 1, "Checksum-1");
166 print_decode_line(aData, 36, 4, "Number of freelist pages"); 214 print_decode_line(aData,20, 4, 1, "Checksum-2");
167 print_decode_line(aData, 40, 4, "Schema cookie"); 215 print_byte_range(iStart+24, pagesize, aData+24, 0);
168 print_decode_line(aData, 44, 4, "Schema format version"); 216 free(aData);
169 print_decode_line(aData, 48, 4, "Default page cache size");
170 print_decode_line(aData, 52, 4, "Largest auto-vac root page");
171 print_decode_line(aData, 56, 4, "Text encoding");
172 print_decode_line(aData, 60, 4, "User version");
173 print_decode_line(aData, 64, 4, "Incremental-vacuum mode");
174 print_decode_line(aData, 68, 4, "meta[7]");
175 print_decode_line(aData, 72, 4, "meta[8]");
176 print_decode_line(aData, 76, 4, "meta[9]");
177 print_decode_line(aData, 80, 4, "meta[10]");
178 print_decode_line(aData, 84, 4, "meta[11]");
179 print_decode_line(aData, 88, 4, "meta[12]");
180 print_decode_line(aData, 92, 4, "Change counter for version number");
181 print_decode_line(aData, 96, 4, "SQLite version number");
182 } 217 }
183 218
184 /* 219 /*
220 ** Summarize a single frame on a single line.
221 */
222 static void print_oneline_frame(int iFrame, Cksum *pCksum){
223 int iStart;
224 unsigned char *aData;
225 unsigned int s0, s1;
226 iStart = 32 + (iFrame-1)*(pagesize+24);
227 aData = getContent(iStart, 24);
228 extendCksum(pCksum, aData, 8, 0);
229 extendCksum(pCksum, getContent(iStart+24, pagesize), pagesize, 0);
230 s0 = getInt32(aData+16);
231 s1 = getInt32(aData+20);
232 fprintf(stdout, "Frame %4d: %6d %6d 0x%08x,%08x 0x%08x,%08x %s\n",
233 iFrame,
234 getInt32(aData),
235 getInt32(aData+4),
236 getInt32(aData+8),
237 getInt32(aData+12),
238 s0,
239 s1,
240 (s0==pCksum->s0 && s1==pCksum->s1) ? "" : "cksum-fail"
241 );
242
243 /* Reset the checksum so that a single frame checksum failure will not
244 ** cause all subsequent frames to also show a failure. */
245 pCksum->s0 = s0;
246 pCksum->s1 = s1;
247 free(aData);
248 }
249
250 /*
251 ** Decode the WAL header.
252 */
253 static void print_wal_header(Cksum *pCksum){
254 unsigned char *aData;
255 aData = getContent(0, 32);
256 if( pCksum ){
257 extendCksum(pCksum, aData, 24, 1);
258 printf("Checksum byte order: %s\n", pCksum->bSwap ? "swapped" : "native");
259 }
260 printf("WAL Header:\n");
261 print_decode_line(aData, 0, 4,1,"Magic. 0x377f0682 (le) or 0x377f0683 (be)");
262 print_decode_line(aData, 4, 4, 0, "File format");
263 print_decode_line(aData, 8, 4, 0, "Database page size");
264 print_decode_line(aData, 12,4, 0, "Checkpoint sequence number");
265 print_decode_line(aData, 16,4, 1, "Salt-1");
266 print_decode_line(aData, 20,4, 1, "Salt-2");
267 print_decode_line(aData, 24,4, 1, "Checksum-1");
268 print_decode_line(aData, 28,4, 1, "Checksum-2");
269 if( pCksum ){
270 if( pCksum->s0!=getInt32(aData+24) ){
271 printf("**** cksum-1 mismatch: 0x%08x\n", pCksum->s0);
272 }
273 if( pCksum->s1!=getInt32(aData+28) ){
274 printf("**** cksum-2 mismatch: 0x%08x\n", pCksum->s1);
275 }
276 }
277 free(aData);
278 }
279 /*
185 ** Describe cell content. 280 ** Describe cell content.
186 */ 281 */
187 static int describeContent( 282 static i64 describeContent(
188 unsigned char *a, /* Cell content */ 283 unsigned char *a, /* Cell content */
189 int nLocal, /* Bytes in a[] */ 284 i64 nLocal, /* Bytes in a[] */
190 char *zDesc /* Write description here */ 285 char *zDesc /* Write description here */
191 ){ 286 ){
192 int nDesc = 0; 287 int nDesc = 0;
193 int n, i, j; 288 int n, j;
194 i64 x, v; 289 i64 i, x, v;
195 const unsigned char *pData; 290 const unsigned char *pData;
196 const unsigned char *pLimit; 291 const unsigned char *pLimit;
197 char sep = ' '; 292 char sep = ' ';
198 293
199 pLimit = &a[nLocal]; 294 pLimit = &a[nLocal];
200 n = decodeVarint(a, &x); 295 n = decodeVarint(a, &x);
201 pData = &a[x]; 296 pData = &a[x];
202 a += n; 297 a += n;
203 i = x - n; 298 i = x - n;
204 while( i>0 && pData<=pLimit ){ 299 while( i>0 && pData<=pLimit ){
(...skipping 19 matching lines...) Expand all
224 } 319 }
225 sprintf(zDesc, "%lld", v); 320 sprintf(zDesc, "%lld", v);
226 }else if( x==7 ){ 321 }else if( x==7 ){
227 sprintf(zDesc, "real"); 322 sprintf(zDesc, "real");
228 pData += 8; 323 pData += 8;
229 }else if( x==8 ){ 324 }else if( x==8 ){
230 sprintf(zDesc, "0"); 325 sprintf(zDesc, "0");
231 }else if( x==9 ){ 326 }else if( x==9 ){
232 sprintf(zDesc, "1"); 327 sprintf(zDesc, "1");
233 }else if( x>=12 ){ 328 }else if( x>=12 ){
234 int size = (x-12)/2; 329 i64 size = (x-12)/2;
235 if( (x&1)==0 ){ 330 if( (x&1)==0 ){
236 sprintf(zDesc, "blob(%d)", size); 331 sprintf(zDesc, "blob(%lld)", size);
237 }else{ 332 }else{
238 sprintf(zDesc, "txt(%d)", size); 333 sprintf(zDesc, "txt(%lld)", size);
239 } 334 }
240 pData += size; 335 pData += size;
241 } 336 }
242 j = strlen(zDesc); 337 j = (int)strlen(zDesc);
243 zDesc += j; 338 zDesc += j;
244 nDesc += j; 339 nDesc += j;
245 } 340 }
246 return nDesc; 341 return nDesc;
247 } 342 }
248 343
249 /* 344 /*
250 ** Compute the local payload size given the total payload size and 345 ** Compute the local payload size given the total payload size and
251 ** the page size. 346 ** the page size.
252 */ 347 */
253 static int localPayload(i64 nPayload, char cType){ 348 static i64 localPayload(i64 nPayload, char cType){
254 int maxLocal; 349 i64 maxLocal;
255 int minLocal; 350 i64 minLocal;
256 int surplus; 351 i64 surplus;
257 int nLocal; 352 i64 nLocal;
258 if( cType==13 ){ 353 if( cType==13 ){
259 /* Table leaf */ 354 /* Table leaf */
260 maxLocal = pagesize-35; 355 maxLocal = pagesize-35;
261 minLocal = (pagesize-12)*32/255-23; 356 minLocal = (pagesize-12)*32/255-23;
262 }else{ 357 }else{
263 maxLocal = (pagesize-12)*64/255-23; 358 maxLocal = (pagesize-12)*64/255-23;
264 minLocal = (pagesize-12)*32/255-23; 359 minLocal = (pagesize-12)*32/255-23;
265 } 360 }
266 if( nPayload>maxLocal ){ 361 if( nPayload>maxLocal ){
267 surplus = minLocal + (nPayload-minLocal)%(pagesize-4); 362 surplus = minLocal + (nPayload-minLocal)%(pagesize-4);
268 if( surplus<=maxLocal ){ 363 if( surplus<=maxLocal ){
269 nLocal = surplus; 364 nLocal = surplus;
270 }else{ 365 }else{
271 nLocal = minLocal; 366 nLocal = minLocal;
272 } 367 }
273 }else{ 368 }else{
274 nLocal = nPayload; 369 nLocal = nPayload;
275 } 370 }
276 return nLocal; 371 return nLocal;
277 } 372 }
278
279 373
280 /* 374 /*
281 ** Create a description for a single cell. 375 ** Create a description for a single cell.
282 ** 376 **
283 ** The return value is the local cell size. 377 ** The return value is the local cell size.
284 */ 378 */
285 static int describeCell( 379 static i64 describeCell(
286 unsigned char cType, /* Page type */ 380 unsigned char cType, /* Page type */
287 unsigned char *a, /* Cell content */ 381 unsigned char *a, /* Cell content */
288 int showCellContent, /* Show cell content if true */ 382 int showCellContent, /* Show cell content if true */
289 char **pzDesc /* Store description here */ 383 char **pzDesc /* Store description here */
290 ){ 384 ){
291 int i; 385 int i;
292 int nDesc = 0; 386 i64 nDesc = 0;
293 int n = 0; 387 int n = 0;
294 int leftChild; 388 int leftChild;
295 i64 nPayload; 389 i64 nPayload;
296 i64 rowid; 390 i64 rowid;
297 int nLocal; 391 i64 nLocal;
298 static char zDesc[1000]; 392 static char zDesc[1000];
299 i = 0; 393 i = 0;
300 if( cType<=5 ){ 394 if( cType<=5 ){
301 leftChild = ((a[0]*256 + a[1])*256 + a[2])*256 + a[3]; 395 leftChild = ((a[0]*256 + a[1])*256 + a[2])*256 + a[3];
302 a += 4; 396 a += 4;
303 n += 4; 397 n += 4;
304 sprintf(zDesc, "lx: %d ", leftChild); 398 sprintf(zDesc, "lx: %d ", leftChild);
305 nDesc = strlen(zDesc); 399 nDesc = strlen(zDesc);
306 } 400 }
307 if( cType!=5 ){ 401 if( cType!=5 ){
(...skipping 25 matching lines...) Expand all
333 nDesc += describeContent(a, nLocal, &zDesc[nDesc-1]); 427 nDesc += describeContent(a, nLocal, &zDesc[nDesc-1]);
334 } 428 }
335 *pzDesc = zDesc; 429 *pzDesc = zDesc;
336 return nLocal+n; 430 return nLocal+n;
337 } 431 }
338 432
339 /* 433 /*
340 ** Decode a btree page 434 ** Decode a btree page
341 */ 435 */
342 static void decode_btree_page( 436 static void decode_btree_page(
343 unsigned char *a, /* Page content */ 437 unsigned char *a, /* Content of the btree page to be decoded */
344 int pgno, /* Page number */ 438 int pgno, /* Page number */
345 int hdrSize, /* Size of the page header. 0 or 100 */ 439 int hdrSize, /* Size of the page1-header in bytes */
346 char *zArgs /* Flags to control formatting */ 440 const char *zArgs /* Flags to control formatting */
347 ){ 441 ){
348 const char *zType = "unknown"; 442 const char *zType = "unknown";
349 int nCell; 443 int nCell;
350 int i, j; 444 int i, j;
351 int iCellPtr; 445 int iCellPtr;
352 int showCellContent = 0; 446 int showCellContent = 0;
353 int showMap = 0; 447 int showMap = 0;
354 char *zMap = 0; 448 char *zMap = 0;
355 switch( a[0] ){ 449 switch( a[0] ){
356 case 2: zType = "index interior node"; break; 450 case 2: zType = "index interior node"; break;
357 case 5: zType = "table interior node"; break; 451 case 5: zType = "table interior node"; break;
358 case 10: zType = "index leaf"; break; 452 case 10: zType = "index leaf"; break;
359 case 13: zType = "table leaf"; break; 453 case 13: zType = "table leaf"; break;
360 } 454 }
361 while( zArgs[0] ){ 455 while( zArgs[0] ){
362 switch( zArgs[0] ){ 456 switch( zArgs[0] ){
363 case 'c': showCellContent = 1; break; 457 case 'c': showCellContent = 1; break;
364 case 'm': showMap = 1; break; 458 case 'm': showMap = 1; break;
365 } 459 }
366 zArgs++; 460 zArgs++;
367 } 461 }
368 printf("Decode of btree page %d:\n", pgno); 462 printf("Decode of btree page %d:\n", pgno);
369 print_decode_line(a, 0, 1, zType); 463 print_decode_line(a, 0, 1, 0, zType);
370 print_decode_line(a, 1, 2, "Offset to first freeblock"); 464 print_decode_line(a, 1, 2, 0, "Offset to first freeblock");
371 print_decode_line(a, 3, 2, "Number of cells on this page"); 465 print_decode_line(a, 3, 2, 0, "Number of cells on this page");
372 nCell = a[3]*256 + a[4]; 466 nCell = a[3]*256 + a[4];
373 print_decode_line(a, 5, 2, "Offset to cell content area"); 467 print_decode_line(a, 5, 2, 0, "Offset to cell content area");
374 print_decode_line(a, 7, 1, "Fragmented byte count"); 468 print_decode_line(a, 7, 1, 0, "Fragmented byte count");
375 if( a[0]==2 || a[0]==5 ){ 469 if( a[0]==2 || a[0]==5 ){
376 print_decode_line(a, 8, 4, "Right child"); 470 print_decode_line(a, 8, 4, 0, "Right child");
377 iCellPtr = 12; 471 iCellPtr = 12;
378 }else{ 472 }else{
379 iCellPtr = 8; 473 iCellPtr = 8;
380 } 474 }
381 if( nCell>0 ){ 475 if( nCell>0 ){
382 printf(" key: lx=left-child n=payload-size r=rowid\n"); 476 printf(" key: lx=left-child n=payload-size r=rowid\n");
383 } 477 }
384 if( showMap ){ 478 if( showMap ){
385 zMap = malloc(pagesize); 479 zMap = malloc(pagesize);
386 memset(zMap, '.', pagesize); 480 memset(zMap, '.', pagesize);
387 memset(zMap, '1', hdrSize); 481 memset(zMap, '1', hdrSize);
388 memset(&zMap[hdrSize], 'H', iCellPtr); 482 memset(&zMap[hdrSize], 'H', iCellPtr);
389 memset(&zMap[hdrSize+iCellPtr], 'P', 2*nCell); 483 memset(&zMap[hdrSize+iCellPtr], 'P', 2*nCell);
390 } 484 }
391 for(i=0; i<nCell; i++){ 485 for(i=0; i<nCell; i++){
392 int cofst = iCellPtr + i*2; 486 int cofst = iCellPtr + i*2;
393 char *zDesc; 487 char *zDesc;
394 int n; 488 i64 n;
395 489
396 cofst = a[cofst]*256 + a[cofst+1]; 490 cofst = a[cofst]*256 + a[cofst+1];
397 n = describeCell(a[0], &a[cofst-hdrSize], showCellContent, &zDesc); 491 n = describeCell(a[0], &a[cofst-hdrSize], showCellContent, &zDesc);
398 if( showMap ){ 492 if( showMap ){
399 char zBuf[30]; 493 char zBuf[30];
400 memset(&zMap[cofst], '*', n); 494 memset(&zMap[cofst], '*', (size_t)n);
401 zMap[cofst] = '['; 495 zMap[cofst] = '[';
402 zMap[cofst+n-1] = ']'; 496 zMap[cofst+n-1] = ']';
403 sprintf(zBuf, "%d", i); 497 sprintf(zBuf, "%d", i);
404 j = strlen(zBuf); 498 j = (int)strlen(zBuf);
405 if( j<=n-2 ) memcpy(&zMap[cofst+1], zBuf, j); 499 if( j<=n-2 ) memcpy(&zMap[cofst+1], zBuf, j);
406 } 500 }
407 printf(" %03x: cell[%d] %s\n", cofst, i, zDesc); 501 printf(" %03x: cell[%d] %s\n", cofst, i, zDesc);
408 } 502 }
409 if( showMap ){ 503 if( showMap ){
410 for(i=0; i<pagesize; i+=64){ 504 for(i=0; i<pagesize; i+=64){
411 printf(" %03x: %.64s\n", i, &zMap[i]); 505 printf(" %03x: %.64s\n", i, &zMap[i]);
412 } 506 }
413 free(zMap); 507 free(zMap);
414 } 508 }
415 } 509 }
416 510
417 /*
418 ** Decode a freelist trunk page.
419 */
420 static void decode_trunk_page(
421 int pgno, /* The page number */
422 int pagesize, /* Size of each page */
423 int detail, /* Show leaf pages if true */
424 int recursive /* Follow the trunk change if true */
425 ){
426 int n, i, k;
427 unsigned char *a;
428 while( pgno>0 ){
429 a = getContent((pgno-1)*pagesize, pagesize);
430 printf("Decode of freelist trunk page %d:\n", pgno);
431 print_decode_line(a, 0, 4, "Next freelist trunk page");
432 print_decode_line(a, 4, 4, "Number of entries on this page");
433 if( detail ){
434 n = (int)decodeInt32(&a[4]);
435 for(i=0; i<n; i++){
436 unsigned int x = decodeInt32(&a[8+4*i]);
437 char zIdx[10];
438 sprintf(zIdx, "[%d]", i);
439 printf(" %5s %7u", zIdx, x);
440 if( i%5==4 ) printf("\n");
441 }
442 if( i%5!=0 ) printf("\n");
443 }
444 if( !recursive ){
445 pgno = 0;
446 }else{
447 pgno = (int)decodeInt32(&a[0]);
448 }
449 free(a);
450 }
451 }
452
453 /*
454 ** Print a usage comment
455 */
456 static void usage(const char *argv0){
457 fprintf(stderr, "Usage %s FILENAME ?args...?\n\n", argv0);
458 fprintf(stderr,
459 "args:\n"
460 " dbheader Show database header\n"
461 " NNN..MMM Show hex of pages NNN through MMM\n"
462 " NNN..end Show hex of pages NNN through end of file\n"
463 " NNNb Decode btree page NNN\n"
464 " NNNbc Decode btree page NNN and show content\n"
465 " NNNbm Decode btree page NNN and show a layout map\n"
466 " NNNt Decode freelist trunk page NNN\n"
467 " NNNtd Show leave freelist pages on the decode\n"
468 " NNNtr Recurisvely decode freelist starting at NNN\n"
469 );
470 }
471
472 int main(int argc, char **argv){ 511 int main(int argc, char **argv){
473 struct stat sbuf; 512 struct stat sbuf;
474 unsigned char zPgSz[2]; 513 unsigned char zPgSz[4];
475 if( argc<2 ){ 514 if( argc<2 ){
476 usage(argv[0]); 515 fprintf(stderr,"Usage: %s FILENAME ?PAGE? ...\n", argv[0]);
477 exit(1); 516 exit(1);
478 } 517 }
479 db = open(argv[1], O_RDONLY); 518 fd = open(argv[1], O_RDONLY);
480 if( db<0 ){ 519 if( fd<0 ){
481 fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]); 520 fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]);
482 exit(1); 521 exit(1);
483 } 522 }
484 zPgSz[0] = 0; 523 zPgSz[0] = 0;
485 zPgSz[1] = 0; 524 zPgSz[1] = 0;
486 lseek(db, 16, SEEK_SET); 525 lseek(fd, 8, SEEK_SET);
487 read(db, zPgSz, 2); 526 read(fd, zPgSz, 4);
488 pagesize = zPgSz[0]*256 + zPgSz[1]*65536; 527 pagesize = zPgSz[1]*65536 + zPgSz[2]*256 + zPgSz[3];
489 if( pagesize==0 ) pagesize = 1024; 528 if( pagesize==0 ) pagesize = 1024;
490 printf("Pagesize: %d\n", pagesize); 529 printf("Pagesize: %d\n", pagesize);
491 fstat(db, &sbuf); 530 fstat(fd, &sbuf);
492 mxPage = sbuf.st_size/pagesize; 531 if( sbuf.st_size<32 ){
493 printf("Available pages: 1..%d\n", mxPage); 532 printf("file too small to be a WAL\n");
533 return 0;
534 }
535 mxFrame = (sbuf.st_size - 32)/(pagesize + 24);
536 printf("Available pages: 1..%d\n", mxFrame);
494 if( argc==2 ){ 537 if( argc==2 ){
495 int i; 538 int i;
496 for(i=1; i<=mxPage; i++) print_page(i); 539 Cksum x;
540 print_wal_header(&x);
541 for(i=1; i<=mxFrame; i++){
542 print_oneline_frame(i, &x);
543 }
497 }else{ 544 }else{
498 int i; 545 int i;
499 for(i=2; i<argc; i++){ 546 for(i=2; i<argc; i++){
500 int iStart, iEnd; 547 int iStart, iEnd;
501 char *zLeft; 548 char *zLeft;
502 if( strcmp(argv[i], "dbheader")==0 ){ 549 if( strcmp(argv[i], "header")==0 ){
503 print_db_header(); 550 print_wal_header(0);
504 continue; 551 continue;
505 } 552 }
506 if( !isdigit(argv[i][0]) ){ 553 if( !isdigit(argv[i][0]) ){
507 fprintf(stderr, "%s: unknown option: [%s]\n", argv[0], argv[i]); 554 fprintf(stderr, "%s: unknown option: [%s]\n", argv[0], argv[i]);
508 continue; 555 continue;
509 } 556 }
510 iStart = strtol(argv[i], &zLeft, 0); 557 iStart = strtol(argv[i], &zLeft, 0);
511 if( zLeft && strcmp(zLeft,"..end")==0 ){ 558 if( zLeft && strcmp(zLeft,"..end")==0 ){
512 iEnd = mxPage; 559 iEnd = mxFrame;
513 }else if( zLeft && zLeft[0]=='.' && zLeft[1]=='.' ){ 560 }else if( zLeft && zLeft[0]=='.' && zLeft[1]=='.' ){
514 iEnd = strtol(&zLeft[2], 0, 0); 561 iEnd = strtol(&zLeft[2], 0, 0);
515 }else if( zLeft && zLeft[0]=='b' ){ 562 }else if( zLeft && zLeft[0]=='b' ){
516 int ofst, nByte, hdrSize; 563 int ofst, nByte, hdrSize;
517 unsigned char *a; 564 unsigned char *a;
518 if( iStart==1 ){ 565 if( iStart==1 ){
566 hdrSize = 100;
519 ofst = hdrSize = 100; 567 ofst = hdrSize = 100;
520 nByte = pagesize-100; 568 nByte = pagesize-100;
521 }else{ 569 }else{
522 hdrSize = 0; 570 hdrSize = 0;
523 ofst = (iStart-1)*pagesize; 571 ofst = (iStart-1)*pagesize;
524 nByte = pagesize; 572 nByte = pagesize;
525 } 573 }
574 ofst = 32 + hdrSize + (iStart-1)*(pagesize+24) + 24;
526 a = getContent(ofst, nByte); 575 a = getContent(ofst, nByte);
527 decode_btree_page(a, iStart, hdrSize, &zLeft[1]); 576 decode_btree_page(a, iStart, hdrSize, zLeft+1);
528 free(a); 577 free(a);
529 continue; 578 continue;
530 }else if( zLeft && zLeft[0]=='t' ){
531 unsigned char *a;
532 int detail = 0;
533 int recursive = 0;
534 int i;
535 for(i=1; zLeft[i]; i++){
536 if( zLeft[i]=='r' ) recursive = 1;
537 if( zLeft[i]=='d' ) detail = 1;
538 }
539 decode_trunk_page(iStart, pagesize, detail, recursive);
540 continue;
541 }else{ 579 }else{
542 iEnd = iStart; 580 iEnd = iStart;
543 } 581 }
544 if( iStart<1 || iEnd<iStart || iEnd>mxPage ){ 582 if( iStart<1 || iEnd<iStart || iEnd>mxFrame ){
545 fprintf(stderr, 583 fprintf(stderr,
546 "Page argument should be LOWER?..UPPER?. Range 1 to %d\n", 584 "Page argument should be LOWER?..UPPER?. Range 1 to %d\n",
547 mxPage); 585 mxFrame);
548 exit(1); 586 exit(1);
549 } 587 }
550 while( iStart<=iEnd ){ 588 while( iStart<=iEnd ){
551 print_page(iStart); 589 print_frame(iStart);
552 iStart++; 590 iStart++;
553 } 591 }
554 } 592 }
555 } 593 }
556 close(db); 594 close(fd);
595 return 0;
557 } 596 }
OLDNEW
« no previous file with comments | « third_party/sqlite/sqlite-src-3080704/tool/showstat4.c ('k') | third_party/sqlite/sqlite-src-3080704/tool/soak1.tcl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698