📄 test3.c
字号:
** Return the data for the entry at which the cursor is pointing.*/static int btree_data( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */){ BtCursor *pCur; int rc; u32 n; char *zBuf; if( argc!=2 && argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pCur = sqlite3TextToPtr(argv[1]); if( argc==2 ){ sqlite3BtreeDataSize(pCur, &n); }else{ n = atoi(argv[2]); } zBuf = malloc( n+1 ); rc = sqlite3BtreeData(pCur, 0, n, zBuf); if( rc ){ Tcl_AppendResult(interp, errorName(rc), 0); free(zBuf); return TCL_ERROR; } zBuf[n] = 0; Tcl_AppendResult(interp, zBuf, 0); free(zBuf); return SQLITE_OK;}/*** Usage: btree_fetch_key ID AMT**** Use the sqlite3BtreeKeyFetch() routine to get AMT bytes of the key.** If sqlite3BtreeKeyFetch() fails, return an empty string.*/static int btree_fetch_key( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */){ BtCursor *pCur; int n; int amt; u64 nKey; const char *zBuf; char zStatic[1000]; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID AMT\"", 0); return TCL_ERROR; } pCur = sqlite3TextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR; sqlite3BtreeKeySize(pCur, (i64*)&nKey); zBuf = sqlite3BtreeKeyFetch(pCur, &amt); if( zBuf && amt>=n ){ assert( nKey<sizeof(zStatic) ); if( n>0 ) nKey = n; memcpy(zStatic, zBuf, (int)nKey); zStatic[nKey] = 0; Tcl_AppendResult(interp, zStatic, 0); } return TCL_OK;}/*** Usage: btree_fetch_data ID AMT**** Use the sqlite3BtreeDataFetch() routine to get AMT bytes of the key.** If sqlite3BtreeDataFetch() fails, return an empty string.*/static int btree_fetch_data( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */){ BtCursor *pCur; int n; int amt; u32 nData; const char *zBuf; char zStatic[1000]; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID AMT\"", 0); return TCL_ERROR; } pCur = sqlite3TextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR; sqlite3BtreeDataSize(pCur, &nData); zBuf = sqlite3BtreeDataFetch(pCur, &amt); if( zBuf && amt>=n ){ assert( nData<sizeof(zStatic) ); if( n>0 ) nData = n; memcpy(zStatic, zBuf, (int)nData); zStatic[nData] = 0; Tcl_AppendResult(interp, zStatic, 0); } return TCL_OK;}/*** Usage: btree_payload_size ID**** Return the number of bytes of payload*/static int btree_payload_size( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */){ BtCursor *pCur; int n2; u64 n1; char zBuf[50]; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pCur = sqlite3TextToPtr(argv[1]); if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){ n1 = 0; }else{ sqlite3BtreeKeySize(pCur, (i64*)&n1); } sqlite3BtreeDataSize(pCur, (u32*)&n2); sqlite3_snprintf(sizeof(zBuf),zBuf, "%d", (int)(n1+n2)); Tcl_AppendResult(interp, zBuf, 0); return SQLITE_OK;}/*** Usage: btree_cursor_info ID ?UP-CNT?**** Return integers containing information about the entry the** cursor is pointing to:**** aResult[0] = The page number** aResult[1] = The entry number** aResult[2] = Total number of entries on this page** aResult[3] = Cell size (local payload + header)** aResult[4] = Number of free bytes on this page** aResult[5] = Number of free blocks on the page** aResult[6] = Total payload size (local + overflow)** aResult[7] = Header size in bytes** aResult[8] = Local payload size** aResult[9] = Parent page number** aResult[10]= Page number of the first overflow page*/static int btree_cursor_info( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */){ BtCursor *pCur; int rc; int i, j; int up; int aResult[11]; char zBuf[400]; if( argc!=2 && argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID ?UP-CNT?\"", 0); return TCL_ERROR; } pCur = sqlite3TextToPtr(argv[1]); if( argc==3 ){ if( Tcl_GetInt(interp, argv[2], &up) ) return TCL_ERROR; }else{ up = 0; } rc = sqlite3BtreeCursorInfo(pCur, aResult, up); if( rc ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } j = 0; for(i=0; i<sizeof(aResult)/sizeof(aResult[0]); i++){ sqlite3_snprintf(40,&zBuf[j]," %d", aResult[i]); j += strlen(&zBuf[j]); } Tcl_AppendResult(interp, &zBuf[1], 0); return SQLITE_OK;}/*** Copied from btree.c:*/static u32 t4Get4byte(unsigned char *p){ return (p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3];}/*** btree_ovfl_info BTREE CURSOR**** Given a cursor, return the sequence of pages number that form the** overflow pages for the data of the entry that the cursor is point** to.*/ static int btree_ovfl_info( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */){ Btree *pBt; BtCursor *pCur; Pager *pPager; int rc; int n; int dataSize; u32 pgno; void *pPage; int aResult[11]; char zElem[100]; Tcl_DString str; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " BTREE CURSOR", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); pCur = sqlite3TextToPtr(argv[2]); if( (*(void**)pCur) != (void*)pBt ){ Tcl_AppendResult(interp, "Cursor ", argv[2], " does not belong to btree ", argv[1], 0); return TCL_ERROR; } pPager = sqlite3BtreePager(pBt); rc = sqlite3BtreeCursorInfo(pCur, aResult, 0); if( rc ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } dataSize = sqlite3BtreeGetPageSize(pBt) - sqlite3BtreeGetReserve(pBt); Tcl_DStringInit(&str); n = aResult[6] - aResult[8]; n = (n + dataSize - 1)/dataSize; pgno = (u32)aResult[10]; while( pgno && n-- ){ DbPage *pDbPage; sprintf(zElem, "%d", pgno); Tcl_DStringAppendElement(&str, zElem); if( sqlite3PagerGet(pPager, pgno, &pDbPage)!=SQLITE_OK ){ Tcl_DStringFree(&str); Tcl_AppendResult(interp, "unable to get page ", zElem, 0); return TCL_ERROR; } pPage = sqlite3PagerGetData(pDbPage); pgno = t4Get4byte((unsigned char*)pPage); sqlite3PagerUnref(pDbPage); } Tcl_DStringResult(interp, &str); return SQLITE_OK;}/*** The command is provided for the purpose of setting breakpoints.** in regression test scripts.**** By setting a GDB breakpoint on this procedure and executing the** btree_breakpoint command in a test script, we can stop GDB at** the point in the script where the btree_breakpoint command is** inserted. This is useful for debugging.*/static int btree_breakpoint( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */){ return TCL_OK;}/*** usage: varint_test START MULTIPLIER COUNT INCREMENT**** This command tests the sqlite3PutVarint() and sqlite3GetVarint()** routines, both for accuracy and for speed.**** An integer is written using PutVarint() and read back with** GetVarint() and varified to be unchanged. This repeats COUNT** times. The first integer is START*MULTIPLIER. Each iteration** increases the integer by INCREMENT.**** This command returns nothing if it works. It returns an error message** if something goes wrong.*/static int btree_varint_test( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */){ u32 start, mult, count, incr; u64 in, out; int n1, n2, i, j; unsigned char zBuf[100]; if( argc!=5 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " START MULTIPLIER COUNT INCREMENT\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[1], (int*)&start) ) return TCL_ERROR; if( Tcl_GetInt(interp, argv[2], (int*)&mult) ) return TCL_ERROR; if( Tcl_GetInt(interp, argv[3], (int*)&count) ) return TCL_ERROR; if( Tcl_GetInt(interp, argv[4], (int*)&incr) ) return TCL_ERROR; in = start; in *= mult; for(i=0; i<count; i++){ char zErr[200]; n1 = sqlite3PutVarint(zBuf, in); if( n1>9 || n1<1 ){ sprintf(zErr, "PutVarint returned %d - should be between 1 and 9", n1); Tcl_AppendResult(interp, zErr, 0); return TCL_ERROR; } n2 = sqlite3GetVarint(zBuf, &out); if( n1!=n2 ){ sprintf(zErr, "PutVarint returned %d and GetVarint returned %d", n1, n2); Tcl_AppendResult(interp, zErr, 0); return TCL_ERROR; } if( in!=out ){ sprintf(zErr, "Wrote 0x%016llx and got back 0x%016llx", in, out); Tcl_AppendResult(interp, zErr, 0); return TCL_ERROR; } if( (in & 0xffffffff)==in ){ u32 out32; n2 = sqlite3GetVarint32(zBuf, &out32); out = out32; if( n1!=n2 ){ sprintf(zErr, "PutVarint returned %d and GetVarint32 returned %d", n1, n2); Tcl_AppendResult(interp, zErr, 0); return TCL_ERROR; } if( in!=out ){ sprintf(zErr, "Wrote 0x%016llx and got back 0x%016llx from GetVarint32", in, out); Tcl_AppendResult(interp, zErr, 0); return TCL_ERROR; } } /* In order to get realistic timings, run getVarint 19 more times. ** This is because getVarint is called about 20 times more often ** than putVarint. */ for(j=0; j<19; j++){ sqlite3GetVarint(zBuf, &out); } in += incr; } return TCL_OK;}/*** usage: btree_from_db DB-HANDLE**** This command returns the btree handle for the main database associated** with the database-handle passed as the argument. Example usage:**** sqlite3 db test.db** set bt [btree_from_db db]*/static int btree_from_db( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */){ char zBuf[100]; Tcl_CmdInfo info; sqlite3 *db; Btree *pBt; int iDb = 0; if( argc!=2 && argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB-HANDLE ?N?\"", 0); return TCL_ERROR; } if( 1!=Tcl_GetCommandInfo(interp, argv[1], &info) ){ Tcl_AppendResult(interp, "No such db-handle: \"", argv[1], "\"", 0); return TCL_ERROR; } if( argc==3 ){ iDb = atoi(argv[2]); } db = *((sqlite3 **)info.objClientData); assert( db ); pBt = db->aDb[iDb].pBt; sqlite3_snprintf(sizeof(zBuf), zBuf, "%p", pBt); Tcl_SetResult(interp, zBuf, TCL_VOLATILE); return TCL_OK;}/*** usage: btree_set_cache_size ID NCACHE**** Set the size of the cache used by btree $ID.*/static int btree_set_cache_size( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */){ int nCache; Btree *pBt; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " BT NCACHE\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR; sqlite3BtreeSetCacheSize(pBt, nCache); return TCL_OK;}/*** Register commands with the TCL interpreter.*/int Sqlitetest3_Init(Tcl_Interp *interp){ extern int sqlite3_btree_trace; static struct { char *zName; Tcl_CmdProc *xProc; } aCmd[] = { { "btree_open", (Tcl_CmdProc*)btree_open }, { "btree_close", (Tcl_CmdProc*)btree_close }, { "btree_begin_transaction", (Tcl_CmdProc*)btree_begin_transaction }, { "btree_commit", (Tcl_CmdProc*)btree_commit }, { "btree_rollback", (Tcl_CmdProc*)btree_rollback }, { "btree_create_table", (Tcl_CmdProc*)btree_create_table }, { "btree_drop_table", (Tcl_CmdProc*)btree_drop_table }, { "btree_clear_table", (Tcl_CmdProc*)btree_clear_table }, { "btree_get_meta", (Tcl_CmdProc*)btree_get_meta }, { "btree_update_meta", (Tcl_CmdProc*)btree_update_meta }, { "btree_page_dump", (Tcl_CmdProc*)btree_page_dump }, { "btree_tree_dump", (Tcl_CmdProc*)btree_tree_dump }, { "btree_pager_stats", (Tcl_CmdProc*)btree_pager_stats }, { "btree_pager_ref_dump", (Tcl_CmdProc*)btree_pager_ref_dump }, { "btree_cursor", (Tcl_CmdProc*)btree_cursor }, { "btree_close_cursor", (Tcl_CmdProc*)btree_close_cursor }, { "btree_move_to", (Tcl_CmdProc*)btree_move_to }, { "btree_delete", (Tcl_CmdProc*)btree_delete }, { "btree_next", (Tcl_CmdProc*)btree_next }, { "btree_prev", (Tcl_CmdProc*)btree_prev }, { "btree_eof", (Tcl_CmdProc*)btree_eof }, { "btree_keysize", (Tcl_CmdProc*)btree_keysize }, { "btree_key", (Tcl_CmdProc*)btree_key }, { "btree_data", (Tcl_CmdProc*)btree_data }, { "btree_fetch_key", (Tcl_CmdProc*)btree_fetch_key }, { "btree_fetch_data", (Tcl_CmdProc*)btree_fetch_data }, { "btree_payload_size", (Tcl_CmdProc*)btree_payload_size }, { "btree_first", (Tcl_CmdProc*)btree_first }, { "btree_last", (Tcl_CmdProc*)btree_last }, { "btree_integrity_check", (Tcl_CmdProc*)btree_integrity_check }, { "btree_breakpoint", (Tcl_CmdProc*)btree_breakpoint }, { "btree_varint_test", (Tcl_CmdProc*)btree_varint_test }, { "btree_begin_statement", (Tcl_CmdProc*)btree_begin_statement }, { "btree_commit_statement", (Tcl_CmdProc*)btree_commit_statement }, { "btree_rollback_statement", (Tcl_CmdProc*)btree_rollback_statement }, { "btree_from_db", (Tcl_CmdProc*)btree_from_db }, { "btree_set_cache_size", (Tcl_CmdProc*)btree_set_cache_size }, { "btree_cursor_info", (Tcl_CmdProc*)btree_cursor_info }, { "btree_ovfl_info", (Tcl_CmdProc*)btree_ovfl_info }, { "btree_cursor_list", (Tcl_CmdProc*)btree_cursor_list }, }; int i; for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); } Tcl_LinkVar(interp, "pager_refinfo_enable", (char*)&pager3_refinfo_enable, TCL_LINK_INT); Tcl_LinkVar(interp, "btree_trace", (char*)&sqlite3_btree_trace, TCL_LINK_INT); /* The btree_insert command is implemented using the tcl 'object' ** interface, not the string interface like the other commands in this ** file. This is so binary data can be inserted into btree tables. */ Tcl_CreateObjCommand(interp, "btree_insert", btree_insert, 0, 0); return TCL_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -