aboutsummaryrefslogtreecommitdiff
path: root/ext/session/test_session.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/session/test_session.c')
-rw-r--r--ext/session/test_session.c255
1 files changed, 167 insertions, 88 deletions
diff --git a/ext/session/test_session.c b/ext/session/test_session.c
index e167cb8fb..6ad5b3774 100644
--- a/ext/session/test_session.c
+++ b/ext/session/test_session.c
@@ -520,6 +520,65 @@ static int test_obj_eq_string(Tcl_Obj *p, const char *z){
return (nObj==n && (n==0 || 0==memcmp(zObj, z, n)));
}
+static Tcl_Obj *testIterData(sqlite3_changeset_iter *pIter){
+ Tcl_Obj *pVar = 0;
+ int nCol; /* Number of columns in table */
+ int nCol2; /* Number of columns in table */
+ int op; /* SQLITE_INSERT, UPDATE or DELETE */
+ const char *zTab; /* Name of table change applies to */
+ Tcl_Obj *pOld; /* Vector of old.* values */
+ Tcl_Obj *pNew; /* Vector of new.* values */
+ int bIndirect;
+
+ char *zPK;
+ unsigned char *abPK;
+ int i;
+
+ sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect);
+ pVar = Tcl_NewObj();
+
+ Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(
+ op==SQLITE_INSERT ? "INSERT" :
+ op==SQLITE_UPDATE ? "UPDATE" :
+ "DELETE", -1
+ ));
+
+ Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zTab, -1));
+ Tcl_ListObjAppendElement(0, pVar, Tcl_NewBooleanObj(bIndirect));
+
+ zPK = ckalloc(nCol+1);
+ memset(zPK, 0, nCol+1);
+ sqlite3changeset_pk(pIter, &abPK, &nCol2);
+ assert( nCol==nCol2 );
+ for(i=0; i<nCol; i++){
+ zPK[i] = (abPK[i] ? 'X' : '.');
+ }
+ Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zPK, -1));
+ ckfree(zPK);
+
+ pOld = Tcl_NewObj();
+ if( op!=SQLITE_INSERT ){
+ for(i=0; i<nCol; i++){
+ sqlite3_value *pVal;
+ sqlite3changeset_old(pIter, i, &pVal);
+ test_append_value(pOld, pVal);
+ }
+ }
+ pNew = Tcl_NewObj();
+ if( op!=SQLITE_DELETE ){
+ for(i=0; i<nCol; i++){
+ sqlite3_value *pVal;
+ sqlite3changeset_new(pIter, i, &pVal);
+ test_append_value(pNew, pVal);
+ }
+ }
+ Tcl_ListObjAppendElement(0, pVar, pOld);
+ Tcl_ListObjAppendElement(0, pVar, pNew);
+
+ return pVar;
+}
+
+
static int test_filter_handler(
void *pCtx, /* Pointer to TestConflictHandler structure */
const char *zTab /* Table name */
@@ -543,6 +602,29 @@ static int test_filter_handler(
return res;
}
+static int test_filter_v3_handler(
+ void *pCtx, /* Pointer to TestConflictHandler structure */
+ sqlite3_changeset_iter *pIter
+){
+ TestConflictHandler *p = (TestConflictHandler *)pCtx;
+ int res = 1;
+ Tcl_Obj *pEval = 0;
+ Tcl_Interp *interp = p->interp;
+
+ pEval = Tcl_DuplicateObj(p->pFilterScript);
+ Tcl_IncrRefCount(pEval);
+ Tcl_ListObjAppendElement(0, pEval, testIterData(pIter));
+
+ if( TCL_OK!=Tcl_EvalObjEx(interp, pEval, TCL_EVAL_GLOBAL)
+ || TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &res)
+ ){
+ Tcl_BackgroundError(interp);
+ }
+
+ Tcl_DecrRefCount(pEval);
+ return res;
+}
+
static int test_conflict_handler(
void *pCtx, /* Pointer to TestConflictHandler structure */
int eConf, /* DATA, MISSING, CONFLICT, CONSTRAINT */
@@ -776,7 +858,7 @@ static int testStreamInput(
static int SQLITE_TCLAPI testSqlite3changesetApply(
- int bV2,
+ int iVersion,
void * clientData,
Tcl_Interp *interp,
int objc,
@@ -793,11 +875,13 @@ static int SQLITE_TCLAPI testSqlite3changesetApply(
int nRebase = 0;
int flags = 0; /* Flags for apply_v2() */
+ assert( iVersion==1 || iVersion==2 || iVersion==3 );
+
memset(&sStr, 0, sizeof(sStr));
sStr.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR);
/* Check for the -nosavepoint, -invert or -ignorenoop switches */
- if( bV2 ){
+ if( iVersion==2 || iVersion==3 ){
while( objc>1 ){
const char *z1 = Tcl_GetString(objv[1]);
int n = (int)strlen(z1);
@@ -822,7 +906,7 @@ static int SQLITE_TCLAPI testSqlite3changesetApply(
if( objc!=4 && objc!=5 ){
const char *zMsg;
- if( bV2 ){
+ if( iVersion==2 || iVersion==3 ){
zMsg = "?-nosavepoint? ?-inverse? ?-ignorenoop? "
"DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?";
}else{
@@ -842,30 +926,49 @@ static int SQLITE_TCLAPI testSqlite3changesetApply(
ctx.interp = interp;
if( sStr.nStream==0 ){
- if( bV2==0 ){
- rc = sqlite3changeset_apply(db, (int)nChangeset, pChangeset,
- (objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx
- );
- }else{
- rc = sqlite3changeset_apply_v2(db, (int)nChangeset, pChangeset,
- (objc==5)?test_filter_handler:0, test_conflict_handler, (void *)&ctx,
- &pRebase, &nRebase, flags
- );
+ switch( iVersion ){
+ case 1:
+ rc = sqlite3changeset_apply(db, (int)nChangeset, pChangeset,
+ (objc==5)?test_filter_handler:0, test_conflict_handler, (void*)&ctx
+ );
+ break;
+ case 2:
+ rc = sqlite3changeset_apply_v2(db, (int)nChangeset, pChangeset,
+ (objc==5)?test_filter_handler:0, test_conflict_handler, (void*)&ctx,
+ &pRebase, &nRebase, flags
+ );
+ break;
+ case 3:
+ rc = sqlite3changeset_apply_v3(db, (int)nChangeset, pChangeset,
+ (objc==5)?test_filter_v3_handler:0, test_conflict_handler,
+ (void*)&ctx, &pRebase, &nRebase, flags
+ );
+ break;
}
}else{
sStr.aData = (unsigned char*)pChangeset;
sStr.nData = (int)nChangeset;
- if( bV2==0 ){
- rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr,
- (objc==5) ? test_filter_handler : 0,
- test_conflict_handler, (void *)&ctx
- );
- }else{
- rc = sqlite3changeset_apply_v2_strm(db, testStreamInput, (void*)&sStr,
- (objc==5) ? test_filter_handler : 0,
- test_conflict_handler, (void *)&ctx,
- &pRebase, &nRebase, flags
- );
+ switch( iVersion ){
+ case 1:
+ rc = sqlite3changeset_apply_strm(db, testStreamInput, (void*)&sStr,
+ (objc==5) ? test_filter_handler : 0,
+ test_conflict_handler, (void *)&ctx
+ );
+ break;
+ case 2:
+ rc = sqlite3changeset_apply_v2_strm(db, testStreamInput, (void*)&sStr,
+ (objc==5) ? test_filter_handler : 0,
+ test_conflict_handler, (void *)&ctx,
+ &pRebase, &nRebase, flags
+ );
+ break;
+ case 3:
+ rc = sqlite3changeset_apply_v3_strm(db, testStreamInput, (void*)&sStr,
+ (objc==5) ? test_filter_v3_handler : 0,
+ test_conflict_handler, (void *)&ctx,
+ &pRebase, &nRebase, flags
+ );
+ break;
}
}
@@ -873,7 +976,7 @@ static int SQLITE_TCLAPI testSqlite3changesetApply(
return test_session_error(interp, rc, 0);
}else{
Tcl_ResetResult(interp);
- if( bV2 && pRebase ){
+ if( (iVersion==2 || iVersion==3) && pRebase ){
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pRebase, nRebase));
}
}
@@ -890,7 +993,7 @@ static int SQLITE_TCLAPI test_sqlite3changeset_apply(
int objc,
Tcl_Obj *CONST objv[]
){
- return testSqlite3changesetApply(0, clientData, interp, objc, objv);
+ return testSqlite3changesetApply(1, clientData, interp, objc, objv);
}
/*
** sqlite3changeset_apply_v2 DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?
@@ -901,7 +1004,18 @@ static int SQLITE_TCLAPI test_sqlite3changeset_apply_v2(
int objc,
Tcl_Obj *CONST objv[]
){
- return testSqlite3changesetApply(1, clientData, interp, objc, objv);
+ return testSqlite3changesetApply(2, clientData, interp, objc, objv);
+}
+/*
+** sqlite3changeset_apply_v3 DB CHANGESET CONFLICT-SCRIPT ?FILTER-SCRIPT?
+*/
+static int SQLITE_TCLAPI test_sqlite3changeset_apply_v3(
+ void * clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ return testSqlite3changesetApply(3, clientData, interp, objc, objv);
}
/*
@@ -1034,64 +1148,6 @@ static int SQLITE_TCLAPI test_sqlite3changeset_concat(
return rc;
}
-static Tcl_Obj *testIterData(sqlite3_changeset_iter *pIter){
- Tcl_Obj *pVar = 0;
- int nCol; /* Number of columns in table */
- int nCol2; /* Number of columns in table */
- int op; /* SQLITE_INSERT, UPDATE or DELETE */
- const char *zTab; /* Name of table change applies to */
- Tcl_Obj *pOld; /* Vector of old.* values */
- Tcl_Obj *pNew; /* Vector of new.* values */
- int bIndirect;
-
- char *zPK;
- unsigned char *abPK;
- int i;
-
- sqlite3changeset_op(pIter, &zTab, &nCol, &op, &bIndirect);
- pVar = Tcl_NewObj();
-
- Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(
- op==SQLITE_INSERT ? "INSERT" :
- op==SQLITE_UPDATE ? "UPDATE" :
- "DELETE", -1
- ));
-
- Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zTab, -1));
- Tcl_ListObjAppendElement(0, pVar, Tcl_NewBooleanObj(bIndirect));
-
- zPK = ckalloc(nCol+1);
- memset(zPK, 0, nCol+1);
- sqlite3changeset_pk(pIter, &abPK, &nCol2);
- assert( nCol==nCol2 );
- for(i=0; i<nCol; i++){
- zPK[i] = (abPK[i] ? 'X' : '.');
- }
- Tcl_ListObjAppendElement(0, pVar, Tcl_NewStringObj(zPK, -1));
- ckfree(zPK);
-
- pOld = Tcl_NewObj();
- if( op!=SQLITE_INSERT ){
- for(i=0; i<nCol; i++){
- sqlite3_value *pVal;
- sqlite3changeset_old(pIter, i, &pVal);
- test_append_value(pOld, pVal);
- }
- }
- pNew = Tcl_NewObj();
- if( op!=SQLITE_DELETE ){
- for(i=0; i<nCol; i++){
- sqlite3_value *pVal;
- sqlite3changeset_new(pIter, i, &pVal);
- test_append_value(pNew, pVal);
- }
- }
- Tcl_ListObjAppendElement(0, pVar, pOld);
- Tcl_ListObjAppendElement(0, pVar, pNew);
-
- return pVar;
-}
-
/*
** sqlite3session_foreach VARNAME CHANGESET SCRIPT
*/
@@ -1459,6 +1515,9 @@ struct TestChangegroup {
typedef struct TestChangeIter TestChangeIter;
struct TestChangeIter {
sqlite3_changeset_iter *pIter;
+
+ /* If this iter uses streaming. */
+ TestStreamInput in;
};
@@ -1681,6 +1740,7 @@ static int SQLITE_TCLAPI test_sqlite3changeset_start(
sqlite3_changeset_iter *pIter = 0;
int flags = 0;
int rc = SQLITE_OK;
+ int nAlloc = 0; /* Bytes of space to allocate */
static int iCmd = 1;
char zCmd[64];
@@ -1696,18 +1756,36 @@ static int SQLITE_TCLAPI test_sqlite3changeset_start(
return TCL_ERROR;
}
- flags = isInvert ? SQLITE_CHANGESETSTART_INVERT : 0;
pChangeset = (void *)Tcl_GetByteArrayFromObj(objv[objc-1], &nChangeset);
- rc = sqlite3changeset_start_v2(&pIter, (int)nChangeset, pChangeset, flags);
+ flags = isInvert ? SQLITE_CHANGESETSTART_INVERT : 0;
+
+ nAlloc = sizeof(TestChangeIter);
+ if( test_tcl_integer(interp, SESSION_STREAM_TCL_VAR) ){
+ nAlloc += nChangeset;
+ }
+ pNew = (TestChangeIter*)ckalloc(nAlloc);
+ memset(pNew, 0, nAlloc);
+ if( test_tcl_integer(interp, SESSION_STREAM_TCL_VAR) ){
+ pNew->in.nStream = test_tcl_integer(interp, SESSION_STREAM_TCL_VAR);
+ pNew->in.nData = nChangeset;
+ pNew->in.aData = (unsigned char*)&pNew[1];
+ memcpy(pNew->in.aData, pChangeset, nChangeset);
+ }
+
+ if( pNew->in.nStream ){
+ void *pCtx = (void*)&pNew->in;
+ rc = sqlite3changeset_start_v2_strm(&pIter, testStreamInput, pCtx, flags);
+ }else{
+ rc = sqlite3changeset_start_v2(&pIter, (int)nChangeset, pChangeset, flags);
+ }
if( rc!=SQLITE_OK ){
char *zErr = sqlite3_mprintf(
"error in sqlite3changeset_start_v2() - %d", rc
);
Tcl_AppendResult(interp, zErr, (char*)0);
+ ckfree(pNew);
return TCL_ERROR;
}
-
- pNew = (TestChangeIter*)ckalloc(sizeof(TestChangeIter));
pNew->pIter = pIter;
sprintf(zCmd, "csiter%d", iCmd++);
@@ -1729,6 +1807,7 @@ int TestSession_Init(Tcl_Interp *interp){
{ "sqlite3changeset_concat", test_sqlite3changeset_concat },
{ "sqlite3changeset_apply", test_sqlite3changeset_apply },
{ "sqlite3changeset_apply_v2", test_sqlite3changeset_apply_v2 },
+ { "sqlite3changeset_apply_v3", test_sqlite3changeset_apply_v3 },
{ "sqlite3changeset_apply_replace_all",
test_sqlite3changeset_apply_replace_all },
{ "sql_exec_changeset", test_sql_exec_changeset },