From 1b5ba8e022836fa8ab93bc90df1b34a29ea6e134 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Thu, 17 Jan 2013 14:18:26 -0500 Subject: Imported Upstream version 2.1.1 --- src/vtab.c | 77 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 25 deletions(-) (limited to 'src/vtab.c') diff --git a/src/vtab.c b/src/vtab.c index c561f71..50d576f 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -22,8 +22,8 @@ ** are invoked only from within xCreate and xConnect methods. */ struct VtabCtx { - Table *pTab; - VTable *pVTable; + VTable *pVTable; /* The virtual table being constructed */ + Table *pTab; /* The Table object to which the virtual table belongs */ }; /* @@ -38,33 +38,35 @@ static int createModule( void *pAux, /* Context pointer for xCreate/xConnect */ void (*xDestroy)(void *) /* Module destructor function */ ){ - int rc, nName; - Module *pMod; + int rc = SQLITE_OK; + int nName; sqlite3_mutex_enter(db->mutex); nName = sqlite3Strlen30(zName); - pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1); - if( pMod ){ - Module *pDel; - char *zCopy = (char *)(&pMod[1]); - memcpy(zCopy, zName, nName+1); - pMod->zName = zCopy; - pMod->pModule = pModule; - pMod->pAux = pAux; - pMod->xDestroy = xDestroy; - pDel = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod); - if( pDel && pDel->xDestroy ){ - sqlite3ResetInternalSchema(db, -1); - pDel->xDestroy(pDel->pAux); - } - sqlite3DbFree(db, pDel); - if( pDel==pMod ){ - db->mallocFailed = 1; + if( sqlite3HashFind(&db->aModule, zName, nName) ){ + rc = SQLITE_MISUSE_BKPT; + }else{ + Module *pMod; + pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1); + if( pMod ){ + Module *pDel; + char *zCopy = (char *)(&pMod[1]); + memcpy(zCopy, zName, nName+1); + pMod->zName = zCopy; + pMod->pModule = pModule; + pMod->pAux = pAux; + pMod->xDestroy = xDestroy; + pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,nName,(void*)pMod); + assert( pDel==0 || pDel==pMod ); + if( pDel ){ + db->mallocFailed = 1; + sqlite3DbFree(db, pDel); + } } - }else if( xDestroy ){ - xDestroy(pAux); } - rc = sqlite3ApiExit(db, SQLITE_OK); + rc = sqlite3ApiExit(db, rc); + if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); + sqlite3_mutex_leave(db->mutex); return rc; } @@ -129,7 +131,7 @@ void sqlite3VtabUnlock(VTable *pVTab){ assert( db ); assert( pVTab->nRef>0 ); - assert( sqlite3SafetyCheckOk(db) ); + assert( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ZOMBIE ); pVTab->nRef--; if( pVTab->nRef==0 ){ @@ -180,6 +182,31 @@ static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ return pRet; } +/* +** Table *p is a virtual table. This function removes the VTable object +** for table *p associated with database connection db from the linked +** list in p->pVTab. It also decrements the VTable ref count. This is +** used when closing database connection db to free all of its VTable +** objects without disturbing the rest of the Schema object (which may +** be being used by other shared-cache connections). +*/ +void sqlite3VtabDisconnect(sqlite3 *db, Table *p){ + VTable **ppVTab; + + assert( IsVirtual(p) ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3_mutex_held(db->mutex) ); + + for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){ + if( (*ppVTab)->db==db ){ + VTable *pVTab = *ppVTab; + *ppVTab = pVTab->pNext; + sqlite3VtabUnlock(pVTab); + break; + } + } +} + /* ** Disconnect all the virtual table objects in the sqlite3.pDisconnect list. -- cgit v1.2.3