1984bfaa4Sdrh /* 2984bfaa4Sdrh ** 2008 March 19 3984bfaa4Sdrh ** 4984bfaa4Sdrh ** The author disclaims copyright to this source code. In place of 5984bfaa4Sdrh ** a legal notice, here is a blessing: 6984bfaa4Sdrh ** 7984bfaa4Sdrh ** May you do good and not evil. 8984bfaa4Sdrh ** May you find forgiveness for yourself and forgive others. 9984bfaa4Sdrh ** May you share freely, never taking more than you give. 10984bfaa4Sdrh ** 11984bfaa4Sdrh ************************************************************************* 12984bfaa4Sdrh ** Code for testing all sorts of SQLite interfaces. This code 13984bfaa4Sdrh ** implements new SQL functions used by the test scripts. 14984bfaa4Sdrh ** 15*da84ca8dSdrh ** $Id: test_func.c,v 1.2 2008/03/19 16:35:24 drh Exp $ 16984bfaa4Sdrh */ 17984bfaa4Sdrh #include "sqlite3.h" 18984bfaa4Sdrh #include "tcl.h" 19984bfaa4Sdrh #include <stdlib.h> 20984bfaa4Sdrh #include <string.h> 21984bfaa4Sdrh #include <assert.h> 22984bfaa4Sdrh 23984bfaa4Sdrh 24984bfaa4Sdrh /* 25984bfaa4Sdrh ** Allocate nByte bytes of space using sqlite3_malloc(). If the 26984bfaa4Sdrh ** allocation fails, call sqlite3_result_error_nomem() to notify 27984bfaa4Sdrh ** the database handle that malloc() has failed. 28984bfaa4Sdrh */ 29984bfaa4Sdrh static void *testContextMalloc(sqlite3_context *context, int nByte){ 30984bfaa4Sdrh char *z = sqlite3_malloc(nByte); 31984bfaa4Sdrh if( !z && nByte>0 ){ 32984bfaa4Sdrh sqlite3_result_error_nomem(context); 33984bfaa4Sdrh } 34984bfaa4Sdrh return z; 35984bfaa4Sdrh } 36984bfaa4Sdrh 37984bfaa4Sdrh /* 38984bfaa4Sdrh ** This function generates a string of random characters. Used for 39984bfaa4Sdrh ** generating test data. 40984bfaa4Sdrh */ 41984bfaa4Sdrh static void randStr(sqlite3_context *context, int argc, sqlite3_value **argv){ 42984bfaa4Sdrh static const unsigned char zSrc[] = 43984bfaa4Sdrh "abcdefghijklmnopqrstuvwxyz" 44984bfaa4Sdrh "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 45984bfaa4Sdrh "0123456789" 46984bfaa4Sdrh ".-!,:*^+=_|?/<> "; 47984bfaa4Sdrh int iMin, iMax, n, r, i; 48984bfaa4Sdrh unsigned char zBuf[1000]; 49984bfaa4Sdrh 50984bfaa4Sdrh /* It used to be possible to call randstr() with any number of arguments, 51984bfaa4Sdrh ** but now it is registered with SQLite as requiring exactly 2. 52984bfaa4Sdrh */ 53984bfaa4Sdrh assert(argc==2); 54984bfaa4Sdrh 55984bfaa4Sdrh iMin = sqlite3_value_int(argv[0]); 56984bfaa4Sdrh if( iMin<0 ) iMin = 0; 57984bfaa4Sdrh if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1; 58984bfaa4Sdrh iMax = sqlite3_value_int(argv[1]); 59984bfaa4Sdrh if( iMax<iMin ) iMax = iMin; 60984bfaa4Sdrh if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1; 61984bfaa4Sdrh n = iMin; 62984bfaa4Sdrh if( iMax>iMin ){ 63984bfaa4Sdrh sqlite3_randomness(sizeof(r), &r); 64984bfaa4Sdrh r &= 0x7fffffff; 65984bfaa4Sdrh n += r%(iMax + 1 - iMin); 66984bfaa4Sdrh } 67984bfaa4Sdrh assert( n<sizeof(zBuf) ); 68984bfaa4Sdrh sqlite3_randomness(n, zBuf); 69984bfaa4Sdrh for(i=0; i<n; i++){ 70984bfaa4Sdrh zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)]; 71984bfaa4Sdrh } 72984bfaa4Sdrh zBuf[n] = 0; 73984bfaa4Sdrh sqlite3_result_text(context, (char*)zBuf, n, SQLITE_TRANSIENT); 74984bfaa4Sdrh } 75984bfaa4Sdrh 76984bfaa4Sdrh /* 77984bfaa4Sdrh ** The following two SQL functions are used to test returning a text 78984bfaa4Sdrh ** result with a destructor. Function 'test_destructor' takes one argument 79984bfaa4Sdrh ** and returns the same argument interpreted as TEXT. A destructor is 80984bfaa4Sdrh ** passed with the sqlite3_result_text() call. 81984bfaa4Sdrh ** 82984bfaa4Sdrh ** SQL function 'test_destructor_count' returns the number of outstanding 83984bfaa4Sdrh ** allocations made by 'test_destructor'; 84984bfaa4Sdrh ** 85984bfaa4Sdrh ** WARNING: Not threadsafe. 86984bfaa4Sdrh */ 87984bfaa4Sdrh static int test_destructor_count_var = 0; 88984bfaa4Sdrh static void destructor(void *p){ 89984bfaa4Sdrh char *zVal = (char *)p; 90984bfaa4Sdrh assert(zVal); 91984bfaa4Sdrh zVal--; 92984bfaa4Sdrh sqlite3_free(zVal); 93984bfaa4Sdrh test_destructor_count_var--; 94984bfaa4Sdrh } 95984bfaa4Sdrh static void test_destructor( 96984bfaa4Sdrh sqlite3_context *pCtx, 97984bfaa4Sdrh int nArg, 98984bfaa4Sdrh sqlite3_value **argv 99984bfaa4Sdrh ){ 100984bfaa4Sdrh char *zVal; 101984bfaa4Sdrh int len; 102984bfaa4Sdrh 103984bfaa4Sdrh test_destructor_count_var++; 104984bfaa4Sdrh assert( nArg==1 ); 105984bfaa4Sdrh if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; 106984bfaa4Sdrh len = sqlite3_value_bytes(argv[0]); 107984bfaa4Sdrh zVal = testContextMalloc(pCtx, len+3); 108984bfaa4Sdrh if( !zVal ){ 109984bfaa4Sdrh return; 110984bfaa4Sdrh } 111984bfaa4Sdrh zVal[len+1] = 0; 112984bfaa4Sdrh zVal[len+2] = 0; 113984bfaa4Sdrh zVal++; 114984bfaa4Sdrh memcpy(zVal, sqlite3_value_text(argv[0]), len); 115984bfaa4Sdrh sqlite3_result_text(pCtx, zVal, -1, destructor); 116984bfaa4Sdrh } 117*da84ca8dSdrh static void test_destructor16( 118*da84ca8dSdrh sqlite3_context *pCtx, 119*da84ca8dSdrh int nArg, 120*da84ca8dSdrh sqlite3_value **argv 121*da84ca8dSdrh ){ 122*da84ca8dSdrh char *zVal; 123*da84ca8dSdrh int len; 124*da84ca8dSdrh 125*da84ca8dSdrh test_destructor_count_var++; 126*da84ca8dSdrh assert( nArg==1 ); 127*da84ca8dSdrh if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; 128*da84ca8dSdrh len = sqlite3_value_bytes16(argv[0]); 129*da84ca8dSdrh zVal = testContextMalloc(pCtx, len+3); 130*da84ca8dSdrh if( !zVal ){ 131*da84ca8dSdrh return; 132*da84ca8dSdrh } 133*da84ca8dSdrh zVal[len+1] = 0; 134*da84ca8dSdrh zVal[len+2] = 0; 135*da84ca8dSdrh zVal++; 136*da84ca8dSdrh memcpy(zVal, sqlite3_value_text16(argv[0]), len); 137*da84ca8dSdrh sqlite3_result_text16(pCtx, zVal, -1, destructor); 138*da84ca8dSdrh } 139984bfaa4Sdrh static void test_destructor_count( 140984bfaa4Sdrh sqlite3_context *pCtx, 141984bfaa4Sdrh int nArg, 142984bfaa4Sdrh sqlite3_value **argv 143984bfaa4Sdrh ){ 144984bfaa4Sdrh sqlite3_result_int(pCtx, test_destructor_count_var); 145984bfaa4Sdrh } 146984bfaa4Sdrh 147984bfaa4Sdrh /* 148984bfaa4Sdrh ** Routines for testing the sqlite3_get_auxdata() and sqlite3_set_auxdata() 149984bfaa4Sdrh ** interface. 150984bfaa4Sdrh ** 151984bfaa4Sdrh ** The test_auxdata() SQL function attempts to register each of its arguments 152984bfaa4Sdrh ** as auxiliary data. If there are no prior registrations of aux data for 153984bfaa4Sdrh ** that argument (meaning the argument is not a constant or this is its first 154984bfaa4Sdrh ** call) then the result for that argument is 0. If there is a prior 155984bfaa4Sdrh ** registration, the result for that argument is 1. The overall result 156984bfaa4Sdrh ** is the individual argument results separated by spaces. 157984bfaa4Sdrh */ 158984bfaa4Sdrh static void free_test_auxdata(void *p) {sqlite3_free(p);} 159984bfaa4Sdrh static void test_auxdata( 160984bfaa4Sdrh sqlite3_context *pCtx, 161984bfaa4Sdrh int nArg, 162984bfaa4Sdrh sqlite3_value **argv 163984bfaa4Sdrh ){ 164984bfaa4Sdrh int i; 165984bfaa4Sdrh char *zRet = testContextMalloc(pCtx, nArg*2); 166984bfaa4Sdrh if( !zRet ) return; 167984bfaa4Sdrh memset(zRet, 0, nArg*2); 168984bfaa4Sdrh for(i=0; i<nArg; i++){ 169984bfaa4Sdrh char const *z = (char*)sqlite3_value_text(argv[i]); 170984bfaa4Sdrh if( z ){ 171984bfaa4Sdrh int n; 172984bfaa4Sdrh char *zAux = sqlite3_get_auxdata(pCtx, i); 173984bfaa4Sdrh if( zAux ){ 174984bfaa4Sdrh zRet[i*2] = '1'; 175984bfaa4Sdrh assert( strcmp(zAux,z)==0 ); 176984bfaa4Sdrh }else { 177984bfaa4Sdrh zRet[i*2] = '0'; 178984bfaa4Sdrh } 179984bfaa4Sdrh n = strlen(z) + 1; 180984bfaa4Sdrh zAux = testContextMalloc(pCtx, n); 181984bfaa4Sdrh if( zAux ){ 182984bfaa4Sdrh memcpy(zAux, z, n); 183984bfaa4Sdrh sqlite3_set_auxdata(pCtx, i, zAux, free_test_auxdata); 184984bfaa4Sdrh } 185984bfaa4Sdrh zRet[i*2+1] = ' '; 186984bfaa4Sdrh } 187984bfaa4Sdrh } 188984bfaa4Sdrh sqlite3_result_text(pCtx, zRet, 2*nArg-1, free_test_auxdata); 189984bfaa4Sdrh } 190984bfaa4Sdrh 191984bfaa4Sdrh /* 192984bfaa4Sdrh ** A function to test error reporting from user functions. This function 193984bfaa4Sdrh ** returns a copy of its first argument as an error. 194984bfaa4Sdrh */ 195984bfaa4Sdrh static void test_error( 196984bfaa4Sdrh sqlite3_context *pCtx, 197984bfaa4Sdrh int nArg, 198984bfaa4Sdrh sqlite3_value **argv 199984bfaa4Sdrh ){ 200984bfaa4Sdrh sqlite3_result_error(pCtx, (char*)sqlite3_value_text(argv[0]), 0); 201984bfaa4Sdrh } 202984bfaa4Sdrh 203984bfaa4Sdrh static int registerTestFunctions(sqlite3 *db){ 204984bfaa4Sdrh static const struct { 205984bfaa4Sdrh char *zName; 206984bfaa4Sdrh signed char nArg; 207984bfaa4Sdrh unsigned char eTextRep; /* 1: UTF-16. 0: UTF-8 */ 208984bfaa4Sdrh void (*xFunc)(sqlite3_context*,int,sqlite3_value **); 209984bfaa4Sdrh } aFuncs[] = { 210984bfaa4Sdrh { "randstr", 2, SQLITE_UTF8, randStr }, 211984bfaa4Sdrh { "test_destructor", 1, SQLITE_UTF8, test_destructor}, 212*da84ca8dSdrh { "test_destructor16", 1, SQLITE_UTF8, test_destructor16}, 213984bfaa4Sdrh { "test_destructor_count", 0, SQLITE_UTF8, test_destructor_count}, 214984bfaa4Sdrh { "test_auxdata", -1, SQLITE_UTF8, test_auxdata}, 215984bfaa4Sdrh { "test_error", 1, SQLITE_UTF8, test_error}, 216984bfaa4Sdrh }; 217984bfaa4Sdrh int i; 218984bfaa4Sdrh 219984bfaa4Sdrh for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){ 220984bfaa4Sdrh sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg, 221984bfaa4Sdrh aFuncs[i].eTextRep, 0, aFuncs[i].xFunc, 0, 0); 222984bfaa4Sdrh } 223984bfaa4Sdrh return SQLITE_OK; 224984bfaa4Sdrh } 225984bfaa4Sdrh 226984bfaa4Sdrh /* 227984bfaa4Sdrh ** TCLCMD: autoinstall_test_functions 228984bfaa4Sdrh ** 229984bfaa4Sdrh ** Invoke this TCL command to use sqlite3_auto_extension() to cause 230984bfaa4Sdrh ** the standard set of test functions to be loaded into each new 231984bfaa4Sdrh ** database connection. 232984bfaa4Sdrh */ 233984bfaa4Sdrh static int autoinstall_test_funcs( 234984bfaa4Sdrh void * clientData, 235984bfaa4Sdrh Tcl_Interp *interp, 236984bfaa4Sdrh int objc, 237984bfaa4Sdrh Tcl_Obj *CONST objv[] 238984bfaa4Sdrh ){ 239984bfaa4Sdrh sqlite3_auto_extension((void*)registerTestFunctions); 240984bfaa4Sdrh return TCL_OK; 241984bfaa4Sdrh } 242984bfaa4Sdrh 243984bfaa4Sdrh 244984bfaa4Sdrh 245984bfaa4Sdrh /* 246984bfaa4Sdrh ** Register commands with the TCL interpreter. 247984bfaa4Sdrh */ 248984bfaa4Sdrh int Sqlitetest_func_Init(Tcl_Interp *interp){ 249984bfaa4Sdrh static struct { 250984bfaa4Sdrh char *zName; 251984bfaa4Sdrh Tcl_ObjCmdProc *xProc; 252984bfaa4Sdrh } aObjCmd[] = { 253984bfaa4Sdrh { "autoinstall_test_functions", autoinstall_test_funcs }, 254984bfaa4Sdrh }; 255984bfaa4Sdrh int i; 256984bfaa4Sdrh for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ 257984bfaa4Sdrh Tcl_CreateObjCommand(interp, aObjCmd[i].zName, aObjCmd[i].xProc, 0, 0); 258984bfaa4Sdrh } 259984bfaa4Sdrh sqlite3_auto_extension((void*)registerTestFunctions); 260984bfaa4Sdrh return TCL_OK; 261984bfaa4Sdrh } 262