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

Side by Side Diff: third_party/sqlite/src/tool/showdb.c

Issue 1610963002: Import SQLite 3.10.2. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 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 all or part of an SQLite database file.
3 */ 3 */
4 #include <stdio.h> 4 #include <stdio.h>
5 #include <ctype.h> 5 #include <ctype.h>
6 #define ISDIGIT(X) isdigit((unsigned char)(X))
7 #define ISPRINT(X) isprint((unsigned char)(X))
6 #include <sys/types.h> 8 #include <sys/types.h>
7 #include <sys/stat.h> 9 #include <sys/stat.h>
8 #include <fcntl.h> 10 #include <fcntl.h>
9 11
10 #if !defined(_MSC_VER) 12 #if !defined(_MSC_VER)
11 #include <unistd.h> 13 #include <unistd.h>
12 #else 14 #else
13 #include <io.h> 15 #include <io.h>
14 #endif 16 #endif
15 17
16 #include <stdlib.h> 18 #include <stdlib.h>
17 #include <string.h> 19 #include <string.h>
20 #include <assert.h>
18 #include "sqlite3.h" 21 #include "sqlite3.h"
19 22
20 23
21 static int pagesize = 1024; /* Size of a database page */ 24 static struct GlobalData {
22 static int db = -1; /* File descriptor for reading the DB */ 25 int pagesize; /* Size of a database page */
23 static int mxPage = 0; /* Last page number */ 26 int dbfd; /* File descriptor for reading the DB */
24 static int perLine = 16; /* HEX elements to print per line */ 27 int mxPage; /* Last page number */
28 int perLine; /* HEX elements to print per line */
29 int bRaw; /* True to access db file via OS APIs */
30 sqlite3_file *pFd; /* File descriptor for non-raw mode */
31 sqlite3 *pDb; /* Database handle that owns pFd */
32 } g = {1024, -1, 0, 16, 0, 0, 0};
33
25 34
26 typedef long long int i64; /* Datatype for 64-bit integers */ 35 typedef long long int i64; /* Datatype for 64-bit integers */
27 36
28 37
29 /* 38 /*
30 ** Convert the var-int format into i64. Return the number of bytes 39 ** Convert the var-int format into i64. Return the number of bytes
31 ** in the var-int. Write the var-int value into *pVal. 40 ** in the var-int. Write the var-int value into *pVal.
32 */ 41 */
33 static int decodeVarint(const unsigned char *z, i64 *pVal){ 42 static int decodeVarint(const unsigned char *z, i64 *pVal){
34 i64 v = 0; 43 i64 v = 0;
(...skipping 15 matching lines...) Expand all
50 } 59 }
51 60
52 /* Report an out-of-memory error and die. 61 /* Report an out-of-memory error and die.
53 */ 62 */
54 static void out_of_memory(void){ 63 static void out_of_memory(void){
55 fprintf(stderr,"Out of memory...\n"); 64 fprintf(stderr,"Out of memory...\n");
56 exit(1); 65 exit(1);
57 } 66 }
58 67
59 /* 68 /*
69 ** Open a database connection.
70 */
71 static sqlite3 *openDatabase(const char *zPrg, const char *zName){
72 sqlite3 *db = 0;
73 int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_URI;
74 int rc = sqlite3_open_v2(zName, &db, flags, 0);
75 if( rc!=SQLITE_OK ){
76 const char *zErr = sqlite3_errmsg(db);
77 fprintf(stderr, "%s: can't open %s (%s)\n", zPrg, zName, zErr);
78 sqlite3_close(db);
79 exit(1);
80 }
81 return db;
82 }
83
84 /**************************************************************************
85 ** Beginning of low-level file access functions.
86 **
87 ** All low-level access to the database file read by this program is
88 ** performed using the following four functions:
89 **
90 ** fileOpen() - open the db file
91 ** fileClose() - close the db file
92 ** fileRead() - read raw data from the db file
93 ** fileGetsize() - return the size of the db file in bytes
94 */
95
96 /*
97 ** Open the database file.
98 */
99 static void fileOpen(const char *zPrg, const char *zName){
100 assert( g.dbfd<0 );
101 if( g.bRaw==0 ){
102 int rc;
103 void *pArg = (void *)(&g.pFd);
104 g.pDb = openDatabase(zPrg, zName);
105 rc = sqlite3_file_control(g.pDb, "main", SQLITE_FCNTL_FILE_POINTER, pArg);
106 if( rc!=SQLITE_OK ){
107 fprintf(stderr,
108 "%s: failed to obtain fd for %s (SQLite too old?)\n", zPrg, zName
109 );
110 exit(1);
111 }
112 }else{
113 g.dbfd = open(zName, O_RDONLY);
114 if( g.dbfd<0 ){
115 fprintf(stderr,"%s: can't open %s\n", zPrg, zName);
116 exit(1);
117 }
118 }
119 }
120
121 /*
122 ** Close the database file opened by fileOpen()
123 */
124 static void fileClose(){
125 if( g.bRaw==0 ){
126 sqlite3_close(g.pDb);
127 g.pDb = 0;
128 g.pFd = 0;
129 }else{
130 close(g.dbfd);
131 g.dbfd = -1;
132 }
133 }
134
135 /*
60 ** Read content from the file. 136 ** Read content from the file.
61 ** 137 **
62 ** Space to hold the content is obtained from malloc() and needs to be 138 ** Space to hold the content is obtained from sqlite3_malloc() and needs
63 ** freed by the caller. 139 ** to be freed by the caller.
64 */ 140 */
65 static unsigned char *getContent(int ofst, int nByte){ 141 static unsigned char *fileRead(sqlite3_int64 ofst, int nByte){
66 unsigned char *aData; 142 unsigned char *aData;
67 aData = malloc(nByte+32); 143 int got;
144 aData = sqlite3_malloc(nByte+32);
68 if( aData==0 ) out_of_memory(); 145 if( aData==0 ) out_of_memory();
69 memset(aData, 0, nByte+32); 146 memset(aData, 0, nByte+32);
70 lseek(db, ofst, SEEK_SET); 147 if( g.bRaw==0 ){
71 if( read(db, aData, nByte)<nByte ) memset(aData, 0, nByte); 148 int rc = g.pFd->pMethods->xRead(g.pFd, (void*)aData, nByte, ofst);
149 if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
150 fprintf(stderr, "error in xRead() - %d\n", rc);
151 exit(1);
152 }
153 }else{
154 lseek(g.dbfd, ofst, SEEK_SET);
155 got = read(g.dbfd, aData, nByte);
156 if( got>0 && got<nByte ) memset(aData+got, 0, nByte-got);
157 }
72 return aData; 158 return aData;
73 } 159 }
74 160
75 /* 161 /*
162 ** Return the size of the file in byte.
163 */
164 static sqlite3_int64 fileGetsize(void){
165 sqlite3_int64 res = 0;
166 if( g.bRaw==0 ){
167 int rc = g.pFd->pMethods->xFileSize(g.pFd, &res);
168 if( rc!=SQLITE_OK ){
169 fprintf(stderr, "error in xFileSize() - %d\n", rc);
170 exit(1);
171 }
172 }else{
173 struct stat sbuf;
174 fstat(g.dbfd, &sbuf);
175 res = (sqlite3_int64)(sbuf.st_size);
176 }
177 return res;
178 }
179
180 /*
181 ** End of low-level file access functions.
182 **************************************************************************/
183
184 /*
76 ** Print a range of bytes as hex and as ascii. 185 ** Print a range of bytes as hex and as ascii.
77 */ 186 */
78 static unsigned char *print_byte_range( 187 static unsigned char *print_byte_range(
79 int ofst, /* First byte in the range of bytes to print */ 188 int ofst, /* First byte in the range of bytes to print */
80 int nByte, /* Number of bytes to print */ 189 int nByte, /* Number of bytes to print */
81 int printOfst /* Add this amount to the index on the left column */ 190 int printOfst /* Add this amount to the index on the left column */
82 ){ 191 ){
83 unsigned char *aData; 192 unsigned char *aData;
84 int i, j; 193 int i, j;
85 const char *zOfstFmt; 194 const char *zOfstFmt;
86 195
87 if( ((printOfst+nByte)&~0xfff)==0 ){ 196 if( ((printOfst+nByte)&~0xfff)==0 ){
88 zOfstFmt = " %03x: "; 197 zOfstFmt = " %03x: ";
89 }else if( ((printOfst+nByte)&~0xffff)==0 ){ 198 }else if( ((printOfst+nByte)&~0xffff)==0 ){
90 zOfstFmt = " %04x: "; 199 zOfstFmt = " %04x: ";
91 }else if( ((printOfst+nByte)&~0xfffff)==0 ){ 200 }else if( ((printOfst+nByte)&~0xfffff)==0 ){
92 zOfstFmt = " %05x: "; 201 zOfstFmt = " %05x: ";
93 }else if( ((printOfst+nByte)&~0xffffff)==0 ){ 202 }else if( ((printOfst+nByte)&~0xffffff)==0 ){
94 zOfstFmt = " %06x: "; 203 zOfstFmt = " %06x: ";
95 }else{ 204 }else{
96 zOfstFmt = " %08x: "; 205 zOfstFmt = " %08x: ";
97 } 206 }
98 207
99 aData = getContent(ofst, nByte); 208 aData = fileRead(ofst, nByte);
100 for(i=0; i<nByte; i += perLine){ 209 for(i=0; i<nByte; i += g.perLine){
101 fprintf(stdout, zOfstFmt, i+printOfst); 210 fprintf(stdout, zOfstFmt, i+printOfst);
102 for(j=0; j<perLine; j++){ 211 for(j=0; j<g.perLine; j++){
103 if( i+j>nByte ){ 212 if( i+j>nByte ){
104 fprintf(stdout, " "); 213 fprintf(stdout, " ");
105 }else{ 214 }else{
106 fprintf(stdout,"%02x ", aData[i+j]); 215 fprintf(stdout,"%02x ", aData[i+j]);
107 } 216 }
108 } 217 }
109 for(j=0; j<perLine; j++){ 218 for(j=0; j<g.perLine; j++){
110 if( i+j>nByte ){ 219 if( i+j>nByte ){
111 fprintf(stdout, " "); 220 fprintf(stdout, " ");
112 }else{ 221 }else{
113 fprintf(stdout,"%c", isprint(aData[i+j]) ? aData[i+j] : '.'); 222 fprintf(stdout,"%c", ISPRINT(aData[i+j]) ? aData[i+j] : '.');
114 } 223 }
115 } 224 }
116 fprintf(stdout,"\n"); 225 fprintf(stdout,"\n");
117 } 226 }
118 return aData; 227 return aData;
119 } 228 }
120 229
121 /* 230 /*
122 ** Print an entire page of content as hex 231 ** Print an entire page of content as hex
123 */ 232 */
124 static void print_page(int iPg){ 233 static void print_page(int iPg){
125 int iStart; 234 int iStart;
126 unsigned char *aData; 235 unsigned char *aData;
127 iStart = (iPg-1)*pagesize; 236 iStart = (iPg-1)*g.pagesize;
128 fprintf(stdout, "Page %d: (offsets 0x%x..0x%x)\n", 237 fprintf(stdout, "Page %d: (offsets 0x%x..0x%x)\n",
129 iPg, iStart, iStart+pagesize-1); 238 iPg, iStart, iStart+g.pagesize-1);
130 aData = print_byte_range(iStart, pagesize, 0); 239 aData = print_byte_range(iStart, g.pagesize, 0);
131 free(aData); 240 sqlite3_free(aData);
132 } 241 }
133 242
134 243
135 /* Print a line of decode output showing a 4-byte integer. 244 /* Print a line of decode output showing a 4-byte integer.
136 */ 245 */
137 static void print_decode_line( 246 static void print_decode_line(
138 unsigned char *aData, /* Content being decoded */ 247 unsigned char *aData, /* Content being decoded */
139 int ofst, int nByte, /* Start and size of decode */ 248 int ofst, int nByte, /* Start and size of decode */
140 const char *zMsg /* Message to append */ 249 const char *zMsg /* Message to append */
141 ){ 250 ){
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 ** Compute the local payload size given the total payload size and 367 ** Compute the local payload size given the total payload size and
259 ** the page size. 368 ** the page size.
260 */ 369 */
261 static i64 localPayload(i64 nPayload, char cType){ 370 static i64 localPayload(i64 nPayload, char cType){
262 i64 maxLocal; 371 i64 maxLocal;
263 i64 minLocal; 372 i64 minLocal;
264 i64 surplus; 373 i64 surplus;
265 i64 nLocal; 374 i64 nLocal;
266 if( cType==13 ){ 375 if( cType==13 ){
267 /* Table leaf */ 376 /* Table leaf */
268 maxLocal = pagesize-35; 377 maxLocal = g.pagesize-35;
269 minLocal = (pagesize-12)*32/255-23; 378 minLocal = (g.pagesize-12)*32/255-23;
270 }else{ 379 }else{
271 maxLocal = (pagesize-12)*64/255-23; 380 maxLocal = (g.pagesize-12)*64/255-23;
272 minLocal = (pagesize-12)*32/255-23; 381 minLocal = (g.pagesize-12)*32/255-23;
273 } 382 }
274 if( nPayload>maxLocal ){ 383 if( nPayload>maxLocal ){
275 surplus = minLocal + (nPayload-minLocal)%(pagesize-4); 384 surplus = minLocal + (nPayload-minLocal)%(g.pagesize-4);
276 if( surplus<=maxLocal ){ 385 if( surplus<=maxLocal ){
277 nLocal = surplus; 386 nLocal = surplus;
278 }else{ 387 }else{
279 nLocal = minLocal; 388 nLocal = minLocal;
280 } 389 }
281 }else{ 390 }else{
282 nLocal = nPayload; 391 nLocal = nPayload;
283 } 392 }
284 return nLocal; 393 return nLocal;
285 } 394 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 ** Write a full decode on stdout for the cell at a[ofst]. 477 ** Write a full decode on stdout for the cell at a[ofst].
369 ** Assume the page contains a header of size szPgHdr bytes. 478 ** Assume the page contains a header of size szPgHdr bytes.
370 */ 479 */
371 static void decodeCell( 480 static void decodeCell(
372 unsigned char *a, /* Page content (without the page-1 header) */ 481 unsigned char *a, /* Page content (without the page-1 header) */
373 unsigned pgno, /* Page number */ 482 unsigned pgno, /* Page number */
374 int iCell, /* Cell index */ 483 int iCell, /* Cell index */
375 int szPgHdr, /* Size of the page header. 0 or 100 */ 484 int szPgHdr, /* Size of the page header. 0 or 100 */
376 int ofst /* Cell begins at a[ofst] */ 485 int ofst /* Cell begins at a[ofst] */
377 ){ 486 ){
378 int i, j; 487 int i, j = 0;
379 int leftChild; 488 int leftChild;
380 i64 k; 489 i64 k;
381 i64 nPayload; 490 i64 nPayload;
382 i64 rowid; 491 i64 rowid;
383 i64 nHdr; 492 i64 nHdr;
384 i64 iType; 493 i64 iType;
385 i64 nLocal; 494 i64 nLocal;
386 unsigned char *x = a + ofst; 495 unsigned char *x = a + ofst;
387 unsigned char *end; 496 unsigned char *end;
388 unsigned char cType = a[0]; 497 unsigned char cType = a[0];
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 char zConst[32]; 595 char zConst[32];
487 if( (typeCol[i]&1)==0 ){ 596 if( (typeCol[i]&1)==0 ){
488 zConst[0] = 'x'; 597 zConst[0] = 'x';
489 zConst[1] = '\''; 598 zConst[1] = '\'';
490 for(ii=2, jj=0; jj<szCol[i] && ii<24; jj++, ii+=2){ 599 for(ii=2, jj=0; jj<szCol[i] && ii<24; jj++, ii+=2){
491 sprintf(zConst+ii, "%02x", pData[jj]); 600 sprintf(zConst+ii, "%02x", pData[jj]);
492 } 601 }
493 }else{ 602 }else{
494 zConst[0] = '\''; 603 zConst[0] = '\'';
495 for(ii=1, jj=0; jj<szCol[i] && ii<24; jj++, ii++){ 604 for(ii=1, jj=0; jj<szCol[i] && ii<24; jj++, ii++){
496 zConst[ii] = isprint(pData[jj]) ? pData[jj] : '.'; 605 zConst[ii] = ISPRINT(pData[jj]) ? pData[jj] : '.';
497 } 606 }
498 zConst[ii] = 0; 607 zConst[ii] = 0;
499 } 608 }
500 if( jj<szCol[i] ){ 609 if( jj<szCol[i] ){
501 memcpy(zConst+ii, "...'", 5); 610 memcpy(zConst+ii, "...'", 5);
502 }else{ 611 }else{
503 memcpy(zConst+ii, "'", 2); 612 memcpy(zConst+ii, "'", 2);
504 } 613 }
505 printf("%s\n", zConst); 614 printf("%s\n", zConst);
506 } 615 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 case 2: zType = "index interior node"; break; 648 case 2: zType = "index interior node"; break;
540 case 5: zType = "table interior node"; break; 649 case 5: zType = "table interior node"; break;
541 case 10: zType = "index leaf"; break; 650 case 10: zType = "index leaf"; break;
542 case 13: zType = "table leaf"; break; 651 case 13: zType = "table leaf"; break;
543 } 652 }
544 while( zArgs[0] ){ 653 while( zArgs[0] ){
545 switch( zArgs[0] ){ 654 switch( zArgs[0] ){
546 case 'c': showCellContent = 1; break; 655 case 'c': showCellContent = 1; break;
547 case 'm': showMap = 1; break; 656 case 'm': showMap = 1; break;
548 case 'd': { 657 case 'd': {
549 if( !isdigit(zArgs[1]) ){ 658 if( !ISDIGIT(zArgs[1]) ){
550 cellToDecode = -1; 659 cellToDecode = -1;
551 }else{ 660 }else{
552 cellToDecode = 0; 661 cellToDecode = 0;
553 while( isdigit(zArgs[1]) ){ 662 while( ISDIGIT(zArgs[1]) ){
554 zArgs++; 663 zArgs++;
555 cellToDecode = cellToDecode*10 + zArgs[0] - '0'; 664 cellToDecode = cellToDecode*10 + zArgs[0] - '0';
556 } 665 }
557 } 666 }
558 break; 667 break;
559 } 668 }
560 } 669 }
561 zArgs++; 670 zArgs++;
562 } 671 }
563 nCell = a[3]*256 + a[4]; 672 nCell = a[3]*256 + a[4];
564 iCellPtr = (a[0]==2 || a[0]==5) ? 12 : 8; 673 iCellPtr = (a[0]==2 || a[0]==5) ? 12 : 8;
565 if( cellToDecode>=nCell ){ 674 if( cellToDecode>=nCell ){
566 printf("Page %d has only %d cells\n", pgno, nCell); 675 printf("Page %d has only %d cells\n", pgno, nCell);
567 return; 676 return;
568 } 677 }
569 printf("Header on btree page %d:\n", pgno); 678 printf("Header on btree page %d:\n", pgno);
570 print_decode_line(a, 0, 1, zType); 679 print_decode_line(a, 0, 1, zType);
571 print_decode_line(a, 1, 2, "Offset to first freeblock"); 680 print_decode_line(a, 1, 2, "Offset to first freeblock");
572 print_decode_line(a, 3, 2, "Number of cells on this page"); 681 print_decode_line(a, 3, 2, "Number of cells on this page");
573 print_decode_line(a, 5, 2, "Offset to cell content area"); 682 print_decode_line(a, 5, 2, "Offset to cell content area");
574 print_decode_line(a, 7, 1, "Fragmented byte count"); 683 print_decode_line(a, 7, 1, "Fragmented byte count");
575 if( a[0]==2 || a[0]==5 ){ 684 if( a[0]==2 || a[0]==5 ){
576 print_decode_line(a, 8, 4, "Right child"); 685 print_decode_line(a, 8, 4, "Right child");
577 } 686 }
578 if( cellToDecode==(-2) && nCell>0 ){ 687 if( cellToDecode==(-2) && nCell>0 ){
579 printf(" key: lx=left-child n=payload-size r=rowid\n"); 688 printf(" key: lx=left-child n=payload-size r=rowid\n");
580 } 689 }
581 if( showMap ){ 690 if( showMap ){
582 zMap = malloc(pagesize); 691 zMap = sqlite3_malloc(g.pagesize);
583 memset(zMap, '.', pagesize); 692 memset(zMap, '.', g.pagesize);
584 memset(zMap, '1', hdrSize); 693 memset(zMap, '1', hdrSize);
585 memset(&zMap[hdrSize], 'H', iCellPtr); 694 memset(&zMap[hdrSize], 'H', iCellPtr);
586 memset(&zMap[hdrSize+iCellPtr], 'P', 2*nCell); 695 memset(&zMap[hdrSize+iCellPtr], 'P', 2*nCell);
587 } 696 }
588 for(i=0; i<nCell; i++){ 697 for(i=0; i<nCell; i++){
589 int cofst = iCellPtr + i*2; 698 int cofst = iCellPtr + i*2;
590 char *zDesc; 699 char *zDesc;
591 i64 n; 700 i64 n;
592 701
593 cofst = a[cofst]*256 + a[cofst+1]; 702 cofst = a[cofst]*256 + a[cofst+1];
594 n = describeCell(a[0], &a[cofst-hdrSize], showCellContent, &zDesc); 703 n = describeCell(a[0], &a[cofst-hdrSize], showCellContent, &zDesc);
595 if( showMap ){ 704 if( showMap ){
596 char zBuf[30]; 705 char zBuf[30];
597 memset(&zMap[cofst], '*', (size_t)n); 706 memset(&zMap[cofst], '*', (size_t)n);
598 zMap[cofst] = '['; 707 zMap[cofst] = '[';
599 zMap[cofst+n-1] = ']'; 708 zMap[cofst+n-1] = ']';
600 sprintf(zBuf, "%d", i); 709 sprintf(zBuf, "%d", i);
601 j = (int)strlen(zBuf); 710 j = (int)strlen(zBuf);
602 if( j<=n-2 ) memcpy(&zMap[cofst+1], zBuf, j); 711 if( j<=n-2 ) memcpy(&zMap[cofst+1], zBuf, j);
603 } 712 }
604 if( cellToDecode==(-2) ){ 713 if( cellToDecode==(-2) ){
605 printf(" %03x: cell[%d] %s\n", cofst, i, zDesc); 714 printf(" %03x: cell[%d] %s\n", cofst, i, zDesc);
606 }else if( cellToDecode==(-1) || cellToDecode==i ){ 715 }else if( cellToDecode==(-1) || cellToDecode==i ){
607 decodeCell(a, pgno, i, hdrSize, cofst-hdrSize); 716 decodeCell(a, pgno, i, hdrSize, cofst-hdrSize);
608 } 717 }
609 } 718 }
610 if( showMap ){ 719 if( showMap ){
611 printf("Page map: (H=header P=cell-index 1=page-1-header .=free-space)\n"); 720 printf("Page map: (H=header P=cell-index 1=page-1-header .=free-space)\n");
612 for(i=0; i<pagesize; i+=64){ 721 for(i=0; i<g.pagesize; i+=64){
613 printf(" %03x: %.64s\n", i, &zMap[i]); 722 printf(" %03x: %.64s\n", i, &zMap[i]);
614 } 723 }
615 free(zMap); 724 sqlite3_free(zMap);
616 } 725 }
617 } 726 }
618 727
619 /* 728 /*
620 ** Decode a freelist trunk page. 729 ** Decode a freelist trunk page.
621 */ 730 */
622 static void decode_trunk_page( 731 static void decode_trunk_page(
623 int pgno, /* The page number */ 732 int pgno, /* The page number */
624 int pagesize, /* Size of each page */
625 int detail, /* Show leaf pages if true */ 733 int detail, /* Show leaf pages if true */
626 int recursive /* Follow the trunk change if true */ 734 int recursive /* Follow the trunk change if true */
627 ){ 735 ){
628 int n, i; 736 int n, i;
629 unsigned char *a; 737 unsigned char *a;
630 while( pgno>0 ){ 738 while( pgno>0 ){
631 a = getContent((pgno-1)*pagesize, pagesize); 739 a = fileRead((pgno-1)*g.pagesize, g.pagesize);
632 printf("Decode of freelist trunk page %d:\n", pgno); 740 printf("Decode of freelist trunk page %d:\n", pgno);
633 print_decode_line(a, 0, 4, "Next freelist trunk page"); 741 print_decode_line(a, 0, 4, "Next freelist trunk page");
634 print_decode_line(a, 4, 4, "Number of entries on this page"); 742 print_decode_line(a, 4, 4, "Number of entries on this page");
635 if( detail ){ 743 if( detail ){
636 n = (int)decodeInt32(&a[4]); 744 n = (int)decodeInt32(&a[4]);
637 for(i=0; i<n; i++){ 745 for(i=0; i<n; i++){
638 unsigned int x = decodeInt32(&a[8+4*i]); 746 unsigned int x = decodeInt32(&a[8+4*i]);
639 char zIdx[10]; 747 char zIdx[10];
640 sprintf(zIdx, "[%d]", i); 748 sprintf(zIdx, "[%d]", i);
641 printf(" %5s %7u", zIdx, x); 749 printf(" %5s %7u", zIdx, x);
642 if( i%5==4 ) printf("\n"); 750 if( i%5==4 ) printf("\n");
643 } 751 }
644 if( i%5!=0 ) printf("\n"); 752 if( i%5!=0 ) printf("\n");
645 } 753 }
646 if( !recursive ){ 754 if( !recursive ){
647 pgno = 0; 755 pgno = 0;
648 }else{ 756 }else{
649 pgno = (int)decodeInt32(&a[0]); 757 pgno = (int)decodeInt32(&a[0]);
650 } 758 }
651 free(a); 759 sqlite3_free(a);
652 } 760 }
653 } 761 }
654 762
655 /* 763 /*
656 ** A short text comment on the use of each page. 764 ** A short text comment on the use of each page.
657 */ 765 */
658 static char **zPageUse; 766 static char **zPageUse;
659 767
660 /* 768 /*
661 ** Add a comment on the use of a page. 769 ** Add a comment on the use of a page.
662 */ 770 */
663 static void page_usage_msg(int pgno, const char *zFormat, ...){ 771 static void page_usage_msg(int pgno, const char *zFormat, ...){
664 va_list ap; 772 va_list ap;
665 char *zMsg; 773 char *zMsg;
666 774
667 va_start(ap, zFormat); 775 va_start(ap, zFormat);
668 zMsg = sqlite3_vmprintf(zFormat, ap); 776 zMsg = sqlite3_vmprintf(zFormat, ap);
669 va_end(ap); 777 va_end(ap);
670 if( pgno<=0 || pgno>mxPage ){ 778 if( pgno<=0 || pgno>g.mxPage ){
671 printf("ERROR: page %d out of range 1..%d: %s\n", 779 printf("ERROR: page %d out of range 1..%d: %s\n",
672 pgno, mxPage, zMsg); 780 pgno, g.mxPage, zMsg);
673 sqlite3_free(zMsg); 781 sqlite3_free(zMsg);
674 return; 782 return;
675 } 783 }
676 if( zPageUse[pgno]!=0 ){ 784 if( zPageUse[pgno]!=0 ){
677 printf("ERROR: page %d used multiple times:\n", pgno); 785 printf("ERROR: page %d used multiple times:\n", pgno);
678 printf("ERROR: previous: %s\n", zPageUse[pgno]); 786 printf("ERROR: previous: %s\n", zPageUse[pgno]);
679 printf("ERROR: current: %s\n", zMsg); 787 printf("ERROR: current: %s\n", zMsg);
680 sqlite3_free(zPageUse[pgno]); 788 sqlite3_free(zPageUse[pgno]);
681 } 789 }
682 zPageUse[pgno] = zMsg; 790 zPageUse[pgno] = zMsg;
(...skipping 27 matching lines...) Expand all
710 nPayload = nLocal = 0; 818 nPayload = nLocal = 0;
711 } 819 }
712 if( cType==5 || cType==13 ){ 820 if( cType==5 || cType==13 ){
713 i = decodeVarint(a, &rowid); 821 i = decodeVarint(a, &rowid);
714 a += i; 822 a += i;
715 n += i; 823 n += i;
716 } 824 }
717 if( nLocal<nPayload ){ 825 if( nLocal<nPayload ){
718 int ovfl = decodeInt32(a+nLocal); 826 int ovfl = decodeInt32(a+nLocal);
719 int cnt = 0; 827 int cnt = 0;
720 while( ovfl && (cnt++)<mxPage ){ 828 while( ovfl && (cnt++)<g.mxPage ){
721 page_usage_msg(ovfl, "overflow %d from cell %d of page %d", 829 page_usage_msg(ovfl, "overflow %d from cell %d of page %d",
722 cnt, cellno, pgno); 830 cnt, cellno, pgno);
723 a = getContent((ovfl-1)*pagesize, 4); 831 a = fileRead((ovfl-1)*g.pagesize, 4);
724 ovfl = decodeInt32(a); 832 ovfl = decodeInt32(a);
725 free(a); 833 sqlite3_free(a);
726 } 834 }
727 } 835 }
728 } 836 }
729 837
730 838
731 /* 839 /*
732 ** Describe the usages of a b-tree page 840 ** Describe the usages of a b-tree page
733 */ 841 */
734 static void page_usage_btree( 842 static void page_usage_btree(
735 int pgno, /* Page to describe */ 843 int pgno, /* Page to describe */
736 int parent, /* Parent of this page. 0 for root pages */ 844 int parent, /* Parent of this page. 0 for root pages */
737 int idx, /* Which child of the parent */ 845 int idx, /* Which child of the parent */
738 const char *zName /* Name of the table */ 846 const char *zName /* Name of the table */
739 ){ 847 ){
740 unsigned char *a; 848 unsigned char *a;
741 const char *zType = "corrupt node"; 849 const char *zType = "corrupt node";
742 int nCell; 850 int nCell;
743 int i; 851 int i;
744 int hdr = pgno==1 ? 100 : 0; 852 int hdr = pgno==1 ? 100 : 0;
745 853
746 if( pgno<=0 || pgno>mxPage ) return; 854 if( pgno<=0 || pgno>g.mxPage ) return;
747 a = getContent((pgno-1)*pagesize, pagesize); 855 a = fileRead((pgno-1)*g.pagesize, g.pagesize);
748 switch( a[hdr] ){ 856 switch( a[hdr] ){
749 case 2: zType = "interior node of index"; break; 857 case 2: zType = "interior node of index"; break;
750 case 5: zType = "interior node of table"; break; 858 case 5: zType = "interior node of table"; break;
751 case 10: zType = "leaf of index"; break; 859 case 10: zType = "leaf of index"; break;
752 case 13: zType = "leaf of table"; break; 860 case 13: zType = "leaf of table"; break;
753 } 861 }
754 if( parent ){ 862 if( parent ){
755 page_usage_msg(pgno, "%s [%s], child %d of page %d", 863 page_usage_msg(pgno, "%s [%s], child %d of page %d",
756 zType, zName, idx, parent); 864 zType, zName, idx, parent);
757 }else{ 865 }else{
(...skipping 16 matching lines...) Expand all
774 } 882 }
775 if( a[hdr]==2 || a[hdr]==10 || a[hdr]==13 ){ 883 if( a[hdr]==2 || a[hdr]==10 || a[hdr]==13 ){
776 int cellstart = hdr + 8 + 4*(a[hdr]<=5); 884 int cellstart = hdr + 8 + 4*(a[hdr]<=5);
777 for(i=0; i<nCell; i++){ 885 for(i=0; i<nCell; i++){
778 int ofst; 886 int ofst;
779 ofst = cellstart + i*2; 887 ofst = cellstart + i*2;
780 ofst = a[ofst]*256 + a[ofst+1]; 888 ofst = a[ofst]*256 + a[ofst+1];
781 page_usage_cell(a[hdr], a+ofst, pgno, i); 889 page_usage_cell(a[hdr], a+ofst, pgno, i);
782 } 890 }
783 } 891 }
784 free(a); 892 sqlite3_free(a);
785 } 893 }
786 894
787 /* 895 /*
788 ** Determine page usage by the freelist 896 ** Determine page usage by the freelist
789 */ 897 */
790 static void page_usage_freelist(int pgno){ 898 static void page_usage_freelist(int pgno){
791 unsigned char *a; 899 unsigned char *a;
792 int cnt = 0; 900 int cnt = 0;
793 int i; 901 int i;
794 int n; 902 int n;
795 int iNext; 903 int iNext;
796 int parent = 1; 904 int parent = 1;
797 905
798 while( pgno>0 && pgno<=mxPage && (cnt++)<mxPage ){ 906 while( pgno>0 && pgno<=g.mxPage && (cnt++)<g.mxPage ){
799 page_usage_msg(pgno, "freelist trunk #%d child of %d", cnt, parent); 907 page_usage_msg(pgno, "freelist trunk #%d child of %d", cnt, parent);
800 a = getContent((pgno-1)*pagesize, pagesize); 908 a = fileRead((pgno-1)*g.pagesize, g.pagesize);
801 iNext = decodeInt32(a); 909 iNext = decodeInt32(a);
802 n = decodeInt32(a+4); 910 n = decodeInt32(a+4);
803 for(i=0; i<n; i++){ 911 for(i=0; i<n; i++){
804 int child = decodeInt32(a + (i*4+8)); 912 int child = decodeInt32(a + (i*4+8));
805 page_usage_msg(child, "freelist leaf, child %d of trunk page %d", 913 page_usage_msg(child, "freelist leaf, child %d of trunk page %d",
806 i, pgno); 914 i, pgno);
807 } 915 }
808 free(a); 916 sqlite3_free(a);
809 parent = pgno; 917 parent = pgno;
810 pgno = iNext; 918 pgno = iNext;
811 } 919 }
812 } 920 }
813 921
814 /* 922 /*
815 ** Determine pages used as PTRMAP pages 923 ** Determine pages used as PTRMAP pages
816 */ 924 */
817 static void page_usage_ptrmap(unsigned char *a){ 925 static void page_usage_ptrmap(unsigned char *a){
818 if( a[55] ){ 926 if( a[55] ){
819 int usable = pagesize - a[20]; 927 int usable = g.pagesize - a[20];
820 int pgno = 2; 928 int pgno = 2;
821 int perPage = usable/5; 929 int perPage = usable/5;
822 while( pgno<=mxPage ){ 930 while( pgno<=g.mxPage ){
823 page_usage_msg(pgno, "PTRMAP page covering %d..%d", 931 page_usage_msg(pgno, "PTRMAP page covering %d..%d",
824 pgno+1, pgno+perPage); 932 pgno+1, pgno+perPage);
825 pgno += perPage + 1; 933 pgno += perPage + 1;
826 } 934 }
827 } 935 }
828 } 936 }
829 937
830 /* 938 /*
831 ** Try to figure out how every page in the database file is being used. 939 ** Try to figure out how every page in the database file is being used.
832 */ 940 */
833 static void page_usage_report(const char *zDbName){ 941 static void page_usage_report(const char *zPrg, const char *zDbName){
834 int i, j; 942 int i, j;
835 int rc; 943 int rc;
836 sqlite3 *db; 944 sqlite3 *db;
837 sqlite3_stmt *pStmt; 945 sqlite3_stmt *pStmt;
838 unsigned char *a; 946 unsigned char *a;
839 char zQuery[200]; 947 char zQuery[200];
840 948
841 /* Avoid the pathological case */ 949 /* Avoid the pathological case */
842 if( mxPage<1 ){ 950 if( g.mxPage<1 ){
843 printf("empty database\n"); 951 printf("empty database\n");
844 return; 952 return;
845 } 953 }
846 954
847 /* Open the database file */ 955 /* Open the database file */
848 rc = sqlite3_open(zDbName, &db); 956 db = openDatabase(zPrg, zDbName);
849 if( rc ){
850 printf("cannot open database: %s\n", sqlite3_errmsg(db));
851 sqlite3_close(db);
852 return;
853 }
854 957
855 /* Set up global variables zPageUse[] and mxPage to record page 958 /* Set up global variables zPageUse[] and g.mxPage to record page
856 ** usages */ 959 ** usages */
857 zPageUse = sqlite3_malloc( sizeof(zPageUse[0])*(mxPage+1) ); 960 zPageUse = sqlite3_malloc( sizeof(zPageUse[0])*(g.mxPage+1) );
858 if( zPageUse==0 ) out_of_memory(); 961 if( zPageUse==0 ) out_of_memory();
859 memset(zPageUse, 0, sizeof(zPageUse[0])*(mxPage+1)); 962 memset(zPageUse, 0, sizeof(zPageUse[0])*(g.mxPage+1));
860 963
861 /* Discover the usage of each page */ 964 /* Discover the usage of each page */
862 a = getContent(0, 100); 965 a = fileRead(0, 100);
863 page_usage_freelist(decodeInt32(a+32)); 966 page_usage_freelist(decodeInt32(a+32));
864 page_usage_ptrmap(a); 967 page_usage_ptrmap(a);
865 free(a); 968 sqlite3_free(a);
866 page_usage_btree(1, 0, 0, "sqlite_master"); 969 page_usage_btree(1, 0, 0, "sqlite_master");
867 sqlite3_exec(db, "PRAGMA writable_schema=ON", 0, 0, 0); 970 sqlite3_exec(db, "PRAGMA writable_schema=ON", 0, 0, 0);
868 for(j=0; j<2; j++){ 971 for(j=0; j<2; j++){
869 sqlite3_snprintf(sizeof(zQuery), zQuery, 972 sqlite3_snprintf(sizeof(zQuery), zQuery,
870 "SELECT type, name, rootpage FROM SQLITE_MASTER WHERE rootpage" 973 "SELECT type, name, rootpage FROM SQLITE_MASTER WHERE rootpage"
871 " ORDER BY rowid %s", j?"DESC":""); 974 " ORDER BY rowid %s", j?"DESC":"");
872 rc = sqlite3_prepare_v2(db, zQuery, -1, &pStmt, 0); 975 rc = sqlite3_prepare_v2(db, zQuery, -1, &pStmt, 0);
873 if( rc==SQLITE_OK ){ 976 if( rc==SQLITE_OK ){
874 while( sqlite3_step(pStmt)==SQLITE_ROW ){ 977 while( sqlite3_step(pStmt)==SQLITE_ROW ){
875 int pgno = sqlite3_column_int(pStmt, 2); 978 int pgno = sqlite3_column_int(pStmt, 2);
876 page_usage_btree(pgno, 0, 0, (const char*)sqlite3_column_text(pStmt,1)); 979 page_usage_btree(pgno, 0, 0, (const char*)sqlite3_column_text(pStmt,1));
877 } 980 }
878 }else{ 981 }else{
879 printf("ERROR: cannot query database: %s\n", sqlite3_errmsg(db)); 982 printf("ERROR: cannot query database: %s\n", sqlite3_errmsg(db));
880 } 983 }
881 rc = sqlite3_finalize(pStmt); 984 rc = sqlite3_finalize(pStmt);
882 if( rc==SQLITE_OK ) break; 985 if( rc==SQLITE_OK ) break;
883 } 986 }
884 sqlite3_close(db); 987 sqlite3_close(db);
885 988
886 /* Print the report and free memory used */ 989 /* Print the report and free memory used */
887 for(i=1; i<=mxPage; i++){ 990 for(i=1; i<=g.mxPage; i++){
888 printf("%5d: %s\n", i, zPageUse[i] ? zPageUse[i] : "???"); 991 printf("%5d: %s\n", i, zPageUse[i] ? zPageUse[i] : "???");
889 sqlite3_free(zPageUse[i]); 992 sqlite3_free(zPageUse[i]);
890 } 993 }
891 sqlite3_free(zPageUse); 994 sqlite3_free(zPageUse);
892 zPageUse = 0; 995 zPageUse = 0;
893 } 996 }
894 997
895 /* 998 /*
896 ** Try to figure out how every page in the database file is being used. 999 ** Try to figure out how every page in the database file is being used.
897 */ 1000 */
898 static void ptrmap_coverage_report(const char *zDbName){ 1001 static void ptrmap_coverage_report(const char *zDbName){
899 int pgno; 1002 int pgno;
900 unsigned char *aHdr; 1003 unsigned char *aHdr;
901 unsigned char *a; 1004 unsigned char *a;
902 int usable; 1005 int usable;
903 int perPage; 1006 int perPage;
904 int i; 1007 int i;
905 1008
906 /* Avoid the pathological case */ 1009 /* Avoid the pathological case */
907 if( mxPage<1 ){ 1010 if( g.mxPage<1 ){
908 printf("empty database\n"); 1011 printf("empty database\n");
909 return; 1012 return;
910 } 1013 }
911 1014
912 /* Make sure PTRMAPs are used in this database */ 1015 /* Make sure PTRMAPs are used in this database */
913 aHdr = getContent(0, 100); 1016 aHdr = fileRead(0, 100);
914 if( aHdr[55]==0 ){ 1017 if( aHdr[55]==0 ){
915 printf("database does not use PTRMAP pages\n"); 1018 printf("database does not use PTRMAP pages\n");
916 return; 1019 return;
917 } 1020 }
918 usable = pagesize - aHdr[20]; 1021 usable = g.pagesize - aHdr[20];
919 perPage = usable/5; 1022 perPage = usable/5;
920 free(aHdr); 1023 sqlite3_free(aHdr);
921 printf("%5d: root of sqlite_master\n", 1); 1024 printf("%5d: root of sqlite_master\n", 1);
922 for(pgno=2; pgno<=mxPage; pgno += perPage+1){ 1025 for(pgno=2; pgno<=g.mxPage; pgno += perPage+1){
923 printf("%5d: PTRMAP page covering %d..%d\n", pgno, 1026 printf("%5d: PTRMAP page covering %d..%d\n", pgno,
924 pgno+1, pgno+perPage); 1027 pgno+1, pgno+perPage);
925 a = getContent((pgno-1)*pagesize, usable); 1028 a = fileRead((pgno-1)*g.pagesize, usable);
926 for(i=0; i+5<=usable && pgno+1+i/5<=mxPage; i+=5){ 1029 for(i=0; i+5<=usable && pgno+1+i/5<=g.mxPage; i+=5){
927 const char *zType = "???"; 1030 const char *zType = "???";
928 unsigned int iFrom = decodeInt32(&a[i+1]); 1031 unsigned int iFrom = decodeInt32(&a[i+1]);
929 switch( a[i] ){ 1032 switch( a[i] ){
930 case 1: zType = "b-tree root page"; break; 1033 case 1: zType = "b-tree root page"; break;
931 case 2: zType = "freelist page"; break; 1034 case 2: zType = "freelist page"; break;
932 case 3: zType = "first page of overflow"; break; 1035 case 3: zType = "first page of overflow"; break;
933 case 4: zType = "later page of overflow"; break; 1036 case 4: zType = "later page of overflow"; break;
934 case 5: zType = "b-tree non-root page"; break; 1037 case 5: zType = "b-tree non-root page"; break;
935 } 1038 }
936 printf("%5d: %s, parent=%u\n", pgno+1+i/5, zType, iFrom); 1039 printf("%5d: %s, parent=%u\n", pgno+1+i/5, zType, iFrom);
937 } 1040 }
938 free(a); 1041 sqlite3_free(a);
939 } 1042 }
940 } 1043 }
941 1044
942 /* 1045 /*
943 ** Print a usage comment 1046 ** Print a usage comment
944 */ 1047 */
945 static void usage(const char *argv0){ 1048 static void usage(const char *argv0){
946 fprintf(stderr, "Usage %s FILENAME ?args...?\n\n", argv0); 1049 fprintf(stderr, "Usage %s ?--uri? FILENAME ?args...?\n\n", argv0);
947 fprintf(stderr, 1050 fprintf(stderr,
1051 "switches:\n"
1052 " --raw Read db file directly, bypassing SQLite VFS\n"
948 "args:\n" 1053 "args:\n"
949 " dbheader Show database header\n" 1054 " dbheader Show database header\n"
950 " pgidx Index of how each page is used\n" 1055 " pgidx Index of how each page is used\n"
951 " ptrmap Show all PTRMAP page content\n" 1056 " ptrmap Show all PTRMAP page content\n"
952 " NNN..MMM Show hex of pages NNN through MMM\n" 1057 " NNN..MMM Show hex of pages NNN through MMM\n"
953 " NNN..end Show hex of pages NNN through end of file\n" 1058 " NNN..end Show hex of pages NNN through end of file\n"
954 " NNNb Decode btree page NNN\n" 1059 " NNNb Decode btree page NNN\n"
955 " NNNbc Decode btree page NNN and show content\n" 1060 " NNNbc Decode btree page NNN and show content\n"
956 " NNNbm Decode btree page NNN and show a layout map\n" 1061 " NNNbm Decode btree page NNN and show a layout map\n"
957 " NNNbdCCC Decode cell CCC on btree page NNN\n" 1062 " NNNbdCCC Decode cell CCC on btree page NNN\n"
958 " NNNt Decode freelist trunk page NNN\n" 1063 " NNNt Decode freelist trunk page NNN\n"
959 " NNNtd Show leaf freelist pages on the decode\n" 1064 " NNNtd Show leaf freelist pages on the decode\n"
960 " NNNtr Recursively decode freelist starting at NNN\n" 1065 " NNNtr Recursively decode freelist starting at NNN\n"
961 ); 1066 );
962 } 1067 }
963 1068
964 int main(int argc, char **argv){ 1069 int main(int argc, char **argv){
965 struct stat sbuf; 1070 sqlite3_int64 szFile;
966 unsigned char zPgSz[2]; 1071 unsigned char *zPgSz;
967 if( argc<2 ){ 1072 const char *zPrg = argv[0]; /* Name of this executable */
968 usage(argv[0]); 1073 char **azArg = argv;
1074 int nArg = argc;
1075
1076 /* Check for the "--uri" or "-uri" switch. */
1077 if( nArg>1 ){
1078 if( sqlite3_stricmp("-raw", azArg[1])==0
1079 || sqlite3_stricmp("--raw", azArg[1])==0
1080 ){
1081 g.bRaw = 1;
1082 azArg++;
1083 nArg--;
1084 }
1085 }
1086
1087 if( nArg<2 ){
1088 usage(zPrg);
969 exit(1); 1089 exit(1);
970 } 1090 }
971 db = open(argv[1], O_RDONLY); 1091
972 if( db<0 ){ 1092 fileOpen(zPrg, azArg[1]);
973 fprintf(stderr,"%s: can't open %s\n", argv[0], argv[1]); 1093 szFile = fileGetsize();
974 exit(1); 1094
975 } 1095 zPgSz = fileRead(16, 2);
976 zPgSz[0] = 0; 1096 g.pagesize = zPgSz[0]*256 + zPgSz[1]*65536;
977 zPgSz[1] = 0; 1097 if( g.pagesize==0 ) g.pagesize = 1024;
978 lseek(db, 16, SEEK_SET); 1098 sqlite3_free(zPgSz);
979 if( read(db, zPgSz, 2)<2 ) memset(zPgSz, 0, 2); 1099
980 pagesize = zPgSz[0]*256 + zPgSz[1]*65536; 1100 printf("Pagesize: %d\n", g.pagesize);
981 if( pagesize==0 ) pagesize = 1024; 1101 g.mxPage = (szFile+g.pagesize-1)/g.pagesize;
982 printf("Pagesize: %d\n", pagesize); 1102
983 fstat(db, &sbuf); 1103 printf("Available pages: 1..%d\n", g.mxPage);
984 mxPage = sbuf.st_size/pagesize; 1104 if( nArg==2 ){
985 printf("Available pages: 1..%d\n", mxPage);
986 if( argc==2 ){
987 int i; 1105 int i;
988 for(i=1; i<=mxPage; i++) print_page(i); 1106 for(i=1; i<=g.mxPage; i++) print_page(i);
989 }else{ 1107 }else{
990 int i; 1108 int i;
991 for(i=2; i<argc; i++){ 1109 for(i=2; i<nArg; i++){
992 int iStart, iEnd; 1110 int iStart, iEnd;
993 char *zLeft; 1111 char *zLeft;
994 if( strcmp(argv[i], "dbheader")==0 ){ 1112 if( strcmp(azArg[i], "dbheader")==0 ){
995 print_db_header(); 1113 print_db_header();
996 continue; 1114 continue;
997 } 1115 }
998 if( strcmp(argv[i], "pgidx")==0 ){ 1116 if( strcmp(azArg[i], "pgidx")==0 ){
999 page_usage_report(argv[1]); 1117 page_usage_report(zPrg, azArg[1]);
1000 continue; 1118 continue;
1001 } 1119 }
1002 if( strcmp(argv[i], "ptrmap")==0 ){ 1120 if( strcmp(azArg[i], "ptrmap")==0 ){
1003 ptrmap_coverage_report(argv[1]); 1121 ptrmap_coverage_report(azArg[1]);
1004 continue; 1122 continue;
1005 } 1123 }
1006 if( strcmp(argv[i], "help")==0 ){ 1124 if( strcmp(azArg[i], "help")==0 ){
1007 usage(argv[0]); 1125 usage(zPrg);
1008 continue; 1126 continue;
1009 } 1127 }
1010 if( !isdigit(argv[i][0]) ){ 1128 if( !ISDIGIT(azArg[i][0]) ){
1011 fprintf(stderr, "%s: unknown option: [%s]\n", argv[0], argv[i]); 1129 fprintf(stderr, "%s: unknown option: [%s]\n", zPrg, azArg[i]);
1012 continue; 1130 continue;
1013 } 1131 }
1014 iStart = strtol(argv[i], &zLeft, 0); 1132 iStart = strtol(azArg[i], &zLeft, 0);
1015 if( zLeft && strcmp(zLeft,"..end")==0 ){ 1133 if( zLeft && strcmp(zLeft,"..end")==0 ){
1016 iEnd = mxPage; 1134 iEnd = g.mxPage;
1017 }else if( zLeft && zLeft[0]=='.' && zLeft[1]=='.' ){ 1135 }else if( zLeft && zLeft[0]=='.' && zLeft[1]=='.' ){
1018 iEnd = strtol(&zLeft[2], 0, 0); 1136 iEnd = strtol(&zLeft[2], 0, 0);
1019 }else if( zLeft && zLeft[0]=='b' ){ 1137 }else if( zLeft && zLeft[0]=='b' ){
1020 int ofst, nByte, hdrSize; 1138 int ofst, nByte, hdrSize;
1021 unsigned char *a; 1139 unsigned char *a;
1022 if( iStart==1 ){ 1140 if( iStart==1 ){
1023 ofst = hdrSize = 100; 1141 ofst = hdrSize = 100;
1024 nByte = pagesize-100; 1142 nByte = g.pagesize-100;
1025 }else{ 1143 }else{
1026 hdrSize = 0; 1144 hdrSize = 0;
1027 ofst = (iStart-1)*pagesize; 1145 ofst = (iStart-1)*g.pagesize;
1028 nByte = pagesize; 1146 nByte = g.pagesize;
1029 } 1147 }
1030 a = getContent(ofst, nByte); 1148 a = fileRead(ofst, nByte);
1031 decode_btree_page(a, iStart, hdrSize, &zLeft[1]); 1149 decode_btree_page(a, iStart, hdrSize, &zLeft[1]);
1032 free(a); 1150 sqlite3_free(a);
1033 continue; 1151 continue;
1034 }else if( zLeft && zLeft[0]=='t' ){ 1152 }else if( zLeft && zLeft[0]=='t' ){
1035 int detail = 0; 1153 int detail = 0;
1036 int recursive = 0; 1154 int recursive = 0;
1037 int i; 1155 int j;
1038 for(i=1; zLeft[i]; i++){ 1156 for(j=1; zLeft[j]; j++){
1039 if( zLeft[i]=='r' ) recursive = 1; 1157 if( zLeft[j]=='r' ) recursive = 1;
1040 if( zLeft[i]=='d' ) detail = 1; 1158 if( zLeft[j]=='d' ) detail = 1;
1041 } 1159 }
1042 decode_trunk_page(iStart, pagesize, detail, recursive); 1160 decode_trunk_page(iStart, detail, recursive);
1043 continue; 1161 continue;
1044 }else{ 1162 }else{
1045 iEnd = iStart; 1163 iEnd = iStart;
1046 } 1164 }
1047 if( iStart<1 || iEnd<iStart || iEnd>mxPage ){ 1165 if( iStart<1 || iEnd<iStart || iEnd>g.mxPage ){
1048 fprintf(stderr, 1166 fprintf(stderr,
1049 "Page argument should be LOWER?..UPPER?. Range 1 to %d\n", 1167 "Page argument should be LOWER?..UPPER?. Range 1 to %d\n",
1050 mxPage); 1168 g.mxPage);
1051 exit(1); 1169 exit(1);
1052 } 1170 }
1053 while( iStart<=iEnd ){ 1171 while( iStart<=iEnd ){
1054 print_page(iStart); 1172 print_page(iStart);
1055 iStart++; 1173 iStart++;
1056 } 1174 }
1057 } 1175 }
1058 } 1176 }
1059 close(db); 1177 fileClose();
1060 return 0; 1178 return 0;
1061 } 1179 }
OLDNEW
« no previous file with comments | « third_party/sqlite/src/tool/run-speed-test.sh ('k') | third_party/sqlite/src/tool/showjournal.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698