1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-14 00:22:38 +03:00

When a connection disconnects from a shared-cache database, only delete the in-memory schema if there are no other connections.

FossilOrigin-Name: 46f4eb5430d7bc9a339cdf7124ff4bd518eaa39b
This commit is contained in:
dan
2012-05-15 17:15:34 +00:00
parent 29ddd3acdd
commit bba02a95d9
7 changed files with 193 additions and 18 deletions

View File

@@ -720,6 +720,30 @@ static void functionDestroy(sqlite3 *db, FuncDef *p){
}
}
/*
** Disconnect all sqlite3_vtab objects that belong to database connection
** db. This is called when db is being closed.
*/
static void disconnectAllVtab(sqlite3 *db){
#ifndef SQLITE_OMIT_VIRTUALTABLE
int i;
sqlite3BtreeEnterAll(db);
for(i=0; i<db->nDb; i++){
Schema *pSchema = db->aDb[i].pSchema;
if( db->aDb[i].pSchema ){
HashElem *p;
for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
Table *pTab = (Table *)sqliteHashData(p);
if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab);
}
}
}
sqlite3BtreeLeaveAll(db);
#else
UNUSED_PARAMETER(db);
#endif
}
/*
** Close an existing SQLite database
*/
@@ -735,10 +759,10 @@ int sqlite3_close(sqlite3 *db){
}
sqlite3_mutex_enter(db->mutex);
/* Force xDestroy calls on all virtual tables */
sqlite3ResetInternalSchema(db, -1);
/* Force xDisconnect calls on all virtual tables */
disconnectAllVtab(db);
/* If a transaction is open, the ResetInternalSchema() call above
/* If a transaction is open, the disconnectAllVtab() call above
** will not have called the xDisconnect() method on any virtual
** tables in the db->aVTrans[] array. The following sqlite3VtabRollback()
** call will do so. We need to do this before the check for active
@@ -779,15 +803,18 @@ int sqlite3_close(sqlite3 *db){
}
}
}
/* This call frees the schema associated with the temp database only (if
** any). It also frees the db->aDb array, if required. */
sqlite3ResetInternalSchema(db, -1);
assert( db->nDb<=2 );
assert( db->aDb==db->aDbStatic );
/* Tell the code in notify.c that the connection no longer holds any
** locks and does not require any further unlock-notify callbacks.
*/
sqlite3ConnectionClosed(db);
assert( db->nDb<=2 );
assert( db->aDb==db->aDbStatic );
for(j=0; j<ArraySize(db->aFunc.a); j++){
FuncDef *pNext, *pHash, *p;
for(p=db->aFunc.a[j]; p; p=pHash){