Index: third_party/sqlite/sqlite-src-3070603/src/test3.c |
diff --git a/third_party/sqlite/sqlite-src-3070603/src/test3.c b/third_party/sqlite/sqlite-src-3070603/src/test3.c |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ef004ca7133aa239887d9532758d01d147d7a298 |
--- /dev/null |
+++ b/third_party/sqlite/sqlite-src-3070603/src/test3.c |
@@ -0,0 +1,644 @@ |
+/* |
+** 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. |
+*/ |
+#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 |
+** |
+** 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; |
+ char zBuf[100]; |
+ if( argc!=3 ){ |
+ 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; |
+ 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, 0, |
+ 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_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_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 = SQLITE_OK; |
+ 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 = sqlite3TestTextToPtr(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); |
+#ifndef SQLITE_OMIT_SHARED_CACHE |
+ rc = sqlite3BtreeLockTable(pBt, iTable, wrFlag); |
+#endif |
+ if( rc==SQLITE_OK ){ |
+ 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_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 = sqlite3TestTextToPtr(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: btree_next ID |
+** |
+** Move the cursor to the next entry in the table. Return 0 on success |
+** or 1 if the cursor was already on the last entry in the table or if |
+** the table is empty. |
+*/ |
+static int btree_next( |
+ 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 = 0; |
+ char zBuf[100]; |
+ |
+ if( argc!=2 ){ |
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
+ " ID\"", 0); |
+ return TCL_ERROR; |
+ } |
+ pCur = sqlite3TestTextToPtr(argv[1]); |
+ sqlite3BtreeEnter(pCur->pBtree); |
+ rc = sqlite3BtreeNext(pCur, &res); |
+ sqlite3BtreeLeave(pCur->pBtree); |
+ if( rc ){ |
+ Tcl_AppendResult(interp, errorName(rc), 0); |
+ return TCL_ERROR; |
+ } |
+ sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res); |
+ Tcl_AppendResult(interp, zBuf, 0); |
+ return SQLITE_OK; |
+} |
+ |
+/* |
+** Usage: btree_first ID |
+** |
+** Move the cursor to the first entry in the table. Return 0 if the |
+** cursor was left point to something and 1 if the table is empty. |
+*/ |
+static int btree_first( |
+ 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 = 0; |
+ char zBuf[100]; |
+ |
+ if( argc!=2 ){ |
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
+ " ID\"", 0); |
+ return TCL_ERROR; |
+ } |
+ pCur = sqlite3TestTextToPtr(argv[1]); |
+ sqlite3BtreeEnter(pCur->pBtree); |
+ rc = sqlite3BtreeFirst(pCur, &res); |
+ sqlite3BtreeLeave(pCur->pBtree); |
+ if( rc ){ |
+ Tcl_AppendResult(interp, errorName(rc), 0); |
+ return TCL_ERROR; |
+ } |
+ sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",res); |
+ Tcl_AppendResult(interp, zBuf, 0); |
+ return SQLITE_OK; |
+} |
+ |
+/* |
+** Usage: btree_eof ID |
+** |
+** Return TRUE if the given cursor is not pointing at a valid entry. |
+** Return FALSE if the cursor does point to a valid entry. |
+*/ |
+static int btree_eof( |
+ 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; |
+ char zBuf[50]; |
+ |
+ if( argc!=2 ){ |
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
+ " ID\"", 0); |
+ return TCL_ERROR; |
+ } |
+ pCur = sqlite3TestTextToPtr(argv[1]); |
+ sqlite3BtreeEnter(pCur->pBtree); |
+ rc = sqlite3BtreeEof(pCur); |
+ sqlite3BtreeLeave(pCur->pBtree); |
+ sqlite3_snprintf(sizeof(zBuf),zBuf, "%d", rc); |
+ Tcl_AppendResult(interp, zBuf, 0); |
+ return SQLITE_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 = sqlite3TestTextToPtr(argv[1]); |
+ sqlite3BtreeEnter(pCur->pBtree); |
+ |
+ /* The cursor may be in "require-seek" state. If this is the case, the |
+ ** call to BtreeDataSize() will fix it. */ |
+ sqlite3BtreeDataSize(pCur, (u32*)&n2); |
+ if( pCur->apPage[pCur->iPage]->intKey ){ |
+ n1 = 0; |
+ }else{ |
+ sqlite3BtreeKeySize(pCur, (i64*)&n1); |
+ } |
+ sqlite3BtreeLeave(pCur->pBtree); |
+ sqlite3_snprintf(sizeof(zBuf),zBuf, "%d", (int)(n1+n2)); |
+ Tcl_AppendResult(interp, zBuf, 0); |
+ return SQLITE_OK; |
+} |
+ |
+/* |
+** usage: varint_test START MULTIPLIER COUNT INCREMENT |
+** |
+** This command tests the putVarint() and getVarint() |
+** 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 = putVarint(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 = getVarint(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 = getVarint32(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++){ |
+ getVarint(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_ismemdb ID |
+** |
+** Return true if the B-Tree is in-memory. |
+*/ |
+static int btree_ismemdb( |
+ 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 res; |
+ |
+ if( argc!=2 ){ |
+ Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
+ " ID\"", 0); |
+ return TCL_ERROR; |
+ } |
+ pBt = sqlite3TestTextToPtr(argv[1]); |
+ sqlite3_mutex_enter(pBt->db->mutex); |
+ sqlite3BtreeEnter(pBt); |
+ res = sqlite3PagerIsMemdb(sqlite3BtreePager(pBt)); |
+ sqlite3BtreeLeave(pBt); |
+ sqlite3_mutex_leave(pBt->db->mutex); |
+ Tcl_SetObjResult(interp, Tcl_NewBooleanObj(res)); |
+ return SQLITE_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 = sqlite3TestTextToPtr(argv[1]); |
+ if( Tcl_GetInt(interp, argv[2], &nCache) ) return TCL_ERROR; |
+ |
+ sqlite3_mutex_enter(pBt->db->mutex); |
+ sqlite3BtreeEnter(pBt); |
+ sqlite3BtreeSetCacheSize(pBt, nCache); |
+ sqlite3BtreeLeave(pBt); |
+ sqlite3_mutex_leave(pBt->db->mutex); |
+ return TCL_OK; |
+} |
+ |
+ |
+ |
+/* |
+** Register commands with the TCL interpreter. |
+*/ |
+int Sqlitetest3_Init(Tcl_Interp *interp){ |
+ 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_pager_stats", (Tcl_CmdProc*)btree_pager_stats }, |
+ { "btree_cursor", (Tcl_CmdProc*)btree_cursor }, |
+ { "btree_close_cursor", (Tcl_CmdProc*)btree_close_cursor }, |
+ { "btree_next", (Tcl_CmdProc*)btree_next }, |
+ { "btree_eof", (Tcl_CmdProc*)btree_eof }, |
+ { "btree_payload_size", (Tcl_CmdProc*)btree_payload_size }, |
+ { "btree_first", (Tcl_CmdProc*)btree_first }, |
+ { "btree_varint_test", (Tcl_CmdProc*)btree_varint_test }, |
+ { "btree_from_db", (Tcl_CmdProc*)btree_from_db }, |
+ { "btree_ismemdb", (Tcl_CmdProc*)btree_ismemdb }, |
+ { "btree_set_cache_size", (Tcl_CmdProc*)btree_set_cache_size } |
+ }; |
+ int i; |
+ |
+ for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ |
+ Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); |
+ } |
+ |
+ return TCL_OK; |
+} |