wasCSharpSQLite – Blame information for rev

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Diagnostics;
3 using System.Text;
4  
5 using i64 = System.Int64;
6 using u8 = System.Byte;
7  
8 namespace Community.CsharpSqlite
9 {
10 #if TCLSH
11 using tcl.lang;
12 using sqlite_int64 = System.Int64;
13 using sqlite3_stmt = Sqlite3.Vdbe;
14 using sqlite3_value = Sqlite3.Mem;
15 using Tcl_Interp = tcl.lang.Interp;
16 using Tcl_Obj = tcl.lang.TclObject;
17 using ClientData = System.Object;
18  
19 public partial class Sqlite3
20 {
21 /*
22 ** 2006 June 10
23 **
24 ** The author disclaims copyright to this source code. In place of
25 ** a legal notice, here is a blessing:
26 **
27 ** May you do good and not evil.
28 ** May you find forgiveness for yourself and forgive others.
29 ** May you share freely, never taking more than you give.
30 **
31 *************************************************************************
32 ** Code for testing the virtual table interfaces. This code
33 ** is not included in the SQLite library. It is used for automated
34 ** testing of the SQLite library.
35 *************************************************************************
36 ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
37 ** C#-SQLite is an independent reimplementation of the SQLite software library
38 **
39 ** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2
40 **
41 *************************************************************************
42 */
43  
44 /* The code in this file defines a sqlite3 virtual-table module that
45 ** provides a read-only view of the current database schema. There is one
46 ** row in the schema table for each column in the database schema.
47 */
48 //#define SCHEMA \
49 //"CREATE TABLE x(" \
50 // "database," /* Name of database (i.e. main, temp etc.) */ \
51 // "tablename," /* Name of table */ \
52 // "cid," /* Column number (from left-to-right, 0 upward) */ \
53 // "name," /* Column name */ \
54 // "type," /* Specified type (i.e. VARCHAR(32)) */ \
55 // "not_null," /* Boolean. True if NOT NULL was specified */ \
56 // "dflt_value," /* Default value for this column */ \
57 // "pk" /* True if this column is part of the primary key */ \
58 //")"
59 const string SCHEMA = "CREATE TABLE x(" +
60 "database," +
61 "tablename," +
62 "cid," +
63 "name," +
64 "type," +
65 "not_null," +
66 "dflt_value," +
67 "pk" +
68 ")";
69  
70 /* If SQLITE_TEST is defined this code is preprocessed for use as part
71 ** of the sqlite test binary "testfixture". Otherwise it is preprocessed
72 ** to be compiled into an sqlite dynamic extension.
73 */
74 //#if SQLITE_TEST
75 // #include "sqliteInt.h"
76 // #include "tcl.h"
77 //#else
78 // #include "sqlite3ext.h"
79 // SQLITE_EXTENSION_INIT1
80 //#endif
81  
82 //#include <stdlib.h>
83 //#include <string.h>
84 //#include <Debug.Assert.h>
85  
86 //typedef struct schema_vtab schema_vtab;
87 //typedef struct schema_cursor schema_cursor;
88  
89 /* A schema table object */
90 class schema_vtab : sqlite3_vtab
91 {
92 // sqlite3_vtab base;
93 public sqlite3 db;
94 };
95  
96 /* A schema table cursor object */
97 class schema_cursor : sqlite3_vtab_cursor
98 {
99 //sqlite3_vtab_cursor base;
100 public sqlite3_stmt pDbList;
101 public sqlite3_stmt pTableList;
102 public sqlite3_stmt pColumnList;
103 public int rowid;
104 };
105  
106 /*
107 ** None of this works unless we have virtual tables.
108 */
109 #if !SQLITE_OMIT_VIRTUALTABLE
110  
111 /*
112 ** Table destructor for the schema module.
113 */
114 static int schemaDestroy( ref object pVtab )
115 {
116 pVtab = null;//sqlite3_free(pVtab);
117 return 0;
118 }
119  
120 /*
121 ** Table constructor for the schema module.
122 */
123 static int schemaCreate(
124 sqlite3 db,
125 object pAux,
126 int argc,
127 string[] argv,
128 out sqlite3_vtab ppVtab,
129 out string pzErr
130 )
131 {
132 int rc = SQLITE_NOMEM;
133 schema_vtab pVtab = new schema_vtab();//sqlite3_malloc(sizeof(schema_vtab));
134 if ( pVtab != null )
135 {
136 //memset(pVtab, 0, sizeof(schema_vtab));
137 pVtab.db = db;
138 #if !SQLITE_OMIT_VIRTUALTABLE
139 rc = sqlite3_declare_vtab( db, SCHEMA );
140 #endif
141 }
142 ppVtab = (sqlite3_vtab)pVtab;
143 pzErr = "";
144 return rc;
145 }
146  
147 /*
148 ** Open a new cursor on the schema table.
149 */
150 static int schemaOpen( sqlite3_vtab pVTab, out sqlite3_vtab_cursor ppCursor )
151 {
152 int rc = SQLITE_NOMEM;
153 schema_cursor pCur;
154 pCur = new schema_cursor();//pCur = sqlite3_malloc(sizeof(schema_cursor));
155 //if ( pCur != null )
156 //{
157 //memset(pCur, 0, sizeof(schema_cursor));
158 ppCursor = (sqlite3_vtab_cursor)pCur;
159 rc = SQLITE_OK;
160 //}
161 return rc;
162 }
163  
164 /*
165 ** Close a schema table cursor.
166 */
167 static int schemaClose( ref sqlite3_vtab_cursor cur )
168 {
169 schema_cursor pCur = (schema_cursor)cur;
170 sqlite3_finalize( pCur.pDbList );
171 sqlite3_finalize( pCur.pTableList );
172 sqlite3_finalize( pCur.pColumnList );
173 //sqlite3_free( pCur );
174 cur = null;//
175 return SQLITE_OK;
176 }
177  
178 /*
179 ** Retrieve a column of data.
180 */
181 static int schemaColumn( sqlite3_vtab_cursor cur, sqlite3_context ctx, int i )
182 {
183 schema_cursor pCur = (schema_cursor)cur;
184 switch ( i )
185 {
186 case 0:
187 sqlite3_result_value( ctx, sqlite3_column_value( pCur.pDbList, 1 ) );
188 break;
189 case 1:
190 sqlite3_result_value( ctx, sqlite3_column_value( pCur.pTableList, 0 ) );
191 break;
192 default:
193 sqlite3_result_value( ctx, sqlite3_column_value( pCur.pColumnList, i - 2 ) );
194 break;
195 }
196 return SQLITE_OK;
197 }
198  
199 /*
200 ** Retrieve the current rowid.
201 */
202 static int schemaRowid( sqlite3_vtab_cursor cur, out sqlite_int64 pRowid )
203 {
204 schema_cursor pCur = (schema_cursor)cur;
205 pRowid = pCur.rowid;
206 return SQLITE_OK;
207 }
208  
209 static int finalize( ref sqlite3_stmt ppStmt )
210 {
211 int rc = sqlite3_finalize( ppStmt );
212 ppStmt = null;
213 return rc;
214 }
215  
216 static int schemaEof( sqlite3_vtab_cursor cur )
217 {
218 schema_cursor pCur = (schema_cursor)cur;
219 return ( pCur.pDbList != null ? 0 : 1 );
220 }
221  
222 /*
223 ** Advance the cursor to the next row.
224 */
225 static int schemaNext( sqlite3_vtab_cursor cur )
226 {
227 int rc = SQLITE_OK;
228 schema_cursor pCur = (schema_cursor)cur;
229 schema_vtab pVtab = (schema_vtab)( cur.pVtab );
230 string zSql = null;
231  
232 while ( null == pCur.pColumnList || SQLITE_ROW != sqlite3_step( pCur.pColumnList ) )
233 {
234 if ( SQLITE_OK != ( rc = finalize( ref pCur.pColumnList ) ) )
235 goto next_exit;
236  
237 while ( null == pCur.pTableList || SQLITE_ROW != sqlite3_step( pCur.pTableList ) )
238 {
239 if ( SQLITE_OK != ( rc = finalize( ref pCur.pTableList ) ) )
240 goto next_exit;
241  
242 Debug.Assert( pCur.pDbList !=null);
243 while ( SQLITE_ROW != sqlite3_step( pCur.pDbList ) )
244 {
245 rc = finalize( ref pCur.pDbList );
246 goto next_exit;
247 }
248  
249 /* Set zSql to the SQL to pull the list of tables from the
250 ** sqlite_master (or sqlite_temp_master) table of the database
251 ** identfied by the row pointed to by the SQL statement pCur.pDbList
252 ** (iterating through a "PRAGMA database_list;" statement).
253 */
254 if ( sqlite3_column_int( pCur.pDbList, 0 ) == 1 )
255 {
256 zSql = sqlite3_mprintf(
257 "SELECT name FROM sqlite_temp_master WHERE type='table'"
258 );
259 }
260 else
261 {
262 sqlite3_stmt pDbList = pCur.pDbList;
263 zSql = sqlite3_mprintf(
264 "SELECT name FROM %Q.sqlite_master WHERE type='table'",
265 sqlite3_column_text( pDbList, 1 )
266 );
267 }
268 //if( !zSql ){
269 // rc = SQLITE_NOMEM;
270 // goto next_exit;
271 //}
272 rc = sqlite3_prepare( pVtab.db, zSql, -1, ref pCur.pTableList, 0 );
273 //sqlite3_free(zSql);
274 if ( rc != SQLITE_OK )
275 goto next_exit;
276 }
277  
278 /* Set zSql to the SQL to the table_info pragma for the table currently
279 ** identified by the rows pointed to by statements pCur.pDbList and
280 ** pCur.pTableList.
281 */
282 zSql = sqlite3_mprintf( "PRAGMA %Q.table_info(%Q)",
283 sqlite3_column_text( pCur.pDbList, 1 ),
284 sqlite3_column_text( pCur.pTableList, 0 )
285 );
286  
287 //if( !Sql ){
288 // rc = SQLITE_NOMEM;
289 // goto next_exit;
290 //}
291 rc = sqlite3_prepare( pVtab.db, zSql, -1, ref pCur.pColumnList, 0 );
292 //sqlite3_free(zSql);
293 if ( rc != SQLITE_OK )
294 goto next_exit;
295 }
296 pCur.rowid++;
297  
298 next_exit:
299 /* TODO: Handle rc */
300 return rc;
301 }
302  
303 /*
304 ** Reset a schema table cursor.
305 */
306 static int schemaFilter(
307 sqlite3_vtab_cursor pVtabCursor,
308 int idxNum,
309 string idxStr,
310 int argc,
311 sqlite3_value[] argv
312 )
313 {
314 int rc;
315 schema_vtab pVtab = (schema_vtab)( pVtabCursor.pVtab );
316 schema_cursor pCur = (schema_cursor)pVtabCursor;
317 pCur.rowid = 0;
318 finalize( ref pCur.pTableList );
319 finalize( ref pCur.pColumnList );
320 finalize( ref pCur.pDbList );
321 rc = sqlite3_prepare( pVtab.db, "PRAGMA database_list", -1, ref pCur.pDbList, 0 );
322 return ( rc == SQLITE_OK ? schemaNext( pVtabCursor ) : rc );
323 }
324  
325 /*
326 ** Analyse the WHERE condition.
327 */
328 static int schemaBestIndex( sqlite3_vtab tab, ref sqlite3_index_info pIdxInfo )
329 {
330 return SQLITE_OK;
331 }
332  
333 /*
334 ** A virtual table module that merely echos method calls into TCL
335 ** variables.
336 */
337 static sqlite3_module schemaModule = new sqlite3_module(
338 0, /* iVersion */
339 schemaCreate,
340 schemaCreate,
341 schemaBestIndex,
342 schemaDestroy,
343 schemaDestroy,
344 schemaOpen, /* xOpen - open a cursor */
345 schemaClose, /* xClose - close a cursor */
346 schemaFilter, /* xFilter - configure scan constraints */
347 schemaNext, /* xNext - advance a cursor */
348 schemaEof, /* xEof */
349 schemaColumn, /* xColumn - read data */
350 schemaRowid, /* xRowid - read data */
351 null, /* xUpdate */
352 null, /* xBegin */
353 null, /* xSync */
354 null, /* xCommit */
355 null, /* xRollback */
356 null, /* xFindMethod */
357 null /* xRename */
358 );
359  
360 #endif //* !defined(SQLITE_OMIT_VIRTUALTABLE) */
361  
362 #if SQLITE_TEST
363  
364 /*
365 ** Decode a pointer to an sqlite3 object.
366 */
367 //extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
368  
369 /*
370 ** Register the schema virtual table module.
371 */
372 static int register_schema_module(
373 ClientData clientData, /* Not used */
374 Tcl_Interp interp, /* The TCL interpreter that invoked this command */
375 int objc, /* Number of arguments */
376 Tcl_Obj[] objv /* Command arguments */
377 )
378 {
379 sqlite3 db = null;
380 if ( objc != 2 )
381 {
382 TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB" );
383 return TCL.TCL_ERROR;
384 }
385 if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 )
386 return TCL.TCL_ERROR;
387 #if !SQLITE_OMIT_VIRTUALTABLE
388 sqlite3_create_module( db, "schema", schemaModule, null );
389 #endif
390 return TCL.TCL_OK;
391 }
392  
393 /*
394 ** Register commands with the TCL interpreter.
395 */
396 static public int Sqlitetestschema_Init( Tcl_Interp interp )
397 {
398 //static struct {
399 // char *zName;
400 // Tcl_ObjCmdProc *xProc;
401 // void *clientData;
402 //}
403 _aObjCmd[] aObjCmd = new _aObjCmd[]{
404 new _aObjCmd( "register_schema_module", register_schema_module, 0 ),
405 };
406 int i;
407 for ( i = 0; i < aObjCmd.Length; i++ )//sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++)
408 {
409 TCL.Tcl_CreateObjCommand( interp, aObjCmd[i].zName,
410 aObjCmd[i].xProc, aObjCmd[i].clientData, null );
411 }
412 return TCL.TCL_OK;
413 }
414  
415 #else
416  
417 /*
418 ** Extension load function.
419 */
420 int sqlite3_extension_init(
421 sqlite3 *db,
422 char **pzErrMsg,
423 const sqlite3_api_routines *pApi
424 ){
425 SQLITE_EXTENSION_INIT2(pApi);
426 #if !SQLITE_OMIT_VIRTUALTABLE
427 sqlite3_create_module(db, "schema", &schemaModule, 0);
428 #endif
429 return 0;
430 }
431  
432 #endif
433 }
434 #endif
435 }