| Index: third_party/sqlite/sqlite-src-3080704/ext/misc/vtshim.c
|
| diff --git a/third_party/sqlite/sqlite-src-3080704/ext/misc/vtshim.c b/third_party/sqlite/sqlite-src-3080704/ext/misc/vtshim.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..01348e8d3eebbfe3161c0b55dd6cbc3d448ea161
|
| --- /dev/null
|
| +++ b/third_party/sqlite/sqlite-src-3080704/ext/misc/vtshim.c
|
| @@ -0,0 +1,551 @@
|
| +/*
|
| +** 2013-06-12
|
| +**
|
| +** 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.
|
| +**
|
| +*************************************************************************
|
| +**
|
| +** A shim that sits between the SQLite virtual table interface and
|
| +** runtimes with garbage collector based memory management.
|
| +*/
|
| +#include "sqlite3ext.h"
|
| +SQLITE_EXTENSION_INIT1
|
| +#include <assert.h>
|
| +#include <string.h>
|
| +
|
| +#ifndef SQLITE_OMIT_VIRTUALTABLE
|
| +
|
| +/* Forward references */
|
| +typedef struct vtshim_aux vtshim_aux;
|
| +typedef struct vtshim_vtab vtshim_vtab;
|
| +typedef struct vtshim_cursor vtshim_cursor;
|
| +
|
| +
|
| +/* The vtshim_aux argument is the auxiliary parameter that is passed
|
| +** into sqlite3_create_module_v2().
|
| +*/
|
| +struct vtshim_aux {
|
| + void *pChildAux; /* pAux for child virtual tables */
|
| + void (*xChildDestroy)(void*); /* Destructor for pChildAux */
|
| + sqlite3_module *pMod; /* Methods for child virtual tables */
|
| + sqlite3 *db; /* The database to which we are attached */
|
| + char *zName; /* Name of the module */
|
| + int bDisposed; /* True if disposed */
|
| + vtshim_vtab *pAllVtab; /* List of all vtshim_vtab objects */
|
| + sqlite3_module sSelf; /* Methods used by this shim */
|
| +};
|
| +
|
| +/* A vtshim virtual table object */
|
| +struct vtshim_vtab {
|
| + sqlite3_vtab base; /* Base class - must be first */
|
| + sqlite3_vtab *pChild; /* Child virtual table */
|
| + vtshim_aux *pAux; /* Pointer to vtshim_aux object */
|
| + vtshim_cursor *pAllCur; /* List of all cursors */
|
| + vtshim_vtab **ppPrev; /* Previous on list */
|
| + vtshim_vtab *pNext; /* Next on list */
|
| +};
|
| +
|
| +/* A vtshim cursor object */
|
| +struct vtshim_cursor {
|
| + sqlite3_vtab_cursor base; /* Base class - must be first */
|
| + sqlite3_vtab_cursor *pChild; /* Cursor generated by the managed subclass */
|
| + vtshim_cursor **ppPrev; /* Previous on list of all cursors */
|
| + vtshim_cursor *pNext; /* Next on list of all cursors */
|
| +};
|
| +
|
| +/* Macro used to copy the child vtable error message to outer vtable */
|
| +#define VTSHIM_COPY_ERRMSG() \
|
| + do { \
|
| + sqlite3_free(pVtab->base.zErrMsg); \
|
| + pVtab->base.zErrMsg = sqlite3_mprintf("%s", pVtab->pChild->zErrMsg); \
|
| + } while (0)
|
| +
|
| +/* Methods for the vtshim module */
|
| +static int vtshimCreate(
|
| + sqlite3 *db,
|
| + void *ppAux,
|
| + int argc,
|
| + const char *const*argv,
|
| + sqlite3_vtab **ppVtab,
|
| + char **pzErr
|
| +){
|
| + vtshim_aux *pAux = (vtshim_aux*)ppAux;
|
| + vtshim_vtab *pNew;
|
| + int rc;
|
| +
|
| + assert( db==pAux->db );
|
| + if( pAux->bDisposed ){
|
| + if( pzErr ){
|
| + *pzErr = sqlite3_mprintf("virtual table was disposed: \"%s\"",
|
| + pAux->zName);
|
| + }
|
| + return SQLITE_ERROR;
|
| + }
|
| + pNew = sqlite3_malloc( sizeof(*pNew) );
|
| + *ppVtab = (sqlite3_vtab*)pNew;
|
| + if( pNew==0 ) return SQLITE_NOMEM;
|
| + memset(pNew, 0, sizeof(*pNew));
|
| + rc = pAux->pMod->xCreate(db, pAux->pChildAux, argc, argv,
|
| + &pNew->pChild, pzErr);
|
| + if( rc ){
|
| + sqlite3_free(pNew);
|
| + *ppVtab = 0;
|
| + }
|
| + pNew->pAux = pAux;
|
| + pNew->ppPrev = &pAux->pAllVtab;
|
| + pNew->pNext = pAux->pAllVtab;
|
| + if( pAux->pAllVtab ) pAux->pAllVtab->ppPrev = &pNew->pNext;
|
| + pAux->pAllVtab = pNew;
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimConnect(
|
| + sqlite3 *db,
|
| + void *ppAux,
|
| + int argc,
|
| + const char *const*argv,
|
| + sqlite3_vtab **ppVtab,
|
| + char **pzErr
|
| +){
|
| + vtshim_aux *pAux = (vtshim_aux*)ppAux;
|
| + vtshim_vtab *pNew;
|
| + int rc;
|
| +
|
| + assert( db==pAux->db );
|
| + if( pAux->bDisposed ){
|
| + if( pzErr ){
|
| + *pzErr = sqlite3_mprintf("virtual table was disposed: \"%s\"",
|
| + pAux->zName);
|
| + }
|
| + return SQLITE_ERROR;
|
| + }
|
| + pNew = sqlite3_malloc( sizeof(*pNew) );
|
| + *ppVtab = (sqlite3_vtab*)pNew;
|
| + if( pNew==0 ) return SQLITE_NOMEM;
|
| + memset(pNew, 0, sizeof(*pNew));
|
| + rc = pAux->pMod->xConnect(db, pAux->pChildAux, argc, argv,
|
| + &pNew->pChild, pzErr);
|
| + if( rc ){
|
| + sqlite3_free(pNew);
|
| + *ppVtab = 0;
|
| + }
|
| + pNew->pAux = pAux;
|
| + pNew->ppPrev = &pAux->pAllVtab;
|
| + pNew->pNext = pAux->pAllVtab;
|
| + if( pAux->pAllVtab ) pAux->pAllVtab->ppPrev = &pNew->pNext;
|
| + pAux->pAllVtab = pNew;
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimBestIndex(
|
| + sqlite3_vtab *pBase,
|
| + sqlite3_index_info *pIdxInfo
|
| +){
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + rc = pAux->pMod->xBestIndex(pVtab->pChild, pIdxInfo);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimDisconnect(sqlite3_vtab *pBase){
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc = SQLITE_OK;
|
| + if( !pAux->bDisposed ){
|
| + rc = pAux->pMod->xDisconnect(pVtab->pChild);
|
| + }
|
| + if( pVtab->pNext ) pVtab->pNext->ppPrev = pVtab->ppPrev;
|
| + *pVtab->ppPrev = pVtab->pNext;
|
| + sqlite3_free(pVtab);
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimDestroy(sqlite3_vtab *pBase){
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc = SQLITE_OK;
|
| + if( !pAux->bDisposed ){
|
| + rc = pAux->pMod->xDestroy(pVtab->pChild);
|
| + }
|
| + if( pVtab->pNext ) pVtab->pNext->ppPrev = pVtab->ppPrev;
|
| + *pVtab->ppPrev = pVtab->pNext;
|
| + sqlite3_free(pVtab);
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimOpen(sqlite3_vtab *pBase, sqlite3_vtab_cursor **ppCursor){
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + vtshim_cursor *pCur;
|
| + int rc;
|
| + *ppCursor = 0;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + pCur = sqlite3_malloc( sizeof(*pCur) );
|
| + if( pCur==0 ) return SQLITE_NOMEM;
|
| + memset(pCur, 0, sizeof(*pCur));
|
| + rc = pAux->pMod->xOpen(pVtab->pChild, &pCur->pChild);
|
| + if( rc ){
|
| + sqlite3_free(pCur);
|
| + VTSHIM_COPY_ERRMSG();
|
| + return rc;
|
| + }
|
| + pCur->pChild->pVtab = pVtab->pChild;
|
| + *ppCursor = &pCur->base;
|
| + pCur->ppPrev = &pVtab->pAllCur;
|
| + if( pVtab->pAllCur ) pVtab->pAllCur->ppPrev = &pCur->pNext;
|
| + pCur->pNext = pVtab->pAllCur;
|
| + pVtab->pAllCur = pCur;
|
| + return SQLITE_OK;
|
| +}
|
| +
|
| +static int vtshimClose(sqlite3_vtab_cursor *pX){
|
| + vtshim_cursor *pCur = (vtshim_cursor*)pX;
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pCur->base.pVtab;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc = SQLITE_OK;
|
| + if( !pAux->bDisposed ){
|
| + rc = pAux->pMod->xClose(pCur->pChild);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + }
|
| + if( pCur->pNext ) pCur->pNext->ppPrev = pCur->ppPrev;
|
| + *pCur->ppPrev = pCur->pNext;
|
| + sqlite3_free(pCur);
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimFilter(
|
| + sqlite3_vtab_cursor *pX,
|
| + int idxNum,
|
| + const char *idxStr,
|
| + int argc,
|
| + sqlite3_value **argv
|
| +){
|
| + vtshim_cursor *pCur = (vtshim_cursor*)pX;
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pCur->base.pVtab;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + rc = pAux->pMod->xFilter(pCur->pChild, idxNum, idxStr, argc, argv);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimNext(sqlite3_vtab_cursor *pX){
|
| + vtshim_cursor *pCur = (vtshim_cursor*)pX;
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pCur->base.pVtab;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + rc = pAux->pMod->xNext(pCur->pChild);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimEof(sqlite3_vtab_cursor *pX){
|
| + vtshim_cursor *pCur = (vtshim_cursor*)pX;
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pCur->base.pVtab;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return 1;
|
| + rc = pAux->pMod->xEof(pCur->pChild);
|
| + VTSHIM_COPY_ERRMSG();
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimColumn(sqlite3_vtab_cursor *pX, sqlite3_context *ctx, int i){
|
| + vtshim_cursor *pCur = (vtshim_cursor*)pX;
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pCur->base.pVtab;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + rc = pAux->pMod->xColumn(pCur->pChild, ctx, i);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimRowid(sqlite3_vtab_cursor *pX, sqlite3_int64 *pRowid){
|
| + vtshim_cursor *pCur = (vtshim_cursor*)pX;
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pCur->base.pVtab;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + rc = pAux->pMod->xRowid(pCur->pChild, pRowid);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimUpdate(
|
| + sqlite3_vtab *pBase,
|
| + int argc,
|
| + sqlite3_value **argv,
|
| + sqlite3_int64 *pRowid
|
| +){
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + rc = pAux->pMod->xUpdate(pVtab->pChild, argc, argv, pRowid);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimBegin(sqlite3_vtab *pBase){
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + rc = pAux->pMod->xBegin(pVtab->pChild);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimSync(sqlite3_vtab *pBase){
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + rc = pAux->pMod->xSync(pVtab->pChild);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimCommit(sqlite3_vtab *pBase){
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + rc = pAux->pMod->xCommit(pVtab->pChild);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimRollback(sqlite3_vtab *pBase){
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + rc = pAux->pMod->xRollback(pVtab->pChild);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimFindFunction(
|
| + sqlite3_vtab *pBase,
|
| + int nArg,
|
| + const char *zName,
|
| + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
|
| + void **ppArg
|
| +){
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return 0;
|
| + rc = pAux->pMod->xFindFunction(pVtab->pChild, nArg, zName, pxFunc, ppArg);
|
| + VTSHIM_COPY_ERRMSG();
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimRename(sqlite3_vtab *pBase, const char *zNewName){
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + rc = pAux->pMod->xRename(pVtab->pChild, zNewName);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimSavepoint(sqlite3_vtab *pBase, int n){
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + rc = pAux->pMod->xSavepoint(pVtab->pChild, n);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimRelease(sqlite3_vtab *pBase, int n){
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + rc = pAux->pMod->xRelease(pVtab->pChild, n);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +static int vtshimRollbackTo(sqlite3_vtab *pBase, int n){
|
| + vtshim_vtab *pVtab = (vtshim_vtab*)pBase;
|
| + vtshim_aux *pAux = pVtab->pAux;
|
| + int rc;
|
| + if( pAux->bDisposed ) return SQLITE_ERROR;
|
| + rc = pAux->pMod->xRollbackTo(pVtab->pChild, n);
|
| + if( rc!=SQLITE_OK ){
|
| + VTSHIM_COPY_ERRMSG();
|
| + }
|
| + return rc;
|
| +}
|
| +
|
| +/* The destructor function for a disposible module */
|
| +static void vtshimAuxDestructor(void *pXAux){
|
| + vtshim_aux *pAux = (vtshim_aux*)pXAux;
|
| + assert( pAux->pAllVtab==0 );
|
| + if( !pAux->bDisposed && pAux->xChildDestroy ){
|
| + pAux->xChildDestroy(pAux->pChildAux);
|
| + pAux->xChildDestroy = 0;
|
| + }
|
| + sqlite3_free(pAux->zName);
|
| + sqlite3_free(pAux->pMod);
|
| + sqlite3_free(pAux);
|
| +}
|
| +
|
| +static int vtshimCopyModule(
|
| + const sqlite3_module *pMod, /* Source module to be copied */
|
| + sqlite3_module **ppMod /* Destination for copied module */
|
| +){
|
| + sqlite3_module *p;
|
| + if( !pMod || !ppMod ) return SQLITE_ERROR;
|
| + p = sqlite3_malloc( sizeof(*p) );
|
| + if( p==0 ) return SQLITE_NOMEM;
|
| + memcpy(p, pMod, sizeof(*p));
|
| + *ppMod = p;
|
| + return SQLITE_OK;
|
| +}
|
| +
|
| +#ifdef _WIN32
|
| +__declspec(dllexport)
|
| +#endif
|
| +void *sqlite3_create_disposable_module(
|
| + sqlite3 *db, /* SQLite connection to register module with */
|
| + const char *zName, /* Name of the module */
|
| + const sqlite3_module *p, /* Methods for the module */
|
| + void *pClientData, /* Client data for xCreate/xConnect */
|
| + void(*xDestroy)(void*) /* Module destructor function */
|
| +){
|
| + vtshim_aux *pAux;
|
| + sqlite3_module *pMod;
|
| + int rc;
|
| + pAux = sqlite3_malloc( sizeof(*pAux) );
|
| + if( pAux==0 ){
|
| + if( xDestroy ) xDestroy(pClientData);
|
| + return 0;
|
| + }
|
| + rc = vtshimCopyModule(p, &pMod);
|
| + if( rc!=SQLITE_OK ){
|
| + sqlite3_free(pAux);
|
| + return 0;
|
| + }
|
| + pAux->pChildAux = pClientData;
|
| + pAux->xChildDestroy = xDestroy;
|
| + pAux->pMod = pMod;
|
| + pAux->db = db;
|
| + pAux->zName = sqlite3_mprintf("%s", zName);
|
| + pAux->bDisposed = 0;
|
| + pAux->pAllVtab = 0;
|
| + pAux->sSelf.iVersion = p->iVersion<=2 ? p->iVersion : 2;
|
| + pAux->sSelf.xCreate = p->xCreate ? vtshimCreate : 0;
|
| + pAux->sSelf.xConnect = p->xConnect ? vtshimConnect : 0;
|
| + pAux->sSelf.xBestIndex = p->xBestIndex ? vtshimBestIndex : 0;
|
| + pAux->sSelf.xDisconnect = p->xDisconnect ? vtshimDisconnect : 0;
|
| + pAux->sSelf.xDestroy = p->xDestroy ? vtshimDestroy : 0;
|
| + pAux->sSelf.xOpen = p->xOpen ? vtshimOpen : 0;
|
| + pAux->sSelf.xClose = p->xClose ? vtshimClose : 0;
|
| + pAux->sSelf.xFilter = p->xFilter ? vtshimFilter : 0;
|
| + pAux->sSelf.xNext = p->xNext ? vtshimNext : 0;
|
| + pAux->sSelf.xEof = p->xEof ? vtshimEof : 0;
|
| + pAux->sSelf.xColumn = p->xColumn ? vtshimColumn : 0;
|
| + pAux->sSelf.xRowid = p->xRowid ? vtshimRowid : 0;
|
| + pAux->sSelf.xUpdate = p->xUpdate ? vtshimUpdate : 0;
|
| + pAux->sSelf.xBegin = p->xBegin ? vtshimBegin : 0;
|
| + pAux->sSelf.xSync = p->xSync ? vtshimSync : 0;
|
| + pAux->sSelf.xCommit = p->xCommit ? vtshimCommit : 0;
|
| + pAux->sSelf.xRollback = p->xRollback ? vtshimRollback : 0;
|
| + pAux->sSelf.xFindFunction = p->xFindFunction ? vtshimFindFunction : 0;
|
| + pAux->sSelf.xRename = p->xRename ? vtshimRename : 0;
|
| + if( p->iVersion>=2 ){
|
| + pAux->sSelf.xSavepoint = p->xSavepoint ? vtshimSavepoint : 0;
|
| + pAux->sSelf.xRelease = p->xRelease ? vtshimRelease : 0;
|
| + pAux->sSelf.xRollbackTo = p->xRollbackTo ? vtshimRollbackTo : 0;
|
| + }else{
|
| + pAux->sSelf.xSavepoint = 0;
|
| + pAux->sSelf.xRelease = 0;
|
| + pAux->sSelf.xRollbackTo = 0;
|
| + }
|
| + rc = sqlite3_create_module_v2(db, zName, &pAux->sSelf,
|
| + pAux, vtshimAuxDestructor);
|
| + return rc==SQLITE_OK ? (void*)pAux : 0;
|
| +}
|
| +
|
| +#ifdef _WIN32
|
| +__declspec(dllexport)
|
| +#endif
|
| +void sqlite3_dispose_module(void *pX){
|
| + vtshim_aux *pAux = (vtshim_aux*)pX;
|
| + if( !pAux->bDisposed ){
|
| + vtshim_vtab *pVtab;
|
| + vtshim_cursor *pCur;
|
| + for(pVtab=pAux->pAllVtab; pVtab; pVtab=pVtab->pNext){
|
| + for(pCur=pVtab->pAllCur; pCur; pCur=pCur->pNext){
|
| + pAux->pMod->xClose(pCur->pChild);
|
| + }
|
| + pAux->pMod->xDisconnect(pVtab->pChild);
|
| + }
|
| + pAux->bDisposed = 1;
|
| + if( pAux->xChildDestroy ){
|
| + pAux->xChildDestroy(pAux->pChildAux);
|
| + pAux->xChildDestroy = 0;
|
| + }
|
| + }
|
| +}
|
| +
|
| +
|
| +#endif /* SQLITE_OMIT_VIRTUALTABLE */
|
| +
|
| +#ifdef _WIN32
|
| +__declspec(dllexport)
|
| +#endif
|
| +int sqlite3_vtshim_init(
|
| + sqlite3 *db,
|
| + char **pzErrMsg,
|
| + const sqlite3_api_routines *pApi
|
| +){
|
| + SQLITE_EXTENSION_INIT2(pApi);
|
| + return SQLITE_OK;
|
| +}
|
|
|