wasCSharpSQLite – Rev
?pathlinks?
using System.Diagnostics;
using unsigned = System.UInt32;
using sqlite_int64 = System.Int64;
using sqlite3_int64 = System.Int64;
using sqlite3_value_int64 = System.Int64;
namespace Community.CsharpSqlite
{
#if TCLSH
using tcl.lang;
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
{
/*
** 2011 April 02
**
** 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.
**
*************************************************************************
**
** This file implements a virtual table that returns the whole numbers
** between 1 and 4294967295, inclusive.
**
** Example:
**
** CREATE VIRTUAL TABLE nums USING wholenumber;
** SELECT value FROM nums WHERE value<10;
**
** Results in:
**
** 1 2 3 4 5 6 7 8 9
*/
//#include "sqlite3.h"
//#include <assert.h>
//#include <string.h>
#if !SQLITE_OMIT_VIRTUALTABLE
/* A wholenumber cursor object */
//typedef struct wholenumber_cursor wholenumber_cursor;
class wholenumber_cursor : sqlite3_vtab_cursor
{
//public sqlite3_vtab_cursor base; /* Base class - must be first */
public unsigned iValue; /* Current value */
public unsigned mxValue; /* Maximum value */
};
/* Methods for the wholenumber module */
static int wholenumberConnect(
sqlite3 db,
object pAux,
int argc, string[] argv,
out sqlite3_vtab ppVtab,
out string pzErr
)
{
sqlite3_vtab pNew;
pNew = ppVtab = new sqlite3_vtab();//sqlite3_malloc( sizeof(*pNew) );
//if ( pNew == null )
// return SQLITE_NOMEM;
sqlite3_declare_vtab( db, "CREATE TABLE x(value)" );
//memset(pNew, 0, sizeof(*pNew));
pzErr = "";
return SQLITE_OK;
}
/* Note that for this virtual table, the xCreate and xConnect
** methods are identical. */
static int wholenumberDisconnect( ref object pVtab )
{
pVtab = null;// sqlite3_free( pVtab );
return SQLITE_OK;
}
/* The xDisconnect and xDestroy methods are also the same */
/*
** Open a new wholenumber cursor.
*/
static int wholenumberOpen( sqlite3_vtab p, out sqlite3_vtab_cursor ppCursor )
{
wholenumber_cursor pCur;
pCur = new wholenumber_cursor();//sqlite3_malloc( sizeof(*pCur) );
//if ( pCur == null )
// return SQLITE_NOMEM;
//memset(pCur, 0, sizeof(*pCur));
ppCursor = pCur;//.base;
return SQLITE_OK;
}
/*
** Close a wholenumber cursor.
*/
static int wholenumberClose( ref sqlite3_vtab_cursor cur )
{
cur = null;// sqlite3_free( ref cur );
return SQLITE_OK;
}
/*
** Advance a cursor to its next row of output
*/
static int wholenumberNext( sqlite3_vtab_cursor cur )
{
wholenumber_cursor pCur = (wholenumber_cursor)cur;
pCur.iValue++;
return SQLITE_OK;
}
/*
** Return the value associated with a wholenumber.
*/
static int wholenumberColumn(
sqlite3_vtab_cursor cur,
sqlite3_context ctx,
int i
)
{
wholenumber_cursor pCur = (wholenumber_cursor)cur;
sqlite3_result_int64( ctx, pCur.iValue );
return SQLITE_OK;
}
/*
** The rowid.
*/
static int wholenumberRowid( sqlite3_vtab_cursor cur, out sqlite_int64 pRowid )
{
wholenumber_cursor pCur = (wholenumber_cursor)cur;
pRowid = pCur.iValue;
return SQLITE_OK;
}
/*
** When the wholenumber_cursor.rLimit value is 0 or less, that is a signal
** that the cursor has nothing more to output.
*/
static int wholenumberEof( sqlite3_vtab_cursor cur )
{
wholenumber_cursor pCur = (wholenumber_cursor)cur;
return ( pCur.iValue > pCur.mxValue || pCur.iValue == 0 ) ? 1 : 0;
}
/*
** Called to "rewind" a cursor back to the beginning so that
** it starts its output over again. Always called at least once
** prior to any wholenumberColumn, wholenumberRowid, or wholenumberEof call.
**
** idxNum Constraints
** ------ ---------------------
** 0 (none)
** 1 value > $argv0
** 2 value >= $argv0
** 4 value < $argv0
** 8 value <= $argv0
**
** 5 value > $argv0 AND value < $argv1
** 6 value >= $argv0 AND value < $argv1
** 9 value > $argv0 AND value <= $argv1
** 10 value >= $argv0 AND value <= $argv1
*/
static int wholenumberFilter(
sqlite3_vtab_cursor pVtabCursor,
int idxNum, string idxStr,
int argc, sqlite3_value[] argv
)
{
wholenumber_cursor pCur = (wholenumber_cursor)pVtabCursor;
sqlite3_int64 v;
int i = 0;
pCur.iValue = 1;
pCur.mxValue = 0xffffffff; /* 4294967295 */
if ( ( idxNum & 3 ) != 0 )
{
v = sqlite3_value_int64( argv[0] ) + ( idxNum & 1 );
if ( v > pCur.iValue && v <= pCur.mxValue )
pCur.iValue = (uint)v;
i++;
}
if ( ( idxNum & 12 ) != 0 )
{
v = sqlite3_value_int64( argv[i] ) - ( ( idxNum >> 2 ) & 1 );
if ( v >= pCur.iValue && v < pCur.mxValue )
pCur.mxValue = (uint)v;
}
return SQLITE_OK;
}
/*
** Search for terms of these forms:
**
** (1) value > $value
** (2) value >= $value
** (4) value < $value
** (8) value <= $value
**
** idxNum is an ORed combination of 1 or 2 with 4 or 8.
*/
static int wholenumberBestIndex(
sqlite3_vtab vtab,
ref sqlite3_index_info pIdxInfo
)
{
int i;
int idxNum = 0;
int argvIdx = 1;
int ltIdx = -1;
int gtIdx = -1;
sqlite3_index_constraint pConstraint;
//pConstraint = pIdxInfo.aConstraint;
for ( i = 0; i < pIdxInfo.nConstraint; i++ )//, pConstraint++)
{
pConstraint = pIdxInfo.aConstraint[i];
if ( pConstraint.usable == false )
continue;
if ( ( idxNum & 3 ) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_GT )
{
idxNum |= 1;
ltIdx = i;
}
if ( ( idxNum & 3 ) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_GE )
{
idxNum |= 2;
ltIdx = i;
}
if ( ( idxNum & 12 ) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_LT )
{
idxNum |= 4;
gtIdx = i;
}
if ( ( idxNum & 12 ) == 0 && pConstraint.op == SQLITE_INDEX_CONSTRAINT_LE )
{
idxNum |= 8;
gtIdx = i;
}
}
pIdxInfo.idxNum = idxNum;
if ( ltIdx >= 0 )
{
pIdxInfo.aConstraintUsage[ltIdx].argvIndex = argvIdx++;
pIdxInfo.aConstraintUsage[ltIdx].omit = true;
}
if ( gtIdx >= 0 )
{
pIdxInfo.aConstraintUsage[gtIdx].argvIndex = argvIdx;
pIdxInfo.aConstraintUsage[gtIdx].omit = true;
}
if ( pIdxInfo.nOrderBy == 1
&& pIdxInfo.aOrderBy[0].desc == false
)
{
pIdxInfo.orderByConsumed = true;
}
pIdxInfo.estimatedCost = (double)1;
return SQLITE_OK;
}
/*
** A virtual table module that provides read-only access to a
** Tcl global variable namespace.
*/
static sqlite3_module wholenumberModule = new sqlite3_module(
2, /* iVersion */
(smdxCreateConnect)wholenumberConnect,
(smdxCreateConnect)wholenumberConnect,
(smdxBestIndex)wholenumberBestIndex,
(smdxDisconnect)wholenumberDisconnect,
(smdxDestroy)wholenumberDisconnect,
(smdxOpen)wholenumberOpen, /* xOpen - open a cursor */
(smdxClose)wholenumberClose, /* xClose - close a cursor */
(smdxFilter)wholenumberFilter, /* xFilter - configure scan constraints */
(smdxNext)wholenumberNext, /* xNext - advance a cursor */
(smdxEof)wholenumberEof, /* xEof - check for end of scan */
(smdxColumn)wholenumberColumn, /* xColumn - read data */
(smdxRowid)wholenumberRowid, /* xRowid - read data */
null, /* xUpdate */
null, /* xBegin */
null, /* xSync */
null, /* xCommit */
null, /* xRollback */
null, /* xFindMethod */
null, /* xRename */
/* The methods above are in version 1 of the sqlite_module object. Those
** below are for version 2 and greater. */
null,
null,
null
);
#endif //* SQLITE_OMIT_VIRTUALTABLE */
/*
** Register the wholenumber virtual table
*/
static int wholenumber_register( sqlite3 db )
{
int rc = SQLITE_OK;
#if !SQLITE_OMIT_VIRTUALTABLE
rc = sqlite3_create_module( db, "wholenumber", wholenumberModule, null );
#endif
return rc;
}
#if SQLITE_TEST
//#include <tcl.h>
/*
** Decode a pointer to an sqlite3 object.
*/
//extern int getDbPointer(Tcl_Interp interp, string zA, sqlite3 **ppDb);
/*
** Register the echo virtual table module.
*/
static int register_wholenumber_module(
ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
Tcl_Interp interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj[] objv /* Command arguments */
)
{
sqlite3 db = null;
if ( objc != 2 )
{
TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB" );
return TCL.TCL_ERROR;
}
if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 )
return TCL.TCL_ERROR;
wholenumber_register( db );
return TCL.TCL_OK;
}
//static class _aObjCmd {
// public string zName;
// public Tcl_ObjCmdProc xProc;
// public object clientData;
//}
/*
** Register commands with the TCL interpreter.
*/
static public int Sqlitetestwholenumber_Init( Tcl_Interp interp )
{
_aObjCmd[] aObjCmd = new _aObjCmd[] {
new _aObjCmd( "register_wholenumber_module", register_wholenumber_module, 0 ),
};
int i;
for ( i = 0; i < aObjCmd.Length; i++ )
{//sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
TCL.Tcl_CreateObjCommand( interp, aObjCmd[i].zName,
aObjCmd[i].xProc, aObjCmd[i].clientData, null );
}
return TCL.TCL_OK;
}
#endif //* SQLITE_TEST */
}
#endif
}
Generated by GNU Enscript 1.6.5.90.