wasCSharpSQLite – Rev
?pathlinks?
using System.Diagnostics;
using i64 = System.Int64;
using u32 = System.UInt32;
namespace Community.CsharpSqlite
{
#if TCLSH
using tcl.lang;
using Tcl_CmdProc = tcl.lang.Interp.dxObjCmdProc;
using Tcl_Interp = tcl.lang.Interp;
using System.Text;
public partial class Sqlite3
{
/*
** 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.
*************************************************************************
** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
** C#-SQLite is an independent reimplementation of the SQLite software library
**
** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2
**
*************************************************************************
*/
//#include "sqliteInt.h"
//#include "btreeInt.h"
//#include "tcl.h"
//#include <stdlib.h>
//#include <string.h>
/*
** Interpret an SQLite error number
*/
static string errorName( int rc )
{
string 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 = new sqlite3();
static int nRefSqlite3 = 0;
/*
** Usage: btree_open FILENAME NCACHE
**
** Open a new database
*/
static int btree_open(
object NotUsed,
Tcl_Interp interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
TclObject[] argv /* Text of each argument */
)
{
Btree pBt = null;
int rc;
int nCache = 0;
StringBuilder zBuf = new StringBuilder( 100 );
if ( argc != 3 )
{
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0].ToString(),
" FILENAME NCACHE\"", "" );
return TCL.TCL_ERROR;
}
if ( TCL.Tcl_GetInt( interp, argv[2], out nCache ) )
return TCL.TCL_ERROR;
nRefSqlite3++;
if ( nRefSqlite3 == 1 )
{
sDb.pVfs = sqlite3_vfs_find( null );
sDb.mutex = sqlite3MutexAlloc( SQLITE_MUTEX_RECURSIVE );
sqlite3_mutex_enter( sDb.mutex );
}
rc = sqlite3BtreeOpen( sDb.pVfs, argv[1].ToString(), sDb, ref pBt, 0,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB );
if ( rc != SQLITE_OK )
{
TCL.Tcl_AppendResult( interp, errorName( rc ), null );
return TCL.TCL_ERROR;
}
sqlite3BtreeSetCacheSize( pBt, nCache );
sqlite3_snprintf( 100, zBuf, "->%p", pBt );
if ( TCL.Tcl_CreateCommandPointer( interp, zBuf, pBt ) )
{
return TCL.TCL_ERROR;
}
else
TCL.Tcl_AppendResult( interp, zBuf, null );
return TCL.TCL_OK;
}
/*
** Usage: btree_close ID
**
** Close the given database.
*/
static int btree_close(
object NotUsed,
Tcl_Interp interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
TclObject[] argv /* Text of each argument */
)
{
Btree pBt;
int rc;
if ( argc != 2 )
{
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0].ToString(),
" ID\"", null );
return TCL.TCL_ERROR;
}
pBt = (Btree)sqlite3TestTextToPtr( interp, argv[1].ToString() );
rc = sqlite3BtreeClose( ref pBt );
if ( rc != SQLITE_OK )
{
TCL.Tcl_AppendResult( interp, errorName( rc ), null );
return TCL.TCL_ERROR;
}
nRefSqlite3--;
if ( nRefSqlite3 == 0 )
{
sqlite3_mutex_leave( sDb.mutex );
sqlite3_mutex_free( sDb.mutex );
sDb.mutex = null;
sDb.pVfs = null;
}
return TCL.TCL_OK;
}
/*
** Usage: btree_begin_transaction ID
**
** Start a new transaction
*/
static int btree_begin_transaction(
object NotUsed,
Tcl_Interp interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
TclObject[] argv /* Text of each argument */
)
{
Btree pBt;
int rc;
if ( argc != 2 )
{
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0].ToString(),
" ID\"", null );
return TCL.TCL_ERROR;
}
pBt = (Btree)sqlite3TestTextToPtr( interp, argv[1].ToString() );
sqlite3BtreeEnter( pBt );
rc = sqlite3BtreeBeginTrans( pBt, 1 );
sqlite3BtreeLeave( pBt );
if ( rc != SQLITE_OK )
{
TCL.Tcl_AppendResult( interp, errorName( rc ), null );
;
return TCL.TCL_ERROR;
}
return TCL.TCL_OK;
}
/*
** Usage: btree_pager_stats ID
**
** Returns pager statistics
*/
static int btree_pager_stats(
object NotUsed,
Tcl_Interp interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
TclObject[] argv /* Text of each argument */
)
{
Btree pBt;
int i;
int[] a;
if ( argc != 2 )
{
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0].ToString(),
" ID\"" );
return TCL.TCL_ERROR;
}
pBt = (Btree)sqlite3TestTextToPtr( interp, argv[1].ToString() );
/* 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++ )
{
string[] zName = new string[]{
"ref", "page", "max", "size", "state", "err",
"hit", "miss", "ovfl", "read", "write"
};
StringBuilder zBuf = new StringBuilder( 100 );
TCL.Tcl_AppendElement( interp, zName[i] );
sqlite3_snprintf( 100, zBuf, "%d", a[i] );
TCL.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.TCL_OK;
}
/*
** Usage: btree_cursor ID TABLENUM WRITEABLE
**
** Create a new cursor. Return the ID for the cursor.
*/
static int btree_cursor(
object NotUsed,
Tcl_Interp interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
TclObject[] argv /* Text of each argument */
)
{
Btree pBt;
int iTable = 0;
BtCursor pCur;
int rc = SQLITE_OK;
int wrFlag = 0;
StringBuilder zBuf = new StringBuilder( 30 );
if ( argc != 4 )
{
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0].ToString(),
" ID TABLENUM WRITEABLE\"" );
return TCL.TCL_ERROR;
}
pBt = (Btree)sqlite3TestTextToPtr( interp, argv[1].ToString() );
if ( TCL.Tcl_GetInt( interp, argv[2], out iTable ) )
return TCL.TCL_ERROR;
if ( TCL.Tcl_GetBoolean( interp, argv[3], out wrFlag ) )
return TCL.TCL_ERROR;
//pCur = (BtCursor )ckalloc(sqlite3BtreeCursorSize());
pCur = new BtCursor();// memset( pCur, 0, sqlite3BtreeCursorSize() );
sqlite3BtreeEnter( pBt );
#if !SQLITE_OMIT_SHARED_CACHE
rc = sqlite3BtreeLockTable( pBt, iTable, wrFlag );
#endif
if ( rc == SQLITE_OK )
{
rc = sqlite3BtreeCursor( pBt, iTable, wrFlag, null, pCur );
}
sqlite3BtreeLeave( pBt );
if ( rc != 0 )
{
pCur = null;// ckfree( pCur );
TCL.Tcl_AppendResult( interp, errorName( rc ), null );
;
return TCL.TCL_ERROR;
}
sqlite3_snprintf( 30, zBuf, "->%p", pCur );
if ( TCL.Tcl_CreateCommandPointer( interp, zBuf, pCur ) )
{
return TCL.TCL_ERROR;
}
else
TCL.Tcl_AppendResult( interp, zBuf );
return SQLITE_OK;
}
/*
** Usage: btree_close_cursor ID
**
** Close a cursor opened using btree_cursor.
*/
static int btree_close_cursor(
object NotUsed,
Tcl_Interp interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
TclObject[] argv /* Text of each argument */
)
{
BtCursor pCur;
Btree pBt;
int rc;
if ( argc != 2 )
{
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0].ToString(),
" ID\"" );
return TCL.TCL_ERROR;
}
pCur = (BtCursor)sqlite3TestTextToPtr( interp, argv[1].ToString() );
pBt = pCur.pBtree;
sqlite3BtreeEnter( pBt );
rc = sqlite3BtreeCloseCursor( pCur );
sqlite3BtreeLeave( pBt );
pCur = null;//ckfree( (char*)pCur );
if ( rc != 0 )
{
TCL.Tcl_AppendResult( interp, errorName( rc ), null );
;
return TCL.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(
object NotUsed,
Tcl_Interp interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
TclObject[] argv /* Text of each argument */
)
{
BtCursor pCur;
int rc;
int res = 0;
StringBuilder zBuf = new StringBuilder( 100 );
if ( argc != 2 )
{
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0].ToString(),
" ID\"" );
return TCL.TCL_ERROR;
}
pCur = (BtCursor)sqlite3TestTextToPtr( interp, argv[1].ToString() );
#if SQLITE_TEST
sqlite3BtreeEnter( pCur.pBtree );
#endif
rc = sqlite3BtreeNext( pCur, ref res );
#if SQLITE_TEST
sqlite3BtreeLeave( pCur.pBtree );
#endif
if ( rc != 0 )
{
TCL.Tcl_AppendResult( interp, errorName( rc ), null );
;
return TCL.TCL_ERROR;
}
sqlite3_snprintf( 100, zBuf, "%d", res );
TCL.Tcl_AppendResult( interp, zBuf );
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(
object NotUsed,
Tcl_Interp interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
TclObject[] argv /* Text of each argument */
)
{
BtCursor pCur;
int rc;
int res = 0;
StringBuilder zBuf = new StringBuilder( 100 );
if ( argc != 2 )
{
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0].ToString(),
" ID\"" );
return TCL.TCL_ERROR;
}
pCur = (BtCursor)sqlite3TestTextToPtr( interp, argv[1].ToString() );
#if SQLITE_TEST
sqlite3BtreeEnter( pCur.pBtree );
#endif
rc = sqlite3BtreeFirst( pCur, ref res );
#if SQLITE_TEST
sqlite3BtreeLeave( pCur.pBtree );
#endif
if ( rc != 0 )
{
TCL.Tcl_AppendResult( interp, errorName( rc ), null );
;
return TCL.TCL_ERROR;
}
sqlite3_snprintf( 100, zBuf, "%d", res );
TCL.Tcl_AppendResult( interp, zBuf );
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(
// object NotUsed,
// Tcl_Interp interp, /* The TCL interpreter that invoked this command */
// int argc, /* Number of arguments */
// TclObject[] argv /* Text of each argument */
//){
// BtCursor pCur;
// int rc;
// char zBuf[50];
// if( argc!=2 ){
// TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0].ToString(),
// " ID\"");
// return TCL.TCL_ERROR;
// }
// pCur = (BtCursor)sqlite3TestTextToPtr(interp,argv[1].ToString());
// sqlite3BtreeEnter(pCur.pBtree);
// rc = sqlite3BtreeEof(pCur);
// sqlite3BtreeLeave(pCur.pBtree);
// sqlite3_snprintf(100, ref zBuf, "%d", rc);
// TCL.Tcl_AppendResult(interp, zBuf);
// return SQLITE_OK;
//}
/*
** Usage: btree_payload_size ID
**
** Return the number of bytes of payload
*/
static int btree_payload_size(
object NotUsed,
Tcl_Interp interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
TclObject[] argv /* Text of each argument */
)
{
BtCursor pCur;
i64 n1 = 0;
u32 n2 = 0;
StringBuilder zBuf = new StringBuilder( 50 );
if ( argc != 2 )
{
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0].ToString(),
" ID\"" );
return TCL.TCL_ERROR;
}
pCur = (BtCursor)sqlite3TestTextToPtr( interp, argv[1].ToString() );
#if SQLITE_TEST
sqlite3BtreeEnter( pCur.pBtree );
#endif
/* The cursor may be in "require-seek" state. If this is the case, the
** call to BtreeDataSize() will fix it. */
sqlite3BtreeDataSize( pCur, ref n2 );
if ( pCur.apPage[pCur.iPage].intKey != 0 )
{
n1 = 0;
}
else
{
sqlite3BtreeKeySize( pCur, ref n1 );
}
sqlite3BtreeLeave( pCur.pBtree );
sqlite3_snprintf( 30, zBuf, "%d", (int)( n1 + n2 ) );
TCL.Tcl_AppendResult( interp, zBuf );
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(
object NotUsed,
Tcl_Interp interp, /* The TCL interpreter that _invoked this command */
int argc, /* Number of arguments */
TclObject[] argv /* Text of each argument */
)
{
int start = 0, mult = 0, count = 0, incr = 0;
int _in;
u32 _out = 0;
int n1, n2, i, j;
byte[] zBuf = new byte[100];
if ( argc != 5 )
{
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0].ToString(),
" START MULTIPLIER COUNT incrEMENT\"", 0 );
return TCL.TCL_ERROR;
}
if ( TCL.Tcl_GetInt( interp, argv[1], out start ) )
return TCL.TCL_ERROR;
if ( TCL.Tcl_GetInt( interp, argv[2], out mult ) )
return TCL.TCL_ERROR;
if ( TCL.Tcl_GetInt( interp, argv[3], out count ) )
return TCL.TCL_ERROR;
if ( TCL.Tcl_GetInt( interp, argv[4], out incr ) )
return TCL.TCL_ERROR;
_in = start;
_in *= mult;
for ( i = 0; i < count; i++ )
{
StringBuilder zErr = new StringBuilder( 200 );
n1 = putVarint( zBuf, 0, _in );
if ( n1 > 9 || n1 < 1 )
{
sqlite3_snprintf( 100, zErr, "putVarint returned %d - should be between 1 and 9", n1 );
TCL.Tcl_AppendResult( interp, zErr );
return TCL.TCL_ERROR;
}
n2 = getVarint( zBuf, 0, out _out );
if ( n1 != n2 )
{
sqlite3_snprintf( 100, zErr, "putVarint returned %d and GetVar_int returned %d", n1, n2 );
TCL.Tcl_AppendResult( interp, zErr );
return TCL.TCL_ERROR;
}
if ( _in != (int)_out )
{
sqlite3_snprintf( 100, zErr, "Wrote 0x%016llx and got back 0x%016llx", _in, _out );
TCL.Tcl_AppendResult( interp, zErr );
return TCL.TCL_ERROR;
}
if ( ( _in & 0xffffffff ) == _in )
{
u32 _out32 = 0;
n2 = getVarint32( zBuf, out _out32 );
_out = _out32;
if ( n1 != n2 )
{
sqlite3_snprintf( 100, zErr, "putVarint returned %d and GetVar_int32 returned %d",
n1, n2 );
TCL.Tcl_AppendResult( interp, zErr );
return TCL.TCL_ERROR;
}
if ( _in != (int)_out )
{
sqlite3_snprintf( 100, zErr, "Wrote 0x%016llx and got back 0x%016llx from GetVar_int32",
_in, _out );
TCL.Tcl_AppendResult( interp, zErr );
return TCL.TCL_ERROR;
}
}
/* _in order to get realistic tim_ings, run getVar_int 19 more times.
** This is because getVar_int is called ab_out 20 times more often
** than putVarint.
*/
for ( j = 0; j < 19; j++ )
{
getVarint( zBuf, 0, out _out );
}
_in += incr;
}
return TCL.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(
object NotUsed,
Tcl_Interp interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
TclObject[] argv /* Text of each argument */
)
{
StringBuilder zBuf = new StringBuilder( 100 );
WrappedCommand info = null;
sqlite3 db;
Btree pBt;
int iDb = 0;
if ( argc != 2 && argc != 3 )
{
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0].ToString(),
" DB-HANDLE ?N?\"" );
return TCL.TCL_ERROR;
}
if ( TCL.Tcl_GetCommandInfo( interp, argv[1].ToString(), out info ) )
{
TCL.Tcl_AppendResult( interp, "No such db-handle: \"", argv[1], "\"" );
return TCL.TCL_ERROR;
}
if ( argc == 3 )
{
iDb = atoi( argv[2].ToString() );
}
db = ( (SqliteDb)info.objClientData ).db;
Debug.Assert( db != null );
pBt = db.aDb[iDb].pBt;
sqlite3_snprintf( 50, zBuf, "->%p", pBt );
if ( TCL.Tcl_CreateCommandPointer( interp, zBuf, pBt ) )
{
return TCL.TCL_ERROR;
}
else
TCL.Tcl_SetResult( interp, zBuf, TCL.TCL_VOLATILE );
return TCL.TCL_OK;
}
/*
** Usage: btree_ismemdb ID
**
** Return true if the B-Tree is in-memory.
*/
static int btree_ismemdb(
object NotUsed,
Tcl_Interp interp, /* The TCL interpreter that invoked this command */
int argc, /* Number of arguments */
TclObject[] argv /* Text of each argument */
)
{
Btree pBt;
int res;
if ( argc != 2 )
{
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
" ID\"" );
return TCL.TCL_ERROR;
}
pBt = (Btree)sqlite3TestTextToPtr( interp, argv[1].ToString() );
sqlite3_mutex_enter( pBt.db.mutex );
sqlite3BtreeEnter( pBt );
res = sqlite3PagerIsMemdb( sqlite3BtreePager( pBt ) ) ? 1 : 0;
sqlite3BtreeLeave( pBt );
sqlite3_mutex_leave( pBt.db.mutex );
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewBooleanObj( res ) );
return TCL.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(
// object NotUsed,
// Tcl_Interp interp, /* The TCL interpreter that invoked this command */
// int argc, /* Number of arguments */
// TclObject[] argv /* Text of each argument */
//){
// int nCache;
// Btree pBt;
// if( argc!=3 ){
// TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0].ToString(),
// " BT NCACHE\"");
// return TCL.TCL_ERROR;
// }
// pBt = (Btree)sqlite3TestTextToPtr(interp,argv[1].ToString());
// if(TCL.Tcl_GetInt(interp, argv[2], nCache) ) return TCL.TCL_ERROR;
// sqlite3_mutex_enter(pBt.db.mutex);
// sqlite3BtreeEnter(pBt);
// sqlite3BtreeSetCacheSize(pBt, nCache);
// sqlite3BtreeLeave(pBt);
// sqlite3_mutex_leave(pBt.db.mutex);
// return TCL.TCL_OK;
//}
/*
** Register commands with the TCL interpreter.
*/
public class _aCmd
{
public string zName;
public Tcl_CmdProc xProc;
public _aCmd( string zName, Tcl_CmdProc xProc )
{
this.zName = zName;
this.xProc = xProc;
}
}
public static int Sqlitetest3_Init( Tcl_Interp interp )
{
_aCmd[] aCmd = new _aCmd[] {
new _aCmd( "btree_open", (Tcl_CmdProc)btree_open ),
new _aCmd( "btree_close", (Tcl_CmdProc)btree_close ),
new _aCmd( "btree_begin_transaction", (Tcl_CmdProc)btree_begin_transaction ),
new _aCmd( "btree_pager_stats", (Tcl_CmdProc)btree_pager_stats ),
new _aCmd( "btree_cursor", (Tcl_CmdProc)btree_cursor ),
new _aCmd( "btree_close_cursor", (Tcl_CmdProc)btree_close_cursor ),
new _aCmd( "btree_next", (Tcl_CmdProc)btree_next ),
//new _aCmd( "btree_eof", (Tcl_CmdProc)btree_eof ),
new _aCmd( "btree_payload_size", (Tcl_CmdProc)btree_payload_size ),
new _aCmd( "btree_first", (Tcl_CmdProc)btree_first ),
new _aCmd( "btree_varint_test", (Tcl_CmdProc)btree_varint_test ),
new _aCmd( "btree_from_db", (Tcl_CmdProc)btree_from_db ),
new _aCmd( "btree_ismemdb", (Tcl_CmdProc)btree_ismemdb ),
//new _aCmd( "btree_set_cache_size", (Tcl_CmdProc)btree_set_cache_size ),
};
int i;
for ( i = 0; i < aCmd.Length; i++ )
{ //sizeof(aCmd)/sizeof(aCmd[0]); i++){
TCL.Tcl_CreateCommand( interp, aCmd[i].zName, aCmd[i].xProc, null, null );
}
return TCL.TCL_OK;
}
}
#endif
}