wasCSharpSQLite – Blame information for rev

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System.Diagnostics;
2  
3 using u8 = System.Byte;
4 using u32 = System.UInt32;
5  
6 namespace Community.CsharpSqlite
7 {
8 #if TCLSH
9 using tcl.lang;
10 using DbPage = Sqlite3.PgHdr;
11 using sqlite_int64 = System.Int64;
12 using sqlite3_int64 = System.Int64;
13 using sqlite3_stmt = Sqlite3.Vdbe;
14 using sqlite3_value = Sqlite3.Mem;
15 using Tcl_CmdInfo = tcl.lang.WrappedCommand;
16 using Tcl_Interp = tcl.lang.Interp;
17 using Tcl_Obj = tcl.lang.TclObject;
18 using ClientData = System.Object;
19 using System;
20 using System.Text;
21 #endif
22  
23 public partial class Sqlite3
24 {
25 /*
26 ** 2009 November 10
27 **
28 ** The author disclaims copyright to this source code. In place of
29 ** a legal notice, here is a blessing:
30 **
31 ** May you do good and not evil.
32 ** May you find forgiveness for yourself and forgive others.
33 ** May you share freely, never taking more than you give.
34 **
35 *************************************************************************
36 **
37 ** This file implements a read-only VIRTUAL TABLE that contains the
38 ** content of a C-language array of integer values. See the corresponding
39 ** header file for full details.
40 *************************************************************************
41 ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
42 ** C#-SQLite is an independent reimplementation of the SQLite software library
43 **
44 ** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2
45 **
46 *************************************************************************
47 */
48 //#include "test_intarray.h"
49 //#include <string.h>
50 //#include <Debug.Assert.h>
51  
52  
53 /*
54 ** Definition of the sqlite3_intarray object.
55 **
56 ** The internal representation of an intarray object is subject
57 ** to change, is not externally visible, and should be used by
58 ** the implementation of intarray only. This object is opaque
59 ** to users.
60 */
61 class sqlite3_intarray : sqlite3_vtab
62 {
63 public int n; /* Number of elements in the array */
64 public sqlite3_int64[] a; /* Contents of the array */
65 public dxFree xFree;//void (*xFree)(void*); /* Function used to free a[] */
66 };
67  
68 /* Objects used internally by the virtual table implementation */
69 //typedef struct intarray_vtab intarray_vtab;
70 //typedef struct intarray_cursor intarray_cursor;
71  
72 /* A intarray table object */
73 class intarray_vtab : sqlite3_vtab
74 {
75 //sqlite3_vtab base; /* Base class */
76 public sqlite3_intarray pContent; /* Content of the integer array */
77 };
78  
79 /* A intarray cursor object */
80 class intarray_cursor : sqlite3_vtab_cursor
81 {
82 //sqlite3_vtab_cursor base; /* Base class */
83 public int i; /* Current cursor position */
84 };
85  
86 /*
87 ** None of this works unless we have virtual tables.
88 */
89 #if !SQLITE_OMIT_VIRTUALTABLE
90  
91 /*
92 ** Free an sqlite3_intarray object.
93 */
94 static int intarrayFree( ref object p )
95 {
96 //if ( ( (sqlite3_intarray)p ).xFree != null )
97 //{
98 // p.xFree( ref p.a );
99 //}
100 p = null;//sqlite3_free(p);
101 return 0;
102 }
103  
104 /*
105 ** Table destructor for the intarray module.
106 */
107 static int intarrayDestroy( ref object p )
108 {
109 //intarray_vtab *pVtab = (intarray_vtab*)p;
110 //sqlite3_free(pVtab);
111 p = null;
112 return 0;
113 }
114  
115 /*
116 ** Table constructor for the intarray module.
117 */
118 static int intarrayCreate(
119 sqlite3 db, /* Database where module is created */
120 object pAux, /* clientdata for the module */
121 int argc, /* Number of arguments */
122 string[] argv, /* Value for all arguments */
123 out sqlite3_vtab ppVtab, /* Write the new virtual table object here */
124 out string pzErr /* Put error message text here */
125 )
126 {
127 int rc = SQLITE_NOMEM;
128 intarray_vtab pVtab = new intarray_vtab();//sqlite3_malloc(sizeof(intarray_vtab));
129  
130 if ( pVtab != null )
131 {
132 //memset(pVtab, 0, sizeof(intarray_vtab));
133 pVtab.pContent = (sqlite3_intarray)pAux;
134 rc = sqlite3_declare_vtab( db, "CREATE TABLE x(value INTEGER PRIMARY KEY)" );
135 }
136 ppVtab = (sqlite3_vtab)pVtab;
137 pzErr = "";
138 return rc;
139 }
140  
141 /*
142 ** Open a new cursor on the intarray table.
143 */
144 static int intarrayOpen( sqlite3_vtab pVTab, out sqlite3_vtab_cursor ppCursor )
145 {
146 int rc = SQLITE_NOMEM;
147 intarray_cursor pCur = new intarray_cursor();//
148 //pCur = sqlite3_malloc(sizeof(intarray_cursor));
149 //if ( pCur != null )
150 {
151 //memset(pCur, 0, sizeof(intarray_cursor));
152 ppCursor = (sqlite3_vtab_cursor)pCur;
153 rc = SQLITE_OK;
154 }
155 return rc;
156 }
157  
158 /*
159 ** Close a intarray table cursor.
160 */
161 static int intarrayClose( ref sqlite3_vtab_cursor cur )
162 {
163 //intarray_cursor *pCur = (intarray_cursor *)cur;
164 //sqlite3_free(pCur);
165 cur = null;
166 return SQLITE_OK;
167 }
168  
169 /*
170 ** Retrieve a column of data.
171 */
172 static int intarrayColumn( sqlite3_vtab_cursor cur, sqlite3_context ctx, int i )
173 {
174 intarray_cursor pCur = (intarray_cursor)cur;
175 intarray_vtab pVtab = (intarray_vtab)cur.pVtab;
176 if ( pCur.i >= 0 && pCur.i < pVtab.pContent.n )
177 {
178 sqlite3_result_int64( ctx, pVtab.pContent.a[pCur.i] );
179 }
180 return SQLITE_OK;
181 }
182  
183 /*
184 ** Retrieve the current rowid.
185 */
186 static int intarrayRowid( sqlite3_vtab_cursor cur, out sqlite_int64 pRowid )
187 {
188 intarray_cursor pCur = (intarray_cursor)cur;
189 pRowid = pCur.i;
190 return SQLITE_OK;
191 }
192  
193 static int intarrayEof( sqlite3_vtab_cursor cur )
194 {
195 intarray_cursor pCur = (intarray_cursor)cur;
196 intarray_vtab pVtab = (intarray_vtab)cur.pVtab;
197 return pCur.i >= pVtab.pContent.n ? 1 : 0;
198 }
199  
200 /*
201 ** Advance the cursor to the next row.
202 */
203 static int intarrayNext( sqlite3_vtab_cursor cur )
204 {
205 intarray_cursor pCur = (intarray_cursor)cur;
206 pCur.i++;
207 return SQLITE_OK;
208 }
209  
210 /*
211 ** Reset a intarray table cursor.
212 */
213 static int intarrayFilter(
214 sqlite3_vtab_cursor pVtabCursor,
215 int idxNum, string idxStr,
216 int argc, sqlite3_value[] argv
217 )
218 {
219 intarray_cursor pCur = (intarray_cursor)pVtabCursor;
220 pCur.i = 0;
221 return SQLITE_OK;
222 }
223  
224 /*
225 ** Analyse the WHERE condition.
226 */
227 static int intarrayBestIndex( sqlite3_vtab tab, ref sqlite3_index_info pIdxInfo )
228 {
229 return SQLITE_OK;
230 }
231  
232 /*
233 ** A virtual table module that merely echos method calls into TCL
234 ** variables.
235 */
236 static sqlite3_module intarrayModule = new sqlite3_module(
237 0, /* iVersion */
238 intarrayCreate, /* xCreate - create a new virtual table */
239 intarrayCreate, /* xConnect - connect to an existing vtab */
240 intarrayBestIndex, /* xBestIndex - find the best query index */
241 intarrayDestroy, /* xDisconnect - disconnect a vtab */
242 intarrayDestroy, /* xDestroy - destroy a vtab */
243 intarrayOpen, /* xOpen - open a cursor */
244 intarrayClose, /* xClose - close a cursor */
245 intarrayFilter, /* xFilter - configure scan constraints */
246 intarrayNext, /* xNext - advance a cursor */
247 intarrayEof, /* xEof */
248 intarrayColumn, /* xColumn - read data */
249 intarrayRowid, /* xRowid - read data */
250 null, /* xUpdate */
251 null, /* xBegin */
252 null, /* xSync */
253 null, /* xCommit */
254 null, /* xRollback */
255 null, /* xFindMethod */
256 null /* xRename */
257 );
258  
259 #endif //* !defined(SQLITE_OMIT_VIRTUALTABLE) */
260  
261 /*
262 ** Invoke this routine to create a specific instance of an intarray object.
263 ** The new intarray object is returned by the 3rd parameter.
264 **
265 ** Each intarray object corresponds to a virtual table in the TEMP table
266 ** with a name of zName.
267 **
268 ** Destroy the intarray object by dropping the virtual table. If not done
269 ** explicitly by the application, the virtual table will be dropped implicitly
270 ** by the system when the database connection is closed.
271 */
272 static int sqlite3_intarray_create(
273 sqlite3 db,
274 string zName,
275 out sqlite3_intarray ppReturn
276 )
277 {
278 int rc = SQLITE_OK;
279 #if !SQLITE_OMIT_VIRTUALTABLE
280 sqlite3_intarray p;
281  
282 ppReturn = p = new sqlite3_intarray();//sqlite3_malloc( sizeof(*p) );
283 //if( p==0 ){
284 // return SQLITE_NOMEM;
285 //}
286 //memset(p, 0, sizeof(*p));
287 rc = sqlite3_create_module_v2( db, zName, intarrayModule, p,
288 intarrayFree );
289 if ( rc == SQLITE_OK )
290 {
291 string zSql;
292 zSql = sqlite3_mprintf( "CREATE VIRTUAL TABLE temp.%Q USING %Q",
293 zName, zName );
294 rc = sqlite3_exec( db, zSql, 0, 0, 0 );
295 //sqlite3_free(zSql);
296 }
297 #endif
298 return rc;
299 }
300  
301 /*
302 ** Bind a new array array of integers to a specific intarray object.
303 **
304 ** The array of integers bound must be unchanged for the duration of
305 ** any query against the corresponding virtual table. If the integer
306 ** array does change or is deallocated undefined behavior will result.
307 */
308 static int sqlite3_intarray_bind(
309 sqlite3_intarray pIntArray, /* The intarray object to bind to */
310 int nElements, /* Number of elements in the intarray */
311 sqlite3_int64[] aElements, /* Content of the intarray */
312 dxFree xFree//void (*xFree)(void*) /* How to dispose of the intarray when done */
313 )
314 {
315 if ( pIntArray.xFree != null )
316 {
317 pIntArray.a = null;//pIntArray.xFree( pIntArray.a );
318 }
319 pIntArray.n = nElements;
320 pIntArray.a = aElements;
321 pIntArray.xFree = xFree;
322 return SQLITE_OK;
323 }
324  
325  
326 /*****************************************************************************
327 ** Everything below is interface for testing this module.
328 */
329 #if SQLITE_TEST
330 //#include <tcl.h>
331  
332 /*
333 ** Routines to encode and decode pointers
334 */
335 //extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
336 //extern void *sqlite3TestTextToPtr(const char*);
337 //extern int sqlite3TestMakePointerStr(Tcl_Interp*, char *zPtr, void*);
338 //extern const char *sqlite3TestErrorName(int);
339  
340 /*
341 ** sqlite3_intarray_create DB NAME
342 **
343 ** Invoke the sqlite3_intarray_create interface. A string that becomes
344 ** the first parameter to sqlite3_intarray_bind.
345 */
346 static int test_intarray_create(
347 ClientData clientData, /* Not used */
348 Tcl_Interp interp, /* The TCL interpreter that invoked this command */
349 int objc, /* Number of arguments */
350 Tcl_Obj[] objv /* Command arguments */
351 )
352 {
353 sqlite3 db;
354 string zName;
355 sqlite3_intarray pArray;
356 int rc = SQLITE_OK;
357 StringBuilder zPtr = new StringBuilder( 100 );
358  
359 if ( objc != 3 )
360 {
361 TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB" );
362 return TCL.TCL_ERROR;
363 }
364 if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 )
365 return TCL.TCL_ERROR;
366 zName = TCL.Tcl_GetString( objv[2] );
367 #if !SQLITE_OMIT_VIRTUALTABLE
368 rc = sqlite3_intarray_create( db, zName, out pArray );
369 #endif
370 if ( rc != SQLITE_OK )
371 {
372 Debug.Assert( pArray == null );
373 TCL.Tcl_AppendResult( interp, sqlite3TestErrorName( rc ), null );
374 return TCL.TCL_ERROR;
375 }
376 sqlite3TestMakePointerStr( interp, zPtr, pArray );
377 TCL.Tcl_AppendResult( interp, zPtr, null );
378 return TCL.TCL_OK;
379 }
380  
381 /*
382 ** sqlite3_intarray_bind INTARRAY ?VALUE ...?
383 **
384 ** Invoke the sqlite3_intarray_bind interface on the given array of integers.
385 */
386 static int test_intarray_bind(
387 ClientData clientData, /* Not used */
388 Tcl_Interp interp, /* The TCL interpreter that invoked this command */
389 int objc, /* Number of arguments */
390 Tcl_Obj[] objv /* Command arguments */
391 )
392 {
393 sqlite3_intarray pArray;
394 int rc = SQLITE_OK;
395 int i, n;
396 sqlite3_int64[] a;
397  
398 if ( objc < 2 )
399 {
400 TCL.Tcl_WrongNumArgs( interp, 1, objv, "INTARRAY" );
401 return TCL.TCL_ERROR;
402 }
403 pArray = (sqlite3_intarray)sqlite3TestTextToPtr( interp, TCL.Tcl_GetString( objv[1] ) );
404 n = objc - 2;
405 #if !SQLITE_OMIT_VIRTUALTABLE
406 a = new sqlite3_int64[n];//sqlite3_malloc( sizeof(a[0])*n );
407 //if( a==0 ){
408 // Tcl_AppendResult(interp, "SQLITE_NOMEM", (char*)0);
409 // return TCL_ERROR;
410 //}
411 for ( i = 0; i < n; i++ )
412 {
413 //a[i] = 0;
414 TCL.Tcl_GetWideIntFromObj( null, objv[i + 2], out a[i] );
415 }
416 rc = sqlite3_intarray_bind( pArray, n, a, sqlite3_free );
417 if ( rc != SQLITE_OK )
418 {
419 TCL.Tcl_AppendResult( interp, sqlite3TestErrorName( rc ), null );
420 return TCL.TCL_ERROR;
421 }
422 #endif
423 return TCL.TCL_OK;
424 }
425  
426 /*
427 ** Register commands with the TCL interpreter.
428 */
429 static public int Sqlitetestintarray_Init( Tcl_Interp interp )
430 {
431 //static struct {
432 // char *zName;
433 // Tcl_ObjCmdProc *xProc;
434 // void *clientData;
435 //}
436 _aObjCmd[] aObjCmd = new _aObjCmd[] {
437 new _aObjCmd( "sqlite3_intarray_create", test_intarray_create, 0 ),
438 new _aObjCmd( "sqlite3_intarray_bind", test_intarray_bind, 0 ),
439 };
440 int i;
441 for ( i = 0; i < aObjCmd.Length; i++ )//sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++)
442 {
443 TCL.Tcl_CreateObjCommand( interp, aObjCmd[i].zName,
444 aObjCmd[i].xProc, aObjCmd[i].clientData, null );
445 }
446 return TCL.TCL_OK;
447 }
448  
449 #endif //* SQLITE_TEST */
450 }
451 }