1d1bf3512Sdrh /* 2b19a2bc6Sdrh ** 2001 September 15 3d1bf3512Sdrh ** 4b19a2bc6Sdrh ** The author disclaims copyright to this source code. In place of 5b19a2bc6Sdrh ** a legal notice, here is a blessing: 6d1bf3512Sdrh ** 7b19a2bc6Sdrh ** May you do good and not evil. 8b19a2bc6Sdrh ** May you find forgiveness for yourself and forgive others. 9b19a2bc6Sdrh ** May you share freely, never taking more than you give. 10d1bf3512Sdrh ** 11d1bf3512Sdrh ************************************************************************* 12d1bf3512Sdrh ** Code for testing the printf() interface to SQLite. This code 13d1bf3512Sdrh ** is not included in the SQLite library. It is used for automated 14d1bf3512Sdrh ** testing of the SQLite library. 15d1bf3512Sdrh ** 16*aef0bf64Sdanielk1977 ** $Id: test1.c,v 1.178 2005/12/30 16:28:02 danielk1977 Exp $ 17d1bf3512Sdrh */ 18d1bf3512Sdrh #include "sqliteInt.h" 19d1bf3512Sdrh #include "tcl.h" 2094e92032Sdrh #include "os.h" 21d1bf3512Sdrh #include <stdlib.h> 22d1bf3512Sdrh #include <string.h> 23d1bf3512Sdrh 242e66f0b9Sdrh const char *sqlite3TestErrorName(int rc){ 256622cce3Sdanielk1977 const char *zName = 0; 266622cce3Sdanielk1977 switch( rc ){ 276622cce3Sdanielk1977 case SQLITE_OK: zName = "SQLITE_OK"; break; 286622cce3Sdanielk1977 case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; 296622cce3Sdanielk1977 case SQLITE_PERM: zName = "SQLITE_PERM"; break; 306622cce3Sdanielk1977 case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; 316622cce3Sdanielk1977 case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; 326622cce3Sdanielk1977 case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; 336622cce3Sdanielk1977 case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; 346622cce3Sdanielk1977 case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; 356622cce3Sdanielk1977 case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; 366622cce3Sdanielk1977 case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; 376622cce3Sdanielk1977 case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; 386622cce3Sdanielk1977 case SQLITE_FULL: zName = "SQLITE_FULL"; break; 396622cce3Sdanielk1977 case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; 406622cce3Sdanielk1977 case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; 416622cce3Sdanielk1977 case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; 426622cce3Sdanielk1977 case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; 436622cce3Sdanielk1977 case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; 446622cce3Sdanielk1977 case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; 456622cce3Sdanielk1977 case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; 466622cce3Sdanielk1977 case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; 476622cce3Sdanielk1977 case SQLITE_AUTH: zName = "SQLITE_AUTH"; break; 486622cce3Sdanielk1977 case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break; 496622cce3Sdanielk1977 case SQLITE_RANGE: zName = "SQLITE_RANGE"; break; 506622cce3Sdanielk1977 case SQLITE_ROW: zName = "SQLITE_ROW"; break; 516622cce3Sdanielk1977 case SQLITE_DONE: zName = "SQLITE_DONE"; break; 52312d6b36Sdanielk1977 case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break; 536622cce3Sdanielk1977 default: zName = "SQLITE_Unknown"; break; 546622cce3Sdanielk1977 } 556622cce3Sdanielk1977 return zName; 566622cce3Sdanielk1977 } 572e66f0b9Sdrh #define errorName sqlite3TestErrorName 586622cce3Sdanielk1977 59d1bf3512Sdrh /* 60c60d0446Sdrh ** Convert an sqlite3_stmt* into an sqlite3*. This depends on the 61c60d0446Sdrh ** fact that the sqlite3* is the first field in the Vdbe structure. 62c60d0446Sdrh */ 6351942bc3Sdrh #define StmtToDb(X) sqlite3_db_handle(X) 64c60d0446Sdrh 65c60d0446Sdrh /* 66c60d0446Sdrh ** Check a return value to make sure it agrees with the results 67c60d0446Sdrh ** from sqlite3_errcode. 68c60d0446Sdrh */ 69c60d0446Sdrh int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){ 70c60d0446Sdrh if( rc!=SQLITE_MISUSE && rc!=SQLITE_OK && sqlite3_errcode(db)!=rc ){ 71c60d0446Sdrh char zBuf[200]; 72c60d0446Sdrh int r2 = sqlite3_errcode(db); 73c60d0446Sdrh sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)", 74c60d0446Sdrh errorName(rc), rc, errorName(r2), r2); 75c60d0446Sdrh Tcl_ResetResult(interp); 76c60d0446Sdrh Tcl_AppendResult(interp, zBuf, 0); 77c60d0446Sdrh return 1; 78c60d0446Sdrh } 79c60d0446Sdrh return 0; 80c60d0446Sdrh } 81c60d0446Sdrh 82c60d0446Sdrh /* 839bb575fdSdrh ** Decode a pointer to an sqlite3 object. 84b86ccfb2Sdrh */ 859bb575fdSdrh static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){ 86fe63d1c9Sdrh *ppDb = (sqlite3*)sqlite3TextToPtr(zA); 87b86ccfb2Sdrh return TCL_OK; 88b86ccfb2Sdrh } 89b86ccfb2Sdrh 90b86ccfb2Sdrh /* 9151e3d8e2Sdanielk1977 ** Decode a pointer to an sqlite3_stmt object. 9251e3d8e2Sdanielk1977 */ 9351e3d8e2Sdanielk1977 static int getStmtPointer( 9451e3d8e2Sdanielk1977 Tcl_Interp *interp, 9551e3d8e2Sdanielk1977 const char *zArg, 9651e3d8e2Sdanielk1977 sqlite3_stmt **ppStmt 9751e3d8e2Sdanielk1977 ){ 98fe63d1c9Sdrh *ppStmt = (sqlite3_stmt*)sqlite3TextToPtr(zArg); 9951e3d8e2Sdanielk1977 return TCL_OK; 10051e3d8e2Sdanielk1977 } 10151e3d8e2Sdanielk1977 10251e3d8e2Sdanielk1977 /* 1039a1d0abeSdanielk1977 ** Decode a pointer to an sqlite3_stmt object. 1049a1d0abeSdanielk1977 */ 1059a1d0abeSdanielk1977 static int getFilePointer( 1069a1d0abeSdanielk1977 Tcl_Interp *interp, 1079a1d0abeSdanielk1977 const char *zArg, 1089a1d0abeSdanielk1977 OsFile **ppFile 1099a1d0abeSdanielk1977 ){ 110fe63d1c9Sdrh *ppFile = (OsFile*)sqlite3TextToPtr(zArg); 1119a1d0abeSdanielk1977 return TCL_OK; 1129a1d0abeSdanielk1977 } 1139a1d0abeSdanielk1977 1149a1d0abeSdanielk1977 /* 1157d8085a8Sdrh ** Generate a text representation of a pointer that can be understood 1167d8085a8Sdrh ** by the getDbPointer and getVmPointer routines above. 1177d8085a8Sdrh ** 1187d8085a8Sdrh ** The problem is, on some machines (Solaris) if you do a printf with 1197d8085a8Sdrh ** "%p" you cannot turn around and do a scanf with the same "%p" and 1207d8085a8Sdrh ** get your pointer back. You have to prepend a "0x" before it will 1217d8085a8Sdrh ** work. Or at least that is what is reported to me (drh). But this 1227d8085a8Sdrh ** behavior varies from machine to machine. The solution used her is 1237d8085a8Sdrh ** to test the string right after it is generated to see if it can be 1247d8085a8Sdrh ** understood by scanf, and if not, try prepending an "0x" to see if 1257d8085a8Sdrh ** that helps. If nothing works, a fatal error is generated. 1267d8085a8Sdrh */ 1277d8085a8Sdrh static int makePointerStr(Tcl_Interp *interp, char *zPtr, void *p){ 128fe63d1c9Sdrh sqlite3_snprintf(100, zPtr, "%p", p); 1297d8085a8Sdrh return TCL_OK; 1307d8085a8Sdrh } 1317d8085a8Sdrh 1327d8085a8Sdrh /* 1336f8a503dSdanielk1977 ** The callback routine for sqlite3_exec_printf(). 134d1bf3512Sdrh */ 135d1bf3512Sdrh static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){ 136d1bf3512Sdrh Tcl_DString *str = (Tcl_DString*)pArg; 137d1bf3512Sdrh int i; 138d1bf3512Sdrh 139d1bf3512Sdrh if( Tcl_DStringLength(str)==0 ){ 140d1bf3512Sdrh for(i=0; i<argc; i++){ 141d1bf3512Sdrh Tcl_DStringAppendElement(str, name[i] ? name[i] : "NULL"); 142d1bf3512Sdrh } 143d1bf3512Sdrh } 144d1bf3512Sdrh for(i=0; i<argc; i++){ 145d1bf3512Sdrh Tcl_DStringAppendElement(str, argv[i] ? argv[i] : "NULL"); 146d1bf3512Sdrh } 147d1bf3512Sdrh return 0; 148d1bf3512Sdrh } 149d1bf3512Sdrh 150d1bf3512Sdrh /* 1516f8a503dSdanielk1977 ** Usage: sqlite3_exec_printf DB FORMAT STRING 152d1bf3512Sdrh ** 1536f8a503dSdanielk1977 ** Invoke the sqlite3_exec_printf() interface using the open database 154d1bf3512Sdrh ** DB. The SQL is the string FORMAT. The format string should contain 155d1bf3512Sdrh ** one %s or %q. STRING is the value inserted into %s or %q. 156d1bf3512Sdrh */ 157d1bf3512Sdrh static int test_exec_printf( 158d1bf3512Sdrh void *NotUsed, 159d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 160d1bf3512Sdrh int argc, /* Number of arguments */ 161d1bf3512Sdrh char **argv /* Text of each argument */ 162d1bf3512Sdrh ){ 1639bb575fdSdrh sqlite3 *db; 164d1bf3512Sdrh Tcl_DString str; 165d1bf3512Sdrh int rc; 166d1bf3512Sdrh char *zErr = 0; 1671211de37Sdrh char *zSql; 168d1bf3512Sdrh char zBuf[30]; 169d1bf3512Sdrh if( argc!=4 ){ 170d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 171d1bf3512Sdrh " DB FORMAT STRING", 0); 172d1bf3512Sdrh return TCL_ERROR; 173d1bf3512Sdrh } 174b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 175d1bf3512Sdrh Tcl_DStringInit(&str); 1761211de37Sdrh zSql = sqlite3_mprintf(argv[2], argv[3]); 1771211de37Sdrh rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr); 1781211de37Sdrh sqlite3_free(zSql); 179d1bf3512Sdrh sprintf(zBuf, "%d", rc); 180d1bf3512Sdrh Tcl_AppendElement(interp, zBuf); 181d1bf3512Sdrh Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr); 182d1bf3512Sdrh Tcl_DStringFree(&str); 183d1bf3512Sdrh if( zErr ) free(zErr); 184c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 185d1bf3512Sdrh return TCL_OK; 186d1bf3512Sdrh } 187d1bf3512Sdrh 188d1bf3512Sdrh /* 1896f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_z_test SEPARATOR ARG0 ARG1 ... 190d93d8a81Sdrh ** 191d93d8a81Sdrh ** Test the %z format of mprintf(). Use multiple mprintf() calls to 192d93d8a81Sdrh ** concatenate arg0 through argn using separator as the separator. 193d93d8a81Sdrh ** Return the result. 194d93d8a81Sdrh */ 195d93d8a81Sdrh static int test_mprintf_z( 196d93d8a81Sdrh void *NotUsed, 197d93d8a81Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 198d93d8a81Sdrh int argc, /* Number of arguments */ 199d93d8a81Sdrh char **argv /* Text of each argument */ 200d93d8a81Sdrh ){ 201d93d8a81Sdrh char *zResult = 0; 202d93d8a81Sdrh int i; 203d93d8a81Sdrh 204d93d8a81Sdrh for(i=2; i<argc; i++){ 2054adee20fSdanielk1977 zResult = sqlite3MPrintf("%z%s%s", zResult, argv[1], argv[i]); 206d93d8a81Sdrh } 207d93d8a81Sdrh Tcl_AppendResult(interp, zResult, 0); 2085f968436Sdrh sqliteFree(zResult); 209d93d8a81Sdrh return TCL_OK; 210d93d8a81Sdrh } 211d93d8a81Sdrh 212d93d8a81Sdrh /* 2136f8a503dSdanielk1977 ** Usage: sqlite3_get_table_printf DB FORMAT STRING 214d1bf3512Sdrh ** 2156f8a503dSdanielk1977 ** Invoke the sqlite3_get_table_printf() interface using the open database 216d1bf3512Sdrh ** DB. The SQL is the string FORMAT. The format string should contain 217d1bf3512Sdrh ** one %s or %q. STRING is the value inserted into %s or %q. 218d1bf3512Sdrh */ 219d1bf3512Sdrh static int test_get_table_printf( 220d1bf3512Sdrh void *NotUsed, 221d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 222d1bf3512Sdrh int argc, /* Number of arguments */ 223d1bf3512Sdrh char **argv /* Text of each argument */ 224d1bf3512Sdrh ){ 2259bb575fdSdrh sqlite3 *db; 226d1bf3512Sdrh Tcl_DString str; 227d1bf3512Sdrh int rc; 228d1bf3512Sdrh char *zErr = 0; 229d1bf3512Sdrh int nRow, nCol; 230d1bf3512Sdrh char **aResult; 231d1bf3512Sdrh int i; 232d1bf3512Sdrh char zBuf[30]; 2331211de37Sdrh char *zSql; 234d1bf3512Sdrh if( argc!=4 ){ 235d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 236d1bf3512Sdrh " DB FORMAT STRING", 0); 237d1bf3512Sdrh return TCL_ERROR; 238d1bf3512Sdrh } 239b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 240d1bf3512Sdrh Tcl_DStringInit(&str); 2411211de37Sdrh zSql = sqlite3_mprintf(argv[2],argv[3]); 2421211de37Sdrh rc = sqlite3_get_table(db, zSql, &aResult, &nRow, &nCol, &zErr); 2431211de37Sdrh sqlite3_free(zSql); 244d1bf3512Sdrh sprintf(zBuf, "%d", rc); 245d1bf3512Sdrh Tcl_AppendElement(interp, zBuf); 246d1bf3512Sdrh if( rc==SQLITE_OK ){ 247d1bf3512Sdrh sprintf(zBuf, "%d", nRow); 248d1bf3512Sdrh Tcl_AppendElement(interp, zBuf); 249d1bf3512Sdrh sprintf(zBuf, "%d", nCol); 250d1bf3512Sdrh Tcl_AppendElement(interp, zBuf); 251d1bf3512Sdrh for(i=0; i<(nRow+1)*nCol; i++){ 252d1bf3512Sdrh Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL"); 253d1bf3512Sdrh } 254d1bf3512Sdrh }else{ 255d1bf3512Sdrh Tcl_AppendElement(interp, zErr); 256d1bf3512Sdrh } 2576f8a503dSdanielk1977 sqlite3_free_table(aResult); 258d1bf3512Sdrh if( zErr ) free(zErr); 259c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 260d1bf3512Sdrh return TCL_OK; 261d1bf3512Sdrh } 262d1bf3512Sdrh 263af9ff33aSdrh 264af9ff33aSdrh /* 2656f8a503dSdanielk1977 ** Usage: sqlite3_last_insert_rowid DB 266af9ff33aSdrh ** 267af9ff33aSdrh ** Returns the integer ROWID of the most recent insert. 268af9ff33aSdrh */ 269af9ff33aSdrh static int test_last_rowid( 270af9ff33aSdrh void *NotUsed, 271af9ff33aSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 272af9ff33aSdrh int argc, /* Number of arguments */ 273af9ff33aSdrh char **argv /* Text of each argument */ 274af9ff33aSdrh ){ 2759bb575fdSdrh sqlite3 *db; 276af9ff33aSdrh char zBuf[30]; 277af9ff33aSdrh 278af9ff33aSdrh if( argc!=2 ){ 279af9ff33aSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0); 280af9ff33aSdrh return TCL_ERROR; 281af9ff33aSdrh } 282b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 283c572ef7fSdanielk1977 sprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db)); 284af9ff33aSdrh Tcl_AppendResult(interp, zBuf, 0); 285af9ff33aSdrh return SQLITE_OK; 286af9ff33aSdrh } 287af9ff33aSdrh 288d1bf3512Sdrh /* 28925d6543dSdrh ** Usage: sqlite3_key DB KEY 29025d6543dSdrh ** 29125d6543dSdrh ** Set the codec key. 29225d6543dSdrh */ 29325d6543dSdrh static int test_key( 29425d6543dSdrh void *NotUsed, 29525d6543dSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 29625d6543dSdrh int argc, /* Number of arguments */ 29725d6543dSdrh char **argv /* Text of each argument */ 29825d6543dSdrh ){ 2999bb575fdSdrh sqlite3 *db; 30025d6543dSdrh const char *zKey; 30125d6543dSdrh int nKey; 30225d6543dSdrh if( argc!=3 ){ 30325d6543dSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 30425d6543dSdrh " FILENAME\"", 0); 30525d6543dSdrh return TCL_ERROR; 30625d6543dSdrh } 30725d6543dSdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 30825d6543dSdrh zKey = argv[2]; 30925d6543dSdrh nKey = strlen(zKey); 31025d6543dSdrh #ifdef SQLITE_HAS_CODEC 31125d6543dSdrh sqlite3_key(db, zKey, nKey); 31225d6543dSdrh #endif 31325d6543dSdrh return TCL_OK; 31425d6543dSdrh } 31525d6543dSdrh 31625d6543dSdrh /* 31725d6543dSdrh ** Usage: sqlite3_rekey DB KEY 31825d6543dSdrh ** 31925d6543dSdrh ** Change the codec key. 32025d6543dSdrh */ 32125d6543dSdrh static int test_rekey( 32225d6543dSdrh void *NotUsed, 32325d6543dSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 32425d6543dSdrh int argc, /* Number of arguments */ 32525d6543dSdrh char **argv /* Text of each argument */ 32625d6543dSdrh ){ 3279bb575fdSdrh sqlite3 *db; 32825d6543dSdrh const char *zKey; 32925d6543dSdrh int nKey; 33025d6543dSdrh if( argc!=3 ){ 33125d6543dSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 33225d6543dSdrh " FILENAME\"", 0); 33325d6543dSdrh return TCL_ERROR; 33425d6543dSdrh } 33525d6543dSdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 33625d6543dSdrh zKey = argv[2]; 33725d6543dSdrh nKey = strlen(zKey); 33825d6543dSdrh #ifdef SQLITE_HAS_CODEC 33925d6543dSdrh sqlite3_rekey(db, zKey, nKey); 34025d6543dSdrh #endif 34125d6543dSdrh return TCL_OK; 34225d6543dSdrh } 34325d6543dSdrh 34425d6543dSdrh /* 3456f8a503dSdanielk1977 ** Usage: sqlite3_close DB 346d1bf3512Sdrh ** 3476f8a503dSdanielk1977 ** Closes the database opened by sqlite3_open. 348d1bf3512Sdrh */ 349d1bf3512Sdrh static int sqlite_test_close( 350d1bf3512Sdrh void *NotUsed, 351d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 352d1bf3512Sdrh int argc, /* Number of arguments */ 353d1bf3512Sdrh char **argv /* Text of each argument */ 354d1bf3512Sdrh ){ 3559bb575fdSdrh sqlite3 *db; 35696d81f99Sdanielk1977 int rc; 357d1bf3512Sdrh if( argc!=2 ){ 358d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 359d1bf3512Sdrh " FILENAME\"", 0); 360d1bf3512Sdrh return TCL_ERROR; 361d1bf3512Sdrh } 362b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 36396d81f99Sdanielk1977 rc = sqlite3_close(db); 364f9d64d2cSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 365d1bf3512Sdrh return TCL_OK; 366d1bf3512Sdrh } 367d1bf3512Sdrh 368d1bf3512Sdrh /* 369c22bd47dSdrh ** Implementation of the x_coalesce() function. 370c22bd47dSdrh ** Return the first argument non-NULL argument. 371c22bd47dSdrh */ 3720ae8b831Sdanielk1977 static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 373c22bd47dSdrh int i; 374c22bd47dSdrh for(i=0; i<argc; i++){ 3759c054830Sdrh if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){ 37603d847eaSdrh sqlite3_result_text(context, (char*)sqlite3_value_text(argv[i]), 3775c434b72Sdrh sqlite3_value_bytes(argv[i]), SQLITE_TRANSIENT); 378c22bd47dSdrh break; 379c22bd47dSdrh } 380c22bd47dSdrh } 381c22bd47dSdrh } 382c22bd47dSdrh 383c22bd47dSdrh /* 384d1d9fc33Sdrh ** A structure into which to accumulate text. 385d1d9fc33Sdrh */ 386d1d9fc33Sdrh struct dstr { 387d1d9fc33Sdrh int nAlloc; /* Space allocated */ 388d1d9fc33Sdrh int nUsed; /* Space used */ 389d1d9fc33Sdrh char *z; /* The space */ 390d1d9fc33Sdrh }; 391d1d9fc33Sdrh 392d1d9fc33Sdrh /* 393d1d9fc33Sdrh ** Append text to a dstr 394d1d9fc33Sdrh */ 395d1d9fc33Sdrh static void dstrAppend(struct dstr *p, const char *z, int divider){ 396d1d9fc33Sdrh int n = strlen(z); 397d1d9fc33Sdrh if( p->nUsed + n + 2 > p->nAlloc ){ 398d1d9fc33Sdrh char *zNew; 399d1d9fc33Sdrh p->nAlloc = p->nAlloc*2 + n + 200; 400d1d9fc33Sdrh zNew = sqliteRealloc(p->z, p->nAlloc); 401d1d9fc33Sdrh if( zNew==0 ){ 402d1d9fc33Sdrh sqliteFree(p->z); 403d1d9fc33Sdrh memset(p, 0, sizeof(*p)); 404d1d9fc33Sdrh return; 405d1d9fc33Sdrh } 406d1d9fc33Sdrh p->z = zNew; 407d1d9fc33Sdrh } 408d1d9fc33Sdrh if( divider && p->nUsed>0 ){ 409d1d9fc33Sdrh p->z[p->nUsed++] = divider; 410d1d9fc33Sdrh } 411d1d9fc33Sdrh memcpy(&p->z[p->nUsed], z, n+1); 412d1d9fc33Sdrh p->nUsed += n; 413d1d9fc33Sdrh } 414d1d9fc33Sdrh 415d1d9fc33Sdrh /* 4164adee20fSdanielk1977 ** Invoked for each callback from sqlite3ExecFunc 417d1d9fc33Sdrh */ 418d1d9fc33Sdrh static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){ 419d1d9fc33Sdrh struct dstr *p = (struct dstr*)pData; 420d1d9fc33Sdrh int i; 421d1d9fc33Sdrh for(i=0; i<argc; i++){ 422d1d9fc33Sdrh if( argv[i]==0 ){ 423d1d9fc33Sdrh dstrAppend(p, "NULL", ' '); 424d1d9fc33Sdrh }else{ 425d1d9fc33Sdrh dstrAppend(p, argv[i], ' '); 426d1d9fc33Sdrh } 427d1d9fc33Sdrh } 428d1d9fc33Sdrh return 0; 429d1d9fc33Sdrh } 430d1d9fc33Sdrh 431d1d9fc33Sdrh /* 432e35ee196Sdanielk1977 ** Implementation of the x_sqlite_exec() function. This function takes 433c22bd47dSdrh ** a single argument and attempts to execute that argument as SQL code. 4346cbe1f1bSdrh ** This is illegal and should set the SQLITE_MISUSE flag on the database. 435c22bd47dSdrh ** 4366f8a503dSdanielk1977 ** 2004-Jan-07: We have changed this to make it legal to call sqlite3_exec() 437d1d9fc33Sdrh ** from within a function call. 438d1d9fc33Sdrh ** 439c22bd47dSdrh ** This routine simulates the effect of having two threads attempt to 440c22bd47dSdrh ** use the same database at the same time. 441c22bd47dSdrh */ 44251ad0ecdSdanielk1977 static void sqlite3ExecFunc( 4430ae8b831Sdanielk1977 sqlite3_context *context, 44451ad0ecdSdanielk1977 int argc, 44551ad0ecdSdanielk1977 sqlite3_value **argv 44651ad0ecdSdanielk1977 ){ 447d1d9fc33Sdrh struct dstr x; 448d1d9fc33Sdrh memset(&x, 0, sizeof(x)); 4499bb575fdSdrh sqlite3_exec((sqlite3*)sqlite3_user_data(context), 45003d847eaSdrh (char*)sqlite3_value_text(argv[0]), 451d1d9fc33Sdrh execFuncCallback, &x, 0); 452d8123366Sdanielk1977 sqlite3_result_text(context, x.z, x.nUsed, SQLITE_TRANSIENT); 453d1d9fc33Sdrh sqliteFree(x.z); 454c22bd47dSdrh } 455c22bd47dSdrh 456c22bd47dSdrh /* 457c22bd47dSdrh ** Usage: sqlite_test_create_function DB 458c22bd47dSdrh ** 4596f8a503dSdanielk1977 ** Call the sqlite3_create_function API on the given database in order 460c22bd47dSdrh ** to create a function named "x_coalesce". This function does the same thing 461c22bd47dSdrh ** as the "coalesce" function. This function also registers an SQL function 462e35ee196Sdanielk1977 ** named "x_sqlite_exec" that invokes sqlite3_exec(). Invoking sqlite3_exec() 463c22bd47dSdrh ** in this way is illegal recursion and should raise an SQLITE_MISUSE error. 464c22bd47dSdrh ** The effect is similar to trying to use the same database connection from 465c22bd47dSdrh ** two threads at the same time. 466c22bd47dSdrh ** 467c22bd47dSdrh ** The original motivation for this routine was to be able to call the 4686f8a503dSdanielk1977 ** sqlite3_create_function function while a query is in progress in order 469c22bd47dSdrh ** to test the SQLITE_MISUSE detection logic. 470c22bd47dSdrh */ 471c2eef3b3Sdrh static int test_create_function( 472c22bd47dSdrh void *NotUsed, 473c22bd47dSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 474c22bd47dSdrh int argc, /* Number of arguments */ 475c22bd47dSdrh char **argv /* Text of each argument */ 476c22bd47dSdrh ){ 477c60d0446Sdrh int rc; 4789bb575fdSdrh sqlite3 *db; 4799bb575fdSdrh extern void Md5_Register(sqlite3*); 480312d6b36Sdanielk1977 481c22bd47dSdrh if( argc!=2 ){ 482c22bd47dSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 4834397de57Sdanielk1977 " DB\"", 0); 484c22bd47dSdrh return TCL_ERROR; 485c22bd47dSdrh } 486b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 487c60d0446Sdrh rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0, 488d8123366Sdanielk1977 ifnullFunc, 0, 0); 489312d6b36Sdanielk1977 4905436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 491312d6b36Sdanielk1977 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 492312d6b36Sdanielk1977 ** because it is not tested anywhere else. */ 493c60d0446Sdrh if( rc==SQLITE_OK ){ 494576ec6b3Sdanielk1977 sqlite3_value *pVal; 495312d6b36Sdanielk1977 pVal = sqlite3ValueNew(); 496312d6b36Sdanielk1977 sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC); 497c60d0446Sdrh rc = sqlite3_create_function16(db, 498c60d0446Sdrh sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), 499312d6b36Sdanielk1977 1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0); 500312d6b36Sdanielk1977 sqlite3ValueFree(pVal); 501c60d0446Sdrh } 5025436dc2dSdrh #endif 5035436dc2dSdrh 504c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 5054397de57Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), 0); 506c22bd47dSdrh return TCL_OK; 507c22bd47dSdrh } 508c22bd47dSdrh 509c22bd47dSdrh /* 510c22bd47dSdrh ** Routines to implement the x_count() aggregate function. 511c22bd47dSdrh */ 512c22bd47dSdrh typedef struct CountCtx CountCtx; 513c22bd47dSdrh struct CountCtx { 514c22bd47dSdrh int n; 515c22bd47dSdrh }; 5160ae8b831Sdanielk1977 static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ 517c22bd47dSdrh CountCtx *p; 5184f26d6c4Sdrh p = sqlite3_aggregate_context(context, sizeof(*p)); 5199c054830Sdrh if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0]) ) && p ){ 520c22bd47dSdrh p->n++; 521c22bd47dSdrh } 522c22bd47dSdrh } 5230ae8b831Sdanielk1977 static void countFinalize(sqlite3_context *context){ 524c22bd47dSdrh CountCtx *p; 5254f26d6c4Sdrh p = sqlite3_aggregate_context(context, sizeof(*p)); 526c572ef7fSdanielk1977 sqlite3_result_int(context, p ? p->n : 0); 527c22bd47dSdrh } 528c22bd47dSdrh 529c22bd47dSdrh /* 530c22bd47dSdrh ** Usage: sqlite_test_create_aggregate DB 531c22bd47dSdrh ** 5326f8a503dSdanielk1977 ** Call the sqlite3_create_function API on the given database in order 533c22bd47dSdrh ** to create a function named "x_count". This function does the same thing 534c22bd47dSdrh ** as the "md5sum" function. 535c22bd47dSdrh ** 536c22bd47dSdrh ** The original motivation for this routine was to be able to call the 5376f8a503dSdanielk1977 ** sqlite3_create_aggregate function while a query is in progress in order 538c22bd47dSdrh ** to test the SQLITE_MISUSE detection logic. 539c22bd47dSdrh */ 540c2eef3b3Sdrh static int test_create_aggregate( 541c22bd47dSdrh void *NotUsed, 542c22bd47dSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 543c22bd47dSdrh int argc, /* Number of arguments */ 544c22bd47dSdrh char **argv /* Text of each argument */ 545c22bd47dSdrh ){ 5469bb575fdSdrh sqlite3 *db; 547c60d0446Sdrh int rc; 548c22bd47dSdrh if( argc!=2 ){ 549c22bd47dSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 550c22bd47dSdrh " FILENAME\"", 0); 551c22bd47dSdrh return TCL_ERROR; 552c22bd47dSdrh } 553b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 554c60d0446Sdrh rc = sqlite3_create_function(db, "x_count", 0, SQLITE_UTF8, 0, 0, 555d8123366Sdanielk1977 countStep,countFinalize); 556c60d0446Sdrh if( rc==SQLITE_OK ){ 557f9d64d2cSdanielk1977 sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0, 558d8123366Sdanielk1977 countStep,countFinalize); 559c60d0446Sdrh } 560c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 561c22bd47dSdrh return TCL_OK; 562c22bd47dSdrh } 563c22bd47dSdrh 564c22bd47dSdrh 565c22bd47dSdrh 566c22bd47dSdrh /* 5676f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER 568d1bf3512Sdrh ** 569d1bf3512Sdrh ** Call mprintf with three integer arguments 570d1bf3512Sdrh */ 5716f8a503dSdanielk1977 static int sqlite3_mprintf_int( 572d1bf3512Sdrh void *NotUsed, 573d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 574d1bf3512Sdrh int argc, /* Number of arguments */ 575d1bf3512Sdrh char **argv /* Text of each argument */ 576d1bf3512Sdrh ){ 577d1bf3512Sdrh int a[3], i; 578d1bf3512Sdrh char *z; 579d1bf3512Sdrh if( argc!=5 ){ 580d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 581d1bf3512Sdrh " FORMAT INT INT INT\"", 0); 582d1bf3512Sdrh return TCL_ERROR; 583d1bf3512Sdrh } 584d1bf3512Sdrh for(i=2; i<5; i++){ 585d1bf3512Sdrh if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 586d1bf3512Sdrh } 5876f8a503dSdanielk1977 z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]); 588d1bf3512Sdrh Tcl_AppendResult(interp, z, 0); 5893f4fedb2Sdrh sqlite3_free(z); 590d1bf3512Sdrh return TCL_OK; 591d1bf3512Sdrh } 592d1bf3512Sdrh 593d1bf3512Sdrh /* 5949d213ef0Sdrh ** If zNum represents an integer that will fit in 64-bits, then set 5959d213ef0Sdrh ** *pValue to that integer and return true. Otherwise return false. 5969d213ef0Sdrh */ 5979d213ef0Sdrh static int sqlite3GetInt64(const char *zNum, i64 *pValue){ 5989d213ef0Sdrh if( sqlite3FitsIn64Bits(zNum) ){ 5999d213ef0Sdrh sqlite3atoi64(zNum, pValue); 6009d213ef0Sdrh return 1; 6019d213ef0Sdrh } 6029d213ef0Sdrh return 0; 6039d213ef0Sdrh } 6049d213ef0Sdrh 6059d213ef0Sdrh /* 606e9707671Sdrh ** Usage: sqlite3_mprintf_int64 FORMAT INTEGER INTEGER INTEGER 607e9707671Sdrh ** 608e9707671Sdrh ** Call mprintf with three 64-bit integer arguments 609e9707671Sdrh */ 610e9707671Sdrh static int sqlite3_mprintf_int64( 611e9707671Sdrh void *NotUsed, 612e9707671Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 613e9707671Sdrh int argc, /* Number of arguments */ 614e9707671Sdrh char **argv /* Text of each argument */ 615e9707671Sdrh ){ 616e9707671Sdrh int i; 617e9707671Sdrh sqlite_int64 a[3]; 618e9707671Sdrh char *z; 619e9707671Sdrh if( argc!=5 ){ 620e9707671Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 621e9707671Sdrh " FORMAT INT INT INT\"", 0); 622e9707671Sdrh return TCL_ERROR; 623e9707671Sdrh } 624e9707671Sdrh for(i=2; i<5; i++){ 625e9707671Sdrh if( !sqlite3GetInt64(argv[i], &a[i-2]) ){ 626e9707671Sdrh Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0); 627e9707671Sdrh return TCL_ERROR; 628e9707671Sdrh } 629e9707671Sdrh } 630e9707671Sdrh z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]); 631e9707671Sdrh Tcl_AppendResult(interp, z, 0); 632e9707671Sdrh sqlite3_free(z); 633e9707671Sdrh return TCL_OK; 634e9707671Sdrh } 635e9707671Sdrh 636e9707671Sdrh /* 6376f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING 638d1bf3512Sdrh ** 639d1bf3512Sdrh ** Call mprintf with two integer arguments and one string argument 640d1bf3512Sdrh */ 6416f8a503dSdanielk1977 static int sqlite3_mprintf_str( 642d1bf3512Sdrh void *NotUsed, 643d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 644d1bf3512Sdrh int argc, /* Number of arguments */ 645d1bf3512Sdrh char **argv /* Text of each argument */ 646d1bf3512Sdrh ){ 647d1bf3512Sdrh int a[3], i; 648d1bf3512Sdrh char *z; 649f220b24fSchw if( argc<4 || argc>5 ){ 650d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 651f220b24fSchw " FORMAT INT INT ?STRING?\"", 0); 652d1bf3512Sdrh return TCL_ERROR; 653d1bf3512Sdrh } 654d1bf3512Sdrh for(i=2; i<4; i++){ 655d1bf3512Sdrh if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 656d1bf3512Sdrh } 6576f8a503dSdanielk1977 z = sqlite3_mprintf(argv[1], a[0], a[1], argc>4 ? argv[4] : NULL); 658d1bf3512Sdrh Tcl_AppendResult(interp, z, 0); 6593f4fedb2Sdrh sqlite3_free(z); 660d1bf3512Sdrh return TCL_OK; 661d1bf3512Sdrh } 662d1bf3512Sdrh 663d1bf3512Sdrh /* 66463782855Sdrh ** Usage: sqlite3_mprintf_double FORMAT INTEGER INTEGER DOUBLE 665d1bf3512Sdrh ** 666d1bf3512Sdrh ** Call mprintf with two integer arguments and one double argument 667d1bf3512Sdrh */ 6686f8a503dSdanielk1977 static int sqlite3_mprintf_double( 669d1bf3512Sdrh void *NotUsed, 670d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 671d1bf3512Sdrh int argc, /* Number of arguments */ 672d1bf3512Sdrh char **argv /* Text of each argument */ 673d1bf3512Sdrh ){ 674d1bf3512Sdrh int a[3], i; 675d1bf3512Sdrh double r; 676d1bf3512Sdrh char *z; 677d1bf3512Sdrh if( argc!=5 ){ 678d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 67963782855Sdrh " FORMAT INT INT DOUBLE\"", 0); 680d1bf3512Sdrh return TCL_ERROR; 681d1bf3512Sdrh } 682d1bf3512Sdrh for(i=2; i<4; i++){ 683d1bf3512Sdrh if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 684d1bf3512Sdrh } 685d1bf3512Sdrh if( Tcl_GetDouble(interp, argv[4], &r) ) return TCL_ERROR; 6866f8a503dSdanielk1977 z = sqlite3_mprintf(argv[1], a[0], a[1], r); 687d1bf3512Sdrh Tcl_AppendResult(interp, z, 0); 6883f4fedb2Sdrh sqlite3_free(z); 689d1bf3512Sdrh return TCL_OK; 690d1bf3512Sdrh } 691d1bf3512Sdrh 692d1bf3512Sdrh /* 69363782855Sdrh ** Usage: sqlite3_mprintf_scaled FORMAT DOUBLE DOUBLE 694b621c237Sdrh ** 695b621c237Sdrh ** Call mprintf with a single double argument which is the product of the 696b621c237Sdrh ** two arguments given above. This is used to generate overflow and underflow 697b621c237Sdrh ** doubles to test that they are converted properly. 698b621c237Sdrh */ 6996f8a503dSdanielk1977 static int sqlite3_mprintf_scaled( 700b621c237Sdrh void *NotUsed, 701b621c237Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 702b621c237Sdrh int argc, /* Number of arguments */ 703b621c237Sdrh char **argv /* Text of each argument */ 704b621c237Sdrh ){ 705b621c237Sdrh int i; 706b621c237Sdrh double r[2]; 707b621c237Sdrh char *z; 708b621c237Sdrh if( argc!=4 ){ 709b621c237Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 710b621c237Sdrh " FORMAT DOUBLE DOUBLE\"", 0); 711b621c237Sdrh return TCL_ERROR; 712b621c237Sdrh } 713b621c237Sdrh for(i=2; i<4; i++){ 714b621c237Sdrh if( Tcl_GetDouble(interp, argv[i], &r[i-2]) ) return TCL_ERROR; 715b621c237Sdrh } 7166f8a503dSdanielk1977 z = sqlite3_mprintf(argv[1], r[0]*r[1]); 717b621c237Sdrh Tcl_AppendResult(interp, z, 0); 7183f4fedb2Sdrh sqlite3_free(z); 719b621c237Sdrh return TCL_OK; 720b621c237Sdrh } 721b621c237Sdrh 722b621c237Sdrh /* 723e29b1a05Sdrh ** Usage: sqlite3_mprintf_stronly FORMAT STRING 724e29b1a05Sdrh ** 725e29b1a05Sdrh ** Call mprintf with a single double argument which is the product of the 726e29b1a05Sdrh ** two arguments given above. This is used to generate overflow and underflow 727e29b1a05Sdrh ** doubles to test that they are converted properly. 728e29b1a05Sdrh */ 729e29b1a05Sdrh static int sqlite3_mprintf_stronly( 730e29b1a05Sdrh void *NotUsed, 731e29b1a05Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 732e29b1a05Sdrh int argc, /* Number of arguments */ 733e29b1a05Sdrh char **argv /* Text of each argument */ 734e29b1a05Sdrh ){ 735e29b1a05Sdrh char *z; 736e29b1a05Sdrh if( argc!=3 ){ 737e29b1a05Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 738e29b1a05Sdrh " FORMAT STRING\"", 0); 739e29b1a05Sdrh return TCL_ERROR; 740e29b1a05Sdrh } 741e29b1a05Sdrh z = sqlite3_mprintf(argv[1], argv[2]); 742e29b1a05Sdrh Tcl_AppendResult(interp, z, 0); 743e29b1a05Sdrh sqlite3_free(z); 744e29b1a05Sdrh return TCL_OK; 745e29b1a05Sdrh } 746e29b1a05Sdrh 747e29b1a05Sdrh /* 74863782855Sdrh ** Usage: sqlite3_mprintf_hexdouble FORMAT HEX 74963782855Sdrh ** 75063782855Sdrh ** Call mprintf with a single double argument which is derived from the 75163782855Sdrh ** hexadecimal encoding of an IEEE double. 75263782855Sdrh */ 75363782855Sdrh static int sqlite3_mprintf_hexdouble( 75463782855Sdrh void *NotUsed, 75563782855Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 75663782855Sdrh int argc, /* Number of arguments */ 75763782855Sdrh char **argv /* Text of each argument */ 75863782855Sdrh ){ 75963782855Sdrh char *z; 76063782855Sdrh double r; 76163782855Sdrh unsigned x1, x2; 76263782855Sdrh long long unsigned d; 76363782855Sdrh if( argc!=3 ){ 76463782855Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 76563782855Sdrh " FORMAT STRING\"", 0); 76663782855Sdrh return TCL_ERROR; 76763782855Sdrh } 76863782855Sdrh if( sscanf(argv[2], "%08x%08x", &x2, &x1)!=2 ){ 76963782855Sdrh Tcl_AppendResult(interp, "2nd argument should be 16-characters of hex", 0); 77063782855Sdrh return TCL_ERROR; 77163782855Sdrh } 77263782855Sdrh d = x2; 77363782855Sdrh d = (d<<32) + x1; 77463782855Sdrh memcpy(&r, &d, sizeof(r)); 77563782855Sdrh z = sqlite3_mprintf(argv[1], r); 77663782855Sdrh Tcl_AppendResult(interp, z, 0); 77763782855Sdrh sqlite3_free(z); 77863782855Sdrh return TCL_OK; 77963782855Sdrh } 78063782855Sdrh 78163782855Sdrh /* 7824693423bSdrh ** Usage: sqlite_malloc_fail N ?REPEAT-INTERVAL? 783daffd0e5Sdrh ** 7844693423bSdrh ** Rig sqliteMalloc() to fail on the N-th call and every REPEAT-INTERVAL call 7854693423bSdrh ** after that. If REPEAT-INTERVAL is 0 or is omitted, then only a single 7864693423bSdrh ** malloc will fail. If REPEAT-INTERVAL is 1 then all mallocs after the 7874693423bSdrh ** first failure will continue to fail on every call. If REPEAT-INTERVAL is 7884693423bSdrh ** 2 then every other malloc will fail. And so forth. 7894693423bSdrh ** 790261919ccSdanielk1977 ** Turn off this mechanism and reset the sqlite3Tsd()->mallocFailed variable is N==0. 791daffd0e5Sdrh */ 7922c336549Sdanielk1977 #ifdef SQLITE_MEMDEBUG 793daffd0e5Sdrh static int sqlite_malloc_fail( 794daffd0e5Sdrh void *NotUsed, 795daffd0e5Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 796daffd0e5Sdrh int argc, /* Number of arguments */ 797daffd0e5Sdrh char **argv /* Text of each argument */ 798daffd0e5Sdrh ){ 799daffd0e5Sdrh int n; 8004693423bSdrh int rep; 8014693423bSdrh if( argc!=2 && argc!=3 ){ 802daffd0e5Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"", 0); 803daffd0e5Sdrh return TCL_ERROR; 804daffd0e5Sdrh } 805daffd0e5Sdrh if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR; 8064693423bSdrh if( argc==3 ){ 8074693423bSdrh if( Tcl_GetInt(interp, argv[2], &rep) ) return TCL_ERROR; 8084693423bSdrh }else{ 8094693423bSdrh rep = 0; 8104693423bSdrh } 8116f8a503dSdanielk1977 sqlite3_iMallocFail = n; 8124693423bSdrh sqlite3_iMallocReset = rep; 813daffd0e5Sdrh return TCL_OK; 814daffd0e5Sdrh } 815daffd0e5Sdrh #endif 816daffd0e5Sdrh 817daffd0e5Sdrh /* 818daffd0e5Sdrh ** Usage: sqlite_malloc_stat 819daffd0e5Sdrh ** 820daffd0e5Sdrh ** Return the number of prior calls to sqliteMalloc() and sqliteFree(). 821daffd0e5Sdrh */ 8222c336549Sdanielk1977 #ifdef SQLITE_MEMDEBUG 823daffd0e5Sdrh static int sqlite_malloc_stat( 824daffd0e5Sdrh void *NotUsed, 825daffd0e5Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 826daffd0e5Sdrh int argc, /* Number of arguments */ 827daffd0e5Sdrh char **argv /* Text of each argument */ 828daffd0e5Sdrh ){ 829daffd0e5Sdrh char zBuf[200]; 8306f8a503dSdanielk1977 sprintf(zBuf, "%d %d %d", sqlite3_nMalloc,sqlite3_nFree,sqlite3_iMallocFail); 831daffd0e5Sdrh Tcl_AppendResult(interp, zBuf, 0); 832daffd0e5Sdrh return TCL_OK; 833daffd0e5Sdrh } 8345591df55Sdanielk1977 8355591df55Sdanielk1977 /* 8365591df55Sdanielk1977 ** This function implements a Tcl command that may be invoked using any of 8375591df55Sdanielk1977 ** the four forms enumerated below. 8385591df55Sdanielk1977 ** 8395591df55Sdanielk1977 ** sqlite_malloc_outstanding 8405591df55Sdanielk1977 ** Return a summary of all unfreed blocks of memory allocated by the 8415591df55Sdanielk1977 ** current thread. See comments above function sqlite3OutstandingMallocs() 8425591df55Sdanielk1977 ** in util.c for a description of the returned value. 8435591df55Sdanielk1977 ** 8445591df55Sdanielk1977 ** sqlite_malloc_outstanding -bytes 8455591df55Sdanielk1977 ** Return the total amount of unfreed memory (in bytes) allocated by 8465591df55Sdanielk1977 ** this thread. 8475591df55Sdanielk1977 ** 8485591df55Sdanielk1977 ** sqlite_malloc_outstanding -maxbytes 8495591df55Sdanielk1977 ** Return the maximum amount of dynamic memory in use at one time 8505591df55Sdanielk1977 ** by this thread. 8515591df55Sdanielk1977 ** 8525591df55Sdanielk1977 ** sqlite_malloc_outstanding -clearmaxbytes 8535591df55Sdanielk1977 ** Set the value returned by [sqlite_malloc_outstanding -maxbytes] 8545591df55Sdanielk1977 ** to the current value of [sqlite_malloc_outstanding -bytes]. 8555591df55Sdanielk1977 */ 8562e588c75Sdanielk1977 static int sqlite_malloc_outstanding( 8575591df55Sdanielk1977 ClientData clientData, 8582e588c75Sdanielk1977 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 8595591df55Sdanielk1977 int objc, /* Number of arguments */ 8605591df55Sdanielk1977 Tcl_Obj *CONST objv[] /* Command arguments */ 8612e588c75Sdanielk1977 ){ 8622e588c75Sdanielk1977 extern int sqlite3OutstandingMallocs(Tcl_Interp *interp); 8635591df55Sdanielk1977 8645591df55Sdanielk1977 if( objc!=1 && objc!=2 ){ 8655591df55Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "?-bytes?"); 8665591df55Sdanielk1977 return TCL_ERROR; 8675591df55Sdanielk1977 } 8685591df55Sdanielk1977 8695591df55Sdanielk1977 if( objc==2 ){ 8705591df55Sdanielk1977 const char *zArg = Tcl_GetString(objv[1]); 8715591df55Sdanielk1977 if( 0==strcmp(zArg, "-bytes") ){ 8725591df55Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3Tsd()->nAlloc)); 8735591df55Sdanielk1977 #ifndef SQLITE_OMIT_MEMORY_MANAGEMENT 8745591df55Sdanielk1977 }else if( 0==strcmp(zArg, "-maxbytes") ){ 8755591df55Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sqlite3Tsd()->nMaxAlloc)); 8765591df55Sdanielk1977 }else if( 0==strcmp(zArg, "-clearmaxbytes") ){ 8775591df55Sdanielk1977 sqlite3Tsd()->nMaxAlloc = sqlite3Tsd()->nAlloc; 8785591df55Sdanielk1977 #endif 8795591df55Sdanielk1977 }else{ 8805591df55Sdanielk1977 Tcl_AppendResult(interp, "bad option \"", zArg, 8815591df55Sdanielk1977 "\": must be -bytes, -maxbytes or -clearmaxbytes", 0 8825591df55Sdanielk1977 ); 8835591df55Sdanielk1977 return TCL_ERROR; 8845591df55Sdanielk1977 } 8855591df55Sdanielk1977 8865591df55Sdanielk1977 return TCL_OK; 8875591df55Sdanielk1977 } 8885591df55Sdanielk1977 8892e588c75Sdanielk1977 return sqlite3OutstandingMallocs(interp); 8902e588c75Sdanielk1977 } 891daffd0e5Sdrh #endif 892daffd0e5Sdrh 893daffd0e5Sdrh /* 894*aef0bf64Sdanielk1977 ** Usage: sqlite3_enable_shared_cache BOOLEAN 895*aef0bf64Sdanielk1977 ** 896*aef0bf64Sdanielk1977 */ 897*aef0bf64Sdanielk1977 #ifndef SQLITE_OMIT_SHARED_CACHE 898*aef0bf64Sdanielk1977 static int test_enable_shared_cache( 899*aef0bf64Sdanielk1977 ClientData clientData, 900*aef0bf64Sdanielk1977 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 901*aef0bf64Sdanielk1977 int objc, /* Number of arguments */ 902*aef0bf64Sdanielk1977 Tcl_Obj *CONST objv[] /* Command arguments */ 903*aef0bf64Sdanielk1977 ){ 904*aef0bf64Sdanielk1977 int rc; 905*aef0bf64Sdanielk1977 int enable; 906*aef0bf64Sdanielk1977 SqliteTsd *pTsd = sqlite3Tsd(); 907*aef0bf64Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(pTsd->useSharedData)); 908*aef0bf64Sdanielk1977 909*aef0bf64Sdanielk1977 if( objc!=2 ){ 910*aef0bf64Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN"); 911*aef0bf64Sdanielk1977 return TCL_ERROR; 912*aef0bf64Sdanielk1977 } 913*aef0bf64Sdanielk1977 if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ){ 914*aef0bf64Sdanielk1977 return TCL_ERROR; 915*aef0bf64Sdanielk1977 } 916*aef0bf64Sdanielk1977 rc = sqlite3_enable_shared_cache(enable); 917*aef0bf64Sdanielk1977 if( rc!=SQLITE_OK ){ 918*aef0bf64Sdanielk1977 Tcl_SetResult(interp, (char *)sqlite3ErrStr(rc), TCL_STATIC); 919*aef0bf64Sdanielk1977 return TCL_ERROR; 920*aef0bf64Sdanielk1977 } 921*aef0bf64Sdanielk1977 return TCL_OK; 922*aef0bf64Sdanielk1977 } 923*aef0bf64Sdanielk1977 #endif 924*aef0bf64Sdanielk1977 925*aef0bf64Sdanielk1977 /* 92628b4e489Sdrh ** Usage: sqlite_abort 92728b4e489Sdrh ** 92828b4e489Sdrh ** Shutdown the process immediately. This is not a clean shutdown. 92928b4e489Sdrh ** This command is used to test the recoverability of a database in 93028b4e489Sdrh ** the event of a program crash. 93128b4e489Sdrh */ 93228b4e489Sdrh static int sqlite_abort( 93328b4e489Sdrh void *NotUsed, 93428b4e489Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 93528b4e489Sdrh int argc, /* Number of arguments */ 93628b4e489Sdrh char **argv /* Text of each argument */ 93728b4e489Sdrh ){ 93828b4e489Sdrh assert( interp==0 ); /* This will always fail */ 93928b4e489Sdrh return TCL_OK; 94028b4e489Sdrh } 94128b4e489Sdrh 94228b4e489Sdrh /* 9436cbe1f1bSdrh ** The following routine is a user-defined SQL function whose purpose 9446cbe1f1bSdrh ** is to test the sqlite_set_result() API. 9456cbe1f1bSdrh */ 9460ae8b831Sdanielk1977 static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 9476cbe1f1bSdrh while( argc>=2 ){ 94803d847eaSdrh const char *zArg0 = (char*)sqlite3_value_text(argv[0]); 9496d88bad4Sdanielk1977 if( zArg0 ){ 9506d88bad4Sdanielk1977 if( 0==sqlite3StrICmp(zArg0, "int") ){ 9516d88bad4Sdanielk1977 sqlite3_result_int(context, sqlite3_value_int(argv[1])); 9526d88bad4Sdanielk1977 }else if( sqlite3StrICmp(zArg0,"int64")==0 ){ 9536d88bad4Sdanielk1977 sqlite3_result_int64(context, sqlite3_value_int64(argv[1])); 95451ad0ecdSdanielk1977 }else if( sqlite3StrICmp(zArg0,"string")==0 ){ 95503d847eaSdrh sqlite3_result_text(context, (char*)sqlite3_value_text(argv[1]), -1, 956d8123366Sdanielk1977 SQLITE_TRANSIENT); 95751ad0ecdSdanielk1977 }else if( sqlite3StrICmp(zArg0,"double")==0 ){ 9586d88bad4Sdanielk1977 sqlite3_result_double(context, sqlite3_value_double(argv[1])); 9596d88bad4Sdanielk1977 }else if( sqlite3StrICmp(zArg0,"null")==0 ){ 9606d88bad4Sdanielk1977 sqlite3_result_null(context); 9616d88bad4Sdanielk1977 }else if( sqlite3StrICmp(zArg0,"value")==0 ){ 9626d88bad4Sdanielk1977 sqlite3_result_value(context, argv[sqlite3_value_int(argv[1])]); 9636cbe1f1bSdrh }else{ 9646d88bad4Sdanielk1977 goto error_out; 9656d88bad4Sdanielk1977 } 9666d88bad4Sdanielk1977 }else{ 9676d88bad4Sdanielk1977 goto error_out; 9686cbe1f1bSdrh } 9696cbe1f1bSdrh argc -= 2; 9706cbe1f1bSdrh argv += 2; 9716cbe1f1bSdrh } 9726d88bad4Sdanielk1977 return; 9736d88bad4Sdanielk1977 9746d88bad4Sdanielk1977 error_out: 9756d88bad4Sdanielk1977 sqlite3_result_error(context,"first argument should be one of: " 9766d88bad4Sdanielk1977 "int int64 string double null value", -1); 9776cbe1f1bSdrh } 9786cbe1f1bSdrh 9796cbe1f1bSdrh /* 9806cbe1f1bSdrh ** Usage: sqlite_register_test_function DB NAME 9816cbe1f1bSdrh ** 9826cbe1f1bSdrh ** Register the test SQL function on the database DB under the name NAME. 9836cbe1f1bSdrh */ 984c2eef3b3Sdrh static int test_register_func( 9856cbe1f1bSdrh void *NotUsed, 9866cbe1f1bSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 9876cbe1f1bSdrh int argc, /* Number of arguments */ 9886cbe1f1bSdrh char **argv /* Text of each argument */ 9896cbe1f1bSdrh ){ 9909bb575fdSdrh sqlite3 *db; 9916cbe1f1bSdrh int rc; 9926cbe1f1bSdrh if( argc!=3 ){ 9936cbe1f1bSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 9946cbe1f1bSdrh " DB FUNCTION-NAME", 0); 9956cbe1f1bSdrh return TCL_ERROR; 9966cbe1f1bSdrh } 997b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 998f9d64d2cSdanielk1977 rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 999d8123366Sdanielk1977 testFunc, 0, 0); 10006cbe1f1bSdrh if( rc!=0 ){ 1001f20b21c8Sdanielk1977 Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0); 10026cbe1f1bSdrh return TCL_ERROR; 10036cbe1f1bSdrh } 1004c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 10056cbe1f1bSdrh return TCL_OK; 10066cbe1f1bSdrh } 10076cbe1f1bSdrh 10086cbe1f1bSdrh /* 1009106bb236Sdanielk1977 ** Usage: sqlite3_finalize STMT 1010b86ccfb2Sdrh ** 1011106bb236Sdanielk1977 ** Finalize a statement handle. 1012b86ccfb2Sdrh */ 1013b86ccfb2Sdrh static int test_finalize( 1014106bb236Sdanielk1977 void * clientData, 1015106bb236Sdanielk1977 Tcl_Interp *interp, 1016106bb236Sdanielk1977 int objc, 1017106bb236Sdanielk1977 Tcl_Obj *CONST objv[] 1018b86ccfb2Sdrh ){ 1019106bb236Sdanielk1977 sqlite3_stmt *pStmt; 1020b86ccfb2Sdrh int rc; 1021c60d0446Sdrh sqlite3 *db; 1022106bb236Sdanielk1977 1023106bb236Sdanielk1977 if( objc!=2 ){ 1024106bb236Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1025106bb236Sdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 1026b86ccfb2Sdrh return TCL_ERROR; 1027b86ccfb2Sdrh } 1028106bb236Sdanielk1977 1029106bb236Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1030106bb236Sdanielk1977 10314397de57Sdanielk1977 if( pStmt ){ 1032c60d0446Sdrh db = StmtToDb(pStmt); 10334397de57Sdanielk1977 } 1034fc57d7bfSdanielk1977 rc = sqlite3_finalize(pStmt); 1035b77f5dadSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 10364397de57Sdanielk1977 if( db && sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1037106bb236Sdanielk1977 return TCL_OK; 1038106bb236Sdanielk1977 } 1039106bb236Sdanielk1977 1040106bb236Sdanielk1977 /* 1041106bb236Sdanielk1977 ** Usage: sqlite3_reset STMT 1042106bb236Sdanielk1977 ** 1043261919ccSdanielk1977 ** Reset a statement handle. 1044106bb236Sdanielk1977 */ 1045106bb236Sdanielk1977 static int test_reset( 1046106bb236Sdanielk1977 void * clientData, 1047106bb236Sdanielk1977 Tcl_Interp *interp, 1048106bb236Sdanielk1977 int objc, 1049106bb236Sdanielk1977 Tcl_Obj *CONST objv[] 1050106bb236Sdanielk1977 ){ 1051106bb236Sdanielk1977 sqlite3_stmt *pStmt; 1052106bb236Sdanielk1977 int rc; 1053106bb236Sdanielk1977 1054106bb236Sdanielk1977 if( objc!=2 ){ 1055106bb236Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1056106bb236Sdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 1057106bb236Sdanielk1977 return TCL_ERROR; 1058106bb236Sdanielk1977 } 1059106bb236Sdanielk1977 1060106bb236Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1061106bb236Sdanielk1977 1062fc57d7bfSdanielk1977 rc = sqlite3_reset(pStmt); 1063261919ccSdanielk1977 if( pStmt && sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ){ 1064261919ccSdanielk1977 return TCL_ERROR; 1065261919ccSdanielk1977 } 10664397de57Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 1067261919ccSdanielk1977 /* 1068106bb236Sdanielk1977 if( rc ){ 1069b86ccfb2Sdrh return TCL_ERROR; 1070b86ccfb2Sdrh } 1071261919ccSdanielk1977 */ 1072b86ccfb2Sdrh return TCL_OK; 1073b86ccfb2Sdrh } 1074b86ccfb2Sdrh 10755a38705eSdrh /* 1076d89bd007Sdrh ** Usage: sqlite3_expired STMT 1077d89bd007Sdrh ** 1078d89bd007Sdrh ** Return TRUE if a recompilation of the statement is recommended. 1079d89bd007Sdrh */ 1080d89bd007Sdrh static int test_expired( 1081d89bd007Sdrh void * clientData, 1082d89bd007Sdrh Tcl_Interp *interp, 1083d89bd007Sdrh int objc, 1084d89bd007Sdrh Tcl_Obj *CONST objv[] 1085d89bd007Sdrh ){ 1086d89bd007Sdrh sqlite3_stmt *pStmt; 1087d89bd007Sdrh if( objc!=2 ){ 1088d89bd007Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", 1089d89bd007Sdrh Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 1090d89bd007Sdrh return TCL_ERROR; 1091d89bd007Sdrh } 1092d89bd007Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1093d89bd007Sdrh Tcl_SetObjResult(interp, Tcl_NewBooleanObj(sqlite3_expired(pStmt))); 1094d89bd007Sdrh return TCL_OK; 1095d89bd007Sdrh } 1096d89bd007Sdrh 1097d89bd007Sdrh /* 1098f8db1bc0Sdrh ** Usage: sqlite3_transfer_bindings FROMSTMT TOSTMT 1099f8db1bc0Sdrh ** 1100f8db1bc0Sdrh ** Transfer all bindings from FROMSTMT over to TOSTMT 1101f8db1bc0Sdrh */ 1102f8db1bc0Sdrh static int test_transfer_bind( 1103f8db1bc0Sdrh void * clientData, 1104f8db1bc0Sdrh Tcl_Interp *interp, 1105f8db1bc0Sdrh int objc, 1106f8db1bc0Sdrh Tcl_Obj *CONST objv[] 1107f8db1bc0Sdrh ){ 1108f8db1bc0Sdrh sqlite3_stmt *pStmt1, *pStmt2; 1109f8db1bc0Sdrh if( objc!=3 ){ 1110f8db1bc0Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", 1111f8db1bc0Sdrh Tcl_GetStringFromObj(objv[0], 0), " FROM-STMT TO-STMT", 0); 1112f8db1bc0Sdrh return TCL_ERROR; 1113f8db1bc0Sdrh } 1114f8db1bc0Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt1)) return TCL_ERROR; 1115f8db1bc0Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[2]), &pStmt2)) return TCL_ERROR; 1116f8db1bc0Sdrh Tcl_SetObjResult(interp, 1117f8db1bc0Sdrh Tcl_NewIntObj(sqlite3_transfer_bindings(pStmt1,pStmt2))); 1118f8db1bc0Sdrh return TCL_OK; 1119f8db1bc0Sdrh } 1120f8db1bc0Sdrh 1121f8db1bc0Sdrh /* 1122fbcd585fSdanielk1977 ** Usage: sqlite3_changes DB 112350457896Sdrh ** 1124fbcd585fSdanielk1977 ** Return the number of changes made to the database by the last SQL 1125fbcd585fSdanielk1977 ** execution. 112650457896Sdrh */ 1127fbcd585fSdanielk1977 static int test_changes( 1128fbcd585fSdanielk1977 void * clientData, 1129fbcd585fSdanielk1977 Tcl_Interp *interp, 1130fbcd585fSdanielk1977 int objc, 1131fbcd585fSdanielk1977 Tcl_Obj *CONST objv[] 1132fbcd585fSdanielk1977 ){ 1133fbcd585fSdanielk1977 sqlite3 *db; 1134fbcd585fSdanielk1977 if( objc!=2 ){ 1135fbcd585fSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1136fbcd585fSdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 1137fbcd585fSdanielk1977 return TCL_ERROR; 1138fbcd585fSdanielk1977 } 1139fbcd585fSdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1140fbcd585fSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_changes(db))); 1141fbcd585fSdanielk1977 return TCL_OK; 1142fbcd585fSdanielk1977 } 114350457896Sdrh 114450457896Sdrh /* 11457c972decSdrh ** This is the "static_bind_value" that variables are bound to when 11466f8a503dSdanielk1977 ** the FLAG option of sqlite3_bind is "static" 114750457896Sdrh */ 11487c972decSdrh static char *sqlite_static_bind_value = 0; 11497c972decSdrh 11507c972decSdrh /* 11516f8a503dSdanielk1977 ** Usage: sqlite3_bind VM IDX VALUE FLAGS 11527c972decSdrh ** 11537c972decSdrh ** Sets the value of the IDX-th occurance of "?" in the original SQL 11547c972decSdrh ** string. VALUE is the new value. If FLAGS=="null" then VALUE is 11557c972decSdrh ** ignored and the value is set to NULL. If FLAGS=="static" then 11567c972decSdrh ** the value is set to the value of a static variable named 11577c972decSdrh ** "sqlite_static_bind_value". If FLAGS=="normal" then a copy 1158bf8aa2a6Sdrh ** of the VALUE is made. If FLAGS=="blob10" then a VALUE is ignored 1159bf8aa2a6Sdrh ** an a 10-byte blob "abc\000xyz\000pq" is inserted. 11607c972decSdrh */ 11617c972decSdrh static int test_bind( 116250457896Sdrh void *NotUsed, 116350457896Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 116450457896Sdrh int argc, /* Number of arguments */ 116550457896Sdrh char **argv /* Text of each argument */ 116650457896Sdrh ){ 1167fc57d7bfSdanielk1977 sqlite3_stmt *pStmt; 116850457896Sdrh int rc; 11697c972decSdrh int idx; 11707c972decSdrh if( argc!=5 ){ 117150457896Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 11727c972decSdrh " VM IDX VALUE (null|static|normal)\"", 0); 117350457896Sdrh return TCL_ERROR; 117450457896Sdrh } 1175fc57d7bfSdanielk1977 if( getStmtPointer(interp, argv[1], &pStmt) ) return TCL_ERROR; 11767c972decSdrh if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR; 11777c972decSdrh if( strcmp(argv[4],"null")==0 ){ 1178fc57d7bfSdanielk1977 rc = sqlite3_bind_null(pStmt, idx); 11797c972decSdrh }else if( strcmp(argv[4],"static")==0 ){ 1180fc57d7bfSdanielk1977 rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0); 11817c972decSdrh }else if( strcmp(argv[4],"normal")==0 ){ 1182d8123366Sdanielk1977 rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, SQLITE_TRANSIENT); 1183bf8aa2a6Sdrh }else if( strcmp(argv[4],"blob10")==0 ){ 1184bf8aa2a6Sdrh rc = sqlite3_bind_text(pStmt, idx, "abc\000xyz\000pq", 10, SQLITE_STATIC); 11857c972decSdrh }else{ 11867c972decSdrh Tcl_AppendResult(interp, "4th argument should be " 11877c972decSdrh "\"null\" or \"static\" or \"normal\"", 0); 11887c972decSdrh return TCL_ERROR; 11897c972decSdrh } 1190c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 119150457896Sdrh if( rc ){ 119250457896Sdrh char zBuf[50]; 119350457896Sdrh sprintf(zBuf, "(%d) ", rc); 1194f20b21c8Sdanielk1977 Tcl_AppendResult(interp, zBuf, sqlite3ErrStr(rc), 0); 119550457896Sdrh return TCL_ERROR; 119650457896Sdrh } 119750457896Sdrh return TCL_OK; 119850457896Sdrh } 119950457896Sdrh 12005436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 12014e6af134Sdanielk1977 /* 12024e6af134Sdanielk1977 ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be> 12034e6af134Sdanielk1977 ** 12044e6af134Sdanielk1977 ** This function is used to test that SQLite selects the correct collation 12054e6af134Sdanielk1977 ** sequence callback when multiple versions (for different text encodings) 12064e6af134Sdanielk1977 ** are available. 12074e6af134Sdanielk1977 ** 12084e6af134Sdanielk1977 ** Calling this routine registers the collation sequence "test_collate" 12094e6af134Sdanielk1977 ** with database handle <db>. The second argument must be a list of three 12104e6af134Sdanielk1977 ** boolean values. If the first is true, then a version of test_collate is 12114e6af134Sdanielk1977 ** registered for UTF-8, if the second is true, a version is registered for 12124e6af134Sdanielk1977 ** UTF-16le, if the third is true, a UTF-16be version is available. 12134e6af134Sdanielk1977 ** Previous versions of test_collate are deleted. 12144e6af134Sdanielk1977 ** 12154e6af134Sdanielk1977 ** The collation sequence test_collate is implemented by calling the 12164e6af134Sdanielk1977 ** following TCL script: 12174e6af134Sdanielk1977 ** 12184e6af134Sdanielk1977 ** "test_collate <enc> <lhs> <rhs>" 12194e6af134Sdanielk1977 ** 12204e6af134Sdanielk1977 ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8. 12214e6af134Sdanielk1977 ** The <enc> parameter is the encoding of the collation function that 12224e6af134Sdanielk1977 ** SQLite selected to call. The TCL test script implements the 12234e6af134Sdanielk1977 ** "test_collate" proc. 12244e6af134Sdanielk1977 ** 12254e6af134Sdanielk1977 ** Note that this will only work with one intepreter at a time, as the 12264e6af134Sdanielk1977 ** interp pointer to use when evaluating the TCL script is stored in 12274e6af134Sdanielk1977 ** pTestCollateInterp. 12284e6af134Sdanielk1977 */ 12294e6af134Sdanielk1977 static Tcl_Interp* pTestCollateInterp; 12304e6af134Sdanielk1977 static int test_collate_func( 12314e6af134Sdanielk1977 void *pCtx, 12324e6af134Sdanielk1977 int nA, const void *zA, 12334e6af134Sdanielk1977 int nB, const void *zB 12344e6af134Sdanielk1977 ){ 12354e6af134Sdanielk1977 Tcl_Interp *i = pTestCollateInterp; 12364e6af134Sdanielk1977 int encin = (int)pCtx; 12374e6af134Sdanielk1977 int res; 12384db38a70Sdrh int n; 12394e6af134Sdanielk1977 12404e6af134Sdanielk1977 sqlite3_value *pVal; 12414e6af134Sdanielk1977 Tcl_Obj *pX; 12424e6af134Sdanielk1977 12434e6af134Sdanielk1977 pX = Tcl_NewStringObj("test_collate", -1); 12444e6af134Sdanielk1977 Tcl_IncrRefCount(pX); 12454e6af134Sdanielk1977 12464e6af134Sdanielk1977 switch( encin ){ 12474e6af134Sdanielk1977 case SQLITE_UTF8: 12484e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-8",-1)); 12494e6af134Sdanielk1977 break; 12504e6af134Sdanielk1977 case SQLITE_UTF16LE: 12514e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16LE",-1)); 12524e6af134Sdanielk1977 break; 12534e6af134Sdanielk1977 case SQLITE_UTF16BE: 12544e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16BE",-1)); 12554e6af134Sdanielk1977 break; 12564e6af134Sdanielk1977 default: 12574e6af134Sdanielk1977 assert(0); 12584e6af134Sdanielk1977 } 12594e6af134Sdanielk1977 12604e6af134Sdanielk1977 pVal = sqlite3ValueNew(); 1261bfd6cce5Sdanielk1977 sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC); 12624db38a70Sdrh n = sqlite3_value_bytes(pVal); 126303d847eaSdrh Tcl_ListObjAppendElement(i,pX, 126403d847eaSdrh Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n)); 1265bfd6cce5Sdanielk1977 sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC); 12664db38a70Sdrh n = sqlite3_value_bytes(pVal); 126703d847eaSdrh Tcl_ListObjAppendElement(i,pX, 126803d847eaSdrh Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n)); 12694e6af134Sdanielk1977 sqlite3ValueFree(pVal); 12704e6af134Sdanielk1977 12714e6af134Sdanielk1977 Tcl_EvalObjEx(i, pX, 0); 12724e6af134Sdanielk1977 Tcl_DecrRefCount(pX); 12734e6af134Sdanielk1977 Tcl_GetIntFromObj(i, Tcl_GetObjResult(i), &res); 12744e6af134Sdanielk1977 return res; 12754e6af134Sdanielk1977 } 12764e6af134Sdanielk1977 static int test_collate( 12774e6af134Sdanielk1977 void * clientData, 12784e6af134Sdanielk1977 Tcl_Interp *interp, 12794e6af134Sdanielk1977 int objc, 12804e6af134Sdanielk1977 Tcl_Obj *CONST objv[] 12814e6af134Sdanielk1977 ){ 12824e6af134Sdanielk1977 sqlite3 *db; 12834e6af134Sdanielk1977 int val; 1284312d6b36Sdanielk1977 sqlite3_value *pVal; 1285c60d0446Sdrh int rc; 12864e6af134Sdanielk1977 12874e6af134Sdanielk1977 if( objc!=5 ) goto bad_args; 12884e6af134Sdanielk1977 pTestCollateInterp = interp; 12894e6af134Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 12904e6af134Sdanielk1977 12914e6af134Sdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; 1292c60d0446Sdrh rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8, 12934e6af134Sdanielk1977 (void *)SQLITE_UTF8, val?test_collate_func:0); 1294c60d0446Sdrh if( rc==SQLITE_OK ){ 12954e6af134Sdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; 1296c60d0446Sdrh rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE, 12974e6af134Sdanielk1977 (void *)SQLITE_UTF16LE, val?test_collate_func:0); 12984e6af134Sdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR; 1299312d6b36Sdanielk1977 1300312d6b36Sdanielk1977 pVal = sqlite3ValueNew(); 1301312d6b36Sdanielk1977 sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC); 1302312d6b36Sdanielk1977 sqlite3_create_collation16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), 1303312d6b36Sdanielk1977 SQLITE_UTF16BE, (void *)SQLITE_UTF16BE, val?test_collate_func:0); 1304312d6b36Sdanielk1977 sqlite3ValueFree(pVal); 1305c60d0446Sdrh } 1306c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 13074e6af134Sdanielk1977 return TCL_OK; 13084e6af134Sdanielk1977 13094e6af134Sdanielk1977 bad_args: 13104e6af134Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 13114e6af134Sdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); 13124e6af134Sdanielk1977 return TCL_ERROR; 13134e6af134Sdanielk1977 } 13144e6af134Sdanielk1977 1315268803a9Sdrh /* 1316268803a9Sdrh ** When the collation needed callback is invoked, record the name of 1317268803a9Sdrh ** the requested collating function here. The recorded name is linked 1318268803a9Sdrh ** to a TCL variable and used to make sure that the requested collation 1319268803a9Sdrh ** name is correct. 1320268803a9Sdrh */ 1321268803a9Sdrh static char zNeededCollation[200]; 1322268803a9Sdrh static char *pzNeededCollation = zNeededCollation; 1323268803a9Sdrh 1324268803a9Sdrh 1325268803a9Sdrh /* 1326268803a9Sdrh ** Called when a collating sequence is needed. Registered using 1327268803a9Sdrh ** sqlite3_collation_needed16(). 1328268803a9Sdrh */ 1329312d6b36Sdanielk1977 static void test_collate_needed_cb( 1330312d6b36Sdanielk1977 void *pCtx, 1331312d6b36Sdanielk1977 sqlite3 *db, 1332312d6b36Sdanielk1977 int eTextRep, 1333268803a9Sdrh const void *pName 1334312d6b36Sdanielk1977 ){ 1335312d6b36Sdanielk1977 int enc = db->enc; 1336268803a9Sdrh int i; 1337268803a9Sdrh char *z; 1338268803a9Sdrh for(z = (char*)pName, i=0; *z || z[1]; z++){ 1339268803a9Sdrh if( *z ) zNeededCollation[i++] = *z; 1340268803a9Sdrh } 1341268803a9Sdrh zNeededCollation[i] = 0; 1342312d6b36Sdanielk1977 sqlite3_create_collation( 1343312d6b36Sdanielk1977 db, "test_collate", db->enc, (void *)enc, test_collate_func); 1344312d6b36Sdanielk1977 } 1345312d6b36Sdanielk1977 1346312d6b36Sdanielk1977 /* 1347312d6b36Sdanielk1977 ** Usage: add_test_collate_needed DB 1348312d6b36Sdanielk1977 */ 1349312d6b36Sdanielk1977 static int test_collate_needed( 1350312d6b36Sdanielk1977 void * clientData, 1351312d6b36Sdanielk1977 Tcl_Interp *interp, 1352312d6b36Sdanielk1977 int objc, 1353312d6b36Sdanielk1977 Tcl_Obj *CONST objv[] 1354312d6b36Sdanielk1977 ){ 1355312d6b36Sdanielk1977 sqlite3 *db; 1356c60d0446Sdrh int rc; 1357312d6b36Sdanielk1977 1358312d6b36Sdanielk1977 if( objc!=2 ) goto bad_args; 1359312d6b36Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1360c60d0446Sdrh rc = sqlite3_collation_needed16(db, 0, test_collate_needed_cb); 1361268803a9Sdrh zNeededCollation[0] = 0; 1362c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1363312d6b36Sdanielk1977 return TCL_OK; 1364312d6b36Sdanielk1977 1365312d6b36Sdanielk1977 bad_args: 1366312d6b36Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "DB"); 1367312d6b36Sdanielk1977 return TCL_ERROR; 1368312d6b36Sdanielk1977 } 13695436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 1370312d6b36Sdanielk1977 1371c8e9a2dfSdanielk1977 /* 1372c8e9a2dfSdanielk1977 ** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be> 1373c8e9a2dfSdanielk1977 ** 1374c8e9a2dfSdanielk1977 ** This function is used to test that SQLite selects the correct user 1375c8e9a2dfSdanielk1977 ** function callback when multiple versions (for different text encodings) 1376c8e9a2dfSdanielk1977 ** are available. 1377c8e9a2dfSdanielk1977 ** 1378c8e9a2dfSdanielk1977 ** Calling this routine registers up to three versions of the user function 1379c8e9a2dfSdanielk1977 ** "test_function" with database handle <db>. If the second argument is 1380c8e9a2dfSdanielk1977 ** true, then a version of test_function is registered for UTF-8, if the 1381c8e9a2dfSdanielk1977 ** third is true, a version is registered for UTF-16le, if the fourth is 1382c8e9a2dfSdanielk1977 ** true, a UTF-16be version is available. Previous versions of 1383c8e9a2dfSdanielk1977 ** test_function are deleted. 1384c8e9a2dfSdanielk1977 ** 1385c8e9a2dfSdanielk1977 ** The user function is implemented by calling the following TCL script: 1386c8e9a2dfSdanielk1977 ** 1387c8e9a2dfSdanielk1977 ** "test_function <enc> <arg>" 1388c8e9a2dfSdanielk1977 ** 1389c8e9a2dfSdanielk1977 ** Where <enc> is one of UTF-8, UTF-16LE or UTF16BE, and <arg> is the 1390c8e9a2dfSdanielk1977 ** single argument passed to the SQL function. The value returned by 1391c8e9a2dfSdanielk1977 ** the TCL script is used as the return value of the SQL function. It 1392c8e9a2dfSdanielk1977 ** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8 1393c8e9a2dfSdanielk1977 ** for a UTF-16LE test_function(), and UTF-16LE for an implementation that 1394c8e9a2dfSdanielk1977 ** prefers UTF-16BE. 1395c8e9a2dfSdanielk1977 */ 13965436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 1397c8e9a2dfSdanielk1977 static void test_function_utf8( 1398c8e9a2dfSdanielk1977 sqlite3_context *pCtx, 1399c8e9a2dfSdanielk1977 int nArg, 1400c8e9a2dfSdanielk1977 sqlite3_value **argv 1401c8e9a2dfSdanielk1977 ){ 1402c8e9a2dfSdanielk1977 Tcl_Interp *interp; 1403c8e9a2dfSdanielk1977 Tcl_Obj *pX; 1404c8e9a2dfSdanielk1977 sqlite3_value *pVal; 1405c8e9a2dfSdanielk1977 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1406c8e9a2dfSdanielk1977 pX = Tcl_NewStringObj("test_function", -1); 1407c8e9a2dfSdanielk1977 Tcl_IncrRefCount(pX); 1408c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-8", -1)); 1409c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, 141003d847eaSdrh Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1)); 1411c8e9a2dfSdanielk1977 Tcl_EvalObjEx(interp, pX, 0); 1412c8e9a2dfSdanielk1977 Tcl_DecrRefCount(pX); 1413c8e9a2dfSdanielk1977 sqlite3_result_text(pCtx, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT); 1414c8e9a2dfSdanielk1977 pVal = sqlite3ValueNew(); 1415c8e9a2dfSdanielk1977 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1416c8e9a2dfSdanielk1977 SQLITE_UTF8, SQLITE_STATIC); 1417c8e9a2dfSdanielk1977 sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal), 1418c8e9a2dfSdanielk1977 -1, SQLITE_TRANSIENT); 1419c8e9a2dfSdanielk1977 sqlite3ValueFree(pVal); 1420c8e9a2dfSdanielk1977 } 1421c8e9a2dfSdanielk1977 static void test_function_utf16le( 1422c8e9a2dfSdanielk1977 sqlite3_context *pCtx, 1423c8e9a2dfSdanielk1977 int nArg, 1424c8e9a2dfSdanielk1977 sqlite3_value **argv 1425c8e9a2dfSdanielk1977 ){ 1426c8e9a2dfSdanielk1977 Tcl_Interp *interp; 1427c8e9a2dfSdanielk1977 Tcl_Obj *pX; 1428c8e9a2dfSdanielk1977 sqlite3_value *pVal; 1429c8e9a2dfSdanielk1977 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1430c8e9a2dfSdanielk1977 pX = Tcl_NewStringObj("test_function", -1); 1431c8e9a2dfSdanielk1977 Tcl_IncrRefCount(pX); 1432c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16LE", -1)); 1433c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, 143403d847eaSdrh Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1)); 1435c8e9a2dfSdanielk1977 Tcl_EvalObjEx(interp, pX, 0); 1436c8e9a2dfSdanielk1977 Tcl_DecrRefCount(pX); 1437c8e9a2dfSdanielk1977 pVal = sqlite3ValueNew(); 1438c8e9a2dfSdanielk1977 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1439c8e9a2dfSdanielk1977 SQLITE_UTF8, SQLITE_STATIC); 144003d847eaSdrh sqlite3_result_text(pCtx,(char*)sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT); 1441c8e9a2dfSdanielk1977 sqlite3ValueFree(pVal); 1442c8e9a2dfSdanielk1977 } 1443c8e9a2dfSdanielk1977 static void test_function_utf16be( 1444c8e9a2dfSdanielk1977 sqlite3_context *pCtx, 1445c8e9a2dfSdanielk1977 int nArg, 1446c8e9a2dfSdanielk1977 sqlite3_value **argv 1447c8e9a2dfSdanielk1977 ){ 1448c8e9a2dfSdanielk1977 Tcl_Interp *interp; 1449c8e9a2dfSdanielk1977 Tcl_Obj *pX; 1450c8e9a2dfSdanielk1977 sqlite3_value *pVal; 1451c8e9a2dfSdanielk1977 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1452c8e9a2dfSdanielk1977 pX = Tcl_NewStringObj("test_function", -1); 1453c8e9a2dfSdanielk1977 Tcl_IncrRefCount(pX); 1454c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16BE", -1)); 1455c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, 145603d847eaSdrh Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1)); 1457c8e9a2dfSdanielk1977 Tcl_EvalObjEx(interp, pX, 0); 1458c8e9a2dfSdanielk1977 Tcl_DecrRefCount(pX); 1459c8e9a2dfSdanielk1977 pVal = sqlite3ValueNew(); 1460c8e9a2dfSdanielk1977 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1461c8e9a2dfSdanielk1977 SQLITE_UTF8, SQLITE_STATIC); 1462c8e9a2dfSdanielk1977 sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal), 1463c8e9a2dfSdanielk1977 -1, SQLITE_TRANSIENT); 1464c8e9a2dfSdanielk1977 sqlite3ValueFree(pVal); 1465c8e9a2dfSdanielk1977 } 14665436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 1467c8e9a2dfSdanielk1977 static int test_function( 1468c8e9a2dfSdanielk1977 void * clientData, 1469c8e9a2dfSdanielk1977 Tcl_Interp *interp, 1470c8e9a2dfSdanielk1977 int objc, 1471c8e9a2dfSdanielk1977 Tcl_Obj *CONST objv[] 1472c8e9a2dfSdanielk1977 ){ 14735436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 1474c8e9a2dfSdanielk1977 sqlite3 *db; 1475c8e9a2dfSdanielk1977 int val; 1476c8e9a2dfSdanielk1977 1477c8e9a2dfSdanielk1977 if( objc!=5 ) goto bad_args; 1478c8e9a2dfSdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1479c8e9a2dfSdanielk1977 1480c8e9a2dfSdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; 1481c8e9a2dfSdanielk1977 if( val ){ 1482c8e9a2dfSdanielk1977 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF8, 1483c8e9a2dfSdanielk1977 interp, test_function_utf8, 0, 0); 1484c8e9a2dfSdanielk1977 } 1485c8e9a2dfSdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; 1486c8e9a2dfSdanielk1977 if( val ){ 1487c8e9a2dfSdanielk1977 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16LE, 1488c8e9a2dfSdanielk1977 interp, test_function_utf16le, 0, 0); 1489c8e9a2dfSdanielk1977 } 1490c8e9a2dfSdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR; 1491c8e9a2dfSdanielk1977 if( val ){ 1492c8e9a2dfSdanielk1977 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16BE, 1493c8e9a2dfSdanielk1977 interp, test_function_utf16be, 0, 0); 1494c8e9a2dfSdanielk1977 } 1495c8e9a2dfSdanielk1977 1496c8e9a2dfSdanielk1977 return TCL_OK; 1497c8e9a2dfSdanielk1977 bad_args: 1498c8e9a2dfSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1499c8e9a2dfSdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); 15005436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 1501c8e9a2dfSdanielk1977 return TCL_ERROR; 1502c8e9a2dfSdanielk1977 } 1503c8e9a2dfSdanielk1977 1504312d6b36Sdanielk1977 /* 1505312d6b36Sdanielk1977 ** Usage: test_errstr <err code> 1506312d6b36Sdanielk1977 ** 1507312d6b36Sdanielk1977 ** Test that the english language string equivalents for sqlite error codes 1508312d6b36Sdanielk1977 ** are sane. The parameter is an integer representing an sqlite error code. 1509312d6b36Sdanielk1977 ** The result is a list of two elements, the string representation of the 1510312d6b36Sdanielk1977 ** error code and the english language explanation. 1511312d6b36Sdanielk1977 */ 1512312d6b36Sdanielk1977 static int test_errstr( 1513312d6b36Sdanielk1977 void * clientData, 1514312d6b36Sdanielk1977 Tcl_Interp *interp, 1515312d6b36Sdanielk1977 int objc, 1516312d6b36Sdanielk1977 Tcl_Obj *CONST objv[] 1517312d6b36Sdanielk1977 ){ 1518312d6b36Sdanielk1977 char *zCode; 1519312d6b36Sdanielk1977 int i; 1520312d6b36Sdanielk1977 if( objc!=1 ){ 1521312d6b36Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "<error code>"); 1522312d6b36Sdanielk1977 } 1523312d6b36Sdanielk1977 1524312d6b36Sdanielk1977 zCode = Tcl_GetString(objv[1]); 1525312d6b36Sdanielk1977 for(i=0; i<200; i++){ 1526312d6b36Sdanielk1977 if( 0==strcmp(errorName(i), zCode) ) break; 1527312d6b36Sdanielk1977 } 1528312d6b36Sdanielk1977 Tcl_SetResult(interp, (char *)sqlite3ErrStr(i), 0); 1529312d6b36Sdanielk1977 return TCL_OK; 1530312d6b36Sdanielk1977 } 1531312d6b36Sdanielk1977 153250457896Sdrh /* 153399ee3600Sdrh ** Usage: breakpoint 153499ee3600Sdrh ** 153599ee3600Sdrh ** This routine exists for one purpose - to provide a place to put a 153699ee3600Sdrh ** breakpoint with GDB that can be triggered using TCL code. The use 153799ee3600Sdrh ** for this is when a particular test fails on (say) the 1485th iteration. 153899ee3600Sdrh ** In the TCL test script, we can add code like this: 153999ee3600Sdrh ** 154099ee3600Sdrh ** if {$i==1485} breakpoint 154199ee3600Sdrh ** 154299ee3600Sdrh ** Then run testfixture in the debugger and wait for the breakpoint to 154399ee3600Sdrh ** fire. Then additional breakpoints can be set to trace down the bug. 154499ee3600Sdrh */ 154599ee3600Sdrh static int test_breakpoint( 154699ee3600Sdrh void *NotUsed, 154799ee3600Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 154899ee3600Sdrh int argc, /* Number of arguments */ 154999ee3600Sdrh char **argv /* Text of each argument */ 155099ee3600Sdrh ){ 155199ee3600Sdrh return TCL_OK; /* Do nothing */ 155299ee3600Sdrh } 155399ee3600Sdrh 1554241db313Sdrh /* 1555241db313Sdrh ** Usage: sqlite3_bind_int STMT N VALUE 1556241db313Sdrh ** 1557241db313Sdrh ** Test the sqlite3_bind_int interface. STMT is a prepared statement. 1558241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1559241db313Sdrh ** binds a 32-bit integer VALUE to that wildcard. 1560241db313Sdrh */ 1561241db313Sdrh static int test_bind_int( 156251e3d8e2Sdanielk1977 void * clientData, 156351e3d8e2Sdanielk1977 Tcl_Interp *interp, 156451e3d8e2Sdanielk1977 int objc, 156551e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 156651e3d8e2Sdanielk1977 ){ 156751e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 156851e3d8e2Sdanielk1977 int idx; 156951e3d8e2Sdanielk1977 int value; 157051e3d8e2Sdanielk1977 int rc; 157151e3d8e2Sdanielk1977 157251e3d8e2Sdanielk1977 if( objc!=4 ){ 157351e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1574241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 157551e3d8e2Sdanielk1977 return TCL_ERROR; 157651e3d8e2Sdanielk1977 } 157751e3d8e2Sdanielk1977 157851e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 157951e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 158051e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR; 158151e3d8e2Sdanielk1977 1582c572ef7fSdanielk1977 rc = sqlite3_bind_int(pStmt, idx, value); 1583c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 158451e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 158551e3d8e2Sdanielk1977 return TCL_ERROR; 158651e3d8e2Sdanielk1977 } 158751e3d8e2Sdanielk1977 158851e3d8e2Sdanielk1977 return TCL_OK; 158951e3d8e2Sdanielk1977 } 159051e3d8e2Sdanielk1977 1591241db313Sdrh 1592241db313Sdrh /* 1593241db313Sdrh ** Usage: sqlite3_bind_int64 STMT N VALUE 1594241db313Sdrh ** 1595241db313Sdrh ** Test the sqlite3_bind_int64 interface. STMT is a prepared statement. 1596241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1597241db313Sdrh ** binds a 64-bit integer VALUE to that wildcard. 1598241db313Sdrh */ 159951e3d8e2Sdanielk1977 static int test_bind_int64( 160051e3d8e2Sdanielk1977 void * clientData, 160151e3d8e2Sdanielk1977 Tcl_Interp *interp, 160251e3d8e2Sdanielk1977 int objc, 160351e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 160451e3d8e2Sdanielk1977 ){ 160551e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 160651e3d8e2Sdanielk1977 int idx; 160751e3d8e2Sdanielk1977 i64 value; 160851e3d8e2Sdanielk1977 int rc; 160951e3d8e2Sdanielk1977 161051e3d8e2Sdanielk1977 if( objc!=4 ){ 161151e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1612241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 161351e3d8e2Sdanielk1977 return TCL_ERROR; 161451e3d8e2Sdanielk1977 } 161551e3d8e2Sdanielk1977 161651e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 161751e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 161851e3d8e2Sdanielk1977 if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR; 161951e3d8e2Sdanielk1977 162051e3d8e2Sdanielk1977 rc = sqlite3_bind_int64(pStmt, idx, value); 1621c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 162251e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 162351e3d8e2Sdanielk1977 return TCL_ERROR; 162451e3d8e2Sdanielk1977 } 162551e3d8e2Sdanielk1977 162651e3d8e2Sdanielk1977 return TCL_OK; 162751e3d8e2Sdanielk1977 } 162851e3d8e2Sdanielk1977 1629241db313Sdrh 1630241db313Sdrh /* 1631241db313Sdrh ** Usage: sqlite3_bind_double STMT N VALUE 1632241db313Sdrh ** 1633241db313Sdrh ** Test the sqlite3_bind_double interface. STMT is a prepared statement. 1634241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1635241db313Sdrh ** binds a 64-bit integer VALUE to that wildcard. 1636241db313Sdrh */ 163751e3d8e2Sdanielk1977 static int test_bind_double( 163851e3d8e2Sdanielk1977 void * clientData, 163951e3d8e2Sdanielk1977 Tcl_Interp *interp, 164051e3d8e2Sdanielk1977 int objc, 164151e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 164251e3d8e2Sdanielk1977 ){ 164351e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 164451e3d8e2Sdanielk1977 int idx; 164551e3d8e2Sdanielk1977 double value; 164651e3d8e2Sdanielk1977 int rc; 164751e3d8e2Sdanielk1977 164851e3d8e2Sdanielk1977 if( objc!=4 ){ 164951e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1650241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 165151e3d8e2Sdanielk1977 return TCL_ERROR; 165251e3d8e2Sdanielk1977 } 165351e3d8e2Sdanielk1977 165451e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 165551e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 165651e3d8e2Sdanielk1977 if( Tcl_GetDoubleFromObj(interp, objv[3], &value) ) return TCL_ERROR; 165751e3d8e2Sdanielk1977 165851e3d8e2Sdanielk1977 rc = sqlite3_bind_double(pStmt, idx, value); 1659c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 166051e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 166151e3d8e2Sdanielk1977 return TCL_ERROR; 166251e3d8e2Sdanielk1977 } 166351e3d8e2Sdanielk1977 166451e3d8e2Sdanielk1977 return TCL_OK; 166551e3d8e2Sdanielk1977 } 166651e3d8e2Sdanielk1977 1667241db313Sdrh /* 1668241db313Sdrh ** Usage: sqlite3_bind_null STMT N 1669241db313Sdrh ** 1670241db313Sdrh ** Test the sqlite3_bind_null interface. STMT is a prepared statement. 1671241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1672241db313Sdrh ** binds a NULL to the wildcard. 1673241db313Sdrh */ 167451e3d8e2Sdanielk1977 static int test_bind_null( 167551e3d8e2Sdanielk1977 void * clientData, 167651e3d8e2Sdanielk1977 Tcl_Interp *interp, 167751e3d8e2Sdanielk1977 int objc, 167851e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 167951e3d8e2Sdanielk1977 ){ 168051e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 168151e3d8e2Sdanielk1977 int idx; 168251e3d8e2Sdanielk1977 int rc; 168351e3d8e2Sdanielk1977 168451e3d8e2Sdanielk1977 if( objc!=3 ){ 168551e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1686241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N", 0); 168751e3d8e2Sdanielk1977 return TCL_ERROR; 168851e3d8e2Sdanielk1977 } 168951e3d8e2Sdanielk1977 169051e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 169151e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 169251e3d8e2Sdanielk1977 169351e3d8e2Sdanielk1977 rc = sqlite3_bind_null(pStmt, idx); 1694c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 169551e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 169651e3d8e2Sdanielk1977 return TCL_ERROR; 169751e3d8e2Sdanielk1977 } 169851e3d8e2Sdanielk1977 169951e3d8e2Sdanielk1977 return TCL_OK; 170051e3d8e2Sdanielk1977 } 170151e3d8e2Sdanielk1977 1702241db313Sdrh /* 1703241db313Sdrh ** Usage: sqlite3_bind_text STMT N STRING BYTES 1704241db313Sdrh ** 1705241db313Sdrh ** Test the sqlite3_bind_text interface. STMT is a prepared statement. 1706241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1707241db313Sdrh ** binds a UTF-8 string STRING to the wildcard. The string is BYTES bytes 1708241db313Sdrh ** long. 1709241db313Sdrh */ 171051e3d8e2Sdanielk1977 static int test_bind_text( 171151e3d8e2Sdanielk1977 void * clientData, 171251e3d8e2Sdanielk1977 Tcl_Interp *interp, 171351e3d8e2Sdanielk1977 int objc, 171451e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 171551e3d8e2Sdanielk1977 ){ 171651e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 171751e3d8e2Sdanielk1977 int idx; 171851e3d8e2Sdanielk1977 int bytes; 171951e3d8e2Sdanielk1977 char *value; 172051e3d8e2Sdanielk1977 int rc; 172151e3d8e2Sdanielk1977 172251e3d8e2Sdanielk1977 if( objc!=5 ){ 172351e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1724241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0); 172551e3d8e2Sdanielk1977 return TCL_ERROR; 172651e3d8e2Sdanielk1977 } 172751e3d8e2Sdanielk1977 172851e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 172951e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 173051e3d8e2Sdanielk1977 value = Tcl_GetString(objv[3]); 173151e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 173251e3d8e2Sdanielk1977 1733d8123366Sdanielk1977 rc = sqlite3_bind_text(pStmt, idx, value, bytes, SQLITE_TRANSIENT); 1734c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 173551e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 1736473d179dSdrh Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0); 173751e3d8e2Sdanielk1977 return TCL_ERROR; 173851e3d8e2Sdanielk1977 } 173951e3d8e2Sdanielk1977 174051e3d8e2Sdanielk1977 return TCL_OK; 174151e3d8e2Sdanielk1977 } 174251e3d8e2Sdanielk1977 1743241db313Sdrh /* 1744241db313Sdrh ** Usage: sqlite3_bind_text16 STMT N STRING BYTES 1745241db313Sdrh ** 1746241db313Sdrh ** Test the sqlite3_bind_text16 interface. STMT is a prepared statement. 1747241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1748241db313Sdrh ** binds a UTF-16 string STRING to the wildcard. The string is BYTES bytes 1749241db313Sdrh ** long. 1750241db313Sdrh */ 175151e3d8e2Sdanielk1977 static int test_bind_text16( 175251e3d8e2Sdanielk1977 void * clientData, 175351e3d8e2Sdanielk1977 Tcl_Interp *interp, 175451e3d8e2Sdanielk1977 int objc, 175551e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 175651e3d8e2Sdanielk1977 ){ 17575436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 175851e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 175951e3d8e2Sdanielk1977 int idx; 176051e3d8e2Sdanielk1977 int bytes; 176151e3d8e2Sdanielk1977 char *value; 176251e3d8e2Sdanielk1977 int rc; 176351e3d8e2Sdanielk1977 176451e3d8e2Sdanielk1977 if( objc!=5 ){ 176551e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1766241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0); 176751e3d8e2Sdanielk1977 return TCL_ERROR; 176851e3d8e2Sdanielk1977 } 176951e3d8e2Sdanielk1977 177051e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 177151e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 177203d847eaSdrh value = (char*)Tcl_GetByteArrayFromObj(objv[3], 0); 177351e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 177451e3d8e2Sdanielk1977 1775d8123366Sdanielk1977 rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, SQLITE_TRANSIENT); 1776c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 177751e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 177851e3d8e2Sdanielk1977 return TCL_ERROR; 177951e3d8e2Sdanielk1977 } 178051e3d8e2Sdanielk1977 17815436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 178251e3d8e2Sdanielk1977 return TCL_OK; 178351e3d8e2Sdanielk1977 } 178451e3d8e2Sdanielk1977 1785241db313Sdrh /* 1786241db313Sdrh ** Usage: sqlite3_bind_blob STMT N DATA BYTES 1787241db313Sdrh ** 1788241db313Sdrh ** Test the sqlite3_bind_blob interface. STMT is a prepared statement. 1789241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1790241db313Sdrh ** binds a BLOB to the wildcard. The BLOB is BYTES bytes in size. 1791241db313Sdrh */ 179251e3d8e2Sdanielk1977 static int test_bind_blob( 179351e3d8e2Sdanielk1977 void * clientData, 179451e3d8e2Sdanielk1977 Tcl_Interp *interp, 179551e3d8e2Sdanielk1977 int objc, 179651e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 179751e3d8e2Sdanielk1977 ){ 179851e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 179951e3d8e2Sdanielk1977 int idx; 180051e3d8e2Sdanielk1977 int bytes; 180151e3d8e2Sdanielk1977 char *value; 180251e3d8e2Sdanielk1977 int rc; 180351e3d8e2Sdanielk1977 180451e3d8e2Sdanielk1977 if( objc!=5 ){ 180551e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1806241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N DATA BYTES", 0); 180751e3d8e2Sdanielk1977 return TCL_ERROR; 180851e3d8e2Sdanielk1977 } 180951e3d8e2Sdanielk1977 181051e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 181151e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 181251e3d8e2Sdanielk1977 value = Tcl_GetString(objv[3]); 181349e4643eSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 181451e3d8e2Sdanielk1977 1815d8123366Sdanielk1977 rc = sqlite3_bind_blob(pStmt, idx, value, bytes, SQLITE_TRANSIENT); 1816c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 181751e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 181851e3d8e2Sdanielk1977 return TCL_ERROR; 181951e3d8e2Sdanielk1977 } 182051e3d8e2Sdanielk1977 182151e3d8e2Sdanielk1977 return TCL_OK; 182251e3d8e2Sdanielk1977 } 182351e3d8e2Sdanielk1977 182499ee3600Sdrh /* 182575f6a032Sdrh ** Usage: sqlite3_bind_parameter_count STMT 182675f6a032Sdrh ** 182775f6a032Sdrh ** Return the number of wildcards in the given statement. 182875f6a032Sdrh */ 182975f6a032Sdrh static int test_bind_parameter_count( 183075f6a032Sdrh void * clientData, 183175f6a032Sdrh Tcl_Interp *interp, 183275f6a032Sdrh int objc, 183375f6a032Sdrh Tcl_Obj *CONST objv[] 183475f6a032Sdrh ){ 183575f6a032Sdrh sqlite3_stmt *pStmt; 183675f6a032Sdrh 183775f6a032Sdrh if( objc!=2 ){ 183875f6a032Sdrh Tcl_WrongNumArgs(interp, 1, objv, "STMT"); 183975f6a032Sdrh return TCL_ERROR; 184075f6a032Sdrh } 184175f6a032Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 184275f6a032Sdrh Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_bind_parameter_count(pStmt))); 184375f6a032Sdrh return TCL_OK; 184475f6a032Sdrh } 184575f6a032Sdrh 184675f6a032Sdrh /* 1847895d7472Sdrh ** Usage: sqlite3_bind_parameter_name STMT N 1848895d7472Sdrh ** 1849895d7472Sdrh ** Return the name of the Nth wildcard. The first wildcard is 1. 1850895d7472Sdrh ** An empty string is returned if N is out of range or if the wildcard 1851895d7472Sdrh ** is nameless. 1852895d7472Sdrh */ 1853895d7472Sdrh static int test_bind_parameter_name( 1854895d7472Sdrh void * clientData, 1855895d7472Sdrh Tcl_Interp *interp, 1856895d7472Sdrh int objc, 1857895d7472Sdrh Tcl_Obj *CONST objv[] 1858895d7472Sdrh ){ 1859895d7472Sdrh sqlite3_stmt *pStmt; 1860895d7472Sdrh int i; 1861895d7472Sdrh 1862895d7472Sdrh if( objc!=3 ){ 1863895d7472Sdrh Tcl_WrongNumArgs(interp, 1, objv, "STMT N"); 1864895d7472Sdrh return TCL_ERROR; 1865895d7472Sdrh } 1866895d7472Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1867895d7472Sdrh if( Tcl_GetIntFromObj(interp, objv[2], &i) ) return TCL_ERROR; 1868895d7472Sdrh Tcl_SetObjResult(interp, 1869895d7472Sdrh Tcl_NewStringObj(sqlite3_bind_parameter_name(pStmt,i),-1) 1870895d7472Sdrh ); 1871895d7472Sdrh return TCL_OK; 1872895d7472Sdrh } 1873895d7472Sdrh 1874895d7472Sdrh /* 1875fa6bc000Sdrh ** Usage: sqlite3_bind_parameter_index STMT NAME 1876fa6bc000Sdrh ** 1877fa6bc000Sdrh ** Return the index of the wildcard called NAME. Return 0 if there is 1878fa6bc000Sdrh ** no such wildcard. 1879fa6bc000Sdrh */ 1880fa6bc000Sdrh static int test_bind_parameter_index( 1881fa6bc000Sdrh void * clientData, 1882fa6bc000Sdrh Tcl_Interp *interp, 1883fa6bc000Sdrh int objc, 1884fa6bc000Sdrh Tcl_Obj *CONST objv[] 1885fa6bc000Sdrh ){ 1886fa6bc000Sdrh sqlite3_stmt *pStmt; 1887fa6bc000Sdrh 1888fa6bc000Sdrh if( objc!=3 ){ 1889fa6bc000Sdrh Tcl_WrongNumArgs(interp, 1, objv, "STMT NAME"); 1890fa6bc000Sdrh return TCL_ERROR; 1891fa6bc000Sdrh } 1892fa6bc000Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1893fa6bc000Sdrh Tcl_SetObjResult(interp, 1894fa6bc000Sdrh Tcl_NewIntObj( 1895fa6bc000Sdrh sqlite3_bind_parameter_index(pStmt,Tcl_GetString(objv[2])) 1896fa6bc000Sdrh ) 1897fa6bc000Sdrh ); 1898fa6bc000Sdrh return TCL_OK; 1899fa6bc000Sdrh } 1900fa6bc000Sdrh 1901fa6bc000Sdrh /* 1902600dd0baSdanielk1977 ** Usage: sqlite3_clear_bindings STMT 1903600dd0baSdanielk1977 ** 1904600dd0baSdanielk1977 */ 1905600dd0baSdanielk1977 #if 0 1906600dd0baSdanielk1977 static int test_clear_bindings( 1907600dd0baSdanielk1977 void * clientData, 1908600dd0baSdanielk1977 Tcl_Interp *interp, 1909600dd0baSdanielk1977 int objc, 1910600dd0baSdanielk1977 Tcl_Obj *CONST objv[] 1911600dd0baSdanielk1977 ){ 1912600dd0baSdanielk1977 sqlite3_stmt *pStmt; 1913600dd0baSdanielk1977 1914600dd0baSdanielk1977 if( objc!=2 ){ 1915600dd0baSdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "STMT"); 1916600dd0baSdanielk1977 return TCL_ERROR; 1917600dd0baSdanielk1977 } 1918600dd0baSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1919600dd0baSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(pStmt))); 1920600dd0baSdanielk1977 return TCL_OK; 1921600dd0baSdanielk1977 } 1922600dd0baSdanielk1977 #endif 1923600dd0baSdanielk1977 1924600dd0baSdanielk1977 /* 19256622cce3Sdanielk1977 ** Usage: sqlite3_errcode DB 19266622cce3Sdanielk1977 ** 19276622cce3Sdanielk1977 ** Return the string representation of the most recent sqlite3_* API 19286622cce3Sdanielk1977 ** error code. e.g. "SQLITE_ERROR". 19296622cce3Sdanielk1977 */ 19306622cce3Sdanielk1977 static int test_errcode( 19316622cce3Sdanielk1977 void * clientData, 19326622cce3Sdanielk1977 Tcl_Interp *interp, 19336622cce3Sdanielk1977 int objc, 19346622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 19356622cce3Sdanielk1977 ){ 19366622cce3Sdanielk1977 sqlite3 *db; 19376622cce3Sdanielk1977 19386622cce3Sdanielk1977 if( objc!=2 ){ 19396622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 19406622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 19416622cce3Sdanielk1977 return TCL_ERROR; 19426622cce3Sdanielk1977 } 19436622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 19446622cce3Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(sqlite3_errcode(db)), 0); 19456622cce3Sdanielk1977 return TCL_OK; 19466622cce3Sdanielk1977 } 19476622cce3Sdanielk1977 19486622cce3Sdanielk1977 /* 19496622cce3Sdanielk1977 ** Usage: test_errmsg DB 19506622cce3Sdanielk1977 ** 19516622cce3Sdanielk1977 ** Returns the UTF-8 representation of the error message string for the 19526622cce3Sdanielk1977 ** most recent sqlite3_* API call. 19536622cce3Sdanielk1977 */ 19546622cce3Sdanielk1977 static int test_errmsg( 19556622cce3Sdanielk1977 void * clientData, 19566622cce3Sdanielk1977 Tcl_Interp *interp, 19576622cce3Sdanielk1977 int objc, 19586622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 19596622cce3Sdanielk1977 ){ 19609bb575fdSdrh sqlite3 *db; 19616622cce3Sdanielk1977 const char *zErr; 19626622cce3Sdanielk1977 19636622cce3Sdanielk1977 if( objc!=2 ){ 19646622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 19656622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 19666622cce3Sdanielk1977 return TCL_ERROR; 19676622cce3Sdanielk1977 } 19686622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 19696622cce3Sdanielk1977 19706622cce3Sdanielk1977 zErr = sqlite3_errmsg(db); 19716622cce3Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1)); 19726622cce3Sdanielk1977 return TCL_OK; 19736622cce3Sdanielk1977 } 19746622cce3Sdanielk1977 19756622cce3Sdanielk1977 /* 19766622cce3Sdanielk1977 ** Usage: test_errmsg16 DB 19776622cce3Sdanielk1977 ** 19786622cce3Sdanielk1977 ** Returns the UTF-16 representation of the error message string for the 19796622cce3Sdanielk1977 ** most recent sqlite3_* API call. This is a byte array object at the TCL 19806622cce3Sdanielk1977 ** level, and it includes the 0x00 0x00 terminator bytes at the end of the 19816622cce3Sdanielk1977 ** UTF-16 string. 19826622cce3Sdanielk1977 */ 19836622cce3Sdanielk1977 static int test_errmsg16( 19846622cce3Sdanielk1977 void * clientData, 19856622cce3Sdanielk1977 Tcl_Interp *interp, 19866622cce3Sdanielk1977 int objc, 19876622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 19886622cce3Sdanielk1977 ){ 19895436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 19909bb575fdSdrh sqlite3 *db; 19916622cce3Sdanielk1977 const void *zErr; 19926622cce3Sdanielk1977 int bytes; 19936622cce3Sdanielk1977 19946622cce3Sdanielk1977 if( objc!=2 ){ 19956622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 19966622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 19976622cce3Sdanielk1977 return TCL_ERROR; 19986622cce3Sdanielk1977 } 19996622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 20006622cce3Sdanielk1977 20016622cce3Sdanielk1977 zErr = sqlite3_errmsg16(db); 20026622cce3Sdanielk1977 bytes = sqlite3utf16ByteLen(zErr, -1); 20036622cce3Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes)); 20045436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 20056622cce3Sdanielk1977 return TCL_OK; 20066622cce3Sdanielk1977 } 20076622cce3Sdanielk1977 20086622cce3Sdanielk1977 /* 20096622cce3Sdanielk1977 ** Usage: sqlite3_prepare DB sql bytes tailvar 20106622cce3Sdanielk1977 ** 20116622cce3Sdanielk1977 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using 20126622cce3Sdanielk1977 ** database handle <DB>. The parameter <tailval> is the name of a global 20136622cce3Sdanielk1977 ** variable that is set to the unused portion of <sql> (if any). A 20146622cce3Sdanielk1977 ** STMT handle is returned. 20156622cce3Sdanielk1977 */ 20166622cce3Sdanielk1977 static int test_prepare( 20176622cce3Sdanielk1977 void * clientData, 20186622cce3Sdanielk1977 Tcl_Interp *interp, 20196622cce3Sdanielk1977 int objc, 20206622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 20216622cce3Sdanielk1977 ){ 20226622cce3Sdanielk1977 sqlite3 *db; 20236622cce3Sdanielk1977 const char *zSql; 20246622cce3Sdanielk1977 int bytes; 20256622cce3Sdanielk1977 const char *zTail = 0; 20266622cce3Sdanielk1977 sqlite3_stmt *pStmt = 0; 20276622cce3Sdanielk1977 char zBuf[50]; 20284ad1713cSdanielk1977 int rc; 20296622cce3Sdanielk1977 20306622cce3Sdanielk1977 if( objc!=5 ){ 20316622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 20326622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); 20336622cce3Sdanielk1977 return TCL_ERROR; 20346622cce3Sdanielk1977 } 20356622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 20366622cce3Sdanielk1977 zSql = Tcl_GetString(objv[2]); 20376622cce3Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; 20386622cce3Sdanielk1977 20394ad1713cSdanielk1977 rc = sqlite3_prepare(db, zSql, bytes, &pStmt, &zTail); 2040c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 20416622cce3Sdanielk1977 if( zTail ){ 20426622cce3Sdanielk1977 if( bytes>=0 ){ 20436622cce3Sdanielk1977 bytes = bytes - (zTail-zSql); 20446622cce3Sdanielk1977 } 20456622cce3Sdanielk1977 Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0); 20466622cce3Sdanielk1977 } 20474ad1713cSdanielk1977 if( rc!=SQLITE_OK ){ 20484ad1713cSdanielk1977 assert( pStmt==0 ); 20494ad1713cSdanielk1977 sprintf(zBuf, "(%d) ", rc); 20504ad1713cSdanielk1977 Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0); 20514ad1713cSdanielk1977 return TCL_ERROR; 20524ad1713cSdanielk1977 } 20536622cce3Sdanielk1977 20544ad1713cSdanielk1977 if( pStmt ){ 20556622cce3Sdanielk1977 if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; 20566622cce3Sdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 20574ad1713cSdanielk1977 } 20586622cce3Sdanielk1977 return TCL_OK; 20596622cce3Sdanielk1977 } 20606622cce3Sdanielk1977 20616622cce3Sdanielk1977 /* 20626622cce3Sdanielk1977 ** Usage: sqlite3_prepare DB sql bytes tailvar 20636622cce3Sdanielk1977 ** 20646622cce3Sdanielk1977 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using 20656622cce3Sdanielk1977 ** database handle <DB>. The parameter <tailval> is the name of a global 20666622cce3Sdanielk1977 ** variable that is set to the unused portion of <sql> (if any). A 20676622cce3Sdanielk1977 ** STMT handle is returned. 20686622cce3Sdanielk1977 */ 20696622cce3Sdanielk1977 static int test_prepare16( 20706622cce3Sdanielk1977 void * clientData, 20716622cce3Sdanielk1977 Tcl_Interp *interp, 20726622cce3Sdanielk1977 int objc, 20736622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 20746622cce3Sdanielk1977 ){ 20755436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 20766622cce3Sdanielk1977 sqlite3 *db; 20776622cce3Sdanielk1977 const void *zSql; 20786622cce3Sdanielk1977 const void *zTail = 0; 20796622cce3Sdanielk1977 Tcl_Obj *pTail = 0; 20806622cce3Sdanielk1977 sqlite3_stmt *pStmt = 0; 20816622cce3Sdanielk1977 char zBuf[50]; 2082c60d0446Sdrh int rc; 20836622cce3Sdanielk1977 int bytes; /* The integer specified as arg 3 */ 20846622cce3Sdanielk1977 int objlen; /* The byte-array length of arg 2 */ 20856622cce3Sdanielk1977 20866622cce3Sdanielk1977 if( objc!=5 ){ 20876622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 20886622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); 20896622cce3Sdanielk1977 return TCL_ERROR; 20906622cce3Sdanielk1977 } 20916622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 20926622cce3Sdanielk1977 zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen); 20936622cce3Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; 20946622cce3Sdanielk1977 2095c60d0446Sdrh rc = sqlite3_prepare16(db, zSql, bytes, &pStmt, &zTail); 2096c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 2097c60d0446Sdrh if( rc ){ 20986622cce3Sdanielk1977 return TCL_ERROR; 20996622cce3Sdanielk1977 } 21006622cce3Sdanielk1977 21016622cce3Sdanielk1977 if( zTail ){ 21026622cce3Sdanielk1977 objlen = objlen - ((u8 *)zTail-(u8 *)zSql); 21036622cce3Sdanielk1977 }else{ 21046622cce3Sdanielk1977 objlen = 0; 21056622cce3Sdanielk1977 } 21066622cce3Sdanielk1977 pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen); 21076622cce3Sdanielk1977 Tcl_IncrRefCount(pTail); 21086622cce3Sdanielk1977 Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0); 21094ad1713cSdanielk1977 Tcl_DecrRefCount(pTail); 21106622cce3Sdanielk1977 21114ad1713cSdanielk1977 if( pStmt ){ 21126622cce3Sdanielk1977 if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; 21134ad1713cSdanielk1977 } 21146622cce3Sdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 21155436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 21166622cce3Sdanielk1977 return TCL_OK; 21176622cce3Sdanielk1977 } 21186622cce3Sdanielk1977 21194ad1713cSdanielk1977 /* 21204ad1713cSdanielk1977 ** Usage: sqlite3_open filename ?options-list? 21214ad1713cSdanielk1977 */ 21224ad1713cSdanielk1977 static int test_open( 21234ad1713cSdanielk1977 void * clientData, 21244ad1713cSdanielk1977 Tcl_Interp *interp, 21254ad1713cSdanielk1977 int objc, 21264ad1713cSdanielk1977 Tcl_Obj *CONST objv[] 21274ad1713cSdanielk1977 ){ 21284ad1713cSdanielk1977 const char *zFilename; 21294ad1713cSdanielk1977 sqlite3 *db; 21304ad1713cSdanielk1977 int rc; 21314ad1713cSdanielk1977 char zBuf[100]; 21324ad1713cSdanielk1977 21334ad1713cSdanielk1977 if( objc!=3 && objc!=2 ){ 21344ad1713cSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 21354ad1713cSdanielk1977 Tcl_GetString(objv[0]), " filename options-list", 0); 21364ad1713cSdanielk1977 return TCL_ERROR; 21374ad1713cSdanielk1977 } 21384ad1713cSdanielk1977 21394ad1713cSdanielk1977 zFilename = Tcl_GetString(objv[1]); 21404f057f90Sdanielk1977 rc = sqlite3_open(zFilename, &db); 21414ad1713cSdanielk1977 21424ad1713cSdanielk1977 if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR; 21434ad1713cSdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 21444ad1713cSdanielk1977 return TCL_OK; 21454ad1713cSdanielk1977 } 21464ad1713cSdanielk1977 21474ad1713cSdanielk1977 /* 21484ad1713cSdanielk1977 ** Usage: sqlite3_open16 filename options 21494ad1713cSdanielk1977 */ 21504ad1713cSdanielk1977 static int test_open16( 21514ad1713cSdanielk1977 void * clientData, 21524ad1713cSdanielk1977 Tcl_Interp *interp, 21534ad1713cSdanielk1977 int objc, 21544ad1713cSdanielk1977 Tcl_Obj *CONST objv[] 21554ad1713cSdanielk1977 ){ 21565436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 21574ad1713cSdanielk1977 const void *zFilename; 21584ad1713cSdanielk1977 sqlite3 *db; 21594ad1713cSdanielk1977 int rc; 21604ad1713cSdanielk1977 char zBuf[100]; 21614ad1713cSdanielk1977 21624ad1713cSdanielk1977 if( objc!=3 ){ 21634ad1713cSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 21644ad1713cSdanielk1977 Tcl_GetString(objv[0]), " filename options-list", 0); 21654ad1713cSdanielk1977 return TCL_ERROR; 21664ad1713cSdanielk1977 } 21674ad1713cSdanielk1977 21684ad1713cSdanielk1977 zFilename = Tcl_GetByteArrayFromObj(objv[1], 0); 21694f057f90Sdanielk1977 rc = sqlite3_open16(zFilename, &db); 21704ad1713cSdanielk1977 21714ad1713cSdanielk1977 if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR; 21724ad1713cSdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 21735436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 21744ad1713cSdanielk1977 return TCL_OK; 21754ad1713cSdanielk1977 } 2176d3d39e93Sdrh 2177d3d39e93Sdrh /* 2178bc6ada41Sdanielk1977 ** Usage: sqlite3_complete16 <UTF-16 string> 2179bc6ada41Sdanielk1977 ** 2180bc6ada41Sdanielk1977 ** Return 1 if the supplied argument is a complete SQL statement, or zero 2181bc6ada41Sdanielk1977 ** otherwise. 2182bc6ada41Sdanielk1977 */ 2183bc6ada41Sdanielk1977 static int test_complete16( 2184bc6ada41Sdanielk1977 void * clientData, 2185bc6ada41Sdanielk1977 Tcl_Interp *interp, 2186bc6ada41Sdanielk1977 int objc, 2187bc6ada41Sdanielk1977 Tcl_Obj *CONST objv[] 2188bc6ada41Sdanielk1977 ){ 2189ccae6026Sdrh #if !defined(SQLITE_OMIT_COMPLETE) && !defined(SQLITE_OMIT_UTF16) 2190bc6ada41Sdanielk1977 char *zBuf; 2191bc6ada41Sdanielk1977 2192bc6ada41Sdanielk1977 if( objc!=2 ){ 2193bc6ada41Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>"); 2194bc6ada41Sdanielk1977 return TCL_ERROR; 2195bc6ada41Sdanielk1977 } 2196bc6ada41Sdanielk1977 219703d847eaSdrh zBuf = (char*)Tcl_GetByteArrayFromObj(objv[1], 0); 2198bc6ada41Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_complete16(zBuf))); 2199ccae6026Sdrh #endif /* SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */ 2200bc6ada41Sdanielk1977 return TCL_OK; 2201bc6ada41Sdanielk1977 } 2202bc6ada41Sdanielk1977 2203bc6ada41Sdanielk1977 /* 2204106bb236Sdanielk1977 ** Usage: sqlite3_step STMT 2205106bb236Sdanielk1977 ** 2206106bb236Sdanielk1977 ** Advance the statement to the next row. 2207106bb236Sdanielk1977 */ 220817240fd9Sdanielk1977 static int test_step( 2209106bb236Sdanielk1977 void * clientData, 2210106bb236Sdanielk1977 Tcl_Interp *interp, 2211106bb236Sdanielk1977 int objc, 2212106bb236Sdanielk1977 Tcl_Obj *CONST objv[] 2213106bb236Sdanielk1977 ){ 2214106bb236Sdanielk1977 sqlite3_stmt *pStmt; 2215106bb236Sdanielk1977 int rc; 2216106bb236Sdanielk1977 2217e1cd9874Sdanielk1977 if( objc!=2 ){ 2218106bb236Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 2219106bb236Sdanielk1977 Tcl_GetString(objv[0]), " STMT", 0); 2220106bb236Sdanielk1977 return TCL_ERROR; 2221106bb236Sdanielk1977 } 2222106bb236Sdanielk1977 2223106bb236Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 222417240fd9Sdanielk1977 rc = sqlite3_step(pStmt); 2225106bb236Sdanielk1977 2226fbcd585fSdanielk1977 /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; */ 22276590493dSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), 0); 2228e1cd9874Sdanielk1977 return TCL_OK; 2229e1cd9874Sdanielk1977 } 2230e1cd9874Sdanielk1977 2231e1cd9874Sdanielk1977 /* 223217240fd9Sdanielk1977 ** Usage: sqlite3_column_count STMT 223317240fd9Sdanielk1977 ** 223417240fd9Sdanielk1977 ** Return the number of columns returned by the sql statement STMT. 223517240fd9Sdanielk1977 */ 223617240fd9Sdanielk1977 static int test_column_count( 223717240fd9Sdanielk1977 void * clientData, 223817240fd9Sdanielk1977 Tcl_Interp *interp, 223917240fd9Sdanielk1977 int objc, 224017240fd9Sdanielk1977 Tcl_Obj *CONST objv[] 224117240fd9Sdanielk1977 ){ 224217240fd9Sdanielk1977 sqlite3_stmt *pStmt; 224317240fd9Sdanielk1977 224417240fd9Sdanielk1977 if( objc!=2 ){ 224517240fd9Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 224617240fd9Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 224717240fd9Sdanielk1977 return TCL_ERROR; 224817240fd9Sdanielk1977 } 224917240fd9Sdanielk1977 225017240fd9Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 225117240fd9Sdanielk1977 225217240fd9Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_column_count(pStmt))); 225317240fd9Sdanielk1977 return TCL_OK; 225417240fd9Sdanielk1977 } 225517240fd9Sdanielk1977 225617240fd9Sdanielk1977 /* 22573cf86063Sdanielk1977 ** Usage: sqlite3_column_type STMT column 22583cf86063Sdanielk1977 ** 22593cf86063Sdanielk1977 ** Return the type of the data in column 'column' of the current row. 22603cf86063Sdanielk1977 */ 22613cf86063Sdanielk1977 static int test_column_type( 22623cf86063Sdanielk1977 void * clientData, 22633cf86063Sdanielk1977 Tcl_Interp *interp, 22643cf86063Sdanielk1977 int objc, 22653cf86063Sdanielk1977 Tcl_Obj *CONST objv[] 22663cf86063Sdanielk1977 ){ 22673cf86063Sdanielk1977 sqlite3_stmt *pStmt; 22683cf86063Sdanielk1977 int col; 22693cf86063Sdanielk1977 int tp; 22703cf86063Sdanielk1977 22713cf86063Sdanielk1977 if( objc!=3 ){ 22723cf86063Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 22733cf86063Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 22743cf86063Sdanielk1977 return TCL_ERROR; 22753cf86063Sdanielk1977 } 22763cf86063Sdanielk1977 22773cf86063Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 22783cf86063Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 22793cf86063Sdanielk1977 22803cf86063Sdanielk1977 tp = sqlite3_column_type(pStmt, col); 22813cf86063Sdanielk1977 switch( tp ){ 22829c054830Sdrh case SQLITE_INTEGER: 22833cf86063Sdanielk1977 Tcl_SetResult(interp, "INTEGER", TCL_STATIC); 22843cf86063Sdanielk1977 break; 22859c054830Sdrh case SQLITE_NULL: 22863cf86063Sdanielk1977 Tcl_SetResult(interp, "NULL", TCL_STATIC); 22873cf86063Sdanielk1977 break; 22889c054830Sdrh case SQLITE_FLOAT: 22893cf86063Sdanielk1977 Tcl_SetResult(interp, "FLOAT", TCL_STATIC); 22903cf86063Sdanielk1977 break; 22919c054830Sdrh case SQLITE_TEXT: 22923cf86063Sdanielk1977 Tcl_SetResult(interp, "TEXT", TCL_STATIC); 22933cf86063Sdanielk1977 break; 22949c054830Sdrh case SQLITE_BLOB: 22953cf86063Sdanielk1977 Tcl_SetResult(interp, "BLOB", TCL_STATIC); 22963cf86063Sdanielk1977 break; 22973cf86063Sdanielk1977 default: 22983cf86063Sdanielk1977 assert(0); 22993cf86063Sdanielk1977 } 23003cf86063Sdanielk1977 23013cf86063Sdanielk1977 return TCL_OK; 23023cf86063Sdanielk1977 } 23033cf86063Sdanielk1977 23043cf86063Sdanielk1977 /* 230504f2e68dSdanielk1977 ** Usage: sqlite3_column_int64 STMT column 23063cf86063Sdanielk1977 ** 23073cf86063Sdanielk1977 ** Return the data in column 'column' of the current row cast as an 230804f2e68dSdanielk1977 ** wide (64-bit) integer. 23093cf86063Sdanielk1977 */ 231004f2e68dSdanielk1977 static int test_column_int64( 23113cf86063Sdanielk1977 void * clientData, 23123cf86063Sdanielk1977 Tcl_Interp *interp, 23133cf86063Sdanielk1977 int objc, 23143cf86063Sdanielk1977 Tcl_Obj *CONST objv[] 23153cf86063Sdanielk1977 ){ 23163cf86063Sdanielk1977 sqlite3_stmt *pStmt; 23173cf86063Sdanielk1977 int col; 231804f2e68dSdanielk1977 i64 iVal; 23193cf86063Sdanielk1977 23203cf86063Sdanielk1977 if( objc!=3 ){ 23213cf86063Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 23223cf86063Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 23233cf86063Sdanielk1977 return TCL_ERROR; 23243cf86063Sdanielk1977 } 23253cf86063Sdanielk1977 23263cf86063Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 23273cf86063Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 23283cf86063Sdanielk1977 232904f2e68dSdanielk1977 iVal = sqlite3_column_int64(pStmt, col); 233004f2e68dSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iVal)); 233104f2e68dSdanielk1977 return TCL_OK; 233204f2e68dSdanielk1977 } 233304f2e68dSdanielk1977 233404f2e68dSdanielk1977 /* 2335ea61b2c4Sdanielk1977 ** Usage: sqlite3_column_blob STMT column 2336ea61b2c4Sdanielk1977 */ 2337ea61b2c4Sdanielk1977 static int test_column_blob( 2338ea61b2c4Sdanielk1977 void * clientData, 2339ea61b2c4Sdanielk1977 Tcl_Interp *interp, 2340ea61b2c4Sdanielk1977 int objc, 2341ea61b2c4Sdanielk1977 Tcl_Obj *CONST objv[] 2342ea61b2c4Sdanielk1977 ){ 2343ea61b2c4Sdanielk1977 sqlite3_stmt *pStmt; 2344ea61b2c4Sdanielk1977 int col; 2345ea61b2c4Sdanielk1977 2346ea61b2c4Sdanielk1977 int len; 2347c572ef7fSdanielk1977 const void *pBlob; 2348ea61b2c4Sdanielk1977 2349ea61b2c4Sdanielk1977 if( objc!=3 ){ 2350ea61b2c4Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 2351ea61b2c4Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 2352ea61b2c4Sdanielk1977 return TCL_ERROR; 2353ea61b2c4Sdanielk1977 } 2354ea61b2c4Sdanielk1977 2355ea61b2c4Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2356ea61b2c4Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2357ea61b2c4Sdanielk1977 2358ea61b2c4Sdanielk1977 pBlob = sqlite3_column_blob(pStmt, col); 2359ea61b2c4Sdanielk1977 len = sqlite3_column_bytes(pStmt, col); 2360ea61b2c4Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len)); 2361ea61b2c4Sdanielk1977 return TCL_OK; 2362ea61b2c4Sdanielk1977 } 2363ea61b2c4Sdanielk1977 2364ea61b2c4Sdanielk1977 /* 236504f2e68dSdanielk1977 ** Usage: sqlite3_column_double STMT column 236604f2e68dSdanielk1977 ** 236704f2e68dSdanielk1977 ** Return the data in column 'column' of the current row cast as a double. 236804f2e68dSdanielk1977 */ 236904f2e68dSdanielk1977 static int test_column_double( 237004f2e68dSdanielk1977 void * clientData, 237104f2e68dSdanielk1977 Tcl_Interp *interp, 237204f2e68dSdanielk1977 int objc, 237304f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 237404f2e68dSdanielk1977 ){ 237504f2e68dSdanielk1977 sqlite3_stmt *pStmt; 237604f2e68dSdanielk1977 int col; 237704f2e68dSdanielk1977 double rVal; 237804f2e68dSdanielk1977 237904f2e68dSdanielk1977 if( objc!=3 ){ 238004f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 238104f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 238204f2e68dSdanielk1977 return TCL_ERROR; 238304f2e68dSdanielk1977 } 238404f2e68dSdanielk1977 238504f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 238604f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 238704f2e68dSdanielk1977 238804f2e68dSdanielk1977 rVal = sqlite3_column_double(pStmt, col); 2389c572ef7fSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rVal)); 23903cf86063Sdanielk1977 return TCL_OK; 23913cf86063Sdanielk1977 } 23923cf86063Sdanielk1977 23933cf86063Sdanielk1977 /* 239417240fd9Sdanielk1977 ** Usage: sqlite3_data_count STMT 239517240fd9Sdanielk1977 ** 239617240fd9Sdanielk1977 ** Return the number of columns returned by the sql statement STMT. 239717240fd9Sdanielk1977 */ 239817240fd9Sdanielk1977 static int test_data_count( 239917240fd9Sdanielk1977 void * clientData, 240017240fd9Sdanielk1977 Tcl_Interp *interp, 240117240fd9Sdanielk1977 int objc, 240217240fd9Sdanielk1977 Tcl_Obj *CONST objv[] 240317240fd9Sdanielk1977 ){ 240417240fd9Sdanielk1977 sqlite3_stmt *pStmt; 240517240fd9Sdanielk1977 240617240fd9Sdanielk1977 if( objc!=2 ){ 240717240fd9Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 240817240fd9Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 240917240fd9Sdanielk1977 return TCL_ERROR; 241017240fd9Sdanielk1977 } 241117240fd9Sdanielk1977 241217240fd9Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 241317240fd9Sdanielk1977 241417240fd9Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_data_count(pStmt))); 241517240fd9Sdanielk1977 return TCL_OK; 241617240fd9Sdanielk1977 } 241717240fd9Sdanielk1977 241817240fd9Sdanielk1977 /* 241904f2e68dSdanielk1977 ** Usage: sqlite3_column_text STMT column 242004f2e68dSdanielk1977 ** 242104f2e68dSdanielk1977 ** Usage: sqlite3_column_decltype STMT column 242204f2e68dSdanielk1977 ** 242304f2e68dSdanielk1977 ** Usage: sqlite3_column_name STMT column 242404f2e68dSdanielk1977 */ 242504f2e68dSdanielk1977 static int test_stmt_utf8( 2426241db313Sdrh void * clientData, /* Pointer to SQLite API function to be invoke */ 242704f2e68dSdanielk1977 Tcl_Interp *interp, 242804f2e68dSdanielk1977 int objc, 242904f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 243004f2e68dSdanielk1977 ){ 243104f2e68dSdanielk1977 sqlite3_stmt *pStmt; 243204f2e68dSdanielk1977 int col; 2433c572ef7fSdanielk1977 const char *(*xFunc)(sqlite3_stmt*, int) = clientData; 2434f93bbbeaSdanielk1977 const char *zRet; 243504f2e68dSdanielk1977 243604f2e68dSdanielk1977 if( objc!=3 ){ 243704f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 243804f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 243904f2e68dSdanielk1977 return TCL_ERROR; 244004f2e68dSdanielk1977 } 244104f2e68dSdanielk1977 244204f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 244304f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2444f93bbbeaSdanielk1977 zRet = xFunc(pStmt, col); 2445f93bbbeaSdanielk1977 if( zRet ){ 2446f93bbbeaSdanielk1977 Tcl_SetResult(interp, (char *)zRet, 0); 2447f93bbbeaSdanielk1977 } 244804f2e68dSdanielk1977 return TCL_OK; 244904f2e68dSdanielk1977 } 245004f2e68dSdanielk1977 24516b456a2bSdanielk1977 static int test_global_recover( 24526b456a2bSdanielk1977 void * clientData, 24536b456a2bSdanielk1977 Tcl_Interp *interp, 24546b456a2bSdanielk1977 int objc, 24556b456a2bSdanielk1977 Tcl_Obj *CONST objv[] 24566b456a2bSdanielk1977 ){ 24576b456a2bSdanielk1977 #ifndef SQLITE_OMIT_GLOBALRECOVER 24586b456a2bSdanielk1977 int rc; 24596b456a2bSdanielk1977 if( objc!=1 ){ 24606b456a2bSdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, ""); 24616b456a2bSdanielk1977 return TCL_ERROR; 24626b456a2bSdanielk1977 } 24636b456a2bSdanielk1977 rc = sqlite3_global_recover(); 24646b456a2bSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 24656b456a2bSdanielk1977 #endif 24666b456a2bSdanielk1977 return TCL_OK; 24676b456a2bSdanielk1977 } 24686b456a2bSdanielk1977 246904f2e68dSdanielk1977 /* 247004f2e68dSdanielk1977 ** Usage: sqlite3_column_text STMT column 247104f2e68dSdanielk1977 ** 247204f2e68dSdanielk1977 ** Usage: sqlite3_column_decltype STMT column 247304f2e68dSdanielk1977 ** 247404f2e68dSdanielk1977 ** Usage: sqlite3_column_name STMT column 247504f2e68dSdanielk1977 */ 247604f2e68dSdanielk1977 static int test_stmt_utf16( 2477241db313Sdrh void * clientData, /* Pointer to SQLite API function to be invoked */ 247804f2e68dSdanielk1977 Tcl_Interp *interp, 247904f2e68dSdanielk1977 int objc, 248004f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 248104f2e68dSdanielk1977 ){ 24825436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 248304f2e68dSdanielk1977 sqlite3_stmt *pStmt; 248404f2e68dSdanielk1977 int col; 248504f2e68dSdanielk1977 Tcl_Obj *pRet; 248604f2e68dSdanielk1977 const void *zName16; 2487c572ef7fSdanielk1977 const void *(*xFunc)(sqlite3_stmt*, int) = clientData; 248804f2e68dSdanielk1977 248904f2e68dSdanielk1977 if( objc!=3 ){ 249004f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 249104f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 249204f2e68dSdanielk1977 return TCL_ERROR; 249304f2e68dSdanielk1977 } 249404f2e68dSdanielk1977 249504f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 249604f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 249704f2e68dSdanielk1977 249804f2e68dSdanielk1977 zName16 = xFunc(pStmt, col); 2499f93bbbeaSdanielk1977 if( zName16 ){ 250004f2e68dSdanielk1977 pRet = Tcl_NewByteArrayObj(zName16, sqlite3utf16ByteLen(zName16, -1)+2); 250104f2e68dSdanielk1977 Tcl_SetObjResult(interp, pRet); 2502f93bbbeaSdanielk1977 } 25035436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 250404f2e68dSdanielk1977 250504f2e68dSdanielk1977 return TCL_OK; 250604f2e68dSdanielk1977 } 250704f2e68dSdanielk1977 250804f2e68dSdanielk1977 /* 250904f2e68dSdanielk1977 ** Usage: sqlite3_column_int STMT column 251004f2e68dSdanielk1977 ** 251104f2e68dSdanielk1977 ** Usage: sqlite3_column_bytes STMT column 251204f2e68dSdanielk1977 ** 251304f2e68dSdanielk1977 ** Usage: sqlite3_column_bytes16 STMT column 251404f2e68dSdanielk1977 ** 251504f2e68dSdanielk1977 */ 251604f2e68dSdanielk1977 static int test_stmt_int( 2517241db313Sdrh void * clientData, /* Pointer to SQLite API function to be invoked */ 251804f2e68dSdanielk1977 Tcl_Interp *interp, 251904f2e68dSdanielk1977 int objc, 252004f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 252104f2e68dSdanielk1977 ){ 252204f2e68dSdanielk1977 sqlite3_stmt *pStmt; 252304f2e68dSdanielk1977 int col; 2524c572ef7fSdanielk1977 int (*xFunc)(sqlite3_stmt*, int) = clientData; 252504f2e68dSdanielk1977 252604f2e68dSdanielk1977 if( objc!=3 ){ 252704f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 252804f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 252904f2e68dSdanielk1977 return TCL_ERROR; 253004f2e68dSdanielk1977 } 253104f2e68dSdanielk1977 253204f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 253304f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 253404f2e68dSdanielk1977 253504f2e68dSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(xFunc(pStmt, col))); 253604f2e68dSdanielk1977 return TCL_OK; 253704f2e68dSdanielk1977 } 253804f2e68dSdanielk1977 253944ee5bf7Sdanielk1977 #ifndef SQLITE_OMIT_DISKIO 25409a1d0abeSdanielk1977 /* 25419a1d0abeSdanielk1977 ** Usage: sqlite3OsOpenReadWrite <filename> 25429a1d0abeSdanielk1977 */ 25439a1d0abeSdanielk1977 static int test_sqlite3OsOpenReadWrite( 25449a1d0abeSdanielk1977 void * clientData, 25459a1d0abeSdanielk1977 Tcl_Interp *interp, 25469a1d0abeSdanielk1977 int objc, 25479a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 25489a1d0abeSdanielk1977 ){ 25499a1d0abeSdanielk1977 OsFile *pFile; 25509a1d0abeSdanielk1977 int rc; 25519a1d0abeSdanielk1977 int dummy; 25529a1d0abeSdanielk1977 char zBuf[100]; 255304f2e68dSdanielk1977 25549a1d0abeSdanielk1977 if( objc!=2 ){ 25559a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 25569a1d0abeSdanielk1977 Tcl_GetString(objv[0]), " filename", 0); 25579a1d0abeSdanielk1977 return TCL_ERROR; 25589a1d0abeSdanielk1977 } 25599a1d0abeSdanielk1977 2560054889ecSdrh rc = sqlite3Os.xOpenReadWrite(Tcl_GetString(objv[1]), &pFile, &dummy); 25619a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 25629a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 25639a1d0abeSdanielk1977 return TCL_ERROR; 25649a1d0abeSdanielk1977 } 25659a1d0abeSdanielk1977 makePointerStr(interp, zBuf, pFile); 25669a1d0abeSdanielk1977 Tcl_SetResult(interp, zBuf, 0); 25679a1d0abeSdanielk1977 return TCL_ERROR; 25689a1d0abeSdanielk1977 } 25699a1d0abeSdanielk1977 25709a1d0abeSdanielk1977 /* 25719a1d0abeSdanielk1977 ** Usage: sqlite3OsClose <file handle> 25729a1d0abeSdanielk1977 */ 25739a1d0abeSdanielk1977 static int test_sqlite3OsClose( 25749a1d0abeSdanielk1977 void * clientData, 25759a1d0abeSdanielk1977 Tcl_Interp *interp, 25769a1d0abeSdanielk1977 int objc, 25779a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 25789a1d0abeSdanielk1977 ){ 25799a1d0abeSdanielk1977 OsFile *pFile; 25809a1d0abeSdanielk1977 int rc; 25819a1d0abeSdanielk1977 25829a1d0abeSdanielk1977 if( objc!=2 ){ 25839a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 25849a1d0abeSdanielk1977 Tcl_GetString(objv[0]), " filehandle", 0); 25859a1d0abeSdanielk1977 return TCL_ERROR; 25869a1d0abeSdanielk1977 } 25879a1d0abeSdanielk1977 25889a1d0abeSdanielk1977 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 25899a1d0abeSdanielk1977 return TCL_ERROR; 25909a1d0abeSdanielk1977 } 2591054889ecSdrh rc = sqlite3OsClose(&pFile); 25929a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 25939a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 25949a1d0abeSdanielk1977 return TCL_ERROR; 25959a1d0abeSdanielk1977 } 25969a1d0abeSdanielk1977 return TCL_OK; 25979a1d0abeSdanielk1977 } 25989a1d0abeSdanielk1977 25999a1d0abeSdanielk1977 /* 26009a1d0abeSdanielk1977 ** Usage: sqlite3OsLock <file handle> <locktype> 26019a1d0abeSdanielk1977 */ 26029a1d0abeSdanielk1977 static int test_sqlite3OsLock( 26039a1d0abeSdanielk1977 void * clientData, 26049a1d0abeSdanielk1977 Tcl_Interp *interp, 26059a1d0abeSdanielk1977 int objc, 26069a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 26079a1d0abeSdanielk1977 ){ 26089a1d0abeSdanielk1977 OsFile * pFile; 26099a1d0abeSdanielk1977 int rc; 26109a1d0abeSdanielk1977 26119a1d0abeSdanielk1977 if( objc!=3 ){ 26129a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 26139a1d0abeSdanielk1977 Tcl_GetString(objv[0]), 26149a1d0abeSdanielk1977 " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0); 26159a1d0abeSdanielk1977 return TCL_ERROR; 26169a1d0abeSdanielk1977 } 26179a1d0abeSdanielk1977 26189a1d0abeSdanielk1977 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 26199a1d0abeSdanielk1977 return TCL_ERROR; 26209a1d0abeSdanielk1977 } 26219a1d0abeSdanielk1977 26229a1d0abeSdanielk1977 if( 0==strcmp("SHARED", Tcl_GetString(objv[2])) ){ 2623054889ecSdrh rc = sqlite3OsLock(pFile, SHARED_LOCK); 26249a1d0abeSdanielk1977 } 26259a1d0abeSdanielk1977 else if( 0==strcmp("RESERVED", Tcl_GetString(objv[2])) ){ 2626054889ecSdrh rc = sqlite3OsLock(pFile, RESERVED_LOCK); 26279a1d0abeSdanielk1977 } 26289a1d0abeSdanielk1977 else if( 0==strcmp("PENDING", Tcl_GetString(objv[2])) ){ 2629054889ecSdrh rc = sqlite3OsLock(pFile, PENDING_LOCK); 26309a1d0abeSdanielk1977 } 26319a1d0abeSdanielk1977 else if( 0==strcmp("EXCLUSIVE", Tcl_GetString(objv[2])) ){ 2632054889ecSdrh rc = sqlite3OsLock(pFile, EXCLUSIVE_LOCK); 26339a1d0abeSdanielk1977 }else{ 26349a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 26359a1d0abeSdanielk1977 Tcl_GetString(objv[0]), 26369a1d0abeSdanielk1977 " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0); 26379a1d0abeSdanielk1977 return TCL_ERROR; 26389a1d0abeSdanielk1977 } 26399a1d0abeSdanielk1977 26409a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 26419a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 26429a1d0abeSdanielk1977 return TCL_ERROR; 26439a1d0abeSdanielk1977 } 26449a1d0abeSdanielk1977 return TCL_OK; 26459a1d0abeSdanielk1977 } 26469a1d0abeSdanielk1977 26479a1d0abeSdanielk1977 /* 26489a1d0abeSdanielk1977 ** Usage: sqlite3OsUnlock <file handle> 26499a1d0abeSdanielk1977 */ 26509a1d0abeSdanielk1977 static int test_sqlite3OsUnlock( 26519a1d0abeSdanielk1977 void * clientData, 26529a1d0abeSdanielk1977 Tcl_Interp *interp, 26539a1d0abeSdanielk1977 int objc, 26549a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 26559a1d0abeSdanielk1977 ){ 26569a1d0abeSdanielk1977 OsFile * pFile; 26579a1d0abeSdanielk1977 int rc; 26589a1d0abeSdanielk1977 26599a1d0abeSdanielk1977 if( objc!=2 ){ 26609a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 26619a1d0abeSdanielk1977 Tcl_GetString(objv[0]), " filehandle", 0); 26629a1d0abeSdanielk1977 return TCL_ERROR; 26639a1d0abeSdanielk1977 } 26649a1d0abeSdanielk1977 26659a1d0abeSdanielk1977 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 26669a1d0abeSdanielk1977 return TCL_ERROR; 26679a1d0abeSdanielk1977 } 2668054889ecSdrh rc = sqlite3OsUnlock(pFile, NO_LOCK); 26699a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 26709a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 26719a1d0abeSdanielk1977 return TCL_ERROR; 26729a1d0abeSdanielk1977 } 26739a1d0abeSdanielk1977 return TCL_OK; 26749a1d0abeSdanielk1977 } 2675d3d39e93Sdrh 2676ab3f9feaSdrh /* 2677ab3f9feaSdrh ** Usage: sqlite3OsTempFileName 2678ab3f9feaSdrh */ 2679ab3f9feaSdrh static int test_sqlite3OsTempFileName( 2680ab3f9feaSdrh void * clientData, 2681ab3f9feaSdrh Tcl_Interp *interp, 2682ab3f9feaSdrh int objc, 2683ab3f9feaSdrh Tcl_Obj *CONST objv[] 2684ab3f9feaSdrh ){ 2685ab3f9feaSdrh char zFile[SQLITE_TEMPNAME_SIZE]; 2686ab3f9feaSdrh int rc; 2687ab3f9feaSdrh 2688054889ecSdrh rc = sqlite3Os.xTempFileName(zFile); 2689ab3f9feaSdrh if( rc!=SQLITE_OK ){ 2690ab3f9feaSdrh Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 2691ab3f9feaSdrh return TCL_ERROR; 2692ab3f9feaSdrh } 2693ab3f9feaSdrh Tcl_AppendResult(interp, zFile, 0); 2694ab3f9feaSdrh return TCL_OK; 2695ab3f9feaSdrh } 269644ee5bf7Sdanielk1977 #endif 2697d8123366Sdanielk1977 26986622cce3Sdanielk1977 /* 2699cacb208eSdrh ** Usage: sqlite_set_magic DB MAGIC-NUMBER 2700cacb208eSdrh ** 2701cacb208eSdrh ** Set the db->magic value. This is used to test error recovery logic. 2702cacb208eSdrh */ 2703cacb208eSdrh static int sqlite_set_magic( 2704cacb208eSdrh void * clientData, 2705cacb208eSdrh Tcl_Interp *interp, 2706cacb208eSdrh int argc, 2707cacb208eSdrh char **argv 2708cacb208eSdrh ){ 2709cacb208eSdrh sqlite3 *db; 2710cacb208eSdrh if( argc!=3 ){ 2711cacb208eSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 2712cacb208eSdrh " DB MAGIC", 0); 2713cacb208eSdrh return TCL_ERROR; 2714cacb208eSdrh } 2715cacb208eSdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 2716cacb208eSdrh if( strcmp(argv[2], "SQLITE_MAGIC_OPEN")==0 ){ 2717cacb208eSdrh db->magic = SQLITE_MAGIC_OPEN; 2718cacb208eSdrh }else if( strcmp(argv[2], "SQLITE_MAGIC_CLOSED")==0 ){ 2719cacb208eSdrh db->magic = SQLITE_MAGIC_CLOSED; 2720cacb208eSdrh }else if( strcmp(argv[2], "SQLITE_MAGIC_BUSY")==0 ){ 2721cacb208eSdrh db->magic = SQLITE_MAGIC_BUSY; 2722cacb208eSdrh }else if( strcmp(argv[2], "SQLITE_MAGIC_ERROR")==0 ){ 2723cacb208eSdrh db->magic = SQLITE_MAGIC_ERROR; 2724cacb208eSdrh }else if( Tcl_GetInt(interp, argv[2], &db->magic) ){ 2725cacb208eSdrh return TCL_ERROR; 2726cacb208eSdrh } 2727cacb208eSdrh return TCL_OK; 2728cacb208eSdrh } 2729cacb208eSdrh 2730cacb208eSdrh /* 2731c5cdca61Sdrh ** Usage: sqlite3_interrupt DB 2732c5cdca61Sdrh ** 2733c5cdca61Sdrh ** Trigger an interrupt on DB 2734c5cdca61Sdrh */ 2735c5cdca61Sdrh static int test_interrupt( 2736c5cdca61Sdrh void * clientData, 2737c5cdca61Sdrh Tcl_Interp *interp, 2738c5cdca61Sdrh int argc, 2739c5cdca61Sdrh char **argv 2740c5cdca61Sdrh ){ 2741c5cdca61Sdrh sqlite3 *db; 2742c5cdca61Sdrh if( argc!=2 ){ 2743c5cdca61Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB", 0); 2744c5cdca61Sdrh return TCL_ERROR; 2745c5cdca61Sdrh } 2746c5cdca61Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 2747c5cdca61Sdrh sqlite3_interrupt(db); 2748c5cdca61Sdrh return TCL_OK; 2749c5cdca61Sdrh } 2750c5cdca61Sdrh 275179158e18Sdrh static u8 *sqlite3_stack_baseline = 0; 275279158e18Sdrh 2753c5cdca61Sdrh /* 275479158e18Sdrh ** Fill the stack with a known bitpattern. 2755600dd0baSdanielk1977 */ 275679158e18Sdrh static void prepStack(void){ 275779158e18Sdrh int i; 275879158e18Sdrh u32 bigBuf[65536]; 275979158e18Sdrh for(i=0; i<sizeof(bigBuf); i++) bigBuf[i] = 0xdeadbeef; 276079158e18Sdrh sqlite3_stack_baseline = (u8*)&bigBuf[65536]; 276179158e18Sdrh } 276279158e18Sdrh 276379158e18Sdrh /* 276479158e18Sdrh ** Get the current stack depth. Used for debugging only. 276579158e18Sdrh */ 276679158e18Sdrh u64 sqlite3StackDepth(void){ 276779158e18Sdrh u8 x; 276879158e18Sdrh return (u64)(sqlite3_stack_baseline - &x); 276979158e18Sdrh } 277079158e18Sdrh 277179158e18Sdrh /* 277279158e18Sdrh ** Usage: sqlite3_stack_used DB SQL 277379158e18Sdrh ** 277479158e18Sdrh ** Try to measure the amount of stack space used by a call to sqlite3_exec 277579158e18Sdrh */ 277679158e18Sdrh static int test_stack_used( 2777600dd0baSdanielk1977 void * clientData, 2778600dd0baSdanielk1977 Tcl_Interp *interp, 2779600dd0baSdanielk1977 int argc, 2780600dd0baSdanielk1977 char **argv 2781600dd0baSdanielk1977 ){ 2782600dd0baSdanielk1977 sqlite3 *db; 278379158e18Sdrh int i; 278479158e18Sdrh if( argc!=3 ){ 278579158e18Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 278679158e18Sdrh " DB SQL", 0); 2787600dd0baSdanielk1977 return TCL_ERROR; 2788600dd0baSdanielk1977 } 278979158e18Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 279079158e18Sdrh prepStack(); 279179158e18Sdrh sqlite3_exec(db, argv[2], 0, 0, 0); 279279158e18Sdrh for(i=65535; i>=0 && ((u32*)sqlite3_stack_baseline)[-i]==0xdeadbeef; i--){} 279379158e18Sdrh Tcl_SetObjResult(interp, Tcl_NewIntObj(i*4)); 2794600dd0baSdanielk1977 return TCL_OK; 2795600dd0baSdanielk1977 } 2796600dd0baSdanielk1977 2797600dd0baSdanielk1977 /* 27989636c4e1Sdanielk1977 ** Usage: sqlite_delete_function DB function-name 27999636c4e1Sdanielk1977 ** 28009636c4e1Sdanielk1977 ** Delete the user function 'function-name' from database handle DB. It 28019636c4e1Sdanielk1977 ** is assumed that the user function was created as UTF8, any number of 28029636c4e1Sdanielk1977 ** arguments (the way the TCL interface does it). 28039636c4e1Sdanielk1977 */ 28049636c4e1Sdanielk1977 static int delete_function( 28059636c4e1Sdanielk1977 void * clientData, 28069636c4e1Sdanielk1977 Tcl_Interp *interp, 28079636c4e1Sdanielk1977 int argc, 28089636c4e1Sdanielk1977 char **argv 28099636c4e1Sdanielk1977 ){ 28109636c4e1Sdanielk1977 int rc; 28119636c4e1Sdanielk1977 sqlite3 *db; 28129636c4e1Sdanielk1977 if( argc!=3 ){ 28139636c4e1Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 28149636c4e1Sdanielk1977 " DB function-name", 0); 28159636c4e1Sdanielk1977 return TCL_ERROR; 28169636c4e1Sdanielk1977 } 28179636c4e1Sdanielk1977 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 28189636c4e1Sdanielk1977 rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 0, 0, 0); 28199636c4e1Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 28209636c4e1Sdanielk1977 return TCL_OK; 28219636c4e1Sdanielk1977 } 28229636c4e1Sdanielk1977 28239636c4e1Sdanielk1977 /* 28249636c4e1Sdanielk1977 ** Usage: sqlite_delete_collation DB collation-name 28259636c4e1Sdanielk1977 ** 28269636c4e1Sdanielk1977 ** Delete the collation sequence 'collation-name' from database handle 28279636c4e1Sdanielk1977 ** DB. It is assumed that the collation sequence was created as UTF8 (the 28289636c4e1Sdanielk1977 ** way the TCL interface does it). 28299636c4e1Sdanielk1977 */ 28309636c4e1Sdanielk1977 static int delete_collation( 28319636c4e1Sdanielk1977 void * clientData, 28329636c4e1Sdanielk1977 Tcl_Interp *interp, 28339636c4e1Sdanielk1977 int argc, 28349636c4e1Sdanielk1977 char **argv 28359636c4e1Sdanielk1977 ){ 28369636c4e1Sdanielk1977 int rc; 28379636c4e1Sdanielk1977 sqlite3 *db; 28389636c4e1Sdanielk1977 if( argc!=3 ){ 28399636c4e1Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 28409636c4e1Sdanielk1977 " DB function-name", 0); 28419636c4e1Sdanielk1977 return TCL_ERROR; 28429636c4e1Sdanielk1977 } 28439636c4e1Sdanielk1977 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 28449636c4e1Sdanielk1977 rc = sqlite3_create_collation(db, argv[2], SQLITE_UTF8, 0, 0); 28459636c4e1Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 28469636c4e1Sdanielk1977 return TCL_OK; 28479636c4e1Sdanielk1977 } 28489636c4e1Sdanielk1977 28499636c4e1Sdanielk1977 /* 28503e1d8e63Sdrh ** Usage: sqlite3_get_autocommit DB 28513e1d8e63Sdrh ** 28523e1d8e63Sdrh ** Return true if the database DB is currently in auto-commit mode. 28533e1d8e63Sdrh ** Return false if not. 28543e1d8e63Sdrh */ 28553e1d8e63Sdrh static int get_autocommit( 28563e1d8e63Sdrh void * clientData, 28573e1d8e63Sdrh Tcl_Interp *interp, 28583e1d8e63Sdrh int argc, 28593e1d8e63Sdrh char **argv 28603e1d8e63Sdrh ){ 28613e1d8e63Sdrh char zBuf[30]; 28623e1d8e63Sdrh sqlite3 *db; 28633e1d8e63Sdrh if( argc!=2 ){ 28643e1d8e63Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 28653e1d8e63Sdrh " DB", 0); 28663e1d8e63Sdrh return TCL_ERROR; 28673e1d8e63Sdrh } 28683e1d8e63Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 28693e1d8e63Sdrh sprintf(zBuf, "%d", sqlite3_get_autocommit(db)); 28703e1d8e63Sdrh Tcl_AppendResult(interp, zBuf, 0); 28713e1d8e63Sdrh return TCL_OK; 28723e1d8e63Sdrh } 28733e1d8e63Sdrh 28743e1d8e63Sdrh /* 287592febd92Sdrh ** Usage: tcl_variable_type VARIABLENAME 287692febd92Sdrh ** 287792febd92Sdrh ** Return the name of the internal representation for the 287892febd92Sdrh ** value of the given variable. 287992febd92Sdrh */ 288092febd92Sdrh static int tcl_variable_type( 288192febd92Sdrh void * clientData, 288292febd92Sdrh Tcl_Interp *interp, 288392febd92Sdrh int objc, 288492febd92Sdrh Tcl_Obj *CONST objv[] 288592febd92Sdrh ){ 288692febd92Sdrh Tcl_Obj *pVar; 288792febd92Sdrh if( objc!=2 ){ 288892febd92Sdrh Tcl_WrongNumArgs(interp, 1, objv, "VARIABLE"); 288992febd92Sdrh return TCL_ERROR; 289092febd92Sdrh } 289192febd92Sdrh pVar = Tcl_GetVar2Ex(interp, Tcl_GetString(objv[1]), 0, TCL_LEAVE_ERR_MSG); 289292febd92Sdrh if( pVar==0 ) return TCL_ERROR; 289392febd92Sdrh if( pVar->typePtr ){ 289492febd92Sdrh Tcl_SetObjResult(interp, Tcl_NewStringObj(pVar->typePtr->name, -1)); 289592febd92Sdrh } 289692febd92Sdrh return TCL_OK; 289792febd92Sdrh } 289892febd92Sdrh 289992febd92Sdrh /* 290027d258a3Sdrh ** This routine sets entries in the global ::sqlite_options() array variable 290127d258a3Sdrh ** according to the compile-time configuration of the database. Test 290227d258a3Sdrh ** procedures use this to determine when tests should be omitted. 290327d258a3Sdrh */ 290427d258a3Sdrh static void set_options(Tcl_Interp *interp){ 290575f86a4bSdrh #ifdef SQLITE_32BIT_ROWID 290675f86a4bSdrh Tcl_SetVar2(interp, "sqlite_options", "rowid32", "1", TCL_GLOBAL_ONLY); 290775f86a4bSdrh #else 290875f86a4bSdrh Tcl_SetVar2(interp, "sqlite_options", "rowid32", "0", TCL_GLOBAL_ONLY); 290975f86a4bSdrh #endif 291075f86a4bSdrh 29119f18e8a0Sdrh #ifdef SQLITE_CASE_SENSITIVE_LIKE 29129f18e8a0Sdrh Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","1",TCL_GLOBAL_ONLY); 29139f18e8a0Sdrh #else 29149f18e8a0Sdrh Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","0",TCL_GLOBAL_ONLY); 29159f18e8a0Sdrh #endif 29169f18e8a0Sdrh 2917d7c03f74Sdanielk1977 #ifdef SQLITE_DISABLE_DIRSYNC 2918d7c03f74Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "dirsync", "0", TCL_GLOBAL_ONLY); 2919d7c03f74Sdanielk1977 #else 2920d7c03f74Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "dirsync", "1", TCL_GLOBAL_ONLY); 2921d7c03f74Sdanielk1977 #endif 2922d7c03f74Sdanielk1977 292326c5d79fSdanielk1977 #ifdef SQLITE_DISABLE_LFS 292426c5d79fSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "lfs", "0", TCL_GLOBAL_ONLY); 292526c5d79fSdanielk1977 #else 292626c5d79fSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "lfs", "1", TCL_GLOBAL_ONLY); 292726c5d79fSdanielk1977 #endif 292826c5d79fSdanielk1977 29291c8c23ccSdanielk1977 #ifdef SQLITE_OMIT_ALTERTABLE 29301c8c23ccSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY); 29311c8c23ccSdanielk1977 #else 29321c8c23ccSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY); 29331c8c23ccSdanielk1977 #endif 293413d7042aSdrh 29359f18e8a0Sdrh #ifdef SQLITE_OMIT_ANALYZE 29369f18e8a0Sdrh Tcl_SetVar2(interp, "sqlite_options", "analyze", "0", TCL_GLOBAL_ONLY); 29379f18e8a0Sdrh #else 29389f18e8a0Sdrh Tcl_SetVar2(interp, "sqlite_options", "analyze", "1", TCL_GLOBAL_ONLY); 29399f18e8a0Sdrh #endif 29409f18e8a0Sdrh 294113d7042aSdrh #ifdef SQLITE_OMIT_AUTHORIZATION 294213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "auth", "0", TCL_GLOBAL_ONLY); 294313d7042aSdrh #else 294413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "auth", "1", TCL_GLOBAL_ONLY); 294513d7042aSdrh #endif 294613d7042aSdrh 2947f3388144Sdrh #ifdef SQLITE_OMIT_AUTOINCREMENT 2948f3388144Sdrh Tcl_SetVar2(interp, "sqlite_options", "autoinc", "0", TCL_GLOBAL_ONLY); 2949f3388144Sdrh #else 2950f3388144Sdrh Tcl_SetVar2(interp, "sqlite_options", "autoinc", "1", TCL_GLOBAL_ONLY); 2951f3388144Sdrh #endif 2952f3388144Sdrh 295345901d62Sdanielk1977 #ifdef SQLITE_OMIT_AUTOVACUUM 295445901d62Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "0", TCL_GLOBAL_ONLY); 295545901d62Sdanielk1977 #else 295645901d62Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "1", TCL_GLOBAL_ONLY); 2957f3388144Sdrh #endif /* SQLITE_OMIT_AUTOVACUUM */ 29584d36b81eSdanielk1977 #if !defined(SQLITE_DEFAULT_AUTOVACUUM) || SQLITE_DEFAULT_AUTOVACUUM==0 295945901d62Sdanielk1977 Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","0",TCL_GLOBAL_ONLY); 296045901d62Sdanielk1977 #else 296145901d62Sdanielk1977 Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","1",TCL_GLOBAL_ONLY); 296245901d62Sdanielk1977 #endif 296313d7042aSdrh 296455ef4d97Sdrh #ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION 296555ef4d97Sdrh Tcl_SetVar2(interp, "sqlite_options", "between_opt", "0", TCL_GLOBAL_ONLY); 296655ef4d97Sdrh #else 296755ef4d97Sdrh Tcl_SetVar2(interp, "sqlite_options", "between_opt", "1", TCL_GLOBAL_ONLY); 296855ef4d97Sdrh #endif 296955ef4d97Sdrh 297013d7042aSdrh #ifdef SQLITE_OMIT_BLOB_LITERAL 297113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "bloblit", "0", TCL_GLOBAL_ONLY); 297213d7042aSdrh #else 297313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY); 297413d7042aSdrh #endif 297513d7042aSdrh 2976487e262fSdrh #ifdef SQLITE_OMIT_CAST 2977487e262fSdrh Tcl_SetVar2(interp, "sqlite_options", "cast", "0", TCL_GLOBAL_ONLY); 2978487e262fSdrh #else 2979487e262fSdrh Tcl_SetVar2(interp, "sqlite_options", "cast", "1", TCL_GLOBAL_ONLY); 2980487e262fSdrh #endif 2981487e262fSdrh 2982ffe07b2dSdrh #ifdef SQLITE_OMIT_CHECK 2983ffe07b2dSdrh Tcl_SetVar2(interp, "sqlite_options", "check", "0", TCL_GLOBAL_ONLY); 2984ffe07b2dSdrh #else 2985ffe07b2dSdrh Tcl_SetVar2(interp, "sqlite_options", "check", "1", TCL_GLOBAL_ONLY); 2986ffe07b2dSdrh #endif 2987ffe07b2dSdrh 2988ccae6026Sdrh #ifdef SQLITE_OMIT_COMPLETE 2989ccae6026Sdrh Tcl_SetVar2(interp, "sqlite_options", "complete", "0", TCL_GLOBAL_ONLY); 2990ccae6026Sdrh #else 2991ccae6026Sdrh Tcl_SetVar2(interp, "sqlite_options", "complete", "1", TCL_GLOBAL_ONLY); 2992ccae6026Sdrh #endif 2993ccae6026Sdrh 299413d7042aSdrh #ifdef SQLITE_OMIT_COMPOUND_SELECT 299513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "compound", "0", TCL_GLOBAL_ONLY); 299613d7042aSdrh #else 299713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "compound", "1", TCL_GLOBAL_ONLY); 299813d7042aSdrh #endif 299913d7042aSdrh 300013d7042aSdrh #ifdef SQLITE_OMIT_CONFLICT_CLAUSE 300113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "conflict", "0", TCL_GLOBAL_ONLY); 300213d7042aSdrh #else 300313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "conflict", "1", TCL_GLOBAL_ONLY); 300413d7042aSdrh #endif 300513d7042aSdrh 300613d7042aSdrh #ifdef SQLITE_OMIT_DATETIME_FUNCS 300713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "datetime", "0", TCL_GLOBAL_ONLY); 300813d7042aSdrh #else 300913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "datetime", "1", TCL_GLOBAL_ONLY); 301013d7042aSdrh #endif 301113d7042aSdrh 30122e66f0b9Sdrh #ifdef SQLITE_OMIT_DISKIO 30132e66f0b9Sdrh Tcl_SetVar2(interp, "sqlite_options", "diskio", "0", TCL_GLOBAL_ONLY); 30142e66f0b9Sdrh #else 30152e66f0b9Sdrh Tcl_SetVar2(interp, "sqlite_options", "diskio", "1", TCL_GLOBAL_ONLY); 30162e66f0b9Sdrh #endif 30172e66f0b9Sdrh 301813d7042aSdrh #ifdef SQLITE_OMIT_EXPLAIN 301913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "explain", "0", TCL_GLOBAL_ONLY); 302013d7042aSdrh #else 302113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "explain", "1", TCL_GLOBAL_ONLY); 302213d7042aSdrh #endif 302313d7042aSdrh 302413d7042aSdrh #ifdef SQLITE_OMIT_FLOATING_POINT 302513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "0", TCL_GLOBAL_ONLY); 302613d7042aSdrh #else 302713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "1", TCL_GLOBAL_ONLY); 302813d7042aSdrh #endif 302913d7042aSdrh 303013d7042aSdrh #ifdef SQLITE_OMIT_FOREIGN_KEY 303113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "0", TCL_GLOBAL_ONLY); 303213d7042aSdrh #else 303313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "1", TCL_GLOBAL_ONLY); 303413d7042aSdrh #endif 303513d7042aSdrh 30366b456a2bSdanielk1977 #ifdef SQLITE_OMIT_GLOBALRECOVER 30376b456a2bSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "0", TCL_GLOBAL_ONLY); 30386b456a2bSdanielk1977 #else 30396b456a2bSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "1", TCL_GLOBAL_ONLY); 30406b456a2bSdanielk1977 #endif 30416b456a2bSdanielk1977 304213d7042aSdrh #ifdef SQLITE_OMIT_INTEGRITY_CHECK 304313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "integrityck", "0", TCL_GLOBAL_ONLY); 304413d7042aSdrh #else 304513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "integrityck", "1", TCL_GLOBAL_ONLY); 304613d7042aSdrh #endif 304713d7042aSdrh 304855ef4d97Sdrh #ifdef SQLITE_OMIT_LIKE_OPTIMIZATION 304955ef4d97Sdrh Tcl_SetVar2(interp, "sqlite_options", "like_opt", "0", TCL_GLOBAL_ONLY); 305055ef4d97Sdrh #else 305155ef4d97Sdrh Tcl_SetVar2(interp, "sqlite_options", "like_opt", "1", TCL_GLOBAL_ONLY); 305255ef4d97Sdrh #endif 305355ef4d97Sdrh 305413d7042aSdrh #ifdef SQLITE_OMIT_MEMORYDB 305513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "memorydb", "0", TCL_GLOBAL_ONLY); 305613d7042aSdrh #else 305713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "memorydb", "1", TCL_GLOBAL_ONLY); 305813d7042aSdrh #endif 305913d7042aSdrh 306055ef4d97Sdrh #ifdef SQLITE_OMIT_OR_OPTIMIZATION 306155ef4d97Sdrh Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY); 306255ef4d97Sdrh #else 306355ef4d97Sdrh Tcl_SetVar2(interp, "sqlite_options", "or_opt", "1", TCL_GLOBAL_ONLY); 306455ef4d97Sdrh #endif 306555ef4d97Sdrh 306613d7042aSdrh #ifdef SQLITE_OMIT_PAGER_PRAGMAS 306713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "0", TCL_GLOBAL_ONLY); 306813d7042aSdrh #else 306913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "1", TCL_GLOBAL_ONLY); 307013d7042aSdrh #endif 307113d7042aSdrh 30722e66f0b9Sdrh #ifdef SQLITE_OMIT_PARSER 30732e66f0b9Sdrh Tcl_SetVar2(interp, "sqlite_options", "parser", "0", TCL_GLOBAL_ONLY); 30742e66f0b9Sdrh #else 30752e66f0b9Sdrh Tcl_SetVar2(interp, "sqlite_options", "parser", "1", TCL_GLOBAL_ONLY); 30762e66f0b9Sdrh #endif 30772e66f0b9Sdrh 3078bf21627bSdrh #if defined(SQLITE_OMIT_PRAGMA) || defined(SQLITE_OMIT_FLAG_PRAGMAS) 307913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pragma", "0", TCL_GLOBAL_ONLY); 308013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "integrityck", "0", TCL_GLOBAL_ONLY); 308113d7042aSdrh #else 308213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pragma", "1", TCL_GLOBAL_ONLY); 308313d7042aSdrh #endif 308413d7042aSdrh 308513d7042aSdrh #ifdef SQLITE_OMIT_PROGRESS_CALLBACK 308613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "progress", "0", TCL_GLOBAL_ONLY); 308713d7042aSdrh #else 308813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "progress", "1", TCL_GLOBAL_ONLY); 308913d7042aSdrh #endif 309013d7042aSdrh 309113d7042aSdrh #ifdef SQLITE_OMIT_REINDEX 309213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "reindex", "0", TCL_GLOBAL_ONLY); 309313d7042aSdrh #else 309413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "reindex", "1", TCL_GLOBAL_ONLY); 309513d7042aSdrh #endif 309613d7042aSdrh 309713d7042aSdrh #ifdef SQLITE_OMIT_SCHEMA_PRAGMAS 309813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "0", TCL_GLOBAL_ONLY); 309913d7042aSdrh #else 310013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "1", TCL_GLOBAL_ONLY); 310113d7042aSdrh #endif 310213d7042aSdrh 310313d7042aSdrh #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS 310413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_version", "0", TCL_GLOBAL_ONLY); 310513d7042aSdrh #else 310613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY); 310713d7042aSdrh #endif 310813d7042aSdrh 3109*aef0bf64Sdanielk1977 #ifdef SQLITE_OMIT_SHARED_CACHE 3110*aef0bf64Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "shared_cache", "0", TCL_GLOBAL_ONLY); 3111*aef0bf64Sdanielk1977 #else 3112*aef0bf64Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "shared_cache", "1", TCL_GLOBAL_ONLY); 3113*aef0bf64Sdanielk1977 #endif 3114*aef0bf64Sdanielk1977 31153e8c37e7Sdanielk1977 #ifdef SQLITE_OMIT_SUBQUERY 31163e8c37e7Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "subquery", "0", TCL_GLOBAL_ONLY); 31173e8c37e7Sdanielk1977 #else 31183e8c37e7Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "subquery", "1", TCL_GLOBAL_ONLY); 31193e8c37e7Sdanielk1977 #endif 31203e8c37e7Sdanielk1977 312113d7042aSdrh #ifdef SQLITE_OMIT_TCL_VARIABLE 312213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "tclvar", "0", TCL_GLOBAL_ONLY); 312313d7042aSdrh #else 312413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "tclvar", "1", TCL_GLOBAL_ONLY); 312513d7042aSdrh #endif 312613d7042aSdrh 312713d7042aSdrh #if defined(THREADSAFE) && THREADSAFE 312813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "1", TCL_GLOBAL_ONLY); 312913d7042aSdrh #else 313013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "0", TCL_GLOBAL_ONLY); 313113d7042aSdrh #endif 313213d7042aSdrh 313319e2d37fSdrh #ifdef SQLITE_OMIT_TRACE 313419e2d37fSdrh Tcl_SetVar2(interp, "sqlite_options", "trace", "0", TCL_GLOBAL_ONLY); 313519e2d37fSdrh #else 313619e2d37fSdrh Tcl_SetVar2(interp, "sqlite_options", "trace", "1", TCL_GLOBAL_ONLY); 313719e2d37fSdrh #endif 313819e2d37fSdrh 313913d7042aSdrh #ifdef SQLITE_OMIT_TRIGGER 314013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "trigger", "0", TCL_GLOBAL_ONLY); 314113d7042aSdrh #else 314213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "trigger", "1", TCL_GLOBAL_ONLY); 314313d7042aSdrh #endif 314413d7042aSdrh 314553c0f748Sdanielk1977 #ifdef SQLITE_OMIT_TEMPDB 314653c0f748Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "tempdb", "0", TCL_GLOBAL_ONLY); 314753c0f748Sdanielk1977 #else 314853c0f748Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "tempdb", "1", TCL_GLOBAL_ONLY); 314953c0f748Sdanielk1977 #endif 315053c0f748Sdanielk1977 315113d7042aSdrh #ifdef SQLITE_OMIT_UTF16 315213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY); 315313d7042aSdrh #else 315413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "utf16", "1", TCL_GLOBAL_ONLY); 315513d7042aSdrh #endif 315613d7042aSdrh 315713d7042aSdrh #ifdef SQLITE_OMIT_VACUUM 315813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "vacuum", "0", TCL_GLOBAL_ONLY); 315913d7042aSdrh #else 316013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "vacuum", "1", TCL_GLOBAL_ONLY); 316113d7042aSdrh #endif 316213d7042aSdrh 316313d7042aSdrh #ifdef SQLITE_OMIT_VIEW 316413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "view", "0", TCL_GLOBAL_ONLY); 316513d7042aSdrh #else 316613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "view", "1", TCL_GLOBAL_ONLY); 316713d7042aSdrh #endif 316827d258a3Sdrh } 316927d258a3Sdrh 317027d258a3Sdrh /* 3171d1bf3512Sdrh ** Register commands with the TCL interpreter. 3172d1bf3512Sdrh */ 3173d1bf3512Sdrh int Sqlitetest1_Init(Tcl_Interp *interp){ 31746f8a503dSdanielk1977 extern int sqlite3_search_count; 31756f8a503dSdanielk1977 extern int sqlite3_interrupt_count; 31766f8a503dSdanielk1977 extern int sqlite3_open_file_count; 31776bf89570Sdrh extern int sqlite3_sort_count; 31786f8a503dSdanielk1977 extern int sqlite3_current_time; 3179c2eef3b3Sdrh static struct { 3180c2eef3b3Sdrh char *zName; 3181c2eef3b3Sdrh Tcl_CmdProc *xProc; 3182c2eef3b3Sdrh } aCmd[] = { 31836f8a503dSdanielk1977 { "sqlite3_mprintf_int", (Tcl_CmdProc*)sqlite3_mprintf_int }, 3184e9707671Sdrh { "sqlite3_mprintf_int64", (Tcl_CmdProc*)sqlite3_mprintf_int64 }, 31856f8a503dSdanielk1977 { "sqlite3_mprintf_str", (Tcl_CmdProc*)sqlite3_mprintf_str }, 3186e29b1a05Sdrh { "sqlite3_mprintf_stronly", (Tcl_CmdProc*)sqlite3_mprintf_stronly}, 31876f8a503dSdanielk1977 { "sqlite3_mprintf_double", (Tcl_CmdProc*)sqlite3_mprintf_double }, 31886f8a503dSdanielk1977 { "sqlite3_mprintf_scaled", (Tcl_CmdProc*)sqlite3_mprintf_scaled }, 318963782855Sdrh { "sqlite3_mprintf_hexdouble", (Tcl_CmdProc*)sqlite3_mprintf_hexdouble}, 31906f8a503dSdanielk1977 { "sqlite3_mprintf_z_test", (Tcl_CmdProc*)test_mprintf_z }, 31916f8a503dSdanielk1977 { "sqlite3_last_insert_rowid", (Tcl_CmdProc*)test_last_rowid }, 31926f8a503dSdanielk1977 { "sqlite3_exec_printf", (Tcl_CmdProc*)test_exec_printf }, 31936f8a503dSdanielk1977 { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, 31946f8a503dSdanielk1977 { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, 31956f8a503dSdanielk1977 { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, 31966f8a503dSdanielk1977 { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, 3197c2eef3b3Sdrh { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, 3198c2eef3b3Sdrh { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, 31992c336549Sdanielk1977 #ifdef SQLITE_MEMDEBUG 3200c2eef3b3Sdrh { "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail }, 3201c2eef3b3Sdrh { "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat }, 3202c2eef3b3Sdrh #endif 320396fc5fe6Sdanielk1977 { "sqlite_bind", (Tcl_CmdProc*)test_bind }, 320499ee3600Sdrh { "breakpoint", (Tcl_CmdProc*)test_breakpoint }, 320525d6543dSdrh { "sqlite3_key", (Tcl_CmdProc*)test_key }, 320625d6543dSdrh { "sqlite3_rekey", (Tcl_CmdProc*)test_rekey }, 3207cacb208eSdrh { "sqlite_set_magic", (Tcl_CmdProc*)sqlite_set_magic }, 3208c5cdca61Sdrh { "sqlite3_interrupt", (Tcl_CmdProc*)test_interrupt }, 3209600dd0baSdanielk1977 #if 0 3210600dd0baSdanielk1977 { "sqlite3_sleep", (Tcl_CmdProc*)test_sleep }, 3211600dd0baSdanielk1977 #endif 32129636c4e1Sdanielk1977 { "sqlite_delete_function", (Tcl_CmdProc*)delete_function }, 32133e1d8e63Sdrh { "sqlite_delete_collation", (Tcl_CmdProc*)delete_collation }, 32143e1d8e63Sdrh { "sqlite3_get_autocommit", (Tcl_CmdProc*)get_autocommit }, 321579158e18Sdrh { "sqlite3_stack_used", (Tcl_CmdProc*)test_stack_used }, 3216c2eef3b3Sdrh }; 321751e3d8e2Sdanielk1977 static struct { 321851e3d8e2Sdanielk1977 char *zName; 321951e3d8e2Sdanielk1977 Tcl_ObjCmdProc *xProc; 322004f2e68dSdanielk1977 void *clientData; 322151e3d8e2Sdanielk1977 } aObjCmd[] = { 3222241db313Sdrh { "sqlite3_bind_int", test_bind_int, 0 }, 322304f2e68dSdanielk1977 { "sqlite3_bind_int64", test_bind_int64, 0 }, 322404f2e68dSdanielk1977 { "sqlite3_bind_double", test_bind_double, 0 }, 322504f2e68dSdanielk1977 { "sqlite3_bind_null", test_bind_null ,0 }, 322604f2e68dSdanielk1977 { "sqlite3_bind_text", test_bind_text ,0 }, 322704f2e68dSdanielk1977 { "sqlite3_bind_text16", test_bind_text16 ,0 }, 322804f2e68dSdanielk1977 { "sqlite3_bind_blob", test_bind_blob ,0 }, 322975f6a032Sdrh { "sqlite3_bind_parameter_count", test_bind_parameter_count, 0}, 3230895d7472Sdrh { "sqlite3_bind_parameter_name", test_bind_parameter_name, 0}, 3231fa6bc000Sdrh { "sqlite3_bind_parameter_index", test_bind_parameter_index, 0}, 3232600dd0baSdanielk1977 #if 0 3233600dd0baSdanielk1977 { "sqlite3_clear_bindings", test_clear_bindings, 0}, 3234600dd0baSdanielk1977 #endif 323504f2e68dSdanielk1977 { "sqlite3_errcode", test_errcode ,0 }, 323604f2e68dSdanielk1977 { "sqlite3_errmsg", test_errmsg ,0 }, 323704f2e68dSdanielk1977 { "sqlite3_errmsg16", test_errmsg16 ,0 }, 323804f2e68dSdanielk1977 { "sqlite3_open", test_open ,0 }, 323904f2e68dSdanielk1977 { "sqlite3_open16", test_open16 ,0 }, 3240bc6ada41Sdanielk1977 { "sqlite3_complete16", test_complete16 ,0 }, 324104f2e68dSdanielk1977 324204f2e68dSdanielk1977 { "sqlite3_prepare", test_prepare ,0 }, 324304f2e68dSdanielk1977 { "sqlite3_prepare16", test_prepare16 ,0 }, 324404f2e68dSdanielk1977 { "sqlite3_finalize", test_finalize ,0 }, 324504f2e68dSdanielk1977 { "sqlite3_reset", test_reset ,0 }, 3246d89bd007Sdrh { "sqlite3_expired", test_expired ,0 }, 3247f8db1bc0Sdrh { "sqlite3_transfer_bindings", test_transfer_bind ,0 }, 3248fbcd585fSdanielk1977 { "sqlite3_changes", test_changes ,0 }, 324904f2e68dSdanielk1977 { "sqlite3_step", test_step ,0 }, 325004f2e68dSdanielk1977 325104f2e68dSdanielk1977 /* sqlite3_column_*() API */ 325204f2e68dSdanielk1977 { "sqlite3_column_count", test_column_count ,0 }, 325304f2e68dSdanielk1977 { "sqlite3_data_count", test_data_count ,0 }, 325404f2e68dSdanielk1977 { "sqlite3_column_type", test_column_type ,0 }, 3255ea61b2c4Sdanielk1977 { "sqlite3_column_blob", test_column_blob ,0 }, 325604f2e68dSdanielk1977 { "sqlite3_column_double", test_column_double ,0 }, 325704f2e68dSdanielk1977 { "sqlite3_column_int64", test_column_int64 ,0 }, 325804f2e68dSdanielk1977 { "sqlite3_column_text", test_stmt_utf8, sqlite3_column_text }, 325904f2e68dSdanielk1977 { "sqlite3_column_decltype", test_stmt_utf8, sqlite3_column_decltype }, 326004f2e68dSdanielk1977 { "sqlite3_column_name", test_stmt_utf8, sqlite3_column_name }, 32616c62608fSdrh { "sqlite3_column_int", test_stmt_int, sqlite3_column_int }, 32626c62608fSdrh { "sqlite3_column_bytes", test_stmt_int, sqlite3_column_bytes }, 32636c62608fSdrh #ifndef SQLITE_OMIT_UTF16 32646c62608fSdrh { "sqlite3_column_bytes16", test_stmt_int, sqlite3_column_bytes16 }, 326504f2e68dSdanielk1977 { "sqlite3_column_text16", test_stmt_utf16, sqlite3_column_text16 }, 326604f2e68dSdanielk1977 { "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16}, 326704f2e68dSdanielk1977 { "sqlite3_column_name16", test_stmt_utf16, sqlite3_column_name16 }, 32686c62608fSdrh #endif 32696b456a2bSdanielk1977 { "sqlite3_global_recover", test_global_recover, 0 }, 327004f2e68dSdanielk1977 32719a1d0abeSdanielk1977 /* Functions from os.h */ 327244ee5bf7Sdanielk1977 #ifndef SQLITE_OMIT_DISKIO 32739a1d0abeSdanielk1977 { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 }, 32749a1d0abeSdanielk1977 { "sqlite3OsClose", test_sqlite3OsClose, 0 }, 32759a1d0abeSdanielk1977 { "sqlite3OsLock", test_sqlite3OsLock, 0 }, 3276ab3f9feaSdrh { "sqlite3OsTempFileName", test_sqlite3OsTempFileName, 0 }, 3277312d6b36Sdanielk1977 3278312d6b36Sdanielk1977 /* Custom test interfaces */ 32799a1d0abeSdanielk1977 { "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 }, 328044ee5bf7Sdanielk1977 #endif 32815436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 32824e6af134Sdanielk1977 { "add_test_collate", test_collate, 0 }, 3283312d6b36Sdanielk1977 { "add_test_collate_needed", test_collate_needed, 0 }, 3284c8e9a2dfSdanielk1977 { "add_test_function", test_function, 0 }, 32855436dc2dSdrh #endif 32865591df55Sdanielk1977 #ifdef SQLITE_MEMDEBUG 32875591df55Sdanielk1977 { "sqlite_malloc_outstanding", sqlite_malloc_outstanding, 0}, 32885591df55Sdanielk1977 #endif 3289312d6b36Sdanielk1977 { "sqlite3_test_errstr", test_errstr, 0 }, 329092febd92Sdrh { "tcl_variable_type", tcl_variable_type, 0 }, 3291*aef0bf64Sdanielk1977 #ifndef SQLITE_OMIT_SHARED_CACHE 3292*aef0bf64Sdanielk1977 { "sqlite3_enable_shared_cache", test_enable_shared_cache, 0}, 3293*aef0bf64Sdanielk1977 #endif 329451e3d8e2Sdanielk1977 }; 32951398ad36Sdrh static int bitmask_size = sizeof(Bitmask)*8; 3296c2eef3b3Sdrh int i; 32972ac3ee97Sdrh extern int sqlite3_os_trace; 329851147baaSdrh extern int sqlite3_where_trace; 3299b851b2c9Sdrh extern int sqlite3_sync_count, sqlite3_fullsync_count; 3300af6df11fSdrh extern int sqlite3_opentemp_count; 330101397205Sdrh extern int sqlite3_memUsed; 33022e588c75Sdanielk1977 extern int sqlite3_malloc_id; 330301397205Sdrh extern int sqlite3_memMax; 330455ef4d97Sdrh extern int sqlite3_like_count; 3305c0929987Sdrh #if OS_WIN 3306c0929987Sdrh extern int sqlite3_os_type; 3307c0929987Sdrh #endif 33088b3d990bSdrh #ifdef SQLITE_DEBUG 33098b3d990bSdrh extern int sqlite3_vdbe_addop_trace; 3310549c8b68Sdrh #endif 3311549c8b68Sdrh #ifdef SQLITE_TEST 3312549c8b68Sdrh extern char sqlite3_query_plan[]; 33139042f395Sdrh static char *query_plan = sqlite3_query_plan; 331448083ceeSdrh #endif 3315c2eef3b3Sdrh 3316c2eef3b3Sdrh for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ 3317c2eef3b3Sdrh Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); 3318c2eef3b3Sdrh } 331951e3d8e2Sdanielk1977 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ 3320c572ef7fSdanielk1977 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 3321c572ef7fSdanielk1977 aObjCmd[i].xProc, aObjCmd[i].clientData, 0); 332251e3d8e2Sdanielk1977 } 33236490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_search_count", 33246f8a503dSdanielk1977 (char*)&sqlite3_search_count, TCL_LINK_INT); 33256bf89570Sdrh Tcl_LinkVar(interp, "sqlite_sort_count", 33266bf89570Sdrh (char*)&sqlite3_sort_count, TCL_LINK_INT); 332755ef4d97Sdrh Tcl_LinkVar(interp, "sqlite_like_count", 332855ef4d97Sdrh (char*)&sqlite3_like_count, TCL_LINK_INT); 33296490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_interrupt_count", 33306f8a503dSdanielk1977 (char*)&sqlite3_interrupt_count, TCL_LINK_INT); 33316490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_open_file_count", 33326f8a503dSdanielk1977 (char*)&sqlite3_open_file_count, TCL_LINK_INT); 33336490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_current_time", 33346f8a503dSdanielk1977 (char*)&sqlite3_current_time, TCL_LINK_INT); 33352ac3ee97Sdrh Tcl_LinkVar(interp, "sqlite_os_trace", 33362ac3ee97Sdrh (char*)&sqlite3_os_trace, TCL_LINK_INT); 3337268803a9Sdrh #ifndef SQLITE_OMIT_UTF16 3338268803a9Sdrh Tcl_LinkVar(interp, "sqlite_last_needed_collation", 3339268803a9Sdrh (char*)&pzNeededCollation, TCL_LINK_STRING|TCL_LINK_READ_ONLY); 3340268803a9Sdrh #endif 334197cb2e96Sdanielk1977 #ifdef SQLITE_MEMDEBUG 33422e588c75Sdanielk1977 Tcl_LinkVar(interp, "sqlite_malloc_id", 33432e588c75Sdanielk1977 (char*)&sqlite3_malloc_id, TCL_LINK_STRING); 334497cb2e96Sdanielk1977 #endif 3345c0929987Sdrh #if OS_WIN 3346c0929987Sdrh Tcl_LinkVar(interp, "sqlite_os_type", 3347c0929987Sdrh (char*)&sqlite3_os_type, TCL_LINK_INT); 3348c0929987Sdrh #endif 3349549c8b68Sdrh #ifdef SQLITE_TEST 3350549c8b68Sdrh Tcl_LinkVar(interp, "sqlite_query_plan", 3351549c8b68Sdrh (char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY); 3352549c8b68Sdrh #endif 33538b3d990bSdrh #ifdef SQLITE_DEBUG 33548b3d990bSdrh Tcl_LinkVar(interp, "sqlite_addop_trace", 33558b3d990bSdrh (char*)&sqlite3_vdbe_addop_trace, TCL_LINK_INT); 335648083ceeSdrh Tcl_LinkVar(interp, "sqlite_where_trace", 335748083ceeSdrh (char*)&sqlite3_where_trace, TCL_LINK_INT); 33588b3d990bSdrh #endif 33597018030dSdrh #ifdef SQLITE_MEMDEBUG 336001397205Sdrh Tcl_LinkVar(interp, "sqlite_memused", 336101397205Sdrh (char*)&sqlite3_memUsed, TCL_LINK_INT | TCL_LINK_READ_ONLY); 336201397205Sdrh Tcl_LinkVar(interp, "sqlite_memmax", 336301397205Sdrh (char*)&sqlite3_memMax, TCL_LINK_INT | TCL_LINK_READ_ONLY); 33647018030dSdrh #endif 3365cbe21be3Sdanielk1977 #ifndef SQLITE_OMIT_DISKIO 3366af6df11fSdrh Tcl_LinkVar(interp, "sqlite_opentemp_count", 3367af6df11fSdrh (char*)&sqlite3_opentemp_count, TCL_LINK_INT); 3368cbe21be3Sdanielk1977 #endif 33697c972decSdrh Tcl_LinkVar(interp, "sqlite_static_bind_value", 33707c972decSdrh (char*)&sqlite_static_bind_value, TCL_LINK_STRING); 3371ab3f9feaSdrh Tcl_LinkVar(interp, "sqlite_temp_directory", 3372effd02bcSdrh (char*)&sqlite3_temp_directory, TCL_LINK_STRING); 33731398ad36Sdrh Tcl_LinkVar(interp, "bitmask_size", 33741398ad36Sdrh (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); 3375748f763fSdrh #if OS_UNIX 3376b851b2c9Sdrh Tcl_LinkVar(interp, "sqlite_sync_count", 3377b851b2c9Sdrh (char*)&sqlite3_sync_count, TCL_LINK_INT); 3378b851b2c9Sdrh Tcl_LinkVar(interp, "sqlite_fullsync_count", 3379b851b2c9Sdrh (char*)&sqlite3_fullsync_count, TCL_LINK_INT); 3380748f763fSdrh #endif /* OS_UNIX */ 338127d258a3Sdrh set_options(interp); 3382d1bf3512Sdrh return TCL_OK; 3383d1bf3512Sdrh } 3384