using System; using System.Diagnostics; namespace Community.CsharpSqlite { #if TCLSH using tcl.lang; using sqlite_int64 = System.Int64; using sqlite3_stmt = Sqlite3.Vdbe; using sqlite3_value = Sqlite3.Mem; using Tcl_Interp = tcl.lang.Interp; using Tcl_Obj = tcl.lang.TclObject; using ClientData = System.Object; public partial class Sqlite3 { /* ** 2006 June 13 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the virtual table interfaces. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** The emphasis of this file is a virtual table that provides ** access to TCL variables. */ //#include "sqliteInt.h" //#include "tcl.h" //#include //#include #if !SQLITE_OMIT_VIRTUALTABLE //typedef struct tclvar_vtab tclvar_vtab; //typedef struct tclvar_cursor tclvar_cursor; /* ** A tclvar virtual-table object */ class tclvar_vtab : sqlite3_vtab { //sqlite3_vtab base; public Tcl_Interp interp; }; /* A tclvar cursor object */ class tclvar_cursor : sqlite3_vtab_cursor { //sqlite3_vtab_cursor base; public Tcl_Obj pList1; /* Result of [info vars ?pattern?] */ public Tcl_Obj pList2; /* Result of [array names [lindex $pList1 $i1]] */ public int i1; /* Current item in pList1 */ public int i2; /* Current item (if any) in pList2 */ }; /* Methods for the tclvar module */ static int tclvarConnect( sqlite3 db, object pAux, int argc, string[] argv, out sqlite3_vtab ppVtab, out string pzErr ){ tclvar_vtab pVtab; string zSchema = "CREATE TABLE whatever(name TEXT, arrayname TEXT, value TEXT)"; pVtab = new tclvar_vtab();//sqlite3MallocZero( sizeof(*pVtab) ); //if( pVtab==0 ) return SQLITE_NOMEM; ppVtab = pVtab;//*ppVtab = pVtab.base; pVtab.interp = (Tcl_Interp)pAux; sqlite3_declare_vtab(db, zSchema); pzErr = ""; return SQLITE_OK; } /* Note that for this virtual table, the xCreate and xConnect ** methods are identical. */ static int tclvarDisconnect(ref object pVtab){ //sqlite3_free(pVtab); pVtab = null; return SQLITE_OK; } /* The xDisconnect and xDestroy methods are also the same */ /* ** Open a new tclvar cursor. */ static int tclvarOpen( sqlite3_vtab pVTab, out sqlite3_vtab_cursor ppCursor ) { //tclvar_cursor pCur; //pCur = sqlite3MallocZero(sizeof(tclvar_cursor)); //*ppCursor = pCur.base; ppCursor = new tclvar_cursor(); return SQLITE_OK; } /* ** Close a tclvar cursor. */ static int tclvarClose( ref sqlite3_vtab_cursor cur ) { tclvar_cursor pCur = (tclvar_cursor )cur; if( pCur.pList1 != null){ TCL.Tcl_DecrRefCount(ref pCur.pList1); } if( pCur.pList2 != null){ TCL.Tcl_DecrRefCount( ref pCur.pList2 ); } cur = null;//sqlite3_free(pCur); return SQLITE_OK; } /* ** Returns 1 if data is ready, or 0 if not. */ static int next2(Tcl_Interp interp, tclvar_cursor pCur, Tcl_Obj pObj){ Tcl_Obj p; if( pObj != null){ if( null==pCur.pList2 ){ p = TCL.Tcl_NewStringObj("array names", -1); TCL.Tcl_IncrRefCount(p); TCL.Tcl_ListObjAppendElement(null, p, pObj); TCL.Tcl_EvalObjEx(interp, p, TCL.TCL_EVAL_GLOBAL); TCL.Tcl_DecrRefCount(ref p); pCur.pList2 = TCL.Tcl_GetObjResult(interp); TCL.Tcl_IncrRefCount(pCur.pList2); Debug.Assert( pCur.i2 == 0 ); } else { int n = 0; pCur.i2++; TCL.Tcl_ListObjLength(null, pCur.pList2, out n); if( pCur.i2>=n ){ TCL.Tcl_DecrRefCount(ref pCur.pList2); pCur.pList2 = null; pCur.i2 = 0; return 0; } } } return 1; } static int tclvarNext(sqlite3_vtab_cursor cur){ Tcl_Obj pObj = null; int n = 0; int ok = 0; tclvar_cursor pCur = (tclvar_cursor )cur; Tcl_Interp interp = ((tclvar_vtab )(cur.pVtab)).interp; TCL.Tcl_ListObjLength( null, pCur.pList1, out n ); while( 0==ok && pCur.i1