/* ** Usage: page_get ID PGNO ** ** Return a pointer to a page from the database. */ static int page_get( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ Pager *pPager; char zBuf[100]; DbPage *pPage; int pgno; int rc; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID PGNO\"", 0); return TCL_ERROR; } pPager = sqlite3TextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR; rc = sqlite3PagerGet(pPager, pgno, &pPage); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage); Tcl_AppendResult(interp, zBuf, 0); return TCL_OK; }
/* ** Usage: btree_get_meta ID ** ** Return meta data */ static int btree_get_meta( 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; int rc; int i; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); for(i=0; i<SQLITE_N_BTREE_META; i++){ char zBuf[30]; unsigned int v; sqlite3BtreeEnter(pBt); rc = sqlite3BtreeGetMeta(pBt, i, &v); sqlite3BtreeLeave(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",v); Tcl_AppendElement(interp, zBuf); } return TCL_OK; }
/* ** Usage: pager_commit ID ** ** Commit all changes */ static int pager_commit( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ Pager *pPager; int rc; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pPager = sqlite3TextToPtr(argv[1]); rc = sqlite3PagerCommitPhaseOne(pPager, 0, 0); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } rc = sqlite3PagerCommitPhaseTwo(pPager); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; }
/* ** Usage: btree_close_cursor ID ** ** Close a cursor opened using btree_cursor. */ static int btree_close_cursor( 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; Btree *pBt; int rc; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pCur = sqlite3TextToPtr(argv[1]); pBt = pCur->pBtree; sqlite3BtreeEnter(pBt); rc = sqlite3BtreeCloseCursor(pCur); sqlite3BtreeLeave(pBt); ckfree((char *)pCur); if( rc ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return SQLITE_OK; }
/* ** Usage: pager_stats ID ** ** Return pager statistics. */ static int pager_stats( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ Pager *pPager; int i, *a; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pPager = sqlite3TextToPtr(argv[1]); a = sqlite3PagerStats(pPager); for(i=0; i<9; i++){ static char *zName[] = { "ref", "page", "max", "size", "state", "err", "hit", "miss", "ovfl", }; char zBuf[100]; Tcl_AppendElement(interp, zName[i]); sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",a[i]); Tcl_AppendElement(interp, zBuf); } return TCL_OK; }
/* ** Usage: btree_cursor ID TABLENUM WRITEABLE ** ** Create a new cursor. Return the ID for the cursor. */ static int btree_cursor( 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; int iTable; BtCursor *pCur; int rc; int wrFlag; char zBuf[30]; if( argc!=4 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID TABLENUM WRITEABLE\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR; if( Tcl_GetBoolean(interp, argv[3], &wrFlag) ) return TCL_ERROR; pCur = (BtCursor *)ckalloc(sqlite3BtreeCursorSize()); memset(pCur, 0, sqlite3BtreeCursorSize()); sqlite3BtreeEnter(pBt); rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, 0, pCur); sqlite3BtreeLeave(pBt); if( rc ){ ckfree((char *)pCur); Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pCur); Tcl_AppendResult(interp, zBuf, 0); return SQLITE_OK; }
/* ** Usage: btree_update_meta ID METADATA... ** ** Return meta data */ static int btree_update_meta( 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; int rc; int i; int aMeta[SQLITE_N_BTREE_META]; if( argc!=2+SQLITE_N_BTREE_META ){ char zBuf[30]; sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",SQLITE_N_BTREE_META); Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID METADATA...\" (METADATA is ", zBuf, " integers)", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); for(i=1; i<SQLITE_N_BTREE_META; i++){ if( Tcl_GetInt(interp, argv[i+2], &aMeta[i]) ) return TCL_ERROR; } for(i=1; i<SQLITE_N_BTREE_META; i++){ sqlite3BtreeEnter(pBt); rc = sqlite3BtreeUpdateMeta(pBt, i, aMeta[i]); sqlite3BtreeLeave(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } } return TCL_OK; }
/* ** Usage: btree_close ID ** ** Close the given database. */ static int btree_close( 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; int rc; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); rc = sqlite3BtreeClose(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } nRefSqlite3--; if( nRefSqlite3==0 ){ sqlite3_mutex_leave(sDb.mutex); sqlite3_mutex_free(sDb.mutex); sDb.mutex = 0; sDb.pVfs = 0; } return TCL_OK; }
/* ** Usage: btree_create_table ID FLAGS ** ** Create a new table in the database */ static int btree_create_table( 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; int rc, iTable, flags; char zBuf[30]; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID FLAGS\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &flags) ) return TCL_ERROR; sqlite3BtreeEnter(pBt); rc = sqlite3BtreeCreateTable(pBt, &iTable, flags); sqlite3BtreeLeave(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", iTable); Tcl_AppendResult(interp, zBuf, 0); return TCL_OK; }
/* ** Usage: page_write PAGE DATA ** ** Write something into a page. */ static int page_write( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ DbPage *pPage; char *pData; int rc; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " PAGE DATA\"", 0); return TCL_ERROR; } pPage = (DbPage *)sqlite3TextToPtr(argv[1]); rc = sqlite3PagerWrite(pPage); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } pData = sqlite3PagerGetData(pPage); strncpy(pData, argv[2], test_pagesize-1); pData[test_pagesize-1] = 0; return TCL_OK; }
/* ** Usage: btree_tree_dump ID PAGENUM ** ** Print a disassembly of a page and all its child pages on standard output */ static int btree_tree_dump( 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; int iPage; int rc; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &iPage) ) return TCL_ERROR; sqlite3BtreeEnter(pBt); rc = sqlite3BtreePageDump(pBt, iPage, 1); sqlite3BtreeLeave(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; }
/* ** Usage: page_number PAGE ** ** Return the page number for a page. */ static int page_number( 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]; DbPage *pPage; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " PAGE\"", 0); return TCL_ERROR; } pPage = (DbPage *)sqlite3TextToPtr(argv[1]); sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", sqlite3PagerPagenumber(pPage)); Tcl_AppendResult(interp, zBuf, 0); return TCL_OK; }
/* ** Usage: btree_pager_stats ID ** ** Returns pager statistics */ static int btree_pager_stats( 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; int i; int *a; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); /* Normally in this file, with a b-tree handle opened using the ** [btree_open] command it is safe to call sqlite3BtreeEnter() directly. ** But this function is sometimes called with a btree handle obtained ** from an open SQLite connection (using [btree_from_db]). In this case ** we need to obtain the mutex for the controlling SQLite handle before ** it is safe to call sqlite3BtreeEnter(). */ sqlite3_mutex_enter(pBt->db->mutex); sqlite3BtreeEnter(pBt); a = sqlite3PagerStats(sqlite3BtreePager(pBt)); for(i=0; i<11; i++){ static char *zName[] = { "ref", "page", "max", "size", "state", "err", "hit", "miss", "ovfl", "read", "write" }; char zBuf[100]; Tcl_AppendElement(interp, zName[i]); sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",a[i]); Tcl_AppendElement(interp, zBuf); } sqlite3BtreeLeave(pBt); /* Release the mutex on the SQLite handle that controls this b-tree */ sqlite3_mutex_leave(pBt->db->mutex); return TCL_OK; }
/* ** Usage: btree_cursor_list ID ** ** Print information about all cursors to standard output for debugging. */ static int btree_cursor_list( 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; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); sqlite3BtreeEnter(pBt); sqlite3BtreeCursorList(pBt); sqlite3BtreeLeave(pBt); return SQLITE_OK; }
/* ** Usage: btree_pager_ref_dump ID ** ** Print out all outstanding pages. */ static int btree_pager_ref_dump( 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; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); #ifdef SQLITE_TEST sqlite3BtreeEnter(pBt); sqlite3PagerRefdump(sqlite3BtreePager(pBt)); sqlite3BtreeLeave(pBt); #endif return TCL_OK; }
/* ** Usage: page_unref PAGE ** ** Drop a pointer to a page. */ static int page_unref( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ DbPage *pPage; int rc; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " PAGE\"", 0); return TCL_ERROR; } pPage = (DbPage *)sqlite3TextToPtr(argv[1]); rc = sqlite3PagerUnref(pPage); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; }
/* ** Usage: btree_move_to ID KEY ** ** Move the cursor to the entry with the given key. */ static int btree_move_to( 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 res; char zBuf[20]; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID KEY\"", 0); return TCL_ERROR; } pCur = sqlite3TextToPtr(argv[1]); sqlite3BtreeEnter(pCur->pBtree); if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){ int iKey; if( Tcl_GetInt(interp, argv[2], &iKey) ){ sqlite3BtreeLeave(pCur->pBtree); return TCL_ERROR; } rc = sqlite3BtreeMoveto(pCur, 0, 0, iKey, 0, &res); }else{ rc = sqlite3BtreeMoveto(pCur, argv[2], 0, strlen(argv[2]), 0, &res); } sqlite3BtreeLeave(pCur->pBtree); if( rc ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } if( res<0 ) res = -1; if( res>0 ) res = 1; sqlite3_snprintf(sizeof(zBuf), zBuf,"%d",res); Tcl_AppendResult(interp, zBuf, 0); return SQLITE_OK; }
/* ** Usage: btree_integrity_check ID ROOT ... ** ** Look through every page of the given BTree file to verify correct ** formatting and linkage. Return a line of text for each problem found. ** Return an empty string if everything worked. */ static int btree_integrity_check( 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; int nRoot; int *aRoot; int i; int nErr; char *zResult; if( argc<3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID ROOT ...\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); nRoot = argc-2; aRoot = (int*)sqlite3_malloc( sizeof(int)*(argc-2) ); for(i=0; i<argc-2; i++){ if( Tcl_GetInt(interp, argv[i+2], &aRoot[i]) ) return TCL_ERROR; } #ifndef SQLITE_OMIT_INTEGRITY_CHECK sqlite3BtreeEnter(pBt); zResult = sqlite3BtreeIntegrityCheck(pBt, aRoot, nRoot, 10000, &nErr); sqlite3BtreeLeave(pBt); #else zResult = 0; #endif sqlite3_free((void*)aRoot); if( zResult ){ Tcl_AppendResult(interp, zResult, 0); sqlite3_free(zResult); } return TCL_OK; }
/* ** Usage: btree_rollback_statement ID ** ** Rollback changes */ static int btree_rollback_statement( 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; int rc; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pBt = sqlite3TextToPtr(argv[1]); sqlite3BtreeEnter(pBt); rc = sqlite3BtreeRollbackStmt(pBt); sqlite3BtreeLeave(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; }
/* ** Usage: pager_truncate ID PGNO */ static int pager_truncate( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ const char **argv /* Text of each argument */ ){ Pager *pPager; int rc; int pgno; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID PGNO\"", 0); return TCL_ERROR; } pPager = sqlite3TextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR; rc = sqlite3PagerTruncate(pPager, pgno); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK; }
/* ** Decode a pointer to an sqlite3 object. */ static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){ *ppDb = (sqlite3*)sqlite3TextToPtr(zA); return TCL_OK; }