diff options
Diffstat (limited to 'ext/session')
-rw-r--r-- | ext/session/sessionsize.test | 23 | ||||
-rw-r--r-- | ext/session/sqlite3session.c | 43 | ||||
-rw-r--r-- | ext/session/sqlite3session.h | 27 | ||||
-rw-r--r-- | ext/session/test_session.c | 26 |
4 files changed, 114 insertions, 5 deletions
diff --git a/ext/session/sessionsize.test b/ext/session/sessionsize.test index 8347097e9..04d05514d 100644 --- a/ext/session/sessionsize.test +++ b/ext/session/sessionsize.test @@ -104,5 +104,28 @@ do_changeset_size_test 2.7 { INSERT INTO t3 VALUES(1,2,3,4); } +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 3.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); +} + +do_test 3.1 { + sqlite3session S db main + S object_config_size -1 +} 1 + +do_test 3.2.1 { S object_config_size 0 } 0 +do_test 3.2.2 { S object_config_size -1 } 0 +do_test 3.2.3 { S object_config_size 1 } 1 +do_test 3.2.4 { S object_config_size -1 } 1 + +do_test 3.3 { S attach t1 } {} +do_test 3.4 { S object_config_size 1 } {SQLITE_MISUSE} +do_test 3.4 { S object_config_size -1 } {1} + +S delete + finish_test diff --git a/ext/session/sqlite3session.c b/ext/session/sqlite3session.c index 077a6e090..1f6c58b4d 100644 --- a/ext/session/sqlite3session.c +++ b/ext/session/sqlite3session.c @@ -42,6 +42,7 @@ struct SessionHook { struct sqlite3_session { sqlite3 *db; /* Database handle session is attached to */ char *zDb; /* Name of database session is attached to */ + int bEnableSize; /* True if changeset_size() enabled */ int bEnable; /* True if currently recording */ int bIndirect; /* True if all changes are indirect */ int bAutoAttach; /* True to auto-attach tables */ @@ -1124,9 +1125,11 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ pTab->bStat1 = 1; } - pSession->nMaxChangesetSize += ( - 1 + sessionVarintLen(pTab->nCol) + pTab->nCol + strlen(pTab->zName) + 1 - ); + if( pSession->bEnableSize ){ + pSession->nMaxChangesetSize += ( + 1 + sessionVarintLen(pTab->nCol) + pTab->nCol + strlen(pTab->zName)+1 + ); + } } } return (pSession->rc || pTab->abPK==0); @@ -1411,7 +1414,9 @@ static void sessionPreupdateOneChange( } assert( rc==SQLITE_OK ); - rc = sessionUpdateMaxSize(op, pSession, pTab, pC); + if( pSession->bEnableSize ){ + rc = sessionUpdateMaxSize(op, pSession, pTab, pC); + } } @@ -2627,7 +2632,9 @@ int sqlite3session_changeset( void **ppChangeset /* OUT: Buffer containing changeset */ ){ int rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset,ppChangeset); - assert( rc || pnChangeset==0 || *pnChangeset<=pSession->nMaxChangesetSize ); + assert( rc || pnChangeset==0 + || pSession->bEnableSize==0 || *pnChangeset<=pSession->nMaxChangesetSize + ); return rc; } @@ -2721,6 +2728,32 @@ sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession){ } /* +** Configure the session object passed as the first argument. +*/ +int sqlite3session_object_config(sqlite3_session *pSession, int op, void *pArg){ + int rc = SQLITE_OK; + switch( op ){ + case SQLITE_SESSION_OBJCONFIG_SIZE: { + int iArg = *(int*)pArg; + if( iArg>=0 ){ + if( pSession->pTable ){ + rc = SQLITE_MISUSE; + }else{ + pSession->bEnableSize = (iArg!=0); + } + } + *(int*)pArg = pSession->bEnableSize; + break; + } + + default: + rc = SQLITE_MISUSE; + } + + return rc; +} + +/* ** Return the maximum size of sqlite3session_changeset() output. */ sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession){ diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h index 78d25ba0f..43a03fc04 100644 --- a/ext/session/sqlite3session.h +++ b/ext/session/sqlite3session.h @@ -79,6 +79,33 @@ int sqlite3session_create( */ void sqlite3session_delete(sqlite3_session *pSession); +/* +** CAPIREF: Conigure a Session Object +** METHOD: sqlite3_session +*/ +int sqlite3session_object_config(sqlite3_session*, int op, void *pArg); + +/* +** CAPI3REF: Arguments for sqlite3session_object_config() +** +** The following values may passed as the the 4th parameter to +** [sqlite3session_object_config]. +** +** <dt>SQLITE_SESSION_OBJCONFIG_SIZE <dd> +** This option is used to set, clear or query the flag that enables +** the [sqlite3session_changeset_size()] API. Because it imposes some +** computational overhead, this API is disabled by default. Argument +** pArg must point to a value of type (int). If the value is initially +** 0, then the sqlite3session_changeset_size() API is disabled. If it +** is greater than 0, then the same API is enabled. Or, if the initial +** value is less than zero, no change is made. In all cases the (int) +** variable is set to 1 if the sqlite3session_changeset_size() API is +** enabled following the current call, or 0 otherwise. +** +** It is an error (SQLITE_MISUSE) to attempt to modify this setting after +** the first table has been attached to the session object. +*/ +#define SQLITE_SESSION_OBJCONFIG_SIZE 1 /* ** CAPI3REF: Enable Or Disable A Session Object diff --git a/ext/session/test_session.c b/ext/session/test_session.c index b7c96b265..f2fc77eee 100644 --- a/ext/session/test_session.c +++ b/ext/session/test_session.c @@ -247,6 +247,7 @@ static int SQLITE_TCLAPI test_session_cmd( { "diff", 2, "FROMDB TBL", }, /* 8 */ { "memory_used", 0, "", }, /* 9 */ { "changeset_size", 0, "", }, /* 10 */ + { "object_config_size", 1, "INTEGER", }, /* 11 */ { 0 } }; int iSub; @@ -364,6 +365,23 @@ static int SQLITE_TCLAPI test_session_cmd( Tcl_SetObjResult(interp, Tcl_NewWideIntObj(nSize)); break; } + case 11: { + int rc; + int iArg; + if( Tcl_GetIntFromObj(interp, objv[2], &iArg) ){ + return TCL_ERROR; + } + rc = sqlite3session_object_config( + pSession, SQLITE_SESSION_OBJCONFIG_SIZE, &iArg + ); + if( rc!=SQLITE_OK ){ + extern const char *sqlite3ErrName(int); + Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); + }else{ + Tcl_SetObjResult(interp, Tcl_NewIntObj(iArg)); + } + break; + } } return TCL_OK; @@ -389,6 +407,7 @@ static int SQLITE_TCLAPI test_sqlite3session( Tcl_CmdInfo info; int rc; /* sqlite3session_create() return code */ TestSession *p; /* New wrapper object */ + int iArg = -1; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 1, objv, "CMD DB-HANDLE DB-NAME"); @@ -409,6 +428,13 @@ static int SQLITE_TCLAPI test_sqlite3session( return test_session_error(interp, rc, 0); } + /* Query the SQLITE_SESSION_OBJCONFIG_SIZE option to ensure that it + ** is clear by default. Then set it. */ + sqlite3session_object_config(p->pSession,SQLITE_SESSION_OBJCONFIG_SIZE,&iArg); + assert( iArg==0 ); + iArg = 1; + sqlite3session_object_config(p->pSession,SQLITE_SESSION_OBJCONFIG_SIZE,&iArg); + Tcl_CreateObjCommand( interp, Tcl_GetString(objv[1]), test_session_cmd, (ClientData)p, test_session_del |