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

Side by Side Diff: third_party/sqlite/src/src/test_stat.c

Issue 901033002: Import SQLite 3.8.7.4. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Chromium changes to support SQLite 3.8.7.4. 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 ** 2010 July 12 2 ** 2010 July 12
3 ** 3 **
4 ** The author disclaims copyright to this source code. In place of 4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing: 5 ** a legal notice, here is a blessing:
6 ** 6 **
7 ** May you do good and not evil. 7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others. 8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give. 9 ** May you share freely, never taking more than you give.
10 ** 10 **
11 ****************************************************************************** 11 ******************************************************************************
12 ** 12 **
13 ** This file contains an implementation of the "dbstat" virtual table. 13 ** This file contains an implementation of the "dbstat" virtual table.
14 ** 14 **
15 ** The dbstat virtual table is used to extract low-level formatting 15 ** The dbstat virtual table is used to extract low-level formatting
16 ** information from an SQLite database in order to implement the 16 ** information from an SQLite database in order to implement the
17 ** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script 17 ** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script
18 ** for an example implementation. 18 ** for an example implementation.
19 */ 19 */
20 20
21 #include "sqliteInt.h" 21 #ifndef SQLITE_AMALGAMATION
22 # include "sqliteInt.h"
23 #endif
22 24
23 #ifndef SQLITE_OMIT_VIRTUALTABLE 25 #ifndef SQLITE_OMIT_VIRTUALTABLE
24 26
25 /* 27 /*
26 ** Page paths: 28 ** Page paths:
27 ** 29 **
28 ** The value of the 'path' column describes the path taken from the 30 ** The value of the 'path' column describes the path taken from the
29 ** root-node of the b-tree structure to each page. The value of the 31 ** root-node of the b-tree structure to each page. The value of the
30 ** root-node path is '/'. 32 ** root-node path is '/'.
31 ** 33 **
(...skipping 23 matching lines...) Expand all
55 */ 57 */
56 #define VTAB_SCHEMA \ 58 #define VTAB_SCHEMA \
57 "CREATE TABLE xx( " \ 59 "CREATE TABLE xx( " \
58 " name STRING, /* Name of table or index */" \ 60 " name STRING, /* Name of table or index */" \
59 " path INTEGER, /* Path to page from root */" \ 61 " path INTEGER, /* Path to page from root */" \
60 " pageno INTEGER, /* Page number */" \ 62 " pageno INTEGER, /* Page number */" \
61 " pagetype STRING, /* 'internal', 'leaf' or 'overflow' */" \ 63 " pagetype STRING, /* 'internal', 'leaf' or 'overflow' */" \
62 " ncell INTEGER, /* Cells on page (0 for overflow) */" \ 64 " ncell INTEGER, /* Cells on page (0 for overflow) */" \
63 " payload INTEGER, /* Bytes of payload on this page */" \ 65 " payload INTEGER, /* Bytes of payload on this page */" \
64 " unused INTEGER, /* Bytes of unused space on this page */" \ 66 " unused INTEGER, /* Bytes of unused space on this page */" \
65 " mx_payload INTEGER /* Largest payload size of all cells */" \ 67 " mx_payload INTEGER, /* Largest payload size of all cells */" \
68 " pgoffset INTEGER, /* Offset of page in file */" \
69 " pgsize INTEGER /* Size of the page */" \
66 ");" 70 ");"
67 71
68 #if 0
69 #define VTAB_SCHEMA2 \
70 "CREATE TABLE yy( " \
71 " pageno INTEGER, /* B-tree page number */" \
72 " cellno INTEGER, /* Cell number within page */" \
73 " local INTEGER, /* Bytes of content stored locally */" \
74 " payload INTEGER, /* Total cell payload size */" \
75 " novfl INTEGER /* Number of overflow pages */" \
76 ");"
77 #endif
78
79 72
80 typedef struct StatTable StatTable; 73 typedef struct StatTable StatTable;
81 typedef struct StatCursor StatCursor; 74 typedef struct StatCursor StatCursor;
82 typedef struct StatPage StatPage; 75 typedef struct StatPage StatPage;
83 typedef struct StatCell StatCell; 76 typedef struct StatCell StatCell;
84 77
85 struct StatCell { 78 struct StatCell {
86 int nLocal; /* Bytes of local payload */ 79 int nLocal; /* Bytes of local payload */
87 u32 iChildPg; /* Child node (or 0 if this is a leaf) */ 80 u32 iChildPg; /* Child node (or 0 if this is a leaf) */
88 int nOvfl; /* Entries in aOvfl[] */ 81 int nOvfl; /* Entries in aOvfl[] */
(...skipping 28 matching lines...) Expand all
117 110
118 /* Values to return. */ 111 /* Values to return. */
119 char *zName; /* Value of 'name' column */ 112 char *zName; /* Value of 'name' column */
120 char *zPath; /* Value of 'path' column */ 113 char *zPath; /* Value of 'path' column */
121 u32 iPageno; /* Value of 'pageno' column */ 114 u32 iPageno; /* Value of 'pageno' column */
122 char *zPagetype; /* Value of 'pagetype' column */ 115 char *zPagetype; /* Value of 'pagetype' column */
123 int nCell; /* Value of 'ncell' column */ 116 int nCell; /* Value of 'ncell' column */
124 int nPayload; /* Value of 'payload' column */ 117 int nPayload; /* Value of 'payload' column */
125 int nUnused; /* Value of 'unused' column */ 118 int nUnused; /* Value of 'unused' column */
126 int nMxPayload; /* Value of 'mx_payload' column */ 119 int nMxPayload; /* Value of 'mx_payload' column */
120 i64 iOffset; /* Value of 'pgOffset' column */
121 int szPage; /* Value of 'pgSize' column */
127 }; 122 };
128 123
129 struct StatTable { 124 struct StatTable {
130 sqlite3_vtab base; 125 sqlite3_vtab base;
131 sqlite3 *db; 126 sqlite3 *db;
132 }; 127 };
133 128
134 #ifndef get2byte 129 #ifndef get2byte
135 # define get2byte(x) ((x)[0]<<8 | (x)[1]) 130 # define get2byte(x) ((x)[0]<<8 | (x)[1])
136 #endif 131 #endif
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 nLocal = nMinLocal + (nTotal - nMinLocal) % (nUsable - 4); 269 nLocal = nMinLocal + (nTotal - nMinLocal) % (nUsable - 4);
275 if( nLocal>nMaxLocal ) nLocal = nMinLocal; 270 if( nLocal>nMaxLocal ) nLocal = nMinLocal;
276 *pnLocal = nLocal; 271 *pnLocal = nLocal;
277 } 272 }
278 273
279 static int statDecodePage(Btree *pBt, StatPage *p){ 274 static int statDecodePage(Btree *pBt, StatPage *p){
280 int nUnused; 275 int nUnused;
281 int iOff; 276 int iOff;
282 int nHdr; 277 int nHdr;
283 int isLeaf; 278 int isLeaf;
279 int szPage;
284 280
285 u8 *aData = sqlite3PagerGetData(p->pPg); 281 u8 *aData = sqlite3PagerGetData(p->pPg);
286 u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0]; 282 u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];
287 283
288 p->flags = aHdr[0]; 284 p->flags = aHdr[0];
289 p->nCell = get2byte(&aHdr[3]); 285 p->nCell = get2byte(&aHdr[3]);
290 p->nMxPayload = 0; 286 p->nMxPayload = 0;
291 287
292 isLeaf = (p->flags==0x0A || p->flags==0x0D); 288 isLeaf = (p->flags==0x0A || p->flags==0x0D);
293 nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100; 289 nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100;
294 290
295 nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell; 291 nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell;
296 nUnused += (int)aHdr[7]; 292 nUnused += (int)aHdr[7];
297 iOff = get2byte(&aHdr[1]); 293 iOff = get2byte(&aHdr[1]);
298 while( iOff ){ 294 while( iOff ){
299 nUnused += get2byte(&aData[iOff+2]); 295 nUnused += get2byte(&aData[iOff+2]);
300 iOff = get2byte(&aData[iOff]); 296 iOff = get2byte(&aData[iOff]);
301 } 297 }
302 p->nUnused = nUnused; 298 p->nUnused = nUnused;
303 p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]); 299 p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]);
300 szPage = sqlite3BtreeGetPageSize(pBt);
304 301
305 if( p->nCell ){ 302 if( p->nCell ){
306 int i; /* Used to iterate through cells */ 303 int i; /* Used to iterate through cells */
307 int nUsable = sqlite3BtreeGetPageSize(pBt) - sqlite3BtreeGetReserve(pBt); 304 int nUsable = szPage - sqlite3BtreeGetReserve(pBt);
308 305
309 p->aCell = sqlite3_malloc((p->nCell+1) * sizeof(StatCell)); 306 p->aCell = sqlite3_malloc((p->nCell+1) * sizeof(StatCell));
310 memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell)); 307 memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
311 308
312 for(i=0; i<p->nCell; i++){ 309 for(i=0; i<p->nCell; i++){
313 StatCell *pCell = &p->aCell[i]; 310 StatCell *pCell = &p->aCell[i];
314 311
315 iOff = get2byte(&aData[nHdr+i*2]); 312 iOff = get2byte(&aData[nHdr+i*2]);
316 if( !isLeaf ){ 313 if( !isLeaf ){
317 pCell->iChildPg = sqlite3Get4byte(&aData[iOff]); 314 pCell->iChildPg = sqlite3Get4byte(&aData[iOff]);
318 iOff += 4; 315 iOff += 4;
319 } 316 }
320 if( p->flags==0x05 ){ 317 if( p->flags==0x05 ){
321 /* A table interior node. nPayload==0. */ 318 /* A table interior node. nPayload==0. */
322 }else{ 319 }else{
323 u32 nPayload; /* Bytes of payload total (local+overflow) */ 320 u32 nPayload; /* Bytes of payload total (local+overflow) */
324 int nLocal; /* Bytes of payload stored locally */ 321 int nLocal; /* Bytes of payload stored locally */
325 iOff += getVarint32(&aData[iOff], nPayload); 322 iOff += getVarint32(&aData[iOff], nPayload);
326 if( p->flags==0x0D ){ 323 if( p->flags==0x0D ){
327 u64 dummy; 324 u64 dummy;
328 iOff += sqlite3GetVarint(&aData[iOff], &dummy); 325 iOff += sqlite3GetVarint(&aData[iOff], &dummy);
329 } 326 }
330 if( nPayload>p->nMxPayload ) p->nMxPayload = nPayload; 327 if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
331 getLocalPayload(nUsable, p->flags, nPayload, &nLocal); 328 getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
332 pCell->nLocal = nLocal; 329 pCell->nLocal = nLocal;
333 assert( nPayload>=nLocal ); 330 assert( nLocal>=0 );
331 assert( nPayload>=(u32)nLocal );
334 assert( nLocal<=(nUsable-35) ); 332 assert( nLocal<=(nUsable-35) );
335 if( nPayload>nLocal ){ 333 if( nPayload>(u32)nLocal ){
336 int j; 334 int j;
337 int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4); 335 int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
338 pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4); 336 pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
339 pCell->nOvfl = nOvfl; 337 pCell->nOvfl = nOvfl;
340 pCell->aOvfl = sqlite3_malloc(sizeof(u32)*nOvfl); 338 pCell->aOvfl = sqlite3_malloc(sizeof(u32)*nOvfl);
341 pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]); 339 pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
342 for(j=1; j<nOvfl; j++){ 340 for(j=1; j<nOvfl; j++){
343 int rc; 341 int rc;
344 u32 iPrev = pCell->aOvfl[j-1]; 342 u32 iPrev = pCell->aOvfl[j-1];
345 DbPage *pPg = 0; 343 DbPage *pPg = 0;
346 rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg); 344 rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg);
347 if( rc!=SQLITE_OK ){ 345 if( rc!=SQLITE_OK ){
348 assert( pPg==0 ); 346 assert( pPg==0 );
349 return rc; 347 return rc;
350 } 348 }
351 pCell->aOvfl[j] = sqlite3Get4byte(sqlite3PagerGetData(pPg)); 349 pCell->aOvfl[j] = sqlite3Get4byte(sqlite3PagerGetData(pPg));
352 sqlite3PagerUnref(pPg); 350 sqlite3PagerUnref(pPg);
353 } 351 }
354 } 352 }
355 } 353 }
356 } 354 }
357 } 355 }
358 356
359 return SQLITE_OK; 357 return SQLITE_OK;
360 } 358 }
361 359
362 /* 360 /*
361 ** Populate the pCsr->iOffset and pCsr->szPage member variables. Based on
362 ** the current value of pCsr->iPageno.
363 */
364 static void statSizeAndOffset(StatCursor *pCsr){
365 StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab;
366 Btree *pBt = pTab->db->aDb[0].pBt;
367 Pager *pPager = sqlite3BtreePager(pBt);
368 sqlite3_file *fd;
369 sqlite3_int64 x[2];
370
371 /* The default page size and offset */
372 pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
373 pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1);
374
375 /* If connected to a ZIPVFS backend, override the page size and
376 ** offset with actual values obtained from ZIPVFS.
377 */
378 fd = sqlite3PagerFile(pPager);
379 x[0] = pCsr->iPageno;
380 if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
381 pCsr->iOffset = x[0];
382 pCsr->szPage = (int)x[1];
383 }
384 }
385
386 /*
363 ** Move a statvfs cursor to the next entry in the file. 387 ** Move a statvfs cursor to the next entry in the file.
364 */ 388 */
365 static int statNext(sqlite3_vtab_cursor *pCursor){ 389 static int statNext(sqlite3_vtab_cursor *pCursor){
366 int rc; 390 int rc;
367 int nPayload; 391 int nPayload;
368 StatCursor *pCsr = (StatCursor *)pCursor; 392 StatCursor *pCsr = (StatCursor *)pCursor;
369 StatTable *pTab = (StatTable *)pCursor->pVtab; 393 StatTable *pTab = (StatTable *)pCursor->pVtab;
370 Btree *pBt = pTab->db->aDb[0].pBt; 394 Btree *pBt = pTab->db->aDb[0].pBt;
371 Pager *pPager = sqlite3BtreePager(pBt); 395 Pager *pPager = sqlite3BtreePager(pBt);
372 396
373 sqlite3_free(pCsr->zPath); 397 sqlite3_free(pCsr->zPath);
374 pCsr->zPath = 0; 398 pCsr->zPath = 0;
375 399
400 statNextRestart:
376 if( pCsr->aPage[0].pPg==0 ){ 401 if( pCsr->aPage[0].pPg==0 ){
377 rc = sqlite3_step(pCsr->pStmt); 402 rc = sqlite3_step(pCsr->pStmt);
378 if( rc==SQLITE_ROW ){ 403 if( rc==SQLITE_ROW ){
379 int nPage; 404 int nPage;
380 u32 iRoot = sqlite3_column_int64(pCsr->pStmt, 1); 405 u32 iRoot = (u32)sqlite3_column_int64(pCsr->pStmt, 1);
381 sqlite3PagerPagecount(pPager, &nPage); 406 sqlite3PagerPagecount(pPager, &nPage);
382 if( nPage==0 ){ 407 if( nPage==0 ){
383 pCsr->isEof = 1; 408 pCsr->isEof = 1;
384 return sqlite3_reset(pCsr->pStmt); 409 return sqlite3_reset(pCsr->pStmt);
385 } 410 }
386 rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg); 411 rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg);
387 pCsr->aPage[0].iPgno = iRoot; 412 pCsr->aPage[0].iPgno = iRoot;
388 pCsr->aPage[0].iCell = 0; 413 pCsr->aPage[0].iCell = 0;
389 pCsr->aPage[0].zPath = sqlite3_mprintf("/"); 414 pCsr->aPage[0].zPath = sqlite3_mprintf("/");
390 pCsr->iPage = 0; 415 pCsr->iPage = 0;
(...skipping 19 matching lines...) Expand all
410 "%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl 435 "%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl
411 ); 436 );
412 if( pCell->iOvfl<pCell->nOvfl-1 ){ 437 if( pCell->iOvfl<pCell->nOvfl-1 ){
413 pCsr->nUnused = 0; 438 pCsr->nUnused = 0;
414 pCsr->nPayload = nUsable - 4; 439 pCsr->nPayload = nUsable - 4;
415 }else{ 440 }else{
416 pCsr->nPayload = pCell->nLastOvfl; 441 pCsr->nPayload = pCell->nLastOvfl;
417 pCsr->nUnused = nUsable - 4 - pCsr->nPayload; 442 pCsr->nUnused = nUsable - 4 - pCsr->nPayload;
418 } 443 }
419 pCell->iOvfl++; 444 pCell->iOvfl++;
445 statSizeAndOffset(pCsr);
420 return SQLITE_OK; 446 return SQLITE_OK;
421 } 447 }
422 if( p->iRightChildPg ) break; 448 if( p->iRightChildPg ) break;
423 p->iCell++; 449 p->iCell++;
424 } 450 }
425 451
426 while( !p->iRightChildPg || p->iCell>p->nCell ){ 452 if( !p->iRightChildPg || p->iCell>p->nCell ){
427 statClearPage(p); 453 statClearPage(p);
428 if( pCsr->iPage==0 ) return statNext(pCursor); 454 if( pCsr->iPage==0 ) return statNext(pCursor);
429 pCsr->iPage--; 455 pCsr->iPage--;
430 p = &pCsr->aPage[pCsr->iPage]; 456 goto statNextRestart; /* Tail recursion */
431 } 457 }
432 pCsr->iPage++; 458 pCsr->iPage++;
433 assert( p==&pCsr->aPage[pCsr->iPage-1] ); 459 assert( p==&pCsr->aPage[pCsr->iPage-1] );
434 460
435 if( p->iCell==p->nCell ){ 461 if( p->iCell==p->nCell ){
436 p[1].iPgno = p->iRightChildPg; 462 p[1].iPgno = p->iRightChildPg;
437 }else{ 463 }else{
438 p[1].iPgno = p->aCell[p->iCell].iChildPg; 464 p[1].iPgno = p->aCell[p->iCell].iChildPg;
439 } 465 }
440 rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg); 466 rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg);
441 p[1].iCell = 0; 467 p[1].iCell = 0;
442 p[1].zPath = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell); 468 p[1].zPath = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
443 p->iCell++; 469 p->iCell++;
444 } 470 }
445 471
446 472
447 /* Populate the StatCursor fields with the values to be returned 473 /* Populate the StatCursor fields with the values to be returned
448 ** by the xColumn() and xRowid() methods. 474 ** by the xColumn() and xRowid() methods.
449 */ 475 */
450 if( rc==SQLITE_OK ){ 476 if( rc==SQLITE_OK ){
451 int i; 477 int i;
452 StatPage *p = &pCsr->aPage[pCsr->iPage]; 478 StatPage *p = &pCsr->aPage[pCsr->iPage];
453 pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0); 479 pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
454 pCsr->iPageno = p->iPgno; 480 pCsr->iPageno = p->iPgno;
455 481
456 statDecodePage(pBt, p); 482 statDecodePage(pBt, p);
483 statSizeAndOffset(pCsr);
457 484
458 switch( p->flags ){ 485 switch( p->flags ){
459 case 0x05: /* table internal */ 486 case 0x05: /* table internal */
460 case 0x02: /* index internal */ 487 case 0x02: /* index internal */
461 pCsr->zPagetype = "internal"; 488 pCsr->zPagetype = "internal";
462 break; 489 break;
463 case 0x0D: /* table leaf */ 490 case 0x0D: /* table leaf */
464 case 0x0A: /* index leaf */ 491 case 0x0A: /* index leaf */
465 pCsr->zPagetype = "leaf"; 492 pCsr->zPagetype = "leaf";
466 break; 493 break;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 break; 549 break;
523 case 5: /* payload */ 550 case 5: /* payload */
524 sqlite3_result_int(ctx, pCsr->nPayload); 551 sqlite3_result_int(ctx, pCsr->nPayload);
525 break; 552 break;
526 case 6: /* unused */ 553 case 6: /* unused */
527 sqlite3_result_int(ctx, pCsr->nUnused); 554 sqlite3_result_int(ctx, pCsr->nUnused);
528 break; 555 break;
529 case 7: /* mx_payload */ 556 case 7: /* mx_payload */
530 sqlite3_result_int(ctx, pCsr->nMxPayload); 557 sqlite3_result_int(ctx, pCsr->nMxPayload);
531 break; 558 break;
559 case 8: /* pgoffset */
560 sqlite3_result_int64(ctx, pCsr->iOffset);
561 break;
562 case 9: /* pgsize */
563 sqlite3_result_int(ctx, pCsr->szPage);
564 break;
532 } 565 }
533 return SQLITE_OK; 566 return SQLITE_OK;
534 } 567 }
535 568
536 static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ 569 static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
537 StatCursor *pCsr = (StatCursor *)pCursor; 570 StatCursor *pCsr = (StatCursor *)pCursor;
538 *pRowid = pCsr->iPageno; 571 *pRowid = pCsr->iPageno;
539 return SQLITE_OK; 572 return SQLITE_OK;
540 } 573 }
541 574
(...skipping 19 matching lines...) Expand all
561 0, /* xRollback */ 594 0, /* xRollback */
562 0, /* xFindMethod */ 595 0, /* xFindMethod */
563 0, /* xRename */ 596 0, /* xRename */
564 }; 597 };
565 sqlite3_create_module(db, "dbstat", &dbstat_module, 0); 598 sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
566 return SQLITE_OK; 599 return SQLITE_OK;
567 } 600 }
568 601
569 #endif 602 #endif
570 603
571 #ifdef SQLITE_TEST 604 #if defined(SQLITE_TEST) || TCLSH==2
572 #include <tcl.h> 605 #include <tcl.h>
573 606
574 static int test_dbstat( 607 static int test_dbstat(
575 void *clientData, 608 void *clientData,
576 Tcl_Interp *interp, 609 Tcl_Interp *interp,
577 int objc, 610 int objc,
578 Tcl_Obj *CONST objv[] 611 Tcl_Obj *CONST objv[]
579 ){ 612 ){
580 #ifdef SQLITE_OMIT_VIRTUALTABLE 613 #ifdef SQLITE_OMIT_VIRTUALTABLE
581 Tcl_AppendResult(interp, "dbstat not available because of " 614 Tcl_AppendResult(interp, "dbstat not available because of "
(...skipping 15 matching lines...) Expand all
597 sqlite3_dbstat_register(db); 630 sqlite3_dbstat_register(db);
598 } 631 }
599 return TCL_OK; 632 return TCL_OK;
600 #endif 633 #endif
601 } 634 }
602 635
603 int SqlitetestStat_Init(Tcl_Interp *interp){ 636 int SqlitetestStat_Init(Tcl_Interp *interp){
604 Tcl_CreateObjCommand(interp, "register_dbstat_vtab", test_dbstat, 0, 0); 637 Tcl_CreateObjCommand(interp, "register_dbstat_vtab", test_dbstat, 0, 0);
605 return TCL_OK; 638 return TCL_OK;
606 } 639 }
607 #endif 640 #endif /* if defined(SQLITE_TEST) || TCLSH==2 */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698