aboutsummaryrefslogtreecommitdiff
path: root/src/test1.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test1.c')
-rw-r--r--src/test1.c134
1 files changed, 130 insertions, 4 deletions
diff --git a/src/test1.c b/src/test1.c
index f458cdb40..bf26b9ea9 100644
--- a/src/test1.c
+++ b/src/test1.c
@@ -1791,6 +1791,131 @@ static int test_create_collation_v2(
}
/*
+** USAGE: sqlite3_create_function_v2 DB NAME NARG ENC ?SWITCHES?
+**
+** Available switches are:
+**
+** -func SCRIPT
+** -step SCRIPT
+** -final SCRIPT
+** -destroy SCRIPT
+*/
+typedef struct CreateFunctionV2 CreateFunctionV2;
+struct CreateFunctionV2 {
+ Tcl_Interp *interp;
+ Tcl_Obj *pFunc; /* Script for function invocation */
+ Tcl_Obj *pStep; /* Script for agg. step invocation */
+ Tcl_Obj *pFinal; /* Script for agg. finalization invocation */
+ Tcl_Obj *pDestroy; /* Destructor script */
+};
+static void cf2Func(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
+}
+static void cf2Step(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
+}
+static void cf2Final(sqlite3_context *ctx){
+}
+static void cf2Destroy(void *pUser){
+ CreateFunctionV2 *p = (CreateFunctionV2 *)pUser;
+
+ if( p->interp && p->pDestroy ){
+ int rc = Tcl_EvalObjEx(p->interp, p->pDestroy, 0);
+ if( rc!=TCL_OK ) Tcl_BackgroundError(p->interp);
+ }
+
+ if( p->pFunc ) Tcl_DecrRefCount(p->pFunc);
+ if( p->pStep ) Tcl_DecrRefCount(p->pStep);
+ if( p->pFinal ) Tcl_DecrRefCount(p->pFinal);
+ if( p->pDestroy ) Tcl_DecrRefCount(p->pDestroy);
+ sqlite3_free(p);
+}
+static int test_create_function_v2(
+ ClientData clientData, /* Not used */
+ Tcl_Interp *interp, /* The invoking TCL interpreter */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ sqlite3 *db;
+ const char *zFunc;
+ int nArg;
+ int enc;
+ CreateFunctionV2 *p;
+ int i;
+ int rc;
+
+ struct EncTable {
+ const char *zEnc;
+ int enc;
+ } aEnc[] = {
+ {"utf8", SQLITE_UTF8 },
+ {"utf16", SQLITE_UTF16 },
+ {"utf16le", SQLITE_UTF16LE },
+ {"utf16be", SQLITE_UTF16BE },
+ {"any", SQLITE_ANY },
+ {"0", 0 }
+ };
+
+ if( objc<5 || (objc%2)==0 ){
+ Tcl_WrongNumArgs(interp, 1, objv, "DB NAME NARG ENC SWITCHES...");
+ return TCL_ERROR;
+ }
+
+ if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
+ zFunc = Tcl_GetString(objv[2]);
+ if( Tcl_GetIntFromObj(interp, objv[3], &nArg) ) return TCL_ERROR;
+ if( Tcl_GetIndexFromObjStruct(interp, objv[4], aEnc, sizeof(aEnc[0]),
+ "encoding", 0, &enc)
+ ){
+ return TCL_ERROR;
+ }
+ enc = aEnc[enc].enc;
+
+ p = sqlite3_malloc(sizeof(CreateFunctionV2));
+ assert( p );
+ memset(p, 0, sizeof(CreateFunctionV2));
+ p->interp = interp;
+
+ for(i=5; i<objc; i+=2){
+ int iSwitch;
+ const char *azSwitch[] = {"-func", "-step", "-final", "-destroy", 0};
+ if( Tcl_GetIndexFromObj(interp, objv[i], azSwitch, "switch", 0, &iSwitch) ){
+ sqlite3_free(p);
+ return TCL_ERROR;
+ }
+
+ switch( iSwitch ){
+ case 0: p->pFunc = objv[i+1]; break;
+ case 1: p->pStep = objv[i+1]; break;
+ case 2: p->pFinal = objv[i+1]; break;
+ case 3: p->pDestroy = objv[i+1]; break;
+ }
+ }
+ if( p->pFunc ) p->pFunc = Tcl_DuplicateObj(p->pFunc);
+ if( p->pStep ) p->pStep = Tcl_DuplicateObj(p->pStep);
+ if( p->pFinal ) p->pFinal = Tcl_DuplicateObj(p->pFinal);
+ if( p->pDestroy ) p->pDestroy = Tcl_DuplicateObj(p->pDestroy);
+
+ if( p->pFunc ) Tcl_IncrRefCount(p->pFunc);
+ if( p->pStep ) Tcl_IncrRefCount(p->pStep);
+ if( p->pFinal ) Tcl_IncrRefCount(p->pFinal);
+ if( p->pDestroy ) Tcl_IncrRefCount(p->pDestroy);
+
+ rc = sqlite3_create_function_v2(db, zFunc, nArg, enc, (void *)p,
+ (p->pFunc ? cf2Func : 0),
+ (p->pStep ? cf2Step : 0),
+ (p->pFinal ? cf2Final : 0),
+ cf2Destroy
+ );
+ if( rc!=SQLITE_OK ){
+ p->interp = 0;
+ cf2Destroy(p);
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0);
+ return TCL_ERROR;
+ }
+ return TCL_OK;
+}
+
+/*
** Usage: sqlite3_load_extension DB-HANDLE FILE ?PROC?
*/
static int test_load_extension(
@@ -2291,7 +2416,7 @@ static int test_collate_func(
int nB, const void *zB
){
Tcl_Interp *i = pTestCollateInterp;
- int encin = (int)pCtx;
+ int encin = SQLITE_PTR_TO_INT(pCtx);
int res;
int n;
@@ -2420,7 +2545,7 @@ static void test_collate_needed_cb(
}
zNeededCollation[i] = 0;
sqlite3_create_collation(
- db, "test_collate", ENC(db), (void *)enc, test_collate_func);
+ db, "test_collate", ENC(db), SQLITE_INT_TO_PTR(enc), test_collate_func);
}
/*
@@ -2469,8 +2594,8 @@ static int alignmentCollFunc(
){
int rc, n;
n = nKey1<nKey2 ? nKey1 : nKey2;
- if( nKey1>0 && 1==(1&(int)pKey1) ) unaligned_string_counter++;
- if( nKey2>0 && 1==(1&(int)pKey2) ) unaligned_string_counter++;
+ if( nKey1>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey1))) ) unaligned_string_counter++;
+ if( nKey2>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey2))) ) unaligned_string_counter++;
rc = memcmp(pKey1, pKey2, n);
if( rc==0 ){
rc = nKey1 - nKey2;
@@ -5187,6 +5312,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
{ "file_control_lockproxy_test", file_control_lockproxy_test, 0 },
{ "file_control_chunksize_test", file_control_chunksize_test, 0 },
{ "sqlite3_vfs_list", vfs_list, 0 },
+ { "sqlite3_create_function_v2", test_create_function_v2, 0 },
/* Functions from os.h */
#ifndef SQLITE_OMIT_UTF16