wasCSharpSQLite – Blame information for rev

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Diagnostics;
3  
4  
5 namespace Community.CsharpSqlite
6 {
7 #if TCLSH
8 using tcl.lang;
9 using sqlite_int64 = System.Int64;
10 using sqlite3_stmt = Sqlite3.Vdbe;
11 using sqlite3_value = Sqlite3.Mem;
12 using Tcl_Interp = tcl.lang.Interp;
13 using Tcl_Obj = tcl.lang.TclObject;
14 using ClientData = System.Object;
15  
16 public partial class Sqlite3
17 {
18 /*
19 ** 2006 June 13
20 **
21 ** The author disclaims copyright to this source code. In place of
22 ** a legal notice, here is a blessing:
23 **
24 ** May you do good and not evil.
25 ** May you find forgiveness for yourself and forgive others.
26 ** May you share freely, never taking more than you give.
27 **
28 *************************************************************************
29 ** Code for testing the virtual table interfaces. This code
30 ** is not included in the SQLite library. It is used for automated
31 ** testing of the SQLite library.
32 **
33 ** The emphasis of this file is a virtual table that provides
34 ** access to TCL variables.
35 */
36 //#include "sqliteInt.h"
37 //#include "tcl.h"
38 //#include <stdlib.h>
39 //#include <string.h>
40  
41 #if !SQLITE_OMIT_VIRTUALTABLE
42  
43 //typedef struct tclvar_vtab tclvar_vtab;
44 //typedef struct tclvar_cursor tclvar_cursor;
45  
46 /*
47 ** A tclvar virtual-table object
48 */
49 class tclvar_vtab : sqlite3_vtab {
50 //sqlite3_vtab base;
51 public Tcl_Interp interp;
52 };
53  
54 /* A tclvar cursor object */
55 class tclvar_cursor : sqlite3_vtab_cursor {
56 //sqlite3_vtab_cursor base;
57  
58 public Tcl_Obj pList1; /* Result of [info vars ?pattern?] */
59 public Tcl_Obj pList2; /* Result of [array names [lindex $pList1 $i1]] */
60 public int i1; /* Current item in pList1 */
61 public int i2; /* Current item (if any) in pList2 */
62 };
63  
64 /* Methods for the tclvar module */
65 static int tclvarConnect(
66 sqlite3 db,
67 object pAux,
68 int argc,
69 string[] argv,
70 out sqlite3_vtab ppVtab,
71 out string pzErr
72 ){
73 tclvar_vtab pVtab;
74 string zSchema =
75 "CREATE TABLE whatever(name TEXT, arrayname TEXT, value TEXT)";
76 pVtab = new tclvar_vtab();//sqlite3MallocZero( sizeof(*pVtab) );
77 //if( pVtab==0 ) return SQLITE_NOMEM;
78 ppVtab = pVtab;//*ppVtab = pVtab.base;
79 pVtab.interp = (Tcl_Interp)pAux;
80 sqlite3_declare_vtab(db, zSchema);
81 pzErr = "";
82 return SQLITE_OK;
83 }
84 /* Note that for this virtual table, the xCreate and xConnect
85 ** methods are identical. */
86  
87 static int tclvarDisconnect(ref object pVtab){
88 //sqlite3_free(pVtab);
89 pVtab = null;
90 return SQLITE_OK;
91 }
92 /* The xDisconnect and xDestroy methods are also the same */
93  
94 /*
95 ** Open a new tclvar cursor.
96 */
97 static int tclvarOpen( sqlite3_vtab pVTab, out sqlite3_vtab_cursor ppCursor )
98 {
99 //tclvar_cursor pCur;
100 //pCur = sqlite3MallocZero(sizeof(tclvar_cursor));
101 //*ppCursor = pCur.base;
102 ppCursor = new tclvar_cursor();
103 return SQLITE_OK;
104 }
105  
106 /*
107 ** Close a tclvar cursor.
108 */
109 static int tclvarClose( ref sqlite3_vtab_cursor cur )
110 {
111 tclvar_cursor pCur = (tclvar_cursor )cur;
112 if( pCur.pList1 != null){
113 TCL.Tcl_DecrRefCount(ref pCur.pList1);
114 }
115 if( pCur.pList2 != null){
116 TCL.Tcl_DecrRefCount( ref pCur.pList2 );
117 }
118 cur = null;//sqlite3_free(pCur);
119 return SQLITE_OK;
120 }
121  
122 /*
123 ** Returns 1 if data is ready, or 0 if not.
124 */
125 static int next2(Tcl_Interp interp, tclvar_cursor pCur, Tcl_Obj pObj){
126 Tcl_Obj p;
127  
128 if( pObj != null){
129 if( null==pCur.pList2 ){
130 p = TCL.Tcl_NewStringObj("array names", -1);
131 TCL.Tcl_IncrRefCount(p);
132 TCL.Tcl_ListObjAppendElement(null, p, pObj);
133 TCL.Tcl_EvalObjEx(interp, p, TCL.TCL_EVAL_GLOBAL);
134 TCL.Tcl_DecrRefCount(ref p);
135 pCur.pList2 = TCL.Tcl_GetObjResult(interp);
136 TCL.Tcl_IncrRefCount(pCur.pList2);
137 Debug.Assert( pCur.i2 == 0 );
138 }
139 else
140 {
141 int n = 0;
142 pCur.i2++;
143 TCL.Tcl_ListObjLength(null, pCur.pList2, out n);
144 if( pCur.i2>=n ){
145 TCL.Tcl_DecrRefCount(ref pCur.pList2);
146 pCur.pList2 = null;
147 pCur.i2 = 0;
148 return 0;
149 }
150 }
151 }
152  
153 return 1;
154 }
155  
156 static int tclvarNext(sqlite3_vtab_cursor cur){
157 Tcl_Obj pObj = null;
158 int n = 0;
159 int ok = 0;
160  
161 tclvar_cursor pCur = (tclvar_cursor )cur;
162 Tcl_Interp interp = ((tclvar_vtab )(cur.pVtab)).interp;
163  
164 TCL.Tcl_ListObjLength( null, pCur.pList1, out n );
165 while( 0==ok && pCur.i1<n ){
166 TCL.Tcl_ListObjIndex( null, pCur.pList1, pCur.i1, out pObj );
167 ok = next2(interp, pCur, pObj);
168 if( 0==ok ){
169 pCur.i1++;
170 }
171 }
172  
173 return 0;
174 }
175  
176 static int tclvarFilter(
177 sqlite3_vtab_cursor pVtabCursor,
178 int idxNum, string idxStr,
179 int argc, sqlite3_value[] argv
180 ){
181 tclvar_cursor pCur = (tclvar_cursor )pVtabCursor;
182 Tcl_Interp interp = ((tclvar_vtab )(pVtabCursor.pVtab)).interp;
183  
184 Tcl_Obj p = TCL.Tcl_NewStringObj("info vars", -1);
185 TCL.Tcl_IncrRefCount(p);
186  
187 Debug.Assert( argc==0 || argc==1 );
188 if( argc==1 ){
189 Tcl_Obj pArg = TCL.Tcl_NewStringObj((string)sqlite3_value_text(argv[0]), -1);
190 TCL.Tcl_ListObjAppendElement(null, p, pArg);
191 }
192 TCL.Tcl_EvalObjEx(interp, p, TCL.TCL_EVAL_GLOBAL);
193 if( pCur.pList1 !=null){
194 TCL.Tcl_DecrRefCount(ref pCur.pList1);
195 }
196 if( pCur.pList2 !=null ){
197 TCL.Tcl_DecrRefCount(ref pCur.pList2);
198 pCur.pList2 = null;
199 }
200 pCur.i1 = 0;
201 pCur.i2 = 0;
202 pCur.pList1 = TCL.Tcl_GetObjResult(interp);
203 TCL.Tcl_IncrRefCount(pCur.pList1);
204 Debug.Assert( pCur.i1==0 && pCur.i2==0 && pCur.pList2==null );
205  
206 TCL.Tcl_DecrRefCount(ref p);
207 return tclvarNext(pVtabCursor);
208 }
209  
210 static int tclvarColumn(sqlite3_vtab_cursor cur, sqlite3_context ctx, int i){
211 Tcl_Obj p1=null;
212 Tcl_Obj p2=null;
213 string z1;
214 string z2 = "";
215 tclvar_cursor pCur = (tclvar_cursor)cur;
216 Tcl_Interp interp = ((tclvar_vtab )cur.pVtab).interp;
217  
218 TCL.Tcl_ListObjIndex( interp, pCur.pList1, pCur.i1, out p1 );
219 TCL.Tcl_ListObjIndex( interp, pCur.pList2, pCur.i2, out p2 );
220 z1 = TCL.Tcl_GetString(p1);
221 if( p2!=null ){
222 z2 = TCL.Tcl_GetString(p2);
223 }
224 switch (i) {
225 case 0: {
226 sqlite3_result_text(ctx, z1, -1, SQLITE_TRANSIENT);
227 break;
228 }
229 case 1: {
230 sqlite3_result_text(ctx, z2, -1, SQLITE_TRANSIENT);
231 break;
232 }
233 case 2: {
234 Tcl_Obj pVal = TCL.Tcl_GetVar2Ex( interp, z1, z2 == "" ? null : z2, (TCL.VarFlag)TCL.TCL_GLOBAL_ONLY );
235 sqlite3_result_text( ctx, TCL.Tcl_GetString( pVal ), -1, SQLITE_TRANSIENT );
236 break;
237 }
238 }
239 return SQLITE_OK;
240 }
241  
242 static int tclvarRowid( sqlite3_vtab_cursor cur, out sqlite_int64 pRowid )
243 {
244 pRowid = 0;
245 return SQLITE_OK;
246 }
247  
248 static int tclvarEof(sqlite3_vtab_cursor cur){
249 tclvar_cursor pCur = (tclvar_cursor)cur;
250 return ( pCur.pList2 != null ? 0 : 1 );
251 }
252  
253 static int tclvarBestIndex( sqlite3_vtab tab, ref sqlite3_index_info pIdxInfo )
254 {
255 int ii;
256  
257 for(ii=0; ii<pIdxInfo.nConstraint; ii++){
258 sqlite3_index_constraint pCons = pIdxInfo.aConstraint[ii];
259 if( pCons.iColumn==0 && pCons.usable
260 && pCons.op==SQLITE_INDEX_CONSTRAINT_EQ ){
261 sqlite3_index_constraint_usage pUsage = new sqlite3_index_constraint_usage();
262 pUsage = pIdxInfo.aConstraintUsage[ii];
263 pUsage.omit = false;
264 pUsage.argvIndex = 1;
265 return SQLITE_OK;
266 }
267 }
268  
269 for(ii=0; ii<pIdxInfo.nConstraint; ii++){
270 sqlite3_index_constraint pCons = pIdxInfo.aConstraint[ii];
271 if( pCons.iColumn==0 && pCons.usable
272 && pCons.op==SQLITE_INDEX_CONSTRAINT_MATCH ){
273 sqlite3_index_constraint_usage pUsage = new sqlite3_index_constraint_usage();
274 pUsage = pIdxInfo.aConstraintUsage[ii];
275 pUsage.omit = true;
276 pUsage.argvIndex = 1;
277 return SQLITE_OK;
278 }
279 }
280  
281 return SQLITE_OK;
282 }
283  
284 /*
285 ** A virtual table module that provides read-only access to a
286 ** Tcl global variable namespace.
287 */
288 static sqlite3_module tclvarModule = new sqlite3_module(
289 0, /* iVersion */
290 tclvarConnect,
291 tclvarConnect,
292 tclvarBestIndex,
293 tclvarDisconnect,
294 tclvarDisconnect,
295 tclvarOpen, /* xOpen - open a cursor */
296 tclvarClose, /* xClose - close a cursor */
297 tclvarFilter, /* xFilter - configure scan constraints */
298 tclvarNext, /* xNext - advance a cursor */
299 tclvarEof, /* xEof - check for end of scan */
300 tclvarColumn, /* xColumn - read data */
301 tclvarRowid, /* xRowid - read data */
302 null, /* xUpdate */
303 null, /* xBegin */
304 null, /* xSync */
305 null, /* xCommit */
306 null, /* xRollback */
307 null, /* xFindMethod */
308 null /* xRename */
309 );
310  
311 /*
312 ** Decode a pointer to an sqlite3 object.
313 */
314 //extern int getDbPointer(Tcl_Interp *interp, string zA, sqlite3 **ppDb);
315  
316 /*
317 ** Register the echo virtual table module.
318 */
319 static int register_tclvar_module(
320 ClientData clientData,/* Pointer to sqlite3_enable_XXX function */
321 Tcl_Interp interp, /* The TCL interpreter that invoked this command */
322 int objc, /* Number of arguments */
323 Tcl_Obj[] objv /* Command arguments */
324 ){
325 sqlite3 db=null;
326 if( objc!=2 ){
327 TCL.Tcl_WrongNumArgs(interp, 1, objv, "DB");
328 return TCL.TCL_ERROR;
329 }
330 if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR;
331 #if !SQLITE_OMIT_VIRTUALTABLE
332 sqlite3_create_module(db, "tclvar", tclvarModule, interp);
333 #endif
334 return TCL.TCL_OK;
335 }
336  
337 #endif
338  
339  
340 /*
341 ** Register commands with the TCL interpreter.
342 */
343 static public int Sqlitetesttclvar_Init(Tcl_Interp interp){
344 #if !SQLITE_OMIT_VIRTUALTABLE
345 //static struct {
346 // char *zName;
347 // Tcl_ObjCmdProc *xProc;
348 // void clientData;
349 //}
350 _aObjCmd[] aObjCmd = new _aObjCmd[] {
351 new _aObjCmd( "register_tclvar_module", register_tclvar_module, 0 ),
352 };
353 int i;
354 for(i=0; i<aObjCmd.Length;i++)//sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++)
355 {
356 TCL.Tcl_CreateObjCommand(interp, aObjCmd[i].zName,
357 aObjCmd[i].xProc, aObjCmd[i].clientData, null);
358 }
359 #endif
360 return TCL.TCL_OK;
361 }
362 }
363 #endif
364 }