📄 test3.c
字号:
/*** 2001 September 15**** The author disclaims copyright to this source code. In place of** a legal notice, here is a blessing:**** May you do good and not evil.** May you find forgiveness for yourself and forgive others.** May you share freely, never taking more than you give.***************************************************************************** Code for testing the btree.c module in SQLite. This code** is not included in the SQLite library. It is used for automated** testing of the SQLite library.**** $Id: test3.c,v 1.101 2008/08/13 19:11:48 drh Exp $*/#include "sqliteInt.h"#include "btreeInt.h"#include "tcl.h"#include <stdlib.h>#include <string.h>/*** Interpret an SQLite error number*/static char *errorName(int rc){ char *zName; switch( rc ){ case SQLITE_OK: zName = "SQLITE_OK"; break; case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; case SQLITE_PERM: zName = "SQLITE_PERM"; break; case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; case SQLITE_FULL: zName = "SQLITE_FULL"; break; case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; default: zName = "SQLITE_Unknown"; break; } return zName;}/*** A bogus sqlite3 connection structure for use in the btree** tests.*/static sqlite3 sDb;static int nRefSqlite3 = 0;/*** Usage: btree_open FILENAME NCACHE FLAGS**** Open a new database*/static int btree_open( 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, nCache, flags; char zBuf[100]; if( argc!=4 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " FILENAME NCACHE FLAGS\"", 0); return TCL_ERROR; } if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR; if( Tcl_GetInt(interp, argv[3], &flags) ) return TCL_ERROR; nRefSqlite3++; if( nRefSqlite3==1 ){ sDb.pVfs = sqlite3_vfs_find(0); sDb.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); sqlite3_mutex_enter(sDb.mutex); } rc = sqlite3BtreeOpen(argv[1], &sDb, &pBt, flags, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } sqlite3BtreeSetCacheSize(pBt, nCache); sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pBt); Tcl_AppendResult(interp, zBuf, 0); 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 = sqlite3TestTextToPtr(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_begin_transaction ID**** Start a new transaction*/static int btree_begin_transaction( 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 = sqlite3TestTextToPtr(argv[1]); sqlite3BtreeEnter(pBt); rc = sqlite3BtreeBeginTrans(pBt, 1); sqlite3BtreeLeave(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK;}/*** Usage: btree_rollback ID**** Rollback changes*/static int btree_rollback( 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 = sqlite3TestTextToPtr(argv[1]); sqlite3BtreeEnter(pBt); rc = sqlite3BtreeRollback(pBt); sqlite3BtreeLeave(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK;}/*** Usage: btree_commit ID**** Commit all changes*/static int btree_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 */){ Btree *pBt; int rc; if( argc!=2 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID\"", 0); return TCL_ERROR; } pBt = sqlite3TestTextToPtr(argv[1]); sqlite3BtreeEnter(pBt); rc = sqlite3BtreeCommit(pBt); sqlite3BtreeLeave(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK;}/*** Usage: btree_begin_statement ID**** Start a new statement transaction*/static int btree_begin_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 = sqlite3TestTextToPtr(argv[1]); sqlite3BtreeEnter(pBt); rc = sqlite3BtreeBeginStmt(pBt); sqlite3BtreeLeave(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } 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 = sqlite3TestTextToPtr(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: btree_commit_statement ID**** Commit all changes*/static int btree_commit_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 = sqlite3TestTextToPtr(argv[1]); sqlite3BtreeEnter(pBt); rc = sqlite3BtreeCommitStmt(pBt); sqlite3BtreeLeave(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } 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 = sqlite3TestTextToPtr(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: btree_drop_table ID TABLENUM**** Delete an entire table from the database*/static int btree_drop_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 iTable; int rc; int notUsed1; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID TABLENUM\"", 0); return TCL_ERROR; } pBt = sqlite3TestTextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR; sqlite3BtreeEnter(pBt); rc = sqlite3BtreeDropTable(pBt, iTable, ¬Used1); sqlite3BtreeLeave(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } return TCL_OK;}/*** Usage: btree_clear_table ID TABLENUM**** Remove all entries from the given table but keep the table around.*/static int btree_clear_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 iTable; int rc; if( argc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ID TABLENUM\"", 0); return TCL_ERROR; } pBt = sqlite3TestTextToPtr(argv[1]); if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR; sqlite3BtreeEnter(pBt); rc = sqlite3BtreeClearTable(pBt, iTable); sqlite3BtreeLeave(pBt); if( rc!=SQLITE_OK ){ Tcl_AppendResult(interp, errorName(rc), 0); return TCL_ERROR; } 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 = sqlite3TestTextToPtr(argv[1]); for(i=0; i<SQLITE_N_BTREE_META; i++){ char zBuf[30]; u32 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: 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 = sqlite3TestTextToPtr(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_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 = sqlite3TestTextToPtr(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_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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -