wasCSharpSQLite – Blame information for rev

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System.Diagnostics;
2 using unsigned = System.UInt32;
3 using sqlite_int64 = System.Int64;
4 using sqlite3_int64 = System.Int64;
5 using sqlite3_value_int64 = System.Int64;
6  
7 namespace Community.CsharpSqlite
8 {
9 #if TCLSH
10 using tcl.lang;
11 using sqlite3_stmt = Sqlite3.Vdbe;
12 using sqlite3_value = Sqlite3.Mem;
13 using Tcl_Interp = tcl.lang.Interp;
14 using Tcl_Obj = tcl.lang.TclObject;
15 using ClientData = System.Object;
16  
17 public partial class Sqlite3
18 {
19 /*
20 ** 2011 April 02
21 **
22 ** The author disclaims copyright to this source code. In place of
23 ** a legal notice, here is a blessing:
24 **
25 ** May you do good and not evil.
26 ** May you find forgiveness for yourself and forgive others.
27 ** May you share freely, never taking more than you give.
28 **
29 *************************************************************************
30 **
31 ** This file implements a virtual table that returns the whole numbers
32 ** between 1 and 4294967295, inclusive.
33 **
34 ** Example:
35 **
36 ** CREATE VIRTUAL TABLE nums USING wholenumber;
37 ** SELECT value FROM nums WHERE value<10;
38 **
39 ** Results in:
40 **
41 ** 1 2 3 4 5 6 7 8 9
42 */
43 //#include "sqlite3.h"
44 //#include <assert.h>
45 //#include <string.h>
46  
47 #if !SQLITE_OMIT_VIRTUALTABLE
48  
49  
50 /* A wholenumber cursor object */
51 //typedef struct wholenumber_cursor wholenumber_cursor;
52 class wholenumber_cursor : sqlite3_vtab_cursor
53 {
54 //public sqlite3_vtab_cursor base; /* Base class - must be first */
55 public unsigned iValue; /* Current value */
56 public unsigned mxValue; /* Maximum value */
57 };
58  
59 /* Methods for the wholenumber module */
60 static int wholenumberConnect(
61 sqlite3 db,
62 object pAux,
63 int argc, string[] argv,
64 out sqlite3_vtab ppVtab,
65 out string pzErr
66 )
67 {
68 sqlite3_vtab pNew;
69 pNew = ppVtab = new sqlite3_vtab();//sqlite3_malloc( sizeof(*pNew) );
70 //if ( pNew == null )
71 // return SQLITE_NOMEM;
72 sqlite3_declare_vtab( db, "CREATE TABLE x(value)" );
73 //memset(pNew, 0, sizeof(*pNew));
74 pzErr = "";
75 return SQLITE_OK;
76 }
77 /* Note that for this virtual table, the xCreate and xConnect
78 ** methods are identical. */
79  
80 static int wholenumberDisconnect( ref object pVtab )
81 {
82 pVtab = null;// sqlite3_free( pVtab );
83 return SQLITE_OK;
84 }
85 /* The xDisconnect and xDestroy methods are also the same */
86  
87  
88 /*
89 ** Open a new wholenumber cursor.
90 */
91 static int wholenumberOpen( sqlite3_vtab p, out sqlite3_vtab_cursor ppCursor )
92 {
93 wholenumber_cursor pCur;
94 pCur = new wholenumber_cursor();//sqlite3_malloc( sizeof(*pCur) );
95 //if ( pCur == null )
96 // return SQLITE_NOMEM;
97 //memset(pCur, 0, sizeof(*pCur));
98 ppCursor = pCur;//.base;
99 return SQLITE_OK;
100 }
101  
102 /*
103 ** Close a wholenumber cursor.
104 */
105 static int wholenumberClose( ref sqlite3_vtab_cursor cur )
106 {
107 cur = null;// sqlite3_free( ref cur );
108 return SQLITE_OK;
109 }
110  
111  
112 /*
113 ** Advance a cursor to its next row of output
114 */
115 static int wholenumberNext( sqlite3_vtab_cursor cur )
116 {
117 wholenumber_cursor pCur = (wholenumber_cursor)cur;
118 pCur.iValue++;
119 return SQLITE_OK;
120 }
121  
122 /*
123 ** Return the value associated with a wholenumber.
124 */
125 static int wholenumberColumn(
126 sqlite3_vtab_cursor cur,
127 sqlite3_context ctx,
128 int i
129 )
130 {
131 wholenumber_cursor pCur = (wholenumber_cursor)cur;
132 sqlite3_result_int64( ctx, pCur.iValue );
133 return SQLITE_OK;
134 }
135  
136 /*
137 ** The rowid.
138 */
139 static int wholenumberRowid( sqlite3_vtab_cursor cur, out sqlite_int64 pRowid )
140 {
141 wholenumber_cursor pCur = (wholenumber_cursor)cur;
142 pRowid = pCur.iValue;
143 return SQLITE_OK;
144 }
145  
146 /*
147 ** When the wholenumber_cursor.rLimit value is 0 or less, that is a signal
148 ** that the cursor has nothing more to output.
149 */
150 static int wholenumberEof( sqlite3_vtab_cursor cur )
151 {
152 wholenumber_cursor pCur = (wholenumber_cursor)cur;
153 return ( pCur.iValue > pCur.mxValue || pCur.iValue == 0 ) ? 1 : 0;
154 }
155  
156 /*
157 ** Called to "rewind" a cursor back to the beginning so that
158 ** it starts its output over again. Always called at least once
159 ** prior to any wholenumberColumn, wholenumberRowid, or wholenumberEof call.
160 **
161 ** idxNum Constraints
162 ** ------ ---------------------
163 ** 0 (none)
164 ** 1 value > $argv0
165 ** 2 value >= $argv0
166 ** 4 value < $argv0
167 ** 8 value <= $argv0
168 **
169 ** 5 value > $argv0 AND value < $argv1
170 ** 6 value >= $argv0 AND value < $argv1
171 ** 9 value > $argv0 AND value <= $argv1
172 ** 10 value >= $argv0 AND value <= $argv1
173 */
174 static int wholenumberFilter(
175 sqlite3_vtab_cursor pVtabCursor,
176 int idxNum, string idxStr,
177 int argc, sqlite3_value[] argv
178 )
179 {
180 wholenumber_cursor pCur = (wholenumber_cursor)pVtabCursor;
181 sqlite3_int64 v;
182 int i = 0;
183 pCur.iValue = 1;
184 pCur.mxValue = 0xffffffff; /* 4294967295 */
185 if ( ( idxNum & 3 ) != 0 )
186 {
187 v = sqlite3_value_int64( argv[0] ) + ( idxNum & 1 );
188 if ( v > pCur.iValue && v <= pCur.mxValue )
189 pCur.iValue = (uint)v;
190 i++;
191 }
192 if ( ( idxNum & 12 ) != 0 )
193 {
194 v = sqlite3_value_int64( argv[i] ) - ( ( idxNum >> 2 ) & 1 );
195 if ( v >= pCur.iValue && v < pCur.mxValue )
196 pCur.mxValue = (uint)v;
197 }
198 return SQLITE_OK;
199 }
200  
201 /*
202 ** Search for terms of these forms:
203 **
204 ** (1) value > $value
205 ** (2) value >= $value
206 ** (4) value < $value
207 ** (8) value <= $value
208 **
209 ** idxNum is an ORed combination of 1 or 2 with 4 or 8.
210 */
211 static int wholenumberBestIndex(
212 sqlite3_vtab vtab,
213 ref sqlite3_index_info pIdxInfo
214 )
215 {
216 int i;
217 int idxNum = 0;
218 int argvIdx = 1;
219 int ltIdx = -1;
220 int gtIdx = -1;
221 sqlite3_index_constraint pConstraint;
222 //pConstraint = pIdxInfo.aConstraint;
223 for ( i = 0; i < pIdxInfo.nConstraint; i++ )//, pConstraint++)
224 {
225 pConstraint = pIdxInfo.aConstraint[i];
226 if ( pConstraint.usable == false )
227 continue;
228 if ( ( idxNum & 3 ) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_GT )
229 {
230 idxNum |= 1;
231 ltIdx = i;
232 }
233 if ( ( idxNum & 3 ) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_GE )
234 {
235 idxNum |= 2;
236 ltIdx = i;
237 }
238 if ( ( idxNum & 12 ) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_LT )
239 {
240 idxNum |= 4;
241 gtIdx = i;
242 }
243 if ( ( idxNum & 12 ) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_LE )
244 {
245 idxNum |= 8;
246 gtIdx = i;
247 }
248 }
249 pIdxInfo.idxNum = idxNum;
250 if ( ltIdx >= 0 )
251 {
252 pIdxInfo.aConstraintUsage[ltIdx].argvIndex = argvIdx++;
253 pIdxInfo.aConstraintUsage[ltIdx].omit = true;
254 }
255 if ( gtIdx >= 0 )
256 {
257 pIdxInfo.aConstraintUsage[gtIdx].argvIndex = argvIdx;
258 pIdxInfo.aConstraintUsage[gtIdx].omit = true;
259 }
260 if ( pIdxInfo.nOrderBy == 1
261 && pIdxInfo.aOrderBy[0].desc == false
262 )
263 {
264 pIdxInfo.orderByConsumed = true;
265 }
266 pIdxInfo.estimatedCost = (double)1;
267 return SQLITE_OK;
268 }
269  
270 /*
271 ** A virtual table module that provides read-only access to a
272 ** Tcl global variable namespace.
273 */
274 static sqlite3_module wholenumberModule = new sqlite3_module(
275 2, /* iVersion */
276 (smdxCreateConnect)wholenumberConnect,
277 (smdxCreateConnect)wholenumberConnect,
278 (smdxBestIndex)wholenumberBestIndex,
279 (smdxDisconnect)wholenumberDisconnect,
280 (smdxDestroy)wholenumberDisconnect,
281 (smdxOpen)wholenumberOpen, /* xOpen - open a cursor */
282 (smdxClose)wholenumberClose, /* xClose - close a cursor */
283 (smdxFilter)wholenumberFilter, /* xFilter - configure scan constraints */
284 (smdxNext)wholenumberNext, /* xNext - advance a cursor */
285 (smdxEof)wholenumberEof, /* xEof - check for end of scan */
286 (smdxColumn)wholenumberColumn, /* xColumn - read data */
287 (smdxRowid)wholenumberRowid, /* xRowid - read data */
288 null, /* xUpdate */
289 null, /* xBegin */
290 null, /* xSync */
291 null, /* xCommit */
292 null, /* xRollback */
293 null, /* xFindMethod */
294 null, /* xRename */
295 /* The methods above are in version 1 of the sqlite_module object. Those
296 ** below are for version 2 and greater. */
297 null,
298 null,
299 null
300 );
301  
302 #endif //* SQLITE_OMIT_VIRTUALTABLE */
303  
304  
305 /*
306 ** Register the wholenumber virtual table
307 */
308 static int wholenumber_register( sqlite3 db )
309 {
310 int rc = SQLITE_OK;
311 #if !SQLITE_OMIT_VIRTUALTABLE
312 rc = sqlite3_create_module( db, "wholenumber", wholenumberModule, null );
313 #endif
314 return rc;
315 }
316  
317 #if SQLITE_TEST
318 //#include <tcl.h>
319 /*
320 ** Decode a pointer to an sqlite3 object.
321 */
322 //extern int getDbPointer(Tcl_Interp interp, string zA, sqlite3 **ppDb);
323  
324 /*
325 ** Register the echo virtual table module.
326 */
327 static int register_wholenumber_module(
328 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
329 Tcl_Interp interp, /* The TCL interpreter that invoked this command */
330 int objc, /* Number of arguments */
331 Tcl_Obj[] objv /* Command arguments */
332 )
333 {
334 sqlite3 db = null;
335 if ( objc != 2 )
336 {
337 TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB" );
338 return TCL.TCL_ERROR;
339 }
340 if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 )
341 return TCL.TCL_ERROR;
342 wholenumber_register( db );
343 return TCL.TCL_OK;
344 }
345  
346  
347 //static class _aObjCmd {
348 // public string zName;
349 // public Tcl_ObjCmdProc xProc;
350 // public object clientData;
351 //}
352 /*
353 ** Register commands with the TCL interpreter.
354 */
355 static public int Sqlitetestwholenumber_Init( Tcl_Interp interp )
356 {
357 _aObjCmd[] aObjCmd = new _aObjCmd[] {
358 new _aObjCmd( "register_wholenumber_module", register_wholenumber_module, 0 ),
359 };
360 int i;
361 for ( i = 0; i < aObjCmd.Length; i++ )
362 {//sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
363 TCL.Tcl_CreateObjCommand( interp, aObjCmd[i].zName,
364 aObjCmd[i].xProc, aObjCmd[i].clientData, null );
365 }
366 return TCL.TCL_OK;
367 }
368  
369 #endif //* SQLITE_TEST */
370 }
371 #endif
372 }