aboutsummaryrefslogtreecommitdiff
path: root/ext/session
diff options
context:
space:
mode:
Diffstat (limited to 'ext/session')
-rw-r--r--ext/session/sessionsize.test23
-rw-r--r--ext/session/sqlite3session.c43
-rw-r--r--ext/session/sqlite3session.h27
-rw-r--r--ext/session/test_session.c26
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