/testfixture/src/test1_c.cs
C# | 6843 lines | 4352 code | 479 blank | 2012 comment | 946 complexity | bf9b03885ff23f6ac2f249711e2306e7 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- 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;
- }
- i…
Large files files are truncated, but you can click here to view the full file