/trunk/testfixture/src/tclsqlite_c.cs |
@@ -0,0 +1,4427 @@ |
using System; |
using System.Diagnostics; |
using sqlite_int64 = System.Int64; |
using sqlite_u3264 = System.UInt64; |
using u32 = System.UInt32; |
|
namespace Community.CsharpSqlite |
{ |
#if TCLSH |
using tcl.lang; |
using ClientData = System.Object; |
|
#if !SQLITE_OMIT_INCRBLOB |
using sqlite3_blob = sqlite.Incrblob; |
#endif |
using sqlite3_stmt = Sqlite3.Vdbe; |
using Tcl_DString = tcl.lang.TclString; |
using Tcl_Interp = tcl.lang.Interp; |
using Tcl_Obj = tcl.lang.TclObject; |
using Tcl_WideInt = System.Int64; |
|
using sqlite3_value = Sqlite3.Mem; |
using System.IO; |
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. |
** |
************************************************************************* |
** A TCL Interface to SQLite. Append this file to sqlite3.c and |
** compile the whole thing to build a TCL-enabled version of SQLite. |
** |
** Compile-time options: |
** |
** -DTCLSH=1 Add a "main()" routine that works as a tclsh. |
** |
** -DSQLITE_TCLMD5 When used in conjuction with -DTCLSH=1, add |
** four new commands to the TCL interpreter for |
** generating MD5 checksums: md5, md5file, |
** md5-10x8, and md5file-10x8. |
** |
** -DSQLITE_TEST When used in conjuction with -DTCLSH=1, add |
** hundreds of new commands used for testing |
** SQLite. This option implies -DSQLITE_TCLMD5. |
************************************************************************* |
** 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 "tcl.h" |
//#include <errno.h> |
|
/* |
** Some additional include files are needed if this file is not |
** appended to the amalgamation. |
*/ |
#if !SQLITE_AMALGAMATION |
//# include "sqlite3.h" |
//# include <stdlib.h> |
//# include <string.h> |
//# include <Debug.Assert.h> |
// typedef unsigned char u8; |
#endif |
|
/* |
* Windows needs to know which symbols to export. Unix does not. |
* BUILD_sqlite should be undefined for Unix. |
*/ |
#if BUILD_sqlite |
//#undef TCL.Tcl_STORAGE_CLASS |
//#define TCL.Tcl_STORAGE_CLASS DLLEXPORT |
#endif // * BUILD_sqlite */ |
|
const int NUM_PREPARED_STMTS = 10;//#define NUM_PREPARED_STMTS 10 |
const int MAX_PREPARED_STMTS = 100;//#define MAX_PREPARED_STMTS 100 |
|
/* |
** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we |
** have to do a translation when going between the two. Set the |
** UTF_TRANSLATION_NEEDED macro to indicate that we need to do |
** this translation. |
*/ |
#if Tcl_UTF_MAX && !SQLITE_UTF8 |
//# define UTF_TRANSLATION_NEEDED 1 |
#endif |
|
/* |
** New SQL functions can be created as TCL scripts. Each such function |
** is described by an instance of the following structure. |
*/ |
//typedef struct SqlFunc SqlFunc; |
public class SqlFunc |
{ |
public Tcl_Interp interp; /* The TCL interpret to execute the function */ |
public Tcl_Obj pScript; /* The Tcl_Obj representation of the script */ |
public int useEvalObjv; /* True if it is safe to use TCL.Tcl_EvalObjv */ |
public string zName; /* Name of this function */ |
public SqlFunc pNext; /* Next function on the list of them all */ |
} |
|
/* |
** New collation sequences function can be created as TCL scripts. Each such |
** function is described by an instance of the following structure. |
*/ |
//typedef struct SqlCollate SqlCollate; |
public class SqlCollate |
{ |
public Tcl_Interp interp; /* The TCL interpret to execute the function */ |
public string zScript; /* The script to be run */ |
public SqlCollate pNext; /* Next function on the list of them all */ |
} |
|
/* |
** Prepared statements are cached for faster execution. Each prepared |
** statement is described by an instance of the following structure. |
*/ |
//typedef struct SqlPreparedStmt SqlPreparedStmt; |
public class SqlPreparedStmt |
{ |
public SqlPreparedStmt pNext; /* Next in linked list */ |
public SqlPreparedStmt pPrev; /* Previous on the list */ |
public sqlite3_stmt pStmt; /* The prepared statement */ |
public Mem[] aMem; /* Original Memory Values to be reused */ |
public int nSql; /* chars in zSql[] */ |
public string zSql; /* Text of the SQL statement */ |
public int nParm; /* Size of apParm array */ |
public Tcl_Obj[] apParm; /* Array of referenced object pointers */ |
} |
|
//typedef struct IncrblobChannel IncrblobChannel; |
|
/* |
** There is one instance of this structure for each SQLite database |
** that has been opened by the SQLite TCL interface. |
*/ |
//typedef struct SqliteDb SqliteDb; |
public class SqliteDb : object |
{ |
public sqlite3 db; /* The "real" database structure. MUST BE FIRST */ |
public Tcl_Interp interp; /* The interpreter used for this database */ |
public string zBusy; /* The busy callback routine */ |
public string zCommit; /* The commit hook callback routine */ |
public string zTrace; /* The trace callback routine */ |
public string zProfile; /* The profile callback routine */ |
public string zProgress; /* The progress callback routine */ |
public string zAuth; /* The authorization callback routine */ |
public int disableAuth; /* Disable the authorizer if it exists */ |
public string zNull = ""; /* Text to substitute for an SQL NULL value */ |
public SqlFunc pFunc; /* List of SQL functions */ |
public Tcl_Obj pUpdateHook; /* Update hook script (if any) */ |
public Tcl_Obj pRollbackHook; /* Rollback hook script (if any) */ |
public Tcl_Obj pWalHook; /* WAL hook script (if any) */ |
public Tcl_Obj pUnlockNotify; /* Unlock notify script (if any) */ |
public SqlCollate pCollate; /* List of SQL collation functions */ |
public int rc; /* Return code of most recent sqlite3_exec() */ |
public Tcl_Obj pCollateNeeded; /* Collation needed script */ |
public SqlPreparedStmt stmtList; /* List of prepared statements*/ |
public SqlPreparedStmt stmtLast; /* Last statement in the list */ |
public int maxStmt; /* The next maximum number of stmtList */ |
public int nStmt; /* Number of statements in stmtList */ |
#if !SQLITE_OMIT_INCRBLOB |
public IncrblobChannel pIncrblob; /* Linked list of open incrblob channels */ |
#endif |
public int nStep, nSort, nIndex; /* Statistics for most recent operation */ |
public int nTransaction; /* Number of nested [transaction] methods */ |
} |
|
#if !SQLITE_OMIT_INCRBLOB |
class IncrblobChannel |
{ |
public sqlite3_blob pBlob; /* sqlite3 blob handle */ |
public SqliteDb pDb; /* Associated database connection */ |
public int iSeek; /* Current seek offset */ |
public Tcl_Channel channel; /* Channel identifier */ |
public IncrblobChannel pNext; /* Linked list of all open incrblob channels */ |
public IncrblobChannel pPrev; /* Linked list of all open incrblob channels */ |
} |
#endif |
|
|
/* |
** Compute a string length that is limited to what can be stored in |
** lower 30 bits of a 32-bit signed integer. |
*/ |
static int strlen30( StringBuilder z ) |
{ |
//string z2 = z; |
//while( *z2 ){ z2++; } |
return 0x3fffffff & z.Length; |
} |
|
static int strlen30( string z ) |
{ |
//string z2 = z; |
//while( *z2 ){ z2++; } |
return 0x3fffffff & z.Length; |
} |
|
|
#if !SQLITE_OMIT_INCRBLOB |
/* |
** Close all incrblob channels opened using database connection pDb. |
** This is called when shutting down the database connection. |
*/ |
static void closeIncrblobChannels( SqliteDb pDb ) |
{ |
IncrblobChannel p; |
IncrblobChannel pNext; |
|
for ( p = pDb.pIncrblob ; p != null ; p = pNext ) |
{ |
pNext = p.pNext; |
|
/* Note: Calling unregister here call TCL.Tcl_Close on the incrblob channel, |
** which deletes the IncrblobChannel structure at p. So do not |
** call TCL.Tcl_Free() here. |
*/ |
TCL.Tcl_UnregisterChannel( pDb.interp, p.channel ); |
} |
} |
|
/* |
** Close an incremental blob channel. |
*/ |
//static int incrblobClose(object instanceData, Tcl_Interp interp){ |
// IncrblobChannel p = (IncrblobChannel )instanceData; |
// int rc = sqlite3_blob_close(p.pBlob); |
// sqlite3 db = p.pDb.db; |
|
// /* Remove the channel from the SqliteDb.pIncrblob list. */ |
// if( p.pNext ){ |
// p.pNext.pPrev = p.pPrev; |
// } |
// if( p.pPrev ){ |
// p.pPrev.pNext = p.pNext; |
// } |
// if( p.pDb.pIncrblob==p ){ |
// p.pDb.pIncrblob = p.pNext; |
// } |
|
// /* Free the IncrblobChannel structure */ |
// TCL.Tcl_Free((char )p); |
|
// if( rc!=SQLITE_OK ){ |
// TCL.Tcl_SetResult(interp, (char )sqlite3_errmsg(db), TCL.Tcl_VOLATILE); |
// return TCL.TCL_ERROR; |
// } |
// return TCL.TCL_OK; |
//} |
|
/* |
** Read data from an incremental blob channel. |
*/ |
//static int incrblobInput( |
// object instanceData, |
// char *buf, |
// int bufSize, |
// int *errorCodePtr |
//){ |
// IncrblobChannel p = (IncrblobChannel )instanceData; |
// int nRead = bufSize; /* Number of bytes to read */ |
// int nBlob; /* Total size of the blob */ |
// int rc; /* sqlite error code */ |
|
// nBlob = sqlite3_blob_bytes(p.pBlob); |
// if( (p.iSeek+nRead)>nBlob ){ |
// nRead = nBlob-p.iSeek; |
// } |
// if( nRead<=0 ){ |
// return 0; |
// } |
|
// rc = sqlite3_blob_read(p.pBlob, (void )buf, nRead, p.iSeek); |
// if( rc!=SQLITE_OK ){ |
// *errorCodePtr = rc; |
// return -1; |
// } |
|
// p.iSeek += nRead; |
// return nRead; |
//} |
|
/* |
** Write data to an incremental blob channel. |
*/ |
//static int incrblobOutput( |
// object instanceData, |
// string buf, |
// int toWrite, |
// int *errorCodePtr |
//){ |
// IncrblobChannel p = (IncrblobChannel )instanceData; |
// int nWrite = toWrite; /* Number of bytes to write */ |
// int nBlob; /* Total size of the blob */ |
// int rc; /* sqlite error code */ |
|
// nBlob = sqlite3_blob_bytes(p.pBlob); |
// if( (p.iSeek+nWrite)>nBlob ){ |
// *errorCodePtr = EINVAL; |
// return -1; |
// } |
// if( nWrite<=0 ){ |
// return 0; |
// } |
|
// rc = sqlite3_blob_write(p.pBlob, (void )buf, nWrite, p.iSeek); |
// if( rc!=SQLITE_OK ){ |
// *errorCodePtr = EIO; |
// return -1; |
// } |
|
// p.iSeek += nWrite; |
// return nWrite; |
//} |
|
/* |
** Seek an incremental blob channel. |
*/ |
//static int incrblobSeek( |
// object instanceData, |
// long offset, |
// int seekMode, |
// int *errorCodePtr |
//){ |
// IncrblobChannel p = (IncrblobChannel )instanceData; |
|
// switch( seekMode ){ |
// case SEEK_SET: |
// p.iSeek = offset; |
// break; |
// case SEEK_CUR: |
// p.iSeek += offset; |
// break; |
// case SEEK_END: |
// p.iSeek = sqlite3_blob_bytes(p.pBlob) + offset; |
// break; |
|
// default: Debug.Assert(!"Bad seekMode"); |
// } |
|
// return p.iSeek; |
//} |
|
|
//static void incrblobWatch(object instanceData, int mode){ |
// /* NO-OP */ |
//} |
//static int incrblobHandle(object instanceData, int dir, object *hPtr){ |
// return TCL.TCL_ERROR; |
//} |
|
static TCL.Tcl_ChannelType IncrblobChannelType = { |
"incrblob", /* typeName */ |
TCL.Tcl_CHANNEL_VERSION_2, /* version */ |
incrblobClose, /* closeProc */ |
incrblobInput, /* inputProc */ |
incrblobOutput, /* outputProc */ |
incrblobSeek, /* seekProc */ |
0, /* setOptionProc */ |
0, /* getOptionProc */ |
incrblobWatch, /* watchProc (this is a no-op) */ |
incrblobHandle, /* getHandleProc (always returns error) */ |
0, /* close2Proc */ |
0, /* blockModeProc */ |
0, /* flushProc */ |
0, /* handlerProc */ |
0, /* wideSeekProc */ |
}; |
|
/* |
** Create a new incrblob channel. |
*/ |
static int count = 0; |
static int createIncrblobChannel( |
Tcl_Interp interp, |
SqliteDb pDb, |
string zDb, |
string zTable, |
string zColumn, |
sqlite_int64 iRow, |
int isReadonly |
){ |
IncrblobChannel p; |
sqlite3 db = pDb.db; |
sqlite3_blob pBlob; |
int rc; |
int flags = TCL.Tcl_READABLE|(isReadonly ? 0 : TCL.Tcl_WRITABLE); |
|
/* This variable is used to name the channels: "incrblob_[incr count]" */ |
//static int count = 0; |
string zChannel = "";//string[64]; |
|
rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, pBlob); |
if( rc!=SQLITE_OK ){ |
TCL.Tcl_SetResult(interp, sqlite3_errmsg(pDb.db), TCL.Tcl_VOLATILE); |
return TCL.TCL_ERROR; |
} |
|
p = new IncrblobChannel();//(IncrblobChannel )Tcl_Alloc(sizeof(IncrblobChannel)); |
p.iSeek = 0; |
p.pBlob = pBlob; |
|
sqlite3_snprintf(64, zChannel, "incrblob_%d", ++count); |
p.channel = TCL.Tcl_CreateChannel(IncrblobChannelType, zChannel, p, flags); |
TCL.Tcl_RegisterChannel(interp, p.channel); |
|
/* Link the new channel into the SqliteDb.pIncrblob list. */ |
p.pNext = pDb.pIncrblob; |
p.pPrev = null; |
if( p.pNext!=null ){ |
p.pNext.pPrev = p; |
} |
pDb.pIncrblob = p; |
p.pDb = pDb; |
|
TCL.Tcl_SetResult(interp, Tcl_GetChannelName(p.channel), TCL.Tcl_VOLATILE); |
return TCL.TCL_OK; |
} |
#else // * else clause for "#if !SQLITE_OMIT_INCRBLOB" */ |
//#define closeIncrblobChannels(pDb) |
static void closeIncrblobChannels( SqliteDb pDb ) |
{ |
} |
#endif |
|
/* |
** Look at the script prefix in pCmd. We will be executing this script |
** after first appending one or more arguments. This routine analyzes |
** the script to see if it is safe to use TCL.Tcl_EvalObjv() on the script |
** rather than the more general TCL.Tcl_EvalEx(). TCL.Tcl_EvalObjv() is much |
** faster. |
** |
** Scripts that are safe to use with TCL.Tcl_EvalObjv() consists of a |
** command name followed by zero or more arguments with no [...] or $ |
** or {...} or ; to be seen anywhere. Most callback scripts consist |
** of just a single procedure name and they meet this requirement. |
*/ |
static int safeToUseEvalObjv( Tcl_Interp interp, Tcl_Obj pCmd ) |
{ |
/* We could try to do something with TCL.Tcl_Parse(). But we will instead |
** just do a search for forbidden characters. If any of the forbidden |
** characters appear in pCmd, we will report the string as unsafe. |
*/ |
string z; |
int n = 0; |
z = TCL.Tcl_GetStringFromObj( pCmd, out n ); |
while ( n-- > 0 ) |
{ |
int c = z[n];// *( z++ ); |
if ( c == '$' || c == '[' || c == ';' ) |
return 0; |
} |
return 1; |
} |
|
/* |
** Find an SqlFunc structure with the given name. Or create a new |
** one if an existing one cannot be found. Return a pointer to the |
** structure. |
*/ |
static SqlFunc findSqlFunc( SqliteDb pDb, string zName ) |
{ |
SqlFunc p, pNew; |
int i; |
pNew = new SqlFunc();//(SqlFunc)Tcl_Alloc( sizeof(*pNew) + strlen30(zName) + 1 ); |
//pNew.zName = (char)&pNew[1]; |
//for(i=0; zName[i]; i++){ pNew.zName[i] = tolower(zName[i]); } |
//pNew.zName[i] = 0; |
pNew.zName = zName.ToLower(); |
for ( p = pDb.pFunc; p != null; p = p.pNext ) |
{ |
if ( p.zName == pNew.zName ) |
{ |
//Tcl_Free((char)pNew); |
return p; |
} |
} |
pNew.interp = pDb.interp; |
pNew.pScript = null; |
pNew.pNext = pDb.pFunc; |
pDb.pFunc = pNew; |
return pNew; |
} |
|
/* |
** Finalize and free a list of prepared statements |
*/ |
static void flushStmtCache( SqliteDb pDb ) |
{ |
SqlPreparedStmt pPreStmt; |
|
while ( pDb.stmtList != null ) |
{ |
sqlite3_finalize( pDb.stmtList.pStmt ); |
pPreStmt = pDb.stmtList; |
pDb.stmtList = pDb.stmtList.pNext; |
TCL.Tcl_Free( ref pPreStmt ); |
} |
pDb.nStmt = 0; |
pDb.stmtLast = null; |
} |
|
/* |
** TCL calls this procedure when an sqlite3 database command is |
** deleted. |
*/ |
static void DbDeleteCmd( ref object db ) |
{ |
SqliteDb pDb = (SqliteDb)db; |
flushStmtCache( pDb ); |
closeIncrblobChannels( pDb ); |
sqlite3_close( pDb.db ); |
while ( pDb.pFunc != null ) |
{ |
SqlFunc pFunc = pDb.pFunc; |
pDb.pFunc = pFunc.pNext; |
TCL.Tcl_DecrRefCount( ref pFunc.pScript ); |
TCL.Tcl_Free( ref pFunc ); |
} |
while ( pDb.pCollate != null ) |
{ |
SqlCollate pCollate = pDb.pCollate; |
pDb.pCollate = pCollate.pNext; |
TCL.Tcl_Free( ref pCollate ); |
} |
if ( pDb.zBusy != null ) |
{ |
TCL.Tcl_Free( ref pDb.zBusy ); |
} |
if ( pDb.zTrace != null ) |
{ |
TCL.Tcl_Free( ref pDb.zTrace ); |
} |
if ( pDb.zProfile != null ) |
{ |
TCL.Tcl_Free( ref pDb.zProfile ); |
} |
if ( pDb.zAuth != null ) |
{ |
TCL.Tcl_Free( ref pDb.zAuth ); |
} |
if ( pDb.zNull != null ) |
{ |
TCL.Tcl_Free( ref pDb.zNull ); |
} |
if ( pDb.pUpdateHook != null ) |
{ |
TCL.Tcl_DecrRefCount( ref pDb.pUpdateHook ); |
} |
if ( pDb.pRollbackHook != null ) |
{ |
TCL.Tcl_DecrRefCount( ref pDb.pRollbackHook ); |
} |
if ( pDb.pWalHook != null ) |
{ |
TCL.Tcl_DecrRefCount( ref pDb.pWalHook ); |
} |
if ( pDb.pCollateNeeded != null ) |
{ |
TCL.Tcl_DecrRefCount( ref pDb.pCollateNeeded ); |
} |
TCL.Tcl_Free( ref pDb ); |
} |
|
/* |
** This routine is called when a database file is locked while trying |
** to execute SQL. |
*/ |
static int DbBusyHandler( object cd, int nTries ) |
{ |
SqliteDb pDb = (SqliteDb)cd; |
int rc; |
StringBuilder zVal = new StringBuilder( 30 );//char zVal[30]; |
|
sqlite3_snprintf( 30, zVal, "%d", nTries ); |
rc = TCL.Tcl_VarEval( pDb.interp, pDb.zBusy, " ", zVal.ToString(), null ); |
if ( rc != TCL.TCL_OK || atoi( TCL.Tcl_GetStringResult( pDb.interp ) ) != 0 ) |
{ |
return 0; |
} |
return 1; |
} |
|
#if !SQLITE_OMIT_PROGRESS_CALLBACK |
/* |
** This routine is invoked as the 'progress callback' for the database. |
*/ |
static int DbProgressHandler( object cd ) |
{ |
SqliteDb pDb = (SqliteDb)cd; |
int rc; |
|
Debug.Assert( pDb.zProgress != null ); |
rc = TCL.Tcl_Eval( pDb.interp, pDb.zProgress ); |
if ( rc != TCL.TCL_OK || atoi( TCL.Tcl_GetStringResult( pDb.interp ) ) != 0 ) |
{ |
return 1; |
} |
return 0; |
} |
#endif |
|
#if !SQLITE_OMIT_TRACE |
/* |
** This routine is called by the SQLite trace handler whenever a new |
** block of SQL is executed. The TCL script in pDb.zTrace is executed. |
*/ |
static void DbTraceHandler( object cd, string zSql ) |
{ |
SqliteDb pDb = (SqliteDb)cd; |
TclObject str = null; |
|
TCL.Tcl_DStringInit( out str ); |
TCL.Tcl_DStringAppendElement( str, pDb.zTrace ); |
TCL.Tcl_DStringAppendElement( str, " {" + zSql + "}" ); |
TCL.Tcl_EvalObjEx( pDb.interp, str, 0 );// TCL.Tcl_Eval( pDb.interp, TCL.Tcl_DStringValue( ref str ) ); |
TCL.Tcl_DStringFree( ref str ); |
TCL.Tcl_ResetResult( pDb.interp ); |
} |
#endif |
|
#if !SQLITE_OMIT_TRACE |
/* |
** This routine is called by the SQLite profile handler after a statement |
** SQL has executed. The TCL script in pDb.zProfile is evaluated. |
*/ |
static void DbProfileHandler( object cd, string zSql, sqlite_int64 tm ) |
{ |
SqliteDb pDb = (SqliteDb)cd; |
TclObject str = null; |
StringBuilder zTm = new StringBuilder( 100 );//char zTm[100]; |
|
sqlite3_snprintf( 100, zTm, "%lld", tm ); |
TCL.Tcl_DStringInit( out str ); |
TCL.Tcl_DStringAppendElement( str, pDb.zProfile ); |
TCL.Tcl_DStringAppendElement( str, " {" + zSql + "}" ); |
TCL.Tcl_DStringAppendElement( str, " {" + zTm.ToString() + "}" ); |
TCL.Tcl_Eval( pDb.interp, str.ToString() ); |
TCL.Tcl_DStringFree( ref str ); |
TCL.Tcl_ResetResult( pDb.interp ); |
} |
#endif |
|
/* |
** This routine is called when a transaction is committed. The |
** TCL script in pDb.zCommit is executed. If it returns non-zero or |
** if it throws an exception, the transaction is rolled back instead |
** of being committed. |
*/ |
static int DbCommitHandler( object cd ) |
{ |
SqliteDb pDb = (SqliteDb)cd; |
int rc; |
|
rc = TCL.Tcl_Eval( pDb.interp, pDb.zCommit ); |
if ( rc != TCL.TCL_OK || atoi( TCL.Tcl_GetStringResult( pDb.interp ) ) != 0 ) |
{ |
return 1; |
} |
return 0; |
} |
|
static void DbRollbackHandler( object _object ) |
{ |
SqliteDb pDb = (SqliteDb)_object; |
Debug.Assert( pDb.pRollbackHook != null ); |
if ( TCL.TCL_OK != TCL.Tcl_EvalObjEx( pDb.interp, pDb.pRollbackHook, 0 ) ) |
{ |
TCL.Tcl_BackgroundError( pDb.interp ); |
} |
} |
|
/* |
** This procedure handles wal_hook callbacks. |
*/ |
static int DbWalHandler( |
object clientData, |
sqlite3 db, |
string zDb, |
int nEntry |
) |
{ |
int ret = SQLITE_OK; |
Tcl_Obj p; |
SqliteDb pDb = (SqliteDb)clientData; |
Tcl_Interp interp = pDb.interp; |
Debug.Assert( pDb.pWalHook != null ); |
|
p = TCL.Tcl_DuplicateObj( pDb.pWalHook ); |
TCL.Tcl_IncrRefCount( p ); |
TCL.Tcl_ListObjAppendElement( interp, p, TCL.Tcl_NewStringObj( zDb, -1 ) ); |
TCL.Tcl_ListObjAppendElement( interp, p, TCL.Tcl_NewIntObj( nEntry ) ); |
if ( TCL.TCL_OK != TCL.Tcl_EvalObjEx( interp, p, 0 ) |
|| TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, TCL.Tcl_GetObjResult( interp ), out ret ) |
) |
{ |
TCL.Tcl_BackgroundError( interp ); |
} |
TCL.Tcl_DecrRefCount( ref p ); |
|
return ret; |
} |
|
#if (SQLITE_TEST) && (SQLITE_ENABLE_UNLOCK_NOTIFY) |
static void setTestUnlockNotifyVars(Tcl_Interp interp, int iArg, int nArg){ |
char zBuf[64]; |
sprintf(zBuf, "%d", iArg); |
Tcl_SetVar(interp, "sqlite_unlock_notify_arg", zBuf, TCL_GLOBAL_ONLY); |
sprintf(zBuf, "%d", nArg); |
Tcl_SetVar(interp, "sqlite_unlock_notify_argcount", zBuf, TCL_GLOBAL_ONLY); |
} |
#else |
//# define setTestUnlockNotifyVars(x,y,z) |
#endif |
|
#if SQLITE_ENABLE_UNLOCK_NOTIFY |
static void DbUnlockNotify(void **apArg, int nArg){ |
int i; |
for(i=0; i<nArg; i++){ |
const int flags = (TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT); |
SqliteDb *pDb = (SqliteDb )apArg[i]; |
setTestUnlockNotifyVars(pDb.interp, i, nArg); |
Debug.Assert( pDb.pUnlockNotify); |
Tcl_EvalObjEx(pDb.interp, pDb.pUnlockNotify, flags); |
Tcl_DecrRefCount(pDb.pUnlockNotify); |
pDb.pUnlockNotify = 0; |
} |
} |
#endif |
|
static void DbUpdateHandler( |
object p, |
int op, |
string zDb, |
string zTbl, |
sqlite_int64 rowid |
) |
{ |
SqliteDb pDb = (SqliteDb)p; |
Tcl_Obj pCmd; |
|
Debug.Assert( pDb.pUpdateHook != null ); |
Debug.Assert( op == SQLITE_INSERT || op == SQLITE_UPDATE || op == SQLITE_DELETE ); |
|
pCmd = TCL.Tcl_DuplicateObj( pDb.pUpdateHook ); |
TCL.Tcl_IncrRefCount( pCmd ); |
TCL.Tcl_ListObjAppendElement( null, pCmd, TCL.Tcl_NewStringObj( |
( ( op == SQLITE_INSERT ) ? "INSERT" : ( op == SQLITE_UPDATE ) ? "UPDATE" : "DELETE" ), -1 ) ); |
TCL.Tcl_ListObjAppendElement( null, pCmd, TCL.Tcl_NewStringObj( zDb, -1 ) ); |
TCL.Tcl_ListObjAppendElement( null, pCmd, TCL.Tcl_NewStringObj( zTbl, -1 ) ); |
TCL.Tcl_ListObjAppendElement( null, pCmd, TCL.Tcl_NewWideIntObj( rowid ) ); |
TCL.Tcl_EvalObjEx( pDb.interp, pCmd, TCL.TCL_EVAL_DIRECT ); |
TCL.Tcl_DecrRefCount( ref pCmd ); |
} |
|
static void tclCollateNeeded( |
object pCtx, |
sqlite3 db, |
int enc, |
string zName |
) |
{ |
SqliteDb pDb = (SqliteDb)pCtx; |
Tcl_Obj pScript = TCL.Tcl_DuplicateObj( pDb.pCollateNeeded ); |
TCL.Tcl_IncrRefCount( pScript ); |
TCL.Tcl_ListObjAppendElement( null, pScript, TCL.Tcl_NewStringObj( zName, -1 ) ); |
TCL.Tcl_EvalObjEx( pDb.interp, pScript, 0 ); |
TCL.Tcl_DecrRefCount( ref pScript ); |
} |
|
/* |
** This routine is called to evaluate an SQL collation function implemented |
** using TCL script. |
*/ |
static int tclSqlCollate( |
object pCtx, |
int nA, |
string zA, |
int nB, |
string zB |
) |
{ |
SqlCollate p = (SqlCollate)pCtx; |
Tcl_Obj pCmd; |
|
pCmd = TCL.Tcl_NewStringObj( p.zScript, -1 ); |
TCL.Tcl_IncrRefCount( pCmd ); |
TCL.Tcl_ListObjAppendElement( p.interp, pCmd, TCL.Tcl_NewStringObj( zA, nA ) ); |
TCL.Tcl_ListObjAppendElement( p.interp, pCmd, TCL.Tcl_NewStringObj( zB, nB ) ); |
TCL.Tcl_EvalObjEx( p.interp, pCmd, TCL.TCL_EVAL_DIRECT ); |
TCL.Tcl_DecrRefCount( ref pCmd ); |
return ( atoi( TCL.Tcl_GetStringResult( p.interp ) ) ); |
} |
|
/* |
** This routine is called to evaluate an SQL function implemented |
** using TCL script. |
*/ |
static void tclSqlFunc( sqlite3_context context, int argc, sqlite3_value[] argv ) |
{ |
SqlFunc p = (SqlFunc)sqlite3_user_data( context ); |
Tcl_Obj pCmd = null; |
int i; |
int rc; |
|
if ( argc == 0 ) |
{ |
/* If there are no arguments to the function, call TCL.Tcl_EvalObjEx on the |
** script object directly. This allows the TCL compiler to generate |
** bytecode for the command on the first invocation and thus make |
** subsequent invocations much faster. */ |
pCmd = p.pScript; |
TCL.Tcl_IncrRefCount( pCmd ); |
rc = TCL.Tcl_EvalObjEx( p.interp, pCmd, 0 ); |
TCL.Tcl_DecrRefCount( ref pCmd ); |
} |
else |
{ |
/* If there are arguments to the function, make a shallow copy of the |
** script object, lappend the arguments, then evaluate the copy. |
** |
** By "shallow" copy, we mean a only the outer list Tcl_Obj is duplicated. |
** The new Tcl_Obj contains pointers to the original list elements. |
** That way, when TCL.Tcl_EvalObjv() is run and shimmers the first element |
** of the list to tclCmdNameType, that alternate representation will |
** be preserved and reused on the next invocation. |
*/ |
Tcl_Obj[] aArg = null; |
int nArg = 0; |
if ( TCL.Tcl_ListObjGetElements( p.interp, p.pScript, out nArg, out aArg ) ) |
{ |
sqlite3_result_error( context, TCL.Tcl_GetStringResult( p.interp ), -1 ); |
return; |
} |
pCmd = TCL.Tcl_NewListObj( nArg, aArg ); |
TCL.Tcl_IncrRefCount( pCmd ); |
for ( i = 0; i < argc; i++ ) |
{ |
sqlite3_value pIn = argv[i]; |
Tcl_Obj pVal; |
|
/* Set pVal to contain the i'th column of this row. */ |
switch ( sqlite3_value_type( pIn ) ) |
{ |
case SQLITE_BLOB: |
{ |
int bytes = sqlite3_value_bytes( pIn ); |
pVal = TCL.Tcl_NewByteArrayObj( sqlite3_value_blob( pIn ), bytes ); |
break; |
} |
case SQLITE_INTEGER: |
{ |
sqlite_int64 v = sqlite3_value_int64( pIn ); |
if ( v >= -2147483647 && v <= 2147483647 ) |
{ |
pVal = TCL.Tcl_NewIntObj( (int)v ); |
} |
else |
{ |
pVal = TCL.Tcl_NewWideIntObj( v ); |
} |
break; |
} |
case SQLITE_FLOAT: |
{ |
double r = sqlite3_value_double( pIn ); |
pVal = TCL.Tcl_NewDoubleObj( r ); |
break; |
} |
case SQLITE_NULL: |
{ |
pVal = TCL.Tcl_NewStringObj( "", 0 ); |
break; |
} |
default: |
{ |
int bytes = sqlite3_value_bytes( pIn ); |
pVal = TCL.Tcl_NewStringObj( sqlite3_value_text( pIn ), bytes ); |
break; |
} |
} |
rc = TCL.Tcl_ListObjAppendElement( p.interp, pCmd, pVal ) ? 1 : 0; |
if ( rc != 0 ) |
{ |
TCL.Tcl_DecrRefCount( ref pCmd ); |
sqlite3_result_error( context, TCL.Tcl_GetStringResult( p.interp ), -1 ); |
return; |
} |
} |
if ( p.useEvalObjv == 0 ) |
{ |
/* TCL.Tcl_EvalObjEx() will automatically call TCL.Tcl_EvalObjv() if pCmd |
** is a list without a string representation. To prevent this from |
** happening, make sure pCmd has a valid string representation */ |
TCL.Tcl_GetString( pCmd ); |
} |
rc = TCL.Tcl_EvalObjEx( p.interp, pCmd, TCL.TCL_EVAL_DIRECT ); |
TCL.Tcl_DecrRefCount( ref pCmd ); |
} |
|
if ( rc != 0 && rc != TCL.TCL_RETURN ) |
{ |
sqlite3_result_error( context, TCL.Tcl_GetStringResult( p.interp ), -1 ); |
} |
else |
{ |
Tcl_Obj pVar = TCL.Tcl_GetObjResult( p.interp ); |
int n = 0; |
string data = ""; |
Tcl_WideInt v = 0; |
double r = 0; |
string zType = pVar.typePtr;//string zType = (pVar.typePtr ? pVar.typePtr.name : ""); |
if ( zType == "bytearray" ) |
{ //&& pVar.bytes==0 ){ |
/* Only return a BLOB type if the Tcl variable is a bytearray and |
** has no string representation. */ |
data = Encoding.UTF8.GetString( TCL.Tcl_GetByteArrayFromObj( pVar, out n ) ); |
sqlite3_result_blob( context, data, n, null ); |
} |
else if ( zType == "boolean" ) |
{ |
TCL.Tcl_GetIntFromObj( null, pVar, out n ); |
sqlite3_result_int( context, n ); |
} |
else if ( zType == "wideint" || |
zType == "int" || Int64.TryParse( pVar.ToString(), out v ) ) |
{ |
TCL.Tcl_GetWideIntFromObj( null, pVar, out v ); |
sqlite3_result_int64( context, v ); |
} |
else if ( zType == "double" || Double.TryParse( pVar.ToString(), out r ) ) |
{ |
TCL.Tcl_GetDoubleFromObj( null, pVar, out r ); |
sqlite3_result_double( context, r ); |
} |
else |
{ |
data = TCL.Tcl_GetStringFromObj( pVar, n ); |
n = data.Length; |
sqlite3_result_text( context, data, n, SQLITE_TRANSIENT ); |
} |
} |
} |
|
#if !SQLITE_OMIT_AUTHORIZATION |
/* |
** This is the authentication function. It appends the authentication |
** type code and the two arguments to zCmd[] then invokes the result |
** on the interpreter. The reply is examined to determine if the |
** authentication fails or succeeds. |
*/ |
static int auth_callback( |
object pArg, |
int code, |
const string zArg1, |
const string zArg2, |
const string zArg3, |
const string zArg4 |
){ |
string zCode; |
TCL.Tcl_DString str; |
int rc; |
const string zReply; |
SqliteDb pDb = (SqliteDb)pArg; |
if( pdb.disableAuth ) return SQLITE_OK; |
|
switch( code ){ |
case SQLITE_COPY : zCode="SQLITE_COPY"; break; |
case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break; |
case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break; |
case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break; |
case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break; |
case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break; |
case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break; |
case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break; |
case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break; |
case SQLITE_DELETE : zCode="SQLITE_DELETE"; break; |
case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break; |
case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break; |
case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break; |
case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break; |
case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break; |
case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break; |
case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break; |
case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break; |
case SQLITE_INSERT : zCode="SQLITE_INSERT"; break; |
case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break; |
case SQLITE_READ : zCode="SQLITE_READ"; break; |
case SQLITE_SELECT : zCode="SQLITE_SELECT"; break; |
case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break; |
case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break; |
case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break; |
case SQLITE_DETACH : zCode="SQLITE_DETACH"; break; |
case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break; |
case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break; |
case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break; |
case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break; |
case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break; |
case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break; |
case SQLITE_SAVEPOINT : zCode="SQLITE_SAVEPOINT"; break; |
default : zCode="????"; break; |
} |
TCL.Tcl_DStringInit(&str); |
TCL.Tcl_DStringAppend(&str, pDb.zAuth, -1); |
TCL.Tcl_DStringAppendElement(&str, zCode); |
TCL.Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : ""); |
TCL.Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : ""); |
TCL.Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : ""); |
TCL.Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : ""); |
rc = TCL.Tcl_GlobalEval(pDb.interp, TCL.Tcl_DStringValue(&str)); |
TCL.Tcl_DStringFree(&str); |
zReply = TCL.Tcl_GetStringResult(pDb.interp); |
if( strcmp(zReply,"SQLITE_OK")==0 ){ |
rc = SQLITE_OK; |
}else if( strcmp(zReply,"SQLITE_DENY")==0 ){ |
rc = SQLITE_DENY; |
}else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){ |
rc = SQLITE_IGNORE; |
}else{ |
rc = 999; |
} |
return rc; |
} |
#endif // * SQLITE_OMIT_AUTHORIZATION */ |
|
/* |
** zText is a pointer to text obtained via an sqlite3_result_text() |
** or similar interface. This routine returns a Tcl string object, |
** reference count set to 0, containing the text. If a translation |
** between iso8859 and UTF-8 is required, it is preformed. |
*/ |
static Tcl_Obj dbTextToObj( string zText ) |
{ |
Tcl_Obj pVal; |
#if UTF_TRANSLATION_NEEDED |
//TCL.Tcl_DString dCol; |
//TCL.Tcl_DStringInit(&dCol); |
//TCL.Tcl_ExternalToUtfDString(NULL, zText, -1, dCol); |
//pVal = TCL.Tcl_NewStringObj(Tcl_DStringValue(&dCol), -1); |
//TCL.Tcl_DStringFree(ref dCol); |
if (zText.Length == Encoding.UTF8.GetByteCount(zText)) pVal = TCL.Tcl_NewStringObj( zText, -1 ); |
else pVal = TCL.Tcl_NewStringObj( zText, -1 ); |
#else |
pVal = TCL.Tcl_NewStringObj( zText, -1 ); |
#endif |
return pVal; |
} |
|
/* |
** This routine reads a line of text from FILE in, stores |
** the text in memory obtained from malloc() and returns a pointer |
** to the text. NULL is returned at end of file, or if malloc() |
** fails. |
** |
** The interface is like "readline" but no command-line editing |
** is done. |
** |
** copied from shell.c from '.import' command |
*/ |
//static char *local_getline(string zPrompt, FILE *in){ |
// string zLine; |
// int nLine; |
// int n; |
// int eol; |
|
// nLine = 100; |
// zLine = malloc( nLine ); |
// if( zLine==0 ) return 0; |
// n = 0; |
// eol = 0; |
// while( !eol ){ |
// if( n+100>nLine ){ |
// nLine = nLine*2 + 100; |
// zLine = realloc(zLine, nLine); |
// if( zLine==0 ) return 0; |
// } |
// if( fgets(&zLine[n], nLine - n, in)==0 ){ |
// if( n==0 ){ |
// free(zLine); |
// return 0; |
// } |
// zLine[n] = 0; |
// eol = 1; |
// break; |
// } |
// while( zLine[n] ){ n++; } |
// if( n>0 && zLine[n-1]=='\n' ){ |
// n--; |
// zLine[n] = 0; |
// eol = 1; |
// } |
// } |
// zLine = realloc( zLine, n+1 ); |
// return zLine; |
//} |
|
|
/* |
** This function is part of the implementation of the command: |
** |
** $db transaction [-deferred|-immediate|-exclusive] SCRIPT |
** |
** It is invoked after evaluating the script SCRIPT to commit or rollback |
** the transaction or savepoint opened by the [transaction] command. |
*/ |
static int DbTransPostCmd( |
object data, /* data[0] is the Sqlite3Db* for $db */ |
Tcl_Interp interp, /* Tcl interpreter */ |
int result /* Result of evaluating SCRIPT */ |
) |
{ |
string[] azEnd = { |
"RELEASE _tcl_transaction", /* rc==TCL_ERROR, nTransaction!=0 */ |
"COMMIT", /* rc!=TCL_ERROR, nTransaction==0 */ |
"ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction", |
"ROLLBACK" /* rc==TCL_ERROR, nTransaction==0 */ |
}; |
SqliteDb pDb = (SqliteDb)data; |
int rc = result; |
string zEnd; |
|
pDb.nTransaction--; |
zEnd = azEnd[( ( rc == TCL.TCL_ERROR ) ? 1 : 0 ) * 2 + ( ( pDb.nTransaction == 0 ) ? 1 : 0 )]; |
|
pDb.disableAuth++; |
if ( sqlite3_exec( pDb.db, zEnd, 0, 0, 0 ) != 0 ) |
{ |
/* This is a tricky scenario to handle. The most likely cause of an |
** error is that the exec() above was an attempt to commit the |
** top-level transaction that returned SQLITE_BUSY. Or, less likely, |
** that an IO-error has occured. In either case, throw a Tcl exception |
** and try to rollback the transaction. |
** |
** But it could also be that the user executed one or more BEGIN, |
** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing |
** this method's logic. Not clear how this would be best handled. |
*/ |
if ( rc != TCL.TCL_ERROR ) |
{ |
TCL.Tcl_AppendResult( interp, sqlite3_errmsg( pDb.db ), 0 ); |
rc = TCL.TCL_ERROR; |
} |
sqlite3_exec( pDb.db, "ROLLBACK", 0, 0, 0 ); |
} |
pDb.disableAuth--; |
|
return rc; |
} |
|
/* |
** Search the cache for a prepared-statement object that implements the |
** first SQL statement in the buffer pointed to by parameter zIn. If |
** no such prepared-statement can be found, allocate and prepare a new |
** one. In either case, bind the current values of the relevant Tcl |
** variables to any $var, :var or @var variables in the statement. Before |
** returning, set *ppPreStmt to point to the prepared-statement object. |
** |
** Output parameter *pzOut is set to point to the next SQL statement in |
** buffer zIn, or to the '\0' byte at the end of zIn if there is no |
** next statement. |
** |
** If successful, TCL_OK is returned. Otherwise, TCL_ERROR is returned |
** and an error message loaded into interpreter pDb.interp. |
*/ |
static int dbPrepareAndBind( |
SqliteDb pDb, /* Database object */ |
string zIn, /* SQL to compile */ |
ref string pzOut, /* OUT: Pointer to next SQL statement */ |
ref SqlPreparedStmt ppPreStmt /* OUT: Object used to cache statement */ |
) |
{ |
string zSql = zIn; /* Pointer to first SQL statement in zIn */ |
sqlite3_stmt pStmt = null; /* Prepared statement object */ |
SqlPreparedStmt pPreStmt; /* Pointer to cached statement */ |
int nSql; /* Length of zSql in bytes */ |
int nVar = 0; /* Number of variables in statement */ |
int iParm = 0; /* Next free entry in apParm */ |
int i; |
Tcl_Interp interp = pDb.interp; |
|
pzOut = null; |
ppPreStmt = null; |
|
/* Trim spaces from the start of zSql and calculate the remaining length. */ |
zSql = zSql.TrimStart(); //while ( isspace( zSql[0] ) ) { zSql++; } |
nSql = strlen30( zSql ); |
|
for ( pPreStmt = pDb.stmtList; pPreStmt != null; pPreStmt = pPreStmt.pNext ) |
{ |
int n = pPreStmt.nSql; |
if ( nSql >= n |
&& zSql.StartsWith(pPreStmt.zSql) |
&& ( nSql == n /* zSql[n]==0 */|| zSql[n - 1] == ';' ) |
) |
{ |
pStmt = pPreStmt.pStmt; |
/* Restore aMem values */ |
if ( pStmt.aMem.Length < pPreStmt.aMem.Length ) |
Array.Resize( ref pStmt.aMem, pPreStmt.aMem.Length ); |
for ( int ix = 0; ix < pPreStmt.aMem.Length; ix++ ) |
{ |
pPreStmt.aMem[ix].CopyTo( ref pStmt.aMem[ix] ); |
} |
|
pzOut = zSql.Substring( pPreStmt.nSql ); |
|
/* When a prepared statement is found, unlink it from the |
** cache list. It will later be added back to the beginning |
** of the cache list in order to implement LRU replacement. |
*/ |
if ( pPreStmt.pPrev != null ) |
{ |
pPreStmt.pPrev.pNext = pPreStmt.pNext; |
} |
else |
{ |
pDb.stmtList = pPreStmt.pNext; |
} |
if ( pPreStmt.pNext != null ) |
{ |
pPreStmt.pNext.pPrev = pPreStmt.pPrev; |
} |
else |
{ |
pDb.stmtLast = pPreStmt.pPrev; |
} |
pDb.nStmt--; |
nVar = sqlite3_bind_parameter_count( pStmt ); |
break; |
} |
} |
|
/* If no prepared statement was found. Compile the SQL text. Also allocate |
** a new SqlPreparedStmt structure. */ |
if ( pPreStmt == null ) |
{ |
int nByte; |
|
if ( SQLITE_OK != sqlite3_prepare_v2( pDb.db, zSql, -1, ref pStmt, ref pzOut ) ) |
{ |
TCL.Tcl_SetObjResult( interp, dbTextToObj( sqlite3_errmsg( pDb.db ) ) ); |
pPreStmt = new SqlPreparedStmt();// (SqlPreparedStmt)Tcl_Alloc( nByte ); |
return TCL.TCL_ERROR; |
} |
if ( pStmt == null ) |
{ |
if ( SQLITE_OK != sqlite3_errcode( pDb.db ) ) |
{ |
/* A compile-time error in the statement. */ |
TCL.Tcl_SetObjResult( interp, dbTextToObj( sqlite3_errmsg( pDb.db ) ) ); |
return TCL.TCL_ERROR; |
} |
else |
{ |
/* The statement was a no-op. Continue to the next statement |
** in the SQL string. |
*/ |
return TCL.TCL_OK; |
} |
} |
|
Debug.Assert( pPreStmt == null ); |
nVar = sqlite3_bind_parameter_count( pStmt ); |
//nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Tcl_Obj ); |
pPreStmt = new SqlPreparedStmt();// (SqlPreparedStmt)Tcl_Alloc( nByte ); |
//memset(pPreStmt, 0, nByte); |
|
pPreStmt.pStmt = pStmt; |
pPreStmt.nSql = ( zSql.Length - pzOut.Length ); |
pPreStmt.zSql = sqlite3_sql( pStmt ); |
pPreStmt.apParm = new TclObject[nVar];//pPreStmt[1]; |
} |
Debug.Assert( pPreStmt != null ); |
Debug.Assert( strlen30( pPreStmt.zSql ) == pPreStmt.nSql ); |
Debug.Assert( zSql.StartsWith( pPreStmt.zSql ) ); |
|
/* Bind values to parameters that begin with $ or : */ |
for ( i = 1; i <= nVar; i++ ) |
{ |
string zVar = sqlite3_bind_parameter_name( pStmt, i ); |
if ( !String.IsNullOrEmpty( zVar ) && ( zVar[0] == '$' || zVar[0] == ':' || zVar[0] == '@' ) ) |
{ |
Tcl_Obj pVar = TCL.Tcl_GetVar2Ex( interp, zVar.Substring( 1 ), null, 0 ); |
if ( pVar != null && pVar.typePtr != "null" ) |
{ |
int n = 0; |
string data; |
string zType = pVar.typePtr; |
//char c = zType[0]; |
if ( zVar[0] == '@' || |
( zType == "bytearray" ) )// TODO -- && pVar.bytes == 0 ) ) |
{ |
/* Load a BLOB type if the Tcl variable is a bytearray and |
** it has no string representation or the host |
** parameter name begins with "@". */ |
if ( zVar[0] == '@' || pVar.stringRep == null ) |
sqlite3_bind_blob( pStmt, i, TCL.Tcl_GetByteArrayFromObj( pVar, out n ), n, SQLITE_STATIC ); |
else |
sqlite3_bind_text( pStmt, i, TCL.Tcl_GetStringFromObj( pVar, out n ), n, SQLITE_STATIC ); |
TCL.Tcl_IncrRefCount( pVar ); |
pPreStmt.apParm[iParm++] = pVar; |
} |
else if ( zType == "boolean" ) |
{ |
TCL.Tcl_GetIntFromObj( interp, pVar, out n ); |
sqlite3_bind_int( pStmt, i, n ); |
} |
else if ( zType == "double" ) |
{ |
double r = 0; |
TCL.Tcl_GetDoubleFromObj( interp, pVar, out r ); |
sqlite3_bind_double( pStmt, i, r ); |
} |
else if ( zType == "wideint" || |
zType == "int" ) |
{ |
Tcl_WideInt v = 0; |
TCL.Tcl_GetWideIntFromObj( interp, pVar, out v ); |
sqlite3_bind_int64( pStmt, i, v ); |
} |
else |
{ |
data = TCL.Tcl_GetStringFromObj( pVar, out n ); |
sqlite3_bind_text( pStmt, i, data, n, SQLITE_STATIC ); |
TCL.Tcl_IncrRefCount( pVar ); |
pPreStmt.apParm[iParm++] = pVar; |
} |
} |
else |
{ |
sqlite3_bind_null( pStmt, i ); |
} |
} |
} |
pPreStmt.nParm = iParm; |
/* save aMem values for later reuse */ |
pPreStmt.aMem = new Mem[pPreStmt.pStmt.aMem.Length]; |
for ( int ix = 0; ix < pPreStmt.pStmt.aMem.Length; ix++ ) |
{ |
pPreStmt.pStmt.aMem[ix].CopyTo( ref pPreStmt.aMem[ix] ); |
} |
ppPreStmt = pPreStmt; |
|
return TCL.TCL_OK; |
} |
|
|
/* |
** Release a statement reference obtained by calling dbPrepareAndBind(). |
** There should be exactly one call to this function for each call to |
** dbPrepareAndBind(). |
** |
** If the discard parameter is non-zero, then the statement is deleted |
** immediately. Otherwise it is added to the LRU list and may be returned |
** by a subsequent call to dbPrepareAndBind(). |
*/ |
static void dbReleaseStmt( |
SqliteDb pDb, /* Database handle */ |
SqlPreparedStmt pPreStmt, /* Prepared statement handle to release */ |
int discard /* True to delete (not cache) the pPreStmt */ |
) |
{ |
int i; |
|
/* Free the bound string and blob parameters */ |
for ( i = 0; i < pPreStmt.nParm; i++ ) |
{ |
TCL.Tcl_DecrRefCount( ref pPreStmt.apParm[i] ); |
} |
pPreStmt.nParm = 0; |
|
if ( pDb.maxStmt <= 0 || discard != 0 ) |
{ |
/* If the cache is turned off, deallocated the statement */ |
sqlite3_finalize( pPreStmt.pStmt ); |
TCL.Tcl_Free( ref pPreStmt ); |
} |
else |
{ |
/* Add the prepared statement to the beginning of the cache list. */ |
pPreStmt.pNext = pDb.stmtList; |
pPreStmt.pPrev = null; |
if ( pDb.stmtList != null ) |
{ |
pDb.stmtList.pPrev = pPreStmt; |
} |
pDb.stmtList = pPreStmt; |
if ( pDb.stmtLast == null ) |
{ |
Debug.Assert( pDb.nStmt == 0 ); |
pDb.stmtLast = pPreStmt; |
} |
else |
{ |
Debug.Assert( pDb.nStmt > 0 ); |
} |
pDb.nStmt++; |
|
/* If we have too many statement in cache, remove the surplus from |
** the end of the cache list. */ |
while ( pDb.nStmt > pDb.maxStmt ) |
{ |
sqlite3_finalize( pDb.stmtLast.pStmt ); |
pDb.stmtLast = pDb.stmtLast.pPrev; |
TCL.Tcl_Free( ref pDb.stmtLast.pNext ); |
pDb.stmtLast.pNext = null; |
pDb.nStmt--; |
} |
} |
} |
|
/* |
** Structure used with dbEvalXXX() functions: |
** |
** dbEvalInit() |
** dbEvalStep() |
** dbEvalFinalize() |
** dbEvalRowInfo() |
** dbEvalColumnValue() |
*/ |
//typedef struct DbEvalContext DbEvalContext; |
public class DbEvalContext |
{ |
public SqliteDb pDb; /* Database handle */ |
public Tcl_Obj pSql; /* Object holding string zSql */ |
public string zSql; /* Remaining SQL to execute */ |
public SqlPreparedStmt pPreStmt; /* Current statement */ |
public int nCol; /* Number of columns returned by pStmt */ |
public Tcl_Obj pArray; /* Name of array variable */ |
public Tcl_Obj[] apColName; /* Array of column names */ |
|
public void Clear() |
{ |
pDb = null; |
pSql = null; |
zSql = null; |
pPreStmt = null; |
pArray = null; |
apColName = null; |
|
} |
}; |
|
/* |
** Release any cache of column names currently held as part of |
** the DbEvalContext structure passed as the first argument. |
*/ |
static void dbReleaseColumnNames( DbEvalContext p ) |
{ |
if ( p.apColName != null ) |
{ |
int i; |
for ( i = 0; i < p.nCol; i++ ) |
{ |
TCL.Tcl_DecrRefCount( ref p.apColName[i] ); |
} |
TCL.Tcl_Free( ref p.apColName ); |
p.apColName = null; |
} |
p.nCol = 0; |
} |
|
/* |
** Initialize a DbEvalContext structure. |
** |
** If pArray is not NULL, then it contains the name of a Tcl array |
** variable. The "*" member of this array is set to a list containing |
** the names of the columns returned by the statement as part of each |
** call to dbEvalStep(), in order from left to right. e.g. if the names |
** of the returned columns are a, b and c, it does the equivalent of the |
** tcl command: |
** |
** set ${pArray}() {a b c} |
*/ |
static void dbEvalInit( |
DbEvalContext p, /* Pointer to structure to initialize */ |
SqliteDb pDb, /* Database handle */ |
Tcl_Obj pSql, /* Object containing SQL script */ |
Tcl_Obj pArray /* Name of Tcl array to set () element of */ |
) |
{ |
if ( p != null ) |
p.Clear();// memset( p, 0, sizeof( DbEvalContext ) ); |
p.pDb = pDb; |
p.zSql = TCL.Tcl_GetString( pSql ); |
p.pSql = pSql; |
TCL.Tcl_IncrRefCount( pSql ); |
if ( pArray != null ) |
{ |
p.pArray = pArray; |
TCL.Tcl_IncrRefCount( pArray ); |
} |
} |
|
/* |
** Obtain information about the row that the DbEvalContext passed as the |
** first argument currently points to. |
*/ |
static void dbEvalRowInfo( |
DbEvalContext p, /* Evaluation context */ |
out int pnCol, /* OUT: Number of column names */ |
out Tcl_Obj[] papColName /* OUT: Array of column names */ |
) |
{ |
/* Compute column names */ |
if ( null == p.apColName ) |
{ |
sqlite3_stmt pStmt = p.pPreStmt.pStmt; |
int i; /* Iterator variable */ |
int nCol; /* Number of columns returned by pStmt */ |
Tcl_Obj[] apColName = null; /* Array of column names */ |
|
p.nCol = nCol = sqlite3_column_count( pStmt ); |
if ( nCol > 0 )// && ( papColName != null || p.pArray != null ) ) |
{ |
apColName = new TclObject[nCol];// (Tcl_Obj*)Tcl_Alloc( sizeof( Tcl_Obj* ) * nCol ); |
for ( i = 0; i < nCol; i++ ) |
{ |
apColName[i] = dbTextToObj( sqlite3_column_name( pStmt, i ) ); |
TCL.Tcl_IncrRefCount( apColName[i] ); |
} |
p.apColName = apColName; |
} |
|
/* If results are being stored in an array variable, then create |
** the array() entry for that array |
*/ |
if ( p.pArray != null ) |
{ |
Tcl_Interp interp = p.pDb.interp; |
Tcl_Obj pColList = TCL.Tcl_NewObj(); |
Tcl_Obj pStar = TCL.Tcl_NewStringObj( "*", -1 ); |
|
for ( i = 0; i < nCol; i++ ) |
{ |
TCL.Tcl_ListObjAppendElement( interp, pColList, apColName[i] ); |
} |
TCL.Tcl_IncrRefCount( pStar ); |
TCL.Tcl_ObjSetVar2( interp, p.pArray, pStar, pColList, 0 ); |
TCL.Tcl_DecrRefCount( ref pStar ); |
} |
} |
|
//if ( papColName != null ) |
{ |
papColName = p.apColName; |
} |
//if ( pnCol !=0) |
{ |
pnCol = p.nCol; |
} |
} |
|
/* |
** Return one of TCL_OK, TCL_BREAK or TCL_ERROR. If TCL_ERROR is |
** returned, then an error message is stored in the interpreter before |
** returning. |
** |
** A return value of TCL_OK means there is a row of data available. The |
** data may be accessed using dbEvalRowInfo() and dbEvalColumnValue(). This |
** is analogous to a return of SQLITE_ROW from sqlite3_step(). If TCL_BREAK |
** is returned, then the SQL script has finished executing and there are |
** no further rows available. This is similar to SQLITE_DONE. |
*/ |
static int dbEvalStep( DbEvalContext p ) |
{ |
while ( !String.IsNullOrEmpty( p.zSql ) || p.pPreStmt != null ) |
{ |
int rc; |
if ( p.pPreStmt == null ) |
{ |
rc = dbPrepareAndBind( p.pDb, p.zSql, ref p.zSql, ref p.pPreStmt ); |
if ( rc != TCL.TCL_OK ) |
return rc; |
} |
else |
{ |
int rcs; |
SqliteDb pDb = p.pDb; |
SqlPreparedStmt pPreStmt = p.pPreStmt; |
sqlite3_stmt pStmt = pPreStmt.pStmt; |
|
rcs = sqlite3_step( pStmt ); |
if ( rcs == SQLITE_ROW ) |
{ |
return TCL.TCL_OK; |
} |
if ( p.pArray != null ) |
{ |
TclObject[] pDummy; |
int iDummy; |
dbEvalRowInfo( p, out iDummy, out pDummy ); |
} |
rcs = sqlite3_reset( pStmt ); |
|
pDb.nStep = sqlite3_stmt_status( pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, 1 ); |
pDb.nSort = sqlite3_stmt_status( pStmt, SQLITE_STMTSTATUS_SORT, 1 ); |
pDb.nIndex = sqlite3_stmt_status( pStmt, SQLITE_STMTSTATUS_AUTOINDEX, 1 ); |
dbReleaseColumnNames( p ); |
p.pPreStmt = null; |
|
if ( rcs != SQLITE_OK ) |
{ |
/* If a run-time error occurs, report the error and stop reading |
** the SQL. */ |
TCL.Tcl_SetObjResult( pDb.interp, dbTextToObj( sqlite3_errmsg( pDb.db ) ) ); |
dbReleaseStmt( pDb, pPreStmt, 1 ); |
return TCL.TCL_ERROR; |
} |
else |
{ |
dbReleaseStmt( pDb, pPreStmt, 0 ); |
} |
} |
} |
|
/* Finished */ |
return TCL.TCL_BREAK; |
} |
|
/* |
** Free all resources currently held by the DbEvalContext structure passed |
** as the first argument. There should be exactly one call to this function |
** for each call to dbEvalInit(). |
*/ |
static void dbEvalFinalize( DbEvalContext p ) |
{ |
if ( p.pPreStmt != null ) |
{ |
sqlite3_reset( p.pPreStmt.pStmt ); |
dbReleaseStmt( p.pDb, p.pPreStmt, 1 ); |
p.pPreStmt = null; |
} |
if ( p.pArray != null ) |
{ |
TCL.Tcl_DecrRefCount( ref p.pArray ); |
p.pArray = null; |
} |
TCL.Tcl_DecrRefCount( ref p.pSql ); |
dbReleaseColumnNames( p ); |
} |
|
/* |
** Return a pointer to a Tcl_Obj structure with ref-count 0 that contains |
** the value for the iCol'th column of the row currently pointed to by |
** the DbEvalContext structure passed as the first argument. |
*/ |
static Tcl_Obj dbEvalColumnValue( DbEvalContext p, int iCol ) |
{ |
sqlite3_stmt pStmt = p.pPreStmt.pStmt; |
switch ( sqlite3_column_type( pStmt, iCol ) ) |
{ |
case SQLITE_BLOB: |
{ |
int bytes = sqlite3_column_bytes( pStmt, iCol ); |
byte[] zBlob = sqlite3_column_blob( pStmt, iCol ); |
if ( null == zBlob ) |
bytes = 0; |
return TCL.Tcl_NewByteArrayObj( zBlob, bytes ); |
} |
case SQLITE_INTEGER: |
{ |
sqlite_int64 v = sqlite3_column_int64( pStmt, iCol ); |
if ( v >= -2147483647 && v <= 2147483647 ) |
{ |
return TCL.Tcl_NewIntObj( (int)v ); |
} |
else |
{ |
return TCL.Tcl_NewWideIntObj( v ); |
} |
} |
case SQLITE_FLOAT: |
{ |
return TCL.Tcl_NewDoubleObj( sqlite3_column_double( pStmt, iCol ) ); |
} |
case SQLITE_NULL: |
{ |
return dbTextToObj( p.pDb.zNull ); |
} |
} |
|
return dbTextToObj( sqlite3_column_text( pStmt, iCol ) ); |
} |
|
/* |
** If using Tcl version 8.6 or greater, use the NR functions to avoid |
** recursive evalution of scripts by the [db eval] and [db trans] |
** commands. Even if the headers used while compiling the extension |
** are 8.6 or newer, the code still tests the Tcl version at runtime. |
** This allows stubs-enabled builds to be used with older Tcl libraries. |
*/ |
#if TCL_MAJOR_VERSION//>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6) |
//# define SQLITE_TCL_NRE 1 |
static int DbUseNre(void){ |
int major, minor; |
Tcl_GetVersion(&major, &minor, 0, 0); |
return( (major==8 && minor>=6) || major>8 ); |
} |
#else |
/* |
** Compiling using headers earlier than 8.6. In this case NR cannot be |
** used, so DbUseNre() to always return zero. Add #defines for the other |
** Tcl_NRxxx() functions to prevent them from causing compilation errors, |
** even though the only invocations of them are within conditional blocks |
** of the form: |
** |
** if( DbUseNre() ) { ... } |
*/ |
const int SQLITE_TCL_NRE = 0; //# define SQLITE_TCL_NRE 0 |
static bool DbUseNre() |
{ |
return false; |
} //# define DbUseNre() 0 |
//# define Tcl_NRAddCallback(a,b,c,d,e,f) 0 |
//# define Tcl_NREvalObj(a,b,c) 0 |
//# define Tcl_NRCreateCommand(a,b,c,d,e,f) 0 |
#endif |
|
/* |
** This function is part of the implementation of the command: |
** |
** $db eval SQL ?ARRAYNAME? SCRIPT |
*/ |
static int DbEvalNextCmd( |
object[] data, /* data[0] is the (DbEvalContext) */ |
Tcl_Interp interp, /* Tcl interpreter */ |
int result /* Result so far */ |
) |
{ |
int rc = result; /* Return code */ |
|
/* The first element of the data[] array is a pointer to a DbEvalContext |
** structure allocated using TCL.Tcl_Alloc(). The second element of data[] |
** is a pointer to a TCL.Tcl_Obj containing the script to run for each row |
** returned by the queries encapsulated in data[0]. */ |
DbEvalContext p = (DbEvalContext)data[0]; |
Tcl_Obj pScript = (Tcl_Obj)data[1]; |
Tcl_Obj pArray = p.pArray; |
|
while ( ( rc == TCL.TCL_OK || rc == TCL.TCL_CONTINUE ) && TCL.TCL_OK == ( rc = dbEvalStep( p ) ) ) |
{ |
int i; |
int nCol; |
Tcl_Obj[] apColName; |
dbEvalRowInfo( p, out nCol, out apColName ); |
for ( i = 0; i < nCol; i++ ) |
{ |
Tcl_Obj pVal = dbEvalColumnValue( p, i ); |
if ( pArray == null ) |
{ |
TCL.Tcl_ObjSetVar2( interp, apColName[i], null, pVal, 0 ); |
} |
else |
{ |
TCL.Tcl_ObjSetVar2( interp, pArray, apColName[i], pVal, 0 ); |
} |
} |
|
/* The required interpreter variables are now populated with the data |
** from the current row. If using NRE, schedule callbacks to evaluate |
** script pScript, then to invoke this function again to fetch the next |
** row (or clean up if there is no next row or the script throws an |
** exception). After scheduling the callbacks, return control to the |
** caller. |
** |
** If not using NRE, evaluate pScript directly and continue with the |
** next iteration of this while(...) loop. */ |
if ( DbUseNre() ) |
{ |
Debugger.Break(); |
//TCL.Tcl_NRAddCallback(interp, DbEvalNextCmd, (void)p, (void)pScript, 0, 0); |
//return TCL.Tcl_NREvalObj(interp, pScript, 0); |
} |
else |
{ |
rc = TCL.Tcl_EvalObjEx( interp, pScript, 0 ); |
} |
} |
|
TCL.Tcl_DecrRefCount( ref pScript ); |
dbEvalFinalize( p ); |
TCL.Tcl_Free( ref p ); |
|
if ( rc == TCL.TCL_OK || rc == TCL.TCL_BREAK ) |
{ |
TCL.Tcl_ResetResult( interp ); |
rc = TCL.TCL_OK; |
} |
return rc; |
} |
|
/* |
** The "sqlite" command below creates a new Tcl command for each |
** connection it opens to an SQLite database. This routine is invoked |
** whenever one of those connection-specific commands is executed |
** in Tcl. For example, if you run Tcl code like this: |
** |
** sqlite3 db1 "my_database" |
** db1 close |
** |
** The first command opens a connection to the "my_database" database |
** and calls that connection "db1". The second command causes this |
** subroutine to be invoked. |
*/ |
enum DB_enum |
{ |
DB_AUTHORIZER, |
DB_BACKUP, |
DB_BUSY, |
DB_CACHE, |
DB_CHANGES, |
DB_CLOSE, |
DB_COLLATE, |
DB_COLLATION_NEEDED, |
DB_COMMIT_HOOK, |
DB_COMPLETE, |
DB_COPY, |
DB_ENABLE_LOAD_EXTENSION, |
DB_ERRORCODE, |
DB_EVAL, |
DB_EXISTS, |
DB_FUNCTION, |
DB_INCRBLOB, |
DB_INTERRUPT, |
DB_LAST_INSERT_ROWID, |
DB_NULLVALUE, |
DB_ONECOLUMN, |
DB_PROFILE, |
DB_PROGRESS, |
DB_REKEY, |
DB_RESTORE, |
DB_ROLLBACK_HOOK, |
DB_STATUS, |
DB_TIMEOUT, |
DB_TOTAL_CHANGES, |
DB_TRACE, |
DB_TRANSACTION, |
DB_UNLOCK_NOTIFY, |
DB_UPDATE_HOOK, |
DB_VERSION, |
DB_WAL_HOOK |
}; |
|
enum TTYPE_enum |
{ |
TTYPE_DEFERRED, |
TTYPE_EXCLUSIVE, |
TTYPE_IMMEDIATE |
}; |
|
static int DbObjCmd( object cd, Tcl_Interp interp, int objc, Tcl_Obj[] objv ) |
{ |
SqliteDb pDb = (SqliteDb)cd; |
int choice = 0; |
int rc = TCL.TCL_OK; |
string[] DB_strs = { |
"authorizer", "backup", "busy", |
"cache", "changes", "close", |
"collate", "collation_needed", "commit_hook", |
"complete", "copy", "enable_load_extension", |
"errorcode", "eval", "exists", |
"function", "incrblob", "interrupt", |
"last_insert_rowid", "nullvalue", "onecolumn", |
"profile", "progress", "rekey", |
"restore", "rollback_hook", "status", |
"timeout", "total_changes", "trace", |
"transaction", "unlock_notify", "update_hook", |
"version", "wal_hook" |
}; |
|
/* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ |
if ( objc < 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "SUBCOMMAND ..." ); |
return TCL.TCL_ERROR; |
} |
if ( TCL.Tcl_GetIndexFromObj( interp, objv[1], DB_strs, "option", 0, out choice ) ) |
{ |
return TCL.TCL_ERROR; |
} |
|
switch ( choice ) |
{ |
|
/* $db authorizer ?CALLBACK? |
** |
** Invoke the given callback to authorize each SQL operation as it is |
** compiled. 5 arguments are appended to the callback before it is |
** invoked: |
** |
** (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...) |
** (2) First descriptive name (depends on authorization type) |
** (3) Second descriptive name |
** (4) Name of the database (ex: "main", "temp") |
** (5) Name of trigger that is doing the access |
** |
** The callback should return on of the following strings: SQLITE_OK, |
** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error. |
** |
** If this method is invoked with no arguments, the current authorization |
** callback string is returned. |
*/ |
case (int)DB_enum.DB_AUTHORIZER: |
{ |
#if SQLITE_OMIT_AUTHORIZATION |
TCL.Tcl_AppendResult( interp, "authorization not available in this build" ); |
return TCL.TCL_RETURN; |
#else |
if( objc>3 ){ |
TCL.Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); |
return TCL.TCL_ERROR; |
}else if( objc==2 ){ |
if( pDb.zAuth ){ |
TCL.Tcl_AppendResult(interp, pDb.zAuth); |
} |
}else{ |
string zAuth; |
int len; |
if( pDb.zAuth ){ |
TCL.Tcl_Free(pDb.zAuth); |
} |
zAuth = TCL.Tcl_GetStringFromObj(objv[2], len); |
if( zAuth && len>0 ){ |
pDb.zAuth = TCL.Tcl_Alloc( len + 1 ); |
memcpy(pDb.zAuth, zAuth, len+1); |
}else{ |
pDb.zAuth = 0; |
} |
if( pDb.zAuth ){ |
pDb.interp = interp; |
sqlite3_set_authorizer(pDb.db, auth_callback, pDb); |
}else{ |
sqlite3_set_authorizer(pDb.db, 0, 0); |
} |
} |
break; |
#endif |
} |
|
/* $db backup ?DATABASE? FILENAME |
** |
** Open or create a database file named FILENAME. Transfer the |
** content of local database DATABASE (default: "main") into the |
** FILENAME database. |
*/ |
case (int)DB_enum.DB_BACKUP: |
{ |
string zDestFile; |
string zSrcDb; |
sqlite3 pDest = null; |
sqlite3_backup pBackup; |
|
if ( objc == 3 ) |
{ |
zSrcDb = "main"; |
zDestFile = TCL.Tcl_GetString( objv[2] ); |
} |
else if ( objc == 4 ) |
{ |
zSrcDb = TCL.Tcl_GetString( objv[2] ); |
zDestFile = TCL.Tcl_GetString( objv[3] ); |
} |
else |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "?DATABASE? FILENAME" ); |
return TCL.TCL_ERROR; |
} |
rc = sqlite3_open( zDestFile, out pDest ); |
if ( rc != SQLITE_OK ) |
{ |
TCL.Tcl_AppendResult( interp, "cannot open target database: ", |
sqlite3_errmsg( pDest ) ); |
sqlite3_close( pDest ); |
return TCL.TCL_ERROR; |
} |
pBackup = sqlite3_backup_init( pDest, "main", pDb.db, zSrcDb ); |
if ( pBackup == null ) |
{ |
TCL.Tcl_AppendResult( interp, "backup failed: ", |
sqlite3_errmsg( pDest ) ); |
sqlite3_close( pDest ); |
return TCL.TCL_ERROR; |
} |
#if SQLITE_HAS_CODEC |
if ( pBackup.pSrc.pBt.pPager.pCodec != null ) |
{ |
pBackup.pDest.pBt.pPager.xCodec = pBackup.pSrc.pBt.pPager.xCodec; |
pBackup.pDest.pBt.pPager.xCodecFree = pBackup.pSrc.pBt.pPager.xCodecFree; |
pBackup.pDest.pBt.pPager.xCodecSizeChng = pBackup.pSrc.pBt.pPager.xCodecSizeChng; |
pBackup.pDest.pBt.pPager.pCodec = pBackup.pSrc.pBt.pPager.pCodec.Copy(); |
} |
#endif |
while ( ( rc = sqlite3_backup_step( pBackup, 100 ) ) == SQLITE_OK ) |
{ |
} |
sqlite3_backup_finish( pBackup ); |
if ( rc == SQLITE_DONE ) |
{ |
rc = TCL.TCL_OK; |
} |
else |
{ |
TCL.Tcl_AppendResult( interp, "backup failed: ", |
sqlite3_errmsg( pDest ) ); |
rc = TCL.TCL_ERROR; |
} |
sqlite3_close( pDest ); |
break; |
} |
|
// /* $db busy ?CALLBACK? |
// ** |
// ** Invoke the given callback if an SQL statement attempts to open |
// ** a locked database file. |
// */ |
case (int)DB_enum.DB_BUSY: |
{ |
if ( objc > 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "CALLBACK" ); |
return TCL.TCL_ERROR; |
} |
else if ( objc == 2 ) |
{ |
if ( pDb.zBusy != null ) |
{ |
TCL.Tcl_AppendResult( interp, pDb.zBusy ); |
} |
} |
else |
{ |
string zBusy; |
int len = 0; |
if ( pDb.zBusy != null ) |
{ |
TCL.Tcl_Free( ref pDb.zBusy ); |
} |
zBusy = TCL.Tcl_GetStringFromObj( objv[2], out len ); |
if ( zBusy != null && len > 0 ) |
{ |
//pDb.zBusy = TCL.Tcl_Alloc( len + 1 ); |
pDb.zBusy = zBusy;// memcpy( pDb.zBusy, zBusy, len + 1 ); |
} |
else |
{ |
pDb.zBusy = null; |
} |
if ( pDb.zBusy != null ) |
{ |
pDb.interp = interp; |
sqlite3_busy_handler( pDb.db, (dxBusy)DbBusyHandler, pDb ); |
} |
else |
{ |
sqlite3_busy_handler( pDb.db, null, null ); |
} |
} |
break; |
} |
|
// /* $db cache flush |
// ** $db cache size n |
// ** |
// ** Flush the prepared statement cache, or set the maximum number of |
// ** cached statements. |
// */ |
case (int)DB_enum.DB_CACHE: |
{ |
string subCmd; |
int n = 0; |
|
if ( objc <= 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "cache option ?arg?" ); |
return TCL.TCL_ERROR; |
} |
subCmd = TCL.Tcl_GetStringFromObj( objv[2], 0 ); |
if ( subCmd == "flush" ) |
{ |
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "flush" ); |
return TCL.TCL_ERROR; |
} |
else |
{ |
flushStmtCache( pDb ); |
} |
} |
else if ( subCmd == "size" ) |
{ |
if ( objc != 4 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "size n" ); |
return TCL.TCL_ERROR; |
} |
else |
{ |
if ( TCL.TCL_ERROR == ( TCL.Tcl_GetIntFromObj( interp, objv[3], out n ) != TCL.TCL_OK ? TCL.TCL_ERROR : TCL.TCL_OK ) ) |
{ |
TCL.Tcl_AppendResult( interp, "cannot convert \"", |
TCL.Tcl_GetStringFromObj( objv[3], 0 ), "\" to integer", 0 ); |
return TCL.TCL_ERROR; |
} |
else |
{ |
if ( n < 0 ) |
{ |
flushStmtCache( pDb ); |
n = 0; |
} |
else if ( n > MAX_PREPARED_STMTS ) |
{ |
n = MAX_PREPARED_STMTS; |
} |
pDb.maxStmt = n; |
} |
} |
} |
else |
{ |
TCL.Tcl_AppendResult( interp, "bad option \"", |
TCL.Tcl_GetStringFromObj( objv[2], 0 ), "\": must be flush or size", null ); |
return TCL.TCL_ERROR; |
} |
break; |
} |
|
/* $db changes |
** |
** Return the number of rows that were modified, inserted, or deleted by |
** the most recent INSERT, UPDATE or DELETE statement, not including |
** any changes made by trigger programs. |
*/ |
case (int)DB_enum.DB_CHANGES: |
{ |
Tcl_Obj pResult; |
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "" ); |
return TCL.TCL_ERROR; |
} |
pResult = TCL.Tcl_GetObjResult( interp ); |
TCL.Tcl_SetResult( interp, sqlite3_changes( pDb.db ).ToString(), 0 ); |
break; |
} |
|
/* $db close |
** |
** Shutdown the database |
*/ |
case (int)DB_enum.DB_CLOSE: |
{ |
TCL.Tcl_DeleteCommand( interp, TCL.Tcl_GetStringFromObj( objv[0], 0 ) ); |
break; |
} |
|
/* |
** $db collate NAME SCRIPT |
** |
** Create a new SQL collation function called NAME. Whenever |
** that function is called, invoke SCRIPT to evaluate the function. |
*/ |
case (int)DB_enum.DB_COLLATE: |
{ |
SqlCollate pCollate; |
string zName; |
string zScript; |
int nScript = 0; |
if ( objc != 4 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "NAME SCRIPT" ); |
return TCL.TCL_ERROR; |
} |
zName = TCL.Tcl_GetStringFromObj( objv[2], 0 ); |
zScript = TCL.Tcl_GetStringFromObj( objv[3], nScript ); |
pCollate = new SqlCollate();//(SqlCollate)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 ); |
//if ( pCollate == null ) return TCL.TCL_ERROR; |
pCollate.interp = interp; |
pCollate.pNext = pDb.pCollate; |
pCollate.zScript = zScript; // pCollate[1]; |
pDb.pCollate = pCollate; |
//memcpy( pCollate.zScript, zScript, nScript + 1 ); |
if ( sqlite3_create_collation( pDb.db, zName, SQLITE_UTF8, |
pCollate, (dxCompare)tclSqlCollate ) != 0 ) |
{ |
TCL.Tcl_SetResult( interp, sqlite3_errmsg( pDb.db ), TCL.TCL_VOLATILE ); |
return TCL.TCL_ERROR; |
} |
break; |
} |
|
/* |
** $db collation_needed SCRIPT |
** |
** Create a new SQL collation function called NAME. Whenever |
** that function is called, invoke SCRIPT to evaluate the function. |
*/ |
case (int)DB_enum.DB_COLLATION_NEEDED: |
{ |
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "SCRIPT" ); |
return TCL.TCL_ERROR; |
} |
if ( pDb.pCollateNeeded != null ) |
{ |
TCL.Tcl_DecrRefCount( ref pDb.pCollateNeeded ); |
} |
pDb.pCollateNeeded = TCL.Tcl_DuplicateObj( objv[2] ); |
TCL.Tcl_IncrRefCount( pDb.pCollateNeeded ); |
sqlite3_collation_needed( pDb.db, (object)pDb, (dxCollNeeded)tclCollateNeeded ); |
break; |
} |
|
/* $db commit_hook ?CALLBACK? |
** |
** Invoke the given callback just before committing every SQL transaction. |
** If the callback throws an exception or returns non-zero, then the |
** transaction is aborted. If CALLBACK is an empty string, the callback |
** is disabled. |
*/ |
case (int)DB_enum.DB_COMMIT_HOOK: |
{ |
if ( objc > 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "?CALLBACK?" ); |
return TCL.TCL_ERROR; |
} |
else if ( objc == 2 ) |
{ |
if ( pDb.zCommit != null ) |
{ |
TCL.Tcl_AppendResult( interp, pDb.zCommit ); |
} |
} |
else |
{ |
string zCommit; |
int len = 0; |
if ( pDb.zCommit != null ) |
{ |
TCL.Tcl_Free( ref pDb.zCommit ); |
} |
zCommit = TCL.Tcl_GetStringFromObj( objv[2], out len ); |
if ( zCommit != null && len > 0 ) |
{ |
pDb.zCommit = zCommit;// TCL.Tcl_Alloc( len + 1 ); |
//memcpy( pDb.zCommit, zCommit, len + 1 ); |
} |
else |
{ |
pDb.zCommit = null; |
} |
if ( pDb.zCommit != null ) |
{ |
pDb.interp = interp; |
sqlite3_commit_hook( pDb.db, DbCommitHandler, pDb ); |
} |
else |
{ |
sqlite3_commit_hook( pDb.db, null, null ); |
} |
} |
break; |
} |
|
/* $db complete SQL |
** |
** Return TRUE if SQL is a complete SQL statement. Return FALSE if |
** additional lines of input are needed. This is similar to the |
** built-in "info complete" command of Tcl. |
*/ |
case (int)DB_enum.DB_COMPLETE: |
{ |
#if !SQLITE_OMIT_COMPLETE |
Tcl_Obj pResult; |
int isComplete; |
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "SQL" ); |
return TCL.TCL_ERROR; |
} |
isComplete = sqlite3_complete( TCL.Tcl_GetStringFromObj( objv[2], 0 ) ); |
pResult = TCL.Tcl_GetObjResult( interp ); |
TCL.Tcl_SetBooleanObj( pResult, isComplete ); |
#endif |
break; |
} |
|
/* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR? |
** |
** Copy data into table from filename, optionally using SEPARATOR |
** as column separators. If a column contains a null string, or the |
** value of NULLINDICATOR, a NULL is inserted for the column. |
** conflict-algorithm is one of the sqlite conflict algorithms: |
** rollback, abort, fail, ignore, replace |
** On success, return the number of lines processed, not necessarily same |
** as 'db changes' due to conflict-algorithm selected. |
** |
** This code is basically an implementation/enhancement of |
** the sqlite3 shell.c ".import" command. |
** |
** This command usage is equivalent to the sqlite2.x COPY statement, |
** which imports file data into a table using the PostgreSQL COPY file format: |
** $db copy $conflit_algo $table_name $filename \t \\N |
*/ |
case (int)DB_enum.DB_COPY: |
{ |
string zTable; /* Insert data into this table */ |
string zFile; /* The file from which to extract data */ |
string zConflict; /* The conflict algorithm to use */ |
sqlite3_stmt pStmt = null; /* A statement */ |
int nCol; /* Number of columns in the table */ |
int nByte; /* Number of bytes in an SQL string */ |
int i, j; /* Loop counters */ |
int nSep; /* Number of bytes in zSep[] */ |
int nNull; /* Number of bytes in zNull[] */ |
StringBuilder zSql = new StringBuilder( 200 ); /* An SQL statement */ |
string zLine; /* A single line of input from the file */ |
string[] azCol; /* zLine[] broken up into columns */ |
string zCommit; /* How to commit changes */ |
TextReader _in; /* The input file */ |
int lineno = 0; /* Line number of input file */ |
StringBuilder zLineNum = new StringBuilder( 80 ); /* Line number print buffer */ |
Tcl_Obj pResult; /* interp result */ |
|
string zSep; |
string zNull; |
if ( objc < 5 || objc > 7 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, |
"CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?" ); |
return TCL.TCL_ERROR; |
} |
if ( objc >= 6 ) |
{ |
zSep = TCL.Tcl_GetStringFromObj( objv[5], 0 ); |
} |
else |
{ |
zSep = "\t"; |
} |
if ( objc >= 7 ) |
{ |
zNull = TCL.Tcl_GetStringFromObj( objv[6], 0 ); |
} |
else |
{ |
zNull = ""; |
} |
zConflict = TCL.Tcl_GetStringFromObj( objv[2], 0 ); |
zTable = TCL.Tcl_GetStringFromObj( objv[3], 0 ); |
zFile = TCL.Tcl_GetStringFromObj( objv[4], 0 ); |
nSep = strlen30( zSep ); |
nNull = strlen30( zNull ); |
if ( nSep == 0 ) |
{ |
TCL.Tcl_AppendResult( interp, "Error: non-null separator required for copy" ); |
return TCL.TCL_ERROR; |
} |
if ( zConflict != "rollback" && |
zConflict != "abort" && |
zConflict != "fail" && |
zConflict != "ignore" && |
zConflict != "replace" ) |
{ |
TCL.Tcl_AppendResult( interp, "Error: \"", zConflict, |
"\", conflict-algorithm must be one of: rollback, " + |
"abort, fail, ignore, or replace", 0 ); |
return TCL.TCL_ERROR; |
} |
zSql.Append( sqlite3_mprintf( "SELECT * FROM '%q'", zTable ) ); |
if ( zSql == null ) |
{ |
TCL.Tcl_AppendResult( interp, "Error: no such table: ", zTable ); |
return TCL.TCL_ERROR; |
} |
nByte = strlen30( zSql ); |
rc = sqlite3_prepare( pDb.db, zSql.ToString(), -1, ref pStmt, 0 ); |
sqlite3DbFree( null, ref zSql ); |
if ( rc != 0 ) |
{ |
TCL.Tcl_AppendResult( interp, "Error: ", sqlite3_errmsg( pDb.db ) ); |
nCol = 0; |
} |
else |
{ |
nCol = sqlite3_column_count( pStmt ); |
} |
sqlite3_finalize( pStmt ); |
if ( nCol == 0 ) |
{ |
return TCL.TCL_ERROR; |
} |
//zSql.Append(malloc( nByte + 50 + nCol*2 ); |
//if( zSql==0 ) { |
// TCL.Tcl_AppendResult(interp, "Error: can't malloc()"); |
// return TCL.TCL_ERROR; |
//} |
sqlite3_snprintf( nByte + 50, zSql, "INSERT OR %q INTO '%q' VALUES(?", |
zConflict, zTable ); |
j = strlen30( zSql ); |
for ( i = 1; i < nCol; i++ ) |
{ |
//zSql+=[j++] = ','; |
//zSql[j++] = '?'; |
zSql.Append( ",?" ); |
} |
//zSql[j++] = ')'; |
//zSql[j] = ""; |
zSql.Append( ")" ); |
rc = sqlite3_prepare( pDb.db, zSql.ToString(), -1, ref pStmt, 0 ); |
//free(zSql); |
if ( rc != 0 ) |
{ |
TCL.Tcl_AppendResult( interp, "Error: ", sqlite3_errmsg( pDb.db ) ); |
sqlite3_finalize( pStmt ); |
return TCL.TCL_ERROR; |
} |
_in = new StreamReader( zFile );//fopen(zFile, "rb"); |
if ( _in == null ) |
{ |
TCL.Tcl_AppendResult( interp, "Error: cannot open file: ", zFile ); |
sqlite3_finalize( pStmt ); |
return TCL.TCL_ERROR; |
} |
azCol = new string[nCol + 1];//malloc( sizeof(azCol[0])*(nCol+1) ); |
if ( azCol == null ) |
{ |
TCL.Tcl_AppendResult( interp, "Error: can't malloc()" ); |
_in.Close();//fclose(_in); |
return TCL.TCL_ERROR; |
} |
sqlite3_exec( pDb.db, "BEGIN", 0, 0, 0 ); |
zCommit = "COMMIT"; |
while ( ( zLine = _in.ReadLine() ) != null )//local_getline(0, _in))!=0 ) |
{ |
string z; |
i = 0; |
lineno++; |
azCol = zLine.Split( zSep[0] ); |
//for(i=0, z=zLine; *z; z++){ |
// if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){ |
// *z = 0; |
// i++; |
// if( i<nCol ){ |
// azCol[i] = z[nSep]; |
// z += nSep-1; |
// } |
// } |
//} |
if ( azCol.Length != nCol ) |
{ |
StringBuilder zErr = new StringBuilder( 200 ); |
int nErr = strlen30( zFile ) + 200; |
//zErr = malloc(nErr); |
//if( zErr ){ |
sqlite3_snprintf( nErr, zErr, |
"Error: %s line %d: expected %d columns of data but found %d", |
zFile, lineno, nCol, i + 1 ); |
TCL.Tcl_AppendResult( interp, zErr ); |
// free(zErr); |
//} |
zCommit = "ROLLBACK"; |
break; |
} |
for ( i = 0; i < nCol; i++ ) |
{ |
/* check for null data, if so, bind as null */ |
if ( ( nNull > 0 && azCol[i] == zNull ) |
|| strlen30( azCol[i] ) == 0 |
) |
{ |
sqlite3_bind_null( pStmt, i + 1 ); |
} |
else |
{ |
sqlite3_bind_text( pStmt, i + 1, azCol[i], -1, SQLITE_STATIC ); |
} |
} |
sqlite3_step( pStmt ); |
rc = sqlite3_reset( pStmt ); |
//free(zLine); |
if ( rc != SQLITE_OK ) |
{ |
TCL.Tcl_AppendResult( interp, "Error: ", sqlite3_errmsg( pDb.db ) ); |
zCommit = "ROLLBACK"; |
break; |
} |
} |
//free(azCol); |
_in.Close();// fclose( _in ); |
sqlite3_finalize( pStmt ); |
sqlite3_exec( pDb.db, zCommit, 0, 0, 0 ); |
|
if ( zCommit[0] == 'C' ) |
{ |
/* success, set result as number of lines processed */ |
pResult = TCL.Tcl_GetObjResult( interp ); |
TCL.Tcl_SetIntObj( pResult, lineno ); |
rc = TCL.TCL_OK; |
} |
else |
{ |
/* failure, append lineno where failed */ |
sqlite3_snprintf( 80, zLineNum, "%d", lineno ); |
TCL.Tcl_AppendResult( interp, ", failed while processing line: ", zLineNum ); |
rc = TCL.TCL_ERROR; |
} |
break; |
} |
|
/* |
** $db enable_load_extension BOOLEAN |
** |
** Turn the extension loading feature on or off. It if off by |
** default. |
*/ |
case (int)DB_enum.DB_ENABLE_LOAD_EXTENSION: |
{ |
#if !SQLITE_OMIT_LOAD_EXTENSION |
bool onoff = false; |
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "BOOLEAN" ); |
return TCL.TCL_ERROR; |
} |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[2], out onoff ) ) |
{ |
return TCL.TCL_ERROR; |
} |
sqlite3_enable_load_extension( pDb.db, onoff ? 1 : 0 ); |
break; |
#else |
TCL.Tcl_AppendResult(interp, "extension loading is turned off at compile-time", |
0); |
return TCL.TCL_ERROR; |
#endif |
} |
|
/* |
** $db errorcode |
** |
** Return the numeric error code that was returned by the most recent |
** call to sqlite3_exec(). |
*/ |
case (int)DB_enum.DB_ERRORCODE: |
{ |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_errcode( pDb.db ) ) ); |
break; |
} |
|
/* |
** $db exists $sql |
** $db onecolumn $sql |
** |
** The onecolumn method is the equivalent of: |
** lindex [$db eval $sql] 0 |
*/ |
case (int)DB_enum.DB_EXISTS: |
case (int)DB_enum.DB_ONECOLUMN: |
{ |
DbEvalContext sEval = new DbEvalContext(); |
; |
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "SQL" ); |
return TCL.TCL_ERROR; |
} |
dbEvalInit( sEval, pDb, objv[2], null ); |
rc = dbEvalStep( sEval ); |
if ( choice == (int)DB_enum.DB_ONECOLUMN ) |
{ |
if ( rc == TCL.TCL_OK ) |
{ |
TCL.Tcl_SetObjResult( interp, dbEvalColumnValue( sEval, 0 ) ); |
} |
} |
else if ( rc == TCL.TCL_BREAK || rc == TCL.TCL_OK ) |
{ |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewBooleanObj( ( rc == TCL.TCL_OK ? 1 : 0 ) ) ); |
} |
dbEvalFinalize( sEval ); |
|
if ( rc == TCL.TCL_BREAK ) |
{ |
rc = TCL.TCL_OK; |
} |
break; |
} |
|
/* |
** $db eval $sql ?array? ?{ ...code... }? |
** |
** The SQL statement in $sql is evaluated. For each row, the values are |
** placed in elements of the array named "array" and ...code... is executed. |
** If "array" and "code" are omitted, then no callback is every invoked. |
** If "array" is an empty string, then the values are placed in variables |
** that have the same name as the fields extracted by the query. |
*/ |
case (int)DB_enum.DB_EVAL: |
{ |
if ( objc < 3 || objc > 5 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?" ); |
return TCL.TCL_ERROR; |
} |
|
if ( objc == 3 ) |
{ |
DbEvalContext sEval = new DbEvalContext(); |
Tcl_Obj pRet = TCL.Tcl_NewObj(); |
TCL.Tcl_IncrRefCount( pRet ); |
dbEvalInit( sEval, pDb, objv[2], null ); |
//Console.WriteLine( objv[2].ToString() ); |
while ( TCL.TCL_OK == ( rc = dbEvalStep( sEval ) ) ) |
{ |
int i; |
int nCol; |
TclObject[] pDummy; |
dbEvalRowInfo( sEval, out nCol, out pDummy ); |
for ( i = 0; i < nCol; i++ ) |
{ |
TCL.Tcl_ListObjAppendElement( interp, pRet, dbEvalColumnValue( sEval, i ) ); |
} |
} |
dbEvalFinalize( sEval ); |
if ( rc == TCL.TCL_BREAK ) |
{ |
TCL.Tcl_SetObjResult( interp, pRet ); |
rc = TCL.TCL_OK; |
} |
TCL.Tcl_DecrRefCount( ref pRet ); |
} |
else |
{ |
cd = new object[2]; |
DbEvalContext p; |
Tcl_Obj pArray = null; |
Tcl_Obj pScript; |
|
if ( objc == 5 && !String.IsNullOrEmpty( TCL.Tcl_GetString( objv[3] ) ) ) |
{ |
pArray = objv[3]; |
} |
pScript = objv[objc - 1]; |
TCL.Tcl_IncrRefCount( pScript ); |
|
p = new DbEvalContext();// (DbEvalContext)Tcl_Alloc( sizeof( DbEvalContext ) ); |
dbEvalInit( p, pDb, objv[2], pArray ); |
|
( (object[])cd )[0] = p; |
( (object[])cd )[1] = pScript; |
rc = DbEvalNextCmd( (object[])cd, interp, TCL.TCL_OK ); |
} |
break; |
} |
|
/* |
** $db function NAME [-argcount N] SCRIPT |
** |
** Create a new SQL function called NAME. Whenever that function is |
** called, invoke SCRIPT to evaluate the function. |
*/ |
case (int)DB_enum.DB_FUNCTION: |
{ |
SqlFunc pFunc; |
Tcl_Obj pScript; |
string zName; |
int nArg = -1; |
if ( objc == 6 ) |
{ |
string z = TCL.Tcl_GetString( objv[3] ); |
int n = strlen30( z ); |
if ( n > 2 && z.StartsWith( "-argcount" ) )//strncmp( z, "-argcount", n ) == 0 ) |
{ |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[4], out nArg ) ) |
return TCL.TCL_ERROR; |
if ( nArg < 0 ) |
{ |
TCL.Tcl_AppendResult( interp, "number of arguments must be non-negative" ); |
return TCL.TCL_ERROR; |
} |
} |
pScript = objv[5]; |
} |
else if ( objc != 4 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "NAME [-argcount N] SCRIPT" ); |
return TCL.TCL_ERROR; |
} |
else |
{ |
pScript = objv[3]; |
} |
zName = TCL.Tcl_GetStringFromObj( objv[2], 0 ); |
pFunc = findSqlFunc( pDb, zName ); |
if ( pFunc == null ) |
return TCL.TCL_ERROR; |
if ( pFunc.pScript != null ) |
{ |
TCL.Tcl_DecrRefCount( ref pFunc.pScript ); |
} |
pFunc.pScript = pScript; |
TCL.Tcl_IncrRefCount( pScript ); |
pFunc.useEvalObjv = safeToUseEvalObjv( interp, pScript ); |
rc = sqlite3_create_function( pDb.db, zName, nArg, SQLITE_UTF8, |
pFunc, tclSqlFunc, null, null ); |
if ( rc != SQLITE_OK ) |
{ |
rc = TCL.TCL_ERROR; |
TCL.Tcl_SetResult( interp, sqlite3_errmsg( pDb.db ), TCL.TCL_VOLATILE ); |
} |
break; |
} |
|
/* |
** $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID |
*/ |
case (int)DB_enum.DB_INCRBLOB: |
{ |
#if SQLITE_OMIT_INCRBLOB |
TCL.Tcl_AppendResult( interp, "incrblob not available in this build" ); |
return TCL.TCL_ERROR; |
#else |
int isReadonly = 0; |
string zDb = "main" ; |
string zTable; |
string zColumn; |
long iRow = 0; |
|
/* Check for the -readonly option */ |
if ( objc > 3 && TCL.Tcl_GetString( objv[2] ) == "-readonly" ) |
{ |
isReadonly = 1; |
} |
|
if ( objc != ( 5 + isReadonly ) && objc != ( 6 + isReadonly ) ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID" ); |
return TCL.TCL_ERROR; |
} |
|
if ( objc == ( 6 + isReadonly ) ) |
{ |
zDb = TCL.Tcl_GetString( objv[2] ) ; |
} |
zTable = TCL.Tcl_GetString( objv[objc - 3] ); |
zColumn = TCL.Tcl_GetString( objv[objc - 2] ) ; |
rc = TCL.Tcl_GetWideIntFromObj( interp, objv[objc - 1], out iRow ) ? 1 : 0; |
|
if ( rc == TCL.TCL_OK ) |
{ |
rc = createIncrblobChannel( |
interp, pDb, zDb, zTable, zColumn, iRow, isReadonly |
); |
} |
break; |
#endif |
} |
/* |
** $db interrupt |
** |
** Interrupt the execution of the inner-most SQL interpreter. This |
** causes the SQL statement to return an error of SQLITE_INTERRUPT. |
*/ |
case (int)DB_enum.DB_INTERRUPT: |
{ |
sqlite3_interrupt( pDb.db ); |
break; |
} |
|
/* |
** $db nullvalue ?STRING? |
** |
** Change text used when a NULL comes back from the database. If ?STRING? |
** is not present, then the current string used for NULL is returned. |
** If STRING is present, then STRING is returned. |
** |
*/ |
case (int)DB_enum.DB_NULLVALUE: |
{ |
if ( objc != 2 && objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "NULLVALUE" ); |
return TCL.TCL_ERROR; |
} |
if ( objc == 3 ) |
{ |
int len = 0; |
string zNull = TCL.Tcl_GetStringFromObj( objv[2], out len ); |
if ( pDb.zNull != null ) |
{ |
TCL.Tcl_Free( ref pDb.zNull ); |
} |
if ( zNull != null && len > 0 ) |
{ |
pDb.zNull = zNull; |
//pDb.zNull = TCL.Tcl_Alloc( len + 1 ); |
//memcpy(pDb->zNull, zNull, len); |
//pDb.zNull[len] = '\0'; |
} |
else |
{ |
pDb.zNull = null; |
} |
} |
TCL.Tcl_SetObjResult( interp, dbTextToObj( pDb.zNull ) ); |
break; |
} |
|
/* |
** $db last_insert_rowid |
** |
** Return an integer which is the ROWID for the most recent insert. |
*/ |
case (int)DB_enum.DB_LAST_INSERT_ROWID: |
{ |
Tcl_Obj pResult; |
Tcl_WideInt rowid; |
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "" ); |
return TCL.TCL_ERROR; |
} |
rowid = sqlite3_last_insert_rowid( pDb.db ); |
pResult = TCL.Tcl_GetObjResult( interp ); |
TCL.Tcl_SetLongObj( pResult, rowid ); |
break; |
} |
|
/* |
** The DB_ONECOLUMN method is implemented together with DB_EXISTS. |
*/ |
|
/* $db progress ?N CALLBACK? |
** |
** Invoke the given callback every N virtual machine opcodes while executing |
** queries. |
*/ |
case (int)DB_enum.DB_PROGRESS: |
{ |
if ( objc == 2 ) |
{ |
if ( !String.IsNullOrEmpty( pDb.zProgress ) ) |
{ |
TCL.Tcl_AppendResult( interp, pDb.zProgress ); |
} |
} |
else if ( objc == 4 ) |
{ |
string zProgress; |
int len = 0; |
int N = 0; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out N ) ) |
{ |
return TCL.TCL_ERROR; |
}; |
if ( !String.IsNullOrEmpty( pDb.zProgress ) ) |
{ |
TCL.Tcl_Free( ref pDb.zProgress ); |
} |
zProgress = TCL.Tcl_GetStringFromObj( objv[3], len ); |
if ( !String.IsNullOrEmpty( zProgress ) ) |
{ |
//pDb.zProgress = TCL.Tcl_Alloc( len + 1 ); |
//memcpy( pDb.zProgress, zProgress, len + 1 ); |
pDb.zProgress = zProgress; |
} |
else |
{ |
pDb.zProgress = null; |
} |
#if !SQLITE_OMIT_PROGRESS_CALLBACK |
if ( !String.IsNullOrEmpty( pDb.zProgress ) ) |
{ |
pDb.interp = interp; |
sqlite3_progress_handler( pDb.db, N, DbProgressHandler, pDb ); |
} |
else |
{ |
sqlite3_progress_handler( pDb.db, 0, null, 0 ); |
} |
#endif |
} |
else |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "N CALLBACK" ); |
return TCL.TCL_ERROR; |
} |
break; |
} |
|
/* $db profile ?CALLBACK? |
** |
** Make arrangements to invoke the CALLBACK routine after each SQL statement |
** that has run. The text of the SQL and the amount of elapse time are |
** appended to CALLBACK before the script is run. |
*/ |
case (int)DB_enum.DB_PROFILE: |
{ |
if ( objc > 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "?CALLBACK?" ); |
return TCL.TCL_ERROR; |
} |
else if ( objc == 2 ) |
{ |
if ( !String.IsNullOrEmpty( pDb.zProfile ) ) |
{ |
TCL.Tcl_AppendResult( interp, pDb.zProfile ); |
} |
} |
else |
{ |
string zProfile; |
int len = 0; |
if ( !String.IsNullOrEmpty( pDb.zProfile ) ) |
{ |
TCL.Tcl_Free( ref pDb.zProfile ); |
} |
zProfile = TCL.Tcl_GetStringFromObj( objv[2], out len ); |
if ( !String.IsNullOrEmpty( zProfile ) && len > 0 ) |
{ |
//pDb.zProfile = TCL.Tcl_Alloc( len + 1 ); |
//memcpy( pDb.zProfile, zProfile, len + 1 ); |
pDb.zProfile = zProfile; |
} |
else |
{ |
pDb.zProfile = null; |
} |
#if !SQLITE_OMIT_TRACE && !(SQLITE_OMIT_FLOATING_POINT) |
if ( !String.IsNullOrEmpty( pDb.zProfile ) ) |
{ |
pDb.interp = interp; |
sqlite3_profile( pDb.db, DbProfileHandler, pDb ); |
} |
else |
{ |
sqlite3_profile( pDb.db, null, null ); |
} |
#endif |
} |
break; |
} |
|
/* |
** $db rekey KEY |
** |
** Change the encryption key on the currently open database. |
*/ |
case (int)DB_enum.DB_REKEY: |
{ |
int nKey = 0; |
string pKey; |
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "KEY" ); |
return TCL.TCL_ERROR; |
} |
pKey = TCL.Tcl_GetStringFromObj( objv[2], out nKey ); |
#if SQLITE_HAS_CODEC |
rc = sqlite3_rekey( pDb.db, pKey, nKey ); |
if ( rc != 0 ) |
{ |
TCL.Tcl_AppendResult( interp, sqlite3ErrStr( rc ) ); |
rc = TCL.TCL_ERROR; |
} |
#endif |
break; |
} |
|
/* $db restore ?DATABASE? FILENAME |
** |
** Open a database file named FILENAME. Transfer the content |
** of FILENAME into the local database DATABASE (default: "main"). |
*/ |
case (int)DB_enum.DB_RESTORE: |
{ |
string zSrcFile; |
string zDestDb; |
sqlite3 pSrc = null; |
sqlite3_backup pBackup; |
int nTimeout = 0; |
|
if ( objc == 3 ) |
{ |
zDestDb = "main"; |
zSrcFile = TCL.Tcl_GetString( objv[2] ); |
} |
else if ( objc == 4 ) |
{ |
zDestDb = TCL.Tcl_GetString( objv[2] ); |
zSrcFile = TCL.Tcl_GetString( objv[3] ); |
} |
else |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "?DATABASE? FILENAME" ); |
return TCL.TCL_ERROR; |
} |
rc = sqlite3_open_v2( zSrcFile, out pSrc, SQLITE_OPEN_READONLY, null ); |
if ( rc != SQLITE_OK ) |
{ |
TCL.Tcl_AppendResult( interp, "cannot open source database: ", |
sqlite3_errmsg( pSrc ) ); |
sqlite3_close( pSrc ); |
return TCL.TCL_ERROR; |
} |
pBackup = sqlite3_backup_init( pDb.db, zDestDb, pSrc, "main" ); |
if ( pBackup == null ) |
{ |
TCL.Tcl_AppendResult( interp, "restore failed: ", |
sqlite3_errmsg( pDb.db ) ); |
sqlite3_close( pSrc ); |
return TCL.TCL_ERROR; |
} |
|
#if SQLITE_HAS_CODEC |
if ( pBackup.pDestDb.aDb[0].pBt.pBt.pPager.pCodec != null ) |
{ |
pBackup.pSrc.pBt.pPager.xCodec = pBackup.pDestDb.aDb[0].pBt.pBt.pPager.xCodec; |
pBackup.pSrc.pBt.pPager.xCodecFree = pBackup.pDestDb.aDb[0].pBt.pBt.pPager.xCodecFree; |
pBackup.pSrc.pBt.pPager.xCodecSizeChng = pBackup.pDestDb.aDb[0].pBt.pBt.pPager.xCodecSizeChng; |
pBackup.pSrc.pBt.pPager.pCodec = pBackup.pDestDb.aDb[0].pBt.pBt.pPager.pCodec.Copy(); |
if ( pBackup.pDest.GetHashCode() != pBackup.pDestDb.aDb[0].GetHashCode() ) // Not Main Database |
{ |
pBackup.pDest.pBt.pPager.xCodec = pBackup.pDestDb.aDb[0].pBt.pBt.pPager.xCodec; |
pBackup.pDest.pBt.pPager.xCodecFree = pBackup.pDestDb.aDb[0].pBt.pBt.pPager.xCodecFree; |
pBackup.pDest.pBt.pPager.xCodecSizeChng = pBackup.pDestDb.aDb[0].pBt.pBt.pPager.xCodecSizeChng; |
pBackup.pDest.pBt.pPager.pCodec = pBackup.pDestDb.aDb[0].pBt.pBt.pPager.pCodec.Copy(); |
} |
} |
#endif |
while ( ( rc = sqlite3_backup_step( pBackup, 100 ) ) == SQLITE_OK |
|| rc == SQLITE_BUSY ) |
{ |
if ( rc == SQLITE_BUSY ) |
{ |
if ( nTimeout++ >= 3 ) |
break; |
sqlite3_sleep( 100 ); |
} |
} |
sqlite3_backup_finish( pBackup ); |
if ( rc == SQLITE_DONE ) |
{ |
rc = TCL.TCL_OK; |
} |
else if ( rc == SQLITE_BUSY || rc == SQLITE_LOCKED ) |
{ |
TCL.Tcl_AppendResult( interp, "restore failed: source database busy" |
); |
rc = TCL.TCL_ERROR; |
} |
else |
{ |
TCL.Tcl_AppendResult( interp, "restore failed: ", |
sqlite3_errmsg( pDb.db ) ); |
rc = TCL.TCL_ERROR; |
} |
sqlite3_close( pSrc ); |
break; |
} |
|
/* |
** $db status (step|sort|autoindex) |
** |
** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or |
** SQLITE_STMTSTATUS_SORT for the most recent eval. |
*/ |
case (int)DB_enum.DB_STATUS: |
{ |
int v; |
string zOp; |
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "(step|sort|autoindex)" ); |
return TCL.TCL_ERROR; |
} |
zOp = TCL.Tcl_GetString( objv[2] ); |
if ( zOp == "step" ) |
{ |
v = pDb.nStep; |
} |
else if ( zOp == "sort" ) |
{ |
v = pDb.nSort; |
} |
else if ( zOp == "autoindex" ) |
{ |
v = pDb.nIndex; |
} |
else |
{ |
TCL.Tcl_AppendResult( interp, "bad argument: should be autoindex, step or sort" ); |
return TCL.TCL_ERROR; |
} |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( v ) ); |
break; |
} |
|
/* |
** $db timeout MILLESECONDS |
** |
** Delay for the number of milliseconds specified when a file is locked. |
*/ |
case (int)DB_enum.DB_TIMEOUT: |
{ |
int ms = 0; |
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "MILLISECONDS" ); |
return TCL.TCL_ERROR; |
} |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out ms ) ) |
return TCL.TCL_ERROR; |
sqlite3_busy_timeout( pDb.db, ms ); |
break; |
} |
|
/* |
** $db total_changes |
** |
** Return the number of rows that were modified, inserted, or deleted |
** since the database handle was created. |
*/ |
case (int)DB_enum.DB_TOTAL_CHANGES: |
{ |
Tcl_Obj pResult; |
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "" ); |
return TCL.TCL_ERROR; |
} |
pResult = TCL.Tcl_GetObjResult( interp ); |
TCL.Tcl_SetIntObj( pResult, sqlite3_total_changes( pDb.db ) ); |
break; |
} |
|
/* $db trace ?CALLBACK? |
** |
** Make arrangements to invoke the CALLBACK routine for each SQL statement |
** that is executed. The text of the SQL is appended to CALLBACK before |
** it is executed. |
*/ |
case (int)DB_enum.DB_TRACE: |
{ |
if ( objc > 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "?CALLBACK?" ); |
return TCL.TCL_ERROR; |
} |
else if ( objc == 2 ) |
{ |
if ( pDb.zTrace != null ) |
{ |
TCL.Tcl_AppendResult( interp, pDb.zTrace ); |
} |
} |
else |
{ |
string zTrace; |
int len = 0; |
if ( pDb.zTrace != null ) |
{ |
TCL.Tcl_Free( ref pDb.zTrace ); |
} |
zTrace = TCL.Tcl_GetStringFromObj( objv[2], out len ); |
if ( zTrace != null && len > 0 ) |
{ |
//pDb.zTrace = TCL.Tcl_Alloc( len + 1 ); |
pDb.zTrace = zTrace;//memcpy( pDb.zTrace, zTrace, len + 1 ); |
} |
else |
{ |
pDb.zTrace = null; |
} |
#if !SQLITE_OMIT_TRACE && !(SQLITE_OMIT_FLOATING_POINT) |
if ( pDb.zTrace != null ) |
{ |
pDb.interp = interp; |
sqlite3_trace( pDb.db, (dxTrace)DbTraceHandler, pDb ); |
} |
else |
{ |
sqlite3_trace( pDb.db, null, null ); |
} |
#endif |
} |
break; |
} |
|
// /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT |
// ** |
// ** Start a new transaction (if we are not already in the midst of a |
// ** transaction) and execute the TCL script SCRIPT. After SCRIPT |
// ** completes, either commit the transaction or roll it back if SCRIPT |
// ** throws an exception. Or if no new transation was started, do nothing. |
// ** pass the exception on up the stack. |
// ** |
// ** This command was inspired by Dave Thomas's talk on Ruby at the |
// ** 2005 O'Reilly Open Source Convention (OSCON). |
// */ |
case (int)DB_enum.DB_TRANSACTION: |
{ |
Tcl_Obj pScript; |
string zBegin = "SAVEPOINT _tcl_transaction"; |
if ( objc != 3 && objc != 4 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "[TYPE] SCRIPT" ); |
return TCL.TCL_ERROR; |
} |
if ( pDb.nTransaction == 0 && objc == 4 ) |
{ |
string[] TTYPE_strs = { "deferred", "exclusive", "immediate", null }; |
|
int ttype = 0; |
if ( TCL.Tcl_GetIndexFromObj( interp, objv[2], TTYPE_strs, "transaction type", |
0, out ttype ) ) |
{ |
return TCL.TCL_ERROR; |
} |
switch ( ttype ) |
{ |
case (int)TTYPE_enum.TTYPE_DEFERRED: /* no-op */ |
; |
break; |
case (int)TTYPE_enum.TTYPE_EXCLUSIVE: |
zBegin = "BEGIN EXCLUSIVE"; |
break; |
case (int)TTYPE_enum.TTYPE_IMMEDIATE: |
zBegin = "BEGIN IMMEDIATE"; |
break; |
} |
} |
pScript = objv[objc - 1]; |
|
/* Run the SQLite BEGIN command to open a transaction or savepoint. */ |
pDb.disableAuth++; |
rc = sqlite3_exec( pDb.db, zBegin, 0, 0, 0 ); |
pDb.disableAuth--; |
if ( rc != SQLITE_OK ) |
{ |
TCL.Tcl_AppendResult( interp, sqlite3_errmsg( pDb.db ) ); |
return TCL.TCL_ERROR; |
} |
pDb.nTransaction++; |
/* If using NRE, schedule a callback to invoke the script pScript, then |
** a second callback to commit (or rollback) the transaction or savepoint |
** opened above. If not using NRE, evaluate the script directly, then |
** call function DbTransPostCmd() to commit (or rollback) the transaction |
** or savepoint. */ |
if ( DbUseNre() ) |
{ |
Debugger.Break(); |
//Tcl_NRAddCallback( interp, DbTransPostCmd, cd, 0, 0, 0 ); |
//Tcl_NREvalObj(interp, pScript, 0); |
} |
else |
{ |
rc = DbTransPostCmd( cd, interp, TCL.Tcl_EvalObjEx( interp, pScript, 0 ) ); |
} |
break; |
} |
|
/* |
** $db unlock_notify ?script? |
*/ |
case (int)DB_enum.DB_UNLOCK_NOTIFY: |
{ |
#if !SQLITE_ENABLE_UNLOCK_NOTIFY |
TCL.Tcl_AppendResult( interp, "unlock_notify not available in this build", 0 ); |
rc = TCL.TCL_ERROR; |
#else |
if( objc!=2 && objc!=3 ){ |
Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); |
rc = TCL.Tcl_ERROR; |
}else{ |
void (*xNotify)(void **, int) = 0; |
void *pNotifyArg = 0; |
|
if( pDb.pUnlockNotify ){ |
Tcl_DecrRefCount(pDb.pUnlockNotify); |
pDb.pUnlockNotify = 0; |
} |
|
if( objc==3 ){ |
xNotify = DbUnlockNotify; |
pNotifyArg = (void )pDb; |
pDb.pUnlockNotify = objv[2]; |
Tcl_IncrRefCount(pDb.pUnlockNotify); |
} |
|
if( sqlite3_unlock_notify(pDb.db, xNotify, pNotifyArg) ){ |
Tcl_AppendResult(interp, sqlite3_errmsg(pDb.db), 0); |
rc = TCL.Tcl_ERROR; |
} |
} |
#endif |
break; |
} |
/* |
** $db wal_hook ?script? |
** $db update_hook ?script? |
** $db rollback_hook ?script? |
*/ |
case (int)DB_enum.DB_WAL_HOOK: |
case (int)DB_enum.DB_UPDATE_HOOK: |
case (int)DB_enum.DB_ROLLBACK_HOOK: |
{ |
|
/* set ppHook to point at pUpdateHook or pRollbackHook, depending on |
** whether [$db update_hook] or [$db rollback_hook] was invoked. |
*/ |
Tcl_Obj ppHook; |
if ( choice == (int)DB_enum.DB_UPDATE_HOOK ) |
{ |
ppHook = pDb.pUpdateHook; |
} |
else if ( choice == (int)DB_enum.DB_WAL_HOOK ) |
{ |
ppHook = pDb.pWalHook; |
} |
else |
{ |
ppHook = pDb.pRollbackHook; |
} |
|
if ( objc != 2 && objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "?SCRIPT?" ); |
return TCL.TCL_ERROR; |
} |
if ( ppHook != null ) |
{ |
TCL.Tcl_SetObjResult( interp, ppHook ); |
if ( objc == 3 ) |
{ |
TCL.Tcl_DecrRefCount( ref ppHook ); |
ppHook = null; |
} |
} |
if ( objc == 3 ) |
{ |
Debug.Assert( null == ppHook ); |
if ( objv[2] != null )//TCL.Tcl_GetCharLength( objv[2] ) > 0 ) |
{ |
ppHook = objv[2]; |
TCL.Tcl_IncrRefCount( ppHook ); |
} |
} |
if ( choice == (int)DB_enum.DB_UPDATE_HOOK ) |
{ |
pDb.pUpdateHook = ppHook; |
} |
else |
{ |
pDb.pRollbackHook = ppHook; |
} |
sqlite3_update_hook( pDb.db, ( pDb.pUpdateHook != null ? (dxUpdateCallback)DbUpdateHandler : null ), pDb ); |
sqlite3_rollback_hook( pDb.db, ( pDb.pRollbackHook != null ? (dxRollbackCallback)DbRollbackHandler : null ), pDb ); |
sqlite3_wal_hook( pDb.db, ( pDb.pWalHook != null ? (dxWalCallback)DbWalHandler : null ), pDb ); |
|
break; |
} |
|
/* $db version |
** |
** Return the version string for this database. |
*/ |
case (int)DB_enum.DB_VERSION: |
{ |
TCL.Tcl_SetResult( interp, sqlite3_libversion(), TCL.TCL_STATIC ); |
break; |
} |
|
default: |
Debug.Assert( false, "Missing switch:" + objv[1].ToString() ); |
break; |
} /* End of the SWITCH statement */ |
return rc; |
} |
|
#if SQLITE_TCL_NRE |
/* |
** Adaptor that provides an objCmd interface to the NRE-enabled |
** interface implementation. |
*/ |
static int DbObjCmdAdaptor( |
void *cd, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj *const*objv |
){ |
return TCL.TCL_NRCallObjProc(interp, DbObjCmd, cd, objc, objv); |
} |
#endif //* SQLITE_TCL_NRE */ |
/* |
** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN? |
** ?-create BOOLEAN? ?-nomutex BOOLEAN? |
** |
** This is the main Tcl command. When the "sqlite" Tcl command is |
** invoked, this routine runs to process that command. |
** |
** The first argument, DBNAME, is an arbitrary name for a new |
** database connection. This command creates a new command named |
** DBNAME that is used to control that connection. The database |
** connection is deleted when the DBNAME command is deleted. |
** |
** The second argument is the name of the database file. |
** |
*/ |
static int DbMain( object cd, Tcl_Interp interp, int objc, Tcl_Obj[] objv ) |
{ |
SqliteDb p; |
string pKey = null; |
int nKey = 0; |
string zArg; |
string zErrMsg; |
int i; |
string zFile; |
string zVfs = null; |
int flags; |
Tcl_DString translatedFilename; |
/* In normal use, each TCL interpreter runs in a single thread. So |
** by default, we can turn of mutexing on SQLite database connections. |
** However, for testing purposes it is useful to have mutexes turned |
** on. So, by default, mutexes default off. But if compiled with |
** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on. |
*/ |
#if SQLITE_TCL_DEFAULT_FULLMUTEX |
flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX; |
#else |
flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX; |
#endif |
if ( objc == 2 ) |
{ |
zArg = TCL.Tcl_GetStringFromObj( objv[1], 0 ); |
if ( zArg == "-version" ) |
{ |
TCL.Tcl_AppendResult( interp, sqlite3_version, null ); |
return TCL.TCL_OK; |
} |
if ( zArg == "-has-codec" ) |
{ |
#if SQLITE_HAS_CODEC |
TCL.Tcl_AppendResult( interp, "1" ); |
#else |
TCL.Tcl_AppendResult( interp, "0", null ); |
#endif |
return TCL.TCL_OK; |
} |
if ( zArg == "-tcl-uses-utf" ) |
{ |
TCL.Tcl_AppendResult( interp, "1", null ); |
return TCL.TCL_OK; |
} |
} |
for ( i = 3; i + 1 < objc; i += 2 ) |
{ |
zArg = TCL.Tcl_GetString( objv[i] ); |
if ( zArg == "-key" ) |
{ |
pKey = TCL.Tcl_GetStringFromObj( objv[i + 1], out nKey ); |
} |
else if ( zArg == "-vfs" ) |
{ |
zVfs = TCL.Tcl_GetString( objv[i + 1] ); |
} |
else if ( zArg == "-readonly" ) |
{ |
bool b = false; |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[i + 1], out b ) ) |
return TCL.TCL_ERROR; |
if ( b ) |
{ |
flags &= ~( SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE ); |
flags |= SQLITE_OPEN_READONLY; |
} |
else |
{ |
flags &= ~SQLITE_OPEN_READONLY; |
flags |= SQLITE_OPEN_READWRITE; |
} |
} |
else if ( zArg == "-create" ) |
{ |
bool b = false; |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[i + 1], out b ) ) |
return TCL.TCL_ERROR; |
if ( b && ( flags & SQLITE_OPEN_READONLY ) == 0 ) |
{ |
flags |= SQLITE_OPEN_CREATE; |
} |
else |
{ |
flags &= ~SQLITE_OPEN_CREATE; |
} |
} |
else if ( zArg == "-nomutex" ) |
{ |
bool b = false; |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[i + 1], out b ) ) |
return TCL.TCL_ERROR; |
if ( b ) |
{ |
flags |= SQLITE_OPEN_NOMUTEX; |
flags &= ~SQLITE_OPEN_FULLMUTEX; |
} |
else |
{ |
flags &= ~SQLITE_OPEN_NOMUTEX; |
} |
} |
else if ( zArg == "-fullmutex" )//strcmp( zArg, "-fullmutex" ) == 0 ) |
{ |
bool b = false; |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[i + 1], out b ) ) |
return TCL.TCL_ERROR; |
if ( b ) |
{ |
flags |= SQLITE_OPEN_FULLMUTEX; |
flags &= ~SQLITE_OPEN_NOMUTEX; |
} |
else |
{ |
flags &= ~SQLITE_OPEN_FULLMUTEX; |
} |
} |
else |
{ |
TCL.Tcl_AppendResult( interp, "unknown option: ", zArg, null ); |
return TCL.TCL_ERROR; |
} |
} |
if ( objc < 3 || ( objc & 1 ) != 1 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, |
"HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN? ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN?" |
#if SQLITE_HAS_CODEC |
+ " ?-key CODECKEY?" |
#endif |
); |
return TCL.TCL_ERROR; |
} |
zErrMsg = ""; |
p = new SqliteDb();//(SqliteDb)Tcl_Alloc( sizeof(*p) ); |
if ( p == null ) |
{ |
TCL.Tcl_SetResult( interp, "malloc failed", TCL.TCL_STATIC ); |
return TCL.TCL_ERROR; |
} |
//memset(p, 0, sizeof(*p)); |
zFile = TCL.Tcl_GetStringFromObj( objv[2], 0 ); |
//zFile = TCL.Tcl_TranslateFileName( interp, zFile, ref translatedFilename ); |
sqlite3_open_v2( zFile, out p.db, flags, zVfs ); |
//Tcl_DStringFree( ref translatedFilename ); |
if ( SQLITE_OK != sqlite3_errcode( p.db ) ) |
{ |
zErrMsg = sqlite3_errmsg( p.db );// sqlite3_mprintf( "%s", sqlite3_errmsg( p.db ) ); |
sqlite3_close( p.db ); |
p.db = null; |
} |
#if SQLITE_HAS_CODEC |
if ( p.db != null ) |
{ |
sqlite3_key( p.db, pKey, nKey ); |
} |
#endif |
if ( p.db == null ) |
{ |
TCL.Tcl_SetResult( interp, zErrMsg, TCL.TCL_VOLATILE ); |
TCL.Tcl_Free( ref p ); |
zErrMsg = "";// sqlite3DbFree( db, ref zErrMsg ); |
return TCL.TCL_ERROR; |
} |
p.maxStmt = NUM_PREPARED_STMTS; |
p.interp = interp; |
zArg = TCL.Tcl_GetStringFromObj( objv[1], 0 ); |
if ( DbUseNre() ) |
{ |
Debugger.Break(); |
//Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd, |
// p, DbDeleteCmd); |
} |
else |
{ |
TCL.Tcl_CreateObjCommand( interp, zArg, (Interp.dxObjCmdProc)DbObjCmd, p, (Interp.dxCmdDeleteProc)DbDeleteCmd ); |
} |
return TCL.TCL_OK; |
} |
|
/* |
** Provide a dummy TCL.Tcl_InitStubs if we are using this as a static |
** library. |
*/ |
#if !USE_TCL_STUBS |
//# undef TCL.Tcl_InitStubs |
static void Tcl_InitStubs( Tcl_Interp interp, string s, int i ) |
{ |
} |
#endif |
|
/* |
** Make sure we have a PACKAGE_VERSION macro defined. This will be |
** defined automatically by the TEA makefile. But other makefiles |
** do not define it. |
*/ |
#if !PACKAGE_VERSION |
public static string PACKAGE_VERSION;//# define PACKAGE_VERSION SQLITE_VERSION |
#endif |
|
|
/* |
** Initialize this module. |
** |
** This Tcl module contains only a single new Tcl command named "sqlite". |
** (Hence there is no namespace. There is no point in using a namespace |
** if the extension only supplies one new name!) The "sqlite" command is |
** used to open a new SQLite database. See the DbMain() routine above |
** for additional information. |
** |
** The EXTERN macros are required by TCL in order to work on windows. |
*/ |
//int Sqlite3_Init(Tcl_Interp interp){ |
static public int Sqlite3_Init( Tcl_Interp interp ) |
{ |
PACKAGE_VERSION = SQLITE_VERSION; |
Tcl_InitStubs( interp, "tclsharp 8.4", 0 ); |
TCL.Tcl_CreateObjCommand( interp, "sqlite3", (Interp.dxObjCmdProc)DbMain, null, null ); |
TCL.Tcl_PkgProvide( interp, "sqlite3", PACKAGE_VERSION ); |
|
#if !SQLITE_3_SUFFIX_ONLY |
/* The "sqlite" alias is undocumented. It is here only to support |
** legacy scripts. All new scripts should use only the "sqlite3" |
** command. |
*/ |
TCL.Tcl_CreateObjCommand( interp, "sqlite", (Interp.dxObjCmdProc)DbMain, null, null ); |
#endif |
return TCL.TCL_OK; |
} |
//int Tclsqlite3_Init(Tcl_Interp interp){ return Sqlite3_Init(interp); } |
//int Sqlite3_SafeInit(Tcl_Interp interp){ return TCL.TCL_OK; } |
//int Tclsqlite3_SafeInit(Tcl_Interp interp){ return TCL.TCL_OK; } |
//int Sqlite3_Unload(Tcl_Interp interp, int flags){ return TCL.TCL_OK; } |
//int Tclsqlite3_Unload(Tcl_Interp interp, int flags){ return TCL.TCL_OK; } |
//int Sqlite3_SafeUnload(Tcl_Interp interp, int flags){ return TCL.TCL_OK; } |
//int Tclsqlite3_SafeUnload(Tcl_Interp interp, int flags){ return TCL.TCL_OK;} |
|
|
#if !SQLITE_3_SUFFIX_ONLY |
//int Sqlite_Init(Tcl_Interp interp){ return Sqlite3_Init(interp); } |
//int Tclsqlite_Init(Tcl_Interp interp){ return Sqlite3_Init(interp); } |
//int Sqlite_SafeInit(Tcl_Interp interp){ return TCL.TCL_OK; } |
//int Tclsqlite_SafeInit(Tcl_Interp interp){ return TCL.TCL_OK; } |
//int Sqlite_Unload(Tcl_Interp interp, int flags){ return TCL.TCL_OK; } |
//int Tclsqlite_Unload(Tcl_Interp interp, int flags){ return TCL.TCL_OK; } |
//int Sqlite_SafeUnload(Tcl_Interp interp, int flags){ return TCL.TCL_OK; } |
//int Tclsqlite_SafeUnload(Tcl_Interp interp, int flags){ return TCL.TCL_OK;} |
#endif |
|
#if TCLSH |
/***************************************************************************** |
** All of the code that follows is used to build standalone TCL interpreters |
** that are statically linked with SQLite. Enable these by compiling |
** with -DTCLSH=n where n can be 1 or 2. An n of 1 generates a standard |
** tclsh but with SQLite built in. An n of 2 generates the SQLite space |
** analysis program. |
*/ |
|
#if (SQLITE_TEST) || (SQLITE_TCLMD5) |
/* |
* This code implements the MD5 message-digest algorithm. |
* The algorithm is due to Ron Rivest. This code was |
* written by Colin Plumb in 1993, no copyright is claimed. |
* This code is in the public domain; do with it what you wish. |
* |
* Equivalent code is available from RSA Data Security, Inc. |
* This code has been tested against that, and is equivalent, |
* except that you don't need to include two pages of legalese |
* with every copy. |
* |
* To compute the message digest of a chunk of bytes, declare an |
* MD5Context structure, pass it to MD5Init, call MD5Update as |
* needed on buffers full of bytes, and then call MD5Final, which |
* will fill a supplied 16-byte array with the digest. |
*/ |
|
/* |
* If compiled on a machine that doesn't have a 32-bit integer, |
* you just set "uint32" to the appropriate datatype for an |
* unsigned 32-bit integer. For example: |
* |
* cc -Duint32='unsigned long' md5.c |
* |
*/ |
//#if !uint32 |
//# define uint32 unsigned int |
//#endif |
|
//struct MD5Context { |
// int isInit; |
// uint32 buf[4]; |
// uint32 bits[2]; |
// unsigned char in[64]; |
//}; |
//typedef struct MD5Context MD5Context; |
class MD5Context |
{ |
public bool isInit; |
public u32[] buf = new u32[4]; |
public u32[] bits = new u32[2]; |
public u32[] _in = new u32[64]; |
public Mem _Mem; |
}; |
|
/* |
* Note: this code is harmless on little-endian machines. |
*/ |
//static void byteReverse (unsigned char *buf, unsigned longs){ |
// uint32 t; |
// do { |
// t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 | |
// ((unsigned)buf[1]<<8 | buf[0]); |
// *(uint32 )buf = t; |
// buf += 4; |
// } while (--longs); |
//} |
|
/* The four core functions - F1 is optimized somewhat */ |
|
delegate u32 dxF1234( u32 x, u32 y, u32 z ); |
|
//* #define F1(x, y, z) (x & y | ~x & z) */ |
//#define F1(x, y, z) (z ^ (x & (y ^ z))) |
static u32 F1( u32 x, u32 y, u32 z ) |
{ |
return ( z ^ ( x & ( y ^ z ) ) ); |
} |
|
//#define F2(x, y, z) F1(z, x, y) |
static u32 F2( u32 x, u32 y, u32 z ) |
{ |
return F1( z, x, y ); |
} |
|
//#define F3(x, y, z) (x ^ y ^ z) |
static u32 F3( u32 x, u32 y, u32 z ) |
{ |
return ( x ^ y ^ z ); |
} |
|
//#define F4(x, y, z) (y ^ (x | ~z)) |
static u32 F4( u32 x, u32 y, u32 z ) |
{ |
return ( y ^ ( x | ~z ) ); |
} |
|
///* This is the central step in the MD5 algorithm. */ |
//#define MD5STEP(f, w, x, y, z, data, s) \ |
// ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) |
static void MD5STEP( dxF1234 f, ref u32 w, u32 x, u32 y, u32 z, u32 data, byte s ) |
{ |
w += f( x, y, z ) + data; |
w = w << s | w >> ( 32 - s ); |
w += x; |
} |
|
/* |
* The core of the MD5 algorithm, this alters an existing MD5 hash to |
* reflect the addition of 16 longwords of new data. MD5Update blocks |
* the data and converts bytes into longwords for this routine. |
*/ |
static void MD5Transform( u32[] buf, u32[] _in ) |
{ |
u32 a, b, c, d; |
|
a = buf[0]; |
b = buf[1]; |
c = buf[2]; |
d = buf[3]; |
|
MD5STEP( F1, ref a, b, c, d, _in[0] + 0xd76aa478, 7 ); |
MD5STEP( F1, ref d, a, b, c, _in[1] + 0xe8c7b756, 12 ); |
MD5STEP( F1, ref c, d, a, b, _in[2] + 0x242070db, 17 ); |
MD5STEP( F1, ref b, c, d, a, _in[3] + 0xc1bdceee, 22 ); |
MD5STEP( F1, ref a, b, c, d, _in[4] + 0xf57c0faf, 7 ); |
MD5STEP( F1, ref d, a, b, c, _in[5] + 0x4787c62a, 12 ); |
MD5STEP( F1, ref c, d, a, b, _in[6] + 0xa8304613, 17 ); |
MD5STEP( F1, ref b, c, d, a, _in[7] + 0xfd469501, 22 ); |
MD5STEP( F1, ref a, b, c, d, _in[8] + 0x698098d8, 7 ); |
MD5STEP( F1, ref d, a, b, c, _in[9] + 0x8b44f7af, 12 ); |
MD5STEP( F1, ref c, d, a, b, _in[10] + 0xffff5bb1, 17 ); |
MD5STEP( F1, ref b, c, d, a, _in[11] + 0x895cd7be, 22 ); |
MD5STEP( F1, ref a, b, c, d, _in[12] + 0x6b901122, 7 ); |
MD5STEP( F1, ref d, a, b, c, _in[13] + 0xfd987193, 12 ); |
MD5STEP( F1, ref c, d, a, b, _in[14] + 0xa679438e, 17 ); |
MD5STEP( F1, ref b, c, d, a, _in[15] + 0x49b40821, 22 ); |
|
MD5STEP( F2, ref a, b, c, d, _in[1] + 0xf61e2562, 5 ); |
MD5STEP( F2, ref d, a, b, c, _in[6] + 0xc040b340, 9 ); |
MD5STEP( F2, ref c, d, a, b, _in[11] + 0x265e5a51, 14 ); |
MD5STEP( F2, ref b, c, d, a, _in[0] + 0xe9b6c7aa, 20 ); |
MD5STEP( F2, ref a, b, c, d, _in[5] + 0xd62f105d, 5 ); |
MD5STEP( F2, ref d, a, b, c, _in[10] + 0x02441453, 9 ); |
MD5STEP( F2, ref c, d, a, b, _in[15] + 0xd8a1e681, 14 ); |
MD5STEP( F2, ref b, c, d, a, _in[4] + 0xe7d3fbc8, 20 ); |
MD5STEP( F2, ref a, b, c, d, _in[9] + 0x21e1cde6, 5 ); |
MD5STEP( F2, ref d, a, b, c, _in[14] + 0xc33707d6, 9 ); |
MD5STEP( F2, ref c, d, a, b, _in[3] + 0xf4d50d87, 14 ); |
MD5STEP( F2, ref b, c, d, a, _in[8] + 0x455a14ed, 20 ); |
MD5STEP( F2, ref a, b, c, d, _in[13] + 0xa9e3e905, 5 ); |
MD5STEP( F2, ref d, a, b, c, _in[2] + 0xfcefa3f8, 9 ); |
MD5STEP( F2, ref c, d, a, b, _in[7] + 0x676f02d9, 14 ); |
MD5STEP( F2, ref b, c, d, a, _in[12] + 0x8d2a4c8a, 20 ); |
|
MD5STEP( F3, ref a, b, c, d, _in[5] + 0xfffa3942, 4 ); |
MD5STEP( F3, ref d, a, b, c, _in[8] + 0x8771f681, 11 ); |
MD5STEP( F3, ref c, d, a, b, _in[11] + 0x6d9d6122, 16 ); |
MD5STEP( F3, ref b, c, d, a, _in[14] + 0xfde5380c, 23 ); |
MD5STEP( F3, ref a, b, c, d, _in[1] + 0xa4beea44, 4 ); |
MD5STEP( F3, ref d, a, b, c, _in[4] + 0x4bdecfa9, 11 ); |
MD5STEP( F3, ref c, d, a, b, _in[7] + 0xf6bb4b60, 16 ); |
MD5STEP( F3, ref b, c, d, a, _in[10] + 0xbebfbc70, 23 ); |
MD5STEP( F3, ref a, b, c, d, _in[13] + 0x289b7ec6, 4 ); |
MD5STEP( F3, ref d, a, b, c, _in[0] + 0xeaa127fa, 11 ); |
MD5STEP( F3, ref c, d, a, b, _in[3] + 0xd4ef3085, 16 ); |
MD5STEP( F3, ref b, c, d, a, _in[6] + 0x04881d05, 23 ); |
MD5STEP( F3, ref a, b, c, d, _in[9] + 0xd9d4d039, 4 ); |
MD5STEP( F3, ref d, a, b, c, _in[12] + 0xe6db99e5, 11 ); |
MD5STEP( F3, ref c, d, a, b, _in[15] + 0x1fa27cf8, 16 ); |
MD5STEP( F3, ref b, c, d, a, _in[2] + 0xc4ac5665, 23 ); |
|
MD5STEP( F4, ref a, b, c, d, _in[0] + 0xf4292244, 6 ); |
MD5STEP( F4, ref d, a, b, c, _in[7] + 0x432aff97, 10 ); |
MD5STEP( F4, ref c, d, a, b, _in[14] + 0xab9423a7, 15 ); |
MD5STEP( F4, ref b, c, d, a, _in[5] + 0xfc93a039, 21 ); |
MD5STEP( F4, ref a, b, c, d, _in[12] + 0x655b59c3, 6 ); |
MD5STEP( F4, ref d, a, b, c, _in[3] + 0x8f0ccc92, 10 ); |
MD5STEP( F4, ref c, d, a, b, _in[10] + 0xffeff47d, 15 ); |
MD5STEP( F4, ref b, c, d, a, _in[1] + 0x85845dd1, 21 ); |
MD5STEP( F4, ref a, b, c, d, _in[8] + 0x6fa87e4f, 6 ); |
MD5STEP( F4, ref d, a, b, c, _in[15] + 0xfe2ce6e0, 10 ); |
MD5STEP( F4, ref c, d, a, b, _in[6] + 0xa3014314, 15 ); |
MD5STEP( F4, ref b, c, d, a, _in[13] + 0x4e0811a1, 21 ); |
MD5STEP( F4, ref a, b, c, d, _in[4] + 0xf7537e82, 6 ); |
MD5STEP( F4, ref d, a, b, c, _in[11] + 0xbd3af235, 10 ); |
MD5STEP( F4, ref c, d, a, b, _in[2] + 0x2ad7d2bb, 15 ); |
MD5STEP( F4, ref b, c, d, a, _in[9] + 0xeb86d391, 21 ); |
|
buf[0] += a; |
buf[1] += b; |
buf[2] += c; |
buf[3] += d; |
} |
|
/* |
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious |
* initialization constants. |
*/ |
static void MD5Init( MD5Context ctx ) |
{ |
ctx.isInit = true; |
ctx.buf[0] = 0x67452301; |
ctx.buf[1] = 0xefcdab89; |
ctx.buf[2] = 0x98badcfe; |
ctx.buf[3] = 0x10325476; |
ctx.bits[0] = 0; |
ctx.bits[1] = 0; |
} |
|
/* |
* Update context to reflect the concatenation of another buffer full |
* of bytes. |
*/ |
static void MD5Update( MD5Context pCtx, byte[] buf, int len ) |
{ |
|
MD5Context ctx = (MD5Context)pCtx; |
int t; |
|
/* Update bitcount */ |
|
t = (int)ctx.bits[0]; |
if ( ( ctx.bits[0] = (u32)( t + ( (u32)len << 3 ) ) ) < t ) |
ctx.bits[1]++; /* Carry from low to high */ |
ctx.bits[1] += (u32)( len >> 29 ); |
|
t = ( t >> 3 ) & 0x3f; /* Bytes already in shsInfo.data */ |
|
/* Handle any leading odd-sized chunks */ |
|
int _buf = 0; // Offset into buffer |
int p = t; //Offset into ctx._in |
if ( t != 0 ) |
{ |
//byte p = (byte)ctx._in + t; |
t = 64 - t; |
if ( len < t ) |
{ |
Buffer.BlockCopy( buf, _buf, ctx._in, p, len );// memcpy( p, buf, len ); |
return; |
} |
Buffer.BlockCopy( buf, _buf, ctx._in, p, t ); //memcpy( p, buf, t ); |
//byteReverse(ctx._in, 16); |
MD5Transform( ctx.buf, ctx._in ); |
_buf += t;// buf += t; |
len -= t; |
} |
|
/* Process data in 64-byte chunks */ |
|
while ( len >= 64 ) |
{ |
Buffer.BlockCopy( buf, _buf, ctx._in, 0, 64 );//memcpy( ctx._in, buf, 64 ); |
//byteReverse(ctx._in, 16); |
MD5Transform( ctx.buf, ctx._in ); |
_buf += 64;// buf += 64; |
len -= 64; |
} |
|
/* Handle any remaining bytes of data. */ |
|
Buffer.BlockCopy( buf, _buf, ctx._in, 0, len ); //memcpy( ctx._in, buf, len ); |
} |
|
/* |
* Final wrapup - pad to 64-byte boundary with the bit pattern |
* 1 0* (64-bit count of bits processed, MSB-first) |
*/ |
|
static void MD5Final( byte[] digest, MD5Context pCtx ) |
{ |
MD5Context ctx = pCtx; |
int count; |
int p; |
|
/* Compute number of bytes mod 64 */ |
count = (int)( ctx.bits[0] >> 3 ) & 0x3F; |
|
/* Set the first char of padding to 0x80. This is safe since there is |
always at least one byte free */ |
p = count; |
ctx._in[p++] = 0x80; |
|
/* Bytes of padding needed to make 64 bytes */ |
count = 64 - 1 - count; |
|
/* Pad out to 56 mod 64 */ |
if ( count < 8 ) |
{ |
/* Two lots of padding: Pad the first block to 64 bytes */ |
Array.Clear( ctx._in, p, count );//memset(p, 0, count); |
//byteReverse( ctx._in, 16 ); |
MD5Transform( ctx.buf, ctx._in ); |
|
/* Now fill the next block with 56 bytes */ |
Array.Clear( ctx._in, 0, 56 );//memset(ctx._in, 0, 56); |
} |
else |
{ |
/* Pad block to 56 bytes */ |
Array.Clear( ctx._in, p, count - 8 );//memset(p, 0, count-8); |
} |
//byteReverse( ctx._in, 14 ); |
|
/* Append length in bits and transform */ |
ctx._in[14] = (byte)ctx.bits[0]; |
ctx._in[15] = (byte)ctx.bits[1]; |
|
MD5Transform( ctx.buf, ctx._in ); |
//byteReverse( ctx.buf, 4 ); |
Buffer.BlockCopy( ctx.buf, 0, digest, 0, 16 );//memcpy(digest, ctx.buf, 16); |
//memset(ctx, 0, sizeof(ctx)); /* In case it is sensitive */ |
Array.Clear( ctx._in, 0, ctx._in.Length ); |
Array.Clear( ctx.bits, 0, ctx.bits.Length ); |
Array.Clear( ctx.buf, 0, ctx.buf.Length ); |
ctx._Mem = null; |
} |
|
/* |
** Convert a 128-bit MD5 digest into a 32-digit base-16 number. |
*/ |
static void DigestToBase16( byte[] digest, byte[] zBuf ) |
{ |
string zEncode = "0123456789abcdef"; |
int i, j; |
|
for ( j = i = 0; i < 16; i++ ) |
{ |
int a = digest[i]; |
zBuf[j++] = (byte)zEncode[( a >> 4 ) & 0xf]; |
zBuf[j++] = (byte)zEncode[a & 0xf]; |
} |
if ( j < zBuf.Length ) |
zBuf[j] = 0; |
} |
|
|
/* |
** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers |
** each representing 16 bits of the digest and separated from each |
** other by a "-" character. |
*/ |
//static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){ |
// int i, j; |
// unsigned int x; |
// for(i=j=0; i<16; i+=2){ |
// x = digest[i]*256 + digest[i+1]; |
// if( i>0 ) zDigest[j++] = '-'; |
// sprintf(&zDigest[j], "%05u", x); |
// j += 5; |
// } |
// zDigest[j] = 0; |
//} |
|
/* |
** A TCL command for md5. The argument is the text to be hashed. The |
** Result is the hash in base64. |
*/ |
static int md5_cmd( object cd, Tcl_Interp interp, int argc, Tcl_Obj[] argv ) |
{ |
MD5Context ctx = new MD5Context(); |
byte[] digest = new byte[16]; |
byte[] zBuf = new byte[32]; |
|
|
if ( argc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" TEXT\"" ); |
return TCL.TCL_ERROR; |
} |
MD5Init( ctx ); |
MD5Update( ctx, Encoding.UTF8.GetBytes( argv[1].ToString() ), Encoding.UTF8.GetByteCount( argv[1].ToString() ) ); |
MD5Final( digest, ctx ); |
DigestToBase16( digest, zBuf ); |
TCL.Tcl_AppendResult( interp, Encoding.UTF8.GetString( zBuf, 0, zBuf.Length ) ); |
return TCL.TCL_OK; |
} |
|
|
/* |
** A TCL command to take the md5 hash of a file. The argument is the |
** name of the file. |
*/ |
static int md5file_cmd( object cd, Tcl_Interp interp, int argc, Tcl_Obj[] argv ) |
{ |
StreamReader _in = null; |
byte[] digest = new byte[16]; |
StringBuilder zBuf = new StringBuilder( 10240 ); |
|
if ( argc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" FILENAME\"", 0 ); |
return TCL.TCL_ERROR; |
} |
Debugger.Break(); // TODO -- _in = fopen( argv[1], "rb" ); |
if ( _in == null ) |
{ |
TCL.Tcl_AppendResult( interp, "unable to open file \"", argv[1], |
"\" for reading", 0 ); |
return TCL.TCL_ERROR; |
} |
Debugger.Break(); // TODO |
//MD5Init( ctx ); |
//for(;;){ |
// int n; |
// n = fread(zBuf, 1, zBuf.Capacity, _in); |
// if( n<=0 ) break; |
// MD5Update(ctx, zBuf.ToString(), (unsigned)n); |
//} |
//fclose(_in); |
//MD5Final(digest, ctx); |
// DigestToBase16(digest, zBuf); |
//Tcl_AppendResult( interp, zBuf ); |
return TCL.TCL_OK; |
} |
|
/* |
** Register the four new TCL commands for generating MD5 checksums |
** with the TCL interpreter. |
*/ |
static public int Md5_Init( Tcl_Interp interp ) |
{ |
TCL.Tcl_CreateCommand( interp, "md5", md5_cmd, null, null ); |
//Tcl_CreateCommand(interp, "md5-10x8", (Tcl_CmdProc)md5_cmd, |
// MD5DigestToBase10x8, 0); |
|
TCL.Tcl_CreateCommand( interp, "md5file", md5file_cmd, null, null ); |
|
//Tcl_CreateCommand(interp, "md5file-10x8", (Tcl_CmdProc)md5file_cmd, |
// MD5DigestToBase10x8, 0); |
return TCL.TCL_OK; |
} |
#endif //* defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) */ |
|
#if (SQLITE_TEST) |
/* |
** During testing, the special md5sum() aggregate function is available. |
** inside SQLite. The following routines implement that function. |
*/ |
static void md5step( sqlite3_context context, int argc, sqlite3_value[] argv ) |
{ |
MD5Context p = null; |
int i; |
if ( argc < 1 ) |
return; |
Mem pMem = sqlite3_aggregate_context( context, 1 );//sizeof(*p)); |
if ( pMem._MD5Context == null ) |
{ |
pMem._MD5Context = new MD5Context(); |
( (MD5Context)pMem._MD5Context )._Mem = pMem; |
} |
p = (MD5Context)pMem._MD5Context; |
if ( p == null ) |
return; |
if ( !p.isInit ) |
{ |
MD5Init( p ); |
} |
for ( i = 0; i < argc; i++ ) |
{ |
byte[] zData = sqlite3_value_text( argv[i] ) == null ? null : Encoding.UTF8.GetBytes( sqlite3_value_text( argv[i] ) ); |
if ( zData != null ) |
{ |
MD5Update( p, zData, zData.Length ); |
} |
} |
} |
|
static void md5finalize( sqlite3_context context ) |
{ |
MD5Context p; |
byte[] digest = new byte[16]; |
byte[] zBuf = new byte[33]; |
Mem pMem = sqlite3_aggregate_context( context, 0 ); |
if ( pMem != null ) |
{ |
p = (MD5Context)pMem._MD5Context; |
MD5Final( digest, p ); |
} |
DigestToBase16( digest, zBuf ); |
sqlite3_result_text( context, Encoding.UTF8.GetString( zBuf, 0, zBuf.Length ), -1, SQLITE_TRANSIENT ); |
} |
|
static int Md5_Register( sqlite3 db, ref string dummy1, sqlite3_api_routines dummy2 ) |
{ |
int rc = sqlite3_create_function( db, "md5sum", -1, SQLITE_UTF8, 0, null, |
md5step, md5finalize ); |
sqlite3_overload_function( db, "md5sum", -1 ); /* To exercise this API */ |
return rc; |
} |
|
#endif //* defined(SQLITE_TEST) */ |
|
|
/* |
** If the macro TCLSH is one, then put in code this for the |
** "main" routine that will initialize Tcl and take input from |
** standard input, or if a file is named on the command line |
** the TCL interpreter reads and evaluates that file. |
*/ |
#if TCLSH//==1 |
//static char zMainloop[] = |
// "set line {}\n" |
// "while {![eof stdin]} {\n" |
// "if {$line!=\"\"} {\n" |
// "puts -nonewline \"> \"\n" |
// "} else {\n" |
// "puts -nonewline \"% \"\n" |
// "}\n" |
// "flush stdout\n" |
// "append line [gets stdin]\n" |
// "if {[info complete $line]} {\n" |
// "if {[catch {uplevel #0 $line} result]} {\n" |
// "puts stderr \"Error: $result\"\n" |
// "} elseif {$result!=\"\"} {\n" |
// "puts $result\n" |
// "}\n" |
// "set line {}\n" |
// "} else {\n" |
// "append line \\n\n" |
// "}\n" |
// "}\n" |
//; |
#endif |
|
//#if TCLSH==2 |
//static char zMainloop[] = |
//#include "spaceanal_tcl.h" |
//; |
//#endif |
//#define TCLSH_MAIN main /* Needed to fake out mktclapp */ |
#if SQLITE_TEST |
//static void init_all(Tcl_Interp ); |
static int init_all_cmd( |
ClientData cd, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
|
Tcl_Interp slave; |
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "SLAVE" ); |
return TCL.TCL_ERROR; |
} |
|
slave = null;// TCL.Tcl_GetSlave( interp, TCL.Tcl_GetString( objv[1] ) ); |
if ( slave == null ) |
{ |
return TCL.TCL_ERROR; |
} |
|
init_all( slave ); |
return TCL.TCL_OK; |
} |
#endif |
|
/* |
** Configure the interpreter passed as the first argument to have access |
** to the commands and linked variables that make up: |
** |
** * the [sqlite3] extension itself, |
** |
** * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and |
** |
** * If SQLITE_TEST is set, the various test interfaces used by the Tcl |
** test suite. |
*/ |
static void init_all( Tcl_Interp interp ) |
{ |
Sqlite3_Init( interp ); |
#if (SQLITE_TEST) || (SQLITE_TCLMD5) |
Md5_Init( interp ); |
#endif |
#if SQLITE_TEST |
//{ |
//extern int Sqliteconfig_Init(Tcl_Interp); |
//extern int Sqlitetest1_Init(Tcl_Interp); |
//extern int Sqlitetest2_Init(Tcl_Interp); |
//extern int Sqlitetest3_Init(Tcl_Interp); |
//extern int Sqlitetest4_Init(Tcl_Interp); |
//extern int Sqlitetest5_Init(Tcl_Interp); |
//extern int Sqlitetest6_Init(Tcl_Interp); |
//extern int Sqlitetest7_Init(Tcl_Interp); |
//extern int Sqlitetest8_Init(Tcl_Interp); |
//extern int Sqlitetest9_Init(Tcl_Interp); |
//extern int Sqlitetestasync_Init(Tcl_Interp); |
//extern int Sqlitetest_autoext_Init(Tcl_Interp); |
//extern int Sqlitetest_demovfs_Init(Tcl_Interp ); |
//extern int Sqlitetest_func_Init(Tcl_Interp); |
//extern int Sqlitetest_hexio_Init(Tcl_Interp); |
//extern int Sqlitetest_malloc_Init(Tcl_Interp); |
//extern int Sqlitetest_mutex_Init(Tcl_Interp); |
//extern int Sqlitetestschema_Init(Tcl_Interp); |
//extern int Sqlitetestsse_Init(Tcl_Interp); |
//extern int Sqlitetesttclvar_Init(Tcl_Interp); |
//extern int SqlitetestThread_Init(Tcl_Interp); |
//extern int SqlitetestOnefile_Init(); |
//extern int SqlitetestOsinst_Init(Tcl_Interp); |
//extern int Sqlitetestbackup_Init(Tcl_Interp); |
//extern int Sqlitetestintarray_Init(Tcl_Interp); |
//extern int Sqlitetestvfs_Init(Tcl_Interp ); |
//extern int SqlitetestStat_Init(Tcl_Interp); |
//extern int Sqlitetestrtree_Init(Tcl_Interp); |
//extern int Sqlitequota_Init(Tcl_Interp); |
//extern int Sqlitemultiplex_Init(Tcl_Interp); |
//extern int SqliteSuperlock_Init(Tcl_Interp); |
//extern int SqlitetestSyscall_Init(Tcl_Interp); |
//extern int Sqlitetestfuzzer_Init(Tcl_Interp); |
//extern int Sqlitetestwholenumber_Init(Tcl_Interp); |
|
#if (SQLITE_ENABLE_FTS3) || (SQLITE_ENABLE_FTS4) |
//extern int Sqlitetestfts3_Init(Tcl_Interp interp); |
#endif |
|
#if SQLITE_ENABLE_ZIPVFS |
// extern int Zipvfs_Init(Tcl_Interp); |
// Zipvfs_Init(interp); |
#endif |
|
Sqliteconfig_Init( interp ); |
Sqlitetest1_Init( interp ); |
Sqlitetest2_Init( interp ); |
Sqlitetest3_Init( interp ); |
|
//Threads not implemented under C# |
//Sqlitetest4_Init(interp); |
|
//TODO implemented under C# |
//Sqlitetest5_Init(interp); |
|
//Simulated Crashtests not implemented under C# |
//Sqlitetest6_Init(interp); |
|
//client/server version (Unix Only) not implemented under C# |
//Sqlitetest7_Init(interp); |
|
//virtual table interface not implemented under C# |
//Sqlitetest8_Init(interp); |
|
Sqlitetest9_Init( interp ); |
|
//asynchronous IO extension interface not implemented under C# |
//Sqlitetestasync_Init(interp); |
|
//sqlite3_auto_extension() function not implemented under C# |
//Sqlitetest_autoext_Init(interp); |
|
//VFS not implemented under C# |
//Sqlitetest_demovfs_Init(interp); |
|
Sqlitetest_func_Init( interp ); |
Sqlitetest_hexio_Init( interp ); |
Sqlitetest_malloc_Init( interp ); |
Sqlitetest_mutex_Init( interp ); |
|
//virtual table interfaces not implemented under C# |
//Sqlitetestschema_Init(interp); |
|
//virtual table interfaces not implemented under C# |
//Sqlitetesttclvar_Init(interp); |
|
//Threads not implemented under C# |
//SqlitetestThread_Init(interp); |
|
//VFS not implemented under C# |
//SqlitetestOnefile_Init(interp); |
|
//VFS not implemented under C# |
//SqlitetestOsinst_Init(interp); |
|
Sqlitetestbackup_Init( interp ); |
|
//virtual table interfaces not implemented under C# |
//Sqlitetestintarray_Init(interp); |
|
//VFS not implemented under C# |
//Sqlitetestvfs_Init(interp); |
|
//virtual table interfaces not implemented under C# |
//SqlitetestStat_Init(interp); |
//Sqlitetestrtree_Init( interp ); |
//Sqlitequota_Init( interp ); |
//Sqlitemultiplex_Init( interp ); |
//SqliteSuperlock_Init( interp ); |
//SqlitetestSyscall_Init( interp ); |
Sqlitetestfuzzer_Init( interp ); |
//Sqlitetestwholenumber_Init( interp ); |
|
#if (SQLITE_ENABLE_FTS3) || (SQLITE_ENABLE_FTS4) |
//Sqlitetestfts3_Init(interp); |
#endif |
TCL.Tcl_CreateObjCommand( interp, "load_testfixture_extensions", init_all_cmd, 0, null ); |
|
#if SQLITE_SSE |
Sqlitetestsse_Init(interp); |
#endif |
} |
#endif |
} |
|
#if FALSE |
//#define TCLSH_MAIN main /* Needed to fake out mktclapp */ |
int TCLSH_MAIN(int argc, char **argv){ |
Tcl_Interp interp; |
|
/* Call sqlite3_shutdown() once before doing anything else. This is to |
** test that sqlite3_shutdown() can be safely called by a process before |
** sqlite3_initialize() is. */ |
sqlite3_shutdown(); |
|
#if TCLSH//TCLSH==2 |
sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); |
#endif |
Tcl_FindExecutable(argv[0]); |
|
interp = TCL.Tcl_CreateInterp(); |
init_all(interp); |
if( argc>=2 ){ |
int i; |
char zArgc[32]; |
sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH)); |
Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY); |
Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY); |
Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY); |
for(i=3-TCLSH; i<argc; i++){ |
Tcl_SetVar(interp, "argv", argv[i], |
TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE); |
} |
if( TCLSH==1 && Tcl_EvalFile(interp, argv[1])!=TCL_OK ){ |
string zInfo = TCL.Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); |
if( zInfo==0 ) zInfo = TCL.Tcl_GetStringResult(interp); |
fprintf(stderr,"%s: %s\n", *argv, zInfo); |
return 1; |
} |
} |
if( TCLSH==2 || argc<=1 ){ |
Tcl_GlobalEval(interp, zMainloop); |
} |
return 0; |
} |
#endif |
#endif // * TCLSH */ |
#endif // NO_TCL |
} |
|
/trunk/testfixture/src/test1_c.cs |
@@ -0,0 +1,6843 @@ |
using System; |
using System.Diagnostics; |
using System.Text; |
|
using i64 = System.Int64; |
using u32 = System.UInt32; |
namespace Community.CsharpSqlite |
{ |
#if TCLSH |
using tcl.lang; |
using ClientData = System.Object; |
using sqlite3_int64 = System.Int64; |
using sqlite3_stmt = Sqlite3.Vdbe; |
using sqlite3_u3264 = System.UInt64; |
using sqlite3_value = Sqlite3.Mem; |
using Tcl_Interp = tcl.lang.Interp; |
using Tcl_Obj = tcl.lang.TclObject; |
|
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 all sorts of SQLite interfaces. 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 "tcl.h" |
//#include <stdlib.h> |
//#include <string.h> |
|
/* |
** This is a copy of the first part of the SqliteDb structure in |
** tclsqlite.c. We need it here so that the get_sqlite_pointer routine |
** can extract the sqlite3* pointer from an existing Tcl SQLite |
** connection. |
*/ |
//struct SqliteDb { |
// sqlite3 db=null; |
//}; |
|
/* |
** Convert text generated by the "%p" conversion format back into |
** a pointer. |
*/ |
static int testHexToInt( int h ) |
{ |
if ( h >= '0' && h <= '9' ) |
{ |
return h - '0'; |
} |
else if ( h >= 'a' && h <= 'f' ) |
{ |
return h - 'a' + 10; |
} |
else |
{ |
Debug.Assert( h >= 'A' && h <= 'F' ); |
return h - 'A' + 10; |
} |
} |
static object sqlite3TestTextToPtr( Tcl_Interp interp, string z ) |
{ |
//object p ; |
//var v = new u64[1]; |
//u32 v2; |
//int zIndex = 0; |
//if ( z[0] == '0' && z[1] == 'x' ) |
//{ |
// zIndex += 2; |
//} |
//v[0] = 0; |
//while ( zIndex < z.Length )* z ) |
//{ |
// v[0] = ( v[0] << 4 ) + (ulong)testHexToInt( z[zIndex] ); |
// zIndex++; |
//} |
//if ( sizeof( object ) == sizeof( u64 ) ) |
//{ |
// Marshal.Copy( v, 0, (IntPtr)p, 1 );// memcpy( &p, v, sizeof( p ) ); |
//} |
//else |
//{ |
// Debug.Assert( sizeof( p ) == sizeof( v2 ) ); |
// v2 = (u32)v; |
// memcpy( &p, v2, sizeof( p ) ); |
//} |
WrappedCommand cmdInfo = new WrappedCommand(); |
if ( TCL.Tcl_GetCommandInfo( interp, z, out cmdInfo ) || cmdInfo == null ) |
{ |
return null; |
} |
else |
{ |
return cmdInfo.objClientData; |
} |
} |
|
|
/* |
** A TCL command that returns the address of the sqlite* pointer |
** for an sqlite connection instance. Bad things happen if the |
** input is not an sqlite connection. |
*/ |
static int get_sqlite_pointer( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
SqliteDb p; |
WrappedCommand cmdInfo = null; |
//string zBuf ;//[100]; |
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "SQLITE-CONNECTION" ); |
return TCL.TCL_ERROR; |
} |
if ( TCL.Tcl_GetCommandInfo( interp, objv[1].ToString(), out cmdInfo ) ) |
{ |
TCL.Tcl_AppendResult( interp, "command not found: ", |
TCL.Tcl_GetString( objv[1] ), null ); |
return TCL.TCL_ERROR; |
} |
//p = (SqliteDb)cmdInfo.objclientdata; |
//zBuf = p.db.GetHashCode().ToString(); |
//sqlite3_snprintf( zBuf, "%p", p.db ); |
//if( strncmp(zBuf,"0x",2) ){ |
// sqlite3_snprintf(zBuf, "0x%p", p.db); |
//} |
//TCL.Tcl_AppendResult(interp, zBuf,null ); |
TCL.Tcl_AppendResult( interp, objv[1].ToString() ); |
return TCL.TCL_OK; |
} |
|
/* |
** Decode a pointer to an sqlite3 object. |
*/ |
static int getDbPointer( Tcl_Interp interp, string zA, out sqlite3 ppDb ) |
{ |
SqliteDb p; |
WrappedCommand cmdInfo = new WrappedCommand(); |
if ( !TCL.Tcl_GetCommandInfo( interp, zA, out cmdInfo ) ) |
{ |
if ( cmdInfo == null ) |
{ |
ppDb = new sqlite3(); |
} |
else |
{ |
p = (SqliteDb)cmdInfo.objClientData; |
ppDb = p.db; |
} |
} |
else |
{ |
ppDb = null; |
} |
return TCL.TCL_OK; |
} |
|
|
static string sqlite3TestErrorName( int rc ) |
{ |
string zName = ""; |
switch ( rc ) |
{ |
case SQLITE_OK: |
zName = "SQLITE_OK"; |
break; |
case SQLITE_ERROR: |
zName = "SQLITE_ERROR"; |
break; |
case SQLITE_INTERNAL: |
zName = "SQLITE_INTERNAL"; |
break; |
case SQLITE_PERM: |
zName = "SQLITE_PERM"; |
break; |
case SQLITE_ABORT: |
zName = "SQLITE_ABORT"; |
break; |
case SQLITE_BUSY: |
zName = "SQLITE_BUSY"; |
break; |
case SQLITE_LOCKED: |
zName = "SQLITE_LOCKED"; |
break; |
case SQLITE_LOCKED_SHAREDCACHE: |
zName = "SQLITE_LOCKED_SHAREDCACHE"; |
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_NOTFOUND: |
zName = "SQLITE_NOTFOUND"; |
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_SCHEMA: |
zName = "SQLITE_SCHEMA"; |
break; |
case SQLITE_TOOBIG: |
zName = "SQLITE_TOOBIG"; |
break; |
case SQLITE_CONSTRAINT: |
zName = "SQLITE_CONSTRAINT"; |
break; |
case SQLITE_MISMATCH: |
zName = "SQLITE_MISMATCH"; |
break; |
case SQLITE_MISUSE: |
zName = "SQLITE_MISUSE"; |
break; |
case SQLITE_NOLFS: |
zName = "SQLITE_NOLFS"; |
break; |
case SQLITE_AUTH: |
zName = "SQLITE_AUTH"; |
break; |
case SQLITE_FORMAT: |
zName = "SQLITE_FORMAT"; |
break; |
case SQLITE_RANGE: |
zName = "SQLITE_RANGE"; |
break; |
case SQLITE_NOTADB: |
zName = "SQLITE_NOTADB"; |
break; |
case SQLITE_ROW: |
zName = "SQLITE_ROW"; |
break; |
case SQLITE_DONE: |
zName = "SQLITE_DONE"; |
break; |
case SQLITE_IOERR_READ: |
zName = "SQLITE_IOERR_READ"; |
break; |
case SQLITE_IOERR_SHORT_READ: |
zName = "SQLITE_IOERR_SHORT_READ"; |
break; |
case SQLITE_IOERR_WRITE: |
zName = "SQLITE_IOERR_WRITE"; |
break; |
case SQLITE_IOERR_FSYNC: |
zName = "SQLITE_IOERR_FSYNC"; |
break; |
case SQLITE_IOERR_DIR_FSYNC: |
zName = "SQLITE_IOERR_DIR_FSYNC"; |
break; |
case SQLITE_IOERR_TRUNCATE: |
zName = "SQLITE_IOERR_TRUNCATE"; |
break; |
case SQLITE_IOERR_FSTAT: |
zName = "SQLITE_IOERR_FSTAT"; |
break; |
case SQLITE_IOERR_UNLOCK: |
zName = "SQLITE_IOERR_UNLOCK"; |
break; |
case SQLITE_IOERR_RDLOCK: |
zName = "SQLITE_IOERR_RDLOCK"; |
break; |
case SQLITE_IOERR_DELETE: |
zName = "SQLITE_IOERR_DELETE"; |
break; |
case SQLITE_IOERR_BLOCKED: |
zName = "SQLITE_IOERR_BLOCKED"; |
break; |
case SQLITE_IOERR_NOMEM: |
zName = "SQLITE_IOERR_NOMEM"; |
break; |
case SQLITE_IOERR_ACCESS: |
zName = "SQLITE_IOERR_ACCESS"; |
break; |
case SQLITE_IOERR_CHECKRESERVEDLOCK: |
zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; |
break; |
case SQLITE_IOERR_LOCK: |
zName = "SQLITE_IOERR_LOCK"; |
break; |
case SQLITE_CORRUPT_VTAB: |
zName = "SQLITE_CORRUPT_VTAB"; |
break; |
case SQLITE_READONLY_RECOVERY: |
zName = "SQLITE_READONLY_RECOVERY"; |
break; |
case SQLITE_READONLY_CANTLOCK: |
zName = "SQLITE_READONLY_CANTLOCK"; |
break; |
default: |
zName = "SQLITE_Unknown"; |
break; |
} |
return zName; |
} |
//#define t1ErrorName sqlite3TestErrorName |
static string t1ErrorName( int i ) |
{ |
return sqlite3TestErrorName( i ); |
} |
/* |
** Convert an sqlite3_stmt* into an sqlite3*. This depends on the |
** fact that the sqlite3* is the first field in the Vdbe structure. |
*/ |
//#define StmtToDb(X) sqlite3_db_handle(X) |
static sqlite3 StmtToDb( Vdbe v ) |
{ |
return sqlite3_db_handle( v ); |
} |
|
/* |
** Check a return value to make sure it agrees with the results |
** from sqlite3_errcode. |
*/ |
static int sqlite3TestErrCode( Tcl_Interp interp, sqlite3 db, int rc ) |
{ |
if ( sqlite3_threadsafe() == 0 && rc != SQLITE_MISUSE && rc != SQLITE_OK |
&& sqlite3_errcode( db ) != rc ) |
{ |
StringBuilder zBuf = new StringBuilder( 200 );//char zBuf[200]; |
int r2 = sqlite3_errcode( db ); |
sqlite3_snprintf( 200, zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)", |
sqlite3TestErrorName( rc ), rc, sqlite3TestErrorName( r2 ), r2 );//t1ErrorName( rc ), rc, t1ErrorName( r2 ), r2 ); |
TCL.Tcl_ResetResult( interp ); |
TCL.Tcl_AppendResult( interp, zBuf.ToString() ); |
return 1; |
} |
return 0; |
} |
|
/* |
** Decode a pointer to an sqlite3_stmt object. |
*/ |
static int getStmtPointer( |
Tcl_Interp interp, |
string zArg, |
out sqlite3_stmt ppStmt |
) |
{ |
ppStmt = (sqlite3_stmt)sqlite3TestTextToPtr( interp, zArg ); |
WrappedCommand cmdInfo = new WrappedCommand(); |
TCL.Tcl_GetCommandInfo( interp, zArg, out cmdInfo ); |
ppStmt = cmdInfo == null ? null : (sqlite3_stmt)cmdInfo.objClientData; |
|
return TCL.TCL_OK; |
} |
|
/* |
** Generate a text representation of a pointer that can be understood |
** by the getDbPointer and getVmPointer routines above. |
** |
** The problem is, on some machines (Solaris) if you do a printf with |
** "%p" you cannot turn around and do a scanf with the same "%p" and |
** get your pointer back. You have to prepend a "0x" before it will |
** work. Or at least that is what is reported to me (drh). But this |
** behavior varies from machine to machine. The solution used her is |
** to test the string right after it is generated to see if it can be |
** understood by scanf, and if not, try prepending an "0x" to see if |
** that helps. If nothing works, a fatal error is generated. |
*/ |
/* |
** Decode a pointer to an sqlite3_stmt object. |
*/ |
|
|
static int sqlite3TestMakePointerStr( Tcl_Interp interp, StringBuilder zPtr, object p ) |
{ |
sqlite3_snprintf( 100, zPtr, "->%p", p ); |
if ( TCL.Tcl_CreateCommandPointer( interp, zPtr, p ) ) |
{ |
return TCL.TCL_ERROR; |
} |
return TCL.TCL_OK; |
} |
|
/* |
** The callback routine for sqlite3_exec_printf(). |
*/ |
static int exec_printf_cb( object pArg, sqlite3_int64 argc, object p2, object p3 ) |
{ |
string[] name = (string[])p3; |
string[] argv = (string[])p2; |
TclObject str = (TclObject)pArg; |
int i; |
|
if ( TCL.Tcl_DStringLength( str ) == 0 ) |
{ |
for ( i = 0; i < argc; i++ ) |
{ |
TCL.Tcl_DStringAppendElement( str, name[i] != null ? name[i] + " " : "NULL " ); |
} |
} |
string beginbrace = "", endbrace = ""; |
for ( i = 0; i < argc; i++ ) |
{ |
if ( argc > 1 ) |
{ |
if ( Util.scanElement( null, argv[i].ToString() ) != 0 ) |
{ |
beginbrace = "{"; |
endbrace = "}"; |
} |
else |
{ |
beginbrace = ""; |
endbrace = ""; |
} |
} |
TCL.Tcl_DStringAppendElement( str, argv[i] != null ? beginbrace + argv[i] + endbrace + ( i < argc - 1 ? " " : "" ) : "NULL" ); |
} |
return 0; |
} |
|
/* |
** The I/O tracing callback. |
*/ |
#if !(SQLITE_OMIT_TRACE) && TRACE |
//static FILE *iotrace_file = 0; |
//static void io_trace_callback(string zFormat, ...){ |
// va_list ap; |
// va_start(ap, zFormat); |
// vfprintf(iotrace_file, zFormat, ap); |
// va_end(ap); |
// fflush(iotrace_file); |
//} |
#endif |
|
/* |
** Usage: io_trace FILENAME |
** |
** Turn I/O tracing on or off. If FILENAME is not an empty string, |
** I/O tracing begins going into FILENAME. If FILENAME is an empty |
** string, I/O tracing is turned off. |
*/ |
//static int test_io_trace( |
// object NotUsed, |
// Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
// int argc, /* Number of arguments */ |
// Tcl_Obj[] argv /* Text of each argument */ |
//){ |
#if !(SQLITE_OMIT_TRACE) && (TRACE) |
// if( argc!=2 ){ |
// TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
// " FILENAME\"", 0); |
// return TCL.TCL_ERROR; |
// } |
// if( iotrace_file ){ |
// if( iotrace_file!=stdout && iotrace_file!=stderr ){ |
// fclose(iotrace_file); |
// } |
// iotrace_file = 0; |
// sqlite3IoTrace = 0; |
// } |
// if( argv[1][0] ){ |
// if( strcmp(argv[1],"stdout")==0 ){ |
// iotrace_file = stdout; |
// }else if( strcmp(argv[1],"stderr")==0 ){ |
// iotrace_file = stderr; |
// }else{ |
// iotrace_file = fopen(argv[1], "w"); |
// } |
// sqlite3IoTrace = io_trace_callback; |
// } |
#endif |
// return TCL.TCL_OK; |
//} |
|
|
/* |
** Usage: sqlite3_exec_printf DB FORMAT STRING |
** |
** Invoke the sqlite3_exec_printf() interface using the open database |
** DB. The SQL is the string FORMAT. The format string should contain |
** one %s or %q. STRING is the value inserted into %s or %q. |
*/ |
static int test_exec_printf( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
sqlite3 db = null; |
TclObject str = null; |
int rc; |
string zErr = ""; |
string zSql = ""; |
StringBuilder zBuf = new StringBuilder( 30 ); |
if ( argc != 4 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" DB FORMAT STRING" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
TCL.Tcl_DStringInit( out str ); |
zSql = sqlite3_mprintf( argv[2].ToString(), argv[3].ToString() ); |
rc = sqlite3_exec( db, zSql, (dxCallback)exec_printf_cb, str, ref zErr ); |
sqlite3DbFree( db, ref zSql ); |
sqlite3_snprintf( 30, zBuf, "%d", rc ); |
TCL.Tcl_AppendElement( interp, zBuf ); |
TCL.Tcl_AppendElement( interp, rc == SQLITE_OK ? str.ToString() : zErr ); //TCL.Tcl_DStringValue(ref str) |
TCL.Tcl_DStringFree( ref str ); |
if ( zErr != null ) |
sqlite3DbFree( db, ref zErr ); |
if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
return TCL.TCL_ERROR; |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_exec_hex DB HEX |
** |
** Invoke the sqlite3_exec() on a string that is obtained by translating |
** HEX into ASCII. Most characters are translated as is. %HH becomes |
** a hex character. |
*/ |
static int test_exec_hex( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
sqlite3 db = null; |
TclObject str = null; |
int rc, i, j; |
string zErr = ""; |
string zHex; |
StringBuilder zSql = new StringBuilder( 500 ); |
string zBuf = ""; |
if ( argc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" DB HEX" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
zHex = argv[2].ToString(); |
for ( i = j = 0; j < zHex.Length && zHex[j] != 0; i++, j++ ) |
{ |
if ( zHex[j] == '%' && zHex[j + 2] != 0 && zHex[j + 2] != 0 ) |
{ |
zSql.Append( (char)( ( testHexToInt( zHex[j + 1] ) << 4 ) + testHexToInt( zHex[j + 2] ) ) ); |
j += 2; |
} |
else |
{ |
zSql.Append( zHex[j] ); |
} |
} |
//zSql[i] = '\0'; |
TCL.Tcl_DStringInit( out str ); |
rc = sqlite3_exec( db, zSql.ToString(), (dxCallback)exec_printf_cb, str, ref zErr ); |
zBuf = rc.ToString();// sprintf( zBuf, "%d", rc ); |
TCL.Tcl_AppendElement( interp, zBuf ); |
TCL.Tcl_AppendElement( interp, rc == SQLITE_OK ? str.ToString() : zErr ); |
TCL.Tcl_DStringFree( ref str ); |
// //sqlite3_free(ref zErr); |
if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
return TCL.TCL_ERROR; |
return TCL.TCL_OK; |
} |
|
|
/* |
** Usage: db_enter DB |
** db_leave DB |
** |
** Enter or leave the mutex on a database connection. |
*/ |
static int db_enter( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
sqlite3 db = null; |
if ( argc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" DB" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
sqlite3_mutex_enter( db.mutex ); |
return TCL.TCL_OK; |
} |
static int db_leave( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
sqlite3 db = null; |
if ( argc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" DB" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
sqlite3_mutex_leave( db.mutex ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_exec DB SQL |
** |
** Invoke the sqlite3_exec interface using the open database DB |
*/ |
static int test_exec( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
sqlite3 db = null; |
TclObject str = TclString.newInstance( "" ); |
int rc; |
string zErr = ""; |
string zSql; |
int i, j; |
StringBuilder zBuf = new StringBuilder( 30 ); |
if ( argc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" DB SQL" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
TCL.Tcl_DStringInit( out str ); |
zSql = sqlite3_mprintf( "%s", argv[2].ToString() ); |
StringBuilder sb = new StringBuilder( zSql.Length ); |
for ( i = 0; i < zSql.Length; i++ ) |
{ |
if ( zSql[i] == '%' ) |
{ |
sb.Append( (char)( ( testHexToInt( zSql[i + 1] ) << 4 ) + testHexToInt( zSql[i + 2] ) ) ); |
i += 2; |
} |
else |
sb.Append( zSql[i] ); |
} |
////zSql[j] = 0; |
rc = sqlite3_exec( db, sb.ToString(), exec_printf_cb, str, ref zErr ); |
sqlite3DbFree( db, ref zSql ); |
sqlite3_snprintf( 30, zBuf, "%d", rc ); |
TCL.Tcl_AppendElement( interp, zBuf ); |
TCL.Tcl_AppendElement( interp, rc == SQLITE_OK ? str.ToString() : zErr ); |
//TCL.Tcl_DStringFree(&str); |
if ( zErr != "" ) |
sqlite3DbFree( db, ref zErr ); |
if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
return TCL.TCL_ERROR; |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_exec_nr DB SQL |
** |
** Invoke the sqlite3_exec interface using the open database DB. Discard |
** all results |
*/ |
static int test_exec_nr( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
sqlite3 db = null; |
int rc; |
string zErr = ""; |
if ( argc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" DB SQL" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
rc = sqlite3_exec( db, argv[2].ToString(), null, null, ref zErr ); |
if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
return TCL.TCL_ERROR; |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_mprintf_z_test SEPARATOR ARG0 ARG1 ... |
** |
** Test the %z format of sqlite_mprintf(). Use multiple mprintf() calls to |
** concatenate arg0 through argn using separator as the separator. |
** Return the result. |
*/ |
static int test_mprintf_z( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
string zResult = ""; |
int i; |
|
for ( i = 2; i < argc && ( i == 2 || zResult != "" ); i++ ) |
{ |
zResult = sqlite3_mprintf( "%z%s%s", zResult, argv[1].ToString(), argv[i].ToString() ); |
} |
TCL.Tcl_AppendResult( interp, zResult ); |
//sqlite3DbFree( db, zResult ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_mprintf_n_test STRING |
** |
** Test the %n format of sqlite_mprintf(). Return the length of the |
** input string. |
*/ |
static int test_mprintf_n( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
string zStr; |
int n = 0; |
zStr = sqlite3_mprintf( "%s%n", argv[1].ToString() ); |
n = zStr.Length; |
//sqlite3DbFree( db, zStr ); |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( n ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_snprintf_int SIZE FORMAT INT |
** |
** Test the of sqlite3_snprintf() routine. SIZE is the size of the |
** output buffer in bytes. The maximum size is 100. FORMAT is the |
** format string. INT is a single integer argument. The FORMAT |
** string must require no more than this one integer argument. If |
** You pass in a format string that requires more than one argument, |
** bad things will happen. |
*/ |
static int test_snprintf_int( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
StringBuilder zStr = new StringBuilder( 100 ); |
int n = atoi( argv[1].ToString() ); |
string zFormat = argv[2].ToString(); |
int a1 = atoi( argv[3].ToString() ); |
if ( n > zStr.Capacity ) |
n = zStr.Capacity;// sizeof( zStr ); |
zStr = new StringBuilder( "abcdefghijklmnopqrstuvwxyz" ); |
sqlite3_snprintf( n, zStr, zFormat, a1 ); |
TCL.Tcl_AppendResult( interp, zStr ); |
return TCL.TCL_OK; |
} |
|
#if !SQLITE_OMIT_GET_TABLE |
/* |
** Usage: sqlite3_get_table_printf DB FORMAT STRING ?--no-counts? |
** |
** Invoke the sqlite3_get_table_printf() interface using the open database |
** DB. The SQL is the string FORMAT. The format string should contain |
** one %s or %q. STRING is the value inserted into %s or %q. |
*/ |
static int test_get_table_printf( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
){ |
sqlite3 db=null; |
TCL.Tcl_DString str; |
int rc; |
string zErr = 0; |
int nRow, nCol; |
char **aResult; |
int i; |
char zBuf[30]; |
string zSql; |
int resCount = -1; |
if( argc==5 ){ |
if( TCL.Tcl_GetInt(interp, argv[4], out resCount) ) return TCL.TCL_ERROR; |
} |
if( argc!=4 && argc!=5 ){ |
TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
" DB FORMAT STRING ?COUNT?", 0); |
return TCL.TCL_ERROR; |
} |
if( getDbPointer(interp, argv[1].ToString(), out db) !=0) return TCL.TCL_ERROR; |
TCL.Tcl_DStringInit(&str); |
zSql = sqlite3_mprintf(argv[2],argv[3]); |
if( argc==5 ){ |
rc = sqlite3_get_table(db, zSql, aResult, 0, 0, zErr); |
}else{ |
rc = sqlite3_get_table(db, zSql, aResult, nRow, nCol, zErr); |
resCount = (nRow+1)*nCol; |
} |
sqlite3DbFree(db,zSql); |
sqlite3_snprintf(zBuf, "%d", rc); |
TCL.Tcl_AppendElement(interp, zBuf); |
if( rc==SQLITE_OK ){ |
if( argc==4 ){ |
sqlite3_snprintf(zBuf, "%d", nRow); |
TCL.Tcl_AppendElement(interp, zBuf); |
sqlite3_snprintf(zBuf, "%d", nCol); |
TCL.Tcl_AppendElement(interp, zBuf); |
} |
for(i=0; i<resCount; i++){ |
TCL.Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL"); |
} |
}else{ |
TCL.Tcl_AppendElement(interp, zErr); |
} |
//sqlite3_free_table(aResult); |
if( zErr ) sqlite3DbFree(db,zErr); |
if( sqlite3TestErrCode(interp, db, rc) ) return TCL.TCL_ERROR; |
return TCL.TCL_OK; |
} |
#endif //* SQLITE_OMIT_GET_TABLE*/ |
|
/* |
** Usage: sqlite3_last_insert_rowid DB |
** |
** Returns the integer ROWID of the most recent insert. |
*/ |
//static int test_last_rowid( |
// object NotUsed, |
// Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
// int argc, /* Number of arguments */ |
// Tcl_Obj[] argv /* Text of each argument */ |
//){ |
// sqlite3 db=null; |
// char zBuf[30]; |
|
// if( argc!=2 ){ |
// TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\""); |
// return TCL.TCL_ERROR; |
// } |
// if( getDbPointer(interp, argv[1].ToString(), out db) !=0) return TCL.TCL_ERROR; |
// sqlite3_snprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db)); |
// TCL.Tcl_AppendResult(interp, zBuf); |
// return SQLITE_OK; |
//} |
|
/* |
** Usage: sqlite3_key DB KEY |
** |
** Set the codec key. |
*/ |
static int test_key( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
sqlite3 db = null; |
string zKey; |
int nKey; |
if ( argc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" FILENAME\"" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
zKey = argv[2].ToString(); |
nKey = zKey.Length; |
#if SQLITE_HAS_CODEC |
sqlite3_key( db, zKey, nKey ); |
#endif |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_rekey DB KEY |
** |
** Change the codec key. |
*/ |
static int test_rekey( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
sqlite3 db = null; |
string zKey; |
int nKey; |
if ( argc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" FILENAME\"" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
zKey = argv[2].ToString(); |
nKey = zKey.Length; |
#if SQLITE_HAS_CODEC |
sqlite3_rekey( db, zKey, nKey ); |
#endif |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_close DB |
** |
** Closes the database opened by sqlite3_open. |
*/ |
static int sqlite_test_close( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
sqlite3 db = null; |
int rc; |
if ( argc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" FILENAME\"" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
rc = sqlite3_close( db ); |
TCL.Tcl_SetResult( interp, t1ErrorName( rc ), TCL.TCL_STATIC ); |
return TCL.TCL_OK; |
} |
|
/* |
** Implementation of the x_coalesce() function. |
** Return the first argument non-NULL argument. |
*/ |
static void t1_ifnullFunc( |
sqlite3_context context, |
int argc, |
sqlite3_value[] argv |
) |
{ |
int i; |
for ( i = 0; i < argc; i++ ) |
{ |
if ( SQLITE_NULL != sqlite3_value_type( argv[i] ) ) |
{ |
int n = sqlite3_value_bytes( argv[i] ); |
sqlite3_result_text( context, sqlite3_value_text( argv[i] ), |
n, SQLITE_TRANSIENT ); |
break; |
} |
} |
} |
|
/* |
** These are test functions. hex8() interprets its argument as |
** UTF8 and returns a hex encoding. hex16le() interprets its argument |
** as UTF16le and returns a hex encoding. |
*/ |
static void hex8Func( sqlite3_context p, int argc, sqlite3_value[] argv ) |
{ |
string z; |
int i; |
StringBuilder zBuf = new StringBuilder( 200 ); |
z = sqlite3_value_text( argv[0] ); |
StringBuilder zTemp = new StringBuilder( 200 ); |
for ( i = 0; i < zBuf.Capacity / 2 - 2 && i < argv[0].n; i++ ) |
{ |
sqlite3_snprintf( 4, zTemp, "%02x", z[i] & 0xff ); |
zBuf.Append( zTemp ); |
} |
//zBuf[i*2] = 0; |
sqlite3_result_text( p, zBuf, -1, SQLITE_TRANSIENT ); |
} |
#if !SQLITE_OMIT_UTF16 |
static void hex16Func(sqlite3_context p, int argc, sqlite3_value[] argv){ |
Debugger.Break (); //TODO -- |
// const unsigned short int *z; |
// int i; |
// char zBuf[400]; |
// z = sqlite3_value_text16(argv[0]); |
// for(i=0; i<sizeof(zBuf)/4 - 4 && z[i]; i++){ |
// sqlite3_snprintf(&zBuf[i*4], "%04x", z[i]&0xff); |
// } |
// zBuf[i*4] = 0; |
// sqlite3_result_text(p, (char)zBuf, -1, SQLITE_TRANSIENT); |
} |
#endif |
|
/* |
** A structure into which to accumulate text. |
*/ |
struct dstr |
{ |
public int nAlloc; /* Space allocated */ |
public int nUsed; /* Space used */ |
public StringBuilder z; /* The space */ |
}; |
|
/* |
** Append text to a dstr |
*/ |
static void dstrAppend( dstr p, string z, int divider ) |
{ |
int n = z.Length;// strlen( z ); |
// if( p.nUsed + n + 2 > p.nAlloc ){ |
// string zNew; |
p.nAlloc = p.nAlloc * 2 + n + 200; |
p.z.Capacity = p.nAlloc; |
// zNew = sqlite3_realloc(p.z, p.nAlloc); |
// if( zNew==0 ){ |
// sqlite3DbFree(db,p.z); |
// memset(p, 0, sizeof(*p)); |
// return; |
// } |
// p.z = zNew; |
// } |
// if( divider && p.nUsed>0 ){ |
// p.z[p.nUsed++] = divider; |
// } |
// memcpy(p.z[p.nUsed], z, n+1); |
p.nUsed += n; |
p.z.Append( divider + z ); |
} |
|
/* |
** Invoked for each callback from sqlite3ExecFunc |
*/ |
static int execFuncCallback( object pData, sqlite3_int64 argc, object _argv, object NotUsed ) |
{ |
Tcl_Obj[] argv = (Tcl_Obj[])_argv; |
dstr p = (dstr)pData; |
int i; |
for ( i = 0; i < argc; i++ ) |
{ |
if ( argv[i] == null ) |
{ |
dstrAppend( p, "NULL", ' ' ); |
} |
else |
{ |
dstrAppend( p, argv[i].ToString(), ' ' ); |
} |
} |
return 0; |
} |
|
/* |
** Implementation of the x_sqlite_exec() function. This function takes |
** a single argument and attempts to execute that argument as SQL code. |
** This is illegal and should set the SQLITE_MISUSE flag on the database. |
** |
** 2004-Jan-07: We have changed this to make it legal to call sqlite3_exec() |
** from within a function call. |
** |
** This routine simulates the effect of having two threads attempt to |
** use the same database at the same time. |
*/ |
static void sqlite3ExecFunc( |
sqlite3_context context, |
int argc, |
sqlite3_value[] argv |
) |
{ |
dstr x = new dstr(); |
//memset(&x, 0, sizeof(x)); |
string sDummy = ""; |
sqlite3_exec( (sqlite3)sqlite3_context_db_handle( context ), |
sqlite3_value_text( argv[0] ), |
(dxCallback)execFuncCallback, (object)x, ref sDummy ); |
sqlite3_result_text( context, x.z, x.nUsed, SQLITE_TRANSIENT ); |
x.z = null;// sqlite3DbFree( db, ref x.z ); |
} |
|
/* |
** Implementation of tkt2213func(), a scalar function that takes exactly |
** one argument. It has two interesting features: |
** |
** * It calls sqlite3_value_text() 3 times on the argument sqlite3_value*. |
** If the three pointers returned are not the same an SQL error is raised. |
** |
** * Otherwise it returns a copy of the text representation of its |
** argument in such a way as the VDBE representation is a Mem* cell |
** with the MEM_Term flag clear. |
** |
** Ticket #2213 can therefore be tested by evaluating the following |
** SQL expression: |
** |
** tkt2213func(tkt2213func('a string')); |
*/ |
static void tkt2213Function( |
sqlite3_context context, |
int argc, |
sqlite3_value[] argv |
) |
{ |
int nText; |
string zText1; |
string zText2; |
string zText3; |
|
nText = sqlite3_value_bytes( argv[0] ); |
zText1 = sqlite3_value_text( argv[0] ); |
zText2 = sqlite3_value_text( argv[0] ); |
zText3 = sqlite3_value_text( argv[0] ); |
|
if ( zText1 != zText2 || zText2 != zText3 ) |
{ |
sqlite3_result_error( context, "tkt2213 is not fixed", -1 ); |
} |
else |
{ |
//string zCopy = (char )sqlite3Malloc(nText); |
//memcpy(zCopy, zText1, nText); |
sqlite3_result_text( context, zText1, nText, null ); //sqlite3_free ); |
} |
} |
|
/* |
** The following SQL function takes 4 arguments. The 2nd and |
** 4th argument must be one of these strings: 'text', 'text16', |
** or 'blob' corresponding to API functions |
** |
** sqlite3_value_text() |
** sqlite3_value_text16() |
** sqlite3_value_blob() |
** |
** The third argument is a string, either 'bytes' or 'bytes16' or 'noop', |
** corresponding to APIs: |
** |
** sqlite3_value_bytes() |
** sqlite3_value_bytes16() |
** noop |
** |
** The APIs designated by the 2nd through 4th arguments are applied |
** to the first argument in order. If the pointers returned by the |
** second and fourth are different, this routine returns 1. Otherwise, |
** this routine returns 0. |
** |
** This function is used to test to see when returned pointers from |
** the _text(), _text16() and _blob() APIs become invalidated. |
*/ |
static void ptrChngFunction( |
sqlite3_context context, |
int argc, |
sqlite3_value[] argv |
) |
{ |
sqlite3_result_int( context, 0 ); |
return; |
//Debugger.Break(); //TODO -- |
//string p1 = "", p2 = ""; |
//string zCmd; |
//if ( argc != 4 ) |
// return; |
//zCmd = sqlite3_value_text( argv[1] ); |
//if ( zCmd == null ) |
// return; |
// if( strcmp(zCmd,"text")==0 ){ |
// p1 = (const void)sqlite3_value_text(argv[0]); |
//#if !SQLITE_OMIT_UTF16 |
// }else if( strcmp(zCmd, "text16")==0 ){ |
// p1 = (const void)sqlite3_value_text16(argv[0]); |
//#endif |
// }else if( strcmp(zCmd, "blob")==0 ){ |
// p1 = (const void)sqlite3_value_blob(argv[0]); |
// }else{ |
// return; |
// } |
// zCmd = (const char)sqlite3_value_text(argv[2]); |
// if( zCmd==0 ) return; |
// if( strcmp(zCmd,"bytes")==0 ){ |
// sqlite3_value_bytes(argv[0]); |
//#if !SQLITE_OMIT_UTF16 |
// }else if( strcmp(zCmd, "bytes16")==0 ){ |
// sqlite3_value_bytes16(argv[0]); |
//#endif |
// }else if( strcmp(zCmd, "noop")==0 ){ |
// /* do nothing */ |
// }else{ |
// return; |
// } |
// zCmd = (const char)sqlite3_value_text(argv[3]); |
// if( zCmd==0 ) return; |
// if( strcmp(zCmd,"text")==0 ){ |
// p2 = (const void)sqlite3_value_text(argv[0]); |
//#if !SQLITE_OMIT_UTF16 |
// }else if( strcmp(zCmd, "text16")==0 ){ |
// p2 = (const void)sqlite3_value_text16(argv[0]); |
//#endif |
// }else if( strcmp(zCmd, "blob")==0 ){ |
// p2 = (const void)sqlite3_value_blob(argv[0]); |
// }else{ |
// return; |
// } |
//sqlite3_result_int( context, p1 != p2 ? 1 : 0 ); |
} |
|
|
/* |
** Usage: sqlite_test_create_function DB |
** |
** Call the sqlite3_create_function API on the given database in order |
** to create a function named "x_coalesce". This function does the same thing |
** as the "coalesce" function. This function also registers an SQL function |
** named "x_sqlite_exec" that invokes sqlite3_exec(). Invoking sqlite3_exec() |
** in this way is illegal recursion and should raise an SQLITE_MISUSE error. |
** The effect is similar to trying to use the same database connection from |
** two threads at the same time. |
** |
** The original motivation for this routine was to be able to call the |
** sqlite3_create_function function while a query is in progress in order |
** to test the SQLITE_MISUSE detection logic. |
*/ |
static int test_create_function( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
int rc; |
sqlite3 db = null; |
|
if ( argc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" DB\"" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
rc = sqlite3_create_function( db, "x_coalesce", -1, SQLITE_ANY, 0, |
t1_ifnullFunc, null, null ); |
if ( rc == SQLITE_OK ) |
{ |
rc = sqlite3_create_function( db, "hex8", 1, SQLITE_ANY, 0, |
hex8Func, null, null ); |
} |
#if !SQLITE_OMIT_UTF16 |
if( rc==SQLITE_OK ){ |
rc = sqlite3_create_function(db, "hex16", 1, SQLITE_ANY, null, hex16Func, null,null); |
} |
#endif |
if ( rc == SQLITE_OK ) |
{ |
rc = sqlite3_create_function( db, "tkt2213func", 1, SQLITE_ANY, 0, |
tkt2213Function, null, null ); |
} |
if ( rc == SQLITE_OK ) |
{ |
rc = sqlite3_create_function( db, "pointer_change", 4, SQLITE_ANY, 0, |
ptrChngFunction, null, null ); |
} |
|
#if !SQLITE_OMIT_UTF16 |
/* Use the sqlite3_create_function16() API here. Mainly for fun, but also |
** because it is not tested anywhere else. */ |
if( rc==SQLITE_OK ){ |
string zUtf16; |
sqlite3_value pVal; |
sqlite3_mutex_enter(db.mutex); |
pVal = sqlite3ValueNew(db); |
sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC); |
zUtf16 = sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); |
if( db.mallocFailed !=0{ |
rc = SQLITE_NOMEM; |
}else{ |
rc = sqlite3_create_function16(db, zUtf16, 1, SQLITE_UTF16, db, sqlite3ExecFunc,null,null ); |
} |
sqlite3ValueFree(ref pVal); |
sqlite3_mutex_leave(db.mutex); |
} |
#endif |
|
if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
return TCL.TCL_ERROR; |
TCL.Tcl_SetResult( interp, sqlite3TestErrorName( rc ), 0 ); |
return TCL.TCL_OK; |
} |
|
/* |
** Routines to implement the x_count() aggregate function. |
** |
** x_count() counts the number of non-null arguments. But there are |
** some twists for testing purposes. |
** |
** If the argument to x_count() is 40 then a UTF-8 error is reported |
** on the step function. If x_count(41) is seen, then a UTF-16 error |
** is reported on the step function. If the total count is 42, then |
** a UTF-8 error is reported on the finalize function. |
*/ |
//typedef struct t1CountCtx t1CountCtx; |
|
static void t1CountStep( |
sqlite3_context context, |
int argc, |
sqlite3_value[] argv |
) |
{ |
SumCtx p; |
Mem pMem = sqlite3_aggregate_context( context, 1 );//sizeof(*p)); |
if ( pMem._SumCtx == null ) |
pMem._SumCtx = new SumCtx(); |
p = pMem._SumCtx; |
if ( p.Context == null ) |
p.Context = pMem; |
if ( ( argc == 0 || SQLITE_NULL != sqlite3_value_type( argv[0] ) ) && p != null ) |
{ |
p.cnt++; |
} |
if ( argc > 0 ) |
{ |
int v = sqlite3_value_int( argv[0] ); |
if ( v == 40 ) |
{ |
sqlite3_result_error( context, "value of 40 handed to x_count", -1 ); |
#if !SQLITE_OMIT_UTF16 |
}else if( v==41 ){ |
Debugger.Break (); // TODO -- |
//const char zUtf16ErrMsg[] = { 0, 0x61, 0, 0x62, 0, 0x63, 0, 0, 0}; |
//sqlite3_result_error16(context, zUtf16ErrMsg[1-SQLITE_BIGENDIAN], -1); |
#endif |
} |
} |
} |
static void t1CountFinalize( sqlite3_context context ) |
{ |
SumCtx p; |
Mem pMem = sqlite3_aggregate_context( context, 0 );//sizeof(*p)); |
p = pMem._SumCtx; |
if ( p != null ) |
{ |
if ( p.cnt == 42 ) |
{ |
sqlite3_result_error( context, "x_count totals to 42", -1 ); |
} |
else |
{ |
sqlite3_result_int( context, p != null ? (int)p.cnt : 0 ); |
} |
} |
} |
|
#if !SQLITE_OMIT_DEPRECATED |
static void legacyCountStep( |
sqlite3_context context, |
int argc, |
sqlite3_value[] argv |
) |
{ |
/* no-op */ |
} |
static void legacyCountFinalize( sqlite3_context context ) |
{ |
sqlite3_result_int( context, sqlite3_aggregate_count( context ) ); |
} |
#endif |
/* |
** Usage: sqlite3_create_aggregate DB |
** |
** Call the sqlite3_create_function API on the given database in order |
** to create a function named "x_count". This function is similar |
** to the built-in count() function, with a few special quirks |
** for testing the sqlite3_result_error() APIs. |
** |
** The original motivation for this routine was to be able to call the |
** sqlite3_create_aggregate function while a query is in progress in order |
** to test the SQLITE_MISUSE detection logic. See misuse.test. |
** |
** This routine was later extended to test the use of sqlite3_result_error() |
** within aggregate functions. |
** |
** Later: It is now also extended to register the aggregate function |
** "legacy_count()" with the supplied database handle. This is used |
** to test the deprecated sqlite3_aggregate_count() API. |
*/ |
static int test_create_aggregate( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
sqlite3 db = new sqlite3(); |
int rc; |
if ( argc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0].ToString(), |
" FILENAME\"" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
rc = sqlite3_create_function( db, "x_count", 0, SQLITE_UTF8, 0, null, |
t1CountStep, t1CountFinalize ); |
if ( rc == SQLITE_OK ) |
{ |
rc = sqlite3_create_function( db, "x_count", 1, SQLITE_UTF8, 0, null, |
t1CountStep, t1CountFinalize ); |
} |
#if !SQLITE_OMIT_DEPRECATED |
if ( rc == SQLITE_OK ) |
{ |
rc = sqlite3_create_function( db, "legacy_count", 0, SQLITE_ANY, 0, null, |
legacyCountStep, legacyCountFinalize |
); |
} |
#endif |
if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
return TCL.TCL_ERROR; |
TCL.Tcl_SetResult( interp, t1ErrorName( rc ), 0 ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: printf TEXT |
** |
** Send output to printf. Use this rather than puts to merge the output |
** in the correct sequence with debugging printfs inserted into C code. |
** Puts uses a separate buffer and debugging statements will be out of |
** sequence if it is used. |
*/ |
//static int test_printf( |
// object NotUsed, |
// Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
// int argc, /* Number of arguments */ |
// Tcl_Obj[] argv /* Text of each argument */ |
//){ |
// if( argc!=2 ){ |
// TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
// " TEXT\""); |
// return TCL.TCL_ERROR; |
// } |
// printf("%s\n", argv[1]); |
// return TCL.TCL_OK; |
//} |
|
|
|
/* |
** Usage: sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER |
** |
** Call mprintf with three integer arguments |
*/ |
static int sqlite3_mprintf_int( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
long[] a = new long[3]; |
int i; |
string z; |
if ( argc != 5 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" FORMAT INT INT INT\"" ); |
return TCL.TCL_ERROR; |
} |
for ( i = 2; i < 5; i++ ) |
{ |
if ( TCL.Tcl_GetLong( interp, argv[i], out a[i - 2] ) ) |
return TCL.TCL_ERROR; |
} |
z = sqlite3_mprintf( argv[1].ToString(), a[0], a[1], a[2] ); |
TCL.Tcl_AppendResult( interp, z ); |
//sqlite3DbFree(db,z); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_mprintf_int64 FORMAT INTEGER INTEGER INTEGER |
** |
** Call mprintf with three 64-bit integer arguments |
*/ |
static int sqlite3_mprintf_int64( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
int i; |
sqlite3_int64[] a = new sqlite3_int64[3]; |
string z; |
if ( argc != 5 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" FORMAT INT INT INT\"" ); |
return TCL.TCL_ERROR; |
} |
for ( i = 2; i < 5; i++ ) |
{ |
if ( sqlite3Atoi64( argv[i].ToString(), ref a[i - 2], argv[i].ToString().Length, SQLITE_UTF8 ) != 0 ) |
{ |
TCL.Tcl_AppendResult( interp, "argument is not a valid 64-bit integer" ); |
return TCL.TCL_ERROR; |
} |
} |
z = sqlite3_mprintf( argv[1].ToString(), a[0], a[1], a[2] ); |
TCL.Tcl_AppendResult( interp, z ); |
//sqlite3DbFree(db,z); |
return TCL.TCL_OK; |
} |
|
|
/* |
** Usage: sqlite3_mprintf_long FORMAT INTEGER INTEGER INTEGER |
** |
** Call mprintf with three long integer arguments. This might be the |
** same as sqlite3_mprintf_int or sqlite3_mprintf_int64, depending on |
** platform. |
*/ |
static int sqlite3_mprintf_long( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
int i; |
long[] a = new long[3]; |
long[] b = new long[3]; |
string z; |
if ( argc != 5 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" FORMAT INT INT INT\"" ); |
return TCL.TCL_ERROR; |
} |
for ( i = 2; i < 5; i++ ) |
{ |
if ( TCL.Tcl_GetLong( interp, argv[i], out b[i - 2] ) ) |
return TCL.TCL_ERROR; |
a[i - 2] = b[i - 2]; |
//a[i-2] &= (((u64)1)<<(sizeof(int)*8))-1; |
} |
z = sqlite3_mprintf( argv[1].ToString(), a[0], a[1], a[2] ); |
TCL.Tcl_AppendResult( interp, z ); |
////sqlite3_free(z); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING |
** |
** Call mprintf with two integer arguments and one string argument |
*/ |
static int sqlite3_mprintf_str( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
long[] a = new long[3]; |
int i; |
string z; |
if ( argc < 4 || argc > 5 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" FORMAT INT INT ?STRING?\"" ); |
return TCL.TCL_ERROR; |
} |
for ( i = 2; i < 4; i++ ) |
{ |
if ( TCL.Tcl_GetLong( interp, argv[i], out a[i - 2] ) ) |
return TCL.TCL_ERROR; |
} |
z = sqlite3_mprintf( argv[1].ToString(), a[0], a[1], argc > 4 ? argv[4].ToString() : null ); |
TCL.Tcl_AppendResult( interp, z ); |
//sqlite3DbFree(db,z); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_snprintf_str INTEGER FORMAT INTEGER INTEGER STRING |
** |
** Call mprintf with two integer arguments and one string argument |
*/ |
static int sqlite3_snprintf_str( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
long[] a = new long[3]; |
int i; |
int n = 0; |
StringBuilder z; |
if ( argc < 5 || argc > 6 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" INT FORMAT INT INT ?STRING?\"" ); |
return TCL.TCL_ERROR; |
} |
if ( TCL.Tcl_GetInt( interp, argv[1], out n ) ) |
return TCL.TCL_ERROR; |
if ( n < 0 ) |
{ |
TCL.Tcl_AppendResult( interp, "N must be non-negative" ); |
return TCL.TCL_ERROR; |
} |
for ( i = 3; i < 5; i++ ) |
{ |
if ( TCL.Tcl_GetLong( interp, argv[i], out a[i - 3] ) ) |
return TCL.TCL_ERROR; |
} |
z = new StringBuilder( n + 1 );//sqlite3Malloc( n+1 ); |
sqlite3_snprintf( n, z, argv[2].ToString(), a[0], a[1], argc > 4 ? argv[5].ToString() : null ); |
TCL.Tcl_AppendResult( interp, z ); |
//sqlite3DbFree(db,z); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_mprintf_double FORMAT INTEGER INTEGER DOUBLE |
** |
** Call mprintf with two integer arguments and one double argument |
*/ |
static int sqlite3_mprintf_double( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
long[] a = new long[3]; |
int i; |
double r = 0; |
string z; |
if ( argc != 5 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" FORMAT INT INT DOUBLE\"" ); |
return TCL.TCL_ERROR; |
} |
for ( i = 2; i < 4; i++ ) |
{ |
if ( TCL.Tcl_GetLong( interp, argv[i], out a[i - 2] ) ) |
return TCL.TCL_ERROR; |
} |
if ( TCL.Tcl_GetDouble( interp, argv[4], out r ) ) |
return TCL.TCL_ERROR; |
z = sqlite3_mprintf( argv[1].ToString(), a[0], a[1], r ); |
TCL.Tcl_AppendResult( interp, z ); |
//sqlite3DbFree(db,z); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_mprintf_scaled FORMAT DOUBLE DOUBLE |
** |
** Call mprintf with a single double argument which is the product of the |
** two arguments given above. This is used to generate overflow and underflow |
** doubles to test that they are converted properly. |
*/ |
static int sqlite3_mprintf_scaled( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
int i; |
double[] r = new double[2]; |
string z; |
if ( argc != 4 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" FORMAT DOUBLE DOUBLE\"" ); |
return TCL.TCL_ERROR; |
} |
for ( i = 2; i < 4; i++ ) |
{ |
if ( TCL.Tcl_GetDouble( interp, argv[i], out r[i - 2] ) ) |
return TCL.TCL_ERROR; |
} |
z = sqlite3_mprintf( argv[1].ToString(), r[0] * r[1] ); |
TCL.Tcl_AppendResult( interp, z ); |
//sqlite3DbFree(db,z); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_mprintf_stronly FORMAT STRING |
** |
** Call mprintf with a single double argument which is the product of the |
** two arguments given above. This is used to generate overflow and underflow |
** doubles to test that they are converted properly. |
*/ |
static int sqlite3_mprintf_stronly( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
string z; |
if ( argc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" FORMAT STRING\"" ); |
return TCL.TCL_ERROR; |
} |
z = sqlite3_mprintf( argv[1].ToString(), argv[2].ToString() ); |
TCL.Tcl_AppendResult( interp, z ); |
//sqlite3DbFree( db, z ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_mprintf_hexdouble FORMAT HEX |
** |
** Call mprintf with a single double argument which is derived from the |
** hexadecimal encoding of an IEEE double. |
*/ |
static int sqlite3_mprintf_hexdouble( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
string z; |
double r; |
u32 x1, x2; |
i64 d = 0; |
if ( argc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" FORMAT STRING\"" ); |
return TCL.TCL_ERROR; |
} |
//if( sscanf(argv[2].ToString(), "%08x%08x", ref x2, ref x1)!=2 ){ |
if ( argv[2].ToString().Length != 16 |
|| !u32.TryParse( argv[2].ToString().Substring( 0, 8 ), System.Globalization.NumberStyles.HexNumber, null, out x2 ) |
|| !u32.TryParse( argv[2].ToString().Substring( 8, 8 ), System.Globalization.NumberStyles.HexNumber, null, out x1 ) |
) |
{ |
TCL.Tcl_AppendResult( interp, "2nd argument should be 16-characters of hex" ); |
return TCL.TCL_ERROR; |
} |
d = x2; |
d = ( d << 32 ) + x1; |
#if WINDOWS_PHONE |
r = BitConverter.ToDouble(BitConverter.GetBytes((long)d), 0); |
#else |
r = BitConverter.Int64BitsToDouble( d );// memcpy( &r, d, sizeof( r ) ); |
#endif |
z = sqlite3_mprintf( argv[1].ToString(), r ); |
TCL.Tcl_AppendResult( interp, z ); |
//sqlite3DbFree(db,z); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_enable_shared_cache ?BOOLEAN? |
** |
*/ |
#if !SQLITE_OMIT_SHARED_CACHE |
static int test_enable_shared( |
object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
int rc; |
bool enable = false; |
int ret = 0; |
|
if ( objc != 2 && objc != 1 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "?BOOLEAN?" ); |
return TCL.TCL_ERROR; |
} |
ret = sqlite3GlobalConfig.sharedCacheEnabled ? 1 : 0; |
|
if ( objc == 2 ) |
{ |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[1], out enable ) ) |
{ |
return TCL.TCL_ERROR; |
} |
rc = sqlite3_enable_shared_cache( enable ); |
if ( rc != SQLITE_OK ) |
{ |
TCL.Tcl_SetResult( interp, sqlite3ErrStr( rc ), TCL.TCL_STATIC ); |
return TCL.TCL_ERROR; |
} |
} |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewBooleanObj( ret ) ); |
return TCL.TCL_OK; |
} |
#endif |
|
|
|
/* |
** Usage: sqlite3_extended_result_codes DB BOOLEAN |
** |
*/ |
static int test_extended_result_codes( |
object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
bool enable = false; |
sqlite3 db = null; |
|
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB BOOLEAN" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, objv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[2], out enable ) ) |
return TCL.TCL_ERROR; |
sqlite3_extended_result_codes( db, enable ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_libversion_number |
** |
*/ |
static int test_libversion_number( |
object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_libversion_number() ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_table_column_metadata DB dbname tblname colname |
** |
*/ |
#if SQLITE_ENABLE_COLUMN_METADATA |
static int test_table_column_metadata( |
object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
sqlite3 db = null; |
string zDb = null; |
string zTbl = null; |
string zCol = null; |
int rc; |
Tcl_Obj pRet; |
|
string zDatatype = null; |
string zCollseq = null; |
int notnull = 0; |
int primarykey = 0; |
int autoincrement = 0; |
|
if ( objc != 5 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB dbname tblname colname" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
zDb = TCL.Tcl_GetString( objv[2] ); |
zTbl = TCL.Tcl_GetString( objv[3] ); |
zCol = TCL.Tcl_GetString( objv[4] ); |
|
if ( zDb.Length == 0 ) |
zDb = null; |
|
rc = sqlite3_table_column_metadata( db, zDb, zTbl, zCol, |
ref zDatatype, ref zCollseq, ref notnull, ref primarykey, ref autoincrement ); |
|
if ( rc != SQLITE_OK ) |
{ |
TCL.Tcl_AppendResult( interp, sqlite3_errmsg( db ) ); |
return TCL.TCL_ERROR; |
} |
|
pRet = TCL.Tcl_NewObj(); |
TCL.Tcl_ListObjAppendElement( null, pRet, TCL.Tcl_NewStringObj( zDatatype, -1 ) ); |
TCL.Tcl_ListObjAppendElement( null, pRet, TCL.Tcl_NewStringObj( zCollseq, -1 ) ); |
TCL.Tcl_ListObjAppendElement( null, pRet, TCL.Tcl_NewIntObj( notnull ) ); |
TCL.Tcl_ListObjAppendElement( null, pRet, TCL.Tcl_NewIntObj( primarykey ) ); |
TCL.Tcl_ListObjAppendElement( null, pRet, TCL.Tcl_NewIntObj( autoincrement ) ); |
TCL.Tcl_SetObjResult( interp, pRet ); |
|
return TCL.TCL_OK; |
} |
#endif |
|
#if !SQLITE_OMIT_INCRBLOB |
static int blobHandleFromObj( |
Tcl_Interp interp, |
Tcl_Obj *pObj, |
sqlite3_blob **ppBlob |
){ |
string z; |
int n; |
|
z = TCL.Tcl_GetStringFromObj(pObj, &n); |
if( n==0 ){ |
*ppBlob = 0; |
}else{ |
int notUsed; |
TCL.Tcl_Channel channel; |
ClientData instanceData; |
|
channel = TCL.Tcl_GetChannel(interp, z, ¬Used); |
if( null==channel ) return TCL.TCL_ERROR; |
|
TCL.Tcl_Flush(channel); |
TCL.Tcl_Seek(channel, 0, SEEK_SET); |
|
instanceData = TCL.Tcl_GetChannelInstanceData(channel); |
*ppBlob = *((sqlite3_blob *)instanceData); |
} |
|
return TCL.TCL_OK; |
} |
|
/* |
** sqlite3_blob_bytes CHANNEL |
*/ |
static int test_blob_bytes( |
ClientData clientData, /* Not used */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
){ |
sqlite3_blob *pBlob; |
int nByte; |
|
if( objc!=2 ){ |
TCL.Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL"); |
return TCL.TCL_ERROR; |
} |
|
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL.TCL_ERROR; |
nByte = sqlite3_blob_bytes(pBlob); |
TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(nByte)); |
|
return TCL.TCL_OK; |
} |
|
/* |
** sqlite3_blob_close CHANNEL |
*/ |
static int test_blob_close( |
ClientData clientData, /* Not used */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
){ |
sqlite3_blob *pBlob; |
|
if( objc!=2 ){ |
TCL.Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL"); |
return TCL.TCL_ERROR; |
} |
|
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL.TCL_ERROR; |
sqlite3_blob_close(pBlob); |
|
return TCL.TCL_OK; |
} |
|
/* |
** sqlite3_blob_read CHANNEL OFFSET N |
** |
** This command is used to test the sqlite3_blob_read() in ways that |
** the Tcl channel interface does not. The first argument should |
** be the name of a valid channel created by the [incrblob] method |
** of a database handle. This function calls sqlite3_blob_read() |
** to read N bytes from offset OFFSET from the underlying SQLite |
** blob handle. |
** |
** On success, a byte-array object containing the read data is |
** returned. On failure, the interpreter result is set to the |
** text representation of the returned error code (i.e. "SQLITE_NOMEM") |
** and a Tcl exception is thrown. |
*/ |
static int test_blob_read( |
ClientData clientData, /* Not used */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
){ |
sqlite3_blob *pBlob; |
int nByte; |
int iOffset; |
unsigned string zBuf = 0; |
int rc; |
|
if( objc!=4 ){ |
TCL.Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET N"); |
return TCL.TCL_ERROR; |
} |
|
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL.TCL_ERROR; |
if( TCL_OK!=TCL.Tcl_GetIntFromObj(interp, objv[2], &iOffset) |
|| TCL_OK!=TCL.Tcl_GetIntFromObj(interp, objv[3], &nByte) |
){ |
return TCL.TCL_ERROR; |
} |
|
if( nByte>0 ){ |
zBuf = (unsigned char )TCL.Tcl_Alloc(nByte); |
} |
rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset); |
if( rc==SQLITE_OK ){ |
TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewByteArrayObj(zBuf, nByte)); |
}else{ |
TCL.Tcl_SetResult(interp, (char )sqlite3TestErrorName(rc), TCL.TCL_VOLATILE); |
} |
TCL.Tcl_Free((char )zBuf); |
|
return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); |
} |
|
/* |
** sqlite3_blob_write CHANNEL OFFSET DATA ?NDATA? |
** |
** This command is used to test the sqlite3_blob_write() in ways that |
** the Tcl channel interface does not. The first argument should |
** be the name of a valid channel created by the [incrblob] method |
** of a database handle. This function calls sqlite3_blob_write() |
** to write the DATA byte-array to the underlying SQLite blob handle. |
** at offset OFFSET. |
** |
** On success, an empty string is returned. On failure, the interpreter |
** result is set to the text representation of the returned error code |
** (i.e. "SQLITE_NOMEM") and a Tcl exception is thrown. |
*/ |
static int test_blob_write( |
ClientData clientData, /* Not used */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
){ |
sqlite3_blob *pBlob; |
int iOffset; |
int rc; |
|
unsigned string zBuf; |
int nBuf; |
|
if( objc!=4 && objc!=5 ){ |
TCL.Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET DATA ?NDATA?"); |
return TCL.TCL_ERROR; |
} |
|
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL.TCL_ERROR; |
if( TCL_OK!=TCL.Tcl_GetIntFromObj(interp, objv[2], &iOffset) ){ |
return TCL.TCL_ERROR; |
} |
|
zBuf = TCL.Tcl_GetByteArrayFromObj(objv[3], &nBuf); |
if( objc==5 && TCL.Tcl_GetIntFromObj(interp, objv[4], &nBuf) ){ |
return TCL.TCL_ERROR; |
} |
rc = sqlite3_blob_write(pBlob, zBuf, nBuf, iOffset); |
if( rc!=SQLITE_OK ){ |
TCL.Tcl_SetResult(interp, (char )sqlite3TestErrorName(rc), TCL.TCL_VOLATILE); |
} |
|
return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); |
} |
|
static int test_blob_reopen( |
ClientData clientData, /* Not used */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
){ |
TCL.Tcl_WideInt iRowid; |
sqlite3_blob *pBlob; |
int rc; |
|
if( objc!=3 ){ |
TCL.Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL ROWID"); |
return TCL.TCL_ERROR; |
} |
|
if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL.TCL_ERROR; |
if( TCL.Tcl_GetWideIntFromObj(interp, objv[2], &iRowid) ) return TCL.TCL_ERROR; |
|
rc = sqlite3_blob_reopen(pBlob, iRowid); |
if( rc!=SQLITE_OK ){ |
TCL.Tcl_SetResult(interp, (char )sqlite3TestErrorName(rc), TCL.TCL_VOLATILE); |
} |
|
return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); |
} |
#endif |
|
/* |
** Usage: sqlite3_create_collation_v2 DB-HANDLE NAME CMP-PROC DEL-PROC |
** |
** This Tcl proc is used for testing the experimental |
** sqlite3_create_collation_v2() interface. |
*/ |
public struct TestCollationX |
{ |
public Tcl_Interp interp; |
public Tcl_Obj pCmp; |
public Tcl_Obj pDel; |
}; |
//typedef struct TestCollationX TestCollationX; |
static void testCreateCollationDel( ref object pCtx ) |
{ |
TestCollationX p = (TestCollationX)pCtx; |
|
int rc = TCL.Tcl_EvalObjEx( p.interp, p.pDel, TCL.TCL_EVAL_DIRECT | TCL.TCL_EVAL_GLOBAL ); |
if ( rc != TCL.TCL_OK ) |
{ |
TCL.Tcl_BackgroundError( p.interp ); |
} |
|
TCL.Tcl_DecrRefCount( ref p.pCmp ); |
TCL.Tcl_DecrRefCount( ref p.pDel ); |
//sqlite3Free(ref p); |
} |
static int testCreateCollationCmp( |
object pCtx, |
int nLeft, |
string zLeft, |
int nRight, |
string zRight |
) |
{ |
TestCollationX p = (TestCollationX)pCtx; |
Tcl_Obj pScript = TCL.Tcl_DuplicateObj( p.pCmp ); |
int iRes = 0; |
|
TCL.Tcl_IncrRefCount( pScript ); |
TCL.Tcl_ListObjAppendElement( null, pScript, TCL.Tcl_NewStringObj( zLeft, nLeft ) ); |
TCL.Tcl_ListObjAppendElement( null, pScript, TCL.Tcl_NewStringObj( zRight, nRight ) ); |
|
if ( TCL.TCL_OK != TCL.Tcl_EvalObjEx( p.interp, pScript, TCL.TCL_EVAL_DIRECT | TCL.TCL_EVAL_GLOBAL ) |
|| ( TCL.Tcl_GetIntFromObj( p.interp, TCL.Tcl_GetObjResult( p.interp ), out iRes ) != TCL.TCL_OK ) |
) |
{ |
TCL.Tcl_BackgroundError( p.interp ); |
} |
TCL.Tcl_DecrRefCount( ref pScript ); |
|
return iRes; |
} |
static int test_create_collation_v2( |
object clientdata, /* Not used */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
TestCollationX p; |
sqlite3 db = null; |
int rc; |
|
if ( objc != 5 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB-HANDLE NAME CMP-PROC DEL-PROC" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
|
p = new TestCollationX(); //(TestCollationX )sqlite3Malloc(sizeof(TestCollationX)); |
p.pCmp = objv[3]; |
p.pDel = objv[4]; |
p.interp = interp; |
TCL.Tcl_IncrRefCount( p.pCmp ); |
TCL.Tcl_IncrRefCount( p.pDel ); |
|
rc = sqlite3_create_collation_v2( db, TCL.Tcl_GetString( objv[2] ), 16, |
p, (dxCompare)testCreateCollationCmp, testCreateCollationDel |
); |
if ( rc != SQLITE_MISUSE ) |
{ |
TCL.Tcl_AppendResult( interp, "sqlite3_create_collate_v2() failed to detect " + |
"an invalid encoding" ); |
return TCL.TCL_ERROR; |
} |
rc = sqlite3_create_collation_v2( db, TCL.Tcl_GetString( objv[2] ), SQLITE_UTF8, |
p, (dxCompare)testCreateCollationCmp, testCreateCollationDel |
); |
return TCL.TCL_OK; |
} |
|
/* |
** USAGE: sqlite3_create_function_v2 DB NAME NARG ENC ?SWITCHES? |
** |
** Available switches are: |
** |
** -func SCRIPT |
** -step SCRIPT |
** -final SCRIPT |
** -destroy SCRIPT |
*/ |
//typedef struct CreateFunctionV2 CreateFunctionV2; |
public class CreateFunctionV2 |
{ |
public Tcl_Interp interp; |
public Tcl_Obj pFunc; /* Script for function invocation */ |
public Tcl_Obj pStep; /* Script for agg. step invocation */ |
public Tcl_Obj pFinal; /* Script for agg. finalization invocation */ |
public Tcl_Obj pDestroy; /* Destructor script */ |
}; |
static void cf2Func( sqlite3_context ctx, int nArg, sqlite3_value[] aArg ) |
{ |
} |
static void cf2Step( sqlite3_context ctx, int nArg, sqlite3_value[] aArg ) |
{ |
} |
static void cf2Final( sqlite3_context ctx ) |
{ |
} |
static void cf2Destroy( object pUser ) |
{ |
CreateFunctionV2 p = (CreateFunctionV2)pUser; |
|
if ( p.interp != null && p.pDestroy != null ) |
{ |
int rc = TCL.Tcl_EvalObjEx( p.interp, p.pDestroy, 0 ); |
if ( rc != TCL.TCL_OK ) |
TCL.Tcl_BackgroundError( p.interp ); |
} |
|
if ( p.pFunc != null ) |
TCL.Tcl_DecrRefCount( ref p.pFunc ); |
if ( p.pStep != null ) |
TCL.Tcl_DecrRefCount( ref p.pStep ); |
if ( p.pFinal != null ) |
TCL.Tcl_DecrRefCount( ref p.pFinal ); |
if ( p.pDestroy != null ) |
TCL.Tcl_DecrRefCount( ref p.pDestroy ); |
//sqlite3_free( p); |
} |
|
public class EncTable |
{ |
public string zEnc; |
public int enc; |
|
public EncTable( string zEnc, int enc ) |
{ |
this.zEnc = zEnc; |
this.enc = enc; |
} |
} |
|
static int test_create_function_v2( |
ClientData clientData, /* Not used */ |
Tcl_Interp interp, /* The invoking TCL interpreter */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
sqlite3 db = null; |
string zFunc; |
int nArg = 0; |
int enc = 0; |
CreateFunctionV2 p; |
int i; |
int rc; |
|
EncTable[] aEnc = { |
new EncTable("utf8", SQLITE_UTF8 ), |
new EncTable("utf16", SQLITE_UTF16 ), |
new EncTable("utf16le", SQLITE_UTF16LE ), |
new EncTable("utf16be", SQLITE_UTF16BE ), |
new EncTable("any", SQLITE_ANY ), |
new EncTable("0", 0 ) |
}; |
|
if ( objc < 5 || ( objc % 2 ) == 0 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB NAME NARG ENC SWITCHES..." ); |
return TCL.TCL_ERROR; |
} |
|
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
zFunc = TCL.Tcl_GetString( objv[2] ); |
if ( TCL.Tcl_GetIntFromObj( interp, objv[3], out nArg ) != 0 ) |
return TCL.TCL_ERROR; |
//if ( TCL.Tcl_GetIndexFromObjStruct( interp, objv[4], aEnc,//sizeof(aEnc[0]), |
// "encoding", 0, ref enc) |
//) |
int iEnc; |
for ( iEnc = 0; iEnc < aEnc.Length && ( aEnc[iEnc].zEnc != objv[4].ToString() ); iEnc++ ) |
{ |
} |
if ( iEnc >= aEnc.Length ) |
return TCL.TCL_ERROR; |
enc = aEnc[iEnc].enc; |
|
p = new CreateFunctionV2();//sqlite3_malloc( sizeof( CreateFunctionV2 ) ); |
//Debug.Assert( p ); |
//memset(p, 0, sizeof(CreateFunctionV2)); |
p.interp = interp; |
|
for ( i = 5; i < objc; i += 2 ) |
{ |
int iSwitch = 0; |
string[] azSwitch = { "-func", "-step", "-final", "-destroy", "" }; |
if ( TCL.Tcl_GetIndexFromObj( interp, objv[i], azSwitch, "switch", 0, out iSwitch ) ) |
{ |
//sqlite3_free(p); |
return TCL.TCL_ERROR; |
} |
|
switch ( iSwitch ) |
{ |
case 0: |
p.pFunc = objv[i + 1]; |
break; |
case 1: |
p.pStep = objv[i + 1]; |
break; |
case 2: |
p.pFinal = objv[i + 1]; |
break; |
case 3: |
p.pDestroy = objv[i + 1]; |
break; |
} |
} |
if ( p.pFunc != null ) |
p.pFunc = TCL.Tcl_DuplicateObj( p.pFunc ); |
if ( p.pStep != null ) |
p.pStep = TCL.Tcl_DuplicateObj( p.pStep ); |
if ( p.pFinal != null ) |
p.pFinal = TCL.Tcl_DuplicateObj( p.pFinal ); |
if ( p.pDestroy != null ) |
p.pDestroy = TCL.Tcl_DuplicateObj( p.pDestroy ); |
|
if ( p.pFunc != null ) |
TCL.Tcl_IncrRefCount( p.pFunc ); |
if ( p.pStep != null ) |
TCL.Tcl_IncrRefCount( p.pStep ); |
if ( p.pFinal != null ) |
TCL.Tcl_IncrRefCount( p.pFinal ); |
if ( p.pDestroy != null ) |
TCL.Tcl_IncrRefCount( p.pDestroy ); |
|
rc = sqlite3_create_function_v2( db, zFunc, nArg, enc, p, |
( p.pFunc != null ? (dxFunc)cf2Func : (dxFunc)null ), |
( p.pStep != null ? (dxStep)cf2Step : (dxStep)null ), |
( p.pFinal != null ? (dxFinal)cf2Final : (dxFinal)null ), |
(dxFDestroy)cf2Destroy |
); |
if ( rc != SQLITE_OK ) |
{ |
TCL.Tcl_ResetResult( interp ); |
TCL.Tcl_AppendResult( interp, sqlite3TestErrorName( rc ) ); |
return TCL.TCL_ERROR; |
} |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_load_extension DB-HANDLE FILE ?PROC? |
*/ |
//static int test_load_extension( |
// object clientdata, /* Not used */ |
// Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
// int objc, /* Number of arguments */ |
// Tcl_Obj[] objv /* Command arguments */ |
//){ |
// TCL.Tcl_CmdInfo cmdInfo; |
// sqlite3 db=null; |
// int rc; |
// string zDb; |
// string zFile; |
// string zProc = 0; |
// string zErr = 0; |
|
// if( objc!=4 && objc!=3 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE FILE ?PROC?"); |
// return TCL.TCL_ERROR; |
// } |
// zDb = TCL.Tcl_GetString(objv[1]); |
// zFile = TCL.Tcl_GetString(objv[2]); |
// if( objc==4 ){ |
// zProc = TCL.Tcl_GetString(objv[3]); |
// } |
|
// /* Extract the C database handle from the Tcl command name */ |
// if( null==TCL.Tcl_GetCommandInfo(interp, zDb, cmdInfo) ){ |
// TCL.Tcl_AppendResult(interp, "command not found: ", zDb); |
// return TCL.TCL_ERROR; |
// } |
// db = ((struct SqliteDb)cmdInfo.objclientdata).db; |
// Debug.Assert(db); |
|
// /* Call the underlying C function. If an error occurs, set rc to |
// ** TCL.TCL_ERROR and load any error string into the interpreter. If no |
// ** error occurs, set rc to TCL.TCL_OK. |
// */ |
#if SQLITE_OMIT_LOAD_EXTENSION |
// rc = SQLITE_ERROR; |
// zErr = sqlite3_mprintf("this build omits sqlite3_load_extension()"); |
#else |
// rc = sqlite3_load_extension(db, zFile, zProc, zErr); |
#endif |
// if( rc!=SQLITE_OK ){ |
// TCL.Tcl_SetResult(interp, zErr ? zErr : "", TCL.Tcl_VOLATILE); |
// rc = TCL.TCL_ERROR; |
// }else{ |
// rc = TCL.TCL_OK; |
// } |
// sqlite3DbFree(db,zErr); |
|
// return rc; |
//} |
|
/* |
** Usage: sqlite3_enable_load_extension DB-HANDLE ONOFF |
*/ |
//static int test_enable_load( |
// object clientdata, /* Not used */ |
// Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
// int objc, /* Number of arguments */ |
// Tcl_Obj[] objv /* Command arguments */ |
//){ |
// TCL.Tcl_CmdInfo cmdInfo; |
// sqlite3 db=null; |
// string zDb; |
// int onoff; |
|
// if( objc!=3 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE ONOFF"); |
// return TCL.TCL_ERROR; |
// } |
// zDb = TCL.Tcl_GetString(objv[1]); |
|
// /* Extract the C database handle from the Tcl command name */ |
// if( null==TCL.Tcl_GetCommandInfo(interp, zDb, cmdInfo) ){ |
// TCL.Tcl_AppendResult(interp, "command not found: ", zDb); |
// return TCL.TCL_ERROR; |
// } |
// db = ((struct SqliteDb)cmdInfo.objclientdata).db; |
// Debug.Assert(db); |
|
// /* Get the onoff parameter */ |
// if( TCL.Tcl_GetBooleanFromObj(interp, objv[2], out onoff) ){ |
// return TCL.TCL_ERROR; |
// } |
|
#if SQLITE_OMIT_LOAD_EXTENSION |
// TCL.Tcl_AppendResult(interp, "this build omits sqlite3_load_extension()"); |
// return TCL.TCL_ERROR; |
#else |
// sqlite3_enable_load_extension(db, onoff); |
// return TCL.TCL_OK; |
#endif |
//} |
|
/* |
** Usage: sqlite_abort |
** |
** Shutdown the process immediately. This is not a clean shutdown. |
** This command is used to test the recoverability of a database in |
** the event of a program crash. |
*/ |
//static int sqlite_abort( |
// object NotUsed, |
// Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
// int argc, /* Number of arguments */ |
// Tcl_Obj[] argv /* Text of each argument */ |
//){ |
//#if defined(_MSC_VER) |
// /* We do this, otherwise the test will halt with a popup message |
// * that we have to click away before the test will continue. |
// */ |
// _set_abort_behavior( 0, _CALL_REPORTFAULT ); |
//#endif |
// exit(255); |
// Debug.Assert( interp==0 ); /* This will always fail */ |
// return TCL.TCL_OK; |
//} |
|
/* |
** The following routine is a user-defined SQL function whose purpose |
** is to test the sqlite_set_result() API. |
*/ |
static void testFunc( sqlite3_context context, int argc, sqlite3_value[] argv ) |
{ |
int ARGV = 0; |
while ( argc >= 2 ) |
{ |
string zArg0 = sqlite3_value_text( argv[ARGV] ); |
if ( zArg0 != null ) |
{ |
if ( zArg0.Equals( "int", StringComparison.InvariantCultureIgnoreCase ) ) |
{ |
sqlite3_result_int( context, sqlite3_value_int( argv[ARGV + 1] ) ); |
} |
else if ( zArg0.Equals( "int64", StringComparison.InvariantCultureIgnoreCase ) ) |
{ |
sqlite3_result_int64( context, sqlite3_value_int64( argv[ARGV + 1] ) ); |
} |
else if ( zArg0.Equals( "string", StringComparison.InvariantCultureIgnoreCase ) ) |
{ |
sqlite3_result_text( context, sqlite3_value_text( argv[ARGV + 1] ), -1, |
SQLITE_TRANSIENT ); |
} |
else if ( zArg0.Equals( "double", StringComparison.InvariantCultureIgnoreCase ) ) |
{ |
sqlite3_result_double( context, sqlite3_value_double( argv[ARGV + 1] ) ); |
} |
else if ( zArg0.Equals( "null", StringComparison.InvariantCultureIgnoreCase ) ) |
{ |
sqlite3_result_null( context ); |
} |
else if ( zArg0.Equals( "value", StringComparison.InvariantCultureIgnoreCase ) ) |
{ |
sqlite3_result_value( context, argv[sqlite3_value_int( argv[ARGV + 1] )] ); |
} |
else |
{ |
goto error_out; |
} |
} |
else |
{ |
goto error_out; |
} |
argc -= 2; |
ARGV += 2; |
} |
return; |
|
error_out: |
sqlite3_result_error( context, "first argument should be one of: " + |
"int int64 string double null value", -1 ); |
} |
|
/* |
** Usage: sqlite_register_test_function DB NAME |
** |
** Register the test SQL function on the database DB under the name NAME. |
*/ |
static int test_register_func( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
sqlite3 db = null; |
int rc; |
if ( argc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" DB FUNCTION-NAME" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
rc = sqlite3_create_function( db, argv[2].ToString(), -1, SQLITE_UTF8, 0, |
testFunc, null, null ); |
if ( rc != 0 ) |
{ |
TCL.Tcl_AppendResult( interp, sqlite3ErrStr( rc ) ); |
return TCL.TCL_ERROR; |
} |
if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
return TCL.TCL_ERROR; |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_finalize STMT |
** |
** Finalize a statement handle. |
*/ |
static int test_finalize( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
int rc; |
sqlite3 db = null; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " <STMT>" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
|
if ( pStmt != null ) |
{ |
db = sqlite3_db_handle( pStmt );// StmtToDb( pStmt ); |
} |
rc = sqlite3_finalize( pStmt ); |
TCL.Tcl_SetResult( interp, sqlite3TestErrorName( rc ), TCL.TCL_STATIC );//t1ErrorName( rc ), TCL.TCL_STATIC ); |
if ( db != null && sqlite3TestErrCode( interp, db, rc ) != 0 ) |
return TCL.TCL_ERROR; |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_stmt_status STMT CODE RESETFLAG |
** |
** Get the value of a status counter from a statement. |
*/ |
static int test_stmt_status( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
int iValue; |
int i, op = 0; |
bool resetFlag = false; |
string zOpName; |
sqlite3_stmt pStmt = null; |
|
//struct _aOp{ |
// string zName; |
// int op; |
//} |
_aOp[] aOp = { |
new _aOp( "SQLITE_STMTSTATUS_FULLSCAN_STEP", SQLITE_STMTSTATUS_FULLSCAN_STEP ), |
new _aOp( "SQLITE_STMTSTATUS_SORT", SQLITE_STMTSTATUS_SORT ), |
new _aOp( "SQLITE_STMTSTATUS_AUTOINDEX", SQLITE_STMTSTATUS_AUTOINDEX ) |
}; |
|
if ( objc != 4 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT PARAMETER RESETFLAG" ); |
return TCL.TCL_ERROR; |
} |
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
zOpName = TCL.Tcl_GetString( objv[2] ); |
for ( i = 0; i < ArraySize( aOp ); i++ ) |
{ |
if ( aOp[i].zName == zOpName ) |
{ |
op = aOp[i].op; |
break; |
} |
} |
if ( i >= ArraySize( aOp ) ) |
{ |
if ( TCL.Tcl_GetIntFromObj( interp, objv[2], out op ) != 0 ) |
return TCL.TCL_ERROR; |
} |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[3], out resetFlag ) ) |
return TCL.TCL_ERROR; |
iValue = sqlite3_stmt_status( pStmt, op, resetFlag ? 1 : 0 ); |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( iValue ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_next_stmt DB STMT |
** |
** Return the next statment in sequence after STMT. |
*/ |
static int test_next_stmt( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
sqlite3 db = null; |
StringBuilder zBuf = new StringBuilder( 50 ); |
if ( objc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " DB STMT" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[2] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
pStmt = sqlite3_next_stmt( db, pStmt ); |
if ( pStmt != null ) |
{ |
if ( sqlite3TestMakePointerStr( interp, zBuf, pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
TCL.Tcl_AppendResult( interp, zBuf ); |
} |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_stmt_readonly STMT |
** |
** Return true if STMT is a NULL pointer or a pointer to a statement |
** that is guaranteed to leave the database unmodified. |
*/ |
static int test_stmt_readonly( |
object clientData, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
int rc; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT", 0 ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
rc = sqlite3_stmt_readonly( pStmt ) ? 1 : 0; |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewBooleanObj( rc ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: uses_stmt_journal STMT |
** |
** Return true if STMT uses a statement journal. |
*/ |
static int uses_stmt_journal( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
int rc; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT", 0 ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
rc = sqlite3_stmt_readonly( pStmt ) ? 1 : 0; |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewBooleanObj( pStmt.usesStmtJournal ? 1 : 0 ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_reset STMT |
** |
** Reset a statement handle. |
*/ |
static int test_reset( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
int rc; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " <STMT>" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
|
rc = sqlite3_reset( pStmt ); |
if ( pStmt != null && sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
{ |
return TCL.TCL_ERROR; |
} |
TCL.Tcl_SetResult( interp, t1ErrorName( rc ), TCL.TCL_STATIC ); |
/* |
if( rc !=0){ |
return TCL.TCL_ERROR; |
} |
*/ |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_expired STMT |
** |
** Return TRUE if a recompilation of the statement is recommended. |
*/ |
static int test_expired( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
#if !SQLITE_OMIT_DEPRECATED |
sqlite3_stmt pStmt = null; |
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " <STMT>" ); |
return TCL.TCL_ERROR; |
} |
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) return TCL.TCL_ERROR; |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewBooleanObj( sqlite3_expired( pStmt ) ) ); |
#endif |
TCL.Tcl_SetResult( interp, "0", 0 ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3TransferBindings FROMSTMT TOSTMT |
** |
** Transfer all bindings from FROMSTMT over to TOSTMT |
*/ |
static int test_transfer_bind( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
#if !SQLITE_OMIT_DEPRECATED |
sqlite3_stmt pStmt1 = null, pStmt2 = null; |
if ( objc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " FROM-STMT TO-STMT" ); |
return TCL.TCL_ERROR; |
} |
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt1 ) != 0 ) return TCL.TCL_ERROR; |
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[2] ), out pStmt2 ) != 0 ) return TCL.TCL_ERROR; |
TCL.Tcl_SetObjResult( interp, |
TCL.Tcl_NewIntObj( pStmt1.nVar == pStmt2.nVar ? sqlite3TransferBindings( pStmt1, pStmt2 ) : TCL.TCL_ERROR ) ); |
#endif |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_changes DB |
** |
** Return the number of changes made to the database by the last SQL |
** execution. |
*/ |
static int test_changes( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3 db = null; |
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " DB" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_changes( db ) ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** This is the "static_bind_value" that variables are bound to when |
** the FLAG option of sqlite3_bind is "static" |
*/ |
//static string sqlite_static_bind_value = ""; |
//static int sqlite_static_bind_nbyte = 0; |
|
/* |
** Usage: sqlite3_bind VM IDX VALUE FLAGS |
** |
** Sets the value of the IDX-th occurance of "?" in the original SQL |
** string. VALUE is the new value. If FLAGS=="null" then VALUE is |
** ignored and the value is set to NULL. If FLAGS=="static" then |
** the value is set to the value of a static variable named |
** "sqlite_static_bind_value". If FLAGS=="normal" then a copy |
** of the VALUE is made. If FLAGS=="blob10" then a VALUE is ignored |
** an a 10-byte blob "abc\000xyz\000pq" is inserted. |
*/ |
static int test_bind( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
sqlite3_stmt pStmt = null; |
int rc; |
int idx = 0; |
if ( argc != 5 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" VM IDX VALUE (null|static|normal)\"" ); |
return TCL.TCL_ERROR; |
} |
if ( getStmtPointer( interp, argv[1].ToString(), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.Tcl_GetInt( interp, argv[2], out idx ) ) |
return TCL.TCL_ERROR; |
if ( argv[4].ToString() == "null" ) |
{ |
rc = sqlite3_bind_null( pStmt, idx ); |
} |
else if ( argv[4].ToString() == "static" ) |
{ |
rc = sqlite3_bind_text( pStmt, idx, sqlite_static_bind_value.sValue, -1, null ); |
} |
else if ( argv[4].ToString() == "static-nbytes" ) |
{ |
rc = sqlite3_bind_text( pStmt, idx, sqlite_static_bind_value.sValue, |
sqlite_static_bind_nbyte.iValue, null ); |
} |
else if ( argv[4].ToString() == "normal" ) |
{ |
rc = sqlite3_bind_text( pStmt, idx, argv[3].ToString(), -1, SQLITE_TRANSIENT ); |
} |
else if ( argv[4].ToString() == "blob10" ) |
{ |
rc = sqlite3_bind_text( pStmt, idx, "abc\0xyz\0pq", 10, SQLITE_STATIC ); |
} |
else |
{ |
TCL.Tcl_AppendResult( interp, "4th argument should be " + |
"\"null\" or \"static\" or \"normal\"" ); |
return TCL.TCL_ERROR; |
} |
if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
return TCL.TCL_ERROR; |
if ( rc != 0 ) |
{ |
StringBuilder zBuf = new StringBuilder( 50 ); |
sqlite3_snprintf( 50, zBuf, "(%d) ", rc ); |
TCL.Tcl_SetResult( interp, zBuf + sqlite3ErrStr( rc ), 0 ); |
return TCL.TCL_ERROR; |
} |
return TCL.TCL_OK; |
} |
|
#if !SQLITE_OMIT_UTF16 |
/* |
** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be> |
** |
** This function is used to test that SQLite selects the correct collation |
** sequence callback when multiple versions (for different text encodings) |
** are available. |
** |
** Calling this routine registers the collation sequence "test_collate" |
** with database handle <db>. The second argument must be a list of three |
** boolean values. If the first is true, then a version of test_collate is |
** registered for UTF-8, if the second is true, a version is registered for |
** UTF-16le, if the third is true, a UTF-16be version is available. |
** Previous versions of test_collate are deleted. |
** |
** The collation sequence test_collate is implemented by calling the |
** following TCL script: |
** |
** "test_collate <enc> <lhs> <rhs>" |
** |
** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8. |
** The <enc> parameter is the encoding of the collation function that |
** SQLite selected to call. The TCL test script implements the |
** "test_collate" proc. |
** |
** Note that this will only work with one intepreter at a time, as the |
** interp pointer to use when evaluating the TCL script is stored in |
** pTestCollateInterp. |
*/ |
//static Tcl_Interp * pTestCollateInterp; |
//static int test_collate_func( |
// object pCtx,, |
// int nA, string zA, |
// int nB, string zB |
//){ |
// Tcl_Interp *i = pTestCollateInterp; |
// int encin = SQLITE_PTR_TO_INT(pCtx); |
// int res; |
// int n; |
|
// sqlite3_value pVal; |
// Tcl_Obj pX; |
|
// pX = TCL.Tcl_NewStringObj("test_collate", -1); |
// TCL.Tcl_IncrRefCount(pX); |
|
// switch( encin ){ |
// case SQLITE_UTF8: |
// TCL.Tcl_ListObjAppendElement(i,pX,TCL.Tcl_NewStringObj("UTF-8",-1)); |
// break; |
// case SQLITE_UTF16LE: |
// TCL.Tcl_ListObjAppendElement(i,pX,TCL.Tcl_NewStringObj("UTF-16LE",-1)); |
// break; |
// case SQLITE_UTF16BE: |
// TCL.Tcl_ListObjAppendElement(i,pX,TCL.Tcl_NewStringObj("UTF-16BE",-1)); |
// break; |
// default: |
// Debug.Assert(false); |
// } |
|
//sqlite3BeginBenignMalloc(); |
// pVal = sqlite3ValueNew(0); |
// if( pVal ){ |
// sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC); |
// n = sqlite3_value_bytes(pVal); |
// TCL.Tcl_ListObjAppendElement(i,pX, |
// TCL.Tcl_NewStringObj((char)sqlite3_value_text(pVal),n)); |
// sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC); |
// n = sqlite3_value_bytes(pVal); |
// TCL.Tcl_ListObjAppendElement(i,pX, |
// TCL.Tcl_NewStringObj((char)sqlite3_value_text(pVal),n)); |
// sqlite3ValueFree(pVal); |
//} |
//sqlite3EndBenignMalloc(); |
|
// TCL.Tcl_EvalObjEx(i, pX, 0); |
// TCL.Tcl_DecrRefCount(pX); |
// TCL.Tcl_GetIntFromObj(i, TCL.Tcl_GetObjResult(i), res); |
// return res; |
//} |
//static int test_collate( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// sqlite3 db=null; |
// int val; |
// sqlite3_value pVal; |
// int rc; |
|
// if( objc!=5 ) goto bad_args; |
// pTestCollateInterp = interp; |
// if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR; |
|
// if( TCL.TCL_OK!=TCL.Tcl_GetBooleanFromObj(interp, objv[2], out val) ) return TCL.TCL_ERROR; |
// rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8, |
// (void )SQLITE_UTF8, val?test_collate_func:0); |
// if( rc==SQLITE_OK ){ |
// string zUtf16; |
// if( TCL.TCL_OK!=TCL.Tcl_GetBooleanFromObj(interp, objv[3], out val) ) return TCL.TCL_ERROR; |
// rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE, |
// (void )SQLITE_UTF16LE, val?test_collate_func:0); |
// if( TCL.TCL_OK!=TCL.Tcl_GetBooleanFromObj(interp, objv[4], out val) ) return TCL.TCL_ERROR; |
|
//#if FALSE |
// if( sqlite3_iMallocFail>0 ){ |
// sqlite3_iMallocFail++; |
// } |
//#endif |
// sqlite3_mutex_enter(db.mutex); |
// pVal = sqlite3ValueNew(db); |
// sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC); |
// zUtf16 = sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); |
// if( db.mallocFailed !=0{ |
// rc = SQLITE_NOMEM; |
// }else{ |
// rc = sqlite3_create_collation16(db, zUtf16, SQLITE_UTF16BE, |
// (void )SQLITE_UTF16BE, val?test_collate_func:0); |
// } |
// sqlite3ValueFree(pVal); |
// sqlite3_mutex_leave(db.mutex); |
// } |
// if( sqlite3TestErrCode(interp, db, rc) ) return TCL.TCL_ERROR; |
|
// if( rc!=SQLITE_OK ){ |
// TCL.Tcl_AppendResult(interp, sqlite3TestErrorName(rc)); |
// return TCL.TCL_ERROR; |
// } |
// return TCL.TCL_OK; |
|
//bad_args: |
// TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
// TCL.Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); |
// return TCL.TCL_ERROR; |
//} |
|
/* |
** When the collation needed callback is invoked, record the name of |
** the requested collating function here. The recorded name is linked |
** to a TCL variable and used to make sure that the requested collation |
** name is correct. |
*/ |
//static char zNeededCollation[200]; |
//static char pzNeededCollation = zNeededCollation; |
|
|
/* |
** Called when a collating sequence is needed. Registered using |
** sqlite3_collation_needed16(). |
*/ |
//static void test_collate_needed_cb( |
// object pCtx,, |
// sqlite3 db, |
// int eTextRep, |
// const void pName |
//){ |
// int enc = ENC(db); |
// int i; |
// string z; |
// for(z = (char)pName, i=0; *z || z[1]; z++){ |
// if( *z ) zNeededCollation[i++] = *z; |
// } |
// zNeededCollation[i] = 0; |
// sqlite3_create_collation( |
// db, "test_collate", ENC(db), SQLITE_INT_TO_PTR(enc), test_collate_func); |
//} |
|
/* |
** Usage: add_test_collate_needed DB |
*/ |
//static int test_collate_needed( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// sqlite3 db=null; |
// int rc; |
|
// if( objc!=2 ) goto bad_args; |
// if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR; |
// rc = sqlite3_collation_needed16(db, 0, test_collate_needed_cb); |
// zNeededCollation[0] = 0; |
// if( sqlite3TestErrCode(interp, db, rc) ) return TCL.TCL_ERROR; |
// return TCL.TCL_OK; |
|
//bad_args: |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "DB"); |
// return TCL.TCL_ERROR; |
//} |
|
/* |
** tclcmd: add_alignment_test_collations DB |
** |
** Add two new collating sequences to the database DB |
** |
** utf16_aligned |
** utf16_unaligned |
** |
** Both collating sequences use the same sort order as BINARY. |
** The only difference is that the utf16_aligned collating |
** sequence is declared with the SQLITE_UTF16_ALIGNED flag. |
** Both collating functions increment the unaligned utf16 counter |
** whenever they see a string that begins on an odd byte boundary. |
*/ |
//static int unaligned_string_counter = 0; |
//static int alignmentCollFunc( |
// object NotUsed, |
// int nKey1, const void pKey1, |
// int nKey2, const void pKey2 |
//){ |
// int rc, n; |
// n = nKey1<nKey2 ? nKey1 : nKey2; |
//if( nKey1>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey1))) ) unaligned_string_counter++; |
//if( nKey2>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey2))) ) unaligned_string_counter++; |
// rc = memcmp(pKey1, pKey2, n); |
// if( rc==0 ){ |
// rc = nKey1 - nKey2; |
// } |
// return rc; |
//} |
//static int add_alignment_test_collations( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// sqlite3 db=null; |
// if( objc>=2 ){ |
// if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR; |
// sqlite3_create_collation(db, "utf16_unaligned", SQLITE_UTF16, |
// 0, alignmentCollFunc); |
// sqlite3_create_collation(db, "utf16_aligned", SQLITE_UTF16_ALIGNED, |
// 0, alignmentCollFunc); |
// } |
// return SQLITE_OK; |
//} |
#endif // * !SQLITE_OMIT_UTF16) */ |
|
/* |
** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be> |
** |
** This function is used to test that SQLite selects the correct user |
** function callback when multiple versions (for different text encodings) |
** are available. |
** |
** Calling this routine registers up to three versions of the user function |
** "test_function" with database handle <db>. If the second argument is |
** true, then a version of test_function is registered for UTF-8, if the |
** third is true, a version is registered for UTF-16le, if the fourth is |
** true, a UTF-16be version is available. Previous versions of |
** test_function are deleted. |
** |
** The user function is implemented by calling the following TCL script: |
** |
** "test_function <enc> <arg>" |
** |
** Where <enc> is one of UTF-8, UTF-16LE or UTF16BE, and <arg> is the |
** single argument passed to the SQL function. The value returned by |
** the TCL script is used as the return value of the SQL function. It |
** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8 |
** for a UTF-16LE test_function(), and UTF-16LE for an implementation that |
** prefers UTF-16BE. |
*/ |
#if !SQLITE_OMIT_UTF16 |
//static void test_function_utf8( |
// sqlite3_context pCtx, |
// int nArg, |
// sqlite3_value[] argv |
//){ |
// Tcl_Interp interp; |
// Tcl_Obj pX; |
// sqlite3_value pVal; |
// interp = (Tcl_Interp )sqlite3_context_db_handle(pCtx); |
// pX = TCL.Tcl_NewStringObj("test_function", -1); |
// TCL.Tcl_IncrRefCount(pX); |
// TCL.Tcl_ListObjAppendElement(interp, pX, TCL.Tcl_NewStringObj("UTF-8", -1)); |
// TCL.Tcl_ListObjAppendElement(interp, pX, |
// TCL.Tcl_NewStringObj((char)sqlite3_value_text(argv[0]), -1)); |
// TCL.Tcl_EvalObjEx(interp, pX, 0); |
// TCL.Tcl_DecrRefCount(pX); |
// sqlite3_result_text(pCtx, TCL.Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT); |
// pVal = sqlite3ValueNew(0); |
// sqlite3ValueSetStr(pVal, -1, TCL.Tcl_GetStringResult(interp), |
// SQLITE_UTF8, SQLITE_STATIC); |
// sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal), |
// -1, SQLITE_TRANSIENT); |
// sqlite3ValueFree(pVal); |
//} |
//static void test_function_utf16le( |
// sqlite3_context pCtx, |
// int nArg, |
// sqlite3_value[] argv |
//){ |
// Tcl_Interp interp; |
// Tcl_Obj pX; |
// sqlite3_value pVal; |
// interp = (Tcl_Interp )sqlite3_context_db_handle(pCtx); |
// pX = TCL.Tcl_NewStringObj("test_function", -1); |
// TCL.Tcl_IncrRefCount(pX); |
// TCL.Tcl_ListObjAppendElement(interp, pX, TCL.Tcl_NewStringObj("UTF-16LE", -1)); |
// TCL.Tcl_ListObjAppendElement(interp, pX, |
// TCL.Tcl_NewStringObj((char)sqlite3_value_text(argv[0]), -1)); |
// TCL.Tcl_EvalObjEx(interp, pX, 0); |
// TCL.Tcl_DecrRefCount(pX); |
// pVal = sqlite3ValueNew(0); |
// sqlite3ValueSetStr(pVal, -1, TCL.Tcl_GetStringResult(interp), |
// SQLITE_UTF8, SQLITE_STATIC); |
// sqlite3_result_text(pCtx,(char)sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT); |
// sqlite3ValueFree(pVal); |
//} |
//static void test_function_utf16be( |
// sqlite3_context pCtx, |
// int nArg, |
// sqlite3_value[] argv |
//){ |
// Tcl_Interp interp; |
// Tcl_Obj pX; |
// sqlite3_value pVal; |
// interp = (Tcl_Interp )sqlite3_context_db_handle(pCtx); |
// pX = TCL.Tcl_NewStringObj("test_function", -1); |
// TCL.Tcl_IncrRefCount(pX); |
// TCL.Tcl_ListObjAppendElement(interp, pX, TCL.Tcl_NewStringObj("UTF-16BE", -1)); |
// TCL.Tcl_ListObjAppendElement(interp, pX, |
// TCL.Tcl_NewStringObj((char)sqlite3_value_text(argv[0]), -1)); |
// TCL.Tcl_EvalObjEx(interp, pX, 0); |
// TCL.Tcl_DecrRefCount(pX); |
// pVal = sqlite3ValueNew(0); |
// sqlite3ValueSetStr(pVal, -1, TCL.Tcl_GetStringResult(interp), |
// SQLITE_UTF8, SQLITE_STATIC); |
// sqlite3_result_text16(pCtx, sqlite3_value_text16le(pVal), |
// -1, SQLITE_TRANSIENT); |
// sqlite3_result_text16be(pCtx, sqlite3_value_text16le(pVal), |
// -1, SQLITE_TRANSIENT); |
// sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal), |
// -1, SQLITE_TRANSIENT); |
// sqlite3ValueFree(pVal); |
//} |
#endif // * SQLITE_OMIT_UTF16 */ |
//static int test_function( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
#if !SQLITE_OMIT_UTF16 |
// sqlite3 db=null; |
// int val; |
|
// if( objc!=5 ) goto bad_args; |
// if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR; |
|
// if( TCL.TCL_OK!=TCL.Tcl_GetBooleanFromObj(interp, objv[2], out val) ) return TCL.TCL_ERROR; |
// if( val ){ |
// sqlite3_create_function(db, "test_function", 1, SQLITE_UTF8, |
// interp, test_function_utf8, 0, 0); |
// } |
// if( TCL.TCL_OK!=TCL.Tcl_GetBooleanFromObj(interp, objv[3], out val) ) return TCL.TCL_ERROR; |
// if( val ){ |
// sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16LE, |
// interp, test_function_utf16le, 0, 0); |
// } |
// if( TCL.TCL_OK!=TCL.Tcl_GetBooleanFromObj(interp, objv[4], out val) ) return TCL.TCL_ERROR; |
// if( val ){ |
// sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16BE, |
// interp, test_function_utf16be, 0, 0); |
// } |
|
// return TCL.TCL_OK; |
//bad_args: |
// TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
// TCL.Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); |
#endif // * SQLITE_OMIT_UTF16 */ |
// return TCL.TCL_ERROR; |
//} |
|
/* |
** Usage: test_errstr <err code> |
** |
** Test that the english language string equivalents for sqlite error codes |
** are sane. The parameter is an integer representing an sqlite error code. |
** The result is a list of two elements, the string representation of the |
** error code and the english language explanation. |
*/ |
static int test_errstr( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
string zCode; |
int i; |
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "<error code>" ); |
} |
|
zCode = TCL.Tcl_GetString( objv[1] ); |
for ( i = 0; i < 200; i++ ) |
{ |
if ( t1ErrorName( i ).Equals( zCode ) ) |
break; |
} |
TCL.Tcl_SetResult( interp, sqlite3ErrStr( i ), 0 ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: breakpoint |
** |
** This routine exists for one purpose - to provide a place to put a |
** breakpoint with GDB that can be triggered using TCL code. The use |
** for this is when a particular test fails on (say) the 1485th iteration. |
** In the TCL test script, we can add code like this: |
** |
** if {$i==1485} breakpoint |
** |
** Then run testfixture in the debugger and wait for the breakpoint to |
** fire. Then additional breakpoints can be set to trace down the bug. |
*/ |
static int test_breakpoint( |
object NotUsed, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int argc, /* Number of arguments */ |
Tcl_Obj[] argv /* Text of each argument */ |
) |
{ |
return TCL.TCL_OK; /* Do nothing */ |
} |
|
/* |
** Usage: sqlite3_bind_zeroblob STMT IDX N |
** |
** Test the sqlite3_bind_zeroblob interface. STMT is a prepared statement. |
** IDX is the index of a wildcard in the prepared statement. This command |
** binds a N-byte zero-filled BLOB to the wildcard. |
*/ |
static int test_bind_zeroblob( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
int idx = 0; |
int n = 0; |
int rc; |
|
if ( objc != 4 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT IDX N" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out idx ) ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[3], out n ) ) |
return TCL.TCL_ERROR; |
|
rc = sqlite3_bind_zeroblob( pStmt, idx, n ); |
if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
return TCL.TCL_ERROR; |
if ( rc != SQLITE_OK ) |
{ |
return TCL.TCL_ERROR; |
} |
|
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_bind_int STMT N VALUE |
** |
** Test the sqlite3_bind_int interface. STMT is a prepared statement. |
** N is the index of a wildcard in the prepared statement. This command |
** binds a 32-bit integer VALUE to that wildcard. |
*/ |
static int test_bind_int( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
int idx = 0; |
int value = 0; |
int rc; |
|
if ( objc != 4 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT N VALUE" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out idx ) ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[3], out value ) ) |
return TCL.TCL_ERROR; |
|
rc = sqlite3_bind_int( pStmt, idx, value ); |
if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
return TCL.TCL_ERROR; |
if ( rc != SQLITE_OK ) |
{ |
return TCL.TCL_ERROR; |
} |
|
return TCL.TCL_OK; |
} |
|
|
/* |
** Usage: sqlite3_bind_int64 STMT N VALUE |
** |
** Test the sqlite3_bind_int64 interface. STMT is a prepared statement. |
** N is the index of a wildcard in the prepared statement. This command |
** binds a 64-bit integer VALUE to that wildcard. |
*/ |
static int test_bind_int64( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
int idx = 0; |
i64 value = 0; |
int rc; |
|
if ( objc != 4 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT N VALUE" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out idx ) ) |
return TCL.TCL_ERROR; |
if ( TCL.Tcl_GetWideIntFromObj( interp, objv[3], out value ) ) |
return TCL.TCL_ERROR; |
|
rc = sqlite3_bind_int64( pStmt, idx, value ); |
if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
return TCL.TCL_ERROR; |
if ( rc != SQLITE_OK ) |
{ |
return TCL.TCL_ERROR; |
} |
|
return TCL.TCL_OK; |
} |
|
|
/* |
** Usage: sqlite3_bind_double STMT N VALUE |
** |
** Test the sqlite3_bind_double interface. STMT is a prepared statement. |
** N is the index of a wildcard in the prepared statement. This command |
** binds a 64-bit integer VALUE to that wildcard. |
*/ |
class _aSpecialFp |
{ |
public string zName; /* Name of the special floating point value */ |
public u32 iUpper; /* Upper 32 bits */ |
public u32 iLower; /* Lower 32 bits */ |
public _aSpecialFp( string zName, u32 iUpper, u32 iLower ) |
{ |
this.zName = zName; |
this.iUpper = iUpper; |
this.iLower = iLower; |
} |
} |
|
static int test_bind_double( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
; |
int idx = 0; |
double value = 0; |
int rc; |
string zVal; |
int i; |
_aSpecialFp[] aSpecialFp = new _aSpecialFp[] { |
new _aSpecialFp( "NaN", 0x7fffffff, 0xffffffff ), |
new _aSpecialFp( "SNaN", 0x7ff7ffff, 0xffffffff ), |
new _aSpecialFp( "-NaN", 0xffffffff, 0xffffffff ), |
new _aSpecialFp( "-SNaN", 0xfff7ffff, 0xffffffff ), |
new _aSpecialFp( "+Inf", 0x7ff00000, 0x00000000 ), |
new _aSpecialFp( "-Inf", 0xfff00000, 0x00000000 ), |
new _aSpecialFp( "Epsilon", 0x00000000, 0x00000001 ), |
new _aSpecialFp( "-Epsilon", 0x80000000, 0x00000001 ), |
new _aSpecialFp( "NaN0", 0x7ff80000, 0x00000000 ), |
new _aSpecialFp( "-NaN0", 0xfff80000, 0x00000000 ), |
}; |
|
if ( objc != 4 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT N VALUE" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out idx ) ) |
return TCL.TCL_ERROR; |
|
/* Intercept the string "NaN" and generate a NaN value for it. |
** All other strings are passed through to TCL.Tcl_GetDoubleFromObj(). |
** TCL.Tcl_GetDoubleFromObj() should understand "NaN" but some versions |
** contain a bug. |
*/ |
zVal = TCL.Tcl_GetString( objv[3] ); |
for ( i = 0; i < aSpecialFp.Length; i++ ) |
{//sizeof(aSpecialFp)/sizeof(aSpecialFp[0]); i++){ |
if ( aSpecialFp[i].zName == zVal ) |
{ |
i64 x; |
x = aSpecialFp[i].iUpper; |
x <<= 32; |
x |= aSpecialFp[i].iLower; |
Debug.Assert( sizeof( double ) == 8 ); |
Debug.Assert( sizeof( sqlite3_u3264 ) == 8 ); |
#if WINDOWS_PHONE |
value = BitConverter.ToDouble(BitConverter.GetBytes((long)x), 0); |
#else |
value = BitConverter.Int64BitsToDouble( x );//memcpy(&value, x, 8); |
#endif |
//value = Double.NaN; |
break; |
} |
} |
if ( ( i >= aSpecialFp.Length ) && //sizeof(aSpecialFp)/sizeof(aSpecialFp[0]) && |
TCL.Tcl_GetDoubleFromObj( interp, objv[3], out value ) ) |
{ |
return TCL.TCL_ERROR; |
} |
rc = sqlite3_bind_double( pStmt, idx, value ); |
if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
return TCL.TCL_ERROR; |
if ( rc != SQLITE_OK ) |
{ |
return TCL.TCL_ERROR; |
} |
|
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_bind_null STMT N |
** |
** Test the sqlite3_bind_null interface. STMT is a prepared statement. |
** N is the index of a wildcard in the prepared statement. This command |
** binds a NULL to the wildcard. |
*/ |
static int test_bind_null( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
; |
int idx = 0; |
int rc; |
|
if ( objc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT N" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out idx ) ) |
return TCL.TCL_ERROR; |
|
rc = sqlite3_bind_null( pStmt, idx ); |
if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
return TCL.TCL_ERROR; |
if ( rc != SQLITE_OK ) |
{ |
return TCL.TCL_ERROR; |
} |
|
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_bind_text STMT N STRING BYTES |
** |
** Test the sqlite3_bind_text interface. STMT is a prepared statement. |
** N is the index of a wildcard in the prepared statement. This command |
** binds a UTF-8 string STRING to the wildcard. The string is BYTES bytes |
** long. |
*/ |
static int test_bind_text( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
int idx = 0; |
int bytes = 0; |
byte[] value; |
int rc; |
|
if ( objc != 5 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT N VALUE BYTES" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out idx ) ) |
return TCL.TCL_ERROR; |
value = TCL.Tcl_GetByteArrayFromObj( objv[3], out bytes ); |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[4], out bytes ) ) |
return TCL.TCL_ERROR; |
|
rc = sqlite3_bind_text( pStmt, idx, Encoding.UTF8.GetString( value, 0, value.Length ), bytes, SQLITE_TRANSIENT ); |
if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
return TCL.TCL_ERROR; |
if ( rc != SQLITE_OK ) |
{ |
TCL.Tcl_AppendResult( interp, sqlite3TestErrorName( rc ) ); |
return TCL.TCL_ERROR; |
} |
|
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_bind_text16 ?-static? STMT N STRING BYTES |
** |
** Test the sqlite3_bind_text16 interface. STMT is a prepared statement. |
** N is the index of a wildcard in the prepared statement. This command |
** binds a UTF-16 string STRING to the wildcard. The string is BYTES bytes |
** long. |
*/ |
static int test_bind_text16( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
#if !SQLITE_OMIT_UTF16 |
sqlite3_stmt pStmt=null; |
int idx=0; |
int bytes=0; |
string value; |
int rc; |
|
dxDel xDel = (objc==6?SQLITE_STATIC:SQLITE_TRANSIENT); |
Tcl_Obj oStmt = objv[objc-4]; |
Tcl_Obj oN = objv[objc-3]; |
Tcl_Obj oString = objv[objc-2]; |
Tcl_Obj oBytes = objv[objc-1]; |
|
if( objc!=5 && objc!=6){ |
TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0); |
return TCL.TCL_ERROR; |
} |
|
if( getStmtPointer(interp, TCL.Tcl_GetString(oStmt), out pStmt)!=0 ) return TCL.TCL_ERROR; |
if( TCL.Tcl_GetIntFromObj(interp, oN, out idx) ) return TCL.TCL_ERROR; |
int dummy0 = 0; |
value = Encoding.UTF8.GetString(TCL.Tcl_GetByteArrayFromObj( oString, out dummy0 )); |
if( TCL.Tcl_GetIntFromObj(interp, oBytes, out bytes) ) return TCL.TCL_ERROR; |
|
rc = sqlite3_bind_text16(pStmt, idx, value, bytes, xDel); |
if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) !=0) return TCL.TCL_ERROR; |
if( rc!=SQLITE_OK ){ |
TCL.Tcl_AppendResult(interp, sqlite3TestErrorName(rc)); |
return TCL.TCL_ERROR; |
} |
|
#endif // * SQLITE_OMIT_UTF16 */ |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_bind_blob ?-static? STMT N DATA BYTES |
** |
** Test the sqlite3_bind_blob interface. STMT is a prepared statement. |
** N is the index of a wildcard in the prepared statement. This command |
** binds a BLOB to the wildcard. The BLOB is BYTES bytes in size. |
*/ |
static int test_bind_blob( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
int idx = 0; |
int bytes = 0; |
byte[] value; |
int rc; |
dxDel xDestructor = SQLITE_TRANSIENT; |
|
int iObjv = 0; |
if ( objc != 5 && objc != 6 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT N DATA BYTES" ); |
return TCL.TCL_ERROR; |
} |
|
if ( objc == 6 ) |
{ |
xDestructor = SQLITE_STATIC; |
iObjv++; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[iObjv + 1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[iObjv + 2], out idx ) ) |
return TCL.TCL_ERROR; |
value = Encoding.UTF8.GetBytes( TCL.Tcl_GetString( objv[iObjv + 3] ) ); |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[iObjv + 4], out bytes ) ) |
return TCL.TCL_ERROR; |
|
rc = sqlite3_bind_blob( pStmt, idx, value, bytes, xDestructor ); |
if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
return TCL.TCL_ERROR; |
if ( rc != SQLITE_OK ) |
{ |
return TCL.TCL_ERROR; |
} |
|
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_bind_parameter_count STMT |
** |
** Return the number of wildcards in the given statement. |
*/ |
static int test_bind_parameter_count( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT" ); |
return TCL.TCL_ERROR; |
} |
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_bind_parameter_count( pStmt ) ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_bind_parameter_name STMT N |
** |
** Return the name of the Nth wildcard. The first wildcard is 1. |
** An empty string is returned if N is out of range or if the wildcard |
** is nameless. |
*/ |
static int test_bind_parameter_name( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
int i = 0; |
|
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT N" ); |
return TCL.TCL_ERROR; |
} |
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out i ) ) |
return TCL.TCL_ERROR; |
TCL.Tcl_SetObjResult( interp, |
TCL.Tcl_NewStringObj( sqlite3_bind_parameter_name( pStmt, i ), -1 ) |
); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_bind_parameter_index STMT NAME |
** |
** Return the index of the wildcard called NAME. Return 0 if there is |
** no such wildcard. |
*/ |
static int test_bind_parameter_index( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
|
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT NAME" ); |
return TCL.TCL_ERROR; |
} |
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
TCL.Tcl_SetObjResult( interp, |
TCL.Tcl_NewIntObj( |
sqlite3_bind_parameter_index( pStmt, TCL.Tcl_GetString( objv[2] ) ) |
) |
); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_clear_bindings STMT |
** |
*/ |
static int test_clear_bindings( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT" ); |
return TCL.TCL_ERROR; |
} |
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_clear_bindings( pStmt ) ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_sleep MILLISECONDS |
*/ |
static int test_sleep( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
int ms = 0; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "MILLISECONDS" ); |
return TCL.TCL_ERROR; |
} |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[1], out ms ) ) |
{ |
return TCL.TCL_ERROR; |
} |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_sleep( ms ) ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_extended_errcode DB |
** |
** Return the string representation of the most recent sqlite3_* API |
** error code. e.g. "SQLITE_ERROR". |
*/ |
static int test_ex_errcode( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3 db = null; |
int rc; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " DB" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
rc = sqlite3_extended_errcode( db ); |
TCL.Tcl_AppendResult( interp, t1ErrorName( rc ) ); |
return TCL.TCL_OK; |
} |
|
|
/* |
** Usage: sqlite3_errcode DB |
** |
** Return the string representation of the most recent sqlite3_* API |
** error code. e.g. "SQLITE_ERROR". |
*/ |
static int test_errcode( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3 db = null; |
int rc; |
StringBuilder zBuf = new StringBuilder( 50 ); |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " DB" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
rc = sqlite3_errcode( db ); |
if ( ( rc & 0xff ) == rc ) |
{ |
zBuf.Length = 0; |
} |
else |
{ |
sqlite3_snprintf( 30, zBuf, "+%d", rc >> 8 ); |
} |
TCL.Tcl_AppendResult( interp, t1ErrorName( rc ), zBuf ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_errmsg DB |
** |
** Returns the UTF-8 representation of the error message string for the |
** most recent sqlite3_* API call. |
*/ |
static int test_errmsg( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3 db = null; |
string zErr; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " DB" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
|
zErr = sqlite3_errmsg( db ); |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewStringObj( zErr, -1 ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: test_errmsg16 DB |
** |
** Returns the UTF-16 representation of the error message string for the |
** most recent sqlite3_* API call. This is a byte array object at the TCL |
** level, and it includes the 0x00 0x00 terminator bytes at the end of the |
** UTF-16 string. |
*/ |
//static int test_errmsg16( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
#if !SQLITE_OMIT_UTF16 |
sqlite3 db; |
string zErr; |
string z; |
int bytes = 0; |
|
if( objc!=2 ){ |
TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
TCL.Tcl_GetString(objv[0]), " DB", 0); |
return TCL.TCL_ERROR; |
} |
if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), &db) ) return TCL.TCL_ERROR; |
|
zErr = sqlite3_errmsg16(db); |
if( zErr ){ |
z = zErr; |
for(bytes=0; z[bytes] || z[bytes+1]; bytes+=2){} |
} |
TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewByteArrayObj(zErr, bytes)); |
#endif // * SQLITE_OMIT_UTF16 */ |
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: sqlite3_prepare DB sql bytes ?tailvar? |
** |
** Compile up to <bytes> bytes of the supplied SQL string <sql> using |
** database handle <DB>. The parameter <tailval> is the name of a global |
** variable that is set to the unused portion of <sql> (if any). A |
** STMT handle is returned. |
*/ |
static int test_prepare( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3 db = null; |
string zSql; |
int bytes = 0; |
string zTail = ""; |
sqlite3_stmt pStmt = null; |
StringBuilder zBuf = new StringBuilder( 50 ); |
int rc; |
|
if ( objc != 5 && objc != 4 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " DB sql bytes ?tailvar?" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
zSql = TCL.Tcl_GetString( objv[2] ); |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[3], out bytes ) ) |
return TCL.TCL_ERROR; |
|
if ( bytes > zSql.Length ) |
bytes = zSql.Length; |
rc = sqlite3_prepare( db, zSql, bytes, ref pStmt, ref zTail ); |
TCL.Tcl_ResetResult( interp ); |
if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
return TCL.TCL_ERROR; |
if ( zTail != null && objc >= 5 ) |
{ |
if ( bytes >= 0 ) |
{ |
bytes = bytes - zSql.Length - zTail.Length;// ( zTail - zSql ); |
} |
if ( zTail.Length < bytes ) |
{ |
bytes = zTail.Length; |
} |
TCL.Tcl_ObjSetVar2( interp, objv[4], null, TCL.Tcl_NewStringObj( zTail, bytes ), 0 ); |
} |
if ( rc != SQLITE_OK ) |
{ |
Debug.Assert( pStmt == null ); |
sqlite3_snprintf( 200, zBuf, "(%d) ", rc ); |
TCL.Tcl_SetResult( interp, zBuf + sqlite3_errmsg( db ), 0 ); |
return TCL.TCL_ERROR; |
} |
|
if ( pStmt != null ) |
{ |
if ( sqlite3TestMakePointerStr( interp, zBuf, pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
TCL.Tcl_AppendResult( interp, zBuf, null ); |
} |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_prepare_v2 DB sql bytes ?tailvar? |
** |
** Compile up to <bytes> bytes of the supplied SQL string <sql> using |
** database handle <DB>. The parameter <tailval> is the name of a global |
** variable that is set to the unused portion of <sql> (if any). A |
** STMT handle is returned. |
*/ |
static int test_prepare_v2( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3 db = null; |
string zSql; |
int bytes = 0; |
string zTail = ""; |
sqlite3_stmt pStmt = null; |
StringBuilder zBuf = new StringBuilder( 50 ); |
int rc; |
|
if ( objc != 5 && objc != 4 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " DB sql bytes ?tailvar?", null ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
zSql = TCL.Tcl_GetString( objv[2] ); |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[3], out bytes ) ) |
return TCL.TCL_ERROR; |
|
rc = sqlite3_prepare_v2( db, zSql, bytes, ref pStmt, ref zTail ); |
Debug.Assert( rc == SQLITE_OK || pStmt == null ); |
TCL.Tcl_ResetResult( interp ); |
if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
return TCL.TCL_ERROR; |
if ( zTail != null && objc >= 5 ) |
{ |
if ( bytes >= 0 ) |
{ |
bytes = bytes - zSql.Length - zTail.Length;// ( zTail - zSql ); |
} |
TCL.Tcl_ObjSetVar2( interp, objv[4], null, TCL.Tcl_NewStringObj( zTail, bytes ), 0 ); |
} |
if ( rc != SQLITE_OK ) |
{ |
Debug.Assert( pStmt == null ); |
sqlite3_snprintf( 50, zBuf, "(%d) ", rc ); |
TCL.Tcl_AppendResult( interp, zBuf, sqlite3_errmsg( db ) ); |
return TCL.TCL_ERROR; |
} |
|
if ( pStmt != null ) |
{ |
if ( sqlite3TestMakePointerStr( interp, zBuf, pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
TCL.Tcl_AppendResult( interp, zBuf ); |
} |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_prepare_tkt3134 DB |
** |
** Generate a prepared statement for a zero-byte string as a test |
** for ticket #3134. The string should be preceeded by a zero byte. |
*/ |
static int test_prepare_tkt3134( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3 db = null; |
string zSql = "\000SELECT 1"; |
sqlite3_stmt pStmt = null; |
StringBuilder zBuf = new StringBuilder( 50 ); |
int rc; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " DB sql bytes tailvar" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
rc = sqlite3_prepare_v2( db, zSql.Substring( 1 ), 0, ref pStmt, 0 ); |
Debug.Assert( rc == SQLITE_OK || pStmt == null ); |
if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
return TCL.TCL_ERROR; |
if ( rc != SQLITE_OK ) |
{ |
Debug.Assert( pStmt == null ); |
zBuf.Length = 0; |
zBuf.Append( rc.ToString() ); //sprintf( zBuf, "(%d) ", rc ); |
TCL.Tcl_AppendResult( interp, zBuf, sqlite3_errmsg( db ) ); |
return TCL.TCL_ERROR; |
} |
|
if ( pStmt != null ) |
{ |
if ( sqlite3TestMakePointerStr( interp, zBuf, pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
TCL.Tcl_AppendResult( interp, zBuf ); |
} |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_prepare16 DB sql bytes tailvar |
** |
** Compile up to <bytes> bytes of the supplied SQL string <sql> using |
** database handle <DB>. The parameter <tailval> is the name of a global |
** variable that is set to the unused portion of <sql> (if any). A |
** STMT handle is returned. |
*/ |
static int test_prepare16( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
#if !SQLITE_OMIT_UTF16 |
sqlite3 db=null; |
string zSql; |
string zTail = 0; |
Tcl_Obj pTail = 0; |
sqlite3_stmt pStmt = null; |
char zBuf[50]; |
int rc; |
int bytes; /* The integer specified as arg 3 */ |
int objlen; /* The byte-array length of arg 2 */ |
|
if( objc!=5 && objc!=4 ){ |
TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
TCL.Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0); |
return TCL.TCL_ERROR; |
} |
if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR; |
zSql = TCL.Tcl_GetByteArrayFromObj(objv[2], out objlen); |
if( TCL.Tcl_GetIntFromObj(interp, objv[3], out bytes) ) return TCL.TCL_ERROR; |
|
rc = sqlite3_prepare16(db, zSql, bytes, pStmt, objc>=5 ? &zTail : 0); |
if( sqlite3TestErrCode(interp, db, rc) ) return TCL.TCL_ERROR; |
if( rc !=0){ |
return TCL.TCL_ERROR; |
} |
|
if( objc>=5 ){ |
if( zTail ){ |
objlen = objlen - ((u8 )zTail-(u8 )zSql); |
}else{ |
objlen = 0; |
} |
pTail = TCL.Tcl_NewByteArrayObj((u8 )zTail, objlen); |
TCL.Tcl_IncrRefCount(pTail); |
Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0); |
TCL.Tcl_DecrRefCount(pTail); |
} |
|
if( pStmt ){ |
if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL.TCL_ERROR; |
} |
TCL.Tcl_AppendResult(interp, zBuf); |
#endif // * SQLITE_OMIT_UTF16 */ |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_prepare16_v2 DB sql bytes tailvar |
** |
** Compile up to <bytes> bytes of the supplied SQL string <sql> using |
** database handle <DB>. The parameter <tailval> is the name of a global |
** variable that is set to the unused portion of <sql> (if any). A |
** STMT handle is returned. |
*/ |
//static int test_prepare16_v2( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
#if !SQLITE_OMIT_UTF16 |
// sqlite3 db=null; |
// string zSql; |
// string zTail = 0; |
// Tcl_Obj pTail = 0; |
// sqlite3_stmt pStmt = null; |
// char zBuf[50]; |
// int rc; |
// int bytes; /* The integer specified as arg 3 */ |
// int objlen; /* The byte-array length of arg 2 */ |
|
// if( objc!=5 && objc!=4 ){ |
// TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
// TCL.Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0); |
// return TCL.TCL_ERROR; |
// } |
// if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR; |
// zSql = TCL.Tcl_GetByteArrayFromObj(objv[2], out objlen); |
// if( TCL.Tcl_GetIntFromObj(interp, objv[3], out bytes) ) return TCL.TCL_ERROR; |
|
// rc = sqlite3_prepare16_v2(db, zSql, bytes, pStmt,objc>=5 ? &zTail : 0); |
// if( sqlite3TestErrCode(interp, db, rc) ) return TCL.TCL_ERROR; |
// if( rc !=0){ |
// return TCL.TCL_ERROR; |
// } |
|
if( objc>=5 ){ |
if( zTail ){ |
objlen = objlen - ((u8 )zTail-(u8 )zSql); |
}else{ |
objlen = 0; |
} |
pTail = TCL.Tcl_NewByteArrayObj((u8 )zTail, objlen); |
TCL.Tcl_IncrRefCount(pTail); |
Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0); |
TCL.Tcl_DecrRefCount(pTail); |
// } |
|
// if( pStmt ){ |
// if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL.TCL_ERROR; |
// } |
// TCL.Tcl_AppendResult(interp, zBuf); |
#endif // * SQLITE_OMIT_UTF16 */ |
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: sqlite3_open filename ?options-list? |
*/ |
static int test_open( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
string zFilename; |
SqliteDb db = new SqliteDb(); |
int rc; |
StringBuilder zBuf = new StringBuilder( 100 ); |
if ( objc != 3 && objc != 2 && objc != 1 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " filename options-list" ); |
return TCL.TCL_ERROR; |
} |
|
zFilename = objc > 1 ? TCL.Tcl_GetString( objv[1] ) : null; |
rc = sqlite3_open( zFilename, out db.db ); |
|
if ( sqlite3TestMakePointerStr( interp, zBuf, db ) != TCL.TCL_OK ) |
return TCL.TCL_ERROR; |
TCL.Tcl_AppendResult( interp, zBuf ); |
return TCL.TCL_OK; |
} |
|
class OpenFlag |
{ |
public string zFlag; |
public int flag; |
|
public OpenFlag( string zFlag, int flag ) |
{ |
this.zFlag = zFlag; |
this.flag = flag; |
} |
} |
/* |
** Usage: sqlite3_open_v2 FILENAME FLAGS VFS |
*/ |
static int test_open_v2( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
string zFilename; |
string zVfs; |
int flags = 0; |
sqlite3 db = null; |
int rc; |
StringBuilder zBuf = new StringBuilder( 100 ); |
|
int nFlag = 0; |
Tcl_Obj[] apFlag = null; |
int i; |
|
if ( objc != 4 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "FILENAME FLAGS VFS" ); |
return TCL.TCL_ERROR; |
} |
zFilename = TCL.Tcl_GetString( objv[1] ); |
zVfs = TCL.Tcl_GetString( objv[3] ); |
if ( zVfs[0] == 0x00 ) |
zVfs = null; |
|
rc = TCL.Tcl_ListObjGetElements( interp, objv[2], out nFlag, out apFlag ) ? TCL.TCL_OK : 1; |
if ( rc != TCL.TCL_OK ) |
return rc; |
for ( i = 0; i < nFlag; i++ ) |
{ |
int iFlag; |
OpenFlag[] aFlag = new OpenFlag[] { |
new OpenFlag( "SQLITE_OPEN_READONLY", SQLITE_OPEN_READONLY ), |
new OpenFlag( "SQLITE_OPEN_READWRITE", SQLITE_OPEN_READWRITE ), |
new OpenFlag( "SQLITE_OPEN_CREATE", SQLITE_OPEN_CREATE ), |
new OpenFlag( "SQLITE_OPEN_DELETEONCLOSE", SQLITE_OPEN_DELETEONCLOSE ), |
new OpenFlag( "SQLITE_OPEN_EXCLUSIVE", SQLITE_OPEN_EXCLUSIVE ), |
new OpenFlag( "SQLITE_OPEN_AUTOPROXY", SQLITE_OPEN_AUTOPROXY ), |
new OpenFlag( "SQLITE_OPEN_MAIN_DB", SQLITE_OPEN_MAIN_DB ), |
new OpenFlag( "SQLITE_OPEN_TEMP_DB", SQLITE_OPEN_TEMP_DB ), |
new OpenFlag( "SQLITE_OPEN_TRANSIENT_DB", SQLITE_OPEN_TRANSIENT_DB ), |
new OpenFlag( "SQLITE_OPEN_MAIN_JOURNAL", SQLITE_OPEN_MAIN_JOURNAL ), |
new OpenFlag( "SQLITE_OPEN_TEMP_JOURNAL", SQLITE_OPEN_TEMP_JOURNAL ), |
new OpenFlag( "SQLITE_OPEN_SUBJOURNAL", SQLITE_OPEN_SUBJOURNAL ), |
new OpenFlag( "SQLITE_OPEN_MASTER_JOURNAL", SQLITE_OPEN_MASTER_JOURNAL ), |
new OpenFlag( "SQLITE_OPEN_NOMUTEX", SQLITE_OPEN_NOMUTEX ), |
new OpenFlag( "SQLITE_OPEN_FULLMUTEX", SQLITE_OPEN_FULLMUTEX ), |
new OpenFlag( "SQLITE_OPEN_SHAREDCACHE", SQLITE_OPEN_SHAREDCACHE ), |
new OpenFlag( "SQLITE_OPEN_PRIVATECACHE", SQLITE_OPEN_PRIVATECACHE ), |
new OpenFlag( "SQLITE_OPEN_WAL", SQLITE_OPEN_WAL ), |
new OpenFlag( "SQLITE_OPEN_URI", SQLITE_OPEN_URI ), |
new OpenFlag( null, 0 ) |
}; |
//rc = TCL.Tcl_GetIndexFromObjStruct( interp, apFlag[i], aFlag, sizeof( aFlag[0] ), |
// "flag", 0, ref iFlag ); |
|
for ( iFlag = 0; iFlag < aFlag.Length && ( aFlag[iFlag].zFlag != objv[4].ToString() ); iFlag++ ) |
{ |
} |
if ( iFlag >= aFlag.Length ) |
return TCL.TCL_ERROR; |
flags |= aFlag[iFlag].flag; |
} |
|
rc = sqlite3_open_v2( zFilename, out db, flags, zVfs ); |
if ( sqlite3TestMakePointerStr( interp, zBuf, db ) != 0 ) |
return TCL.TCL_ERROR; |
TCL.Tcl_AppendResult( interp, zBuf, 0 ); |
return TCL.TCL_OK; |
} |
/* |
** Usage: sqlite3_open16 filename options |
*/ |
//static int test_open16( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
#if !SQLITE_OMIT_UTF16 |
// string zFilename; |
// sqlite3 db=null; |
// int rc; |
// char zBuf[100]; |
|
// if( objc!=3 ){ |
// TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
// TCL.Tcl_GetString(objv[0]), " filename options-list", 0); |
// return TCL.TCL_ERROR; |
// } |
|
// zFilename = TCL.Tcl_GetByteArrayFromObj(objv[1], 0); |
// rc = sqlite3_open16(zFilename, ref db); |
|
// if ( sqlite3TestMakePointerStr( interp, zBuf, db ) != TCL.TCL_OK ) return TCL.TCL_ERROR; |
// TCL.Tcl_AppendResult(interp, zBuf); |
#endif // * SQLITE_OMIT_UTF16 */ |
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: sqlite3_complete16 <UTF-16 string> |
** |
** Return 1 if the supplied argument is a complete SQL statement, or zero |
** otherwise. |
*/ |
//static int test_complete16( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
#if !SQLITE_OMIT_COMPLETE && !SQLITE_OMIT_UTF16 |
// string zBuf; |
|
// if( objc!=2 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>"); |
// return TCL.TCL_ERROR; |
// } |
|
// zBuf = (char)TCL.Tcl_GetByteArrayFromObj(objv[1], 0); |
// TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(sqlite3_complete16(zBuf))); |
#endif // * SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */ |
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: sqlite3_step STMT |
** |
** Advance the statement to the next row. |
*/ |
static int test_step( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
int rc; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " STMT" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
rc = sqlite3_step( pStmt ); |
|
/* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL.TCL_ERROR; */ |
TCL.Tcl_SetResult( interp, t1ErrorName( rc ), 0 ); |
return TCL.TCL_OK; |
} |
|
static int test_sql( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
TCL.Tcl_SetResult( interp, sqlite3_sql( pStmt ), TCL.TCL_VOLATILE ); |
return TCL.TCL_OK; |
} |
|
|
/* |
** Usage: sqlite3_column_count STMT |
** |
** Return the number of columns returned by the sql statement STMT. |
*/ |
static int test_column_count( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
|
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_column_count( pStmt ) ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_column_type STMT column |
** |
** Return the type of the data in column 'column' of the current row. |
*/ |
static int test_column_type( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
int col = 0; |
int tp; |
|
if ( objc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out col ) ) |
return TCL.TCL_ERROR; |
|
tp = sqlite3_column_type( pStmt, col ); |
switch ( tp ) |
{ |
case SQLITE_INTEGER: |
TCL.Tcl_SetResult( interp, "INTEGER", TCL.TCL_STATIC ); |
break; |
case SQLITE_NULL: |
TCL.Tcl_SetResult( interp, "NULL", TCL.TCL_STATIC ); |
break; |
case SQLITE_FLOAT: |
TCL.Tcl_SetResult( interp, "FLOAT", TCL.TCL_STATIC ); |
break; |
case SQLITE_TEXT: |
TCL.Tcl_SetResult( interp, "TEXT", TCL.TCL_STATIC ); |
break; |
case SQLITE_BLOB: |
TCL.Tcl_SetResult( interp, "BLOB", TCL.TCL_STATIC ); |
break; |
default: |
Debugger.Break(); |
break; |
} |
|
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_column_int64 STMT column |
** |
** Return the data in column 'column' of the current row cast as an |
** wide (64-bit) integer. |
*/ |
static int test_column_int64( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = new sqlite3_stmt(); |
int col = 0; |
i64 iVal; |
|
if ( objc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != TCL.TCL_OK ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out col ) ) |
return TCL.TCL_ERROR; |
|
iVal = sqlite3_column_int64( pStmt, col ); |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewWideIntObj( iVal ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_column_blob STMT column |
*/ |
static int test_column_blob( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = new sqlite3_stmt(); |
int col = 0; |
|
int len; |
byte[] pBlob; |
|
if ( objc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != TCL.TCL_OK ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out col ) ) |
return TCL.TCL_ERROR; |
|
len = sqlite3_column_bytes( pStmt, col ); |
pBlob = sqlite3_column_blob( pStmt, col ); |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewByteArrayObj( pBlob, len ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_column_double STMT column |
** |
** Return the data in column 'column' of the current row cast as a double. |
*/ |
static int test_column_double( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = new sqlite3_stmt(); |
int col = 0; |
double rVal; |
|
if ( objc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != TCL.TCL_OK ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out col ) ) |
return TCL.TCL_ERROR; |
|
rVal = sqlite3_column_double( pStmt, col ); |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewDoubleObj( rVal ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_data_count STMT |
** |
** Return the number of columns returned by the sql statement STMT. |
*/ |
static int test_data_count( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != TCL.TCL_OK ) |
return TCL.TCL_ERROR; |
|
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_data_count( pStmt ) ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_column_text STMT column |
** |
** Usage: sqlite3_column_decltype STMT column |
** |
** Usage: sqlite3_column_name STMT column |
*/ |
static int test_stmt_utf8( |
object clientdata, /* Pointer to SQLite API function to be invoke */ |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
int col = 0; |
dxColumn xFunc;//string (*xFunc)(sqlite3_stmt*, int); |
string zRet; |
|
xFunc = (dxColumn)clientdata; //(string ()(sqlite3_stmt*, int))clientData; |
if ( objc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out col ) ) |
return TCL.TCL_ERROR; |
zRet = (string)xFunc( pStmt, col ); |
if ( zRet != null ) |
{ |
TCL.Tcl_SetResult( interp, zRet, 0 ); |
} |
return TCL.TCL_OK; |
} |
|
static int test_global_recover( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
#if !SQLITE_OMIT_DEPRECATED |
int rc; |
if ( objc != 1 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "" ); |
return TCL.TCL_ERROR; |
} |
rc = sqlite3_global_recover(); |
TCL.Tcl_SetResult( interp, t1ErrorName( rc ), TCL.TCL_STATIC ); |
#else |
TCL.Tcl_SetResult( interp, t1ErrorName( SQLITE_OK ), TCL.TCL_STATIC ); |
#endif |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_column_text STMT column |
** |
** Usage: sqlite3_column_decltype STMT column |
** |
** Usage: sqlite3_column_name STMT column |
*/ |
//static int test_stmt_utf16( |
// object clientdata, /* Pointer to SQLite API function to be invoked */ |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
#if !SQLITE_OMIT_UTF16 |
// sqlite3_stmt pStmt; |
// int col; |
// Tcl_Obj pRet; |
// string zName16; |
// const void *(*xFunc)(sqlite3_stmt*, int); |
|
xFunc = (dxColumn)clientdata; //(string ()(sqlite3_stmt*, int))clientData; |
// if( objc!=3 ){ |
// TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
// TCL.Tcl_GetString(objv[0]), " STMT column", 0); |
// return TCL.TCL_ERROR; |
// } |
|
// if( getStmtPointer(interp, TCL.Tcl_GetString(objv[1]), pStmt) ) return TCL.TCL_ERROR; |
// if( TCL.Tcl_GetIntFromObj(interp, objv[2], out col) ) return TCL.TCL_ERROR; |
|
// zName16 = xFunc(pStmt, col); |
// if( zName16 ){ |
int n; |
string z = zName16; |
for(n=0; z[n] || z[n+1]; n+=2){} |
pRet = TCL.Tcl_NewByteArrayObj(zName16, n+2); |
// TCL.Tcl_SetObjResult(interp, pRet); |
// } |
#endif // * SQLITE_OMIT_UTF16 */ |
|
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: sqlite3_column_int STMT column |
** |
** Usage: sqlite3_column_bytes STMT column |
** |
** Usage: sqlite3_column_bytes16 STMT column |
** |
*/ |
static int test_stmt_int( |
object clientdata, /* Pointer to SQLite API function to be invoked */ |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_stmt pStmt = null; |
int col = 0; |
dxColumn_I xFunc;//(sqlite3_stmt*, int) ; |
|
xFunc = (dxColumn_I)clientdata; //(int ()(sqlite3_stmt*, int))clientData; |
if ( objc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out col ) ) |
return TCL.TCL_ERROR; |
|
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( xFunc( pStmt, col ) ) ); |
return TCL.TCL_OK; |
} |
|
|
/* |
** Usage: sqlite_set_magic DB MAGIC-NUMBER |
** |
** Set the db.magic value. This is used to test error recovery logic. |
*/ |
static int sqlite_set_magic( |
object clientdata, /* Pointer to SQLite API function to be invoked */ |
Tcl_Interp interp, |
int argc, |
Tcl_Obj[] argv |
) |
{ |
sqlite3 db = null; |
if ( argc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" DB MAGIC" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
if ( argv[2].ToString() == "SQLITE_MAGIC_OPEN" ) |
{ |
db.magic = SQLITE_MAGIC_OPEN; |
} |
else if ( argv[2].ToString() == "SQLITE_MAGIC_CLOSED" ) |
{ |
db.magic = SQLITE_MAGIC_CLOSED; |
} |
else if ( argv[2].ToString() == "SQLITE_MAGIC_BUSY" ) |
{ |
db.magic = SQLITE_MAGIC_BUSY; |
} |
else if ( argv[2].ToString() == "SQLITE_MAGIC_ERROR" ) |
{ |
db.magic = SQLITE_MAGIC_ERROR; |
} |
else if ( TCL.Tcl_GetInt( interp, argv[2], out db.magic ) ) |
{ |
return TCL.TCL_ERROR; |
} |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_interrupt DB |
** |
** Trigger an interrupt on DB |
*/ |
static int test_interrupt( |
object clientdata, |
Tcl_Interp interp, |
int argc, |
Tcl_Obj[] argv ) |
{ |
sqlite3 db = null; |
if ( argc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], " DB" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
sqlite3_interrupt( db ); |
return TCL.TCL_OK; |
} |
|
//static u8 *sqlite3_stack_baseline = 0; |
|
/* |
** Fill the stack with a known bitpattern. |
*/ |
//static void prepStack(void){ |
// int i; |
// u32 bigBuf[65536]; |
// for(i=0; i<sizeof(bigBuf); i++) bigBuf[i] = 0xdeadbeef; |
// sqlite3_stack_baseline = (u8)&bigBuf[65536]; |
//} |
|
/* |
** Get the current stack depth. Used for debugging only. |
*/ |
//u64 sqlite3StackDepth(void){ |
// u8 x; |
// return (u64)(sqlite3_stack_baseline - &x); |
//} |
|
/* |
** Usage: sqlite3_stack_used DB SQL |
** |
** Try to measure the amount of stack space used by a call to sqlite3_exec |
*/ |
//static int test_stack_used( |
// object clientdata, |
// Tcl_Interp interp, |
// int argc, |
// char **argv |
//){ |
// sqlite3 db=null; |
// int i; |
// if( argc!=3 ){ |
// TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
// " DB SQL", 0); |
// return TCL.TCL_ERROR; |
// } |
// if( getDbPointer(interp, argv[1].ToString(), out db) !=0) return TCL.TCL_ERROR; |
// prepStack(); |
// (void)sqlite3_exec(db, argv[2], 0, 0, 0); |
// for(i=65535; i>=0 && ((u32)sqlite3_stack_baseline)[-i]==0xdeadbeef; i--){} |
// TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(i*4)); |
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: sqlite_delete_function DB function-name |
** |
** Delete the user function 'function-name' from database handle DB. It |
** is assumed that the user function was created as UTF8, any number of |
** arguments (the way the TCL interface does it). |
*/ |
static int delete_function( |
object clientdata, |
Tcl_Interp interp, |
int argc, |
Tcl_Obj[] argv |
) |
{ |
int rc; |
sqlite3 db = null; |
if ( argc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" DB function-name", null ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
rc = sqlite3_create_function( db, argv[2].ToString(), -1, SQLITE_UTF8, null, null, null, null ); |
TCL.Tcl_SetResult( interp, t1ErrorName( rc ), TCL.TCL_STATIC ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite_delete_collation DB collation-name |
** |
** Delete the collation sequence 'collation-name' from database handle |
** DB. It is assumed that the collation sequence was created as UTF8 (the |
** way the TCL interface does it). |
*/ |
static int delete_collation( |
object clientdata, |
Tcl_Interp interp, |
int argc, |
Tcl_Obj[] argv |
) |
{ |
int rc; |
sqlite3 db = null; |
if ( argc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" DB function-name", null ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
rc = sqlite3_create_collation( db, argv[2].ToString(), SQLITE_UTF8, null, null ); |
TCL.Tcl_SetResult( interp, t1ErrorName( rc ), TCL.TCL_STATIC ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_get_autocommit DB |
** |
** Return true if the database DB is currently in auto-commit mode. |
** Return false if not. |
*/ |
static int get_autocommit( |
object clientdata, |
Tcl_Interp interp, |
int argc, |
Tcl_Obj[] argv |
) |
{ |
StringBuilder zBuf = new StringBuilder( 30 ); |
sqlite3 db = null; |
if ( argc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" DB" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
sqlite3_snprintf( 30, zBuf, "%d", sqlite3_get_autocommit( db ) ); |
TCL.Tcl_AppendResult( interp, zBuf ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_busy_timeout DB MS |
** |
** Set the busy timeout. This is more easily done using the timeout |
** method of the TCL interface. But we need a way to test the case |
** where it returns SQLITE_MISUSE. |
*/ |
static int test_busy_timeout( |
object clientdata, |
Tcl_Interp interp, |
int argc, |
Tcl_Obj[] argv |
) |
{ |
int rc, ms = 0; |
sqlite3 db = null; |
if ( argc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
" DB" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.Tcl_GetInt( interp, argv[2], out ms ) ) |
return TCL.TCL_ERROR; |
rc = sqlite3_busy_timeout( db, ms ); |
TCL.Tcl_AppendResult( interp, sqlite3TestErrorName( rc ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: tcl_variable_type VARIABLENAME |
** |
** Return the name of the internal representation for the |
** value of the given variable. |
*/ |
static int tcl_variable_type( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
Tcl_Obj pVar; |
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "VARIABLE" ); |
return TCL.TCL_ERROR; |
} |
pVar = TCL.Tcl_GetVar2Ex( interp, TCL.Tcl_GetString( objv[1] ), null, (TCL.VarFlag)TCL.TCL_LEAVE_ERR_MSG ); |
if ( pVar == null ) |
return TCL.TCL_ERROR; |
if ( pVar.typePtr != "" ) |
{ |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewStringObj( pVar.typePtr, -1 ) ); |
} |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_release_memory ?N? |
** |
** Attempt to release memory currently held but not actually required. |
** The integer N is the number of bytes we are trying to release. The |
** return value is the amount of memory actually released. |
*/ |
static int test_release_memory( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
#if SQLITE_ENABLE_MEMORY_MANAGEMENT && !SQLITE_OMIT_DISKIO |
int N; |
int amt; |
if( objc!=1 && objc!=2 ){ |
TCL.Tcl_WrongNumArgs(interp, 1, objv, "?N?"); |
return TCL.TCL_ERROR; |
} |
if( objc==2 ){ |
if( TCL.Tcl_GetIntFromObj(interp, objv[1], out N) ) return TCL.TCL_ERROR; |
}else{ |
N = -1; |
} |
amt = sqlite3_release_memory(N); |
TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(amt)); |
#endif |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_soft_heap_limit ?N? |
** |
** Query or set the soft heap limit for the current thread. The |
** limit is only changed if the N is present. The previous limit |
** is returned. |
*/ |
static int test_soft_heap_limit( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
sqlite3_int64 amt; |
sqlite3_int64 N = -1; |
if ( objc != 1 && objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "?N?" ); |
return TCL.TCL_ERROR; |
} |
if ( objc == 2 ) |
{ |
if ( TCL.Tcl_GetWideIntFromObj( interp, objv[1], out N ) ) |
return TCL.TCL_ERROR; |
} |
amt = sqlite3_soft_heap_limit64( N ); |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewWideIntObj( amt ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_thread_cleanup |
** |
** Call the sqlite3_thread_cleanup API. |
*/ |
//static int test_thread_cleanup( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// sqlite3_thread_cleanup(); |
// return TCL.TCL_OK; |
//} |
|
|
/* |
** Usage: sqlite3_pager_refcounts DB |
** |
** Return a list of numbers which are the PagerRefcount for all |
** pagers on each database connection. |
*/ |
//static int test_pager_refcounts( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// sqlite3 db=null; |
// int i; |
// int v, *a; |
// Tcl_Obj pResult; |
|
// if( objc!=2 ){ |
// TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
// TCL.Tcl_GetStringFromObj(objv[0], 0), " DB", 0); |
// return TCL.TCL_ERROR; |
// } |
// if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR; |
// pResult = TCL.Tcl_NewObj(); |
// for(i=0; i<db.nDb; i++){ |
// if( db.aDb[i].pBt==null ){ |
// v = -1; |
// }else{ |
// sqlite3_mutex_enter(db.mutex); |
// a = sqlite3PagerStats(sqlite3BtreePager(db.aDb[i].pBt)); |
// v = a[0]; |
// sqlite3_mutex_leave(db.mutex); |
// } |
// TCL.Tcl_ListObjAppendElement(0, pResult, TCL.Tcl_NewIntObj(v)); |
// } |
// TCL.Tcl_SetObjResult(interp, pResult); |
// return TCL.TCL_OK; |
//} |
|
|
/* |
** tclcmd: working_64bit_int |
** |
** Some TCL builds (ex: cygwin) do not support 64-bit integers. This |
** leads to a number of test failures. The present command checks the |
** TCL build to see whether or not it supports 64-bit integers. It |
** returns TRUE if it does and FALSE if not. |
** |
** This command is used to warn users that their TCL build is defective |
** and that the errors they are seeing in the test scripts might be |
** a result of their defective TCL rather than problems in SQLite. |
*/ |
static int working_64bit_int( |
object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
Tcl_Obj pTestObj; |
int working = 0; |
|
pTestObj = TCL.Tcl_NewWideIntObj( 1000000 * (i64)1234567890 ); |
working = ( TCL.Tcl_GetString( pTestObj ) == "1234567890000000" ) ? 1 : 0; |
TCL.Tcl_DecrRefCount( ref pTestObj ); |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewBooleanObj( working ) ); |
return TCL.TCL_OK; |
} |
|
|
/* |
** tclcmd: vfs_unlink_test |
** |
** This TCL command unregisters the primary VFS and then registers |
** it back again. This is used to test the ability to register a |
** VFS when none are previously registered, and the ability to |
** unregister the only available VFS. Ticket #2738 |
*/ |
static int vfs_unlink_test( |
object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
int i; |
sqlite3_vfs pMain; |
sqlite3_vfs one = new sqlite3_vfs(); |
sqlite3_vfs two = new sqlite3_vfs(); |
|
sqlite3_vfs_unregister( null ); /* Unregister of NULL is harmless */ |
one.zName = "__one"; |
two.zName = "__two"; |
|
/* Calling sqlite3_vfs_register with 2nd argument of 0 does not |
** change the default VFS |
*/ |
pMain = sqlite3_vfs_find( null ); |
sqlite3_vfs_register( one, 0 ); |
Debug.Assert( pMain == null || pMain == sqlite3_vfs_find( null ) ); |
sqlite3_vfs_register( two, 0 ); |
Debug.Assert( pMain == null || pMain == sqlite3_vfs_find( null ) ); |
|
/* We can find a VFS by its name */ |
Debug.Assert( sqlite3_vfs_find( "__one" ) == one ); |
Debug.Assert( sqlite3_vfs_find( "__two" ) == two ); |
|
/* Calling sqlite_vfs_register with non-zero second parameter changes the |
** default VFS, even if the 1st parameter is an existig VFS that is |
** previously registered as the non-default. |
*/ |
sqlite3_vfs_register( one, 1 ); |
Debug.Assert( sqlite3_vfs_find( "__one" ) == one ); |
Debug.Assert( sqlite3_vfs_find( "__two" ) == two ); |
Debug.Assert( sqlite3_vfs_find( null ) == one ); |
sqlite3_vfs_register( two, 1 ); |
Debug.Assert( sqlite3_vfs_find( "__one" ) == one ); |
Debug.Assert( sqlite3_vfs_find( "__two" ) == two ); |
Debug.Assert( sqlite3_vfs_find( null ) == two ); |
if ( pMain != null ) |
{ |
sqlite3_vfs_register( pMain, 1 ); |
Debug.Assert( sqlite3_vfs_find( "__one" ) == one ); |
Debug.Assert( sqlite3_vfs_find( "__two" ) == two ); |
Debug.Assert( sqlite3_vfs_find( null ) == pMain ); |
} |
|
/* Unlink the default VFS. Repeat until there are no more VFSes |
** registered. |
*/ |
for ( i = 0; i < apVfs.Length; i++ ) |
{//sizeof(apVfs)/sizeof(apVfs[0]); i++){ |
apVfs[i] = sqlite3_vfs_find( null ); |
if ( apVfs[i] != null ) |
{ |
Debug.Assert( apVfs[i] == sqlite3_vfs_find( apVfs[i].zName ) ); |
sqlite3_vfs_unregister( apVfs[i] ); |
Debug.Assert( null == sqlite3_vfs_find( apVfs[i].zName ) ); |
} |
} |
Debug.Assert( null == sqlite3_vfs_find( null ) ); |
|
|
/* Register the main VFS as non-default (will be made default, since |
** it'll be the only one in existence). |
*/ |
sqlite3_vfs_register( pMain, 0 ); |
Debug.Assert( sqlite3_vfs_find( null ) == pMain ); |
|
/* Un-register the main VFS again to restore an empty VFS list */ |
sqlite3_vfs_unregister( pMain ); |
Debug.Assert( null == sqlite3_vfs_find( null ) ); |
|
/* Relink all VFSes in reverse order. */ |
for ( i = apVfs.Length - 1; i >= 0; i-- ) |
{//sizeof(apVfs)/sizeof(apVfs[0])-1; i>=0; i--){ |
if ( apVfs[i] != null ) |
{ |
sqlite3_vfs_register( apVfs[i], 1 ); |
Debug.Assert( apVfs[i] == sqlite3_vfs_find( null ) ); |
Debug.Assert( apVfs[i] == sqlite3_vfs_find( apVfs[i].zName ) ); |
} |
} |
|
/* Unregister out sample VFSes. */ |
sqlite3_vfs_unregister( one ); |
sqlite3_vfs_unregister( two ); |
|
/* Unregistering a VFS that is not currently registered is harmless */ |
sqlite3_vfs_unregister( one ); |
sqlite3_vfs_unregister( two ); |
Debug.Assert( sqlite3_vfs_find( "__one" ) == null ); |
Debug.Assert( sqlite3_vfs_find( "__two" ) == null ); |
|
/* We should be left with the original default VFS back as the |
** original */ |
Debug.Assert( sqlite3_vfs_find( null ) == pMain ); |
|
return TCL.TCL_OK; |
} |
|
/* |
** tclcmd: vfs_initfail_test |
** |
** This TCL command attempts to vfs_find and vfs_register when the |
** sqlite3_initialize() interface is failing. All calls should fail. |
*/ |
//static int vfs_initfail_test( |
// ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
// Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
// int objc, /* Number of arguments */ |
// Tcl_Obj[] objv /* Command arguments */ |
//){ |
// sqlite3_vfs one; |
// one.zName = "__one"; |
|
// if( sqlite3_vfs_find(0) ) return TCL.TCL_ERROR; |
// sqlite3_vfs_register(&one, 0); |
// if( sqlite3_vfs_find(0) ) return TCL.TCL_ERROR; |
// sqlite3_vfs_register(&one, 1); |
// if( sqlite3_vfs_find(0) ) return TCL.TCL_ERROR; |
// return TCL.TCL_OK; |
//} |
|
|
/* |
** Saved VFSes |
*/ |
static sqlite3_vfs[] apVfs = new sqlite3_vfs[20]; |
static int nVfs = 0; |
|
/* |
** tclcmd: vfs_unregister_all |
** |
** Unregister all VFSes. |
*/ |
static int vfs_unregister_all( |
object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
int i; |
for ( i = 0; i < apVfs.Length; i++ ) |
{ |
apVfs[i] = sqlite3_vfs_find( null ); |
if ( apVfs[i] == null ) |
break; |
sqlite3_vfs_unregister( apVfs[i] ); |
} |
nVfs = i; |
return TCL.TCL_OK; |
} |
|
/* |
** tclcmd: vfs_reregister_all |
** |
** Restore all VFSes that were removed using vfs_unregister_all |
*/ |
static int vfs_reregister_all( |
object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
int i; |
for ( i = 0; i < nVfs; i++ ) |
{ |
sqlite3_vfs_register( apVfs[i], i == 0 ? 1 : 0 ); |
} |
return TCL.TCL_OK; |
} |
|
|
/* |
** tclcmd: file_control_test DB |
** |
** This TCL command runs the sqlite3_file_control interface and |
** verifies correct operation of the same. |
*/ |
static int file_control_test( |
object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
sqlite3_int64 iArg = 0; |
sqlite3 db = null; |
int rc; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " DB" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
rc = sqlite3_file_control( db, null, 0, ref iArg ); |
Debug.Assert( rc == SQLITE_NOTFOUND ); |
rc = sqlite3_file_control( db, "notadatabase", SQLITE_FCNTL_LOCKSTATE, ref iArg ); |
Debug.Assert( rc == SQLITE_ERROR ); |
rc = sqlite3_file_control( db, "main", -1, ref iArg ); |
Debug.Assert( rc == SQLITE_NOTFOUND ); |
rc = sqlite3_file_control( db, "temp", -1, ref iArg ); |
Debug.Assert( rc == SQLITE_NOTFOUND || rc == SQLITE_ERROR ); |
return TCL.TCL_OK; |
} |
|
|
/* |
** tclcmd: file_control_lasterrno_test DB |
** |
** This TCL command runs the sqlite3_file_control interface and |
** verifies correct operation of the SQLITE_LAST_ERRNO verb. |
*/ |
static int file_control_lasterrno_test( |
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
sqlite3_int64 iArg = 0; |
sqlite3 db = null; |
int rc; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " DB" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
{ |
return TCL.TCL_ERROR; |
} |
rc = sqlite3_file_control( db, null, SQLITE_LAST_ERRNO, ref iArg ); |
if ( rc != 0 ) |
{ |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( rc ) ); |
return TCL.TCL_ERROR; |
} |
if ( iArg != 0 ) |
{ |
TCL.Tcl_AppendResult( interp, "Unexpected non-zero errno: ", iArg.ToString(), "" ); |
//TCL.Tcl_GetStringFromObj(TCL.Tcl_NewIntObj(iArg), 0), " ", 0); |
return TCL.TCL_ERROR; |
} |
return TCL.TCL_OK; |
} |
|
|
/* |
** tclcmd: file_control_chunksize_test DB DBNAME SIZE |
** |
** This TCL command runs the sqlite3_file_control interface and |
** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and |
** SQLITE_SET_LOCKPROXYFILE verbs. |
*/ |
static int file_control_chunksize_test( |
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
int nSize = 0; /* New chunk size */ |
string zDb; /* Db name ("main", "temp" etc.) */ |
sqlite3 db = null; /* Database handle */ |
int rc; /* file_control() return code */ |
|
if ( objc != 4 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB DBNAME SIZE" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 |
|| TCL.Tcl_GetIntFromObj( interp, objv[3], out nSize ) != 0 |
) |
{ |
return TCL.TCL_ERROR; |
} |
zDb = TCL.Tcl_GetString( objv[2] ); |
if ( zDb == "" ) |
zDb = null; |
|
i64 iSize = 0; |
rc = sqlite3_file_control( db, zDb, SQLITE_FCNTL_CHUNK_SIZE, ref iSize ); |
nSize = (int)iSize; |
|
if ( rc != 0 ) |
{ |
TCL.Tcl_SetResult( interp, sqlite3TestErrorName( rc ), TCL.TCL_STATIC ); |
return TCL.TCL_ERROR; |
} |
return TCL.TCL_OK; |
} |
|
|
|
/* |
** tclcmd: file_control_sizehint_test DB DBNAME SIZE |
** |
** This TCL command runs the sqlite3_file_control interface and |
** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and |
** SQLITE_SET_LOCKPROXYFILE verbs. |
*/ |
static int file_control_sizehint_test( |
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
sqlite3_int64 nSize = 0; /* Hinted size */ |
string zDb; /* Db name ("main", "temp" etc.) */ |
sqlite3 db = null; /* Database handle */ |
int rc; /* file_control() return code */ |
|
if ( objc != 4 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB DBNAME SIZE" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 |
|| TCL.Tcl_GetWideIntFromObj( interp, objv[3], out nSize ) |
) |
{ |
return TCL.TCL_ERROR; |
} |
zDb = TCL.Tcl_GetString( objv[2] ); |
if ( zDb[0] == '\0' ) |
zDb = null; |
|
rc = sqlite3_file_control( db, zDb, SQLITE_FCNTL_SIZE_HINT, ref nSize ); |
if ( rc != 0 ) |
{ |
TCL.Tcl_SetResult( interp, sqlite3TestErrorName( rc ), TCL.TCL_STATIC ); |
return TCL.TCL_ERROR; |
} |
return TCL.TCL_OK; |
} |
|
/* |
** tclcmd: file_control_lockproxy_test DB PWD |
** |
** This TCL command runs the sqlite3_file_control interface and |
** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and |
** SQLITE_SET_LOCKPROXYFILE verbs. |
*/ |
static int file_control_lockproxy_test( |
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
sqlite3 db = null; |
string zPwd; |
int nPwd = 0; |
|
if ( objc != 3 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " DB PWD" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
{ |
return TCL.TCL_ERROR; |
} |
zPwd = TCL.Tcl_GetStringFromObj( objv[2], out nPwd ); |
|
//#if !(SQLITE_ENABLE_LOCKING_STYLE) && (__APPLE__) |
//{ |
// char *testPath; |
// int rc; |
// char proxyPath[400]; |
|
// if( sizeof(proxyPath)<nPwd+20 ){ |
// TCL.Tcl_AppendResult(interp, "PWD too big", (void)0); |
// return TCL.TCL_ERROR; |
// } |
// sprintf(proxyPath, "%s/test.proxy", zPwd); |
// rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath); |
// if( rc ){ |
// TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(rc)); |
// return TCL.TCL_ERROR; |
// } |
// rc = sqlite3_file_control(db, NULL, SQLITE_GET_LOCKPROXYFILE, &testPath); |
// if( strncmp(proxyPath,testPath,11) ){ |
// TCL.Tcl_AppendResult(interp, "Lock proxy file did not match the " |
// "previously assigned value", 0); |
// return TCL.TCL_ERROR; |
// } |
// if( rc ){ |
// TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(rc)); |
// return TCL.TCL_ERROR; |
// } |
// rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath); |
// if( rc ){ |
// TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(rc)); |
// return TCL.TCL_ERROR; |
// } |
//} |
//#endif |
return TCL.TCL_OK; |
} |
|
/* |
** tclcmd: sqlite3_vfs_list |
** |
** Return a tcl list containing the names of all registered vfs's. |
*/ |
//static int vfs_list( |
// ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
// Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
// int objc, /* Number of arguments */ |
// Tcl_Obj[] objv /* Command arguments */ |
//){ |
// sqlite3_vfs pVfs; |
// Tcl_Obj pRet = TCL.Tcl_NewObj(); |
// if( objc!=1 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, ""); |
// return TCL.TCL_ERROR; |
// } |
// for(pVfs=sqlite3_vfs_find(0); pVfs!=null; pVfs=pVfs.pNext){ |
// TCL.Tcl_ListObjAppendElement(interp, pRet, TCL.Tcl_NewStringObj(pVfs.zName, -1)); |
// } |
// TCL.Tcl_SetObjResult(interp, pRet); |
// return TCL.TCL_OK; |
//} |
|
/* |
** tclcmd: sqlite3_limit DB ID VALUE |
** |
** This TCL command runs the sqlite3_limit interface and |
** verifies correct operation of the same. |
*/ |
struct _aID |
{ |
public string zName; |
public int id; |
public _aID( string zName, int id ) |
{ |
this.zName = zName; |
this.id = id; |
} |
} |
|
static int test_limit( |
object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
sqlite3 db = null; |
int rc = 0; |
_aID[] aId = new _aID[] { |
new _aID( "SQLITE_LIMIT_LENGTH", SQLITE_LIMIT_LENGTH ), |
new _aID( "SQLITE_LIMIT_SQL_LENGTH", SQLITE_LIMIT_SQL_LENGTH ), |
new _aID( "SQLITE_LIMIT_COLUMN", SQLITE_LIMIT_COLUMN ), |
new _aID( "SQLITE_LIMIT_EXPR_DEPTH", SQLITE_LIMIT_EXPR_DEPTH ), |
new _aID( "SQLITE_LIMIT_COMPOUND_SELECT", SQLITE_LIMIT_COMPOUND_SELECT ), |
new _aID( "SQLITE_LIMIT_VDBE_OP", SQLITE_LIMIT_VDBE_OP ), |
new _aID( "SQLITE_LIMIT_FUNCTION_ARG", SQLITE_LIMIT_FUNCTION_ARG ), |
new _aID( "SQLITE_LIMIT_ATTACHED", SQLITE_LIMIT_ATTACHED ), |
new _aID( "SQLITE_LIMIT_LIKE_PATTERN_LENGTH", SQLITE_LIMIT_LIKE_PATTERN_LENGTH ), |
new _aID( "SQLITE_LIMIT_VARIABLE_NUMBER", SQLITE_LIMIT_VARIABLE_NUMBER ), |
new _aID( "SQLITE_LIMIT_TRIGGER_DEPTH", SQLITE_LIMIT_TRIGGER_DEPTH ), |
|
/* Out of range test cases */ |
new _aID( "SQLITE_LIMIT_TOOSMALL", -1 ), |
new _aID( "SQLITE_LIMIT_TOOBIG", SQLITE_LIMIT_TRIGGER_DEPTH+1 ), |
}; |
int i, id = 0; |
int val = 0; |
string zId; |
|
if ( objc != 4 ) |
{ |
TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
TCL.Tcl_GetStringFromObj( objv[0], 0 ), " DB ID VALUE" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
zId = TCL.Tcl_GetString( objv[2] ); |
for ( i = 0; i < aId.Length; i++ ) |
{ |
if ( zId == aId[i].zName ) |
{ |
id = aId[i].id; |
break; |
} |
} |
if ( i >= aId.Length ) |
{ |
TCL.Tcl_AppendResult( interp, "unknown limit type: ", zId, '\0' ); |
return TCL.TCL_ERROR; |
} |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[3], out val ) ) |
return TCL.TCL_ERROR; |
rc = sqlite3_limit( db, id, val ); |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( rc ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** tclcmd: save_prng_state |
** |
** Save the state of the pseudo-random number generator. |
** At the same time, verify that sqlite3_test_control works even when |
** called with an out-of-range opcode. |
*/ |
static int save_prng_state( |
object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
int rc = sqlite3_test_control( 9999 ); |
Debug.Assert( rc == 0 ); |
rc = sqlite3_test_control( -1 ); |
Debug.Assert( rc == 0 ); |
sqlite3_test_control( SQLITE_TESTCTRL_PRNG_SAVE ); |
return TCL.TCL_OK; |
} |
/* |
** tclcmd: restore_prng_state |
*/ |
static int restore_prng_state( |
object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
sqlite3_test_control( SQLITE_TESTCTRL_PRNG_RESTORE ); |
return TCL.TCL_OK; |
} |
/* |
** tclcmd: reset_prng_state |
*/ |
static int reset_prng_state( |
object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
sqlite3_test_control( SQLITE_TESTCTRL_PRNG_RESET ); |
return TCL.TCL_OK; |
} |
|
|
/* |
** tclcmd: pcache_stats |
*/ |
static int test_pcache_stats( |
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
int nMin; |
int nMax; |
int nCurrent; |
int nRecyclable; |
Tcl_Obj pRet; |
|
sqlite3PcacheStats( out nCurrent, out nMax, out nMin, out nRecyclable ); |
|
pRet = TCL.Tcl_NewObj(); |
TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewStringObj( "current", -1 ) ); |
TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewIntObj( nCurrent ) ); |
TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewStringObj( "max", -1 ) ); |
TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewIntObj( nMax ) ); |
TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewStringObj( "min", -1 ) ); |
TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewIntObj( nMin ) ); |
TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewStringObj( "recyclable", -1 ) ); |
TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewIntObj( nRecyclable ) ); |
|
TCL.Tcl_SetObjResult( interp, pRet ); |
|
return TCL.TCL_OK; |
} |
|
|
|
public class _aObjCmd |
{ |
public string zName; |
public Interp.dxObjCmdProc xProc; |
public object clientData; |
public _aObjCmd( string zName, Interp.dxObjCmdProc xProc ) |
{ |
this.zName = zName; |
this.xProc = xProc; |
this.clientData = null; |
} |
public _aObjCmd( string zName, Interp.dxObjCmdProc xProc, object clientdata ) |
{ |
this.zName = zName; |
this.xProc = xProc; |
this.clientData = clientdata.GetType().Name == "Int32" && (int)clientdata == 0 ? null : clientdata; |
} |
} |
|
#if SQLITE_ENABLE_UNLOCK_NOTIFY |
static void test_unlock_notify_cb(void **aArg, int nArg){ |
int ii; |
for(ii=0; ii<nArg; ii++){ |
TCL.Tcl_EvalEx((Tcl_Interp )aArg[ii], "unlock_notify", -1, TCL.TCL_EVAL_GLOBAL); |
} |
} |
#endif //* SQLITE_ENABLE_UNLOCK_NOTIFY */ |
|
/* |
** tclcmd: sqlite3_unlock_notify db |
*/ |
#if SQLITE_ENABLE_UNLOCK_NOTIFY |
static int test_unlock_notify( |
ClientData clientData, /* Unused */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
){ |
sqlite3 db; |
int rc; |
|
if( objc!=2 ){ |
TCL.Tcl_WrongNumArgs(interp, 1, objv, "DB"); |
return TCL.TCL_ERROR; |
} |
|
if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), &db) ){ |
return TCL.TCL_ERROR; |
} |
rc = sqlite3_unlock_notify(db, test_unlock_notify_cb, (void )interp); |
TCL.Tcl_SetResult(interp, (char )t1ErrorName(rc), TCL.TCL_STATIC); |
return TCL.TCL_OK; |
} |
#endif |
|
/* |
** tclcmd: sqlite3_wal_checkpoint db ?NAME? |
*/ |
static int test_wal_checkpoint( |
ClientData clientData, /* Unused */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
string zDb = ""; |
sqlite3 db = null; |
int rc; |
|
if ( objc != 3 && objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB ?NAME?" ); |
return TCL.TCL_ERROR; |
} |
|
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
{ |
return TCL.TCL_ERROR; |
} |
if ( objc == 3 ) |
{ |
zDb = TCL.Tcl_GetString( objv[2] ); |
} |
rc = sqlite3_wal_checkpoint( db, zDb ); |
TCL.Tcl_SetResult( interp, t1ErrorName( rc ), TCL.TCL_STATIC ); |
return TCL.TCL_OK; |
} |
|
/* |
** tclcmd: sqlite3_wal_checkpoint_v2 db MODE ?NAME? |
** |
** This command calls the wal_checkpoint_v2() function with the specified |
** mode argument (passive, full or restart). If present, the database name |
** NAME is passed as the second argument to wal_checkpoint_v2(). If it the |
** NAME argument is not present, a NULL pointer is passed instead. |
** |
** If wal_checkpoint_v2() returns any value other than SQLITE_BUSY or |
** SQLITE_OK, then this command returns TCL_ERROR. The Tcl result is set |
** to the error message obtained from sqlite3_errmsg(). |
** |
** Otherwise, this command returns a list of three integers. The first integer |
** is 1 if SQLITE_BUSY was returned, or 0 otherwise. The following two integers |
** are the values returned via the output paramaters by wal_checkpoint_v2() - |
** the number of frames in the log and the number of frames in the log |
** that have been checkpointed. |
*/ |
static int test_wal_checkpoint_v2( |
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
string zDb = ""; |
sqlite3 db = null; |
int rc; |
|
int eMode = 0; |
int nLog = -555; |
int nCkpt = -555; |
Tcl_Obj pRet; |
|
string[] aMode = new string[] { "passive", "full", "restart" }; |
Debug.Assert( SQLITE_CHECKPOINT_PASSIVE == 0 ); |
Debug.Assert( SQLITE_CHECKPOINT_FULL == 1 ); |
Debug.Assert( SQLITE_CHECKPOINT_RESTART == 2 ); |
|
if ( objc != 3 && objc != 4 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB MODE ?NAME?" ); |
return TCL.TCL_ERROR; |
} |
|
if ( objc == 4 ) |
{ |
zDb = TCL.Tcl_GetString( objv[3] ); |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 |
|| TCL.Tcl_GetIndexFromObj( interp, objv[2], aMode, "mode", 0, out eMode ) |
) |
{ |
return TCL.TCL_ERROR; |
} |
|
rc = sqlite3_wal_checkpoint_v2( db, zDb, eMode, out nLog, out nCkpt ); |
if ( rc != SQLITE_OK && rc != SQLITE_BUSY ) |
{ |
TCL.Tcl_SetResult( interp, sqlite3_errmsg( db ), TCL.TCL_VOLATILE ); |
return TCL.TCL_ERROR; |
} |
|
pRet = TCL.Tcl_NewObj(); |
TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewIntObj( rc == SQLITE_BUSY ? 1 : 0 ) ); |
TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewIntObj( nLog ) ); |
TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewIntObj( nCkpt ) ); |
TCL.Tcl_SetObjResult( interp, pRet ); |
|
return TCL.TCL_OK; |
} |
|
/* |
** tclcmd: test_sqlite3_log ?SCRIPT? |
*/ |
struct LogCallback |
{ |
public Tcl_Interp pInterp; |
public Tcl_Obj pObj; |
} |
static LogCallback logcallback = new LogCallback(); |
|
static void xLogcallback( object unused, int err, string zMsg ) |
{ |
Tcl_Obj pNew = TCL.Tcl_DuplicateObj( logcallback.pObj ); |
TCL.Tcl_IncrRefCount( pNew ); |
TCL.Tcl_ListObjAppendElement( |
null, pNew, TCL.Tcl_NewStringObj( sqlite3TestErrorName( err ), -1 ) |
); |
TCL.Tcl_ListObjAppendElement( null, pNew, TCL.Tcl_NewStringObj( zMsg, -1 ) ); |
TCL.Tcl_EvalObjEx( logcallback.pInterp, pNew, TCL.TCL_EVAL_GLOBAL | TCL.TCL_EVAL_DIRECT ); |
TCL.Tcl_DecrRefCount( ref pNew ); |
} |
|
static int test_sqlite3_log( |
ClientData clientData, |
Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
int objc, /* Number of arguments */ |
Tcl_Obj[] objv /* Command arguments */ |
) |
{ |
if ( objc > 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "SCRIPT" ); |
return TCL.TCL_ERROR; |
} |
if ( logcallback.pObj != null ) |
{ |
TCL.Tcl_DecrRefCount( ref logcallback.pObj ); |
logcallback.pObj = null; |
logcallback.pInterp = null; |
sqlite3_config( SQLITE_CONFIG_LOG, 0, 0 ); |
} |
if ( objc > 1 ) |
{ |
logcallback.pObj = objv[1]; |
TCL.Tcl_IncrRefCount( logcallback.pObj ); |
logcallback.pInterp = interp; |
sqlite3_config( SQLITE_CONFIG_LOG, (dxLogcallback)xLogcallback, 0 ); |
} |
return TCL.TCL_OK; |
} |
|
|
/* |
** tcl_objproc COMMANDNAME ARGS... |
** |
** Run a TCL command using its objProc interface. Throw an error if |
** the command has no objProc interface. |
*/ |
//static int runAsObjProc( |
// void * clientData, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// TCL.Tcl_CmdInfo cmdInfo; |
// if( objc<2 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "COMMAND ..."); |
// return TCL.TCL_ERROR; |
// } |
// if( null==TCL.Tcl_GetCommandInfo(interp, TCL.Tcl_GetString(objv[1]), &cmdInfo) ){ |
// TCL.Tcl_AppendResult(interp, "command not found: ", |
// TCL.Tcl_GetString(objv[1]), (char)0); |
// return TCL.TCL_ERROR; |
// } |
// if( cmdInfo.objProc==0 ){ |
// TCL.Tcl_AppendResult(interp, "command has no objProc: ", |
// TCL.Tcl_GetString(objv[1]), (char)0); |
// return TCL.TCL_ERROR; |
// } |
// return cmdInfo.objProc(cmdInfo.objClientData, interp, objc-1, objv+1); |
//} |
|
/* |
** Register commands with the TCL interpreter. |
*/ |
|
#if !SQLITE_OMIT_EXPLAIN |
/* |
** WARNING: The following function, printExplainQueryPlan() is an exact |
** copy of example code from eqp.in (eqp.html). If this code is modified, |
** then the documentation copy needs to be modified as well. |
*/ |
/* |
** Argument pStmt is a prepared SQL statement. This function compiles |
** an EXPLAIN QUERY PLAN command to report on the prepared statement, |
** and prints the report to stdout using printf(). |
*/ |
static int printExplainQueryPlan( sqlite3_stmt pStmt ) |
{ |
string zSql; /* Input SQL */ |
string zExplain; /* SQL with EXPLAIN QUERY PLAN prepended */ |
sqlite3_stmt pExplain = null; /* Compiled EXPLAIN QUERY PLAN command */ |
int rc; /* Return code from sqlite3_prepare_v2() */ |
|
zSql = sqlite3_sql( pStmt ); |
if ( zSql == null ) |
return SQLITE_ERROR; |
|
zExplain = sqlite3_mprintf( "EXPLAIN QUERY PLAN %s", zSql ); |
//if ( zExplain == null ) |
// return SQLITE_NOMEM; |
|
rc = sqlite3_prepare_v2( sqlite3_db_handle( pStmt ), zExplain, -1, ref pExplain, 0 ); |
//sqlite3_free(zExplain); |
if ( rc != SQLITE_OK ) |
return rc; |
|
while ( SQLITE_ROW == sqlite3_step( pExplain ) ) |
{ |
int iSelectid = sqlite3_column_int( pExplain, 0 ); |
int iOrder = sqlite3_column_int( pExplain, 1 ); |
int iFrom = sqlite3_column_int( pExplain, 2 ); |
string zDetail = sqlite3_column_text( pExplain, 3 ); |
|
printf( "%d %d %d %s\n", iSelectid, iOrder, iFrom, zDetail ); |
} |
|
return sqlite3_finalize( pExplain ); |
} |
|
static int test_print_eqp( |
object clientData, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
int rc; |
sqlite3_stmt pStmt = null; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT" ); |
return TCL.TCL_ERROR; |
} |
if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
return TCL.TCL_ERROR; |
rc = printExplainQueryPlan( pStmt ); |
/* This is needed on Windows so that a test case using this |
** function can open a read pipe and get the output of |
** printExplainQueryPlan() immediately. |
*/ |
//fflush( stdout ); |
TCL.Tcl_SetResult( interp, t1ErrorName( rc ), 0 ); |
return TCL.TCL_OK; |
} |
#endif //* SQLITE_OMIT_EXPLAIN */ |
|
class Verb |
{ |
public string zName; |
public int i; |
|
public Verb( string zName, int i ) |
{ |
this.zName = zName; |
this.i = i; |
} |
} |
|
/* |
** sqlite3_test_control VERB ARGS... |
*/ |
static int test_test_control( |
object clientData, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
Verb[] aVerb = new Verb[] { |
new Verb( "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT ), |
}; |
int iVerb; |
int iFlag; |
int rc; |
|
if ( objc < 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "VERB ARGS..." ); |
return TCL.TCL_ERROR; |
} |
|
//rc = TCL.Tcl_GetIndexFromObjStruct( |
// interp, objv[1], aVerb, sizeof(aVerb[0]), "VERB", 0, &iVerb |
//); |
for ( iVerb = 0; iVerb < aVerb.Length && ( aVerb[iVerb].zName != objv[1].ToString() ); iVerb++ ) |
{ |
} |
if ( iVerb >= aVerb.Length ) |
return TCL.TCL_ERROR; |
|
iFlag = aVerb[iVerb].i; |
switch ( iFlag ) |
{ |
case SQLITE_TESTCTRL_LOCALTIME_FAULT: |
{ |
bool val = false; |
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 2, objv, "ONOFF" ); |
return TCL.TCL_ERROR; |
} |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[2], out val ) ) |
return TCL.TCL_ERROR; |
sqlite3_test_control( SQLITE_TESTCTRL_LOCALTIME_FAULT, val ); |
break; |
} |
} |
|
TCL.Tcl_ResetResult( interp ); |
return TCL.TCL_OK; |
} |
|
/* |
** optimization_control DB OPT BOOLEAN |
** |
** Enable or disable query optimizations using the sqlite3_test_control() |
** interface. Disable if BOOLEAN is false and enable if BOOLEAN is true. |
** OPT is the name of the optimization to be disabled. |
*/ |
public class _aOpt |
{ |
public string zOptName; |
public int mask; |
|
public _aOpt( string zOptName, int mask ) |
{ |
this.zOptName = zOptName; |
this.mask = mask; |
} |
} |
|
static int optimization_control( |
object clientData, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
int i; |
sqlite3 db = null; |
string zOpt; |
bool onoff = false; |
int mask = 0; |
_aOpt[] aOpt = { |
new _aOpt( "all", SQLITE_OptMask ), |
new _aOpt( "query-flattener", SQLITE_QueryFlattener ), |
new _aOpt( "column-cache", SQLITE_ColumnCache ), |
new _aOpt( "index-sort", SQLITE_IndexSort ), |
new _aOpt( "index-search", SQLITE_IndexSearch ), |
new _aOpt( "index-cover", SQLITE_IndexCover ), |
new _aOpt( "groupby-order", SQLITE_GroupByOrder ), |
new _aOpt( "factor-constants", SQLITE_FactorOutConst ), |
new _aOpt( "real-as-int", SQLITE_IdxRealAsInt ), |
}; |
|
if ( objc != 4 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB OPT BOOLEAN" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[3], out onoff ) ) |
return TCL.TCL_ERROR; |
zOpt = TCL.Tcl_GetString( objv[2] ); |
for ( i = 0; i < aOpt.Length; i++ )//sizeof(aOpt)/sizeof(aOpt[0]); i++) |
{ |
if ( zOpt == aOpt[i].zOptName ) |
{ |
mask = aOpt[i].mask; |
break; |
} |
} |
if ( onoff ) |
mask = ~mask; |
if ( i >= aOpt.Length )//sizeof(aOpt)/sizeof(aOpt[0]) ) |
{ |
TCL.Tcl_AppendResult( interp, "unknown optimization - should be one of:", |
null ); |
for ( i = 0; i < aOpt.Length; i++ )//sizeof(aOpt)/sizeof(aOpt[0]); i++) |
{ |
TCL.Tcl_AppendResult( interp, " ", aOpt[i].zOptName ); |
} |
return TCL.TCL_ERROR; |
} |
sqlite3_test_control( SQLITE_TESTCTRL_OPTIMIZATIONS, db, mask ); |
return TCL.TCL_OK; |
} |
|
|
static Var.SQLITE3_GETSET bitmask_size = new Var.SQLITE3_GETSET( "bitmask_size" ); |
|
#if SQLITE_OS_UNIX && (__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE |
extern int sqlite3_hostid_num; |
#endif |
static Var.SQLITE3_GETSET sqlite_static_bind_nbyte = new Var.SQLITE3_GETSET( "static_bind_nbyte" ); |
static Var.SQLITE3_GETSET sqlite_static_bind_value = new Var.SQLITE3_GETSET( "static_bind_value" ); |
|
public static int Sqlitetest1_Init( Tcl_Interp interp ) |
{ |
// extern int sqlite3_search_count; |
// extern int sqlite3_found_count; |
// extern int sqlite3_interrupt_count; |
// extern int sqlite3_sort_count; |
// extern int sqlite3_current_time; |
// extern int sqlite3_max_blobsize; |
// extern int sqlite3BtreeSharedCacheReport(void*, |
// Tcl_Interp *,int,Tcl_Obj*CONST); |
// static struct { |
// string zName; |
// TCL.Tcl_CmdProc *xProc; |
_aCmd[] aCmd = new _aCmd[] { |
new _aCmd( "db_enter", db_enter ), |
new _aCmd( "db_leave", db_leave ), |
new _aCmd( "sqlite3_mprintf_int", sqlite3_mprintf_int ), |
new _aCmd( "sqlite3_mprintf_int64", sqlite3_mprintf_int64 ), |
new _aCmd( "sqlite3_mprintf_long", sqlite3_mprintf_long ), |
new _aCmd( "sqlite3_mprintf_str", sqlite3_mprintf_str ), |
new _aCmd( "sqlite3_snprintf_str", sqlite3_snprintf_str ), |
new _aCmd( "sqlite3_mprintf_stronly", sqlite3_mprintf_stronly), |
new _aCmd( "sqlite3_mprintf_double", sqlite3_mprintf_double ), |
new _aCmd( "sqlite3_mprintf_scaled", sqlite3_mprintf_scaled ), |
new _aCmd( "sqlite3_mprintf_hexdouble", sqlite3_mprintf_hexdouble), |
new _aCmd( "sqlite3_mprintf_z_test", test_mprintf_z ), |
new _aCmd( "sqlite3_mprintf_n_test", test_mprintf_n ), |
new _aCmd( "sqlite3_snprintf_int", test_snprintf_int ), |
// new _aCmd( "sqlite3_last_insert_rowid", test_last_rowid ), |
new _aCmd( "sqlite3_exec_printf", test_exec_printf ), |
new _aCmd( "sqlite3_exec_hex", test_exec_hex ), |
new _aCmd( "sqlite3_exec", test_exec ), |
new _aCmd( "sqlite3_exec_nr", test_exec_nr ), |
#if !SQLITE_OMIT_GET_TABLE |
new _aCmd( "sqlite3_get_table_printf", test_get_table_printf ), |
#endif |
new _aCmd( "sqlite3_close", sqlite_test_close ), |
new _aCmd( "sqlite3_create_function", test_create_function ), |
new _aCmd( "sqlite3_create_aggregate", test_create_aggregate ), |
new _aCmd( "sqlite_register_test_function", test_register_func ), |
// new _aCmd( "sqlite_abort", sqlite_abort ), |
new _aCmd( "sqlite_bind", test_bind ), |
new _aCmd( "breakpoint", test_breakpoint ), |
new _aCmd( "sqlite3_key", test_key ), |
new _aCmd( "sqlite3_rekey", test_rekey ), |
new _aCmd( "sqlite_set_magic", sqlite_set_magic ), |
new _aCmd( "sqlite3_interrupt", test_interrupt ), |
new _aCmd( "sqlite_delete_function", delete_function ), |
new _aCmd( "sqlite_delete_collation", delete_collation ), |
new _aCmd( "sqlite3_get_autocommit", get_autocommit ), |
// new _aCmd( "sqlite3_stack_used", test_stack_used ), |
new _aCmd( "sqlite3_busy_timeout", test_busy_timeout ), |
// new _aCmd( "printf", test_printf ), |
// new _aCmd( "sqlite3IoTrace", test_io_trace ), |
}; |
// static struct { |
// string zName; |
// Tcl_ObjCmdProc *xProc; |
// void *object; |
_aObjCmd[] aObjCmd = new _aObjCmd[]{ |
new _aObjCmd( "sqlite3_connection_pointer", get_sqlite_pointer, 0 ), |
new _aObjCmd( "sqlite3_bind_int", test_bind_int, 0 ), |
new _aObjCmd( "sqlite3_bind_zeroblob", test_bind_zeroblob, 0 ), |
new _aObjCmd( "sqlite3_bind_int64", test_bind_int64, 0 ), |
new _aObjCmd( "sqlite3_bind_double", test_bind_double, 0 ), |
new _aObjCmd( "sqlite3_bind_null", test_bind_null ,0 ), |
new _aObjCmd( "sqlite3_bind_text", test_bind_text ,0 ), |
new _aObjCmd( "sqlite3_bind_text16", test_bind_text16 ,0 ), |
new _aObjCmd( "sqlite3_bind_blob", test_bind_blob ,0 ), |
new _aObjCmd( "sqlite3_bind_parameter_count", test_bind_parameter_count, 0), |
new _aObjCmd( "sqlite3_bind_parameter_name", test_bind_parameter_name, 0), |
new _aObjCmd( "sqlite3_bind_parameter_index", test_bind_parameter_index, 0), |
new _aObjCmd( "sqlite3_clear_bindings", test_clear_bindings, 0), |
new _aObjCmd( "sqlite3_sleep", test_sleep, 0), |
new _aObjCmd( "sqlite3_errcode", test_errcode ,0 ), |
new _aObjCmd( "sqlite3_extended_errcode", test_ex_errcode ,0 ), |
new _aObjCmd( "sqlite3_errmsg", test_errmsg ,0 ), |
// new _aObjCmd( "sqlite3_errmsg16", test_errmsg16 ,0 ), |
new _aObjCmd( "sqlite3_open", test_open ,0 ), |
// new _aObjCmd( "sqlite3_open16", test_open16 ,0 ), |
new _aObjCmd( "sqlite3_open_v2", test_open_v2 ,0 ), |
// new _aObjCmd( "sqlite3_complete16", test_complete16 ,0 ), |
|
new _aObjCmd( "sqlite3_prepare", test_prepare ,0 ), |
new _aObjCmd( "sqlite3_prepare16", test_prepare16 ,0 ), |
new _aObjCmd( "sqlite3_prepare_v2", test_prepare_v2 ,0 ), |
new _aObjCmd( "sqlite3_prepare_tkt3134", test_prepare_tkt3134, 0), |
// new _aObjCmd( "sqlite3_prepare16_v2", test_prepare16_v2 ,0 ), |
new _aObjCmd( "sqlite3_finalize", test_finalize ,0 ), |
new _aObjCmd( "sqlite3_reset", test_reset ,0 ), |
new _aObjCmd( "sqlite3_expired", test_expired ,0 ), |
new _aObjCmd( "sqlite3_transfer_bindings", test_transfer_bind ,0 ), |
new _aObjCmd( "sqlite3_changes", test_changes ,0 ), |
new _aObjCmd( "sqlite3_step", test_step ,0 ), |
// { "sqlite3_sql", test_sql ,0 }, |
new _aObjCmd( "sqlite3_next_stmt", test_next_stmt ,0 ), |
new _aObjCmd( "sqlite3_stmt_readonly", test_stmt_readonly ,0 ), |
new _aObjCmd( "uses_stmt_journal", uses_stmt_journal ,0 ), |
|
new _aObjCmd( "sqlite3_release_memory", test_release_memory, 0), |
new _aObjCmd( "sqlite3_soft_heap_limit", test_soft_heap_limit, 0), |
// new _aObjCmd( "sqlite3_thread_cleanup", test_thread_cleanup, 0), |
// new _aObjCmd( "sqlite3_pager_refcounts", test_pager_refcounts, 0), |
|
// new _aObjCmd( "sqlite3_load_extension", test_load_extension, 0), |
// new _aObjCmd( "sqlite3_enable_load_extension", test_enable_load, 0), |
new _aObjCmd( "sqlite3_extended_result_codes", test_extended_result_codes, 0), |
new _aObjCmd( "sqlite3_limit", test_limit, 0), |
|
new _aObjCmd( "save_prng_state", save_prng_state, 0 ), |
new _aObjCmd( "restore_prng_state", restore_prng_state, 0 ), |
new _aObjCmd( "reset_prng_state", reset_prng_state, 0 ), |
new _aObjCmd( "optimization_control", optimization_control,0), |
// { "tcl_objproc", runAsObjProc, 0 }, |
|
// /* sqlite3_column_*() API */ |
new _aObjCmd( "sqlite3_column_count", test_column_count ,0 ), |
new _aObjCmd( "sqlite3_data_count", test_data_count ,0 ), |
new _aObjCmd( "sqlite3_column_type", test_column_type ,0 ), |
new _aObjCmd( "sqlite3_column_blob", test_column_blob ,0 ), |
new _aObjCmd( "sqlite3_column_double", test_column_double ,0 ), |
new _aObjCmd( "sqlite3_column_int64", test_column_int64 ,0 ), |
new _aObjCmd( "sqlite3_column_text", test_stmt_utf8, (dxColumn)sqlite3_column_text ), |
new _aObjCmd( "sqlite3_column_name", test_stmt_utf8, (dxColumn)sqlite3_column_name ), |
new _aObjCmd( "sqlite3_column_int", test_stmt_int, (dxColumn_I)sqlite3_column_int ), |
new _aObjCmd( "sqlite3_column_bytes", test_stmt_int, (dxColumn_I)sqlite3_column_bytes ), |
#if !SQLITE_OMIT_DECLTYPE |
new _aObjCmd( "sqlite3_column_decltype", test_stmt_utf8, (dxColumn) sqlite3_column_decltype ), |
#endif |
#if SQLITE_ENABLE_COLUMN_METADATA |
new _aObjCmd( "sqlite3_column_database_name", test_stmt_utf8, (dxColumn)sqlite3_column_database_name), |
new _aObjCmd( "sqlite3_column_table_name", test_stmt_utf8, (dxColumn)sqlite3_column_table_name), |
new _aObjCmd( "sqlite3_column_origin_name", test_stmt_utf8, (dxColumn)sqlite3_column_origin_name), |
#endif |
|
#if !SQLITE_OMIT_UTF16 |
// { "sqlite3_column_bytes16", test_stmt_int, sqlite3_column_bytes16 ), |
// { "sqlite3_column_text16", test_stmt_utf16, sqlite3_column_text16 ), |
// { "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16), |
// { "sqlite3_column_name16", test_stmt_utf16, sqlite3_column_name16 ), |
// { "add_alignment_test_collations", add_alignment_test_collations, 0 ), |
#if SQLITE_ENABLE_COLUMN_METADATA |
//{"sqlite3_column_database_name16", |
// test_stmt_utf16, sqlite3_column_database_name16), |
//{"sqlite3_column_table_name16", test_stmt_utf16, sqlite3_column_table_name16), |
//{"sqlite3_column_origin_name16", test_stmt_utf16, sqlite3_column_origin_name16), |
#endif |
#endif |
new _aObjCmd( "sqlite3_create_collation_v2", test_create_collation_v2, 0 ), |
new _aObjCmd( "sqlite3_global_recover", test_global_recover, 0 ), |
new _aObjCmd( "working_64bit_int", working_64bit_int, 0 ), |
new _aObjCmd( "vfs_unlink_test", vfs_unlink_test, 0 ), |
//{ "vfs_initfail_test", vfs_initfail_test, 0 }, |
new _aObjCmd( "vfs_unregister_all", vfs_unregister_all, 0 ), |
new _aObjCmd("vfs_reregister_all", vfs_reregister_all, 0 ), |
new _aObjCmd( "file_control_test", file_control_test, 0 ), |
new _aObjCmd("file_control_lasterrno_test", file_control_lasterrno_test, 0 ), |
new _aObjCmd("file_control_lockproxy_test", file_control_lockproxy_test, 0 ), |
new _aObjCmd("file_control_chunksize_test", file_control_chunksize_test, 0 ), |
new _aObjCmd("file_control_sizehint_test", file_control_sizehint_test, 0), |
//new _aObjCmd( "sqlite3_vfs_list", vfs_list, 0 ), |
new _aObjCmd( "sqlite3_create_function_v2", test_create_function_v2, 0 ), |
|
// /* Functions from os.h */ |
#if !SQLITE_OMIT_UTF16 |
// { "add_test_collate", test_collate, 0 ), |
// { "add_test_collate_needed", test_collate_needed, 0 ), |
// { "add_test_function", test_function, 0 ), |
#endif |
new _aObjCmd( "sqlite3_test_errstr", test_errstr, 0 ), |
new _aObjCmd( "tcl_variable_type", tcl_variable_type, 0 ), |
#if !SQLITE_OMIT_SHARED_CACHE |
new _aObjCmd( "sqlite3_enable_shared_cache", test_enable_shared, 0 ), |
//{ "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0), |
#endif |
new _aObjCmd( "sqlite3_libversion_number", test_libversion_number, 0 ), |
#if SQLITE_ENABLE_COLUMN_METADATA |
new _aObjCmd( "sqlite3_table_column_metadata", test_table_column_metadata, 0 ), |
#endif |
#if !SQLITE_OMIT_INCRBLOB |
// new _aObjCmd( "sqlite3_blob_read", test_blob_read, 0 ), |
// new _aObjCmd( "sqlite3_blob_write", test_blob_write, 0 ), |
//{ "sqlite3_blob_reopen", test_blob_reopen, 0 }, |
//{ "sqlite3_blob_bytes", test_blob_bytes, 0 }, |
//{ "sqlite3_blob_close", test_blob_close, 0 }, |
#endif |
new _aObjCmd( "pcache_stats", test_pcache_stats, 0 ), |
#if SQLITE_ENABLE_UNLOCK_NOTIFY |
{ "sqlite3_unlock_notify", test_unlock_notify, 0 }, |
#endif |
new _aObjCmd( "sqlite3_wal_checkpoint", test_wal_checkpoint, 0 ), |
new _aObjCmd( "sqlite3_wal_checkpoint_v2", test_wal_checkpoint_v2, 0 ), |
new _aObjCmd( "test_sqlite3_log", test_sqlite3_log, 0 ), |
#if !SQLITE_OMIT_EXPLAIN |
new _aObjCmd( "print_explain_query_plan", test_print_eqp, 0 ), |
#endif |
new _aObjCmd( "sqlite3_test_control", test_test_control ), |
}; |
bitmask_size.iValue = BMS; |
int i; |
// extern int sqlite3_sync_count, sqlite3_fullsync_count; |
// extern int sqlite3_opentemp_count; |
// extern int sqlite3_like_count; |
// extern int sqlite3_xferopt_count; |
// extern int sqlite3_pager_readdb_count; |
// extern int sqlite3_pager_writedb_count; |
// extern int sqlite3_pager_writej_count; |
#if SQLITE_OS_WIN |
// extern int sqlite3_os_type; |
#endif |
#if SQLITE_DEBUG |
// extern int sqlite3WhereTrace; |
// extern int sqlite3OSTrace; |
// extern int sqlite3VdbeAddopTrace; |
// extern int sqlite3WalTrace; |
#endif |
#if SQLITE_TEST |
// extern char sqlite3_query_plan[]; |
// static char *query_plan = sqlite3_query_plan; |
#if SQLITE_ENABLE_FTS3 |
extern int sqlite3_fts3_enable_parentheses; |
#endif |
#endif |
|
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 ); |
} |
for ( i = 0; i < aObjCmd.Length; i++ ) |
{// i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ |
TCL.Tcl_CreateObjCommand( interp, aObjCmd[i].zName, |
(Interp.dxObjCmdProc)aObjCmd[i].xProc, (object)aObjCmd[i].clientData, null ); |
} |
TCL.Tcl_LinkVar( interp, "sqlite_search_count", |
sqlite3_search_count, VarFlags.SQLITE3_LINK_INT ); |
TCL.Tcl_LinkVar( interp, "sqlite_found_count", |
sqlite3_found_count, VarFlags.SQLITE3_LINK_INT ); |
TCL.Tcl_LinkVar( interp, "sqlite_sort_count", |
sqlite3_sort_count, VarFlags.SQLITE3_LINK_INT ); |
TCL.Tcl_LinkVar( interp, "sqlite3_max_blobsize", |
sqlite3_max_blobsize, VarFlags.SQLITE3_LINK_INT ); |
TCL.Tcl_LinkVar( interp, "sqlite_like_count", |
sqlite3_like_count, VarFlags.SQLITE3_LINK_INT ); |
TCL.Tcl_LinkVar( interp, "sqlite_interrupt_count", |
sqlite3_interrupt_count, VarFlags.SQLITE3_LINK_INT ); |
TCL.Tcl_LinkVar( interp, "sqlite_open_file_count", |
sqlite3_open_file_count, VarFlags.SQLITE3_LINK_INT ); |
TCL.Tcl_LinkVar( interp, "sqlite_current_time", |
sqlite3_current_time, VarFlags.SQLITE3_LINK_INT ); |
#if SQLITE_OS_UNIX && (__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE |
TCL.Tcl_LinkVar(interp, "sqlite_hostid_num", |
(char)&sqlite3_hostid_num, TCL.Tcl_LINK_INT); |
#endif |
TCL.Tcl_LinkVar( interp, "sqlite3_xferopt_count", |
sqlite3_xferopt_count, VarFlags.SQLITE3_LINK_INT ); |
TCL.Tcl_LinkVar( interp, "sqlite3_pager_readdb_count", |
sqlite3_pager_readdb_count, VarFlags.SQLITE3_LINK_INT ); |
TCL.Tcl_LinkVar( interp, "sqlite3_pager_writedb_count", |
sqlite3_pager_writedb_count, VarFlags.SQLITE3_LINK_INT ); |
TCL.Tcl_LinkVar( interp, "sqlite3_pager_writej_count", |
sqlite3_pager_writej_count, VarFlags.SQLITE3_LINK_INT ); |
#if !SQLITE_OMIT_UTF16 |
// TCL.Tcl_LinkVar(interp, "unaligned_string_counter", |
// (char)&unaligned_string_counter, VarFlag.SQLITE3_LINK_INT); |
#endif |
#if !SQLITE_OMIT_UTF16 |
// TCL.Tcl_LinkVar(interp, "sqlite_last_needed_collation", |
// (char)&pzNeededCollation, VarFlag.TCL_LINK_STRING|VarFlag.TCL_LINK_READ_ONLY); |
#endif |
#if SQLITE_OS_WIN |
// TCL.Tcl_LinkVar(interp, "sqlite_os_type", |
// (char)&sqlite3_os_type, VarFlag.SQLITE3_LINK_INT); |
#endif |
#if SQLITE_TEST |
TCL.Tcl_LinkVar( interp, "sqlite_query_plan", |
sqlite3_query_plan, VarFlags.SQLITE3_LINK_STRING | VarFlags.SQLITE3_LINK_READ_ONLY ); |
#endif |
#if SQLITE_DEBUG |
// TCL.Tcl_LinkVar(interp, "sqlite_addop_trace", |
// (char)&sqlite3VdbeAddopTrace, VarFlag.SQLITE3_LINK_INT); |
// TCL.Tcl_LinkVar(interp, "sqlite_where_trace", |
// (char)&sqlite3WhereTrace, VarFlag.SQLITE3_LINK_INT); |
// TCL.Tcl_LinkVar(interp, "sqlite_os_trace", |
// (char)&sqlite3OSTrace, VarFlag.SQLITE3_LINK_INT); |
#if !SQLITE_OMIT_WAL |
TCL.Tcl_LinkVar((interp, "sqlite_wal_trace", |
(char)&sqlite3WalTrace, VarFlag.SQLITE3_LINK_INT); |
#endif |
#endif |
#if !SQLITE_OMIT_DISKIO |
TCL.Tcl_LinkVar( interp, "sqlite_opentemp_count", |
sqlite3_opentemp_count, VarFlags.SQLITE3_LINK_INT ); |
#endif |
TCL.Tcl_LinkVar( interp, "sqlite_static_bind_value", |
sqlite_static_bind_value, VarFlags.SQLITE3_LINK_STRING ); |
TCL.Tcl_LinkVar( interp, "sqlite_static_bind_nbyte", |
sqlite_static_bind_nbyte, VarFlags.SQLITE3_LINK_INT ); |
// TCL.Tcl_LinkVar(interp, "sqlite_temp_directory", |
// (char)&sqlite3_temp_directory, VarFlag.TCL_LINK_STRING); |
TCL.Tcl_LinkVar( interp, "bitmask_size", |
bitmask_size, VarFlags.SQLITE3_LINK_INT | VarFlags.SQLITE3_LINK_READ_ONLY ); |
TCL.Tcl_LinkVar( interp, "sqlite_sync_count", |
sqlite3_sync_count, VarFlags.SQLITE3_LINK_INT ); |
TCL.Tcl_LinkVar( interp, "sqlite_fullsync_count", |
sqlite3_fullsync_count, VarFlags.SQLITE3_LINK_INT ); |
#if (SQLITE_ENABLE_FTS3) && (SQLITE_TEST) |
TCL.Tcl_LinkVar(interp, "sqlite_fts3_enable_parentheses", |
(char)&sqlite3_fts3_enable_parentheses, TCL.Tcl_LINK_INT); |
#endif |
return TCL.TCL_OK; |
} |
} |
#endif |
} |
/trunk/testfixture/src/test_malloc_c.cs |
@@ -0,0 +1,1637 @@ |
using System.Diagnostics; |
|
|
namespace Community.CsharpSqlite |
{ |
#if TCLSH |
using tcl.lang; |
using Tcl_Interp = tcl.lang.Interp; |
using Tcl_Obj = tcl.lang.TclObject; |
|
public partial class Sqlite3 |
{ |
|
/* |
** 2007 August 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. |
** |
************************************************************************* |
** |
** This file contains code used to implement test interfaces to the |
** memory allocation subsystem. |
************************************************************************* |
** 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 "tcl.h" |
//#include <stdlib.h> |
//#include <string.h> |
//#include <assert.h> |
|
/* |
** This structure is used to encapsulate the global state variables used |
** by malloc() fault simulation. |
*/ |
struct MemFault |
{ |
public int iCountdown; /* Number of pending successes before a failure */ |
public int nRepeat; /* Number of times to repeat the failure */ |
public int nBenign; /* Number of benign failures seen since last config */ |
public int nFail; /* Number of failures seen since last config */ |
public int enable; /* True if enabled */ |
public int isInstalled; /* True if the fault simulation layer is installed */ |
public int isBenignMode; /* True if malloc failures are considered benign */ |
public sqlite3_mem_methods m; /* 'Real' malloc implementation */ |
} |
static MemFault memfault; |
|
/* |
** This routine exists as a place to set a breakpoint that will |
** fire on any simulated malloc() failure. |
*/ |
static int cnt = 0; |
static void sqlite3Fault() |
{ |
cnt++; |
} |
|
/* |
** Check to see if a fault should be simulated. Return true to simulate |
** the fault. Return false if the fault should not be simulated. |
*/ |
static int faultsimStep() |
{ |
if ( likely( memfault.enable != 0 ) ) |
{ |
return 0; |
} |
if ( memfault.iCountdown > 0 ) |
{ |
memfault.iCountdown--; |
return 0; |
} |
sqlite3Fault(); |
memfault.nFail++; |
if ( memfault.isBenignMode > 0 ) |
{ |
memfault.nBenign++; |
} |
memfault.nRepeat--; |
if ( memfault.nRepeat <= 0 ) |
{ |
memfault.enable = 0; |
} |
return 1; |
} |
|
/* |
** A version of sqlite3_mem_methods.xMalloc() that includes fault simulation |
** logic. |
*/ |
static byte[] faultsimMalloc( int n ) |
{ |
byte[] p = null; |
if ( faultsimStep() != 0 ) |
{ |
p = memfault.m.xMalloc( n ); |
} |
return p; |
} |
static int[] faultsimMallocInt( int n ) |
{ |
int[] p = null; |
if ( faultsimStep() != 0 ) |
{ |
p = memfault.m.xMallocInt( n ); |
} |
return p; |
} |
static Mem faultsimMallocMem( Mem n ) |
{ |
Mem p = null; |
if ( faultsimStep() != 0 ) |
{ |
p = memfault.m.xMallocMem( n ); |
} |
return p; |
} |
/* |
** A version of sqlite3_mem_methods.xRealloc() that includes fault simulation |
** logic. |
*/ |
static byte[] faultsimRealloc( byte[] pOld, int n ) |
{ |
byte[] p = null; |
if ( faultsimStep() != 0 ) |
{ |
p = memfault.m.xRealloc( pOld, n ); |
} |
return p; |
} |
|
/* |
** The following method calls are passed directly through to the underlying |
** malloc system: |
** |
** xFree |
** xSize |
** xRoundup |
** xInit |
** xShutdown |
*/ |
static void faultsimFree( ref byte[] p ) |
{ |
memfault.m.xFree( ref p ); |
} |
static void faultsimFreeInt( ref int[] p ) |
{ |
memfault.m.xFreeInt( ref p ); |
} |
static void faultsimFreeMem( ref Mem p ) |
{ |
memfault.m.xFreeMem( ref p ); |
} |
static int faultsimSize( byte[] p ) |
{ |
return memfault.m.xSize( p ); |
} |
static int faultsimRoundup( int n ) |
{ |
return memfault.m.xRoundup( n ); |
} |
static int faultsimInit( object p ) |
{ |
return memfault.m.xInit( memfault.m.pAppData ); |
} |
static void faultsimShutdown( object p ) |
{ |
memfault.m.xShutdown( memfault.m.pAppData ); |
} |
|
/* |
** This routine configures the malloc failure simulation. After |
** calling this routine, the next nDelay mallocs will succeed, followed |
** by a block of nRepeat failures, after which malloc() calls will begin |
** to succeed again. |
*/ |
static void faultsimConfig( int nDelay, int nRepeat ) |
{ |
memfault.iCountdown = nDelay; |
memfault.nRepeat = nRepeat; |
memfault.nBenign = 0; |
memfault.nFail = 0; |
memfault.enable = ( nDelay >= 0 ) ? 1 : 0; |
|
/* Sometimes, when running multi-threaded tests, the isBenignMode |
** variable is not properly incremented/decremented so that it is |
** 0 when not inside a benign malloc block. This doesn't affect |
** the multi-threaded tests, as they do not use this system. But |
** it does affect OOM tests run later in the same process. So |
** zero the variable here, just to be sure. |
*/ |
memfault.isBenignMode = 0; |
} |
|
/* |
** Return the number of faults (both hard and benign faults) that have |
** occurred since the injector was last configured. |
*/ |
static int faultsimFailures() |
{ |
return memfault.nFail; |
} |
|
/* |
** Return the number of benign faults that have occurred since the |
** injector was last configured. |
*/ |
static int faultsimBenignFailures() |
{ |
return memfault.nBenign; |
} |
|
/* |
** Return the number of successes that will occur before the next failure. |
** If no failures are scheduled, return -1. |
*/ |
static int faultsimPending() |
{ |
if ( memfault.enable != 0 ) |
{ |
return memfault.iCountdown; |
} |
else |
{ |
return -1; |
} |
} |
|
|
static void faultsimBeginBenign() |
{ |
memfault.isBenignMode++; |
} |
static void faultsimEndBenign() |
{ |
memfault.isBenignMode--; |
} |
|
/* |
** Add or remove the fault-simulation layer using sqlite3_config(). If |
** the argument is non-zero, the |
*/ |
static int faultsimInstall( int install ) |
{ |
sqlite3_mem_methods m = new sqlite3_mem_methods( |
(dxMalloc)faultsimMalloc, /* xMalloc */ |
(dxMallocInt)faultsimMallocInt, /* xMalloc */ |
(dxMallocMem)faultsimMallocMem, /* xMalloc */ |
(dxFree)faultsimFree, /* xFree */ |
(dxFreeInt)faultsimFreeInt, /* xFree */ |
(dxFreeMem)faultsimFreeMem, |
(dxRealloc)faultsimRealloc, /* xRealloc */ |
(dxSize)faultsimSize, /* xSize */ |
(dxRoundup)faultsimRoundup, /* xRoundup */ |
(dxMemInit)faultsimInit, /* xInit */ |
(dxMemShutdown)faultsimShutdown, /* xShutdown */ |
null /* pAppData */ |
); |
int rc; |
|
//install = ( install != 0 ? 1 : 0 ); |
Debug.Assert( memfault.isInstalled == 1 || memfault.isInstalled == 0 ); |
|
if ( install == memfault.isInstalled ) |
{ |
return SQLITE_ERROR; |
} |
|
if ( install != 0 ) |
{ |
rc = sqlite3_config( SQLITE_CONFIG_GETMALLOC, ref memfault.m ); |
Debug.Assert( memfault.m.xMalloc != null ); |
if ( rc == SQLITE_OK ) |
{ |
rc = sqlite3_config( SQLITE_CONFIG_MALLOC, m ); |
} |
sqlite3_test_control( SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, |
(void_function)faultsimBeginBenign, (void_function)faultsimEndBenign |
); |
} |
else |
{ |
//sqlite3_mem_methods m; |
Debug.Assert( memfault.m.xMalloc != null ); |
|
/* One should be able to reset the default memory allocator by storing |
** a zeroed allocator then calling GETMALLOC. */ |
m = new sqlite3_mem_methods();// memset( &m, 0, sizeof( m ) ); |
sqlite3_config( SQLITE_CONFIG_MALLOC, m ); |
sqlite3_config( SQLITE_CONFIG_GETMALLOC, ref m ); |
Debug.Assert( m.GetHashCode() == memfault.m.GetHashCode() );//memcmp(&m, &memfault.m, sizeof(m))==0 ); |
|
rc = sqlite3_config( SQLITE_CONFIG_MALLOC, ref memfault.m ); |
sqlite3_test_control( SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, 0, 0 ); |
} |
|
if ( rc == SQLITE_OK ) |
{ |
memfault.isInstalled = 1; |
} |
return rc; |
} |
|
#if SQLITE_TEST |
|
/* |
** This function is implemented in test1.c. Returns a pointer to a static |
** buffer containing the symbolic SQLite error code that corresponds to |
** the least-significant 8-bits of the integer passed as an argument. |
** For example: |
** |
** sqlite3TestErrorName(1) -> "SQLITE_ERROR" |
*/ |
//string sqlite3TestErrorName(int); |
|
|
/* |
** Transform pointers to text and back again |
*/ |
//static void pointerToText(object p, string z){ |
// static const char zHex[] = "0123456789abcdef"; |
// int i, k; |
// unsigned int u; |
// sqlite3_u3264 n; |
// if( p==0 ){ |
// strcpy(z, "0"); |
// return; |
//} |
// if( sizeof(n)==sizeof(p) ){ |
// memcpy(&n, ref p, sizeof(p)); |
// }else if( sizeof(u)==sizeof(p) ){ |
// memcpy(&u, ref p, sizeof(u)); |
// n = u; |
// }else{ |
// Debug.Assert( 0 ); |
// } |
// for(i=0, k=sizeof(p)*2-1; i<sizeof(p)*2; i++, k--){ |
// z[k] = zHex[n&0xf]; |
// n >>= 4; |
// } |
// z[sizeof(p)*2] = 0; |
//} |
//static int hexToInt(int h){ |
// if( h>='0' && h<='9' ){ |
// return h - '0'; |
// }else if( h>='a' && h<='f' ){ |
// return h - 'a' + 10; |
// }else{ |
// return -1; |
// } |
//} |
//static int textToPointer(string z, object **pp){ |
// sqlite3_u3264 n = 0; |
// int i; |
// unsigned int u; |
// for(i=0; i<sizeof(void)*2 && z[0]; i++){ |
// int v; |
// v = hexToInt(*z++); |
// if( v<0 ) return TCL.TCL_ERROR; |
// n = n*16 + v; |
// } |
// if( *z!=0 ) return TCL.TCL_ERROR; |
// if( sizeof(n)==sizeof(*pp) ){ |
// memcpy(pp, ref n, sizeof(n)); |
// }else if( sizeof(u)==sizeof(*pp) ){ |
// u = (unsigned int)n; |
// memcpy(pp, ref u, sizeof(u)); |
// }else{ |
// Debug.Assert( 0 ); |
// } |
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: sqlite3Malloc NBYTES |
** |
** Raw test interface for sqlite3Malloc(). |
*/ |
//static int test_malloc( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// int nByte; |
// object p; |
// char zOut[100]; |
// if( objc!=2 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "NBYTES"); |
// return TCL.TCL_ERROR; |
// } |
// if( TCL.Tcl_GetIntFromObj(interp, objv[1], out nByte) ) return TCL.TCL_ERROR; |
// p = sqlite3Malloc((unsigned)nByte); |
// pointerToText(p, zOut); |
// TCL.TCL_AppendResult(interp, zOut, NULL); |
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: sqlite3_realloc PRIOR NBYTES |
** |
** Raw test interface for sqlite3_realloc(). |
*/ |
//static int test_realloc( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// int nByte; |
// void pPrior, p; |
// char zOut[100]; |
// if( objc!=3 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "PRIOR NBYTES"); |
// return TCL.TCL_ERROR; |
// } |
// if( TCL.Tcl_GetIntFromObj(interp, objv[2], out nByte) ) return TCL.TCL_ERROR; |
// if( textToPointer(Tcl_GetString(objv[1]), out pPrior) ){ |
// TCL.TCL_AppendResult(interp, "bad pointer: ", TCL.Tcl_GetString(objv[1])); |
// return TCL.TCL_ERROR; |
// } |
// p = sqlite3_realloc(pPrior, (unsigned)nByte); |
// pointerToText(p, zOut); |
// TCL.TCL_AppendResult(interp, zOut, NULL); |
// return TCL.TCL_OK; |
//} |
|
/* |
** tclcmd: sqlite3_config_uri BOOLEAN |
** |
** Invoke sqlite3_config() or sqlite3_db_config() with invalid |
** opcodes and verify that they return errors. |
*/ |
static int test_config_uri( |
object clientData, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
){ |
int rc; |
bool bOpenUri = false; |
|
if( objc!=2 ){ |
TCL.Tcl_WrongNumArgs(interp, 1, objv, "BOOL"); |
return TCL.TCL_ERROR; |
} |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[1], out bOpenUri ) ) |
{ |
return TCL.TCL_ERROR; |
} |
|
rc = sqlite3_config(SQLITE_CONFIG_URI, bOpenUri); |
TCL.Tcl_SetResult( interp, sqlite3TestErrorName( rc ), TCL.TCL_VOLATILE ); |
|
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_free PRIOR |
** |
** Raw test interface for sqlite3DbFree(db,). |
*/ |
//static int test_free( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// void pPrior; |
// if( objc!=2 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "PRIOR"); |
// return TCL.TCL_ERROR; |
// } |
// if( textToPointer(Tcl_GetString(objv[1]), out pPrior) ){ |
// TCL.TCL_AppendResult(interp, "bad pointer: ", TCL.Tcl_GetString(objv[1])); |
// return TCL.TCL_ERROR; |
// } |
// sqlite3DbFree(db,pPrior); |
// return TCL.TCL_OK; |
//} |
|
/* |
** These routines are in test_hexio.c |
*/ |
//int sqlite3TestHexToBin(string , int, char ); |
//int sqlite3TestBinToHex(char*,int); |
|
/* |
** Usage: memset ADDRESS SIZE HEX |
** |
** Set a chunk of memory (obtained from malloc, probably) to a |
** specified hex pattern. |
*/ |
//static int test_memset( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// object p; |
// int size, n, i; |
// string zHex; |
// string zOut; |
// char zBin[100]; |
|
// if( objc!=4 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "ADDRESS SIZE HEX"); |
// return TCL.TCL_ERROR; |
// } |
// if( textToPointer(Tcl_GetString(objv[1]), out p) ){ |
// TCL.TCL_AppendResult(interp, "bad pointer: ", TCL.Tcl_GetString(objv[1])); |
// return TCL.TCL_ERROR; |
// } |
// if( TCL.Tcl_GetIntFromObj(interp, objv[2], out size) ){ |
// return TCL.TCL_ERROR; |
// } |
// if( size<=0 ){ |
// TCL.TCL_AppendResult(interp, "size must be positive"); |
// return TCL.TCL_ERROR; |
// } |
// zHex = TCL.Tcl_GetStringFromObj(objv[3], out n); |
// if( n>sizeof(zBin)*2 ) n = sizeof(zBin)*2; |
// n = sqlite3TestHexToBin(zHex, n, zBin); |
// if( n==0 ){ |
// TCL.TCL_AppendResult(interp, "no data"); |
// return TCL.TCL_ERROR; |
// } |
// zOut = p; |
// for(i=0; i<size; i++){ |
// zOut[i] = zBin[i%n]; |
// } |
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: memget ADDRESS SIZE |
** |
** Return memory as hexadecimal text. |
*/ |
//static int test_memget( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// object p; |
// int size, n; |
// string zBin; |
// char zHex[100]; |
|
// if( objc!=3 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "ADDRESS SIZE"); |
// return TCL.TCL_ERROR; |
// } |
// if( textToPointer(Tcl_GetString(objv[1]), out p) ){ |
// TCL.TCL_AppendResult(interp, "bad pointer: ", TCL.Tcl_GetString(objv[1])); |
// return TCL.TCL_ERROR; |
// } |
// if( TCL.Tcl_GetIntFromObj(interp, objv[2], out size) ){ |
// return TCL.TCL_ERROR; |
// } |
// if( size<=0 ){ |
// TCL.TCL_AppendResult(interp, "size must be positive"); |
// return TCL.TCL_ERROR; |
// } |
// zBin = p; |
// while( size>0 ){ |
// if( size>(sizeof(zHex)-1)/2 ){ |
// n = (sizeof(zHex)-1)/2; |
// }else{ |
// n = size; |
// } |
// memcpy(zHex, zBin, n); |
// zBin += n; |
// size -= n; |
// sqlite3TestBinToHex(zHex, n); |
// TCL.TCL_AppendResult(interp, zHex); |
// } |
// return TCL.TCL_OK; |
//} |
#if FALSE |
/* |
** Usage: sqlite3_memory_used |
** |
** Raw test interface for sqlite3_memory_used(). |
*/ |
static int test_memory_used( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewWideIntObj( sqlite3_memory_used() ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_memory_highwater ?RESETFLAG? |
** |
** Raw test interface for sqlite3_memory_highwater(). |
*/ |
static int test_memory_highwater( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
bool resetFlag = false; |
if ( objc != 1 && objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "?RESET?" ); |
return TCL.TCL_ERROR; |
} |
if ( objc == 2 ) |
{ |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[1], out resetFlag ) ) return TCL.TCL_ERROR; |
} |
TCL.Tcl_SetObjResult( interp, |
TCL.Tcl_NewWideIntObj( sqlite3_memory_highwater( resetFlag ? 1 : 0 ) ) ); |
return TCL.TCL_OK; |
} |
#endif |
|
/* |
** Usage: sqlite3_memdebug_backtrace DEPTH |
** |
** Set the depth of backtracing. If SQLITE_MEMDEBUG is not defined |
** then this routine is a no-op. |
*/ |
//static int test_memdebug_backtrace( |
// object clientdata, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// int depth; |
// if( objc!=2 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "DEPT"); |
// return TCL.TCL_ERROR; |
// } |
// if( TCL.Tcl_GetIntFromObj(interp, objv[1], out depth) ) return TCL.TCL_ERROR; |
//#if SQLITE_MEMDEBUG |
// { |
// extern void sqlite3MemdebugBacktrace(int); |
// sqlite3MemdebugBacktrace(depth); |
// } |
//#endif |
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: sqlite3_memdebug_dump FILENAME |
** |
** Write a summary of unfreed memory to FILENAME. |
*/ |
static int test_memdebug_dump( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "FILENAME" ); |
return TCL.TCL_ERROR; |
} |
#if (SQLITE_MEMDEBUG) || (SQLITE_MEMORY_SIZE) || (SQLITE_POW2_MEMORY_SIZE) |
{ |
extern void sqlite3MemdebugDump(const char); |
sqlite3MemdebugDump(Tcl_GetString(objv[1])); |
} |
#endif |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_memdebug_malloc_count |
** |
** Return the total number of times malloc() has been called. |
*/ |
static int test_memdebug_malloc_count( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
int nMalloc = -1; |
if ( objc != 1 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "" ); |
return TCL.TCL_ERROR; |
} |
#if SQLITE_MEMDEBUG |
{ |
extern int sqlite3MemdebugMallocCount(); |
nMalloc = sqlite3MemdebugMallocCount(); |
} |
#endif |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( nMalloc ) ); |
return TCL.TCL_OK; |
} |
|
|
/* |
** Usage: sqlite3_memdebug_fail COUNTER ?OPTIONS? |
** |
** where options are: |
** |
** -repeat <count> |
** -benigncnt <varname> |
** |
** Arrange for a simulated malloc() failure after COUNTER successes. |
** If a repeat count is specified, the fault is repeated that many |
** times. |
** |
** Each call to this routine overrides the prior counter value. |
** This routine returns the number of simulated failures that have |
** happened since the previous call to this routine. |
** |
** To disable simulated failures, use a COUNTER of -1. |
*/ |
static int test_memdebug_fail( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
int ii; |
int iFail = 0; |
int nRepeat = 1; |
Tcl_Obj pBenignCnt = null; |
int nBenign; |
int nFail = 0; |
|
if ( objc < 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "COUNTER ?OPTIONS?" ); |
return TCL.TCL_ERROR; |
} |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[1], out iFail ) ) |
return TCL.TCL_ERROR; |
|
for ( ii = 2; ii < objc; ii += 2 ) |
{ |
int nOption = 0; |
string zOption = TCL.Tcl_GetStringFromObj( objv[ii], out nOption ); |
string zErr = ""; |
|
if ( nOption > 1 && zOption == "-repeat" ) |
{ |
if ( ii == ( objc - 1 ) ) |
{ |
zErr = "option requires an argument: "; |
} |
else |
{ |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[ii + 1], out nRepeat ) ) |
{ |
return TCL.TCL_ERROR; |
} |
} |
} |
else if ( nOption > 1 && zOption == "-benigncnt" ) |
{ |
if ( ii == ( objc - 1 ) ) |
{ |
zErr = "option requires an argument: "; |
} |
else |
{ |
pBenignCnt = objv[ii + 1]; |
} |
} |
else |
{ |
zErr = "unknown option: "; |
} |
|
if ( zErr != "" ) |
{ |
TCL.Tcl_AppendResult( interp, zErr, zOption ); |
return TCL.TCL_ERROR; |
} |
} |
|
nBenign = faultsimBenignFailures(); |
nFail = faultsimFailures(); |
faultsimConfig( iFail, nRepeat ); |
if ( pBenignCnt != null ) |
{ |
TCL.Tcl_ObjSetVar2( interp, pBenignCnt, null, TCL.Tcl_NewIntObj( nBenign ), 0 ); |
} |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( nFail ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_memdebug_pending |
** |
** Return the number of malloc() calls that will succeed before a |
** simulated failure occurs. A negative return value indicates that |
** no malloc() failure is scheduled. |
*/ |
// static int test_memdebug_pending( |
// object clientData, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// int nPending; |
// if( objc!=1 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, ""); |
// return TCL.TCL_ERROR; |
// } |
// nPending = faultsimPending(); |
// TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(nPending)); |
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: sqlite3_memdebug_settitle TITLE |
** |
** Set a title string stored with each allocation. The TITLE is |
** typically the name of the test that was running when the |
** allocation occurred. The TITLE is stored with the allocation |
** and can be used to figure out which tests are leaking memory. |
** |
** Each title overwrite the previous. |
*/ |
static int test_memdebug_settitle( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
string zTitle; |
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "TITLE" ); |
return TCL.TCL_ERROR; |
} |
zTitle = TCL.Tcl_GetString( objv[1] ); |
#if SQLITE_MEMDEBUG |
{ |
extern int sqlite3MemdebugSettitle(const char); |
sqlite3MemdebugSettitle(zTitle); |
} |
#endif |
return TCL.TCL_OK; |
} |
|
//#define MALLOC_LOG_FRAMES 10 |
//static TCL.Tcl_HashTable aMallocLog; |
//static int mallocLogEnabled = 0; |
|
//typedef struct MallocLog MallocLog; |
//struct MallocLog { |
// int nCall; |
// int nByte; |
//}; |
|
//#if SQLITE_MEMDEBUG |
//static void test_memdebug_callback(int nByte, int nFrame, object **aFrame){ |
// if( mallocLogEnabled ){ |
// MallocLog pLog; |
// TCL.Tcl_HashEntry pEntry; |
// int isNew; |
|
// int aKey[MALLOC_LOG_FRAMES]; |
// int nKey = sizeof(int)*MALLOC_LOG_FRAMES; |
|
// memset(aKey, 0, nKey); |
// if( (sizeof(void)*nFrame)<nKey ){ |
// nKey = nFrame*sizeof(void); |
// } |
// memcpy(aKey, aFrame, nKey); |
|
// pEntry = TCL.Tcl_CreateHashEntry(&aMallocLog, (string )aKey, ref isNew); |
// if( isNew ){ |
// pLog = (MallocLog )Tcl_Alloc(sizeof(MallocLog)); |
// memset(pLog, 0, sizeof(MallocLog)); |
// TCL.Tcl_SetHashValue(pEntry, (ClientData)pLog); |
// }else{ |
// pLog = (MallocLog )Tcl_GetHashValue(pEntry); |
// } |
|
// pLog->nCall++; |
// pLog->nByte += nByte; |
// } |
//} |
//#endif //* SQLITE_MEMDEBUG */ |
|
//static void test_memdebug_log_clear(){ |
// TCL.Tcl_HashSearch search; |
// TCL.Tcl_HashEntry pEntry; |
// for( |
// pEntry=Tcl_FirstHashEntry(&aMallocLog, ref search); |
// pEntry; |
// pEntry=Tcl_NextHashEntry(&search) |
// ){ |
// MallocLog pLog = (MallocLog )Tcl_GetHashValue(pEntry); |
// TCL.Tcl_Free((char )pLog); |
// } |
// TCL.Tcl_DeleteHashTable(&aMallocLog); |
// TCL.Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_FRAMES); |
//} |
|
//static int test_memdebug_log( |
// object clientData, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// static int isInit = 0; |
// int iSub; |
|
// static string MB_strs[] = { "start", "stop", "dump", "clear", "sync" }; |
// enum MB_enum { |
// MB_LOG_START, MB_LOG_STOP, MB_LOG_DUMP, MB_LOG_CLEAR, MB_LOG_SYNC |
// }; |
|
// if( null==isInit ){ |
//#if SQLITE_MEMDEBUG |
// extern void sqlite3MemdebugBacktraceCallback( |
// void (*xBacktrace)(int, int, object *)); |
// sqlite3MemdebugBacktraceCallback(test_memdebug_callback); |
//#endif |
// TCL.Tcl_InitHashTable(&aMallocLog, MALLOC_LOG_FRAMES); |
// isInit = 1; |
// } |
|
// if( objc<2 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ..."); |
// } |
// if( TCL.Tcl_GetIndexFromObj(interp, objv[1], MB_strs, "sub-command", 0, out iSub) ){ |
// return TCL.TCL_ERROR; |
// } |
|
// switch( (enum MB_enum)iSub ){ |
// case MB_LOG_START: |
// mallocLogEnabled = 1; |
// break; |
// case MB_LOG_STOP: |
// mallocLogEnabled = 0; |
// break; |
// case MB_LOG_DUMP: { |
// TCL.Tcl_HashSearch search; |
// TCL.Tcl_HashEntry pEntry; |
// Tcl_Obj pRet = TCL.Tcl_NewObj(); |
|
// Debug.Assert(sizeof(int)==sizeof(void)); |
|
// for( |
// pEntry=Tcl_FirstHashEntry(&aMallocLog, ref search); |
// pEntry; |
// pEntry=Tcl_NextHashEntry(&search) |
// ){ |
// Tcl_Obj *apElem[MALLOC_LOG_FRAMES+2]; |
// MallocLog pLog = (MallocLog )Tcl_GetHashValue(pEntry); |
// int *aKey = (int )Tcl_GetHashKey(&aMallocLog, pEntry); |
// int ii; |
|
// apElem[0] = TCL.Tcl_NewIntObj(pLog->nCall); |
// apElem[1] = TCL.Tcl_NewIntObj(pLog->nByte); |
// for(ii=0; ii<MALLOC_LOG_FRAMES; ii++){ |
// apElem[ii+2] = TCL.Tcl_NewIntObj(aKey[ii]); |
// } |
|
// TCL.Tcl_ListObjAppendElement(interp, pRet, |
// TCL.Tcl_NewListObj(MALLOC_LOG_FRAMES+2, apElem) |
// ); |
// } |
|
// TCL.Tcl_SetObjResult(interp, pRet); |
// break; |
// } |
// case MB_LOG_CLEAR: { |
// test_memdebug_log_clear(); |
// break; |
// } |
|
// case MB_LOG_SYNC: { |
//#if SQLITE_MEMDEBUG |
// extern void sqlite3MemdebugSync(); |
// test_memdebug_log_clear(); |
// mallocLogEnabled = 1; |
// sqlite3MemdebugSync(); |
//#endif |
// break; |
// } |
// } |
|
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: sqlite3_config_scratch SIZE N |
** |
** Set the scratch memory buffer using SQLITE_CONFIG_SCRATCH. |
** The buffer is static and is of limited size. N might be |
** adjusted downward as needed to accomodate the requested size. |
** The revised value of N is returned. |
** |
** A negative SIZE causes the buffer pointer to be NULL. |
*/ |
static int test_config_scratch( |
object clientData, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
int sz = 0, N = 0, rc; |
Tcl_Obj pResult; |
byte[][] buf = null; |
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "SIZE N" ); |
return TCL.TCL_ERROR; |
} |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[1], out sz ) ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out N ) ) |
return TCL.TCL_ERROR; |
//free(buf); |
if ( sz < 0 ) |
{ |
buf = null; |
rc = sqlite3_config( SQLITE_CONFIG_SCRATCH, 0, 0, 0 ); |
} |
else |
{ |
buf = new byte[2][];//// malloc( sz * N + 1 ); |
rc = sqlite3_config( SQLITE_CONFIG_SCRATCH, buf, sz, N ); |
} |
pResult = TCL.Tcl_NewObj(); |
TCL.Tcl_ListObjAppendElement( null, pResult, TCL.Tcl_NewIntObj( rc ) ); |
TCL.Tcl_ListObjAppendElement( null, pResult, TCL.Tcl_NewIntObj( N ) ); |
TCL.Tcl_SetObjResult( interp, pResult ); |
return TCL.TCL_OK; |
} |
|
|
/* |
** Usage: sqlite3_config_pagecache SIZE N |
** |
** Set the page-cache memory buffer using SQLITE_CONFIG_PAGECACHE. |
** The buffer is static and is of limited size. N might be |
** adjusted downward as needed to accomodate the requested size. |
** The revised value of N is returned. |
** |
** A negative SIZE causes the buffer pointer to be NULL. |
*/ |
static int test_config_pagecache( |
object clientData, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
int sz = 0, N = 0, rc; |
Tcl_Obj pResult; |
MemPage buf; // byte[] buf = null; |
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "SIZE N" ); |
return TCL.TCL_ERROR; |
} |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[1], out sz ) ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out N ) ) |
return TCL.TCL_ERROR; |
//free(buf); |
if ( sz < 0 ) |
{ |
buf = null; |
rc = sqlite3_config( SQLITE_CONFIG_PAGECACHE, 0, 0, 0 ); |
} |
else |
{ |
buf = new MemPage();// new byte[sz * N]; //malloc( sz * N ); |
rc = sqlite3_config( SQLITE_CONFIG_PAGECACHE, buf, sz, N ); |
} |
pResult = TCL.Tcl_NewObj(); |
TCL.Tcl_ListObjAppendElement( null, pResult, TCL.Tcl_NewIntObj( rc ) ); |
TCL.Tcl_ListObjAppendElement( null, pResult, TCL.Tcl_NewIntObj( N ) ); |
TCL.Tcl_SetObjResult( interp, pResult ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_config_alt_pcache INSTALL_FLAG DISCARD_CHANCE PRNG_SEED |
** |
** Set up the alternative test page cache. Install if INSTALL_FLAG is |
** true and uninstall (reverting to the default page cache) if INSTALL_FLAG |
** is false. DISCARD_CHANGE is an integer between 0 and 100 inclusive |
** which determines the chance of discarding a page when unpinned. 100 |
** is certainty. 0 is never. PRNG_SEED is the pseudo-random number generator |
** seed. |
*/ |
//static int test_alt_pcache( |
// object clientData, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// int installFlag; |
// int discardChance = 0; |
// int prngSeed = 0; |
// int highStress = 0; |
// extern void installTestPCache(int,unsigned,unsigned,unsigned); |
// if( objc<2 || objc>5 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, |
// "INSTALLFLAG DISCARDCHANCE PRNGSEEED HIGHSTRESS"); |
// return TCL.TCL_ERROR; |
// } |
// if( TCL.Tcl_GetIntFromObj(interp, objv[1], &installFlag) ) return TCL.TCL_ERROR; |
// if( objc>=3 && TCL.Tcl_GetIntFromObj(interp, objv[2], &discardChance) ){ |
// return TCL.TCL_ERROR; |
// } |
// if( objc>=4 && TCL.Tcl_GetIntFromObj(interp, objv[3], &prngSeed) ){ |
// return TCL.TCL_ERROR; |
// } |
// if( objc>=5 && TCL.Tcl_GetIntFromObj(interp, objv[4], &highStress) ){ |
// return TCL.TCL_ERROR; |
// } |
// if( discardChance<0 || discardChance>100 ){ |
// TCL.Tcl_AppendResult(interp, "discard-chance should be between 0 and 100", |
// (char)0); |
// return TCL.TCL_ERROR; |
// } |
// installTestPCache(installFlag, (unsigned)discardChance, (unsigned)prngSeed, |
// (unsigned)highStress); |
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: sqlite3_config_memstatus BOOLEAN |
** |
** Enable or disable memory status reporting using SQLITE_CONFIG_MEMSTATUS. |
*/ |
static int test_config_memstatus( |
object clientData, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
bool enable = false; |
int rc; |
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "BOOLEAN" ); |
return TCL.TCL_ERROR; |
} |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[1], out enable ) ) |
return TCL.TCL_ERROR; |
rc = sqlite3_config( SQLITE_CONFIG_MEMSTATUS, enable ); |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( rc ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_config_lookaside SIZE COUNT |
** |
*/ |
static int test_config_lookaside( |
object clientData, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
int rc; |
int sz = 0, cnt = 0; |
Tcl_Obj pRet; |
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "SIZE COUNT" ); |
return TCL.TCL_ERROR; |
} |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[1], out sz ) ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out cnt ) ) |
return TCL.TCL_ERROR; |
pRet = TCL.Tcl_NewObj(); |
TCL.Tcl_ListObjAppendElement( |
interp, pRet, TCL.Tcl_NewIntObj( sqlite3GlobalConfig.szLookaside ) |
); |
TCL.Tcl_ListObjAppendElement( |
interp, pRet, TCL.Tcl_NewIntObj( sqlite3GlobalConfig.nLookaside ) |
); |
rc = sqlite3_config( SQLITE_CONFIG_LOOKASIDE, sz, cnt ); |
TCL.Tcl_SetObjResult( interp, pRet ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: sqlite3_db_config_lookaside CONNECTION BUFID SIZE COUNT |
** |
** There are two static buffers with BUFID 1 and 2. Each static buffer |
** is 10KB in size. A BUFID of 0 indicates that the buffer should be NULL |
** which will cause sqlite3_db_config() to allocate space on its own. |
*/ |
static int test_db_config_lookaside( |
object clientData, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
int rc; |
int sz = 0, cnt = 0; |
sqlite3 db = new sqlite3(); |
int bufid = 0; |
byte[][] azBuf = new byte[2][]; |
//int getDbPointer(Tcl_Interp*, const char*, sqlite3*); |
if ( objc != 5 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "BUFID SIZE COUNT" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out bufid ) ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[3], out sz ) ) |
return TCL.TCL_ERROR; |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[4], out cnt ) ) |
return TCL.TCL_ERROR; |
if ( bufid == 0 ) |
{ |
rc = sqlite3_db_config( db, SQLITE_DBCONFIG_LOOKASIDE, null, sz, cnt ); |
} |
else if ( bufid >= 1 && bufid <= 2 && sz * cnt <= azBuf[0].Length ) |
{ |
rc = sqlite3_db_config( db, SQLITE_DBCONFIG_LOOKASIDE, azBuf[bufid], sz, cnt ); |
} |
else |
{ |
TCL.Tcl_AppendResult( interp, "illegal arguments - see documentation" ); |
return TCL.TCL_ERROR; |
} |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( rc ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Usage: |
** |
** sqlite3_config_heap NBYTE NMINALLOC |
*/ |
//static int test_config_heap( |
// object clientData, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// static string zBuf; /* Use this memory */ |
// static int szBuf; /* Bytes allocated for zBuf */ |
// int nByte; /* Size of buffer to pass to sqlite3_config() */ |
// int nMinAlloc; /* Size of minimum allocation */ |
// int rc; /* Return code of sqlite3_config() */ |
|
// Tcl_Obj * CONST *aArg = objv[1]; |
// int nArg = objc-1; |
|
// if( nArg!=2 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "NBYTE NMINALLOC"); |
// return TCL.TCL_ERROR; |
// } |
// if( TCL.Tcl_GetIntFromObj(interp, aArg[0], out nByte) ) return TCL.TCL_ERROR; |
// if( TCL.Tcl_GetIntFromObj(interp, aArg[1], out nMinAlloc) ) return TCL.TCL_ERROR; |
|
// if( nByte==0 ){ |
// free( zBuf ); |
// zBuf = 0; |
// szBuf = 0; |
// rc = sqlite3_config(SQLITE_CONFIG_HEAP, (void)0, 0, 0); |
// }else{ |
// zBuf = realloc(zBuf, nByte); |
// szBuf = nByte; |
// rc = sqlite3_config(SQLITE_CONFIG_HEAP, zBuf, nByte, nMinAlloc); |
// } |
|
// TCL.Tcl_SetResult(interp, (char )sqlite3TestErrorName(rc), TCL.Tcl_VOLATILE); |
// return TCL.TCL_OK; |
//} |
|
/* |
** tclcmd: sqlite3_config_error [DB] |
** |
** Invoke sqlite3_config() or sqlite3_db_config() with invalid |
** opcodes and verify that they return errors. |
*/ |
//static int test_config_error( |
// object clientData, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// sqlite3 db; |
// int getDbPointer(Tcl_Interp*, const char*, sqlite3*); |
|
// if( objc!=2 && objc!=1 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "[DB]"); |
// return TCL.TCL_ERROR; |
// } |
// if( objc==2 ){ |
// if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) ) return TCL.TCL_ERROR; |
// if( sqlite3_db_config(db, 99999)!=SQLITE_ERROR ){ |
// TCL.Tcl_AppendResult(interp, |
// "sqlite3_db_config(db, 99999) does not return SQLITE_ERROR", |
// (char)0); |
// return TCL.TCL_ERROR; |
// } |
// }else{ |
// if( sqlite3_config(99999)!=SQLITE_ERROR ){ |
// TCL.Tcl_AppendResult(interp, |
// "sqlite3_config(99999) does not return SQLITE_ERROR", |
// (char)0); |
// return TCL.TCL_ERROR; |
// } |
// } |
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: |
** |
** sqlite3_dump_memsys3 FILENAME |
** sqlite3_dump_memsys5 FILENAME |
** |
** Write a summary of unfreed memsys3 allocations to FILENAME. |
*/ |
//static int test_dump_memsys3( |
// object clientData, |
// Tcl_Interp interp, |
// int objc, |
// Tcl_Obj[] objv |
//){ |
// if( objc!=2 ){ |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "FILENAME"); |
// return TCL.TCL_ERROR; |
// } |
|
// switch( (int)clientData ){ |
// case 3: { |
//#if SQLITE_ENABLE_MEMSYS3 |
// extern void sqlite3Memsys3Dump(const char); |
// sqlite3Memsys3Dump(Tcl_GetString(objv[1])); |
// break; |
//#endif |
// } |
// case 5: { |
//#if SQLITE_ENABLE_MEMSYS5 |
// extern void sqlite3Memsys5Dump(const char); |
// sqlite3Memsys5Dump(Tcl_GetString(objv[1])); |
// break; |
//#endif |
// } |
// } |
// return TCL.TCL_OK; |
//} |
|
/* |
** Usage: sqlite3_status OPCODE RESETFLAG |
** |
** Return a list of three elements which are the sqlite3_status() return |
** code, the current value, and the high-water mark value. |
*/ |
class _aOp |
{ |
public string zName; |
public int op; |
public _aOp( string zName, int op ) |
{ |
this.zName = zName; |
this.op = op; |
} |
} |
|
static int test_status( |
object clientdata, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
int rc, iValue, mxValue; |
int i, op = 0; |
bool resetFlag = false; |
string zOpName; |
|
_aOp[] aOp = new _aOp[] { |
new _aOp( "SQLITE_STATUS_MEMORY_USED", SQLITE_STATUS_MEMORY_USED ), |
new _aOp( "SQLITE_STATUS_MALLOC_SIZE", SQLITE_STATUS_MALLOC_SIZE ), |
new _aOp( "SQLITE_STATUS_PAGECACHE_USED", SQLITE_STATUS_PAGECACHE_USED ), |
new _aOp( "SQLITE_STATUS_PAGECACHE_OVERFLOW", SQLITE_STATUS_PAGECACHE_OVERFLOW ), |
new _aOp( "SQLITE_STATUS_PAGECACHE_SIZE", SQLITE_STATUS_PAGECACHE_SIZE ), |
new _aOp( "SQLITE_STATUS_SCRATCH_USED", SQLITE_STATUS_SCRATCH_USED ), |
new _aOp( "SQLITE_STATUS_SCRATCH_OVERFLOW", SQLITE_STATUS_SCRATCH_OVERFLOW ), |
new _aOp( "SQLITE_STATUS_SCRATCH_SIZE", SQLITE_STATUS_SCRATCH_SIZE ), |
new _aOp( "SQLITE_STATUS_PARSER_STACK", SQLITE_STATUS_PARSER_STACK ), |
new _aOp("SQLITE_STATUS_MALLOC_COUNT", SQLITE_STATUS_MALLOC_COUNT ), |
}; |
Tcl_Obj pResult; |
if ( objc != 3 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "PARAMETER RESETFLAG" ); |
return TCL.TCL_ERROR; |
} |
zOpName = TCL.Tcl_GetString( objv[1] ); |
for ( i = 0; i < ArraySize( aOp ); i++ ) |
{ |
if ( aOp[i].zName == zOpName ) |
{//strcmp(aOp[i].zName, zOpName)==0 ){ |
op = aOp[i].op; |
break; |
} |
} |
if ( i >= ArraySize( aOp ) ) |
{ |
if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[1], out op ) ) |
return TCL.TCL_ERROR; |
} |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[2], out resetFlag ) ) |
return TCL.TCL_ERROR; |
iValue = 0; |
mxValue = 0; |
rc = sqlite3_status( op, ref iValue, ref mxValue, resetFlag ? 1 : 0 ); |
pResult = TCL.Tcl_NewObj(); |
TCL.Tcl_ListObjAppendElement( null, pResult, TCL.Tcl_NewIntObj( rc ) ); |
TCL.Tcl_ListObjAppendElement( null, pResult, TCL.Tcl_NewIntObj( iValue ) ); |
TCL.Tcl_ListObjAppendElement( null, pResult, TCL.Tcl_NewIntObj( mxValue ) ); |
TCL.Tcl_SetObjResult( interp, pResult ); |
return TCL.TCL_OK; |
} |
/* |
** Usage: sqlite3_db_status DATABASE OPCODE RESETFLAG |
** |
** Return a list of three elements which are the sqlite3_db_status() return |
** code, the current value, and the high-water mark value. |
*/ |
static int test_db_status( |
object clientData, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
int rc, iValue, mxValue; |
int i, op = 0; |
bool resetFlag = false; |
string zOpName; |
sqlite3 db = null; |
//int getDbPointer (Tcl_Interp*, const char*, sqlite3*); |
//static const struct { |
//string zName; |
//int op; |
//} |
_aOp[] aOp = { |
new _aOp( "LOOKASIDE_USED", SQLITE_DBSTATUS_LOOKASIDE_USED ), |
new _aOp( "CACHE_USED", SQLITE_DBSTATUS_CACHE_USED ), |
new _aOp( "SCHEMA_USED", SQLITE_DBSTATUS_SCHEMA_USED ), |
new _aOp( "STMT_USED", SQLITE_DBSTATUS_STMT_USED ), |
new _aOp( "LOOKASIDE_HIT", SQLITE_DBSTATUS_LOOKASIDE_HIT ), |
new _aOp( "LOOKASIDE_MISS_SIZE", SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE ), |
new _aOp( "LOOKASIDE_MISS_FULL", SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL ) |
}; |
Tcl_Obj pResult; |
if ( objc != 4 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "PARAMETER RESETFLAG" ); |
return TCL.TCL_ERROR; |
} |
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
return TCL.TCL_ERROR; |
zOpName = TCL.Tcl_GetString( objv[2] ); |
if ( zOpName.StartsWith( "SQLITE_" ) ) |
zOpName = zOpName.Remove( 0, 7 ); //zOpName += 7; |
if ( zOpName.StartsWith( "DBSTATUS_" ) ) |
zOpName = zOpName.Remove( 0, 9 ); //zOpName += 9; |
for ( i = 0; i < ArraySize( aOp ); i++ ) |
{ |
if ( aOp[i].zName == zOpName ) |
{ |
op = aOp[i].op; |
break; |
} |
} |
if ( i >= ArraySize( aOp ) ) |
{ |
if ( TCL.Tcl_GetIntFromObj( interp, objv[2], out op ) != 0 ) |
return TCL.TCL_ERROR; |
} |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[3], out resetFlag ) ) |
return TCL.TCL_ERROR; |
iValue = 0; |
mxValue = 0; |
rc = sqlite3_db_status( db, op, ref iValue, ref mxValue, resetFlag ? 1 : 0 ); |
pResult = TCL.Tcl_NewObj(); |
TCL.Tcl_ListObjAppendElement( null, pResult, TCL.Tcl_NewIntObj( rc ) ); |
TCL.Tcl_ListObjAppendElement( null, pResult, TCL.Tcl_NewIntObj( iValue ) ); |
TCL.Tcl_ListObjAppendElement( null, pResult, TCL.Tcl_NewIntObj( mxValue ) ); |
TCL.Tcl_SetObjResult( interp, pResult ); |
return TCL.TCL_OK; |
} |
|
/* |
** install_malloc_faultsim BOOLEAN |
*/ |
static int test_install_malloc_faultsim( |
object clientData, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
int rc; |
int isInstall; |
bool bisInstall = false; |
|
if ( objc != 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "BOOLEAN" ); |
return TCL.TCL_ERROR; |
} |
if ( TCL.Tcl_GetBooleanFromObj( interp, objv[1], out bisInstall ) ) |
{ |
return TCL.TCL_ERROR; |
} |
isInstall = bisInstall ? 1 : 0; |
rc = faultsimInstall( isInstall ); |
TCL.Tcl_SetResult( interp, sqlite3TestErrorName( rc ), TCL.TCL_VOLATILE ); |
return TCL.TCL_OK; |
} |
|
static int test_vfs_oom_test( |
object clientData, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
) |
{ |
//extern int sqlite3_memdebug_vfs_oom_test; |
if ( objc > 2 ) |
{ |
TCL.Tcl_WrongNumArgs( interp, 1, objv, "?INTEGER?" ); |
return TCL.TCL_ERROR; |
} |
else if ( objc == 2 ) |
{ |
int iNew = 0; |
if ( TCL.Tcl_GetIntFromObj( interp, objv[1], out iNew ) != 0 ) |
return TCL.TCL_ERROR; |
sqlite3_memdebug_vfs_oom_test = iNew; |
} |
TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_memdebug_vfs_oom_test ) ); |
return TCL.TCL_OK; |
} |
|
/* |
** Register commands with the TCL interpreter. |
*/ |
static public int Sqlitetest_malloc_Init( Tcl_Interp interp ) |
{ |
//static struct { |
// string zName; |
// Tcl_ObjCmdProc *xProc; |
// int clientData; |
//} aObjCmd[] = { |
_aObjCmd[] aObjCmd = new _aObjCmd[] { |
//{ "sqlite3_malloc", test_malloc ,0 }, |
//{ "sqlite3_realloc", test_realloc ,0 }, |
//{ "sqlite3_free", test_free ,0 }, |
//{ "memset", test_memset ,0 }, |
//{ "memget", test_memget ,0 }, |
//{ "sqlite3_memory_used", test_memory_used ,0 }, |
#if FALSE |
new _aObjCmd( "sqlite3_memory_used", test_memory_used ,0 ), |
new _aObjCmd( "sqlite3_memory_highwater", test_memory_highwater ,0), |
#endif |
//{ "sqlite3_memory_highwater", test_memory_highwater ,0 }, |
//{ "sqlite3_memdebug_backtrace", test_memdebug_backtrace ,0 }, |
new _aObjCmd( "sqlite3_memdebug_dump", test_memdebug_dump ,0 ), |
new _aObjCmd( "sqlite3_memdebug_fail", test_memdebug_fail ,0 ), |
//{ "sqlite3_memdebug_pending", test_memdebug_pending ,0 }, |
new _aObjCmd( "sqlite3_memdebug_settitle", test_memdebug_settitle ,0 ), |
new _aObjCmd( "sqlite3_memdebug_malloc_count", test_memdebug_malloc_count ,0), |
//{ "sqlite3_memdebug_log", test_memdebug_log ,0 }, |
new _aObjCmd( "sqlite3_config_scratch", test_config_scratch ,0 ), |
new _aObjCmd("sqlite3_config_pagecache", test_config_pagecache ,0 ), |
//{ "sqlite3_config_alt_pcache", test_alt_pcache ,0 }, |
new _aObjCmd( "sqlite3_status", test_status,0 ), |
new _aObjCmd( "sqlite3_db_status", test_db_status, 0 ), |
new _aObjCmd( "install_malloc_faultsim", test_install_malloc_faultsim ,0), |
//{ "sqlite3_config_heap", test_config_heap ,0 }, |
new _aObjCmd( "sqlite3_config_memstatus", test_config_memstatus ,0 ), |
new _aObjCmd( "sqlite3_config_lookaside", test_config_lookaside ,0 ), |
//{ "sqlite3_config_error", test_config_error ,0 }, |
new _aObjCmd( "sqlite3_config_uri",test_config_uri ,0 ), |
new _aObjCmd( "sqlite3_db_config_lookaside",test_db_config_lookaside ,0 ), |
//{ "sqlite3_dump_memsys3", test_dump_memsys3 ,3 }, |
//{ "sqlite3_dump_memsys5", test_dump_memsys3 ,5 }, |
//{ "sqlite3_install_memsys3", test_install_memsys3 ,0 }, |
//{ "sqlite3_memdebug_vfs_oom_test", test_vfs_oom_test ,0 }, |
}; |
int i; |
for ( i = 0; i < aObjCmd.Length; i++ ) |
{//<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ |
object c = (object)aObjCmd[i].clientData; |
TCL.Tcl_CreateObjCommand( interp, aObjCmd[i].zName, aObjCmd[i].xProc, c, null ); |
} |
return TCL.TCL_OK; |
} |
#endif |
} |
#endif |
} |
/trunk/testfixture/src/test_vfs_c.cs |
@@ -0,0 +1,1523 @@ |
using System; |
using System.Diagnostics; |
using System.Text; |
|
using u8 = System.Byte; |
using u32 = System.UInt32; |
|
namespace Community.CsharpSqlite |
{ |
#if TCLSH |
using tcl.lang; |
using sqlite_int64 = System.Int64; |
using sqlite3_int64 = System.Int64; |
using sqlite3_stmt = Community.CsharpSqlite.Sqlite3.Vdbe; |
using Tcl_Interp = tcl.lang.Interp; |
using Tcl_Obj = tcl.lang.TclObject; |
using ClientData = System.Object; |
|
public partial class Sqlite3 |
{ |
/* |
** 2010 May 05 |
** |
** 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. |
** |
****************************************************************************** |
** |
** This file contains the implementation of the Tcl [testvfs] command, |
** used to create SQLite VFS implementations with various properties and |
** instrumentation to support testing SQLite. |
** |
** testvfs VFSNAME ?OPTIONS? |
** |
** Available options are: |
** |
** -noshm BOOLEAN (True to omit shm methods. Default false) |
** -default BOOLEAN (True to make the vfs default. Default false) |
** -szosfile INTEGER (Value for sqlite3_vfs.szOsFile) |
** -mxpathname INTEGER (Value for sqlite3_vfs.mxPathname) |
** -iversion INTEGER (Value for sqlite3_vfs.iVersion) |
*/ |
#if SQLITE_TEST //* This file is used for testing only */ |
|
//#include "sqlite3.h" |
//#include "sqliteInt.h" |
|
//typedef struct Testvfs Testvfs; |
//typedef struct TestvfsShm TestvfsShm; |
//typedef struct TestvfsBuffer TestvfsBuffer; |
//typedef struct TestvfsFile TestvfsFile; |
//typedef struct TestvfsFd TestvfsFd; |
|
/* |
** An open file handle. |
*/ |
class TestvfsFile : sqlite3_file |
{ |
//public sqlite3_file base; /* Base class. Must be first */ |
public TestvfsFd pFd; /* File data */ |
}; |
//#define tvfsGetFd(pFile) (((TestvfsFile )pFile)->pFd) |
static TestvfsFd tvfsGetFd( sqlite3_file pFile ) |
{ |
return ((TestvfsFile)pFile).pFd; |
} |
|
class TestvfsFd { |
public sqlite3_vfs pVfs; /* The VFS */ |
public string zFilename; /* Filename as passed to xOpen() */ |
public sqlite3_file pReal; /* The real, underlying file descriptor */ |
public Tcl_Obj pShmId; /* Shared memory id for Tcl callbacks */ |
|
public TestvfsBuffer pShm; /* Shared memory buffer */ |
public u32 excllock; /* Mask of exclusive locks */ |
public u32 sharedlock; /* Mask of shared locks */ |
public TestvfsFd pNext; /* Next handle opened on the same file */ |
}; |
|
|
//#define FAULT_INJECT_NONE 0 |
//#define FAULT_INJECT_TRANSIENT 1 |
//#define FAULT_INJECT_PERSISTENT 2 |
const int FAULT_INJECT_NONE = 0; |
const int FAULT_INJECT_TRANSIENT = 1; |
const int FAULT_INJECT_PERSISTENT = 2; |
|
//typedef struct TestFaultInject TestFaultInject; |
class TestFaultInject { |
public int iCnt; /* Remaining calls before fault injection */ |
public int eFault; /* A FAULT_INJECT_* value */ |
public int nFail; /* Number of faults injected */ |
}; |
|
/* |
** An instance of this structure is allocated for each VFS created. The |
** sqlite3_vfs.pAppData field of the VFS structure registered with SQLite |
** is set to point to it. |
*/ |
class Testvfs { |
public string zName; /* Name of this VFS */ |
public sqlite3_vfs pParent; /* The VFS to use for file IO */ |
public sqlite3_vfs pVfs; /* The testvfs registered with SQLite */ |
public Tcl_Interp interp; /* Interpreter to run script in */ |
public Tcl_Obj pScript; /* Script to execute */ |
public TestvfsBuffer pBuffer; /* List of shared buffers */ |
public int isNoshm; |
|
public int mask; /* Mask controlling [script] and [ioerr] */ |
|
public TestFaultInject ioerr_err; |
public TestFaultInject full_err; |
public TestFaultInject cantopen_err; |
|
#if FALSE |
public int iIoerrCnt; |
public int ioerr; |
public int nIoerrFail; |
public int iFullCnt; |
public int fullerr; |
public int nFullFail; |
#endif |
|
public int iDevchar; |
public int iSectorsize; |
}; |
|
/* |
** The Testvfs.mask variable is set to a combination of the following. |
** If a bit is clear in Testvfs.mask, then calls made by SQLite to the |
** corresponding VFS method is ignored for purposes of: |
** |
** + Simulating IO errors, and |
** + Invoking the Tcl callback script. |
*/ |
//#define TESTVFS_SHMOPEN_MASK 0x00000001 |
//#define TESTVFS_SHMLOCK_MASK 0x00000010 |
//#define TESTVFS_SHMMAP_MASK 0x00000020 |
//#define TESTVFS_SHMBARRIER_MASK 0x00000040 |
//#define TESTVFS_SHMCLOSE_MASK 0x00000080 |
const int TESTVFS_SHMOPEN_MASK =0x00000001; |
const int TESTVFS_SHMLOCK_MASK =0x00000010; |
const int TESTVFS_SHMMAP_MASK =0x00000020; |
const int TESTVFS_SHMBARRIER_MASK =0x00000040; |
const int TESTVFS_SHMCLOSE_MASK =0x00000080; |
|
//#define TESTVFS_OPEN_MASK 0x00000100 |
//#define TESTVFS_SYNC_MASK 0x00000200 |
//#define TESTVFS_DELETE_MASK 0x00000400 |
//#define TESTVFS_CLOSE_MASK 0x00000800 |
//#define TESTVFS_WRITE_MASK 0x00001000 |
//#define TESTVFS_TRUNCATE_MASK 0x00002000 |
//#define TESTVFS_ACCESS_MASK 0x00004000 |
//#define TESTVFS_FULLPATHNAME_MASK 0x00008000 |
//#define TESTVFS_ALL_MASK 0x0001FFFF |
const int TESTVFS_OPEN_MASK =0x00000100; |
const int TESTVFS_SYNC_MASK =0x00000200; |
const int TESTVFS_DELETE_MASK =0x00000400; |
const int TESTVFS_CLOSE_MASK =0x00000800; |
const int TESTVFS_WRITE_MASK =0x00001000; |
const int TESTVFS_TRUNCATE_MASK =0x00002000; |
const int TESTVFS_ACCESS_MASK =0x00004000; |
const int TESTVFS_FULLPATHNAME_MASK =0x00008000; |
const int TESTVFS_ALL_MASK =0x0001FFFF; |
|
//#define TESTVFS_MAX_PAGES 1024 |
const int TESTVFS_MAX_PAGES =1024; |
|
/* |
** A shared-memory buffer. There is one of these objects for each shared |
** memory region opened by clients. If two clients open the same file, |
** there are two TestvfsFile structures but only one TestvfsBuffer structure. |
*/ |
class TestvfsBuffer { |
public string zFile; /* Associated file name */ |
public int pgsz; /* Page size */ |
public u8[] aPage = new u8[TESTVFS_MAX_PAGES]; /* Array of ckalloc'd pages */ |
public TestvfsFd pFile; /* List of open handles */ |
public TestvfsBuffer pNext; /* Next in linked list of all buffers */ |
}; |
|
|
//#define PARENTVFS(x) (((Testvfs )((x)->pAppData))->pParent) |
static sqlite3_vfs PARENTVFS( sqlite3_vfs x ) |
{ |
return ( (Testvfs)x.pAppData ).pParent; |
} |
|
//#define TESTVFS_MAX_ARGS 12 |
const int TESTVFS_MAX_ARGS =12; |
|
|
/* |
** Method declarations for TestvfsFile. |
*/ |
//static int tvfsClose(sqlite3_file); |
//static int tvfsRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); |
//static int tvfsWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); |
//static int tvfsTruncate(sqlite3_file*, sqlite3_int64 size); |
//static int tvfsSync(sqlite3_file*, int flags); |
//static int tvfsFileSize(sqlite3_file*, sqlite3_int64 *pSize); |
//static int tvfsLock(sqlite3_file*, int); |
//static int tvfsUnlock(sqlite3_file*, int); |
//static int tvfsCheckReservedLock(sqlite3_file*, int ); |
//static int tvfsFileControl(sqlite3_file*, int op, object *pArg); |
//static int tvfsSectorSize(sqlite3_file); |
//static int tvfsDeviceCharacteristics(sqlite3_file); |
|
///* |
//** Method declarations for tvfs_vfs. |
//*/ |
//static int tvfsOpen(sqlite3_vfs*, string , sqlite3_file*, int , int ); |
//static int tvfsDelete(sqlite3_vfs*, string zName, int syncDir); |
//static int tvfsAccess(sqlite3_vfs*, string zName, int flags, int ); |
//static int tvfsFullPathname(sqlite3_vfs*, string zName, int, string zOut); |
//#if !SQLITE_OMIT_LOAD_EXTENSION |
//static void tvfsDlOpen(sqlite3_vfs*, string zFilename); |
//static void tvfsDlError(sqlite3_vfs*, int nByte, string zErrMsg); |
//static void (*tvfsDlSym(sqlite3_vfs*,void*, string zSymbol))(void); |
//static void tvfsDlClose(sqlite3_vfs*, void); |
//#endif //* SQLITE_OMIT_LOAD_EXTENSION */ |
//static int tvfsRandomness(sqlite3_vfs*, int nByte, string zOut); |
//static int tvfsSleep(sqlite3_vfs*, int microseconds); |
//static int tvfsCurrentTime(sqlite3_vfs*, double); |
|
//static int tvfsShmOpen(sqlite3_file); |
//static int tvfsShmLock(sqlite3_file*, int , int, int); |
//static int tvfsShmMap(sqlite3_file*,int,int,int, object volatile *); |
//static void tvfsShmBarrier(sqlite3_file); |
//static int tvfsShmUnmap(sqlite3_file*, int); |
|
static sqlite3_io_methods tvfs_io_methods = new sqlite3_io_methods( |
2, /* iVersion */ |
tvfsClose, /* xClose */ |
tvfsRead, /* xRead */ |
tvfsWrite, /* xWrite */ |
tvfsTruncate, /* xTruncate */ |
tvfsSync, /* xSync */ |
tvfsFileSize, /* xFileSize */ |
tvfsLock, /* xLock */ |
tvfsUnlock, /* xUnlock */ |
tvfsCheckReservedLock, /* xCheckReservedLock */ |
tvfsFileControl, /* xFileControl */ |
tvfsSectorSize, /* xSectorSize */ |
tvfsDeviceCharacteristics, /* xDeviceCharacteristics */ |
tvfsShmMap, /* xShmMap */ |
tvfsShmLock, /* xShmLock */ |
tvfsShmBarrier, /* xShmBarrier */ |
tvfsShmUnmap /* xShmUnmap */ |
); |
|
class errcode { |
public int eCode; |
public string zCode; |
|
public errcode(int eCode, string zCode){ |
this.eCode=eCode;this.zCode=zCode; |
} |
} |
static int tvfsResultCode(Testvfs p, ref int pRc){ |
errcode[] aCode = new errcode[] { |
new errcode( SQLITE_OK, "SQLITE_OK" ), |
new errcode( SQLITE_ERROR, "SQLITE_ERROR" ), |
new errcode( SQLITE_IOERR, "SQLITE_IOERR" ), |
new errcode( SQLITE_LOCKED, "SQLITE_LOCKED" ), |
new errcode( SQLITE_BUSY, "SQLITE_BUSY" ) |
}; |
|
string z; |
int i; |
|
z = TCL.Tcl_GetStringResult(p.interp); |
for(i=0; i<ArraySize(aCode); i++){ |
if ( 0 == z.CompareTo( aCode[i].zCode ) ) |
{ |
pRc = aCode[i].eCode; |
return 1; |
} |
} |
|
return 0; |
} |
|
static int tvfsInjectFault(TestFaultInject p){ |
int ret = 0; |
if ( p.eFault != 0 ) |
{ |
p.iCnt--; |
if( p.iCnt==0 || (p.iCnt<0 && p.eFault==FAULT_INJECT_PERSISTENT ) ){ |
ret = 1; |
p.nFail++; |
} |
} |
return ret; |
} |
|
|
static int tvfsInjectIoerr(Testvfs p){ |
return tvfsInjectFault(p.ioerr_err); |
} |
|
static int tvfsInjectFullerr(Testvfs p){ |
return tvfsInjectFault(p.full_err); |
} |
static int tvfsInjectCantopenerr(Testvfs p){ |
return tvfsInjectFault(p.cantopen_err); |
} |
|
|
static void tvfsExecTcl( |
Testvfs p, |
string zMethod, |
Tcl_Obj arg1, |
Tcl_Obj arg2, |
Tcl_Obj arg3 |
){ |
int rc; /* Return code from Tcl_EvalObj() */ |
Tcl_Obj pEval; |
Debug.Assert( p.pScript!=null ); |
|
Debug.Assert( zMethod != null ); |
Debug.Assert( p != null ); |
Debug.Assert( arg2 == null || arg1 != null ); |
Debug.Assert( arg3 == null || arg2 != null ); |
|
pEval = TCL.Tcl_DuplicateObj(p.pScript); |
TCL.Tcl_IncrRefCount(p.pScript); |
TCL.Tcl_ListObjAppendElement( p.interp, pEval, TCL.Tcl_NewStringObj( zMethod, -1 ) ); |
if ( arg1!=null ) |
TCL.Tcl_ListObjAppendElement( p.interp, pEval, arg1 ); |
if ( arg2 !=null ) |
TCL.Tcl_ListObjAppendElement( p.interp, pEval, arg2 ); |
if ( arg3 != null ) |
TCL.Tcl_ListObjAppendElement( p.interp, pEval, arg3 ); |
|
rc = TCL.Tcl_EvalObjEx(p.interp, pEval, TCL.TCL_EVAL_GLOBAL); |
if ( rc != TCL.TCL_OK ) |
{ |
TCL.Tcl_BackgroundError( p.interp ); |
TCL.Tcl_ResetResult( p.interp ); |
} |
} |
|
|
/* |
** Close an tvfs-file. |
*/ |
static int tvfsClose(sqlite3_file pFile){ |
int rc=0; |
TestvfsFile pTestfile = (TestvfsFile )pFile; |
TestvfsFd pFd = pTestfile.pFd; |
Testvfs p = (Testvfs )pFd.pVfs.pAppData; |
|
Debugger.Break(); //TODO |
//if( p.pScript != null && (p.mask&TESTVFS_CLOSE_MASK)!=0 ){ |
// tvfsExecTcl(p, "xClose", |
// Tcl_NewStringObj(pFd.zFilename, -1), pFd.pShmId, 0 |
// ); |
//} |
|
//if( pFd.pShmId != null){ |
// Tcl_DecrRefCount(pFd.pShmId); |
// pFd.pShmId = null; |
//} |
//if ( pFile.pMethods != null ) |
//{ |
// ckfree((char )pFile.pMethods); |
//} |
//rc = sqlite3OsClose(pFd.pReal); |
//ckfree((char )pFd); |
//pTestfile.pFd = null; |
return rc; |
} |
|
/* |
** Read data from an tvfs-file. |
*/ |
static int tvfsRead( |
sqlite3_file pFile, |
byte[] zBuf, |
int iAmt, |
sqlite_int64 iOfst |
){ |
TestvfsFd p = tvfsGetFd(pFile); |
return sqlite3OsRead(p.pReal, zBuf, iAmt, iOfst); |
} |
|
/* |
** Write data to an tvfs-file. |
*/ |
static int tvfsWrite( |
sqlite3_file pFile, |
byte[] zBuf, |
int iAmt, |
sqlite_int64 iOfst |
){ |
int rc = SQLITE_OK; |
Debugger.Break();//TODO |
//TestvfsFd pFd = tvfsGetFd(pFile); |
//Testvfs p = (Testvfs )pFd.pVfs.pAppData; |
|
//if ( p.pScript != null && (p.mask & TESTVFS_WRITE_MASK) != 0 ) |
//{ |
// tvfsExecTcl(p, "xWrite", |
// TCL.Tcl_NewStringObj(pFd.zFilename, -1), pFd.pShmId, null |
// ); |
// tvfsResultCode(p, ref rc); |
//} |
|
//if( rc==SQLITE_OK && tvfsInjectFullerr(p)!=0 ){ |
// rc = SQLITE_FULL; |
//} |
//if ( rc == SQLITE_OK && (p.mask & TESTVFS_WRITE_MASK) != 0 && tvfsInjectIoerr( p ) != 0 ) |
//{ |
// rc = SQLITE_IOERR; |
//} |
|
//if( rc==SQLITE_OK ){ |
// rc = sqlite3OsWrite(pFd.pReal, zBuf, iAmt, iOfst); |
//} |
return rc; |
} |
|
/* |
** Truncate an tvfs-file. |
*/ |
static int tvfsTruncate(sqlite3_file pFile, sqlite_int64 size){ |
int rc = SQLITE_OK; |
TestvfsFd pFd = tvfsGetFd(pFile); |
Testvfs p = (Testvfs )pFd.pVfs.pAppData; |
|
if ( p.pScript != null && ( p.mask & TESTVFS_TRUNCATE_MASK ) != 0 ) |
{ |
tvfsExecTcl(p, "xTruncate", |
TCL.Tcl_NewStringObj(pFd.zFilename, -1), pFd.pShmId,null |
); |
tvfsResultCode(p, ref rc); |
} |
|
if( rc==SQLITE_OK ){ |
rc = sqlite3OsTruncate(pFd.pReal, size); |
} |
return rc; |
} |
|
/* |
** Sync an tvfs-file. |
*/ |
static int tvfsSync(sqlite3_file pFile, int flags){ |
int rc = SQLITE_OK; |
TestvfsFd pFd = tvfsGetFd(pFile); |
Testvfs p = (Testvfs )pFd.pVfs.pAppData; |
|
if ( p.pScript != null && ( p.mask & TESTVFS_SYNC_MASK ) != 0 ) |
{ |
string zFlags = ""; |
|
switch( flags ){ |
case SQLITE_SYNC_NORMAL: |
zFlags = "normal"; |
break; |
case SQLITE_SYNC_FULL: |
zFlags = "full"; |
break; |
case SQLITE_SYNC_NORMAL|SQLITE_SYNC_DATAONLY: |
zFlags = "normal|dataonly"; |
break; |
case SQLITE_SYNC_FULL|SQLITE_SYNC_DATAONLY: |
zFlags = "full|dataonly"; |
break; |
default: |
Debug.Assert(false); |
break; |
} |
|
tvfsExecTcl(p, "xSync", |
TCL.Tcl_NewStringObj(pFd.zFilename, -1), pFd.pShmId, |
TCL.Tcl_NewStringObj( zFlags, -1 ) |
); |
tvfsResultCode(p, ref rc); |
} |
|
if( rc==SQLITE_OK && tvfsInjectFullerr(p)!=0 ) rc = SQLITE_FULL; |
|
if( rc==SQLITE_OK ){ |
rc = sqlite3OsSync(pFd.pReal, flags); |
} |
|
return rc; |
} |
|
/* |
** Return the current file-size of an tvfs-file. |
*/ |
static int tvfsFileSize(sqlite3_file pFile, ref sqlite_int64 pSize){ |
TestvfsFd p = tvfsGetFd(pFile); |
return sqlite3OsFileSize(p.pReal, ref pSize); |
} |
|
/* |
** Lock an tvfs-file. |
*/ |
static int tvfsLock(sqlite3_file pFile, int eLock){ |
TestvfsFd p = tvfsGetFd(pFile); |
return sqlite3OsLock(p.pReal, eLock); |
} |
|
/* |
** Unlock an tvfs-file. |
*/ |
static int tvfsUnlock(sqlite3_file pFile, int eLock){ |
TestvfsFd p = tvfsGetFd(pFile); |
return sqlite3OsUnlock(p.pReal, eLock); |
} |
|
/* |
** Check if another file-handle holds a RESERVED lock on an tvfs-file. |
*/ |
static int tvfsCheckReservedLock( sqlite3_file pFile, ref int pResOut ) |
{ |
TestvfsFd p = tvfsGetFd(pFile); |
return sqlite3OsCheckReservedLock( p.pReal, ref pResOut ); |
} |
|
/* |
** File control method. For custom operations on an tvfs-file. |
*/ |
static int tvfsFileControl( sqlite3_file pFile, int op, ref sqlite3_int64 pArg ) |
{ |
TestvfsFd p = tvfsGetFd(pFile); |
return sqlite3OsFileControl( p.pReal, (u32)op, ref pArg ); |
} |
|
/* |
** Return the sector-size in bytes for an tvfs-file. |
*/ |
static int tvfsSectorSize(sqlite3_file pFile){ |
TestvfsFd pFd = tvfsGetFd(pFile); |
Testvfs p = (Testvfs )pFd.pVfs.pAppData; |
if( p.iSectorsize>=0 ){ |
return p.iSectorsize; |
} |
return sqlite3OsSectorSize(pFd.pReal); |
} |
|
/* |
** Return the device characteristic flags supported by an tvfs-file. |
*/ |
static int tvfsDeviceCharacteristics(sqlite3_file pFile){ |
TestvfsFd pFd = tvfsGetFd(pFile); |
Testvfs p = (Testvfs )pFd.pVfs.pAppData; |
if( p.iDevchar>=0 ){ |
return p.iDevchar; |
} |
return sqlite3OsDeviceCharacteristics(pFd.pReal); |
} |
|
/* |
** Open an tvfs file handle. |
*/ |
static int tvfsOpen( |
sqlite3_vfs pVfs, |
string zName, |
sqlite3_file pFile, |
int flags, |
ref int pOutFlags |
){ |
int rc=0; |
Debugger.Break();//TODO |
//TestvfsFile pTestfile = (TestvfsFile)pFile; |
//TestvfsFd pFd; |
//Tcl_Obj pId = null; |
//Testvfs p = (Testvfs )pVfs.pAppData; |
|
//pFd = (TestvfsFd )ckalloc(sizeof(TestvfsFd) + PARENTVFS(pVfs).szOsFile); |
//pFd = new TestvfsFd();// memset( pFd, 0, sizeof( TestvfsFd ) + PARENTVFS( pVfs ).szOsFile ); |
//pFd.pShm = null; |
//pFd.pShmId = null; |
//pFd.zFilename = zName; |
//pFd.pVfs = pVfs; |
//pFd.pReal = (sqlite3_file )pFd[1]; |
//pTestfile = new TestvfsFile();// memset( pTestfile, 0, sizeof( TestvfsFile ) ); |
//pTestfile.pFd = pFd; |
|
///* Evaluate the Tcl script: |
//** |
//** SCRIPT xOpen FILENAME KEY-VALUE-ARGS |
//** |
//** If the script returns an SQLite error code other than SQLITE_OK, an |
//** error is returned to the caller. If it returns SQLITE_OK, the new |
//** connection is named "anon". Otherwise, the value returned by the |
//** script is used as the connection name. |
//*/ |
//TCL.Tcl_ResetResult(p.interp); |
//if ( p.pScript != null && ( p.mask & TESTVFS_OPEN_MASK ) != 0 ) |
//{ |
// Tcl_Obj pArg = TCL.Tcl_NewObj(); |
// TCL.Tcl_IncrRefCount( pArg ); |
// if( (flags&SQLITE_OPEN_MAIN_DB )!=0){ |
// string z = zName[strlen(zName)+1]; |
// while( *z ){ |
// TCL.Tcl_ListObjAppendElement( 0, pArg, TCL.Tcl_NewStringObj( z, -1 ) ); |
// z += strlen(z) + 1; |
// TCL.Tcl_ListObjAppendElement( 0, pArg, TCL.Tcl_NewStringObj( z, -1 ) ); |
// z += strlen(z) + 1; |
// } |
// } |
// tvfsExecTcl(p, "xOpen", TCL.Tcl_NewStringObj(pFd.zFilename, -1), pArg, null); |
// TCL.Tcl_DecrRefCount( pArg ); |
// if( tvfsResultCode(p, ref rc)!=0 ){ |
// if( rc!=SQLITE_OK ) return rc; |
// }else{ |
// pId = TCL.Tcl_GetObjResult(p.interp); |
// } |
//} |
|
//if( (p.mask&TESTVFS_OPEN_MASK)!=0 && tvfsInjectIoerr(p) !=0) return SQLITE_IOERR; |
//if( tvfsInjectCantopenerr(p)!=0 ) return SQLITE_CANTOPEN; |
//if( tvfsInjectFullerr(p)!=0 ) return SQLITE_FULL; |
|
//if( null==pId ){ |
// pId = TCL.Tcl_NewStringObj("anon", -1); |
//} |
//TCL.Tcl_IncrRefCount( pId ); |
//pFd.pShmId = pId; |
//TCL.Tcl_ResetResult( p.interp ); |
|
//rc = sqlite3OsOpen(PARENTVFS(pVfs), zName, pFd.pReal, flags, pOutFlags); |
//if ( pFd.pReal.pMethods != null ) |
//{ |
// sqlite3_io_methods pMethods; |
// int nByte; |
|
//if( pVfs.iVersion>1 ){ |
// nByte = sizeof(sqlite3_io_methods); |
//}else{ |
// nByte = offsetof(sqlite3_io_methods, xShmMap); |
//} |
|
//pMethods = (sqlite3_io_methods)ckalloc( nByte ); |
//memcpy(pMethods, &tvfs_io_methods, nByte); |
//pMethods.iVersion = pVfs.iVersion; |
//if( pVfs.iVersion>1 && ((Testvfs )pVfs.pAppData).isNoshm ){ |
// pMethods.xShmUnmap = 0; |
// pMethods.xShmLock = 0; |
// pMethods.xShmBarrier = 0; |
// pMethods.xShmMap = 0; |
//} |
// pFile.pMethods = pMethods; |
//} |
|
return rc; |
} |
|
/* |
** Delete the file located at zPath. If the dirSync argument is true, |
** ensure the file-system modifications are synced to disk before |
** returning. |
*/ |
static int tvfsDelete(sqlite3_vfs pVfs, string zPath, int dirSync){ |
int rc = SQLITE_OK; |
Testvfs p = (Testvfs )pVfs.pAppData; |
|
if( p.pScript !=null && (p.mask&TESTVFS_DELETE_MASK)!=0 ){ |
tvfsExecTcl(p, "xDelete", |
TCL.Tcl_NewStringObj( zPath, -1 ), TCL.Tcl_NewIntObj( dirSync ), null |
); |
tvfsResultCode(p, ref rc); |
} |
if( rc==SQLITE_OK ){ |
rc = sqlite3OsDelete(PARENTVFS(pVfs), zPath, dirSync); |
} |
return rc; |
} |
|
/* |
** Test for access permissions. Return true if the requested permission |
** is available, or false otherwise. |
*/ |
static int tvfsAccess( |
sqlite3_vfs pVfs, |
string zPath, |
int flags, |
ref int pResOut |
){ |
Testvfs p = (Testvfs )pVfs.pAppData; |
if ( p.pScript != null && ( p.mask & TESTVFS_ACCESS_MASK ) != 0 ) |
{ |
int rc=0; |
string zArg = ""; |
if( flags==SQLITE_ACCESS_EXISTS ) zArg = "SQLITE_ACCESS_EXISTS"; |
if( flags==SQLITE_ACCESS_READWRITE ) zArg = "SQLITE_ACCESS_READWRITE"; |
if( flags==SQLITE_ACCESS_READ ) zArg = "SQLITE_ACCESS_READ"; |
tvfsExecTcl(p, "xAccess", |
TCL.Tcl_NewStringObj( zPath, -1 ), TCL.Tcl_NewStringObj( zArg, -1 ), null |
); |
if( tvfsResultCode(p, ref rc) !=0){ |
if( rc!=SQLITE_OK ) return rc; |
}else{ |
Tcl_Interp interp = p.interp; |
bool bTemp = false; |
if ( !TCL.Tcl_GetBooleanFromObj( null, TCL.Tcl_GetObjResult( interp ), out bTemp ) ) |
{ |
pResOut = bTemp ? 1 : 0; |
return SQLITE_OK; |
} |
} |
} |
return sqlite3OsAccess( PARENTVFS( pVfs ), zPath, flags, ref pResOut ); |
} |
|
/* |
** Populate buffer zOut with the full canonical pathname corresponding |
** to the pathname in zPath. zOut is guaranteed to point to a buffer |
** of at least (DEVSYM_MAX_PATHNAME+1) bytes. |
*/ |
static int tvfsFullPathname( |
sqlite3_vfs pVfs, |
string zPath, |
int nOut, |
StringBuilder zOut |
){ |
Testvfs p = (Testvfs )pVfs.pAppData; |
if ( p.pScript != null && ( p.mask & TESTVFS_FULLPATHNAME_MASK ) != 0 ) |
{ |
int rc=0; |
tvfsExecTcl(p, "xFullPathname", TCL.Tcl_NewStringObj(zPath, -1),null,null); |
if( tvfsResultCode(p, ref rc) !=0){ |
if( rc!=SQLITE_OK ) return rc; |
} |
} |
return sqlite3OsFullPathname(PARENTVFS(pVfs), zPath, nOut, zOut); |
} |
|
#if !SQLITE_OMIT_LOAD_EXTENSION |
/* |
** Open the dynamic library located at zPath and return a handle. |
*/ |
static IntPtr tvfsDlOpen(sqlite3_vfs pVfs, string zPath){ |
return sqlite3OsDlOpen(PARENTVFS(pVfs), zPath); |
} |
|
/* |
** Populate the buffer zErrMsg (size nByte bytes) with a human readable |
** utf-8 string describing the most recent error encountered associated |
** with dynamic libraries. |
*/ |
static void tvfsDlError(sqlite3_vfs pVfs, int nByte, string zErrMsg){ |
sqlite3OsDlError(PARENTVFS(pVfs), nByte, zErrMsg); |
} |
|
/* |
** Return a pointer to the symbol zSymbol in the dynamic library pHandle. |
*/ |
static void tvfsDlSym(sqlite3_vfs pVfs, IntPtr p, string zSym){ |
sqlite3OsDlSym(PARENTVFS(pVfs), p, ref zSym); |
} |
|
/* |
** Close the dynamic library handle pHandle. |
*/ |
static void tvfsDlClose( sqlite3_vfs pVfs, IntPtr pHandle ) |
{ |
sqlite3OsDlClose(PARENTVFS(pVfs), pHandle); |
} |
#endif //* SQLITE_OMIT_LOAD_EXTENSION */ |
|
/* |
** Populate the buffer pointed to by zBufOut with nByte bytes of |
** random data. |
*/ |
static int tvfsRandomness(sqlite3_vfs pVfs, int nByte, byte[] zBufOut){ |
return sqlite3OsRandomness(PARENTVFS(pVfs), nByte, zBufOut); |
} |
|
/* |
** Sleep for nMicro microseconds. Return the number of microseconds |
** actually slept. |
*/ |
static int tvfsSleep(sqlite3_vfs pVfs, int nMicro){ |
return sqlite3OsSleep(PARENTVFS(pVfs), nMicro); |
} |
|
/* |
** Return the current time as a Julian Day number in pTimeOut. |
*/ |
static int tvfsCurrentTime(sqlite3_vfs pVfs, double pTimeOut){ |
return PARENTVFS(pVfs).xCurrentTime(PARENTVFS(pVfs), ref pTimeOut); |
} |
|
static int tvfsShmOpen(sqlite3_file pFile){ |
Testvfs p; |
int rc = SQLITE_OK; /* Return code */ |
Debugger.Break();//TODO |
//TestvfsBuffer pBuffer; /* Buffer to open connection to */ |
//TestvfsFd pFd; /* The testvfs file structure */ |
|
//pFd = tvfsGetFd(pFile); |
//p = (Testvfs )pFd.pVfs.pAppData; |
//Debug.Assert( pFd.pShmId && pFd.pShm==null && pFd.pNext==null ); |
|
///* Evaluate the Tcl script: |
//** |
//** SCRIPT xShmOpen FILENAME |
//*/ |
//TCL.Tcl_ResetResult(p.interp); |
//if ( p.pScript != null && ( p.mask & TESTVFS_SHMOPEN_MASK ) != 0 ) |
//{ |
// tvfsExecTcl(p, "xShmOpen", TCL.Tcl_NewStringObj(pFd.zFilename, -1), 0, 0); |
// if( tvfsResultCode(p, ref rc)!=0 ){ |
// if( rc!=SQLITE_OK ) return rc; |
// } |
//} |
|
//Debug.Assert( rc==SQLITE_OK ); |
//if ( ( p.mask & TESTVFS_SHMOPEN_MASK ) != 0 && tvfsInjectIoerr( p ) ) |
//{ |
// return SQLITE_IOERR; |
//} |
|
///* Search for a TestvfsBuffer. Create a new one if required. */ |
//for(pBuffer=p.pBuffer; pBuffer!=null; pBuffer=pBuffer.pNext){ |
// if( 0==strcmp(pFd.zFilename, pBuffer.zFile) ) break; |
//} |
//if( null==pBuffer ){ |
// int nByte = sizeof(TestvfsBuffer) + strlen(pFd.zFilename) + 1; |
// pBuffer = (TestvfsBuffer )ckalloc(nByte); |
// memset(pBuffer, 0, nByte); |
// pBuffer.zFile = (char )&pBuffer[1]; |
// strcpy(pBuffer.zFile, pFd.zFilename); |
// pBuffer.pNext = p.pBuffer; |
// p.pBuffer = pBuffer; |
//} |
|
///* Connect the TestvfsBuffer to the new TestvfsShm handle and return. */ |
//pFd.pNext = pBuffer.pFile; |
//pBuffer.pFile = pFd; |
//pFd.pShm = pBuffer; |
return SQLITE_OK; |
} |
|
static void tvfsAllocPage(TestvfsBuffer p, int iPage, int pgsz){ |
Debugger.Break();//TODO |
//Debug.Assert( iPage < TESTVFS_MAX_PAGES ); |
//if( p.aPage[iPage]==0 ){ |
// p.aPage[iPage] = (u8 )ckalloc(pgsz); |
// memset(p.aPage[iPage], 0, pgsz); |
// p.pgsz = pgsz; |
//} |
} |
|
static int tvfsShmMap( |
sqlite3_file pFile, /* Handle open on database file */ |
int iPage, /* Page to retrieve */ |
int pgsz, /* Size of pages */ |
int isWrite, /* True to extend file if necessary */ |
out object pp /* OUT: Mapped memory */ |
){ |
int rc = SQLITE_OK; |
Debugger.Break();//TODO |
pp = null; |
//TestvfsFd pFd = tvfsGetFd( pFile ); |
//Testvfs p = (Testvfs )(pFd.pVfs.pAppData); |
|
//if( 0==pFd.pShm ){ |
// rc = tvfsShmOpen(pFile); |
// if( rc!=SQLITE_OK ){ |
// return rc; |
// } |
//} |
|
//if( p.pScript != null && (p.mask&TESTVFS_SHMMAP_MASK )!=0){ |
// Tcl_Obj pArg = TCL.Tcl_NewObj(); |
// Tcl_IncrRefCount(pArg); |
// Tcl_ListObjAppendElement(p.interp, pArg, TCL.Tcl_NewIntObj(iPage)); |
// Tcl_ListObjAppendElement(p.interp, pArg, TCL.Tcl_NewIntObj(pgsz)); |
// Tcl_ListObjAppendElement(p.interp, pArg, TCL.Tcl_NewIntObj(isWrite)); |
// tvfsExecTcl(p, "xShmMap", |
// Tcl_NewStringObj(pFd.pShm.zFile, -1), pFd.pShmId, pArg |
// ); |
// tvfsResultCode(p, ref rc); |
// Tcl_DecrRefCount(pArg); |
//} |
//if( rc==SQLITE_OK && (p.mask&TESTVFS_SHMMAP_MASK )!=0&& tvfsInjectIoerr(p) ){ |
// rc = SQLITE_IOERR; |
//} |
|
//if( rc==SQLITE_OK && isWrite && !pFd.pShm.aPage[iPage] ){ |
// tvfsAllocPage(pFd.pShm, iPage, pgsz); |
//} |
//pp = pFd.pShm.aPage[iPage]; |
|
return rc; |
} |
|
|
static int tvfsShmLock( |
sqlite3_file pFile, |
int ofst, |
int n, |
int flags |
){ |
int rc = SQLITE_OK; |
Debugger.Break();//TODO |
//TestvfsFd pFd = tvfsGetFd(pFile); |
//Testvfs p = (Testvfs )(pFd.pVfs.pAppData); |
//int nLock; |
//StringBuilder zLock =new StringBuilder(80);//char zLock[80]; |
|
//if( p.pScript !=null && (p.mask&TESTVFS_SHMLOCK_MASK)!=0 ){ |
// sqlite3_snprintf(sizeof(zLock), zLock, "%d %d", ofst, n); |
// nLock = strlen(zLock); |
// if( flags & SQLITE_SHM_LOCK ){ |
// strcpy(&zLock[nLock], " lock"); |
// }else{ |
// strcpy(&zLock[nLock], " unlock"); |
// } |
// nLock += strlen(&zLock[nLock]); |
// if( flags & SQLITE_SHM_SHARED ){ |
// strcpy(&zLock[nLock], " shared"); |
// }else{ |
// strcpy(&zLock[nLock], " exclusive"); |
// } |
// tvfsExecTcl(p, "xShmLock", |
// Tcl_NewStringObj(pFd.pShm.zFile, -1), pFd.pShmId, |
// Tcl_NewStringObj(zLock, -1) |
// ); |
// tvfsResultCode(p, ref rc); |
//} |
|
//if( rc==SQLITE_OK && (p.mask&TESTVFS_SHMLOCK_MASK )!=0&& tvfsInjectIoerr(p) ){ |
// rc = SQLITE_IOERR; |
//} |
|
//if( rc==SQLITE_OK ){ |
// int isLock = (flags & SQLITE_SHM_LOCK); |
// int isExcl = (flags & SQLITE_SHM_EXCLUSIVE); |
// u32 mask = (((1<<n)-1) << ofst); |
// if( isLock ){ |
// TestvfsFd p2; |
// for(p2=pFd.pShm.pFile; p2; p2=p2.pNext){ |
// if( p2==pFd ) continue; |
// if( (p2.excllock&mask) || (isExcl && p2.sharedlock&mask) ){ |
// rc = SQLITE_BUSY; |
// break; |
// } |
// } |
// if( rc==SQLITE_OK ){ |
// if( isExcl ) pFd.excllock |= mask; |
// if( null==isExcl ) pFd.sharedlock |= mask; |
// } |
// }else{ |
// if( isExcl ) pFd.excllock &= (~mask); |
// if( null==isExcl ) pFd.sharedlock &= (~mask); |
// } |
//} |
|
return rc; |
} |
|
static void tvfsShmBarrier(sqlite3_file pFile){ |
Debugger.Break();//TODO |
//TestvfsFd pFd = tvfsGetFd(pFile); |
//Testvfs p = (Testvfs )(pFd.pVfs.pAppData); |
|
//if ( p.pScript != null && ( p.mask & TESTVFS_SHMBARRIER_MASK ) != 0 ) |
//{ |
// tvfsExecTcl(p, "xShmBarrier", |
// Tcl_NewStringObj(pFd.pShm.zFile, -1), pFd.pShmId, 0 |
// ); |
//} |
} |
|
static int tvfsShmUnmap( |
sqlite3_file pFile, |
int deleteFlag |
){ |
int rc = SQLITE_OK; |
Debugger.Break();//TODO |
//TestvfsFd pFd = tvfsGetFd( pFile ); |
//Testvfs p = (Testvfs )(pFd.pVfs.pAppData); |
//TestvfsBuffer pBuffer = pFd.pShm; |
//TestvfsFd ppFd; |
|
//if( null==pBuffer ) return SQLITE_OK; |
//Debug.Assert( pFd.pShmId && pFd.pShm ); |
|
//if ( p.pScript != null && ( p.mask & TESTVFS_SHMCLOSE_MASK ) != 0 ) |
//{ |
// tvfsExecTcl(p, "xShmUnmap", |
// Tcl_NewStringObj(pFd.pShm.zFile, -1), pFd.pShmId, 0 |
// ); |
// tvfsResultCode(p, ref rc); |
//} |
|
//for(ppFd=pBuffer.pFile; ppFd!=pFd; ppFd=&((ppFd).pNext)); |
//Debug.Assert( (ppFd)==pFd ); |
//ppFd = pFd.pNext; |
//pFd.pNext = 0; |
|
//if( pBuffer.pFile==null ){ |
// int i; |
// TestvfsBuffer pp; |
// for(pp=p.pBuffer; pp!=pBuffer; pp=((pp).pNext)); |
// pp = (pp).pNext; |
// Debugger.Break();//TODO |
// //for(i=0; pBuffer.aPage[i]!= null; i++){ |
// // ckfree((char )pBuffer.aPage[i]); |
// //} |
// //ckfree((char )pBuffer); |
//} |
//pFd.pShm = null; |
|
return rc; |
} |
|
enum DB_enum_CMD { |
CMD_SHM, CMD_DELETE, CMD_FILTER, CMD_IOERR, CMD_SCRIPT, |
CMD_DEVCHAR, CMD_SECTORSIZE, CMD_FULLERR, CMD_CANTOPENERR |
}; |
class TestvfsSubcmd { |
public string zName; |
public DB_enum_CMD eCmd; |
public TestvfsSubcmd (string zName, DB_enum_CMD eCmd){this.zName=zName;this.eCmd=eCmd;} |
} |
class VfsMethod { |
public string zName; |
public int mask; |
public VfsMethod (string zName, int mask){this.zName=zName;this.mask=mask;} |
} |
|
class DeviceFlag { |
public string zName; |
public int iValue; |
public DeviceFlag (string zName, int iValue){this.zName=zName;this.iValue=iValue;} |
} |
|
class _aFlag |
{ |
public string zName; |
public int iValue; |
public _aFlag( string zName, int iValue ) |
{ |
this.zName = zName; |
this.iValue = iValue; |
} |
} |
|
|
static int testvfs_obj_cmd( |
ClientData cd, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
){ |
Debugger.Break();//TODO |
// Testvfs p = (Testvfs)cd; |
|
// TestvfsSubcmd[] aSubcmd = new TestvfsSubcmd[] { |
// new TestvfsSubcmd( "shm", DB_enum_CMD.CMD_SHM ), |
// new TestvfsSubcmd( "delete", DB_enum_CMD.CMD_DELETE ), |
// new TestvfsSubcmd( "filter", DB_enum_CMD.CMD_FILTER ), |
// new TestvfsSubcmd( "ioerr", DB_enum_CMD.CMD_IOERR ), |
// new TestvfsSubcmd( "fullerr", DB_enum_CMD.CMD_FULLERR ), |
// new TestvfsSubcmd( "cantopenerr", DB_enum_CMD.CMD_CANTOPENERR ), |
// new TestvfsSubcmd( "script", DB_enum_CMD.CMD_SCRIPT ), |
// new TestvfsSubcmd( "devchar", DB_enum_CMD.CMD_DEVCHAR ), |
// new TestvfsSubcmd( "sectorsize", DB_enum_CMD.CMD_SECTORSIZE ), |
// new TestvfsSubcmd( 0, 0 ) |
// }; |
// int i=0; |
|
// if( objc<2 ){ |
// TCL.Tcl_WrongNumArgs( interp, 1, objv, "SUBCOMMAND ..." ); |
// return TCL.TCL_ERROR; |
// } |
// if ( TCL.Tcl_GetIndexFromObjStruct( |
// interp, objv[1], aSubcmd, aSubcmd.Length, "subcommand", 0, ref i) |
// ){ |
// return TCL.TCL_ERROR; |
// } |
// TCL.Tcl_ResetResult( interp ); |
|
// switch( aSubcmd[i].eCmd ){ |
// case DB_enum_CMD.CMD_SHM: { |
// Tcl_Obj pObj; |
// int i; |
// TestvfsBuffer pBuffer; |
// string zName; |
// if( objc!=3 && objc!=4 ){ |
// TCL.Tcl_WrongNumArgs( interp, 2, objv, "FILE ?VALUE?" ); |
// return TCL.TCL_ERROR; |
// } |
// zName = ckalloc(p.pParent.mxPathname); |
// p.pParent.xFullPathname( |
// p.pParent, TCL.Tcl_GetString(objv[2]), |
// p.pParent.mxPathname, zName |
// ); |
// for(pBuffer=p.pBuffer; pBuffer; pBuffer=pBuffer.pNext){ |
// if( 0==strcmp(pBuffer.zFile, zName) ) break; |
// } |
// ckfree(zName); |
// if( null==pBuffer ){ |
// TCL.Tcl_AppendResult( interp, "no such file: ", TCL.Tcl_GetString( objv[2] ), 0 ); |
// return TCL.TCL_ERROR; |
// } |
// if( objc==4 ){ |
// int n; |
// u8 *a = TCL.Tcl_GetByteArrayFromObj(objv[3], &n); |
// int pgsz = pBuffer.pgsz; |
// if( pgsz==0 ) pgsz = 65536; |
// for(i=0; ipgsz<n; i++){ |
// int nByte = pgsz; |
// tvfsAllocPage(pBuffer, i, pgsz); |
// if( n-ipgsz<pgsz ){ |
// nByte = n; |
// } |
// memcpy(pBuffer.aPage[i], &a[ipgsz], nByte); |
// } |
// } |
|
// pObj = TCL.Tcl_NewObj(); |
// for(i=0; pBuffer.aPage[i]!=null; i++){ |
// int pgsz = pBuffer.pgsz; |
// if( pgsz==0 ) pgsz = 65536; |
// TCL.Tcl_AppendObjToObj(pObj, TCL.Tcl_NewByteArrayObj(pBuffer.aPage[i], pgsz)); |
// } |
// TCL.Tcl_SetObjResult( interp, pObj ); |
// break; |
// } |
// case DB_enum_CMD.CMD_FILTER: { |
//VfsMethod[] vfsmethod = new VfsMethod[] { |
// new VfsMethod( "xShmOpen", TESTVFS_SHMOPEN_MASK ), |
// new VfsMethod( "xShmLock", TESTVFS_SHMLOCK_MASK ), |
// new VfsMethod( "xShmBarrier", TESTVFS_SHMBARRIER_MASK ), |
// new VfsMethod( "xShmUnmap", TESTVFS_SHMCLOSE_MASK ), |
// new VfsMethod( "xShmMap", TESTVFS_SHMMAP_MASK ), |
// new VfsMethod( "xSync", TESTVFS_SYNC_MASK ), |
// new VfsMethod( "xDelete", TESTVFS_DELETE_MASK ), |
// new VfsMethod( "xWrite", TESTVFS_WRITE_MASK ), |
// new VfsMethod( "xTruncate", TESTVFS_TRUNCATE_MASK ), |
// new VfsMethod( "xOpen", TESTVFS_OPEN_MASK ), |
// new VfsMethod( "xClose", TESTVFS_CLOSE_MASK ), |
// new VfsMethod( "xAccess", TESTVFS_ACCESS_MASK ), |
// new VfsMethod( "xFullPathname", TESTVFS_FULLPATHNAME_MASK ), |
//}; |
// Tcl_Obj[] apElem = null; |
// int nElem = 0; |
// int i; |
// int mask = 0; |
// if( objc!=3 ){ |
// TCL.Tcl_WrongNumArgs( interp, 2, objv, "LIST" ); |
// return TCL.TCL_ERROR; |
// } |
// if ( TCL.Tcl_ListObjGetElements( interp, objv[2], ref nElem, ref apElem ) ) |
// { |
// return TCL.TCL_ERROR; |
// } |
// TCL.Tcl_ResetResult( interp ); |
// for(i=0; i<nElem; i++){ |
// int iMethod; |
// string zElem = TCL.Tcl_GetString(apElem[i]); |
// for(iMethod=0; iMethod<ArraySize(vfsmethod); iMethod++){ |
// if( strcmp(zElem, vfsmethod[iMethod].zName)==0 ){ |
// mask |= vfsmethod[iMethod].mask; |
// break; |
// } |
// } |
// if( iMethod==ArraySize(vfsmethod) ){ |
// TCL.Tcl_AppendResult( interp, "unknown method: ", zElem, 0 ); |
// return TCL.TCL_ERROR; |
// } |
// } |
// p.mask = mask; |
// break; |
// } |
|
// case DB_enum_CMD.CMD_SCRIPT: { |
// if( objc==3 ){ |
// int nByte; |
// if( p.pScript !=null){ |
// TCL.Tcl_DecrRefCount( p.pScript ); |
// p.pScript = 0; |
// } |
// TCL.Tcl_GetStringFromObj( objv[2], &nByte ); |
// if( nByte>0 ){ |
// p.pScript = TCL.Tcl_DuplicateObj(objv[2]); |
// TCL.Tcl_IncrRefCount( p.pScript ); |
// } |
// }else if( objc!=2 ){ |
// TCL.Tcl_WrongNumArgs( interp, 2, objv, "?SCRIPT?" ); |
// return TCL.TCL_ERROR; |
// } |
|
// TCL.Tcl_ResetResult( interp ); |
// if( p.pScript !=null) if( p.pScript )TCL.Tcl_SetObjResult(interp, p.pScript); |
|
// break; |
// } |
|
// /* |
// ** TESTVFS ioerr ?IFAIL PERSIST? |
// ** |
// ** Where IFAIL is an integer and PERSIST is boolean. |
// */ |
// case DB_enum_CMD.CMD_CANTOPENERR: |
// case DB_enum_CMD.CMD_IOERR: |
// case DB_enum_CMD.CMD_FULLERR: { |
// TestFaultInject pTest; |
// int iRet; |
|
// switch( aSubcmd[i].eCmd ){ |
// case DB_enum_CMD.CMD_IOERR: pTest = p.ioerr_err; break; |
// case DB_enum_CMD.CMD_FULLERR: pTest = p.full_err; break; |
// case DB_enum_CMD.CMD_CANTOPENERR: pTest = p.cantopen_err; break; |
// default: Debug.Assert(false); |
// } |
// iRet = pTest.nFail; |
// pTest.nFail = 0; |
// pTest.eFault = 0; |
// pTest.iCnt = 0; |
|
// if( objc==4 ){ |
// int iCnt, iPersist; |
// if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], &iCnt ) |
// || TCL.TCL_OK != TCL.Tcl_GetBooleanFromObj( interp, objv[3], &iPersist ) |
// ){ |
// return TCL.TCL_ERROR; |
// } |
// pTest.eFault = iPersist != 0 ? FAULT_INJECT_PERSISTENT : FAULT_INJECT_TRANSIENT; |
// pTest.iCnt = iCnt; |
// }else if( objc!=2 ){ |
// TCL.Tcl_WrongNumArgs( interp, 2, objv, "?CNT PERSIST?" ); |
// return TCL.TCL_ERROR; |
// } |
// TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( iRet ) ); |
// break; |
// } |
|
// case DB_enum_CMD.CMD_DELETE: { |
// TCL.Tcl_DeleteCommand( interp, TCL.Tcl_GetString( objv[0] ) ); |
// break; |
// } |
|
// case DB_enum_CMD.CMD_DEVCHAR: { |
//_aFlag[] aFlag = new _aFlag[] { |
// new _aFlag( "default", -1 ), |
// new _aFlag( "atomic", SQLITE_IOCAP_ATOMIC ), |
// new _aFlag( "atomic512", SQLITE_IOCAP_ATOMIC512 ), |
// new _aFlag( "atomic1k", SQLITE_IOCAP_ATOMIC1K ), |
// new _aFlag( "atomic2k", SQLITE_IOCAP_ATOMIC2K ), |
// new _aFlag( "atomic4k", SQLITE_IOCAP_ATOMIC4K ), |
// new _aFlag( "atomic8k", SQLITE_IOCAP_ATOMIC8K ), |
// new _aFlag( "atomic16k", SQLITE_IOCAP_ATOMIC16K ), |
// new _aFlag( "atomic32k", SQLITE_IOCAP_ATOMIC32K ), |
// new _aFlag( "atomic64k", SQLITE_IOCAP_ATOMIC64K ), |
// new _aFlag( "sequential", SQLITE_IOCAP_SEQUENTIAL ), |
// new _aFlag( "safe_append", SQLITE_IOCAP_SAFE_APPEND ), |
// new _aFlag( "undeletable_when_open", SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN ), |
// new _aFlag( 0, 0 ) |
// }; |
// Tcl_Obj pRet; |
// int iFlag; |
|
// if( objc>3 ){ |
// Tcl_WrongNumArgs(interp, 2, objv, "?ATTR-LIST?"); |
// return TCL.TCL_ERROR; |
// } |
// if( objc==3 ){ |
// int j; |
// int iNew = 0; |
// Tcl_Obj[] flags = null; |
// int nFlags = 0; |
|
// if ( TCL.Tcl_ListObjGetElements( interp, objv[2], ref nFlags, ref flags ) ) |
// { |
// return TCL.TCL_ERROR; |
// } |
|
// for(j=0; j<nFlags; j++){ |
// int idx = 0; |
// if( Tcl_GetIndexFromObjStruct(interp, flags[j], aFlag, |
// aFlag.Length, "flag", 0, ref idx) |
// ){ |
// return TCL.TCL_ERROR; |
// } |
// if( aFlag[idx].iValue<0 && nFlags>1 ){ |
// TCL.Tcl_AppendResult( interp, "bad flags: ", TCL.Tcl_GetString( objv[2] ), 0 ); |
// return TCL.TCL_ERROR; |
// } |
// iNew |= aFlag[idx].iValue; |
// } |
|
// p.iDevchar = iNew; |
// } |
|
// pRet = TCL.Tcl_NewObj(); |
// for(iFlag=0; iFlag<aFlag.Length ; iFlag++)//sizeof(aFlag)/sizeof(aFlag[0]); iFlag++) |
// { |
// if( p.iDevchar & aFlag[iFlag].iValue ){ |
// TCL.Tcl_ListObjAppendElement( |
// interp, pRet, TCL.Tcl_NewStringObj(aFlag[iFlag].zName, -1) |
// ); |
// } |
// } |
// TCL.Tcl_SetObjResult( interp, pRet ); |
|
// break; |
// } |
|
// case DB_enum_CMD.CMD_SECTORSIZE: { |
// if( objc>3 ){ |
// TCL.Tcl_WrongNumArgs( interp, 2, objv, "?VALUE?" ); |
// return TCL.TCL_ERROR; |
// } |
// if( objc==3 ){ |
// int iNew = 0; |
// if( Tcl_GetIntFromObj(interp, objv[2], ref iNew) ){ |
// return TCL.TCL_ERROR; |
// } |
// p.iSectorsize = iNew; |
// } |
// TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( p.iSectorsize ) ); |
// break; |
// } |
// } |
return TCL.TCL_OK; |
} |
|
static void testvfs_obj_del(ClientData cd){ |
Testvfs p = (Testvfs)cd; |
if ( p.pScript !=null) |
TCL.Tcl_DecrRefCount( ref p.pScript ); |
sqlite3_vfs_unregister(p.pVfs); |
Debugger.Break();//TODO |
//ckfree((char )p.pVfs); |
//ckfree((char )p); |
} |
|
/* |
** Usage: testvfs VFSNAME ?SWITCHES? |
** |
** Switches are: |
** |
** -noshm BOOLEAN (True to omit shm methods. Default false) |
** -default BOOLEAN (True to make the vfs default. Default false) |
** |
** This command creates two things when it is invoked: an SQLite VFS, and |
** a Tcl command. Both are named VFSNAME. The VFS is installed. It is not |
** installed as the default VFS. |
** |
** The VFS passes all file I/O calls through to the underlying VFS. |
** |
** Whenever the xShmMap method of the VFS |
** is invoked, the SCRIPT is executed as follows: |
** |
** SCRIPT xShmMap FILENAME ID |
** |
** The value returned by the invocation of SCRIPT above is interpreted as |
** an SQLite error code and returned to SQLite. Either a symbolic |
** "SQLITE_OK" or numeric "0" value may be returned. |
** |
** The contents of the shared-memory buffer associated with a given file |
** may be read and set using the following command: |
** |
** VFSNAME shm FILENAME ?NEWVALUE? |
** |
** When the xShmLock method is invoked by SQLite, the following script is |
** run: |
** |
** SCRIPT xShmLock FILENAME ID LOCK |
** |
** where LOCK is of the form "OFFSET NBYTE lock/unlock shared/exclusive" |
*/ |
static int testvfs_cmd( |
ClientData cd, |
Tcl_Interp interp, |
int objc, |
Tcl_Obj[] objv |
){ |
Debugger.Break();//TODO |
// sqlite3_vfs tvfs_vfs = new sqlite3_vfs( |
// 2, /* iVersion */ |
// 0, /* szOsFile */ |
// 0, /* mxPathname */ |
// null, /* pNext */ |
// null, /* zName */ |
// 0, /* pAppData */ |
// tvfsOpen, /* xOpen */ |
// tvfsDelete, /* xDelete */ |
// tvfsAccess, /* xAccess */ |
// tvfsFullPathname, /* xFullPathname */ |
//#if !SQLITE_OMIT_LOAD_EXTENSION |
// tvfsDlOpen, /* xDlOpen */ |
// tvfsDlError, /* xDlError */ |
// tvfsDlSym, /* xDlSym */ |
// tvfsDlClose, /* xDlClose */ |
//#else |
// null, /* xDlOpen */ |
// null, /* xDlError */ |
// null, /* xDlSym */ |
// null, /* xDlClose */ |
//#endif //* SQLITE_OMIT_LOAD_EXTENSION */ |
// tvfsRandomness, /* xRandomness */ |
// tvfsSleep, /* xSleep */ |
// tvfsCurrentTime, /* xCurrentTime */ |
// null, /* xGetLastError */ |
// null, /* xCurrentTimeInt64 */ |
// null, null, null |
// ); |
|
// Testvfs p; /* New object */ |
// sqlite3_vfs pVfs; /* New VFS */ |
// string zVfs; |
// int nByte; /* Bytes of space to allocate at p */ |
|
// int i; |
// int isNoshm = 0; /* True if -noshm is passed */ |
// int isDefault = 0; /* True if -default is passed */ |
// int szOsFile = 0; /* Value passed to -szosfile */ |
// int mxPathname = -1; /* Value passed to -mxpathname */ |
// int iVersion = 2; /* Value passed to -iversion */ |
|
// if( objc<2 || 0!=(objc%2) ) goto bad_args; |
// for(i=2; i<objc; i += 2){ |
// int nSwitch; |
// string zSwitch; |
// zSwitch = TCL.Tcl_GetStringFromObj(objv[i], &nSwitch); |
|
// if( nSwitch>2 && 0==strncmp("-noshm", zSwitch, nSwitch) ){ |
// if ( TCL.Tcl_GetBooleanFromObj( interp, objv[i + 1], &isNoshm ) ) |
// { |
// return TCL.TCL_ERROR; |
// } |
// } |
// else if( nSwitch>2 && 0==strncmp("-default", zSwitch, nSwitch) ){ |
// if ( TCL.Tcl_GetBooleanFromObj( interp, objv[i + 1], &isDefault ) ) |
// { |
// return TCL.TCL_ERROR; |
// } |
// } |
// else if( nSwitch>2 && 0==strncmp("-szosfile", zSwitch, nSwitch) ){ |
// if ( TCL.Tcl_GetIntFromObj( interp, objv[i + 1], &szOsFile ) ) |
// { |
// return TCL.TCL_ERROR; |
// } |
// } |
// else if( nSwitch>2 && 0==strncmp("-mxpathname", zSwitch, nSwitch) ){ |
// if ( TCL.Tcl_GetIntFromObj( interp, objv[i + 1], &mxPathname ) ) |
// { |
// return TCL.TCL_ERROR; |
// } |
// } |
// else if( nSwitch>2 && 0==strncmp("-iversion", zSwitch, nSwitch) ){ |
// if ( TCL.Tcl_GetIntFromObj( interp, objv[i + 1], &iVersion ) ) |
// { |
// return TCL.TCL_ERROR; |
// } |
// } |
// else{ |
// goto bad_args; |
// } |
// } |
|
// if( szOsFile<sizeof(TestvfsFile) ){ |
// szOsFile = sizeof(TestvfsFile); |
// } |
|
// zVfs = TCL.Tcl_GetString(objv[1]); |
// nByte = sizeof(Testvfs) + strlen(zVfs)+1; |
// p = (Testvfs )ckalloc(nByte); |
// memset(p, 0, nByte); |
// p.iDevchar = -1; |
// p.iSectorsize = -1; |
|
// /* Create the new object command before querying SQLite for a default VFS |
// ** to use for 'real' IO operations. This is because creating the new VFS |
// ** may delete an existing [testvfs] VFS of the same name. If such a VFS |
// ** is currently the default, the new [testvfs] may end up calling the |
// ** methods of a deleted object. |
// */ |
// TCL.Tcl_CreateObjCommand( interp, zVfs, testvfs_obj_cmd, p, testvfs_obj_del ); |
// p.pParent = sqlite3_vfs_find(""); |
// p.interp = interp; |
|
// p.zName = (char )&p[1]; |
// memcpy(p.zName, zVfs, strlen(zVfs)+1); |
|
// pVfs = new sqlite3_vfs();//(sqlite3_vfs )ckalloc(sizeof(sqlite3_vfs)); |
// tvfs_vfs.CopyTo(pVfs);//memcpy( pVfs, &tvfs_vfs, sizeof( sqlite3_vfs ) ); |
// pVfs.pAppData = p; |
// pVfs.iVersion = iVersion; |
// pVfs.zName = p.zName; |
// pVfs.mxPathname = p.pParent.mxPathname; |
// if( mxPathname>=0 && mxPathname<pVfs.mxPathname ){ |
// pVfs.mxPathname = mxPathname; |
// } |
// pVfs.szOsFile = szOsFile; |
// p.pVfs = pVfs; |
// p.isNoshm = isNoshm; |
// p.mask = TESTVFS_ALL_MASK; |
|
// sqlite3_vfs_register(pVfs, isDefault); |
|
// return TCL.TCL_OK; |
|
// bad_args: |
// TCL.Tcl_WrongNumArgs(interp, 1, objv, "VFSNAME ?-noshm BOOL? ?-default BOOL? ?-mxpathname INT? ?-szosfile INT? ?-iversion INT?"); |
return TCL.TCL_ERROR; |
} |
|
static int Sqlitetestvfs_Init(Tcl_Interp interp){ |
TCL.Tcl_CreateObjCommand( interp, "testvfs", testvfs_cmd, null, null ); |
return TCL.TCL_OK; |
} |
#endif |
} |
#endif |
} |
/trunk/testfixture/testfixture.csproj |
@@ -0,0 +1,2399 @@ |
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5"> |
<PropertyGroup> |
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
<ProductVersion>9.0.30729</ProductVersion> |
<SchemaVersion>2.0</SchemaVersion> |
<ProjectGuid>{FDA6FB30-1601-4C64-85C1-49C7AD3C78DD}</ProjectGuid> |
<OutputType>Exe</OutputType> |
<AppDesignerFolder>Properties</AppDesignerFolder> |
<RootNamespace>Community.Data.SQLite</RootNamespace> |
<AssemblyName>Testfixture</AssemblyName> |
<StartupObject>Testing</StartupObject> |
<FileUpgradeFlags> |
</FileUpgradeFlags> |
<OldToolsVersion>2.0</OldToolsVersion> |
<UpgradeBackupLocation> |
</UpgradeBackupLocation> |
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion> |
<PublishUrl>publish\</PublishUrl> |
<Install>true</Install> |
<InstallFrom>Disk</InstallFrom> |
<UpdateEnabled>false</UpdateEnabled> |
<UpdateMode>Foreground</UpdateMode> |
<UpdateInterval>7</UpdateInterval> |
<UpdateIntervalUnits>Days</UpdateIntervalUnits> |
<UpdatePeriodically>false</UpdatePeriodically> |
<UpdateRequired>false</UpdateRequired> |
<MapFileExtensions>true</MapFileExtensions> |
<ApplicationRevision>0</ApplicationRevision> |
<ApplicationVersion>1.0.0.%2a</ApplicationVersion> |
<IsWebBootstrapper>false</IsWebBootstrapper> |
<UseApplicationTrust>false</UseApplicationTrust> |
<BootstrapperEnabled>true</BootstrapperEnabled> |
<TargetFrameworkSubset> |
</TargetFrameworkSubset> |
</PropertyGroup> |
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
<DebugSymbols>true</DebugSymbols> |
<DebugType>full</DebugType> |
<Optimize>false</Optimize> |
<OutputPath>bin\Debug\</OutputPath> |
<DefineConstants>DEBUG;TRUE _MSC_VER WIN32 NET_35 SQLITE_ASCII SQLITE_DEBUG SQLITE_DISABLE_LFS SQLITE_ENABLE_COLUMN_METADATA SQLITE_HAS_CODEC SQLITE_MUTEX_W32 SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_WAL SQLITE_OS_WIN SQLITE_THREADSAFE SQLITE_TEST SQLITE_USE_URI SQLITE_POOL_MEM SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_ENABLE_STAT2 VDBE_PROFILE_OFF TCLSH</DefineConstants> |
<ErrorReport>prompt</ErrorReport> |
<WarningLevel>4</WarningLevel> |
<NoWarn>0168 ; 0169; 0414; 0618; 0649</NoWarn> |
<PlatformTarget>AnyCPU</PlatformTarget> |
</PropertyGroup> |
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
<DebugType>pdbonly</DebugType> |
<Optimize>true</Optimize> |
<OutputPath>bin\Release\</OutputPath> |
<DefineConstants>TRACE;DEBUG;TRUE WIN32 _MSC_VER SQLITE_ASCII SQLITE_DEBUG SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OMIT_WAL SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC SQLITE_TEST VDBE_PROFILE_OFF</DefineConstants> |
<ErrorReport>prompt</ErrorReport> |
<WarningLevel>4</WarningLevel> |
<NoWarn>0168 ; 0169; 0414; 0618; 0649</NoWarn> |
<PlatformTarget>x86</PlatformTarget> |
</PropertyGroup> |
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' "> |
<DebugSymbols>true</DebugSymbols> |
<OutputPath>bin\Debug\</OutputPath> |
<DefineConstants>DEBUG;TRUE _MSC_VER WIN32 NET_35 SQLITE_ASCII SQLITE_DEBUG SQLITE_DISABLE_LFS SQLITE_ENABLE_COLUMN_METADATA SQLITE_HAS_CODEC SQLITE_MUTEX_W32 SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_WAL SQLITE_OS_WIN SQLITE_THREADSAFE SQLITE_TEST SQLITE_USE_URI SQLITE_POOL_MEM SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_ENABLE_STAT2 VDBE_PROFILE_OFF TCLSH</DefineConstants> |
<NoWarn>0168 ; 0169; 0414; 0618; 0649</NoWarn> |
<DebugType>full</DebugType> |
<PlatformTarget>x86</PlatformTarget> |
<ErrorReport>prompt</ErrorReport> |
</PropertyGroup> |
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' "> |
<OutputPath>bin\x64\Release\</OutputPath> |
<DefineConstants>TRACE;DEBUG;TRUE WIN32 _MSC_VER SQLITE_ASCII SQLITE_DEBUG SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OMIT_WAL SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC SQLITE_TEST VDBE_PROFILE_OFF</DefineConstants> |
<Optimize>true</Optimize> |
<NoWarn>0168 ; 0169; 0414; 0618; 0649</NoWarn> |
<DebugType>pdbonly</DebugType> |
<PlatformTarget>x64</PlatformTarget> |
<ErrorReport>prompt</ErrorReport> |
</PropertyGroup> |
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> |
<DebugSymbols>true</DebugSymbols> |
<OutputPath>bin\x86\Debug\</OutputPath> |
<DefineConstants>DEBUG;TRUE _MSC_VER WIN32 NET_35 SQLITE_ASCII SQLITE_DEBUG SQLITE_DISABLE_LFS SQLITE_ENABLE_COLUMN_METADATA SQLITE_HAS_CODEC SQLITE_MUTEX_W32 SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_WAL SQLITE_OS_WIN SQLITE_THREADSAFE SQLITE_TEST SQLITE_USE_URI SQLITE_POOL_MEM SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_ENABLE_STAT2 VDBE_PROFILE_OFF TCLSH</DefineConstants> |
<NoWarn>0168 ; 0169; 0414; 0618; 0649</NoWarn> |
<DebugType>full</DebugType> |
<PlatformTarget>x86</PlatformTarget> |
<ErrorReport>prompt</ErrorReport> |
</PropertyGroup> |
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> |
<OutputPath>bin\x86\Release\</OutputPath> |
<DefineConstants>TRACE;DEBUG;TRUE WIN32 _MSC_VER SQLITE_ASCII SQLITE_DEBUG SQLITE_DISABLE_LFS SQLITE_ENABLE_OVERSIZE_CELL_CHECK SQLITE_MUTEX_OMIT SQLITE_OMIT_AUTHORIZATION SQLITE_OMIT_DEPRECATED SQLITE_OMIT_GET_TABLE SQLITE_OMIT_INCRBLOB SQLITE_OMIT_LOOKASIDE SQLITE_OMIT_SHARED_CACHE SQLITE_OMIT_UTF16 SQLITE_OMIT_VIRTUALTABLE SQLITE_OMIT_WAL SQLITE_OS_WIN SQLITE_SYSTEM_MALLOC SQLITE_TEST VDBE_PROFILE_OFF</DefineConstants> |
<Optimize>true</Optimize> |
<NoWarn>0168 ; 0169; 0414; 0618; 0649</NoWarn> |
<DebugType>pdbonly</DebugType> |
<PlatformTarget>x86</PlatformTarget> |
<ErrorReport>prompt</ErrorReport> |
</PropertyGroup> |
<ItemGroup> |
<Reference Include="System" /> |
<Reference Include="System.Core"> |
<RequiredTargetFramework>3.5</RequiredTargetFramework> |
</Reference> |
<Reference Include="System.Data" /> |
<Reference Include="System.Management" /> |
<Reference Include="System.Xml" /> |
</ItemGroup> |
<ItemGroup> |
<Compile Include="..\Community.CsharpSqlite\src\alter_c.cs"> |
<Link>Community.CsharpSqlite\alter_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\analyze_c.cs"> |
<Link>Community.CsharpSqlite\analyze_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\attach_c.cs"> |
<Link>Community.CsharpSqlite\attach_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\auth_c.cs"> |
<Link>Community.CsharpSqlite\auth_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\backup_c.cs"> |
<Link>Community.CsharpSqlite\backup_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\bitvec_c.cs"> |
<Link>Community.CsharpSqlite\bitvec_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\btmutex_c.cs"> |
<Link>Community.CsharpSqlite\btmutex_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\btreeInt_h.cs"> |
<Link>Community.CsharpSqlite\BtreeInt_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\btree_c.cs"> |
<Link>Community.CsharpSqlite\btree_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\btree_h.cs"> |
<Link>Community.CsharpSqlite\btree_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\build_c.cs"> |
<Link>Community.CsharpSqlite\build_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\callback_c.cs"> |
<Link>Community.CsharpSqlite\callback_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\complete_c.cs"> |
<Link>Community.CsharpSqlite\complete_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\crypto.cs"> |
<Link>Community.CsharpSqlite\crypto.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\ctime_c.cs"> |
<Link>Community.CsharpSqlite\ctime_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\date_c.cs"> |
<Link>Community.CsharpSqlite\date_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\Delegates.cs"> |
<Link>Community.CsharpSqlite\Delegates.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\delete_c.cs"> |
<Link>Community.CsharpSqlite\delete_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\expr_c.cs"> |
<Link>Community.CsharpSqlite\expr_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\fault_c.cs"> |
<Link>Community.CsharpSqlite\fault_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\fkey_c.cs"> |
<Link>Community.CsharpSqlite\fkey_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\func_c.cs"> |
<Link>Community.CsharpSqlite\func_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\global_c.cs"> |
<Link>Community.CsharpSqlite\global_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\hash_c.cs"> |
<Link>Community.CsharpSqlite\hash_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\Hash_h.cs"> |
<Link>Community.CsharpSqlite\Hash_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\hwtime_c.cs"> |
<Link>Community.CsharpSqlite\hwtime_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\insert_c.cs"> |
<Link>Community.CsharpSqlite\insert_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\journal_c.cs"> |
<Link>Community.CsharpSqlite\journal_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\keywordhash_h.cs"> |
<Link>Community.CsharpSqlite\keywordhash_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\legacy_c.cs"> |
<Link>Community.CsharpSqlite\legacy_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\loadext_c.cs"> |
<Link>Community.CsharpSqlite\loadext_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\main_c.cs"> |
<Link>Community.CsharpSqlite\main_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\malloc_c.cs"> |
<Link>Community.CsharpSqlite\malloc_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\memjournal_c.cs"> |
<Link>Community.CsharpSqlite\memjournal_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\mem_Pool.cs"> |
<Link>Community.CsharpSqlite\mem_Pool.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\mutex_c.cs"> |
<Link>Community.CsharpSqlite\mutex_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\mutex_h.cs"> |
<Link>Community.CsharpSqlite\mutex_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\mutex_noop_c.cs"> |
<Link>Community.CsharpSqlite\mutex_noop_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\mutex_w32.cs"> |
<Link>Community.CsharpSqlite\mutex_w32.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\opcodes_c.cs"> |
<Link>Community.CsharpSqlite\opcodes_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\opcodes_h.cs"> |
<Link>Community.CsharpSqlite\opcodes_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\os_c.cs"> |
<Link>Community.CsharpSqlite\os_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\os_common_h.cs"> |
<Link>Community.CsharpSqlite\os_common_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\os_h.cs"> |
<Link>Community.CsharpSqlite\os_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\os_win_c.cs"> |
<Link>Community.CsharpSqlite\os_win_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\pager_c.cs"> |
<Link>Community.CsharpSqlite\pager_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\pager_h.cs"> |
<Link>Community.CsharpSqlite\pager_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\parse_c.cs"> |
<Link>Community.CsharpSqlite\parse_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\parse_h.cs"> |
<Link>Community.CsharpSqlite\parse_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\pcache1_c.cs"> |
<Link>Community.CsharpSqlite\pcache1_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\pcache_c.cs"> |
<Link>Community.CsharpSqlite\pcache_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\pcache_h.cs"> |
<Link>Community.CsharpSqlite\pcache_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\pragma_c.cs"> |
<Link>Community.CsharpSqlite\pragma_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\prepare_c.cs"> |
<Link>Community.CsharpSqlite\prepare_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\printf_c.cs"> |
<Link>Community.CsharpSqlite\printf_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\random_c.cs"> |
<Link>Community.CsharpSqlite\random_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\resolve_c.cs"> |
<Link>Community.CsharpSqlite\resolve_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\rowset_c.cs"> |
<Link>Community.CsharpSqlite\rowset_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\select_c.cs"> |
<Link>Community.CsharpSqlite\select_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\sqlite3_h.cs"> |
<Link>Community.CsharpSqlite\sqlite3_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\sqliteInt_h.cs"> |
<Link>Community.CsharpSqlite\sqliteInt_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\sqliteLimit_h.cs"> |
<Link>Community.CsharpSqlite\sqliteLimit_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\status_c.cs"> |
<Link>Community.CsharpSqlite\status_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\table_c.cs"> |
<Link>Community.CsharpSqlite\table_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\tokenize_c.cs"> |
<Link>Community.CsharpSqlite\tokenize_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\trigger_c.cs"> |
<Link>Community.CsharpSqlite\trigger_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\update_c.cs"> |
<Link>Community.CsharpSqlite\update_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\utf_c.cs"> |
<Link>Community.CsharpSqlite\utf_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\util_c.cs"> |
<Link>Community.CsharpSqlite\util_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\vacuum_c.cs"> |
<Link>Community.CsharpSqlite\vacuum_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\vdbeapi_c.cs"> |
<Link>Community.CsharpSqlite\vdbeapi_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\vdbeaux_c.cs"> |
<Link>Community.CsharpSqlite\vdbeaux_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\vdbeblob_c.cs"> |
<Link>Community.CsharpSqlite\vdbeblob_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\vdbeInt_h.cs"> |
<Link>Community.CsharpSqlite\vdbeInt_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\vdbemem_c.cs"> |
<Link>Community.CsharpSqlite\vdbemem_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\vdbetrace_c.cs"> |
<Link>Community.CsharpSqlite\vdbetrace_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\vdbe_c.cs"> |
<Link>Community.CsharpSqlite\vdbe_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\vdbe_h.cs"> |
<Link>Community.CsharpSqlite\vdbe_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\vtab_c.cs"> |
<Link>Community.CsharpSqlite\vtab_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\walker_c.cs"> |
<Link>Community.CsharpSqlite\walker_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\wal_c.cs"> |
<Link>Community.CsharpSqlite\wal_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\wal_h.cs"> |
<Link>Community.CsharpSqlite\wal_h.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\where_c.cs"> |
<Link>Community.CsharpSqlite\where_c.cs</Link> |
</Compile> |
<Compile Include="..\Community.CsharpSqlite\src\_Custom.cs"> |
<Link>Community.CsharpSqlite\_Custom.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\AssocData.cs"> |
<Link>TCL\src\base\AssocData.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\BackSlashResult.cs"> |
<Link>TCL\src\base\BackSlashResult.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\BgErrorMgr.cs"> |
<Link>TCL\src\base\BgErrorMgr.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\CallFrame.cs"> |
<Link>TCL\src\base\CallFrame.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\CharPointer.cs"> |
<Link>TCL\src\base\CharPointer.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\CObject.cs"> |
<Link>TCL\src\base\CObject.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\Command.cs"> |
<Link>TCL\src\base\Command.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\CommandWithDispose.cs"> |
<Link>TCL\src\base\CommandWithDispose.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\DebugInfo.cs"> |
<Link>TCL\src\base\DebugInfo.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\Env.cs"> |
<Link>TCL\src\base\Env.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\EventDeleter.cs"> |
<Link>TCL\src\base\EventDeleter.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\EventuallyFreed.cs"> |
<Link>TCL\src\base\EventuallyFreed.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\Expression.cs"> |
<Link>TCL\src\base\Expression.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\ExprValue.cs"> |
<Link>TCL\src\base\ExprValue.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\Extension.cs"> |
<Link>TCL\src\base\Extension.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\FindElemResult.cs"> |
<Link>TCL\src\base\FindElemResult.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\IdleHandler.cs"> |
<Link>TCL\src\base\IdleHandler.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\ImportedCmdData.cs"> |
<Link>TCL\src\base\ImportedCmdData.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\ImportRef.cs"> |
<Link>TCL\src\base\ImportRef.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\InternalRep.cs"> |
<Link>TCL\src\base\InternalRep.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\Interp.cs"> |
<Link>TCL\src\base\Interp.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\JACL.cs"> |
<Link>TCL\src\base\JACL.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\Notifier.cs"> |
<Link>TCL\src\base\Notifier.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\Parser.cs"> |
<Link>TCL\src\base\Parser.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\ParseResult.cs"> |
<Link>TCL\src\base\ParseResult.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\Procedure.cs"> |
<Link>TCL\src\base\Procedure.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\QSort.cs"> |
<Link>TCL\src\base\QSort.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\Resolver.cs"> |
<Link>TCL\src\base\Resolver.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\SearchId.cs"> |
<Link>TCL\src\base\SearchId.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TCL.cs"> |
<Link>TCL\src\base\TCL.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclBoolean.cs"> |
<Link>TCL\src\base\TclBoolean.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclByteArray.cs"> |
<Link>TCL\src\base\TclByteArray.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclDouble.cs"> |
<Link>TCL\src\base\TclDouble.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclEvent.cs"> |
<Link>TCL\src\base\TclEvent.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclException.cs"> |
<Link>TCL\src\base\TclException.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclIndex.cs"> |
<Link>TCL\src\base\TclIndex.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclInteger.cs"> |
<Link>TCL\src\base\TclInteger.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclList.cs"> |
<Link>TCL\src\base\TclList.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclLong.cs"> |
<Link>TCL\src\base\TclLong.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclNumArgsException.cs"> |
<Link>TCL\src\base\TclNumArgsException.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TCLObj.cs"> |
<Link>TCL\src\base\TCLObj.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclObject.cs"> |
<Link>TCL\src\base\TclObject.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclParse.cs"> |
<Link>TCL\src\base\TclParse.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclPosixException.cs"> |
<Link>TCL\src\base\TclPosixException.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclRegexp.cs"> |
<Link>TCL\src\base\TclRegexp.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclRuntimeError.cs"> |
<Link>TCL\src\base\TclRuntimeError.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclString.cs"> |
<Link>TCL\src\base\TclString.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclToken.cs"> |
<Link>TCL\src\base\TclToken.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TclVarException.cs"> |
<Link>TCL\src\base\TclVarException.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TimerHandler.cs"> |
<Link>TCL\src\base\TimerHandler.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\TraceRecord.cs"> |
<Link>TCL\src\base\TraceRecord.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\Util.cs"> |
<Link>TCL\src\base\Util.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\Var.cs"> |
<Link>TCL\src\base\Var.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\VarTrace.cs"> |
<Link>TCL\src\base\VarTrace.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\base\WrappedCommand.cs"> |
<Link>TCL\src\base\WrappedCommand.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\AfterCmd.cs"> |
<Link>TCL\src\commands\AfterCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\AppendCmd.cs"> |
<Link>TCL\src\commands\AppendCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ArrayCmd.cs"> |
<Link>TCL\src\commands\ArrayCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\BinaryCmd.cs"> |
<Link>TCL\src\commands\BinaryCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\BreakCmd.cs"> |
<Link>TCL\src\commands\BreakCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\CaseCmd.cs"> |
<Link>TCL\src\commands\CaseCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\CatchCmd.cs"> |
<Link>TCL\src\commands\CatchCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\CdCmd.cs"> |
<Link>TCL\src\commands\CdCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ClockCmd.cs"> |
<Link>TCL\src\commands\ClockCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\CloseCmd.cs"> |
<Link>TCL\src\commands\CloseCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ConcatCmd.cs"> |
<Link>TCL\src\commands\ConcatCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ContinueCmd.cs"> |
<Link>TCL\src\commands\ContinueCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\EncodingCmd.cs"> |
<Link>TCL\src\commands\EncodingCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\EofCmd.cs"> |
<Link>TCL\src\commands\EofCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ErrorCmd.cs"> |
<Link>TCL\src\commands\ErrorCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\EvalCmd.cs"> |
<Link>TCL\src\commands\EvalCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ExecCmd.cs"> |
<Link>TCL\src\commands\ExecCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ExitCmd.cs"> |
<Link>TCL\src\commands\ExitCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ExprCmd.cs"> |
<Link>TCL\src\commands\ExprCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\FblockedCmd.cs"> |
<Link>TCL\src\commands\FblockedCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\FconfigureCmd.cs"> |
<Link>TCL\src\commands\FconfigureCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\FileCmd.cs"> |
<Link>TCL\src\commands\FileCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\FlushCmd.cs"> |
<Link>TCL\src\commands\FlushCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ForCmd.cs"> |
<Link>TCL\src\commands\ForCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ForeachCmd.cs"> |
<Link>TCL\src\commands\ForeachCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\FormatCmd.cs"> |
<Link>TCL\src\commands\FormatCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\GetsCmd.cs"> |
<Link>TCL\src\commands\GetsCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\GlobalCmd.cs"> |
<Link>TCL\src\commands\GlobalCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\GlobCmd.cs"> |
<Link>TCL\src\commands\GlobCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\IfCmd.cs"> |
<Link>TCL\src\commands\IfCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\IncrCmd.cs"> |
<Link>TCL\src\commands\IncrCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\InfoCmd.cs"> |
<Link>TCL\src\commands\InfoCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\InterpAliasCmd.cs"> |
<Link>TCL\src\commands\InterpAliasCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\InterpCmd.cs"> |
<Link>TCL\src\commands\InterpCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\InterpSlaveCmd.cs"> |
<Link>TCL\src\commands\InterpSlaveCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\JoinCmd.cs"> |
<Link>TCL\src\commands\JoinCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\LappendCmd.cs"> |
<Link>TCL\src\commands\LappendCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\LindexCmd.cs"> |
<Link>TCL\src\commands\LindexCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\LinsertCmd.cs"> |
<Link>TCL\src\commands\LinsertCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ListCmd.cs"> |
<Link>TCL\src\commands\ListCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\LlengthCmd.cs"> |
<Link>TCL\src\commands\LlengthCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\LrangeCmd.cs"> |
<Link>TCL\src\commands\LrangeCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\LreplaceCmd.cs"> |
<Link>TCL\src\commands\LreplaceCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\LsearchCmd.cs"> |
<Link>TCL\src\commands\LsearchCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\LsetCmd.cs"> |
<Link>TCL\src\commands\LsetCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\LsortCmd.cs"> |
<Link>TCL\src\commands\LsortCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\NamespaceCmd.cs"> |
<Link>TCL\src\commands\NamespaceCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\OpenCmd.cs"> |
<Link>TCL\src\commands\OpenCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\PackageCmd.cs"> |
<Link>TCL\src\commands\PackageCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ParseAdaptor.cs"> |
<Link>TCL\src\commands\ParseAdaptor.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ProcCmd.cs"> |
<Link>TCL\src\commands\ProcCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\PutsCmd.cs"> |
<Link>TCL\src\commands\PutsCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\PwdCmd.cs"> |
<Link>TCL\src\commands\PwdCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ReadCmd.cs"> |
<Link>TCL\src\commands\ReadCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\RegexpCmd.cs"> |
<Link>TCL\src\commands\RegexpCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\RegsubCmd.cs"> |
<Link>TCL\src\commands\RegsubCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\RenameCmd.cs"> |
<Link>TCL\src\commands\RenameCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ReturnCmd.cs"> |
<Link>TCL\src\commands\ReturnCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\ScanCmd.cs"> |
<Link>TCL\src\commands\ScanCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\SeekCmd.cs"> |
<Link>TCL\src\commands\SeekCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\SetCmd.cs"> |
<Link>TCL\src\commands\SetCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\SocketChannel.cs"> |
<Link>TCL\src\commands\SocketChannel.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\SourceCmd.cs"> |
<Link>TCL\src\commands\srcCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\SplitCmd.cs"> |
<Link>TCL\src\commands\SplitCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\StdChannel.cs"> |
<Link>TCL\src\commands\StdChannel.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\StringCmd.cs"> |
<Link>TCL\src\commands\StringCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\StrtodResult.cs"> |
<Link>TCL\src\commands\StrtodResult.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\StrtoulResult.cs"> |
<Link>TCL\src\commands\StrtoulResult.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\SubstCmd.cs"> |
<Link>TCL\src\commands\SubstCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\SwitchCmd.cs"> |
<Link>TCL\src\commands\SwitchCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\TellCmd.cs"> |
<Link>TCL\src\commands\TellCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\TimeCmd.cs"> |
<Link>TCL\src\commands\TimeCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\TraceCmd.cs"> |
<Link>TCL\src\commands\TraceCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\UnsetCmd.cs"> |
<Link>TCL\src\commands\UnsetCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\UpdateCmd.cs"> |
<Link>TCL\src\commands\UpdateCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\UplevelCmd.cs"> |
<Link>TCL\src\commands\UplevelCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\UpvarCmd.cs"> |
<Link>TCL\src\commands\UpvarCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\VariableCmd.cs"> |
<Link>TCL\src\commands\VariableCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\VwaitCmd.cs"> |
<Link>TCL\src\commands\VwaitCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\commands\WhileCmd.cs"> |
<Link>TCL\src\commands\WhileCmd.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\io\Channel.cs"> |
<Link>TCL\src\io\Channel.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\io\ChannelBuffer.cs"> |
<Link>TCL\src\io\ChannelBuffer.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\io\FileChannel.cs"> |
<Link>TCL\src\io\FileChannel.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\io\FileUtil.cs"> |
<Link>TCL\src\io\FileUtil.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\io\TclInputStream.cs"> |
<Link>TCL\src\io\TclInputStream.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\io\TclIO.cs"> |
<Link>TCL\src\io\TclIO.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\io\TclOutputStream.cs"> |
<Link>TCL\src\io\TclOutputStream.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\regexp_brazil\Regexp.cs"> |
<Link>TCL\src\regexp_brazil\Regexp.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\regexp_brazil\Regsub.cs"> |
<Link>TCL\src\regexp_brazil\Regsub.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\SupportClass.cs"> |
<Link>TCL\src\SupportClass.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\tcl_h.cs"> |
<Link>TCL\src\tcl_h.cs</Link> |
</Compile> |
<Compile Include="..\TCL\src\_tcl_Conversions.cs"> |
<Link>TCL\src\_tcl_Conversions.cs</Link> |
</Compile> |
<Compile Include="Properties\AssemblyInfo.cs" /> |
<Compile Include="src\tclsqlite_c.cs"> |
<SubType>Code</SubType> |
</Compile> |
<Compile Include="src\test1_c.cs" /> |
<Compile Include="src\test2_c.cs" /> |
<Compile Include="src\test3_c.cs" /> |
<Compile Include="src\test8_c.cs" /> |
<Compile Include="src\test_intarray_c.cs" /> |
<Compile Include="src\test9_c.cs" /> |
<Compile Include="src\testfixture.cs" /> |
<Compile Include="src\test_autoext_c.cs" /> |
<Compile Include="src\test_backup_c.cs" /> |
<Compile Include="src\test_btree_c.cs" /> |
<Compile Include="src\test_config_c.cs" /> |
<Compile Include="src\test_func_c.cs" /> |
<Compile Include="src\test_fuzzer_c.cs" /> |
<Compile Include="src\test_hexio_c.cs" /> |
<Compile Include="src\test_malloc_c.cs"> |
<SubType>Code</SubType> |
</Compile> |
<Compile Include="src\test_mutex_c.cs" /> |
<Compile Include="src\test_schema_c.cs" /> |
<Compile Include="src\test_stat_c.cs" /> |
<Compile Include="src\test_tclvar_c.cs" /> |
<Compile Include="src\test_vfstrace_c.cs" /> |
<Compile Include="src\test_vfs_c.cs" /> |
<Compile Include="src\test_wholenumber_c.cs" /> |
</ItemGroup> |
<ItemGroup> |
<None Include="..\test\8_3_names.test"> |
<Link>test\8_3_names.test</Link> |
</None> |
<None Include="..\test\aggerror.test"> |
<Link>test\aggerror.test</Link> |
</None> |
<None Include="..\test\alias.test"> |
<Link>test\alias.test</Link> |
</None> |
<None Include="..\test\alter.test"> |
<Link>test\alter.test</Link> |
</None> |
<None Include="..\test\alter2.test"> |
<Link>test\alter2.test</Link> |
</None> |
<None Include="..\test\alter3.test"> |
<Link>test\alter3.test</Link> |
</None> |
<None Include="..\test\alter4.test"> |
<Link>test\alter4.test</Link> |
</None> |
<None Include="..\test\analyze.test"> |
<Link>test\analyze.test</Link> |
</None> |
<None Include="..\test\analyze2.test"> |
<Link>test\analyze2.test</Link> |
</None> |
<None Include="..\test\analyze3.test"> |
<Link>test\analyze3.test</Link> |
</None> |
<None Include="..\test\analyze4.test"> |
<Link>test\analyze4.test</Link> |
</None> |
<None Include="..\test\analyze5.test"> |
<Link>test\analyze5.test</Link> |
</None> |
<None Include="..\test\analyze6.test"> |
<Link>test\analyze6.test</Link> |
</None> |
<None Include="..\test\analyze7.test"> |
<Link>test\analyze7.test</Link> |
</None> |
<None Include="..\test\async.test"> |
<Link>test\async.test</Link> |
</None> |
<None Include="..\test\async2.test"> |
<Link>test\async2.test</Link> |
</None> |
<None Include="..\test\async3.test"> |
<Link>test\async3.test</Link> |
</None> |
<None Include="..\test\async4.test"> |
<Link>test\async4.test</Link> |
</None> |
<None Include="..\test\async5.test"> |
<Link>test\async5.test</Link> |
</None> |
<None Include="..\test\attach.test"> |
<Link>test\attach.test</Link> |
</None> |
<None Include="..\test\attach2.test"> |
<Link>test\attach2.test</Link> |
</None> |
<None Include="..\test\attach3.test"> |
<Link>test\attach3.test</Link> |
</None> |
<None Include="..\test\attach4.test"> |
<Link>test\attach4.test</Link> |
</None> |
<None Include="..\test\auth.test"> |
<Link>test\auth.test</Link> |
</None> |
<None Include="..\test\auth2.test"> |
<Link>test\auth2.test</Link> |
</None> |
<None Include="..\test\auth3.test"> |
<Link>test\auth3.test</Link> |
</None> |
<None Include="..\test\autoinc.test"> |
<Link>test\autoinc.test</Link> |
</None> |
<None Include="..\test\autoindex1.test"> |
<Link>test\autoindex1.test</Link> |
</None> |
<None Include="..\test\autovacuum.test"> |
<Link>test\autovacuum.test</Link> |
</None> |
<None Include="..\test\avtrans.test"> |
<Link>test\avtrans.test</Link> |
</None> |
<None Include="..\test\backcompat.test"> |
<Link>test\backcompat.test</Link> |
</None> |
<None Include="..\test\backup.test"> |
<Link>test\backup.test</Link> |
</None> |
<None Include="..\test\backup2.test"> |
<Link>test\backup2.test</Link> |
</None> |
<None Include="..\test\badutf.test"> |
<Link>test\badutf.test</Link> |
</None> |
<None Include="..\test\badutf2.test"> |
<Link>test\badutf2.test</Link> |
</None> |
<None Include="..\test\between.test"> |
<Link>test\between.test</Link> |
</None> |
<None Include="..\test\bigfile.test"> |
<Link>test\bigfile.test</Link> |
</None> |
<None Include="..\test\bigrow.test"> |
<Link>test\bigrow.test</Link> |
</None> |
<None Include="..\test\bind.test"> |
<Link>test\bind.test</Link> |
</None> |
<None Include="..\test\bindxfer.test"> |
<Link>test\bindxfer.test</Link> |
</None> |
<None Include="..\test\bitvec.test"> |
<Link>test\bitvec.test</Link> |
</None> |
<None Include="..\test\blob.test"> |
<Link>test\blob.test</Link> |
</None> |
<None Include="..\test\boundary1.tcl"> |
<Link>test\boundary1.tcl</Link> |
</None> |
<None Include="..\test\boundary1.test"> |
<Link>test\boundary1.test</Link> |
</None> |
<None Include="..\test\boundary2.tcl"> |
<Link>test\boundary2.tcl</Link> |
</None> |
<None Include="..\test\boundary2.test"> |
<Link>test\boundary2.test</Link> |
</None> |
<None Include="..\test\boundary3.tcl"> |
<Link>test\boundary3.tcl</Link> |
</None> |
<None Include="..\test\boundary3.test"> |
<Link>test\boundary3.test</Link> |
</None> |
<None Include="..\test\boundary4.tcl"> |
<Link>test\boundary4.tcl</Link> |
</None> |
<None Include="..\test\boundary4.test"> |
<Link>test\boundary4.test</Link> |
</None> |
<None Include="..\test\busy.test"> |
<Link>test\busy.test</Link> |
</None> |
<None Include="..\test\cache.test"> |
<Link>test\cache.test</Link> |
</None> |
<None Include="..\test\capi2.test"> |
<Link>test\capi2.test</Link> |
</None> |
<None Include="..\test\capi3.test"> |
<Link>test\capi3.test</Link> |
</None> |
<None Include="..\test\capi3b.test"> |
<Link>test\capi3b.test</Link> |
</None> |
<None Include="..\test\capi3c.test"> |
<Link>test\capi3c.test</Link> |
</None> |
<None Include="..\test\capi3d.test"> |
<Link>test\capi3d.test</Link> |
</None> |
<None Include="..\test\capi3e.test"> |
<Link>test\capi3e.test</Link> |
</None> |
<None Include="..\test\cast.test"> |
<Link>test\cast.test</Link> |
</None> |
<None Include="..\test\check.test"> |
<Link>test\check.test</Link> |
</None> |
<None Include="..\test\coalesce.test"> |
<Link>test\coalesce.test</Link> |
</None> |
<None Include="..\test\collate1.test"> |
<Link>test\collate1.test</Link> |
</None> |
<None Include="..\test\collate2.test"> |
<Link>test\collate2.test</Link> |
</None> |
<None Include="..\test\collate3.test"> |
<Link>test\collate3.test</Link> |
</None> |
<None Include="..\test\collate4.test"> |
<Link>test\collate4.test</Link> |
</None> |
<None Include="..\test\collate5.test"> |
<Link>test\collate5.test</Link> |
</None> |
<None Include="..\test\collate6.test"> |
<Link>test\collate6.test</Link> |
</None> |
<None Include="..\test\collate7.test"> |
<Link>test\collate7.test</Link> |
</None> |
<None Include="..\test\collate8.test"> |
<Link>test\collate8.test</Link> |
</None> |
<None Include="..\test\collate9.test"> |
<Link>test\collate9.test</Link> |
</None> |
<None Include="..\test\collateA.test"> |
<Link>test\collateA.test</Link> |
</None> |
<None Include="..\test\colmeta.test"> |
<Link>test\colmeta.test</Link> |
</None> |
<None Include="..\test\colname.test"> |
<Link>test\colname.test</Link> |
</None> |
<None Include="..\test\conflict.test"> |
<Link>test\conflict.test</Link> |
</None> |
<None Include="..\test\corrupt.test"> |
<Link>test\corrupt.test</Link> |
</None> |
<None Include="..\test\corrupt2.test"> |
<Link>test\corrupt2.test</Link> |
</None> |
<None Include="..\test\corrupt3.test"> |
<Link>test\corrupt3.test</Link> |
</None> |
<None Include="..\test\corrupt4.test"> |
<Link>test\corrupt4.test</Link> |
</None> |
<None Include="..\test\corrupt5.test"> |
<Link>test\corrupt5.test</Link> |
</None> |
<None Include="..\test\corrupt6.test"> |
<Link>test\corrupt6.test</Link> |
</None> |
<None Include="..\test\corrupt7.test"> |
<Link>test\corrupt7.test</Link> |
</None> |
<None Include="..\test\corrupt8.test"> |
<Link>test\corrupt8.test</Link> |
</None> |
<None Include="..\test\corrupt9.test"> |
<Link>test\corrupt9.test</Link> |
</None> |
<None Include="..\test\corruptA.test"> |
<Link>test\corruptA.test</Link> |
</None> |
<None Include="..\test\corruptB.test"> |
<Link>test\corruptB.test</Link> |
</None> |
<None Include="..\test\corruptC.test"> |
<Link>test\corruptC.test</Link> |
</None> |
<None Include="..\test\corruptD.test"> |
<Link>test\corruptD.test</Link> |
</None> |
<None Include="..\test\corruptE.test"> |
<Link>test\corruptE.test</Link> |
</None> |
<None Include="..\test\count.test"> |
<Link>test\count.test</Link> |
</None> |
<None Include="..\test\crash.test"> |
<Link>test\crash.test</Link> |
</None> |
<None Include="..\test\crash2.test"> |
<Link>test\crash2.test</Link> |
</None> |
<None Include="..\test\crash3.test"> |
<Link>test\crash3.test</Link> |
</None> |
<None Include="..\test\crash4.test"> |
<Link>test\crash4.test</Link> |
</None> |
<None Include="..\test\crash5.test"> |
<Link>test\crash5.test</Link> |
</None> |
<None Include="..\test\crash6.test"> |
<Link>test\crash6.test</Link> |
</None> |
<None Include="..\test\crash7.test"> |
<Link>test\crash7.test</Link> |
</None> |
<None Include="..\test\crash8.test"> |
<Link>test\crash8.test</Link> |
</None> |
<None Include="..\test\createtab.test"> |
<Link>test\createtab.test</Link> |
</None> |
<None Include="..\test\cse.test"> |
<Link>test\cse.test</Link> |
</None> |
<None Include="..\test\ctime.test"> |
<Link>test\ctime.test</Link> |
</None> |
<None Include="..\test\date.test"> |
<Link>test\date.test</Link> |
</None> |
<None Include="..\test\default.test"> |
<Link>test\default.test</Link> |
</None> |
<None Include="..\test\delete.test"> |
<Link>test\delete.test</Link> |
</None> |
<None Include="..\test\delete2.test"> |
<Link>test\delete2.test</Link> |
</None> |
<None Include="..\test\delete3.test"> |
<Link>test\delete3.test</Link> |
</None> |
<None Include="..\test\descidx1.test"> |
<Link>test\descidx1.test</Link> |
</None> |
<None Include="..\test\descidx2.test"> |
<Link>test\descidx2.test</Link> |
</None> |
<None Include="..\test\descidx3.test"> |
<Link>test\descidx3.test</Link> |
</None> |
<None Include="..\test\diskfull.test"> |
<Link>test\diskfull.test</Link> |
</None> |
<None Include="..\test\distinctagg.test"> |
<Link>test\distinctagg.test</Link> |
</None> |
<None Include="..\test\enc.test"> |
<Link>test\enc.test</Link> |
</None> |
<None Include="..\test\enc2.test"> |
<Link>test\enc2.test</Link> |
</None> |
<None Include="..\test\enc3.test"> |
<Link>test\enc3.test</Link> |
</None> |
<None Include="..\test\enc4.test"> |
<Link>test\enc4.test</Link> |
</None> |
<None Include="..\test\eqp.test"> |
<Link>test\eqp.test</Link> |
</None> |
<None Include="..\test\eval.test"> |
<Link>test\eval.test</Link> |
</None> |
<None Include="..\test\exclusive.test"> |
<Link>test\exclusive.test</Link> |
</None> |
<None Include="..\test\exclusive2.test"> |
<Link>test\exclusive2.test</Link> |
</None> |
<None Include="..\test\exec.test"> |
<Link>test\exec.test</Link> |
</None> |
<None Include="..\test\exists.test"> |
<Link>test\exists.test</Link> |
</None> |
<None Include="..\test\expr.test"> |
<Link>test\expr.test</Link> |
</None> |
<None Include="..\test\e_createtable.test"> |
<Link>test\e_createtable.test</Link> |
</None> |
<None Include="..\test\e_delete.test"> |
<Link>test\e_delete.test</Link> |
</None> |
<None Include="..\test\e_droptrigger.test"> |
<Link>test\e_droptrigger.test</Link> |
</None> |
<None Include="..\test\e_dropview.test"> |
<Link>test\e_dropview.test</Link> |
</None> |
<None Include="..\test\e_expr.test"> |
<Link>test\e_expr.test</Link> |
</None> |
<None Include="..\test\e_fkey.test"> |
<Link>test\e_fkey.test</Link> |
</None> |
<None Include="..\test\e_insert.test"> |
<Link>test\e_insert.test</Link> |
</None> |
<None Include="..\test\e_reindex.test"> |
<Link>test\e_reindex.test</Link> |
</None> |
<None Include="..\test\e_resolve.test"> |
<Link>test\e_resolve.test</Link> |
</None> |
<None Include="..\test\e_select.test"> |
<Link>test\e_select.test</Link> |
</None> |
<None Include="..\test\e_select2.test"> |
<Link>test\e_select2.test</Link> |
</None> |
<None Include="..\test\e_update.test"> |
<Link>test\e_update.test</Link> |
</None> |
<None Include="..\test\e_uri.test"> |
<Link>test\e_uri.test</Link> |
</None> |
<None Include="..\test\e_vacuum.test"> |
<Link>test\e_vacuum.test</Link> |
</None> |
<None Include="..\test\filectrl.test"> |
<Link>test\filectrl.test</Link> |
</None> |
<None Include="..\test\filefmt.test"> |
<Link>test\filefmt.test</Link> |
</None> |
<None Include="..\test\fkey1.test"> |
<Link>test\fkey1.test</Link> |
</None> |
<None Include="..\test\fkey2.test"> |
<Link>test\fkey2.test</Link> |
</None> |
<None Include="..\test\fkey3.test"> |
<Link>test\fkey3.test</Link> |
</None> |
<None Include="..\test\fkey4.test"> |
<Link>test\fkey4.test</Link> |
</None> |
<None Include="..\test\format4.test"> |
<Link>test\format4.test</Link> |
</None> |
<None Include="..\test\func.test"> |
<Link>test\func.test</Link> |
</None> |
<None Include="..\test\func2.test"> |
<Link>test\func2.test</Link> |
</None> |
<None Include="..\test\func3.test"> |
<Link>test\func3.test</Link> |
</None> |
<None Include="..\test\fuzz.test"> |
<Link>test\fuzz.test</Link> |
</None> |
<None Include="..\test\fuzz2.test"> |
<Link>test\fuzz2.test</Link> |
</None> |
<None Include="..\test\fuzz3.test"> |
<Link>test\fuzz3.test</Link> |
</None> |
<None Include="..\test\fuzzer1.test"> |
<Link>test\fuzzer1.test</Link> |
</None> |
<None Include="..\test\fuzz_common.tcl"> |
<Link>test\fuzz_common.tcl</Link> |
</None> |
<None Include="..\test\hook.test"> |
<Link>test\hook.test</Link> |
</None> |
<None Include="..\test\icu.test"> |
<Link>test\icu.test</Link> |
</None> |
<None Include="..\test\in.test"> |
<Link>test\in.test</Link> |
</None> |
<None Include="..\test\in2.test"> |
<Link>test\in2.test</Link> |
</None> |
<None Include="..\test\in3.test"> |
<Link>test\in3.test</Link> |
</None> |
<None Include="..\test\in4.test"> |
<Link>test\in4.test</Link> |
</None> |
<None Include="..\test\incrblob.test"> |
<Link>test\incrblob.test</Link> |
</None> |
<None Include="..\test\incrblob2.test"> |
<Link>test\incrblob2.test</Link> |
</None> |
<None Include="..\test\incrblob3.test"> |
<Link>test\incrblob3.test</Link> |
</None> |
<None Include="..\test\incrvacuum.test"> |
<Link>test\incrvacuum.test</Link> |
</None> |
<None Include="..\test\incrvacuum2.test"> |
<Link>test\incrvacuum2.test</Link> |
</None> |
<None Include="..\test\index.test"> |
<Link>test\index.test</Link> |
</None> |
<None Include="..\test\index2.test"> |
<Link>test\index2.test</Link> |
</None> |
<None Include="..\test\index3.test"> |
<Link>test\index3.test</Link> |
</None> |
<None Include="..\test\indexedby.test"> |
<Link>test\indexedby.test</Link> |
</None> |
<None Include="..\test\init.test"> |
<Link>test\init.test</Link> |
</None> |
<None Include="..\test\insert.test"> |
<Link>test\insert.test</Link> |
</None> |
<None Include="..\test\insert2.test"> |
<Link>test\insert2.test</Link> |
</None> |
<None Include="..\test\insert3.test"> |
<Link>test\insert3.test</Link> |
</None> |
<None Include="..\test\insert4.test"> |
<Link>test\insert4.test</Link> |
</None> |
<None Include="..\test\insert5.test"> |
<Link>test\insert5.test</Link> |
</None> |
<None Include="..\test\intarray.test"> |
<Link>test\intarray.test</Link> |
</None> |
<None Include="..\test\interrupt.test"> |
<Link>test\interrupt.test</Link> |
</None> |
<None Include="..\test\intpkey.test"> |
<Link>test\intpkey.test</Link> |
</None> |
<None Include="..\test\join.test"> |
<Link>test\join.test</Link> |
</None> |
<None Include="..\test\join2.test"> |
<Link>test\join2.test</Link> |
</None> |
<None Include="..\test\join3.test"> |
<Link>test\join3.test</Link> |
</None> |
<None Include="..\test\join4.test"> |
<Link>test\join4.test</Link> |
</None> |
<None Include="..\test\join5.test"> |
<Link>test\join5.test</Link> |
</None> |
<None Include="..\test\join6.test"> |
<Link>test\join6.test</Link> |
</None> |
<None Include="..\test\journal1.test"> |
<Link>test\journal1.test</Link> |
</None> |
<None Include="..\test\journal2.test"> |
<Link>test\journal2.test</Link> |
</None> |
<None Include="..\test\journal3.test"> |
<Link>test\journal3.test</Link> |
</None> |
<None Include="..\test\jrnlmode.test"> |
<Link>test\jrnlmode.test</Link> |
</None> |
<None Include="..\test\jrnlmode2.test"> |
<Link>test\jrnlmode2.test</Link> |
</None> |
<None Include="..\test\jrnlmode3.test"> |
<Link>test\jrnlmode3.test</Link> |
</None> |
<None Include="..\test\keyword1.test"> |
<Link>test\keyword1.test</Link> |
</None> |
<None Include="..\test\lastinsert.test"> |
<Link>test\lastinsert.test</Link> |
</None> |
<None Include="..\test\laststmtchanges.test"> |
<Link>test\laststmtchanges.test</Link> |
</None> |
<None Include="..\test\like.test"> |
<Link>test\like.test</Link> |
</None> |
<None Include="..\test\like2.test"> |
<Link>test\like2.test</Link> |
</None> |
<None Include="..\test\limit.test"> |
<Link>test\limit.test</Link> |
</None> |
<None Include="..\test\loadext.test"> |
<Link>test\loadext.test</Link> |
</None> |
<None Include="..\test\loadext2.test"> |
<Link>test\loadext2.test</Link> |
</None> |
<None Include="..\test\lock.test"> |
<Link>test\lock.test</Link> |
</None> |
<None Include="..\test\lock5.test"> |
<Link>test\lock5.test</Link> |
</None> |
<None Include="..\test\lock6.test"> |
<Link>test\lock6.test</Link> |
</None> |
<None Include="..\test\lock7.test"> |
<Link>test\lock7.test</Link> |
</None> |
<None Include="..\test\lock_common.tcl"> |
<Link>test\lock_common.tcl</Link> |
</None> |
<None Include="..\test\lookaside.test"> |
<Link>test\lookaside.test</Link> |
</None> |
<None Include="..\test\main.test"> |
<Link>test\main.test</Link> |
</None> |
<None Include="..\test\make-where7.tcl"> |
<Link>test\make-where7.tcl</Link> |
</None> |
<None Include="..\test\malloc_common.tcl"> |
<Link>test\malloc_common.tcl</Link> |
</None> |
<None Include="..\test\manydb.test"> |
<Link>test\manydb.test</Link> |
</None> |
<None Include="..\test\mem5.test"> |
<Link>test\mem5.test</Link> |
</None> |
<None Include="..\test\memdb.test"> |
<Link>test\memdb.test</Link> |
</None> |
<None Include="..\test\memleak.test"> |
<Link>test\memleak.test</Link> |
</None> |
<None Include="..\test\memsubsys1.test"> |
<Link>test\memsubsys1.test</Link> |
</None> |
<None Include="..\test\minmax.test"> |
<Link>test\minmax.test</Link> |
</None> |
<None Include="..\test\minmax2.test"> |
<Link>test\minmax2.test</Link> |
</None> |
<None Include="..\test\minmax3.test"> |
<Link>test\minmax3.test</Link> |
</None> |
<None Include="..\test\misc1.test"> |
<Link>test\misc1.test</Link> |
</None> |
<None Include="..\test\misc2.test"> |
<Link>test\misc2.test</Link> |
</None> |
<None Include="..\test\misc3.test"> |
<Link>test\misc3.test</Link> |
</None> |
<None Include="..\test\misc4.test"> |
<Link>test\misc4.test</Link> |
</None> |
<None Include="..\test\misc5.test"> |
<Link>test\misc5.test</Link> |
</None> |
<None Include="..\test\misc6.test"> |
<Link>test\misc6.test</Link> |
</None> |
<None Include="..\test\misc7.test"> |
<Link>test\misc7.test</Link> |
</None> |
<None Include="..\test\misuse.test"> |
<Link>test\misuse.test</Link> |
</None> |
<None Include="..\test\mutex1.test"> |
<Link>test\mutex1.test</Link> |
</None> |
<None Include="..\test\mutex2.test"> |
<Link>test\mutex2.test</Link> |
</None> |
<None Include="..\test\nan.test"> |
<Link>test\nan.test</Link> |
</None> |
<None Include="..\test\notify1.test"> |
<Link>test\notify1.test</Link> |
</None> |
<None Include="..\test\notify2.test"> |
<Link>test\notify2.test</Link> |
</None> |
<None Include="..\test\notify3.test"> |
<Link>test\notify3.test</Link> |
</None> |
<None Include="..\test\notnull.test"> |
<Link>test\notnull.test</Link> |
</None> |
<None Include="..\test\null.test"> |
<Link>test\null.test</Link> |
</None> |
<None Include="..\test\openv2.test"> |
<Link>test\openv2.test</Link> |
</None> |
<None Include="..\test\pager1.test"> |
<Link>test\pager1.test</Link> |
</None> |
<None Include="..\test\pager2.test"> |
<Link>test\pager2.test</Link> |
</None> |
<None Include="..\test\pager3.test"> |
<Link>test\pager3.test</Link> |
</None> |
<None Include="..\test\pageropt.test"> |
<Link>test\pageropt.test</Link> |
</None> |
<None Include="..\test\pagesize.test"> |
<Link>test\pagesize.test</Link> |
</None> |
<None Include="..\test\pcache.test"> |
<Link>test\pcache.test</Link> |
</None> |
<None Include="..\test\pcache2.test"> |
<Link>test\pcache2.test</Link> |
</None> |
<None Include="..\test\permutations.test"> |
<Link>test\permutations.test</Link> |
</None> |
<None Include="..\test\pragma.test"> |
<Link>test\pragma.test</Link> |
</None> |
<None Include="..\test\pragma2.test"> |
<Link>test\pragma2.test</Link> |
</None> |
<None Include="..\test\printf.test"> |
<Link>test\printf.test</Link> |
</None> |
<None Include="..\test\progress.test"> |
<Link>test\progress.test</Link> |
</None> |
<None Include="..\test\ptrchng.test"> |
<Link>test\ptrchng.test</Link> |
</None> |
<None Include="..\test\quota.test"> |
<Link>test\quota.test</Link> |
</None> |
<None Include="..\test\quote.test"> |
<Link>test\quote.test</Link> |
</None> |
<None Include="..\test\randexpr1.tcl"> |
<Link>test\randexpr1.tcl</Link> |
</None> |
<None Include="..\test\randexpr1.test"> |
<Link>test\randexpr1.test</Link> |
</None> |
<None Include="..\test\rdonly.test"> |
<Link>test\rdonly.test</Link> |
</None> |
<None Include="..\test\reindex.test"> |
<Link>test\reindex.test</Link> |
</None> |
<None Include="..\test\rollback.test"> |
<Link>test\rollback.test</Link> |
</None> |
<None Include="..\test\rowhash.test"> |
<Link>test\rowhash.test</Link> |
</None> |
<None Include="..\test\rowid.test"> |
<Link>test\rowid.test</Link> |
</None> |
<None Include="..\test\savepoint.test"> |
<Link>test\savepoint.test</Link> |
</None> |
<None Include="..\test\savepoint2.test"> |
<Link>test\savepoint2.test</Link> |
</None> |
<None Include="..\test\savepoint3.test"> |
<Link>test\savepoint3.test</Link> |
</None> |
<None Include="..\test\savepoint4.test"> |
<Link>test\savepoint4.test</Link> |
</None> |
<None Include="..\test\savepoint5.test"> |
<Link>test\savepoint5.test</Link> |
</None> |
<None Include="..\test\savepoint6.test"> |
<Link>test\savepoint6.test</Link> |
</None> |
<None Include="..\test\schema.test"> |
<Link>test\schema.test</Link> |
</None> |
<None Include="..\test\schema2.test"> |
<Link>test\schema2.test</Link> |
</None> |
<None Include="..\test\schema3.test"> |
<Link>test\schema3.test</Link> |
</None> |
<None Include="..\test\schema4.test"> |
<Link>test\schema4.test</Link> |
</None> |
<None Include="..\test\securedel.test"> |
<Link>test\securedel.test</Link> |
</None> |
<None Include="..\test\select1.test"> |
<Link>test\select1.test</Link> |
</None> |
<None Include="..\test\select2.test"> |
<Link>test\select2.test</Link> |
</None> |
<None Include="..\test\select3.test"> |
<Link>test\select3.test</Link> |
</None> |
<None Include="..\test\select4.test"> |
<Link>test\select4.test</Link> |
</None> |
<None Include="..\test\select5.test"> |
<Link>test\select5.test</Link> |
</None> |
<None Include="..\test\select6.test"> |
<Link>test\select6.test</Link> |
</None> |
<None Include="..\test\select7.test"> |
<Link>test\select7.test</Link> |
</None> |
<None Include="..\test\select8.test"> |
<Link>test\select8.test</Link> |
</None> |
<None Include="..\test\select9.test"> |
<Link>test\select9.test</Link> |
</None> |
<None Include="..\test\selectA.test"> |
<Link>test\selectA.test</Link> |
</None> |
<None Include="..\test\selectB.test"> |
<Link>test\selectB.test</Link> |
</None> |
<None Include="..\test\selectC.test"> |
<Link>test\selectC.test</Link> |
</None> |
<None Include="..\test\server1.test"> |
<Link>test\server1.test</Link> |
</None> |
<None Include="..\test\shared.test"> |
<Link>test\shared.test</Link> |
</None> |
<None Include="..\test\shared2.test"> |
<Link>test\shared2.test</Link> |
</None> |
<None Include="..\test\shared3.test"> |
<Link>test\shared3.test</Link> |
</None> |
<None Include="..\test\shared4.test"> |
<Link>test\shared4.test</Link> |
</None> |
<None Include="..\test\shared6.test"> |
<Link>test\shared6.test</Link> |
</None> |
<None Include="..\test\shared7.test"> |
<Link>test\shared7.test</Link> |
</None> |
<None Include="..\test\sharedlock.test"> |
<Link>test\sharedlock.test</Link> |
</None> |
<None Include="..\test\shared_err.test"> |
<Link>test\shared_err.test</Link> |
</None> |
<None Include="..\test\shortread1.test"> |
<Link>test\shortread1.test</Link> |
</None> |
<None Include="..\test\sidedelete.test"> |
<Link>test\sidedelete.test</Link> |
</None> |
<None Include="..\test\soak.test"> |
<Link>test\soak.test</Link> |
</None> |
<None Include="..\test\softheap1.test"> |
<Link>test\softheap1.test</Link> |
</None> |
<None Include="..\test\sort.test"> |
<Link>test\sort.test</Link> |
</None> |
<None Include="..\test\speed1.test"> |
<Link>test\speed1.test</Link> |
</None> |
<None Include="..\test\speed1p.explain"> |
<Link>test\speed1p.explain</Link> |
</None> |
<None Include="..\test\speed1p.test"> |
<Link>test\speed1p.test</Link> |
</None> |
<None Include="..\test\speed2.test"> |
<Link>test\speed2.test</Link> |
</None> |
<None Include="..\test\speed3.test"> |
<Link>test\speed3.test</Link> |
</None> |
<None Include="..\test\speed4.test"> |
<Link>test\speed4.test</Link> |
</None> |
<None Include="..\test\speed4p.explain"> |
<Link>test\speed4p.explain</Link> |
</None> |
<None Include="..\test\speed4p.test"> |
<Link>test\speed4p.test</Link> |
</None> |
<None Include="..\test\sqllimits1.test"> |
<Link>test\sqllimits1.test</Link> |
</None> |
<None Include="..\test\stat.test"> |
<Link>test\stat.test</Link> |
</None> |
<None Include="..\test\stmt.test"> |
<Link>test\stmt.test</Link> |
</None> |
<None Include="..\test\subquery.test"> |
<Link>test\subquery.test</Link> |
</None> |
<None Include="..\test\subselect.test"> |
<Link>test\subselect.test</Link> |
</None> |
<None Include="..\test\substr.test"> |
<Link>test\substr.test</Link> |
</None> |
<None Include="..\test\sync.test"> |
<Link>test\sync.test</Link> |
</None> |
<None Include="..\test\table.test"> |
<Link>test\table.test</Link> |
</None> |
<None Include="..\test\tableapi.test"> |
<Link>test\tableapi.test</Link> |
</None> |
<None Include="..\test\tempdb.test"> |
<Link>test\tempdb.test</Link> |
</None> |
<None Include="..\test\temptable.test"> |
<Link>test\temptable.test</Link> |
</None> |
<None Include="..\test\temptrigger.test"> |
<Link>test\temptrigger.test</Link> |
</None> |
<None Include="..\test\tester.tcl"> |
<Link>test\tester.tcl</Link> |
</None> |
<None Include="..\test\thread_common.tcl"> |
<Link>test\thread_common.tcl</Link> |
</None> |
<None Include="..\test\tkt-02a8e81d44.test"> |
<Link>test\tkt-02a8e81d44.test</Link> |
</None> |
<None Include="..\test\tkt-26ff0c2d1e.test"> |
<Link>test\tkt-26ff0c2d1e.test</Link> |
</None> |
<None Include="..\test\tkt-2d1a5c67d.test"> |
<Link>test\tkt-2d1a5c67d.test</Link> |
</None> |
<None Include="..\test\tkt-2ea2425d34.test"> |
<Link>test\tkt-2ea2425d34.test</Link> |
</None> |
<None Include="..\test\tkt-31338dca7e.test"> |
<Link>test\tkt-31338dca7e.test</Link> |
</None> |
<None Include="..\test\tkt-313723c356.test"> |
<Link>test\tkt-313723c356.test</Link> |
</None> |
<None Include="..\test\tkt-38cb5df375.test"> |
<Link>test\tkt-38cb5df375.test</Link> |
</None> |
<None Include="..\test\tkt-3998683a16.test"> |
<Link>test\tkt-3998683a16.test</Link> |
</None> |
<None Include="..\test\tkt-3fe897352e.test"> |
<Link>test\tkt-3fe897352e.test</Link> |
</None> |
<None Include="..\test\tkt-4a03edc4c8.test"> |
<Link>test\tkt-4a03edc4c8.test</Link> |
</None> |
<None Include="..\test\tkt-5d863f876e.test"> |
<Link>test\tkt-5d863f876e.test</Link> |
</None> |
<None Include="..\test\tkt-5e10420e8d.test"> |
<Link>test\tkt-5e10420e8d.test</Link> |
</None> |
<None Include="..\test\tkt-5ee23731f.test"> |
<Link>test\tkt-5ee23731f.test</Link> |
</None> |
<None Include="..\test\tkt-752e1646fc.test"> |
<Link>test\tkt-752e1646fc.test</Link> |
</None> |
<None Include="..\test\tkt-78e04e52ea.test"> |
<Link>test\tkt-78e04e52ea.test</Link> |
</None> |
<None Include="..\test\tkt-80ba201079.test"> |
<Link>test\tkt-80ba201079.test</Link> |
</None> |
<None Include="..\test\tkt-80e031a00f.test"> |
<Link>test\tkt-80e031a00f.test</Link> |
</None> |
<None Include="..\test\tkt-8454a207b9.test"> |
<Link>test\tkt-8454a207b9.test</Link> |
</None> |
<None Include="..\test\tkt-94c04eaadb.test"> |
<Link>test\tkt-94c04eaadb.test</Link> |
</None> |
<None Include="..\test\tkt-9d68c883.test"> |
<Link>test\tkt-9d68c883.test</Link> |
</None> |
<None Include="..\test\tkt-b351d95f9.test"> |
<Link>test\tkt-b351d95f9.test</Link> |
</None> |
<None Include="..\test\tkt-b72787b1.test"> |
<Link>test\tkt-b72787b1.test</Link> |
</None> |
<None Include="..\test\tkt-cbd054fa6b.test"> |
<Link>test\tkt-cbd054fa6b.test</Link> |
</None> |
<None Include="..\test\tkt-d11f09d36e.test"> |
<Link>test\tkt-d11f09d36e.test</Link> |
</None> |
<None Include="..\test\tkt-d82e3f3721.test"> |
<Link>test\tkt-d82e3f3721.test</Link> |
</None> |
<None Include="..\test\tkt-f3e5abed55.test"> |
<Link>test\tkt-f3e5abed55.test</Link> |
</None> |
<None Include="..\test\tkt-f777251dc7a.test"> |
<Link>test\tkt-f777251dc7a.test</Link> |
</None> |
<None Include="..\test\tkt-f7b4edec.test"> |
<Link>test\tkt-f7b4edec.test</Link> |
</None> |
<None Include="..\test\tkt-f973c7ac31.test"> |
<Link>test\tkt-f973c7ac31.test</Link> |
</None> |
<None Include="..\test\tkt-fc62af4523.test"> |
<Link>test\tkt-fc62af4523.test</Link> |
</None> |
<None Include="..\test\tkt1435.test"> |
<Link>test\tkt1435.test</Link> |
</None> |
<None Include="..\test\tkt1443.test"> |
<Link>test\tkt1443.test</Link> |
</None> |
<None Include="..\test\tkt1444.test"> |
<Link>test\tkt1444.test</Link> |
</None> |
<None Include="..\test\tkt1449.test"> |
<Link>test\tkt1449.test</Link> |
</None> |
<None Include="..\test\tkt1473.test"> |
<Link>test\tkt1473.test</Link> |
</None> |
<None Include="..\test\tkt1501.test"> |
<Link>test\tkt1501.test</Link> |
</None> |
<None Include="..\test\tkt1512.test"> |
<Link>test\tkt1512.test</Link> |
</None> |
<None Include="..\test\tkt1514.test"> |
<Link>test\tkt1514.test</Link> |
</None> |
<None Include="..\test\tkt1536.test"> |
<Link>test\tkt1536.test</Link> |
</None> |
<None Include="..\test\tkt1537.test"> |
<Link>test\tkt1537.test</Link> |
</None> |
<None Include="..\test\tkt1567.test"> |
<Link>test\tkt1567.test</Link> |
</None> |
<None Include="..\test\tkt1644.test"> |
<Link>test\tkt1644.test</Link> |
</None> |
<None Include="..\test\tkt1667.test"> |
<Link>test\tkt1667.test</Link> |
</None> |
<None Include="..\test\tkt1873.test"> |
<Link>test\tkt1873.test</Link> |
</None> |
<None Include="..\test\tkt2141.test"> |
<Link>test\tkt2141.test</Link> |
</None> |
<None Include="..\test\tkt2192.test"> |
<Link>test\tkt2192.test</Link> |
</None> |
<None Include="..\test\tkt2213.test"> |
<Link>test\tkt2213.test</Link> |
</None> |
<None Include="..\test\tkt2251.test"> |
<Link>test\tkt2251.test</Link> |
</None> |
<None Include="..\test\tkt2285.test"> |
<Link>test\tkt2285.test</Link> |
</None> |
<None Include="..\test\tkt2332.test"> |
<Link>test\tkt2332.test</Link> |
</None> |
<None Include="..\test\tkt2339.test"> |
<Link>test\tkt2339.test</Link> |
</None> |
<None Include="..\test\tkt2391.test"> |
<Link>test\tkt2391.test</Link> |
</None> |
<None Include="..\test\tkt2409.test"> |
<Link>test\tkt2409.test</Link> |
</None> |
<None Include="..\test\tkt2450.test"> |
<Link>test\tkt2450.test</Link> |
</None> |
<None Include="..\test\tkt2565.test"> |
<Link>test\tkt2565.test</Link> |
</None> |
<None Include="..\test\tkt2640.test"> |
<Link>test\tkt2640.test</Link> |
</None> |
<None Include="..\test\tkt2643.test"> |
<Link>test\tkt2643.test</Link> |
</None> |
<None Include="..\test\tkt2686.test"> |
<Link>test\tkt2686.test</Link> |
</None> |
<None Include="..\test\tkt2767.test"> |
<Link>test\tkt2767.test</Link> |
</None> |
<None Include="..\test\tkt2817.test"> |
<Link>test\tkt2817.test</Link> |
</None> |
<None Include="..\test\tkt2820.test"> |
<Link>test\tkt2820.test</Link> |
</None> |
<None Include="..\test\tkt2822.test"> |
<Link>test\tkt2822.test</Link> |
</None> |
<None Include="..\test\tkt2832.test"> |
<Link>test\tkt2832.test</Link> |
</None> |
<None Include="..\test\tkt2854.test"> |
<Link>test\tkt2854.test</Link> |
</None> |
<None Include="..\test\tkt2920.test"> |
<Link>test\tkt2920.test</Link> |
</None> |
<None Include="..\test\tkt2927.test"> |
<Link>test\tkt2927.test</Link> |
</None> |
<None Include="..\test\tkt2942.test"> |
<Link>test\tkt2942.test</Link> |
</None> |
<None Include="..\test\tkt3080.test"> |
<Link>test\tkt3080.test</Link> |
</None> |
<None Include="..\test\tkt3093.test"> |
<Link>test\tkt3093.test</Link> |
</None> |
<None Include="..\test\tkt3121.test"> |
<Link>test\tkt3121.test</Link> |
</None> |
<None Include="..\test\tkt3201.test"> |
<Link>test\tkt3201.test</Link> |
</None> |
<None Include="..\test\tkt3292.test"> |
<Link>test\tkt3292.test</Link> |
</None> |
<None Include="..\test\tkt3298.test"> |
<Link>test\tkt3298.test</Link> |
</None> |
<None Include="..\test\tkt3334.test"> |
<Link>test\tkt3334.test</Link> |
</None> |
<None Include="..\test\tkt3346.test"> |
<Link>test\tkt3346.test</Link> |
</None> |
<None Include="..\test\tkt3357.test"> |
<Link>test\tkt3357.test</Link> |
</None> |
<None Include="..\test\tkt3419.test"> |
<Link>test\tkt3419.test</Link> |
</None> |
<None Include="..\test\tkt3424.test"> |
<Link>test\tkt3424.test</Link> |
</None> |
<None Include="..\test\tkt3442.test"> |
<Link>test\tkt3442.test</Link> |
</None> |
<None Include="..\test\tkt3457.test"> |
<Link>test\tkt3457.test</Link> |
</None> |
<None Include="..\test\tkt3461.test"> |
<Link>test\tkt3461.test</Link> |
</None> |
<None Include="..\test\tkt3493.test"> |
<Link>test\tkt3493.test</Link> |
</None> |
<None Include="..\test\tkt3508.test"> |
<Link>test\tkt3508.test</Link> |
</None> |
<None Include="..\test\tkt3522.test"> |
<Link>test\tkt3522.test</Link> |
</None> |
<None Include="..\test\tkt3527.test"> |
<Link>test\tkt3527.test</Link> |
</None> |
<None Include="..\test\tkt3541.test"> |
<Link>test\tkt3541.test</Link> |
</None> |
<None Include="..\test\tkt3554.test"> |
<Link>test\tkt3554.test</Link> |
</None> |
<None Include="..\test\tkt3581.test"> |
<Link>test\tkt3581.test</Link> |
</None> |
<None Include="..\test\tkt35xx.test"> |
<Link>test\tkt35xx.test</Link> |
</None> |
<None Include="..\test\tkt3630.test"> |
<Link>test\tkt3630.test</Link> |
</None> |
<None Include="..\test\tkt3718.test"> |
<Link>test\tkt3718.test</Link> |
</None> |
<None Include="..\test\tkt3731.test"> |
<Link>test\tkt3731.test</Link> |
</None> |
<None Include="..\test\tkt3757.test"> |
<Link>test\tkt3757.test</Link> |
</None> |
<None Include="..\test\tkt3761.test"> |
<Link>test\tkt3761.test</Link> |
</None> |
<None Include="..\test\tkt3762.test"> |
<Link>test\tkt3762.test</Link> |
</None> |
<None Include="..\test\tkt3773.test"> |
<Link>test\tkt3773.test</Link> |
</None> |
<None Include="..\test\tkt3791.test"> |
<Link>test\tkt3791.test</Link> |
</None> |
<None Include="..\test\tkt3793.test"> |
<Link>test\tkt3793.test</Link> |
</None> |
<None Include="..\test\tkt3810.test"> |
<Link>test\tkt3810.test</Link> |
</None> |
<None Include="..\test\tkt3824.test"> |
<Link>test\tkt3824.test</Link> |
</None> |
<None Include="..\test\tkt3832.test"> |
<Link>test\tkt3832.test</Link> |
</None> |
<None Include="..\test\tkt3838.test"> |
<Link>test\tkt3838.test</Link> |
</None> |
<None Include="..\test\tkt3841.test"> |
<Link>test\tkt3841.test</Link> |
</None> |
<None Include="..\test\tkt3871.test"> |
<Link>test\tkt3871.test</Link> |
</None> |
<None Include="..\test\tkt3879.test"> |
<Link>test\tkt3879.test</Link> |
</None> |
<None Include="..\test\tkt3911.test"> |
<Link>test\tkt3911.test</Link> |
</None> |
<None Include="..\test\tkt3918.test"> |
<Link>test\tkt3918.test</Link> |
</None> |
<None Include="..\test\tkt3922.test"> |
<Link>test\tkt3922.test</Link> |
</None> |
<None Include="..\test\tkt3929.test"> |
<Link>test\tkt3929.test</Link> |
</None> |
<None Include="..\test\tkt3935.test"> |
<Link>test\tkt3935.test</Link> |
</None> |
<None Include="..\test\tkt3992.test"> |
<Link>test\tkt3992.test</Link> |
</None> |
<None Include="..\test\tkt3997.test"> |
<Link>test\tkt3997.test</Link> |
</None> |
<None Include="..\test\tkt4018.test"> |
<Link>test\tkt4018.test</Link> |
</None> |
<None Include="..\test\tokenize.test"> |
<Link>test\tokenize.test</Link> |
</None> |
<None Include="..\test\trace.test"> |
<Link>test\trace.test</Link> |
</None> |
<None Include="..\test\trace2.test"> |
<Link>test\trace2.test</Link> |
</None> |
<None Include="..\test\trans.test"> |
<Link>test\trans.test</Link> |
</None> |
<None Include="..\test\trans2.test"> |
<Link>test\trans2.test</Link> |
</None> |
<None Include="..\test\trans3.test"> |
<Link>test\trans3.test</Link> |
</None> |
<None Include="..\test\trigger1.test"> |
<Link>test\trigger1.test</Link> |
</None> |
<None Include="..\test\trigger2.test"> |
<Link>test\trigger2.test</Link> |
</None> |
<None Include="..\test\trigger3.test"> |
<Link>test\trigger3.test</Link> |
</None> |
<None Include="..\test\trigger4.test"> |
<Link>test\trigger4.test</Link> |
</None> |
<None Include="..\test\trigger5.test"> |
<Link>test\trigger5.test</Link> |
</None> |
<None Include="..\test\trigger6.test"> |
<Link>test\trigger6.test</Link> |
</None> |
<None Include="..\test\trigger7.test"> |
<Link>test\trigger7.test</Link> |
</None> |
<None Include="..\test\trigger8.test"> |
<Link>test\trigger8.test</Link> |
</None> |
<None Include="..\test\trigger9.test"> |
<Link>test\trigger9.test</Link> |
</None> |
<None Include="..\test\triggerA.test"> |
<Link>test\triggerA.test</Link> |
</None> |
<None Include="..\test\triggerB.test"> |
<Link>test\triggerB.test</Link> |
</None> |
<None Include="..\test\triggerC.test"> |
<Link>test\triggerC.test</Link> |
</None> |
<None Include="..\test\triggerD.test"> |
<Link>test\triggerD.test</Link> |
</None> |
<None Include="..\test\types.test"> |
<Link>test\types.test</Link> |
</None> |
<None Include="..\test\types2.test"> |
<Link>test\types2.test</Link> |
</None> |
<None Include="..\test\types3.test"> |
<Link>test\types3.test</Link> |
</None> |
<None Include="..\test\unique.test"> |
<Link>test\unique.test</Link> |
</None> |
<None Include="..\test\unordered.test"> |
<Link>test\unordered.test</Link> |
</None> |
<None Include="..\test\update.test"> |
<Link>test\update.test</Link> |
</None> |
<None Include="..\test\uri.test"> |
<Link>test\uri.test</Link> |
</None> |
<None Include="..\test\utf16align.test"> |
<Link>test\utf16align.test</Link> |
</None> |
<None Include="..\test\vacuum.test"> |
<Link>test\vacuum.test</Link> |
</None> |
<None Include="..\test\vacuum2.test"> |
<Link>test\vacuum2.test</Link> |
</None> |
<None Include="..\test\vacuum3.test"> |
<Link>test\vacuum3.test</Link> |
</None> |
<None Include="..\test\vacuum4.test"> |
<Link>test\vacuum4.test</Link> |
</None> |
<None Include="..\test\varint.test"> |
<Link>test\varint.test</Link> |
</None> |
<None Include="..\test\view.test"> |
<Link>test\view.test</Link> |
</None> |
<None Include="..\test\vtab1.test"> |
<Link>test\vtab1.test</Link> |
</None> |
<None Include="..\test\vtab2.test"> |
<Link>test\vtab2.test</Link> |
</None> |
<None Include="..\test\vtab3.test"> |
<Link>test\vtab3.test</Link> |
</None> |
<None Include="..\test\vtab4.test"> |
<Link>test\vtab4.test</Link> |
</None> |
<None Include="..\test\vtab5.test"> |
<Link>test\vtab5.test</Link> |
</None> |
<None Include="..\test\vtab6.test"> |
<Link>test\vtab6.test</Link> |
</None> |
<None Include="..\test\vtab7.test"> |
<Link>test\vtab7.test</Link> |
</None> |
<None Include="..\test\vtab8.test"> |
<Link>test\vtab8.test</Link> |
</None> |
<None Include="..\test\vtab9.test"> |
<Link>test\vtab9.test</Link> |
</None> |
<None Include="..\test\vtabA.test"> |
<Link>test\vtabA.test</Link> |
</None> |
<None Include="..\test\vtabB.test"> |
<Link>test\vtabB.test</Link> |
</None> |
<None Include="..\test\vtabC.test"> |
<Link>test\vtabC.test</Link> |
</None> |
<None Include="..\test\vtabD.test"> |
<Link>test\vtabD.test</Link> |
</None> |
<None Include="..\test\vtabE.test"> |
<Link>test\vtabE.test</Link> |
</None> |
<None Include="..\test\vtab_alter.test"> |
<Link>test\vtab_alter.test</Link> |
</None> |
<None Include="..\test\vtab_err.test"> |
<Link>test\vtab_err.test</Link> |
</None> |
<None Include="..\test\vtab_shared.test"> |
<Link>test\vtab_shared.test</Link> |
</None> |
<None Include="..\test\wal.test"> |
<Link>test\wal.test</Link> |
</None> |
<None Include="..\test\wal2.test"> |
<Link>test\wal2.test</Link> |
</None> |
<None Include="..\test\wal3.test"> |
<Link>test\wal3.test</Link> |
</None> |
<None Include="..\test\wal4.test"> |
<Link>test\wal4.test</Link> |
</None> |
<None Include="..\test\wal5.test"> |
<Link>test\wal5.test</Link> |
</None> |
<None Include="..\test\wal6.test"> |
<Link>test\wal6.test</Link> |
</None> |
<None Include="..\test\walbak.test"> |
<Link>test\walbak.test</Link> |
</None> |
<None Include="..\test\walbig.test"> |
<Link>test\walbig.test</Link> |
</None> |
<None Include="..\test\walcksum.test"> |
<Link>test\walcksum.test</Link> |
</None> |
<None Include="..\test\walcrash.test"> |
<Link>test\walcrash.test</Link> |
</None> |
<None Include="..\test\walcrash2.test"> |
<Link>test\walcrash2.test</Link> |
</None> |
<None Include="..\test\walfault.test"> |
<Link>test\walfault.test</Link> |
</None> |
<None Include="..\test\walhook.test"> |
<Link>test\walhook.test</Link> |
</None> |
<None Include="..\test\walmode.test"> |
<Link>test\walmode.test</Link> |
</None> |
<None Include="..\test\walnoshm.test"> |
<Link>test\walnoshm.test</Link> |
</None> |
<None Include="..\test\walshared.test"> |
<Link>test\walshared.test</Link> |
</None> |
<None Include="..\test\walslow.test"> |
<Link>test\walslow.test</Link> |
</None> |
<None Include="..\test\walthread.test"> |
<Link>test\walthread.test</Link> |
</None> |
<None Include="..\test\wal_common.tcl"> |
<Link>test\wal_common.tcl</Link> |
</None> |
<None Include="..\test\where.test"> |
<Link>test\where.test</Link> |
</None> |
<None Include="..\test\where2.test"> |
<Link>test\where2.test</Link> |
</None> |
<None Include="..\test\where3.test"> |
<Link>test\where3.test</Link> |
</None> |
<None Include="..\test\where4.test"> |
<Link>test\where4.test</Link> |
</None> |
<None Include="..\test\where5.test"> |
<Link>test\where5.test</Link> |
</None> |
<None Include="..\test\where6.test"> |
<Link>test\where6.test</Link> |
</None> |
<None Include="..\test\where7.test"> |
<Link>test\where7.test</Link> |
</None> |
<None Include="..\test\where8.test"> |
<Link>test\where8.test</Link> |
</None> |
<None Include="..\test\where8m.test"> |
<Link>test\where8m.test</Link> |
</None> |
<None Include="..\test\where9.test"> |
<Link>test\where9.test</Link> |
</None> |
<None Include="..\test\whereA.test"> |
<Link>test\whereA.test</Link> |
</None> |
<None Include="..\test\whereB.test"> |
<Link>test\whereB.test</Link> |
</None> |
<None Include="..\test\wherelimit.test"> |
<Link>test\wherelimit.test</Link> |
</None> |
<None Include="..\test\zeroblob.test"> |
<Link>test\zeroblob.test</Link> |
</None> |
<None Include="..\test\^testscripts.test"> |
<Link>test\^testscripts.test</Link> |
</None> |
<None Include="..\test\_C#SQLite.test"> |
<Link>test\_C#SQLite.test</Link> |
</None> |
<None Include="app.config" /> |
</ItemGroup> |
<ItemGroup> |
<BootstrapperPackage Include="Microsoft.Net.Client.3.5"> |
<Visible>False</Visible> |
<ProductName>.NET Framework Client Profile</ProductName> |
<Install>false</Install> |
</BootstrapperPackage> |
<BootstrapperPackage Include="Microsoft.Net.Framework.2.0"> |
<Visible>False</Visible> |
<ProductName>.NET Framework 2.0 %28x86%29</ProductName> |
<Install>false</Install> |
</BootstrapperPackage> |
<BootstrapperPackage Include="Microsoft.Net.Framework.3.0"> |
<Visible>False</Visible> |
<ProductName>.NET Framework 3.0 %28x86%29</ProductName> |
<Install>false</Install> |
</BootstrapperPackage> |
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5"> |
<Visible>False</Visible> |
<ProductName>.NET Framework 3.5</ProductName> |
<Install>false</Install> |
</BootstrapperPackage> |
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1"> |
<Visible>False</Visible> |
<ProductName>.NET Framework 3.5 SP1</ProductName> |
<Install>true</Install> |
</BootstrapperPackage> |
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1"> |
<Visible>False</Visible> |
<ProductName>Windows Installer 3.1</ProductName> |
<Install>true</Install> |
</BootstrapperPackage> |
</ItemGroup> |
<ItemGroup> |
<Content Include="..\test\crashtest1.c"> |
<Link>test\crashtest1.c</Link> |
</Content> |
</ItemGroup> |
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> |
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
Other similar extension points exist, see Microsoft.Common.targets. |
<Target Name="BeforeBuild"> |
</Target> |
<Target Name="AfterBuild"> |
</Target> |
--> |
<PropertyGroup> |
<PostBuildEvent>call "$(DevEnvDir)..\tools\vsvars32.bat" |
editbin /stack:4000000 “$(TargetPath)”</PostBuildEvent> |
</PropertyGroup> |
</Project> |