1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-24 22:22:08 +03:00

If a NULL pointer is passed to sqlite3session_attach() in place of a table name, attach all database tables to the session object.

FossilOrigin-Name: e9037e4e4ccaa5c633759c4d041b60b631b92c6c
This commit is contained in:
dan
2011-03-22 15:21:03 +00:00
parent 7aa469cdd3
commit ff4d0f41bb
7 changed files with 88 additions and 40 deletions

View File

@ -19,6 +19,7 @@ struct sqlite3_session {
sqlite3 *db; /* Database handle session is attached to */
char *zDb; /* Name of database session is attached to */
int bEnable; /* True if currently recording */
int bAutoAttach; /* True to auto-attach tables */
int rc; /* Non-zero if an error has occurred */
sqlite3_session *pNext; /* Next session object on same db. */
SessionTable *pTable; /* List of attached tables */
@ -775,7 +776,16 @@ static void xPreUpdate(
if( pSession->rc ) continue;
if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue;
for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
for(pTab=pSession->pTable; pTab || pSession->bAutoAttach; pTab=pTab->pNext){
if( !pTab ){
/* This branch is taken if table zName has not yet been attached to
** this session and the auto-attach flag is set. */
pSession->rc = sqlite3session_attach(pSession,zName);
if( pSession->rc ) continue;
pTab = pSession->pTable;
assert( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) );
}
if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ){
sessionPreupdateOneChange(op, pSession, pTab);
if( op==SQLITE_UPDATE ){
@ -876,31 +886,35 @@ int sqlite3session_attach(
sqlite3_session *pSession, /* Session object */
const char *zName /* Table name */
){
SessionTable *pTab; /* New table object (if required) */
int nName; /* Number of bytes in string zName */
int rc = SQLITE_OK;
sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db));
/* First search for an existing entry. If one is found, this call is
** a no-op. Return early. */
nName = strlen(zName);
for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break;
}
if( !zName ){
pSession->bAutoAttach = 1;
}else{
SessionTable *pTab; /* New table object (if required) */
int nName; /* Number of bytes in string zName */
/* First search for an existing entry. If one is found, this call is
** a no-op. Return early. */
nName = strlen(zName);
for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){
if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break;
}
if( !pTab ){
/* Allocate new SessionTable object. */
pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1);
if( !pTab ){
rc = SQLITE_NOMEM;
}else{
/* Populate the new SessionTable object and link it into the list. */
memset(pTab, 0, sizeof(SessionTable));
pTab->zName = (char *)&pTab[1];
memcpy(pTab->zName, zName, nName+1);
pTab->pNext = pSession->pTable;
pSession->pTable = pTab;
/* Allocate new SessionTable object. */
pTab = (SessionTable *)sqlite3_malloc(sizeof(SessionTable) + nName + 1);
if( !pTab ){
rc = SQLITE_NOMEM;
}else{
/* Populate the new SessionTable object and link it into the list. */
memset(pTab, 0, sizeof(SessionTable));
pTab->zName = (char *)&pTab[1];
memcpy(pTab->zName, zName, nName+1);
pTab->pNext = pSession->pTable;
pSession->pTable = pTab;
}
}
}