/*** 2009 November 10**** 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 read-only VIRTUAL TABLE that contains the** content of a C-language array of integer values. See the corresponding** header file for full details.**** This virtual table is used for internal testing of SQLite only. It is** not recommended for use in production. For a similar virtual table that** is production-ready, see the "carray" virtual table over in ext/misc.*/#include "test_intarray.h"#include <string.h>#include <assert.h>/*** Definition of the sqlite3_intarray object.**** The internal representation of an intarray object is subject** to change, is not externally visible, and should be used by** the implementation of intarray only. This object is opaque** to users.*/struct sqlite3_intarray {int n; /* Number of elements in the array */sqlite3_int64 *a; /* Contents of the array */void (*xFree)(void*); /* Function used to free a[] */};/* Objects used internally by the virtual table implementation */typedef struct intarray_vtab intarray_vtab;typedef struct intarray_cursor intarray_cursor;/* An intarray table object */struct intarray_vtab {sqlite3_vtab base; /* Base class */sqlite3_intarray *pContent; /* Content of the integer array */};/* An intarray cursor object */struct intarray_cursor {sqlite3_vtab_cursor base; /* Base class */int i; /* Current cursor position */};/*** None of this works unless we have virtual tables.*/#ifndef SQLITE_OMIT_VIRTUALTABLE/*** Free an sqlite3_intarray object.*/static void intarrayFree(sqlite3_intarray *p){if( p->xFree ){p->xFree(p->a);}sqlite3_free(p);}/*** Table destructor for the intarray module.*/static int intarrayDestroy(sqlite3_vtab *p){intarray_vtab *pVtab = (intarray_vtab*)p;sqlite3_free(pVtab);return 0;}/*** Table constructor for the intarray module.*/static int intarrayCreate(sqlite3 *db, /* Database where module is created */void *pAux, /* clientdata for the module */int argc, /* Number of arguments */const char *const*argv, /* Value for all arguments */sqlite3_vtab **ppVtab, /* Write the new virtual table object here */char **pzErr /* Put error message text here */){int rc = SQLITE_NOMEM;intarray_vtab *pVtab = sqlite3_malloc64(sizeof(intarray_vtab));if( pVtab ){memset(pVtab, 0, sizeof(intarray_vtab));pVtab->pContent = (sqlite3_intarray*)pAux;rc = sqlite3_declare_vtab(db, "CREATE TABLE x(value INTEGER PRIMARY KEY)");}*ppVtab = (sqlite3_vtab *)pVtab;return rc;}/*** Open a new cursor on the intarray table.*/static int intarrayOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){int rc = SQLITE_NOMEM;intarray_cursor *pCur;pCur = sqlite3_malloc64(sizeof(intarray_cursor));if( pCur ){memset(pCur, 0, sizeof(intarray_cursor));*ppCursor = (sqlite3_vtab_cursor *)pCur;rc = SQLITE_OK;}return rc;}/*** Close a intarray table cursor.*/static int intarrayClose(sqlite3_vtab_cursor *cur){intarray_cursor *pCur = (intarray_cursor *)cur;sqlite3_free(pCur);return SQLITE_OK;}/*** Retrieve a column of data.*/static int intarrayColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){intarray_cursor *pCur = (intarray_cursor*)cur;intarray_vtab *pVtab = (intarray_vtab*)cur->pVtab;if( pCur->i>=0 && pCur->i<pVtab->pContent->n ){sqlite3_result_int64(ctx, pVtab->pContent->a[pCur->i]);}return SQLITE_OK;}/*** Retrieve the current rowid.*/static int intarrayRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){intarray_cursor *pCur = (intarray_cursor *)cur;*pRowid = pCur->i;return SQLITE_OK;}static int intarrayEof(sqlite3_vtab_cursor *cur){intarray_cursor *pCur = (intarray_cursor *)cur;intarray_vtab *pVtab = (intarray_vtab *)cur->pVtab;return pCur->i>=pVtab->pContent->n;}/*** Advance the cursor to the next row.*/static int intarrayNext(sqlite3_vtab_cursor *cur){intarray_cursor *pCur = (intarray_cursor *)cur;pCur->i++;return SQLITE_OK;}/*** Reset a intarray table cursor.*/static int intarrayFilter(sqlite3_vtab_cursor *pVtabCursor,int idxNum, const char *idxStr,int argc, sqlite3_value **argv){intarray_cursor *pCur = (intarray_cursor *)pVtabCursor;pCur->i = 0;return SQLITE_OK;}/*** Analyse the WHERE condition.*/static int intarrayBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){return SQLITE_OK;}/*** A virtual table module that merely echos method calls into TCL** variables.*/static sqlite3_module intarrayModule = {0, /* iVersion */intarrayCreate, /* xCreate - create a new virtual table */intarrayCreate, /* xConnect - connect to an existing vtab */intarrayBestIndex, /* xBestIndex - find the best query index */intarrayDestroy, /* xDisconnect - disconnect a vtab */intarrayDestroy, /* xDestroy - destroy a vtab */intarrayOpen, /* xOpen - open a cursor */intarrayClose, /* xClose - close a cursor */intarrayFilter, /* xFilter - configure scan constraints */intarrayNext, /* xNext - advance a cursor */intarrayEof, /* xEof */intarrayColumn, /* xColumn - read data */intarrayRowid, /* xRowid - read data */0, /* xUpdate */0, /* xBegin */0, /* xSync */0, /* xCommit */0, /* xRollback */0, /* xFindMethod */0, /* xRename */0, /* xSavepoint */0, /* xRelease */0, /* xRollbackTo */0, /* xShadowName */0 /* xIntegrity */};#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) *//*** Invoke this routine to create a specific instance of an intarray object.** The new intarray object is returned by the 3rd parameter.**** Each intarray object corresponds to a virtual table in the TEMP table** with a name of zName.**** Destroy the intarray object by dropping the virtual table. If not done** explicitly by the application, the virtual table will be dropped implicitly** by the system when the database connection is closed.*/SQLITE_API int sqlite3_intarray_create(sqlite3 *db,const char *zName,sqlite3_intarray **ppReturn){int rc = SQLITE_OK;#ifndef SQLITE_OMIT_VIRTUALTABLEsqlite3_intarray *p;*ppReturn = p = sqlite3_malloc64( sizeof(*p) );if( p==0 ){return SQLITE_NOMEM;}memset(p, 0, sizeof(*p));rc = sqlite3_create_module_v2(db, zName, &intarrayModule, p,(void(*)(void*))intarrayFree);if( rc==SQLITE_OK ){char *zSql;zSql = sqlite3_mprintf("CREATE VIRTUAL TABLE temp.%Q USING %Q",zName, zName);rc = sqlite3_exec(db, zSql, 0, 0, 0);sqlite3_free(zSql);}#endifreturn rc;}/*** Bind a new array array of integers to a specific intarray object.**** The array of integers bound must be unchanged for the duration of** any query against the corresponding virtual table. If the integer** array does change or is deallocated undefined behavior will result.*/SQLITE_API int sqlite3_intarray_bind(sqlite3_intarray *pIntArray, /* The intarray object to bind to */int nElements, /* Number of elements in the intarray */sqlite3_int64 *aElements, /* Content of the intarray */void (*xFree)(void*) /* How to dispose of the intarray when done */){if( pIntArray->xFree ){pIntArray->xFree(pIntArray->a);}pIntArray->n = nElements;pIntArray->a = aElements;pIntArray->xFree = xFree;return SQLITE_OK;}/******************************************************************************* Everything below is interface for testing this module.*/#ifdef SQLITE_TEST#if defined(INCLUDE_SQLITE_TCL_H)# include "sqlite_tcl.h"#else# include "tcl.h"# ifndef SQLITE_TCLAPI# define SQLITE_TCLAPI# endif#endif/*** Routines to encode and decode pointers*/extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);extern void *sqlite3TestTextToPtr(const char*);extern int sqlite3TestMakePointerStr(Tcl_Interp*, char *zPtr, void*);extern const char *sqlite3ErrName(int);/*** sqlite3_intarray_create DB NAME**** Invoke the sqlite3_intarray_create interface. A string that becomes** the first parameter to sqlite3_intarray_bind.*/static int SQLITE_TCLAPI test_intarray_create(ClientData clientData, /* Not used */Tcl_Interp *interp, /* The TCL interpreter that invoked this command */int objc, /* Number of arguments */Tcl_Obj *CONST objv[] /* Command arguments */){sqlite3 *db;const char *zName;sqlite3_intarray *pArray;int rc = SQLITE_OK;char zPtr[100];if( objc!=3 ){Tcl_WrongNumArgs(interp, 1, objv, "DB");return TCL_ERROR;}if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;zName = Tcl_GetString(objv[2]);#ifndef SQLITE_OMIT_VIRTUALTABLErc = sqlite3_intarray_create(db, zName, &pArray);#endifif( rc!=SQLITE_OK ){Tcl_AppendResult(interp, sqlite3ErrName(rc), (char*)0);return TCL_ERROR;}sqlite3TestMakePointerStr(interp, zPtr, pArray);Tcl_AppendResult(interp, zPtr, (char*)0);return TCL_OK;}/*** sqlite3_intarray_bind INTARRAY ?VALUE ...?**** Invoke the sqlite3_intarray_bind interface on the given array of integers.*/static int SQLITE_TCLAPI test_intarray_bind(ClientData clientData, /* Not used */Tcl_Interp *interp, /* The TCL interpreter that invoked this command */int objc, /* Number of arguments */Tcl_Obj *CONST objv[] /* Command arguments */){sqlite3_intarray *pArray;int rc = SQLITE_OK;int i, n;sqlite3_int64 *a;if( objc<2 ){Tcl_WrongNumArgs(interp, 1, objv, "INTARRAY");return TCL_ERROR;}pArray = (sqlite3_intarray*)sqlite3TestTextToPtr(Tcl_GetString(objv[1]));n = objc - 2;#ifndef SQLITE_OMIT_VIRTUALTABLEa = sqlite3_malloc64( sizeof(a[0])*n );if( a==0 ){Tcl_AppendResult(interp, "SQLITE_NOMEM", (char*)0);return TCL_ERROR;}for(i=0; i<n; i++){Tcl_WideInt x = 0;Tcl_GetWideIntFromObj(0, objv[i+2], &x);a[i] = x;}rc = sqlite3_intarray_bind(pArray, n, a, sqlite3_free);if( rc!=SQLITE_OK ){Tcl_AppendResult(interp, sqlite3ErrName(rc), (char*)0);return TCL_ERROR;}#endifreturn TCL_OK;}/*** Register commands with the TCL interpreter.*/int Sqlitetestintarray_Init(Tcl_Interp *interp){static struct {char *zName;Tcl_ObjCmdProc *xProc;void *clientData;} aObjCmd[] = {{ "sqlite3_intarray_create", test_intarray_create, 0 },{ "sqlite3_intarray_bind", test_intarray_bind, 0 },};int i;for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){Tcl_CreateObjCommand(interp, aObjCmd[i].zName,aObjCmd[i].xProc, aObjCmd[i].clientData, 0);}return TCL_OK;}#endif /* SQLITE_TEST */
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。