diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/delete.c | 4 | ||||
-rw-r--r-- | src/main.c | 6 | ||||
-rw-r--r-- | src/sqlite.h.in | 6 | ||||
-rw-r--r-- | src/sqliteInt.h | 16 | ||||
-rw-r--r-- | src/test8.c | 6 | ||||
-rw-r--r-- | src/test_tclvar.c | 7 | ||||
-rw-r--r-- | src/vtab.c | 62 |
7 files changed, 67 insertions, 40 deletions
diff --git a/src/delete.c b/src/delete.c index 37b8577d8..f1cdcdb9a 100644 --- a/src/delete.c +++ b/src/delete.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** -** $Id: delete.c,v 1.124 2006/06/14 19:00:21 drh Exp $ +** $Id: delete.c,v 1.125 2006/06/15 04:28:13 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -45,7 +45,7 @@ int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ if( (pTab->readOnly && (pParse->db->flags & SQLITE_WriteSchema)==0 && pParse->nested==0) #ifndef SQLITE_OMIT_VIRTUALTABLE - || (pTab->pModule && pTab->pModule->xUpdate==0) + || (pTab->pMod && pTab->pMod->pModule->xUpdate==0) #endif ){ sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); diff --git a/src/main.c b/src/main.c index 526eaed6a..463ba997a 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.343 2006/06/14 15:35:37 drh Exp $ +** $Id: main.c,v 1.344 2006/06/15 04:28:13 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -160,6 +160,10 @@ int sqlite3_close(sqlite3 *db){ } sqlite3HashClear(&db->aCollSeq); #ifndef SQLITE_OMIT_VIRTUALTABLE + for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ + Module *pMod = (Module *)sqliteHashData(i); + sqliteFree(pMod); + } sqlite3HashClear(&db->aModule); #endif diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 2f8f1443c..68f3a568b 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.176 2006/06/14 13:03:23 danielk1977 Exp $ +** @(#) $Id: sqlite.h.in,v 1.177 2006/06/15 04:28:13 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -1536,7 +1536,6 @@ typedef struct sqlite3_module sqlite3_module; struct sqlite3_module { int iVersion; const char *zName; - void *pAux; int (*xCreate)(sqlite3*, void *pAux, int argc, char **argv, sqlite3_vtab **ppVTab); @@ -1649,7 +1648,8 @@ struct sqlite3_index_info { int sqlite3_create_module( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ - const sqlite3_module * /* Methods for the module */ + const sqlite3_module *, /* Methods for the module */ + void * /* Client data for xCreate/xConnect */ ); /* diff --git a/src/sqliteInt.h b/src/sqliteInt.h index fcc147adf..f51ead317 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.505 2006/06/14 19:00:21 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.506 2006/06/15 04:28:13 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -343,6 +343,7 @@ typedef struct IdList IdList; typedef struct Index Index; typedef struct KeyClass KeyClass; typedef struct KeyInfo KeyInfo; +typedef struct Module Module; typedef struct NameContext NameContext; typedef struct Parse Parse; typedef struct Select Select; @@ -567,6 +568,17 @@ struct FuncDef { }; /* +** Each SQLite module (virtual table definition) is defined by an +** instance of the following structure, stored in the sqlite3.aModule +** hash table. +*/ +struct Module { + const sqlite3_module *pModule; /* Callback pointers */ + const char *zName; /* Name passed to create_module() */ + void *pAux; /* pAux passed to create_module() */ +}; + +/* ** Possible values for FuncDef.flags */ #define SQLITE_FUNC_LIKE 0x01 /* Candidate for the LIKE optimization */ @@ -705,7 +717,7 @@ struct Table { int addColOffset; /* Offset in CREATE TABLE statement to add a new column */ #endif #ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3_module *pModule; /* Pointer to the implementation of the module */ + Module *pMod; /* Pointer to the implementation of the module */ sqlite3_vtab *pVtab; /* Pointer to the module instance */ u8 isVirtual; /* True if this is a virtual table */ int nModuleArg; /* Number of arguments to the module */ diff --git a/src/test8.c b/src/test8.c index 774221635..ead66444f 100644 --- a/src/test8.c +++ b/src/test8.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test8.c,v 1.19 2006/06/14 23:43:31 drh Exp $ +** $Id: test8.c,v 1.20 2006/06/15 04:28:13 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -622,7 +622,6 @@ int echoUpdate(sqlite3_vtab *tab, int nData, sqlite3_value **apData){ static sqlite3_module echoModule = { 0, /* iVersion */ "echo", /* zName */ - 0, /* pAux */ echoCreate, echoConnect, echoBestIndex, @@ -661,9 +660,8 @@ static int register_echo_module( return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; - echoModule.pAux = interp; #ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3_create_module(db, "echo", &echoModule); + sqlite3_create_module(db, "echo", &echoModule, (void *)interp); #endif return TCL_OK; } diff --git a/src/test_tclvar.c b/src/test_tclvar.c index fc474bb70..daa86e780 100644 --- a/src/test_tclvar.c +++ b/src/test_tclvar.c @@ -16,7 +16,7 @@ ** The emphasis of this file is a virtual table that provides ** access to TCL variables. ** -** $Id: test_tclvar.c,v 1.2 2006/06/14 06:58:16 danielk1977 Exp $ +** $Id: test_tclvar.c,v 1.3 2006/06/15 04:28:13 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" @@ -65,6 +65,7 @@ static int tclvarConnect( ** methods are identical. */ static int tclvarDisconnect(sqlite3_vtab *pVtab){ free(pVtab); + return SQLITE_OK; } /* The xDisconnect and xDestroy methods are also the same */ @@ -126,7 +127,6 @@ static int tclvarBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ static sqlite3_module tclvarModule = { 0, /* iVersion */ "tclvar", /* zName */ - 0, /* pAux */ tclvarConnect, tclvarConnect, tclvarBestIndex, @@ -164,9 +164,8 @@ static int register_tclvar_module( return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; - tclvarModule.pAux = interp; #ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3_create_module(db, "tclvar", &tclvarModule); + sqlite3_create_module(db, "tclvar", &tclvarModule, (void *)interp); #endif return TCL_OK; } diff --git a/src/vtab.c b/src/vtab.c index a7fd6a88e..727ee5117 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to help implement virtual tables. ** -** $Id: vtab.c,v 1.11 2006/06/14 13:03:24 danielk1977 Exp $ +** $Id: vtab.c,v 1.12 2006/06/15 04:28:13 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" @@ -22,11 +22,22 @@ int sqlite3_create_module( sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ - const sqlite3_module *pModule /* The definition of the module */ + const sqlite3_module *pModule, /* The definition of the module */ + void *pAux /* Context pointer for xCreate/xConnect */ ){ - sqlite3HashInsert(&db->aModule, zName, strlen(zName), (void*)pModule); - sqlite3ResetInternalSchema(db, 0); - return SQLITE_OK; + int nName = strlen(zName); + Module *pMod = (Module *)sqliteMallocRaw(sizeof(Module) + nName + 1); + if( pMod ){ + char *zCopy = (char *)(&pMod[1]); + strcpy(zCopy, zName); + pMod->zName = zCopy; + pMod->pModule = pModule; + pMod->pAux = pAux; + pMod = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod); + sqliteFree(pMod); + sqlite3ResetInternalSchema(db, 0); + } + return sqlite3ApiExit(db, SQLITE_OK); } /* @@ -36,8 +47,8 @@ int sqlite3_create_module( */ void sqlite3VtabClear(Table *p){ if( p->pVtab ){ - assert( p->pModule!=0 ); - p->pModule->xDisconnect(p->pVtab); + assert( p->pMod && p->pMod->pModule ); + p->pMod->pModule->xDisconnect(p->pVtab); } if( p->azModuleArg ){ int i; @@ -116,6 +127,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ Table *pTab; /* The table being constructed */ sqlite3 *db; /* The database connection */ char *zModule; /* The module name of the table: USING modulename */ + Module *pMod = 0; addArgumentToVtab(pParse); sqliteFree(pParse->zArg); @@ -128,8 +140,8 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ db = pParse->db; if( pTab->nModuleArg<1 ) return; zModule = pTab->azModuleArg[0]; - pTab->pModule = (sqlite3_module*)sqlite3HashFind(&db->aModule, - zModule, strlen(zModule)); + pMod = (Module *)sqlite3HashFind(&db->aModule, zModule, strlen(zModule)); + pTab->pMod = pMod; /* If the CREATE VIRTUAL TABLE statement is being entered for the ** first time (in other words if the virtual table is actually being @@ -142,7 +154,7 @@ void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ char *zWhere; int iDb; Vdbe *v; - if( pTab->pModule==0 ){ + if( !pMod ){ sqlite3ErrorMsg(pParse, "no such module: %s", zModule); } @@ -241,7 +253,7 @@ void sqlite3VtabArgExtend(Parse *pParse, Token *p){ static int vtabCallConstructor( sqlite3 *db, Table *pTab, - sqlite3_module *pModule, + Module *pMod, int (*xConstruct)(sqlite3*, void *, int, char **, sqlite3_vtab **), char **pzErr ){ @@ -256,10 +268,10 @@ static int vtabCallConstructor( db->pVTab = pTab; rc = sqlite3SafetyOff(db); assert( rc==SQLITE_OK ); - rc = xConstruct(db, pModule->pAux, nArg, azArg, &pTab->pVtab); + rc = xConstruct(db, pMod->pAux, nArg, azArg, &pTab->pVtab); rc2 = sqlite3SafetyOn(db); if( pTab->pVtab ){ - pTab->pVtab->pModule = pModule; + pTab->pVtab->pModule = pMod->pModule; } if( SQLITE_OK!=rc ){ @@ -284,7 +296,7 @@ static int vtabCallConstructor( ** This call is a no-op if table pTab is not a virtual table. */ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ - sqlite3_module *pModule; + Module *pMod; const char *zModule; int rc = SQLITE_OK; @@ -292,15 +304,16 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ return SQLITE_OK; } - pModule = pTab->pModule; + pMod = pTab->pMod; zModule = pTab->azModuleArg[0]; - if( !pModule ){ + if( !pMod ){ const char *zModule = pTab->azModuleArg[0]; sqlite3ErrorMsg(pParse, "no such module: %s", zModule); rc = SQLITE_ERROR; } else { char *zErr = 0; - rc = vtabCallConstructor(pParse->db,pTab,pModule,pModule->xConnect,&zErr); + sqlite3 *db = pParse->db; + rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr); if( rc!=SQLITE_OK ){ sqlite3ErrorMsg(pParse, "%s", zErr); } @@ -321,23 +334,23 @@ int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ int rc = SQLITE_OK; Table *pTab; - sqlite3_module *pModule; + Module *pMod; const char *zModule; pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); assert(pTab && pTab->isVirtual && !pTab->pVtab); - pModule = pTab->pModule; + pMod = pTab->pMod; zModule = pTab->azModuleArg[0]; /* If the module has been registered and includes a Create method, ** invoke it now. If the module has not been registered, return an ** error. Otherwise, do nothing. */ - if( !pModule ){ + if( !pMod ){ *pzErr = sqlite3MPrintf("no such module: %s", zModule); rc = SQLITE_ERROR; }else{ - rc = vtabCallConstructor(db, pTab, pModule, pModule->xCreate, pzErr); + rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr); } return rc; @@ -401,15 +414,16 @@ int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab) { int rc = SQLITE_OK; Table *pTab; - sqlite3_module *pModule; pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); - pModule = pTab->pModule; assert(pTab); if( pTab->pVtab ){ + int (*xDestroy)(sqlite3_vtab *pVTab) = pTab->pMod->pModule->xDestroy; rc = sqlite3SafetyOff(db); assert( rc==SQLITE_OK ); - rc = pModule->xDestroy(pTab->pVtab); + if( xDestroy ){ + rc = xDestroy(pTab->pVtab); + } sqlite3SafetyOn(db); if( rc==SQLITE_OK ){ pTab->pVtab = 0; |