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*19e2d37fSdrh ** $Id: test1.c,v 1.156 2005/08/29 23:00:05 drh 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]) ){ 376d8123366Sdanielk1977 sqlite3_result_text(context, sqlite3_value_text(argv[i]), -1, 377d8123366Sdanielk1977 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), 4504f26d6c4Sdrh 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 /* 6646f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_str 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], 679d1bf3512Sdrh " FORMAT INT INT STRING\"", 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 /* 6936f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_str 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 /* 7484693423bSdrh ** Usage: sqlite_malloc_fail N ?REPEAT-INTERVAL? 749daffd0e5Sdrh ** 7504693423bSdrh ** Rig sqliteMalloc() to fail on the N-th call and every REPEAT-INTERVAL call 7514693423bSdrh ** after that. If REPEAT-INTERVAL is 0 or is omitted, then only a single 7524693423bSdrh ** malloc will fail. If REPEAT-INTERVAL is 1 then all mallocs after the 7534693423bSdrh ** first failure will continue to fail on every call. If REPEAT-INTERVAL is 7544693423bSdrh ** 2 then every other malloc will fail. And so forth. 7554693423bSdrh ** 7564693423bSdrh ** Turn off this mechanism and reset the sqlite3_malloc_failed variable is N==0. 757daffd0e5Sdrh */ 7582c336549Sdanielk1977 #ifdef SQLITE_MEMDEBUG 759daffd0e5Sdrh static int sqlite_malloc_fail( 760daffd0e5Sdrh void *NotUsed, 761daffd0e5Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 762daffd0e5Sdrh int argc, /* Number of arguments */ 763daffd0e5Sdrh char **argv /* Text of each argument */ 764daffd0e5Sdrh ){ 765daffd0e5Sdrh int n; 7664693423bSdrh int rep; 7674693423bSdrh if( argc!=2 && argc!=3 ){ 768daffd0e5Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"", 0); 769daffd0e5Sdrh return TCL_ERROR; 770daffd0e5Sdrh } 771daffd0e5Sdrh if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR; 7724693423bSdrh if( argc==3 ){ 7734693423bSdrh if( Tcl_GetInt(interp, argv[2], &rep) ) return TCL_ERROR; 7744693423bSdrh }else{ 7754693423bSdrh rep = 0; 7764693423bSdrh } 7776f8a503dSdanielk1977 sqlite3_iMallocFail = n; 7784693423bSdrh sqlite3_iMallocReset = rep; 7796f8a503dSdanielk1977 sqlite3_malloc_failed = 0; 780daffd0e5Sdrh return TCL_OK; 781daffd0e5Sdrh } 782daffd0e5Sdrh #endif 783daffd0e5Sdrh 784daffd0e5Sdrh /* 785daffd0e5Sdrh ** Usage: sqlite_malloc_stat 786daffd0e5Sdrh ** 787daffd0e5Sdrh ** Return the number of prior calls to sqliteMalloc() and sqliteFree(). 788daffd0e5Sdrh */ 7892c336549Sdanielk1977 #ifdef SQLITE_MEMDEBUG 790daffd0e5Sdrh static int sqlite_malloc_stat( 791daffd0e5Sdrh void *NotUsed, 792daffd0e5Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 793daffd0e5Sdrh int argc, /* Number of arguments */ 794daffd0e5Sdrh char **argv /* Text of each argument */ 795daffd0e5Sdrh ){ 796daffd0e5Sdrh char zBuf[200]; 7976f8a503dSdanielk1977 sprintf(zBuf, "%d %d %d", sqlite3_nMalloc, sqlite3_nFree, sqlite3_iMallocFail); 798daffd0e5Sdrh Tcl_AppendResult(interp, zBuf, 0); 799daffd0e5Sdrh return TCL_OK; 800daffd0e5Sdrh } 801daffd0e5Sdrh #endif 802daffd0e5Sdrh 803daffd0e5Sdrh /* 80428b4e489Sdrh ** Usage: sqlite_abort 80528b4e489Sdrh ** 80628b4e489Sdrh ** Shutdown the process immediately. This is not a clean shutdown. 80728b4e489Sdrh ** This command is used to test the recoverability of a database in 80828b4e489Sdrh ** the event of a program crash. 80928b4e489Sdrh */ 81028b4e489Sdrh static int sqlite_abort( 81128b4e489Sdrh void *NotUsed, 81228b4e489Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 81328b4e489Sdrh int argc, /* Number of arguments */ 81428b4e489Sdrh char **argv /* Text of each argument */ 81528b4e489Sdrh ){ 81628b4e489Sdrh assert( interp==0 ); /* This will always fail */ 81728b4e489Sdrh return TCL_OK; 81828b4e489Sdrh } 81928b4e489Sdrh 82028b4e489Sdrh /* 8216cbe1f1bSdrh ** The following routine is a user-defined SQL function whose purpose 8226cbe1f1bSdrh ** is to test the sqlite_set_result() API. 8236cbe1f1bSdrh */ 8240ae8b831Sdanielk1977 static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 8256cbe1f1bSdrh while( argc>=2 ){ 8264f26d6c4Sdrh const char *zArg0 = sqlite3_value_text(argv[0]); 8276d88bad4Sdanielk1977 if( zArg0 ){ 8286d88bad4Sdanielk1977 if( 0==sqlite3StrICmp(zArg0, "int") ){ 8296d88bad4Sdanielk1977 sqlite3_result_int(context, sqlite3_value_int(argv[1])); 8306d88bad4Sdanielk1977 }else if( sqlite3StrICmp(zArg0,"int64")==0 ){ 8316d88bad4Sdanielk1977 sqlite3_result_int64(context, sqlite3_value_int64(argv[1])); 83251ad0ecdSdanielk1977 }else if( sqlite3StrICmp(zArg0,"string")==0 ){ 833d8123366Sdanielk1977 sqlite3_result_text(context, sqlite3_value_text(argv[1]), -1, 834d8123366Sdanielk1977 SQLITE_TRANSIENT); 83551ad0ecdSdanielk1977 }else if( sqlite3StrICmp(zArg0,"double")==0 ){ 8366d88bad4Sdanielk1977 sqlite3_result_double(context, sqlite3_value_double(argv[1])); 8376d88bad4Sdanielk1977 }else if( sqlite3StrICmp(zArg0,"null")==0 ){ 8386d88bad4Sdanielk1977 sqlite3_result_null(context); 8396d88bad4Sdanielk1977 }else if( sqlite3StrICmp(zArg0,"value")==0 ){ 8406d88bad4Sdanielk1977 sqlite3_result_value(context, argv[sqlite3_value_int(argv[1])]); 8416cbe1f1bSdrh }else{ 8426d88bad4Sdanielk1977 goto error_out; 8436d88bad4Sdanielk1977 } 8446d88bad4Sdanielk1977 }else{ 8456d88bad4Sdanielk1977 goto error_out; 8466cbe1f1bSdrh } 8476cbe1f1bSdrh argc -= 2; 8486cbe1f1bSdrh argv += 2; 8496cbe1f1bSdrh } 8506d88bad4Sdanielk1977 return; 8516d88bad4Sdanielk1977 8526d88bad4Sdanielk1977 error_out: 8536d88bad4Sdanielk1977 sqlite3_result_error(context,"first argument should be one of: " 8546d88bad4Sdanielk1977 "int int64 string double null value", -1); 8556cbe1f1bSdrh } 8566cbe1f1bSdrh 8576cbe1f1bSdrh /* 8586cbe1f1bSdrh ** Usage: sqlite_register_test_function DB NAME 8596cbe1f1bSdrh ** 8606cbe1f1bSdrh ** Register the test SQL function on the database DB under the name NAME. 8616cbe1f1bSdrh */ 862c2eef3b3Sdrh static int test_register_func( 8636cbe1f1bSdrh void *NotUsed, 8646cbe1f1bSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 8656cbe1f1bSdrh int argc, /* Number of arguments */ 8666cbe1f1bSdrh char **argv /* Text of each argument */ 8676cbe1f1bSdrh ){ 8689bb575fdSdrh sqlite3 *db; 8696cbe1f1bSdrh int rc; 8706cbe1f1bSdrh if( argc!=3 ){ 8716cbe1f1bSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 8726cbe1f1bSdrh " DB FUNCTION-NAME", 0); 8736cbe1f1bSdrh return TCL_ERROR; 8746cbe1f1bSdrh } 875b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 876f9d64d2cSdanielk1977 rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 877d8123366Sdanielk1977 testFunc, 0, 0); 8786cbe1f1bSdrh if( rc!=0 ){ 879f20b21c8Sdanielk1977 Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0); 8806cbe1f1bSdrh return TCL_ERROR; 8816cbe1f1bSdrh } 882c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 8836cbe1f1bSdrh return TCL_OK; 8846cbe1f1bSdrh } 8856cbe1f1bSdrh 8866cbe1f1bSdrh /* 887106bb236Sdanielk1977 ** Usage: sqlite3_finalize STMT 888b86ccfb2Sdrh ** 889106bb236Sdanielk1977 ** Finalize a statement handle. 890b86ccfb2Sdrh */ 891b86ccfb2Sdrh static int test_finalize( 892106bb236Sdanielk1977 void * clientData, 893106bb236Sdanielk1977 Tcl_Interp *interp, 894106bb236Sdanielk1977 int objc, 895106bb236Sdanielk1977 Tcl_Obj *CONST objv[] 896b86ccfb2Sdrh ){ 897106bb236Sdanielk1977 sqlite3_stmt *pStmt; 898b86ccfb2Sdrh int rc; 899c60d0446Sdrh sqlite3 *db; 900106bb236Sdanielk1977 901106bb236Sdanielk1977 if( objc!=2 ){ 902106bb236Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 903106bb236Sdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 904b86ccfb2Sdrh return TCL_ERROR; 905b86ccfb2Sdrh } 906106bb236Sdanielk1977 907106bb236Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 908106bb236Sdanielk1977 9094397de57Sdanielk1977 if( pStmt ){ 910c60d0446Sdrh db = StmtToDb(pStmt); 9114397de57Sdanielk1977 } 912fc57d7bfSdanielk1977 rc = sqlite3_finalize(pStmt); 913b77f5dadSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 9144397de57Sdanielk1977 if( db && sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 915106bb236Sdanielk1977 return TCL_OK; 916106bb236Sdanielk1977 } 917106bb236Sdanielk1977 918106bb236Sdanielk1977 /* 919106bb236Sdanielk1977 ** Usage: sqlite3_reset STMT 920106bb236Sdanielk1977 ** 921106bb236Sdanielk1977 ** Finalize a statement handle. 922106bb236Sdanielk1977 */ 923106bb236Sdanielk1977 static int test_reset( 924106bb236Sdanielk1977 void * clientData, 925106bb236Sdanielk1977 Tcl_Interp *interp, 926106bb236Sdanielk1977 int objc, 927106bb236Sdanielk1977 Tcl_Obj *CONST objv[] 928106bb236Sdanielk1977 ){ 929106bb236Sdanielk1977 sqlite3_stmt *pStmt; 930106bb236Sdanielk1977 int rc; 931106bb236Sdanielk1977 932106bb236Sdanielk1977 if( objc!=2 ){ 933106bb236Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 934106bb236Sdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 935106bb236Sdanielk1977 return TCL_ERROR; 936106bb236Sdanielk1977 } 937106bb236Sdanielk1977 938106bb236Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 939106bb236Sdanielk1977 940fc57d7bfSdanielk1977 rc = sqlite3_reset(pStmt); 9414397de57Sdanielk1977 if( pStmt && 9424397de57Sdanielk1977 sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 9434397de57Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 944106bb236Sdanielk1977 if( rc ){ 945b86ccfb2Sdrh return TCL_ERROR; 946b86ccfb2Sdrh } 947b86ccfb2Sdrh return TCL_OK; 948b86ccfb2Sdrh } 949b86ccfb2Sdrh 9505a38705eSdrh /* 951d89bd007Sdrh ** Usage: sqlite3_expired STMT 952d89bd007Sdrh ** 953d89bd007Sdrh ** Return TRUE if a recompilation of the statement is recommended. 954d89bd007Sdrh */ 955d89bd007Sdrh static int test_expired( 956d89bd007Sdrh void * clientData, 957d89bd007Sdrh Tcl_Interp *interp, 958d89bd007Sdrh int objc, 959d89bd007Sdrh Tcl_Obj *CONST objv[] 960d89bd007Sdrh ){ 961d89bd007Sdrh sqlite3_stmt *pStmt; 962d89bd007Sdrh if( objc!=2 ){ 963d89bd007Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", 964d89bd007Sdrh Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 965d89bd007Sdrh return TCL_ERROR; 966d89bd007Sdrh } 967d89bd007Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 968d89bd007Sdrh Tcl_SetObjResult(interp, Tcl_NewBooleanObj(sqlite3_expired(pStmt))); 969d89bd007Sdrh return TCL_OK; 970d89bd007Sdrh } 971d89bd007Sdrh 972d89bd007Sdrh /* 973f8db1bc0Sdrh ** Usage: sqlite3_transfer_bindings FROMSTMT TOSTMT 974f8db1bc0Sdrh ** 975f8db1bc0Sdrh ** Transfer all bindings from FROMSTMT over to TOSTMT 976f8db1bc0Sdrh */ 977f8db1bc0Sdrh static int test_transfer_bind( 978f8db1bc0Sdrh void * clientData, 979f8db1bc0Sdrh Tcl_Interp *interp, 980f8db1bc0Sdrh int objc, 981f8db1bc0Sdrh Tcl_Obj *CONST objv[] 982f8db1bc0Sdrh ){ 983f8db1bc0Sdrh sqlite3_stmt *pStmt1, *pStmt2; 984f8db1bc0Sdrh if( objc!=3 ){ 985f8db1bc0Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", 986f8db1bc0Sdrh Tcl_GetStringFromObj(objv[0], 0), " FROM-STMT TO-STMT", 0); 987f8db1bc0Sdrh return TCL_ERROR; 988f8db1bc0Sdrh } 989f8db1bc0Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt1)) return TCL_ERROR; 990f8db1bc0Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[2]), &pStmt2)) return TCL_ERROR; 991f8db1bc0Sdrh Tcl_SetObjResult(interp, 992f8db1bc0Sdrh Tcl_NewIntObj(sqlite3_transfer_bindings(pStmt1,pStmt2))); 993f8db1bc0Sdrh return TCL_OK; 994f8db1bc0Sdrh } 995f8db1bc0Sdrh 996f8db1bc0Sdrh /* 997fbcd585fSdanielk1977 ** Usage: sqlite3_changes DB 99850457896Sdrh ** 999fbcd585fSdanielk1977 ** Return the number of changes made to the database by the last SQL 1000fbcd585fSdanielk1977 ** execution. 100150457896Sdrh */ 1002fbcd585fSdanielk1977 static int test_changes( 1003fbcd585fSdanielk1977 void * clientData, 1004fbcd585fSdanielk1977 Tcl_Interp *interp, 1005fbcd585fSdanielk1977 int objc, 1006fbcd585fSdanielk1977 Tcl_Obj *CONST objv[] 1007fbcd585fSdanielk1977 ){ 1008fbcd585fSdanielk1977 sqlite3 *db; 1009fbcd585fSdanielk1977 if( objc!=2 ){ 1010fbcd585fSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1011fbcd585fSdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 1012fbcd585fSdanielk1977 return TCL_ERROR; 1013fbcd585fSdanielk1977 } 1014fbcd585fSdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1015fbcd585fSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_changes(db))); 1016fbcd585fSdanielk1977 return TCL_OK; 1017fbcd585fSdanielk1977 } 101850457896Sdrh 101950457896Sdrh /* 10207c972decSdrh ** This is the "static_bind_value" that variables are bound to when 10216f8a503dSdanielk1977 ** the FLAG option of sqlite3_bind is "static" 102250457896Sdrh */ 10237c972decSdrh static char *sqlite_static_bind_value = 0; 10247c972decSdrh 10257c972decSdrh /* 10266f8a503dSdanielk1977 ** Usage: sqlite3_bind VM IDX VALUE FLAGS 10277c972decSdrh ** 10287c972decSdrh ** Sets the value of the IDX-th occurance of "?" in the original SQL 10297c972decSdrh ** string. VALUE is the new value. If FLAGS=="null" then VALUE is 10307c972decSdrh ** ignored and the value is set to NULL. If FLAGS=="static" then 10317c972decSdrh ** the value is set to the value of a static variable named 10327c972decSdrh ** "sqlite_static_bind_value". If FLAGS=="normal" then a copy 10337c972decSdrh ** of the VALUE is made. 10347c972decSdrh */ 10357c972decSdrh static int test_bind( 103650457896Sdrh void *NotUsed, 103750457896Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 103850457896Sdrh int argc, /* Number of arguments */ 103950457896Sdrh char **argv /* Text of each argument */ 104050457896Sdrh ){ 1041fc57d7bfSdanielk1977 sqlite3_stmt *pStmt; 104250457896Sdrh int rc; 10437c972decSdrh int idx; 10447c972decSdrh if( argc!=5 ){ 104550457896Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 10467c972decSdrh " VM IDX VALUE (null|static|normal)\"", 0); 104750457896Sdrh return TCL_ERROR; 104850457896Sdrh } 1049fc57d7bfSdanielk1977 if( getStmtPointer(interp, argv[1], &pStmt) ) return TCL_ERROR; 10507c972decSdrh if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR; 10517c972decSdrh if( strcmp(argv[4],"null")==0 ){ 1052fc57d7bfSdanielk1977 rc = sqlite3_bind_null(pStmt, idx); 10537c972decSdrh }else if( strcmp(argv[4],"static")==0 ){ 1054fc57d7bfSdanielk1977 rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0); 10557c972decSdrh }else if( strcmp(argv[4],"normal")==0 ){ 1056d8123366Sdanielk1977 rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, SQLITE_TRANSIENT); 10577c972decSdrh }else{ 10587c972decSdrh Tcl_AppendResult(interp, "4th argument should be " 10597c972decSdrh "\"null\" or \"static\" or \"normal\"", 0); 10607c972decSdrh return TCL_ERROR; 10617c972decSdrh } 1062c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 106350457896Sdrh if( rc ){ 106450457896Sdrh char zBuf[50]; 106550457896Sdrh sprintf(zBuf, "(%d) ", rc); 1066f20b21c8Sdanielk1977 Tcl_AppendResult(interp, zBuf, sqlite3ErrStr(rc), 0); 106750457896Sdrh return TCL_ERROR; 106850457896Sdrh } 106950457896Sdrh return TCL_OK; 107050457896Sdrh } 107150457896Sdrh 10725436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 10734e6af134Sdanielk1977 /* 10744e6af134Sdanielk1977 ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be> 10754e6af134Sdanielk1977 ** 10764e6af134Sdanielk1977 ** This function is used to test that SQLite selects the correct collation 10774e6af134Sdanielk1977 ** sequence callback when multiple versions (for different text encodings) 10784e6af134Sdanielk1977 ** are available. 10794e6af134Sdanielk1977 ** 10804e6af134Sdanielk1977 ** Calling this routine registers the collation sequence "test_collate" 10814e6af134Sdanielk1977 ** with database handle <db>. The second argument must be a list of three 10824e6af134Sdanielk1977 ** boolean values. If the first is true, then a version of test_collate is 10834e6af134Sdanielk1977 ** registered for UTF-8, if the second is true, a version is registered for 10844e6af134Sdanielk1977 ** UTF-16le, if the third is true, a UTF-16be version is available. 10854e6af134Sdanielk1977 ** Previous versions of test_collate are deleted. 10864e6af134Sdanielk1977 ** 10874e6af134Sdanielk1977 ** The collation sequence test_collate is implemented by calling the 10884e6af134Sdanielk1977 ** following TCL script: 10894e6af134Sdanielk1977 ** 10904e6af134Sdanielk1977 ** "test_collate <enc> <lhs> <rhs>" 10914e6af134Sdanielk1977 ** 10924e6af134Sdanielk1977 ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8. 10934e6af134Sdanielk1977 ** The <enc> parameter is the encoding of the collation function that 10944e6af134Sdanielk1977 ** SQLite selected to call. The TCL test script implements the 10954e6af134Sdanielk1977 ** "test_collate" proc. 10964e6af134Sdanielk1977 ** 10974e6af134Sdanielk1977 ** Note that this will only work with one intepreter at a time, as the 10984e6af134Sdanielk1977 ** interp pointer to use when evaluating the TCL script is stored in 10994e6af134Sdanielk1977 ** pTestCollateInterp. 11004e6af134Sdanielk1977 */ 11014e6af134Sdanielk1977 static Tcl_Interp* pTestCollateInterp; 11024e6af134Sdanielk1977 static int test_collate_func( 11034e6af134Sdanielk1977 void *pCtx, 11044e6af134Sdanielk1977 int nA, const void *zA, 11054e6af134Sdanielk1977 int nB, const void *zB 11064e6af134Sdanielk1977 ){ 11074e6af134Sdanielk1977 Tcl_Interp *i = pTestCollateInterp; 11084e6af134Sdanielk1977 int encin = (int)pCtx; 11094e6af134Sdanielk1977 int res; 11104e6af134Sdanielk1977 11114e6af134Sdanielk1977 sqlite3_value *pVal; 11124e6af134Sdanielk1977 Tcl_Obj *pX; 11134e6af134Sdanielk1977 11144e6af134Sdanielk1977 pX = Tcl_NewStringObj("test_collate", -1); 11154e6af134Sdanielk1977 Tcl_IncrRefCount(pX); 11164e6af134Sdanielk1977 11174e6af134Sdanielk1977 switch( encin ){ 11184e6af134Sdanielk1977 case SQLITE_UTF8: 11194e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-8",-1)); 11204e6af134Sdanielk1977 break; 11214e6af134Sdanielk1977 case SQLITE_UTF16LE: 11224e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16LE",-1)); 11234e6af134Sdanielk1977 break; 11244e6af134Sdanielk1977 case SQLITE_UTF16BE: 11254e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16BE",-1)); 11264e6af134Sdanielk1977 break; 11274e6af134Sdanielk1977 default: 11284e6af134Sdanielk1977 assert(0); 11294e6af134Sdanielk1977 } 11304e6af134Sdanielk1977 11314e6af134Sdanielk1977 pVal = sqlite3ValueNew(); 1132bfd6cce5Sdanielk1977 sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC); 11334e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj(sqlite3_value_text(pVal),-1)); 1134bfd6cce5Sdanielk1977 sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC); 11354e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj(sqlite3_value_text(pVal),-1)); 11364e6af134Sdanielk1977 sqlite3ValueFree(pVal); 11374e6af134Sdanielk1977 11384e6af134Sdanielk1977 Tcl_EvalObjEx(i, pX, 0); 11394e6af134Sdanielk1977 Tcl_DecrRefCount(pX); 11404e6af134Sdanielk1977 Tcl_GetIntFromObj(i, Tcl_GetObjResult(i), &res); 11414e6af134Sdanielk1977 return res; 11424e6af134Sdanielk1977 } 11434e6af134Sdanielk1977 static int test_collate( 11444e6af134Sdanielk1977 void * clientData, 11454e6af134Sdanielk1977 Tcl_Interp *interp, 11464e6af134Sdanielk1977 int objc, 11474e6af134Sdanielk1977 Tcl_Obj *CONST objv[] 11484e6af134Sdanielk1977 ){ 11494e6af134Sdanielk1977 sqlite3 *db; 11504e6af134Sdanielk1977 int val; 1151312d6b36Sdanielk1977 sqlite3_value *pVal; 1152c60d0446Sdrh int rc; 11534e6af134Sdanielk1977 11544e6af134Sdanielk1977 if( objc!=5 ) goto bad_args; 11554e6af134Sdanielk1977 pTestCollateInterp = interp; 11564e6af134Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 11574e6af134Sdanielk1977 11584e6af134Sdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; 1159c60d0446Sdrh rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8, 11604e6af134Sdanielk1977 (void *)SQLITE_UTF8, val?test_collate_func:0); 1161c60d0446Sdrh if( rc==SQLITE_OK ){ 11624e6af134Sdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; 1163c60d0446Sdrh rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE, 11644e6af134Sdanielk1977 (void *)SQLITE_UTF16LE, val?test_collate_func:0); 11654e6af134Sdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR; 1166312d6b36Sdanielk1977 1167312d6b36Sdanielk1977 pVal = sqlite3ValueNew(); 1168312d6b36Sdanielk1977 sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC); 1169312d6b36Sdanielk1977 sqlite3_create_collation16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), 1170312d6b36Sdanielk1977 SQLITE_UTF16BE, (void *)SQLITE_UTF16BE, val?test_collate_func:0); 1171312d6b36Sdanielk1977 sqlite3ValueFree(pVal); 1172c60d0446Sdrh } 1173c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 11744e6af134Sdanielk1977 return TCL_OK; 11754e6af134Sdanielk1977 11764e6af134Sdanielk1977 bad_args: 11774e6af134Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 11784e6af134Sdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); 11794e6af134Sdanielk1977 return TCL_ERROR; 11804e6af134Sdanielk1977 } 11814e6af134Sdanielk1977 1182312d6b36Sdanielk1977 static void test_collate_needed_cb( 1183312d6b36Sdanielk1977 void *pCtx, 1184312d6b36Sdanielk1977 sqlite3 *db, 1185312d6b36Sdanielk1977 int eTextRep, 1186312d6b36Sdanielk1977 const void *notUsed 1187312d6b36Sdanielk1977 ){ 1188312d6b36Sdanielk1977 int enc = db->enc; 1189312d6b36Sdanielk1977 sqlite3_create_collation( 1190312d6b36Sdanielk1977 db, "test_collate", db->enc, (void *)enc, test_collate_func); 1191312d6b36Sdanielk1977 } 1192312d6b36Sdanielk1977 1193312d6b36Sdanielk1977 /* 1194312d6b36Sdanielk1977 ** Usage: add_test_collate_needed DB 1195312d6b36Sdanielk1977 */ 1196312d6b36Sdanielk1977 static int test_collate_needed( 1197312d6b36Sdanielk1977 void * clientData, 1198312d6b36Sdanielk1977 Tcl_Interp *interp, 1199312d6b36Sdanielk1977 int objc, 1200312d6b36Sdanielk1977 Tcl_Obj *CONST objv[] 1201312d6b36Sdanielk1977 ){ 1202312d6b36Sdanielk1977 sqlite3 *db; 1203c60d0446Sdrh int rc; 1204312d6b36Sdanielk1977 1205312d6b36Sdanielk1977 if( objc!=2 ) goto bad_args; 1206312d6b36Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1207c60d0446Sdrh rc = sqlite3_collation_needed16(db, 0, test_collate_needed_cb); 1208c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1209312d6b36Sdanielk1977 return TCL_OK; 1210312d6b36Sdanielk1977 1211312d6b36Sdanielk1977 bad_args: 1212312d6b36Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "DB"); 1213312d6b36Sdanielk1977 return TCL_ERROR; 1214312d6b36Sdanielk1977 } 12155436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 1216312d6b36Sdanielk1977 1217c8e9a2dfSdanielk1977 /* 1218c8e9a2dfSdanielk1977 ** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be> 1219c8e9a2dfSdanielk1977 ** 1220c8e9a2dfSdanielk1977 ** This function is used to test that SQLite selects the correct user 1221c8e9a2dfSdanielk1977 ** function callback when multiple versions (for different text encodings) 1222c8e9a2dfSdanielk1977 ** are available. 1223c8e9a2dfSdanielk1977 ** 1224c8e9a2dfSdanielk1977 ** Calling this routine registers up to three versions of the user function 1225c8e9a2dfSdanielk1977 ** "test_function" with database handle <db>. If the second argument is 1226c8e9a2dfSdanielk1977 ** true, then a version of test_function is registered for UTF-8, if the 1227c8e9a2dfSdanielk1977 ** third is true, a version is registered for UTF-16le, if the fourth is 1228c8e9a2dfSdanielk1977 ** true, a UTF-16be version is available. Previous versions of 1229c8e9a2dfSdanielk1977 ** test_function are deleted. 1230c8e9a2dfSdanielk1977 ** 1231c8e9a2dfSdanielk1977 ** The user function is implemented by calling the following TCL script: 1232c8e9a2dfSdanielk1977 ** 1233c8e9a2dfSdanielk1977 ** "test_function <enc> <arg>" 1234c8e9a2dfSdanielk1977 ** 1235c8e9a2dfSdanielk1977 ** Where <enc> is one of UTF-8, UTF-16LE or UTF16BE, and <arg> is the 1236c8e9a2dfSdanielk1977 ** single argument passed to the SQL function. The value returned by 1237c8e9a2dfSdanielk1977 ** the TCL script is used as the return value of the SQL function. It 1238c8e9a2dfSdanielk1977 ** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8 1239c8e9a2dfSdanielk1977 ** for a UTF-16LE test_function(), and UTF-16LE for an implementation that 1240c8e9a2dfSdanielk1977 ** prefers UTF-16BE. 1241c8e9a2dfSdanielk1977 */ 12425436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 1243c8e9a2dfSdanielk1977 static void test_function_utf8( 1244c8e9a2dfSdanielk1977 sqlite3_context *pCtx, 1245c8e9a2dfSdanielk1977 int nArg, 1246c8e9a2dfSdanielk1977 sqlite3_value **argv 1247c8e9a2dfSdanielk1977 ){ 1248c8e9a2dfSdanielk1977 Tcl_Interp *interp; 1249c8e9a2dfSdanielk1977 Tcl_Obj *pX; 1250c8e9a2dfSdanielk1977 sqlite3_value *pVal; 1251c8e9a2dfSdanielk1977 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1252c8e9a2dfSdanielk1977 pX = Tcl_NewStringObj("test_function", -1); 1253c8e9a2dfSdanielk1977 Tcl_IncrRefCount(pX); 1254c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-8", -1)); 1255c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, 1256c8e9a2dfSdanielk1977 Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); 1257c8e9a2dfSdanielk1977 Tcl_EvalObjEx(interp, pX, 0); 1258c8e9a2dfSdanielk1977 Tcl_DecrRefCount(pX); 1259c8e9a2dfSdanielk1977 sqlite3_result_text(pCtx, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT); 1260c8e9a2dfSdanielk1977 pVal = sqlite3ValueNew(); 1261c8e9a2dfSdanielk1977 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1262c8e9a2dfSdanielk1977 SQLITE_UTF8, SQLITE_STATIC); 1263c8e9a2dfSdanielk1977 sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal), 1264c8e9a2dfSdanielk1977 -1, SQLITE_TRANSIENT); 1265c8e9a2dfSdanielk1977 sqlite3ValueFree(pVal); 1266c8e9a2dfSdanielk1977 } 1267c8e9a2dfSdanielk1977 static void test_function_utf16le( 1268c8e9a2dfSdanielk1977 sqlite3_context *pCtx, 1269c8e9a2dfSdanielk1977 int nArg, 1270c8e9a2dfSdanielk1977 sqlite3_value **argv 1271c8e9a2dfSdanielk1977 ){ 1272c8e9a2dfSdanielk1977 Tcl_Interp *interp; 1273c8e9a2dfSdanielk1977 Tcl_Obj *pX; 1274c8e9a2dfSdanielk1977 sqlite3_value *pVal; 1275c8e9a2dfSdanielk1977 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1276c8e9a2dfSdanielk1977 pX = Tcl_NewStringObj("test_function", -1); 1277c8e9a2dfSdanielk1977 Tcl_IncrRefCount(pX); 1278c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16LE", -1)); 1279c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, 1280c8e9a2dfSdanielk1977 Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); 1281c8e9a2dfSdanielk1977 Tcl_EvalObjEx(interp, pX, 0); 1282c8e9a2dfSdanielk1977 Tcl_DecrRefCount(pX); 1283c8e9a2dfSdanielk1977 pVal = sqlite3ValueNew(); 1284c8e9a2dfSdanielk1977 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1285c8e9a2dfSdanielk1977 SQLITE_UTF8, SQLITE_STATIC); 1286c8e9a2dfSdanielk1977 sqlite3_result_text(pCtx,sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT); 1287c8e9a2dfSdanielk1977 sqlite3ValueFree(pVal); 1288c8e9a2dfSdanielk1977 } 1289c8e9a2dfSdanielk1977 static void test_function_utf16be( 1290c8e9a2dfSdanielk1977 sqlite3_context *pCtx, 1291c8e9a2dfSdanielk1977 int nArg, 1292c8e9a2dfSdanielk1977 sqlite3_value **argv 1293c8e9a2dfSdanielk1977 ){ 1294c8e9a2dfSdanielk1977 Tcl_Interp *interp; 1295c8e9a2dfSdanielk1977 Tcl_Obj *pX; 1296c8e9a2dfSdanielk1977 sqlite3_value *pVal; 1297c8e9a2dfSdanielk1977 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1298c8e9a2dfSdanielk1977 pX = Tcl_NewStringObj("test_function", -1); 1299c8e9a2dfSdanielk1977 Tcl_IncrRefCount(pX); 1300c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16BE", -1)); 1301c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, 1302c8e9a2dfSdanielk1977 Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); 1303c8e9a2dfSdanielk1977 Tcl_EvalObjEx(interp, pX, 0); 1304c8e9a2dfSdanielk1977 Tcl_DecrRefCount(pX); 1305c8e9a2dfSdanielk1977 pVal = sqlite3ValueNew(); 1306c8e9a2dfSdanielk1977 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1307c8e9a2dfSdanielk1977 SQLITE_UTF8, SQLITE_STATIC); 1308c8e9a2dfSdanielk1977 sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal), 1309c8e9a2dfSdanielk1977 -1, SQLITE_TRANSIENT); 1310c8e9a2dfSdanielk1977 sqlite3ValueFree(pVal); 1311c8e9a2dfSdanielk1977 } 13125436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 1313c8e9a2dfSdanielk1977 static int test_function( 1314c8e9a2dfSdanielk1977 void * clientData, 1315c8e9a2dfSdanielk1977 Tcl_Interp *interp, 1316c8e9a2dfSdanielk1977 int objc, 1317c8e9a2dfSdanielk1977 Tcl_Obj *CONST objv[] 1318c8e9a2dfSdanielk1977 ){ 13195436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 1320c8e9a2dfSdanielk1977 sqlite3 *db; 1321c8e9a2dfSdanielk1977 int val; 1322c8e9a2dfSdanielk1977 1323c8e9a2dfSdanielk1977 if( objc!=5 ) goto bad_args; 1324c8e9a2dfSdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1325c8e9a2dfSdanielk1977 1326c8e9a2dfSdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; 1327c8e9a2dfSdanielk1977 if( val ){ 1328c8e9a2dfSdanielk1977 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF8, 1329c8e9a2dfSdanielk1977 interp, test_function_utf8, 0, 0); 1330c8e9a2dfSdanielk1977 } 1331c8e9a2dfSdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; 1332c8e9a2dfSdanielk1977 if( val ){ 1333c8e9a2dfSdanielk1977 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16LE, 1334c8e9a2dfSdanielk1977 interp, test_function_utf16le, 0, 0); 1335c8e9a2dfSdanielk1977 } 1336c8e9a2dfSdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR; 1337c8e9a2dfSdanielk1977 if( val ){ 1338c8e9a2dfSdanielk1977 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16BE, 1339c8e9a2dfSdanielk1977 interp, test_function_utf16be, 0, 0); 1340c8e9a2dfSdanielk1977 } 1341c8e9a2dfSdanielk1977 1342c8e9a2dfSdanielk1977 return TCL_OK; 1343c8e9a2dfSdanielk1977 bad_args: 1344c8e9a2dfSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1345c8e9a2dfSdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); 13465436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 1347c8e9a2dfSdanielk1977 return TCL_ERROR; 1348c8e9a2dfSdanielk1977 } 1349c8e9a2dfSdanielk1977 1350312d6b36Sdanielk1977 /* 1351312d6b36Sdanielk1977 ** Usage: test_errstr <err code> 1352312d6b36Sdanielk1977 ** 1353312d6b36Sdanielk1977 ** Test that the english language string equivalents for sqlite error codes 1354312d6b36Sdanielk1977 ** are sane. The parameter is an integer representing an sqlite error code. 1355312d6b36Sdanielk1977 ** The result is a list of two elements, the string representation of the 1356312d6b36Sdanielk1977 ** error code and the english language explanation. 1357312d6b36Sdanielk1977 */ 1358312d6b36Sdanielk1977 static int test_errstr( 1359312d6b36Sdanielk1977 void * clientData, 1360312d6b36Sdanielk1977 Tcl_Interp *interp, 1361312d6b36Sdanielk1977 int objc, 1362312d6b36Sdanielk1977 Tcl_Obj *CONST objv[] 1363312d6b36Sdanielk1977 ){ 1364312d6b36Sdanielk1977 char *zCode; 1365312d6b36Sdanielk1977 int i; 1366312d6b36Sdanielk1977 if( objc!=1 ){ 1367312d6b36Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "<error code>"); 1368312d6b36Sdanielk1977 } 1369312d6b36Sdanielk1977 1370312d6b36Sdanielk1977 zCode = Tcl_GetString(objv[1]); 1371312d6b36Sdanielk1977 for(i=0; i<200; i++){ 1372312d6b36Sdanielk1977 if( 0==strcmp(errorName(i), zCode) ) break; 1373312d6b36Sdanielk1977 } 1374312d6b36Sdanielk1977 Tcl_SetResult(interp, (char *)sqlite3ErrStr(i), 0); 1375312d6b36Sdanielk1977 return TCL_OK; 1376312d6b36Sdanielk1977 } 1377312d6b36Sdanielk1977 1378c8e9a2dfSdanielk1977 static int sqlite3_crashparams( 13798a6c550dSdanielk1977 void * clientData, 13808a6c550dSdanielk1977 Tcl_Interp *interp, 13818a6c550dSdanielk1977 int objc, 13828a6c550dSdanielk1977 Tcl_Obj *CONST objv[] 13838a6c550dSdanielk1977 ){ 13848a6c550dSdanielk1977 #ifdef OS_TEST 1385c8e9a2dfSdanielk1977 int delay; 1386c8e9a2dfSdanielk1977 if( objc!=3 ) goto bad_args; 1387c8e9a2dfSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[1], &delay) ) return TCL_ERROR; 1388c8e9a2dfSdanielk1977 sqlite3SetCrashParams(delay, Tcl_GetString(objv[2])); 13898a6c550dSdanielk1977 #endif 13908a6c550dSdanielk1977 return TCL_OK; 13918a6c550dSdanielk1977 1392241db313Sdrh #ifdef OS_TEST 13938a6c550dSdanielk1977 bad_args: 13948a6c550dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1395c8e9a2dfSdanielk1977 Tcl_GetStringFromObj(objv[0], 0), "<delay> <filename>", 0); 13968a6c550dSdanielk1977 return TCL_ERROR; 1397241db313Sdrh #endif 13988a6c550dSdanielk1977 } 13998a6c550dSdanielk1977 14008a6c550dSdanielk1977 140150457896Sdrh /* 140299ee3600Sdrh ** Usage: breakpoint 140399ee3600Sdrh ** 140499ee3600Sdrh ** This routine exists for one purpose - to provide a place to put a 140599ee3600Sdrh ** breakpoint with GDB that can be triggered using TCL code. The use 140699ee3600Sdrh ** for this is when a particular test fails on (say) the 1485th iteration. 140799ee3600Sdrh ** In the TCL test script, we can add code like this: 140899ee3600Sdrh ** 140999ee3600Sdrh ** if {$i==1485} breakpoint 141099ee3600Sdrh ** 141199ee3600Sdrh ** Then run testfixture in the debugger and wait for the breakpoint to 141299ee3600Sdrh ** fire. Then additional breakpoints can be set to trace down the bug. 141399ee3600Sdrh */ 141499ee3600Sdrh static int test_breakpoint( 141599ee3600Sdrh void *NotUsed, 141699ee3600Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 141799ee3600Sdrh int argc, /* Number of arguments */ 141899ee3600Sdrh char **argv /* Text of each argument */ 141999ee3600Sdrh ){ 142099ee3600Sdrh return TCL_OK; /* Do nothing */ 142199ee3600Sdrh } 142299ee3600Sdrh 1423241db313Sdrh /* 1424241db313Sdrh ** Usage: sqlite3_bind_int STMT N VALUE 1425241db313Sdrh ** 1426241db313Sdrh ** Test the sqlite3_bind_int interface. STMT is a prepared statement. 1427241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1428241db313Sdrh ** binds a 32-bit integer VALUE to that wildcard. 1429241db313Sdrh */ 1430241db313Sdrh static int test_bind_int( 143151e3d8e2Sdanielk1977 void * clientData, 143251e3d8e2Sdanielk1977 Tcl_Interp *interp, 143351e3d8e2Sdanielk1977 int objc, 143451e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 143551e3d8e2Sdanielk1977 ){ 143651e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 143751e3d8e2Sdanielk1977 int idx; 143851e3d8e2Sdanielk1977 int value; 143951e3d8e2Sdanielk1977 int rc; 144051e3d8e2Sdanielk1977 144151e3d8e2Sdanielk1977 if( objc!=4 ){ 144251e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1443241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 144451e3d8e2Sdanielk1977 return TCL_ERROR; 144551e3d8e2Sdanielk1977 } 144651e3d8e2Sdanielk1977 144751e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 144851e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 144951e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR; 145051e3d8e2Sdanielk1977 1451c572ef7fSdanielk1977 rc = sqlite3_bind_int(pStmt, idx, value); 1452c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 145351e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 145451e3d8e2Sdanielk1977 return TCL_ERROR; 145551e3d8e2Sdanielk1977 } 145651e3d8e2Sdanielk1977 145751e3d8e2Sdanielk1977 return TCL_OK; 145851e3d8e2Sdanielk1977 } 145951e3d8e2Sdanielk1977 1460241db313Sdrh 1461241db313Sdrh /* 1462241db313Sdrh ** Usage: sqlite3_bind_int64 STMT N VALUE 1463241db313Sdrh ** 1464241db313Sdrh ** Test the sqlite3_bind_int64 interface. STMT is a prepared statement. 1465241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1466241db313Sdrh ** binds a 64-bit integer VALUE to that wildcard. 1467241db313Sdrh */ 146851e3d8e2Sdanielk1977 static int test_bind_int64( 146951e3d8e2Sdanielk1977 void * clientData, 147051e3d8e2Sdanielk1977 Tcl_Interp *interp, 147151e3d8e2Sdanielk1977 int objc, 147251e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 147351e3d8e2Sdanielk1977 ){ 147451e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 147551e3d8e2Sdanielk1977 int idx; 147651e3d8e2Sdanielk1977 i64 value; 147751e3d8e2Sdanielk1977 int rc; 147851e3d8e2Sdanielk1977 147951e3d8e2Sdanielk1977 if( objc!=4 ){ 148051e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1481241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 148251e3d8e2Sdanielk1977 return TCL_ERROR; 148351e3d8e2Sdanielk1977 } 148451e3d8e2Sdanielk1977 148551e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 148651e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 148751e3d8e2Sdanielk1977 if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR; 148851e3d8e2Sdanielk1977 148951e3d8e2Sdanielk1977 rc = sqlite3_bind_int64(pStmt, idx, value); 1490c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 149151e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 149251e3d8e2Sdanielk1977 return TCL_ERROR; 149351e3d8e2Sdanielk1977 } 149451e3d8e2Sdanielk1977 149551e3d8e2Sdanielk1977 return TCL_OK; 149651e3d8e2Sdanielk1977 } 149751e3d8e2Sdanielk1977 1498241db313Sdrh 1499241db313Sdrh /* 1500241db313Sdrh ** Usage: sqlite3_bind_double STMT N VALUE 1501241db313Sdrh ** 1502241db313Sdrh ** Test the sqlite3_bind_double interface. STMT is a prepared statement. 1503241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1504241db313Sdrh ** binds a 64-bit integer VALUE to that wildcard. 1505241db313Sdrh */ 150651e3d8e2Sdanielk1977 static int test_bind_double( 150751e3d8e2Sdanielk1977 void * clientData, 150851e3d8e2Sdanielk1977 Tcl_Interp *interp, 150951e3d8e2Sdanielk1977 int objc, 151051e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 151151e3d8e2Sdanielk1977 ){ 151251e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 151351e3d8e2Sdanielk1977 int idx; 151451e3d8e2Sdanielk1977 double value; 151551e3d8e2Sdanielk1977 int rc; 151651e3d8e2Sdanielk1977 151751e3d8e2Sdanielk1977 if( objc!=4 ){ 151851e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1519241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 152051e3d8e2Sdanielk1977 return TCL_ERROR; 152151e3d8e2Sdanielk1977 } 152251e3d8e2Sdanielk1977 152351e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 152451e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 152551e3d8e2Sdanielk1977 if( Tcl_GetDoubleFromObj(interp, objv[3], &value) ) return TCL_ERROR; 152651e3d8e2Sdanielk1977 152751e3d8e2Sdanielk1977 rc = sqlite3_bind_double(pStmt, idx, value); 1528c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 152951e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 153051e3d8e2Sdanielk1977 return TCL_ERROR; 153151e3d8e2Sdanielk1977 } 153251e3d8e2Sdanielk1977 153351e3d8e2Sdanielk1977 return TCL_OK; 153451e3d8e2Sdanielk1977 } 153551e3d8e2Sdanielk1977 1536241db313Sdrh /* 1537241db313Sdrh ** Usage: sqlite3_bind_null STMT N 1538241db313Sdrh ** 1539241db313Sdrh ** Test the sqlite3_bind_null interface. STMT is a prepared statement. 1540241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1541241db313Sdrh ** binds a NULL to the wildcard. 1542241db313Sdrh */ 154351e3d8e2Sdanielk1977 static int test_bind_null( 154451e3d8e2Sdanielk1977 void * clientData, 154551e3d8e2Sdanielk1977 Tcl_Interp *interp, 154651e3d8e2Sdanielk1977 int objc, 154751e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 154851e3d8e2Sdanielk1977 ){ 154951e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 155051e3d8e2Sdanielk1977 int idx; 155151e3d8e2Sdanielk1977 int rc; 155251e3d8e2Sdanielk1977 155351e3d8e2Sdanielk1977 if( objc!=3 ){ 155451e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1555241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N", 0); 155651e3d8e2Sdanielk1977 return TCL_ERROR; 155751e3d8e2Sdanielk1977 } 155851e3d8e2Sdanielk1977 155951e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 156051e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 156151e3d8e2Sdanielk1977 156251e3d8e2Sdanielk1977 rc = sqlite3_bind_null(pStmt, idx); 1563c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 156451e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 156551e3d8e2Sdanielk1977 return TCL_ERROR; 156651e3d8e2Sdanielk1977 } 156751e3d8e2Sdanielk1977 156851e3d8e2Sdanielk1977 return TCL_OK; 156951e3d8e2Sdanielk1977 } 157051e3d8e2Sdanielk1977 1571241db313Sdrh /* 1572241db313Sdrh ** Usage: sqlite3_bind_text STMT N STRING BYTES 1573241db313Sdrh ** 1574241db313Sdrh ** Test the sqlite3_bind_text interface. STMT is a prepared statement. 1575241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1576241db313Sdrh ** binds a UTF-8 string STRING to the wildcard. The string is BYTES bytes 1577241db313Sdrh ** long. 1578241db313Sdrh */ 157951e3d8e2Sdanielk1977 static int test_bind_text( 158051e3d8e2Sdanielk1977 void * clientData, 158151e3d8e2Sdanielk1977 Tcl_Interp *interp, 158251e3d8e2Sdanielk1977 int objc, 158351e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 158451e3d8e2Sdanielk1977 ){ 158551e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 158651e3d8e2Sdanielk1977 int idx; 158751e3d8e2Sdanielk1977 int bytes; 158851e3d8e2Sdanielk1977 char *value; 158951e3d8e2Sdanielk1977 int rc; 159051e3d8e2Sdanielk1977 159151e3d8e2Sdanielk1977 if( objc!=5 ){ 159251e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1593241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0); 159451e3d8e2Sdanielk1977 return TCL_ERROR; 159551e3d8e2Sdanielk1977 } 159651e3d8e2Sdanielk1977 159751e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 159851e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 159951e3d8e2Sdanielk1977 value = Tcl_GetString(objv[3]); 160051e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 160151e3d8e2Sdanielk1977 1602d8123366Sdanielk1977 rc = sqlite3_bind_text(pStmt, idx, value, bytes, SQLITE_TRANSIENT); 1603c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 160451e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 1605473d179dSdrh Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0); 160651e3d8e2Sdanielk1977 return TCL_ERROR; 160751e3d8e2Sdanielk1977 } 160851e3d8e2Sdanielk1977 160951e3d8e2Sdanielk1977 return TCL_OK; 161051e3d8e2Sdanielk1977 } 161151e3d8e2Sdanielk1977 1612241db313Sdrh /* 1613241db313Sdrh ** Usage: sqlite3_bind_text16 STMT N STRING BYTES 1614241db313Sdrh ** 1615241db313Sdrh ** Test the sqlite3_bind_text16 interface. STMT is a prepared statement. 1616241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1617241db313Sdrh ** binds a UTF-16 string STRING to the wildcard. The string is BYTES bytes 1618241db313Sdrh ** long. 1619241db313Sdrh */ 162051e3d8e2Sdanielk1977 static int test_bind_text16( 162151e3d8e2Sdanielk1977 void * clientData, 162251e3d8e2Sdanielk1977 Tcl_Interp *interp, 162351e3d8e2Sdanielk1977 int objc, 162451e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 162551e3d8e2Sdanielk1977 ){ 16265436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 162751e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 162851e3d8e2Sdanielk1977 int idx; 162951e3d8e2Sdanielk1977 int bytes; 163051e3d8e2Sdanielk1977 char *value; 163151e3d8e2Sdanielk1977 int rc; 163251e3d8e2Sdanielk1977 163351e3d8e2Sdanielk1977 if( objc!=5 ){ 163451e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1635241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0); 163651e3d8e2Sdanielk1977 return TCL_ERROR; 163751e3d8e2Sdanielk1977 } 163851e3d8e2Sdanielk1977 163951e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 164051e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 164151e3d8e2Sdanielk1977 value = Tcl_GetByteArrayFromObj(objv[3], 0); 164251e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 164351e3d8e2Sdanielk1977 1644d8123366Sdanielk1977 rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, SQLITE_TRANSIENT); 1645c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 164651e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 164751e3d8e2Sdanielk1977 return TCL_ERROR; 164851e3d8e2Sdanielk1977 } 164951e3d8e2Sdanielk1977 16505436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 165151e3d8e2Sdanielk1977 return TCL_OK; 165251e3d8e2Sdanielk1977 } 165351e3d8e2Sdanielk1977 1654241db313Sdrh /* 1655241db313Sdrh ** Usage: sqlite3_bind_blob STMT N DATA BYTES 1656241db313Sdrh ** 1657241db313Sdrh ** Test the sqlite3_bind_blob interface. STMT is a prepared statement. 1658241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1659241db313Sdrh ** binds a BLOB to the wildcard. The BLOB is BYTES bytes in size. 1660241db313Sdrh */ 166151e3d8e2Sdanielk1977 static int test_bind_blob( 166251e3d8e2Sdanielk1977 void * clientData, 166351e3d8e2Sdanielk1977 Tcl_Interp *interp, 166451e3d8e2Sdanielk1977 int objc, 166551e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 166651e3d8e2Sdanielk1977 ){ 166751e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 166851e3d8e2Sdanielk1977 int idx; 166951e3d8e2Sdanielk1977 int bytes; 167051e3d8e2Sdanielk1977 char *value; 167151e3d8e2Sdanielk1977 int rc; 167251e3d8e2Sdanielk1977 167351e3d8e2Sdanielk1977 if( objc!=5 ){ 167451e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1675241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N DATA BYTES", 0); 167651e3d8e2Sdanielk1977 return TCL_ERROR; 167751e3d8e2Sdanielk1977 } 167851e3d8e2Sdanielk1977 167951e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 168051e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 168151e3d8e2Sdanielk1977 value = Tcl_GetString(objv[3]); 168249e4643eSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 168351e3d8e2Sdanielk1977 1684d8123366Sdanielk1977 rc = sqlite3_bind_blob(pStmt, idx, value, bytes, SQLITE_TRANSIENT); 1685c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 168651e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 168751e3d8e2Sdanielk1977 return TCL_ERROR; 168851e3d8e2Sdanielk1977 } 168951e3d8e2Sdanielk1977 169051e3d8e2Sdanielk1977 return TCL_OK; 169151e3d8e2Sdanielk1977 } 169251e3d8e2Sdanielk1977 169399ee3600Sdrh /* 169475f6a032Sdrh ** Usage: sqlite3_bind_parameter_count STMT 169575f6a032Sdrh ** 169675f6a032Sdrh ** Return the number of wildcards in the given statement. 169775f6a032Sdrh */ 169875f6a032Sdrh static int test_bind_parameter_count( 169975f6a032Sdrh void * clientData, 170075f6a032Sdrh Tcl_Interp *interp, 170175f6a032Sdrh int objc, 170275f6a032Sdrh Tcl_Obj *CONST objv[] 170375f6a032Sdrh ){ 170475f6a032Sdrh sqlite3_stmt *pStmt; 170575f6a032Sdrh 170675f6a032Sdrh if( objc!=2 ){ 170775f6a032Sdrh Tcl_WrongNumArgs(interp, 1, objv, "STMT"); 170875f6a032Sdrh return TCL_ERROR; 170975f6a032Sdrh } 171075f6a032Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 171175f6a032Sdrh Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_bind_parameter_count(pStmt))); 171275f6a032Sdrh return TCL_OK; 171375f6a032Sdrh } 171475f6a032Sdrh 171575f6a032Sdrh /* 1716895d7472Sdrh ** Usage: sqlite3_bind_parameter_name STMT N 1717895d7472Sdrh ** 1718895d7472Sdrh ** Return the name of the Nth wildcard. The first wildcard is 1. 1719895d7472Sdrh ** An empty string is returned if N is out of range or if the wildcard 1720895d7472Sdrh ** is nameless. 1721895d7472Sdrh */ 1722895d7472Sdrh static int test_bind_parameter_name( 1723895d7472Sdrh void * clientData, 1724895d7472Sdrh Tcl_Interp *interp, 1725895d7472Sdrh int objc, 1726895d7472Sdrh Tcl_Obj *CONST objv[] 1727895d7472Sdrh ){ 1728895d7472Sdrh sqlite3_stmt *pStmt; 1729895d7472Sdrh int i; 1730895d7472Sdrh 1731895d7472Sdrh if( objc!=3 ){ 1732895d7472Sdrh Tcl_WrongNumArgs(interp, 1, objv, "STMT N"); 1733895d7472Sdrh return TCL_ERROR; 1734895d7472Sdrh } 1735895d7472Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1736895d7472Sdrh if( Tcl_GetIntFromObj(interp, objv[2], &i) ) return TCL_ERROR; 1737895d7472Sdrh Tcl_SetObjResult(interp, 1738895d7472Sdrh Tcl_NewStringObj(sqlite3_bind_parameter_name(pStmt,i),-1) 1739895d7472Sdrh ); 1740895d7472Sdrh return TCL_OK; 1741895d7472Sdrh } 1742895d7472Sdrh 1743895d7472Sdrh /* 1744fa6bc000Sdrh ** Usage: sqlite3_bind_parameter_index STMT NAME 1745fa6bc000Sdrh ** 1746fa6bc000Sdrh ** Return the index of the wildcard called NAME. Return 0 if there is 1747fa6bc000Sdrh ** no such wildcard. 1748fa6bc000Sdrh */ 1749fa6bc000Sdrh static int test_bind_parameter_index( 1750fa6bc000Sdrh void * clientData, 1751fa6bc000Sdrh Tcl_Interp *interp, 1752fa6bc000Sdrh int objc, 1753fa6bc000Sdrh Tcl_Obj *CONST objv[] 1754fa6bc000Sdrh ){ 1755fa6bc000Sdrh sqlite3_stmt *pStmt; 1756fa6bc000Sdrh 1757fa6bc000Sdrh if( objc!=3 ){ 1758fa6bc000Sdrh Tcl_WrongNumArgs(interp, 1, objv, "STMT NAME"); 1759fa6bc000Sdrh return TCL_ERROR; 1760fa6bc000Sdrh } 1761fa6bc000Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1762fa6bc000Sdrh Tcl_SetObjResult(interp, 1763fa6bc000Sdrh Tcl_NewIntObj( 1764fa6bc000Sdrh sqlite3_bind_parameter_index(pStmt,Tcl_GetString(objv[2])) 1765fa6bc000Sdrh ) 1766fa6bc000Sdrh ); 1767fa6bc000Sdrh return TCL_OK; 1768fa6bc000Sdrh } 1769fa6bc000Sdrh 1770fa6bc000Sdrh /* 1771600dd0baSdanielk1977 ** Usage: sqlite3_clear_bindings STMT 1772600dd0baSdanielk1977 ** 1773600dd0baSdanielk1977 */ 1774600dd0baSdanielk1977 #if 0 1775600dd0baSdanielk1977 static int test_clear_bindings( 1776600dd0baSdanielk1977 void * clientData, 1777600dd0baSdanielk1977 Tcl_Interp *interp, 1778600dd0baSdanielk1977 int objc, 1779600dd0baSdanielk1977 Tcl_Obj *CONST objv[] 1780600dd0baSdanielk1977 ){ 1781600dd0baSdanielk1977 sqlite3_stmt *pStmt; 1782600dd0baSdanielk1977 1783600dd0baSdanielk1977 if( objc!=2 ){ 1784600dd0baSdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "STMT"); 1785600dd0baSdanielk1977 return TCL_ERROR; 1786600dd0baSdanielk1977 } 1787600dd0baSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1788600dd0baSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(pStmt))); 1789600dd0baSdanielk1977 return TCL_OK; 1790600dd0baSdanielk1977 } 1791600dd0baSdanielk1977 #endif 1792600dd0baSdanielk1977 1793600dd0baSdanielk1977 /* 17946622cce3Sdanielk1977 ** Usage: sqlite3_errcode DB 17956622cce3Sdanielk1977 ** 17966622cce3Sdanielk1977 ** Return the string representation of the most recent sqlite3_* API 17976622cce3Sdanielk1977 ** error code. e.g. "SQLITE_ERROR". 17986622cce3Sdanielk1977 */ 17996622cce3Sdanielk1977 static int test_errcode( 18006622cce3Sdanielk1977 void * clientData, 18016622cce3Sdanielk1977 Tcl_Interp *interp, 18026622cce3Sdanielk1977 int objc, 18036622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 18046622cce3Sdanielk1977 ){ 18056622cce3Sdanielk1977 sqlite3 *db; 18066622cce3Sdanielk1977 18076622cce3Sdanielk1977 if( objc!=2 ){ 18086622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 18096622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 18106622cce3Sdanielk1977 return TCL_ERROR; 18116622cce3Sdanielk1977 } 18126622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 18136622cce3Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(sqlite3_errcode(db)), 0); 18146622cce3Sdanielk1977 return TCL_OK; 18156622cce3Sdanielk1977 } 18166622cce3Sdanielk1977 18176622cce3Sdanielk1977 /* 18186622cce3Sdanielk1977 ** Usage: test_errmsg DB 18196622cce3Sdanielk1977 ** 18206622cce3Sdanielk1977 ** Returns the UTF-8 representation of the error message string for the 18216622cce3Sdanielk1977 ** most recent sqlite3_* API call. 18226622cce3Sdanielk1977 */ 18236622cce3Sdanielk1977 static int test_errmsg( 18246622cce3Sdanielk1977 void * clientData, 18256622cce3Sdanielk1977 Tcl_Interp *interp, 18266622cce3Sdanielk1977 int objc, 18276622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 18286622cce3Sdanielk1977 ){ 18299bb575fdSdrh sqlite3 *db; 18306622cce3Sdanielk1977 const char *zErr; 18316622cce3Sdanielk1977 18326622cce3Sdanielk1977 if( objc!=2 ){ 18336622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 18346622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 18356622cce3Sdanielk1977 return TCL_ERROR; 18366622cce3Sdanielk1977 } 18376622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 18386622cce3Sdanielk1977 18396622cce3Sdanielk1977 zErr = sqlite3_errmsg(db); 18406622cce3Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1)); 18416622cce3Sdanielk1977 return TCL_OK; 18426622cce3Sdanielk1977 } 18436622cce3Sdanielk1977 18446622cce3Sdanielk1977 /* 18456622cce3Sdanielk1977 ** Usage: test_errmsg16 DB 18466622cce3Sdanielk1977 ** 18476622cce3Sdanielk1977 ** Returns the UTF-16 representation of the error message string for the 18486622cce3Sdanielk1977 ** most recent sqlite3_* API call. This is a byte array object at the TCL 18496622cce3Sdanielk1977 ** level, and it includes the 0x00 0x00 terminator bytes at the end of the 18506622cce3Sdanielk1977 ** UTF-16 string. 18516622cce3Sdanielk1977 */ 18526622cce3Sdanielk1977 static int test_errmsg16( 18536622cce3Sdanielk1977 void * clientData, 18546622cce3Sdanielk1977 Tcl_Interp *interp, 18556622cce3Sdanielk1977 int objc, 18566622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 18576622cce3Sdanielk1977 ){ 18585436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 18599bb575fdSdrh sqlite3 *db; 18606622cce3Sdanielk1977 const void *zErr; 18616622cce3Sdanielk1977 int bytes; 18626622cce3Sdanielk1977 18636622cce3Sdanielk1977 if( objc!=2 ){ 18646622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 18656622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 18666622cce3Sdanielk1977 return TCL_ERROR; 18676622cce3Sdanielk1977 } 18686622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 18696622cce3Sdanielk1977 18706622cce3Sdanielk1977 zErr = sqlite3_errmsg16(db); 18716622cce3Sdanielk1977 bytes = sqlite3utf16ByteLen(zErr, -1); 18726622cce3Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes)); 18735436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 18746622cce3Sdanielk1977 return TCL_OK; 18756622cce3Sdanielk1977 } 18766622cce3Sdanielk1977 18776622cce3Sdanielk1977 /* 18786622cce3Sdanielk1977 ** Usage: sqlite3_prepare DB sql bytes tailvar 18796622cce3Sdanielk1977 ** 18806622cce3Sdanielk1977 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using 18816622cce3Sdanielk1977 ** database handle <DB>. The parameter <tailval> is the name of a global 18826622cce3Sdanielk1977 ** variable that is set to the unused portion of <sql> (if any). A 18836622cce3Sdanielk1977 ** STMT handle is returned. 18846622cce3Sdanielk1977 */ 18856622cce3Sdanielk1977 static int test_prepare( 18866622cce3Sdanielk1977 void * clientData, 18876622cce3Sdanielk1977 Tcl_Interp *interp, 18886622cce3Sdanielk1977 int objc, 18896622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 18906622cce3Sdanielk1977 ){ 18916622cce3Sdanielk1977 sqlite3 *db; 18926622cce3Sdanielk1977 const char *zSql; 18936622cce3Sdanielk1977 int bytes; 18946622cce3Sdanielk1977 const char *zTail = 0; 18956622cce3Sdanielk1977 sqlite3_stmt *pStmt = 0; 18966622cce3Sdanielk1977 char zBuf[50]; 18974ad1713cSdanielk1977 int rc; 18986622cce3Sdanielk1977 18996622cce3Sdanielk1977 if( objc!=5 ){ 19006622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 19016622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); 19026622cce3Sdanielk1977 return TCL_ERROR; 19036622cce3Sdanielk1977 } 19046622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 19056622cce3Sdanielk1977 zSql = Tcl_GetString(objv[2]); 19066622cce3Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; 19076622cce3Sdanielk1977 19084ad1713cSdanielk1977 rc = sqlite3_prepare(db, zSql, bytes, &pStmt, &zTail); 1909c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 19106622cce3Sdanielk1977 if( zTail ){ 19116622cce3Sdanielk1977 if( bytes>=0 ){ 19126622cce3Sdanielk1977 bytes = bytes - (zTail-zSql); 19136622cce3Sdanielk1977 } 19146622cce3Sdanielk1977 Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0); 19156622cce3Sdanielk1977 } 19164ad1713cSdanielk1977 if( rc!=SQLITE_OK ){ 19174ad1713cSdanielk1977 assert( pStmt==0 ); 19184ad1713cSdanielk1977 sprintf(zBuf, "(%d) ", rc); 19194ad1713cSdanielk1977 Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0); 19204ad1713cSdanielk1977 return TCL_ERROR; 19214ad1713cSdanielk1977 } 19226622cce3Sdanielk1977 19234ad1713cSdanielk1977 if( pStmt ){ 19246622cce3Sdanielk1977 if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; 19256622cce3Sdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 19264ad1713cSdanielk1977 } 19276622cce3Sdanielk1977 return TCL_OK; 19286622cce3Sdanielk1977 } 19296622cce3Sdanielk1977 19306622cce3Sdanielk1977 /* 19316622cce3Sdanielk1977 ** Usage: sqlite3_prepare DB sql bytes tailvar 19326622cce3Sdanielk1977 ** 19336622cce3Sdanielk1977 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using 19346622cce3Sdanielk1977 ** database handle <DB>. The parameter <tailval> is the name of a global 19356622cce3Sdanielk1977 ** variable that is set to the unused portion of <sql> (if any). A 19366622cce3Sdanielk1977 ** STMT handle is returned. 19376622cce3Sdanielk1977 */ 19386622cce3Sdanielk1977 static int test_prepare16( 19396622cce3Sdanielk1977 void * clientData, 19406622cce3Sdanielk1977 Tcl_Interp *interp, 19416622cce3Sdanielk1977 int objc, 19426622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 19436622cce3Sdanielk1977 ){ 19445436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 19456622cce3Sdanielk1977 sqlite3 *db; 19466622cce3Sdanielk1977 const void *zSql; 19476622cce3Sdanielk1977 const void *zTail = 0; 19486622cce3Sdanielk1977 Tcl_Obj *pTail = 0; 19496622cce3Sdanielk1977 sqlite3_stmt *pStmt = 0; 19506622cce3Sdanielk1977 char zBuf[50]; 1951c60d0446Sdrh int rc; 19526622cce3Sdanielk1977 int bytes; /* The integer specified as arg 3 */ 19536622cce3Sdanielk1977 int objlen; /* The byte-array length of arg 2 */ 19546622cce3Sdanielk1977 19556622cce3Sdanielk1977 if( objc!=5 ){ 19566622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 19576622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); 19586622cce3Sdanielk1977 return TCL_ERROR; 19596622cce3Sdanielk1977 } 19606622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 19616622cce3Sdanielk1977 zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen); 19626622cce3Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; 19636622cce3Sdanielk1977 1964c60d0446Sdrh rc = sqlite3_prepare16(db, zSql, bytes, &pStmt, &zTail); 1965c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1966c60d0446Sdrh if( rc ){ 19676622cce3Sdanielk1977 return TCL_ERROR; 19686622cce3Sdanielk1977 } 19696622cce3Sdanielk1977 19706622cce3Sdanielk1977 if( zTail ){ 19716622cce3Sdanielk1977 objlen = objlen - ((u8 *)zTail-(u8 *)zSql); 19726622cce3Sdanielk1977 }else{ 19736622cce3Sdanielk1977 objlen = 0; 19746622cce3Sdanielk1977 } 19756622cce3Sdanielk1977 pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen); 19766622cce3Sdanielk1977 Tcl_IncrRefCount(pTail); 19776622cce3Sdanielk1977 Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0); 19784ad1713cSdanielk1977 Tcl_DecrRefCount(pTail); 19796622cce3Sdanielk1977 19804ad1713cSdanielk1977 if( pStmt ){ 19816622cce3Sdanielk1977 if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; 19824ad1713cSdanielk1977 } 19836622cce3Sdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 19845436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 19856622cce3Sdanielk1977 return TCL_OK; 19866622cce3Sdanielk1977 } 19876622cce3Sdanielk1977 19884ad1713cSdanielk1977 /* 19894ad1713cSdanielk1977 ** Usage: sqlite3_open filename ?options-list? 19904ad1713cSdanielk1977 */ 19914ad1713cSdanielk1977 static int test_open( 19924ad1713cSdanielk1977 void * clientData, 19934ad1713cSdanielk1977 Tcl_Interp *interp, 19944ad1713cSdanielk1977 int objc, 19954ad1713cSdanielk1977 Tcl_Obj *CONST objv[] 19964ad1713cSdanielk1977 ){ 19974ad1713cSdanielk1977 const char *zFilename; 19984ad1713cSdanielk1977 sqlite3 *db; 19994ad1713cSdanielk1977 int rc; 20004ad1713cSdanielk1977 char zBuf[100]; 20014ad1713cSdanielk1977 20024ad1713cSdanielk1977 if( objc!=3 && objc!=2 ){ 20034ad1713cSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 20044ad1713cSdanielk1977 Tcl_GetString(objv[0]), " filename options-list", 0); 20054ad1713cSdanielk1977 return TCL_ERROR; 20064ad1713cSdanielk1977 } 20074ad1713cSdanielk1977 20084ad1713cSdanielk1977 zFilename = Tcl_GetString(objv[1]); 20094f057f90Sdanielk1977 rc = sqlite3_open(zFilename, &db); 20104ad1713cSdanielk1977 20114ad1713cSdanielk1977 if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR; 20124ad1713cSdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 20134ad1713cSdanielk1977 return TCL_OK; 20144ad1713cSdanielk1977 } 20154ad1713cSdanielk1977 20164ad1713cSdanielk1977 /* 20174ad1713cSdanielk1977 ** Usage: sqlite3_open16 filename options 20184ad1713cSdanielk1977 */ 20194ad1713cSdanielk1977 static int test_open16( 20204ad1713cSdanielk1977 void * clientData, 20214ad1713cSdanielk1977 Tcl_Interp *interp, 20224ad1713cSdanielk1977 int objc, 20234ad1713cSdanielk1977 Tcl_Obj *CONST objv[] 20244ad1713cSdanielk1977 ){ 20255436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 20264ad1713cSdanielk1977 const void *zFilename; 20274ad1713cSdanielk1977 sqlite3 *db; 20284ad1713cSdanielk1977 int rc; 20294ad1713cSdanielk1977 char zBuf[100]; 20304ad1713cSdanielk1977 20314ad1713cSdanielk1977 if( objc!=3 ){ 20324ad1713cSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 20334ad1713cSdanielk1977 Tcl_GetString(objv[0]), " filename options-list", 0); 20344ad1713cSdanielk1977 return TCL_ERROR; 20354ad1713cSdanielk1977 } 20364ad1713cSdanielk1977 20374ad1713cSdanielk1977 zFilename = Tcl_GetByteArrayFromObj(objv[1], 0); 20384f057f90Sdanielk1977 rc = sqlite3_open16(zFilename, &db); 20394ad1713cSdanielk1977 20404ad1713cSdanielk1977 if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR; 20414ad1713cSdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 20425436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 20434ad1713cSdanielk1977 return TCL_OK; 20444ad1713cSdanielk1977 } 2045d3d39e93Sdrh 2046d3d39e93Sdrh /* 2047bc6ada41Sdanielk1977 ** Usage: sqlite3_complete16 <UTF-16 string> 2048bc6ada41Sdanielk1977 ** 2049bc6ada41Sdanielk1977 ** Return 1 if the supplied argument is a complete SQL statement, or zero 2050bc6ada41Sdanielk1977 ** otherwise. 2051bc6ada41Sdanielk1977 */ 2052bc6ada41Sdanielk1977 static int test_complete16( 2053bc6ada41Sdanielk1977 void * clientData, 2054bc6ada41Sdanielk1977 Tcl_Interp *interp, 2055bc6ada41Sdanielk1977 int objc, 2056bc6ada41Sdanielk1977 Tcl_Obj *CONST objv[] 2057bc6ada41Sdanielk1977 ){ 2058ccae6026Sdrh #if !defined(SQLITE_OMIT_COMPLETE) && !defined(SQLITE_OMIT_UTF16) 2059bc6ada41Sdanielk1977 char *zBuf; 2060bc6ada41Sdanielk1977 2061bc6ada41Sdanielk1977 if( objc!=2 ){ 2062bc6ada41Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>"); 2063bc6ada41Sdanielk1977 return TCL_ERROR; 2064bc6ada41Sdanielk1977 } 2065bc6ada41Sdanielk1977 2066bc6ada41Sdanielk1977 zBuf = Tcl_GetByteArrayFromObj(objv[1], 0); 2067bc6ada41Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_complete16(zBuf))); 2068ccae6026Sdrh #endif /* SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */ 2069bc6ada41Sdanielk1977 return TCL_OK; 2070bc6ada41Sdanielk1977 } 2071bc6ada41Sdanielk1977 2072bc6ada41Sdanielk1977 /* 2073106bb236Sdanielk1977 ** Usage: sqlite3_step STMT 2074106bb236Sdanielk1977 ** 2075106bb236Sdanielk1977 ** Advance the statement to the next row. 2076106bb236Sdanielk1977 */ 207717240fd9Sdanielk1977 static int test_step( 2078106bb236Sdanielk1977 void * clientData, 2079106bb236Sdanielk1977 Tcl_Interp *interp, 2080106bb236Sdanielk1977 int objc, 2081106bb236Sdanielk1977 Tcl_Obj *CONST objv[] 2082106bb236Sdanielk1977 ){ 2083106bb236Sdanielk1977 sqlite3_stmt *pStmt; 2084106bb236Sdanielk1977 int rc; 2085106bb236Sdanielk1977 2086e1cd9874Sdanielk1977 if( objc!=2 ){ 2087106bb236Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 2088106bb236Sdanielk1977 Tcl_GetString(objv[0]), " STMT", 0); 2089106bb236Sdanielk1977 return TCL_ERROR; 2090106bb236Sdanielk1977 } 2091106bb236Sdanielk1977 2092106bb236Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 209317240fd9Sdanielk1977 rc = sqlite3_step(pStmt); 2094106bb236Sdanielk1977 2095fbcd585fSdanielk1977 /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; */ 20966590493dSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), 0); 2097e1cd9874Sdanielk1977 return TCL_OK; 2098e1cd9874Sdanielk1977 } 2099e1cd9874Sdanielk1977 2100e1cd9874Sdanielk1977 /* 210117240fd9Sdanielk1977 ** Usage: sqlite3_column_count STMT 210217240fd9Sdanielk1977 ** 210317240fd9Sdanielk1977 ** Return the number of columns returned by the sql statement STMT. 210417240fd9Sdanielk1977 */ 210517240fd9Sdanielk1977 static int test_column_count( 210617240fd9Sdanielk1977 void * clientData, 210717240fd9Sdanielk1977 Tcl_Interp *interp, 210817240fd9Sdanielk1977 int objc, 210917240fd9Sdanielk1977 Tcl_Obj *CONST objv[] 211017240fd9Sdanielk1977 ){ 211117240fd9Sdanielk1977 sqlite3_stmt *pStmt; 211217240fd9Sdanielk1977 211317240fd9Sdanielk1977 if( objc!=2 ){ 211417240fd9Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 211517240fd9Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 211617240fd9Sdanielk1977 return TCL_ERROR; 211717240fd9Sdanielk1977 } 211817240fd9Sdanielk1977 211917240fd9Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 212017240fd9Sdanielk1977 212117240fd9Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_column_count(pStmt))); 212217240fd9Sdanielk1977 return TCL_OK; 212317240fd9Sdanielk1977 } 212417240fd9Sdanielk1977 212517240fd9Sdanielk1977 /* 21263cf86063Sdanielk1977 ** Usage: sqlite3_column_type STMT column 21273cf86063Sdanielk1977 ** 21283cf86063Sdanielk1977 ** Return the type of the data in column 'column' of the current row. 21293cf86063Sdanielk1977 */ 21303cf86063Sdanielk1977 static int test_column_type( 21313cf86063Sdanielk1977 void * clientData, 21323cf86063Sdanielk1977 Tcl_Interp *interp, 21333cf86063Sdanielk1977 int objc, 21343cf86063Sdanielk1977 Tcl_Obj *CONST objv[] 21353cf86063Sdanielk1977 ){ 21363cf86063Sdanielk1977 sqlite3_stmt *pStmt; 21373cf86063Sdanielk1977 int col; 21383cf86063Sdanielk1977 int tp; 21393cf86063Sdanielk1977 21403cf86063Sdanielk1977 if( objc!=3 ){ 21413cf86063Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 21423cf86063Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 21433cf86063Sdanielk1977 return TCL_ERROR; 21443cf86063Sdanielk1977 } 21453cf86063Sdanielk1977 21463cf86063Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 21473cf86063Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 21483cf86063Sdanielk1977 21493cf86063Sdanielk1977 tp = sqlite3_column_type(pStmt, col); 21503cf86063Sdanielk1977 switch( tp ){ 21519c054830Sdrh case SQLITE_INTEGER: 21523cf86063Sdanielk1977 Tcl_SetResult(interp, "INTEGER", TCL_STATIC); 21533cf86063Sdanielk1977 break; 21549c054830Sdrh case SQLITE_NULL: 21553cf86063Sdanielk1977 Tcl_SetResult(interp, "NULL", TCL_STATIC); 21563cf86063Sdanielk1977 break; 21579c054830Sdrh case SQLITE_FLOAT: 21583cf86063Sdanielk1977 Tcl_SetResult(interp, "FLOAT", TCL_STATIC); 21593cf86063Sdanielk1977 break; 21609c054830Sdrh case SQLITE_TEXT: 21613cf86063Sdanielk1977 Tcl_SetResult(interp, "TEXT", TCL_STATIC); 21623cf86063Sdanielk1977 break; 21639c054830Sdrh case SQLITE_BLOB: 21643cf86063Sdanielk1977 Tcl_SetResult(interp, "BLOB", TCL_STATIC); 21653cf86063Sdanielk1977 break; 21663cf86063Sdanielk1977 default: 21673cf86063Sdanielk1977 assert(0); 21683cf86063Sdanielk1977 } 21693cf86063Sdanielk1977 21703cf86063Sdanielk1977 return TCL_OK; 21713cf86063Sdanielk1977 } 21723cf86063Sdanielk1977 21733cf86063Sdanielk1977 /* 217404f2e68dSdanielk1977 ** Usage: sqlite3_column_int64 STMT column 21753cf86063Sdanielk1977 ** 21763cf86063Sdanielk1977 ** Return the data in column 'column' of the current row cast as an 217704f2e68dSdanielk1977 ** wide (64-bit) integer. 21783cf86063Sdanielk1977 */ 217904f2e68dSdanielk1977 static int test_column_int64( 21803cf86063Sdanielk1977 void * clientData, 21813cf86063Sdanielk1977 Tcl_Interp *interp, 21823cf86063Sdanielk1977 int objc, 21833cf86063Sdanielk1977 Tcl_Obj *CONST objv[] 21843cf86063Sdanielk1977 ){ 21853cf86063Sdanielk1977 sqlite3_stmt *pStmt; 21863cf86063Sdanielk1977 int col; 218704f2e68dSdanielk1977 i64 iVal; 21883cf86063Sdanielk1977 21893cf86063Sdanielk1977 if( objc!=3 ){ 21903cf86063Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 21913cf86063Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 21923cf86063Sdanielk1977 return TCL_ERROR; 21933cf86063Sdanielk1977 } 21943cf86063Sdanielk1977 21953cf86063Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 21963cf86063Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 21973cf86063Sdanielk1977 219804f2e68dSdanielk1977 iVal = sqlite3_column_int64(pStmt, col); 219904f2e68dSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iVal)); 220004f2e68dSdanielk1977 return TCL_OK; 220104f2e68dSdanielk1977 } 220204f2e68dSdanielk1977 220304f2e68dSdanielk1977 /* 2204ea61b2c4Sdanielk1977 ** Usage: sqlite3_column_blob STMT column 2205ea61b2c4Sdanielk1977 */ 2206ea61b2c4Sdanielk1977 static int test_column_blob( 2207ea61b2c4Sdanielk1977 void * clientData, 2208ea61b2c4Sdanielk1977 Tcl_Interp *interp, 2209ea61b2c4Sdanielk1977 int objc, 2210ea61b2c4Sdanielk1977 Tcl_Obj *CONST objv[] 2211ea61b2c4Sdanielk1977 ){ 2212ea61b2c4Sdanielk1977 sqlite3_stmt *pStmt; 2213ea61b2c4Sdanielk1977 int col; 2214ea61b2c4Sdanielk1977 2215ea61b2c4Sdanielk1977 int len; 2216c572ef7fSdanielk1977 const void *pBlob; 2217ea61b2c4Sdanielk1977 2218ea61b2c4Sdanielk1977 if( objc!=3 ){ 2219ea61b2c4Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 2220ea61b2c4Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 2221ea61b2c4Sdanielk1977 return TCL_ERROR; 2222ea61b2c4Sdanielk1977 } 2223ea61b2c4Sdanielk1977 2224ea61b2c4Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2225ea61b2c4Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2226ea61b2c4Sdanielk1977 2227ea61b2c4Sdanielk1977 pBlob = sqlite3_column_blob(pStmt, col); 2228ea61b2c4Sdanielk1977 len = sqlite3_column_bytes(pStmt, col); 2229ea61b2c4Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len)); 2230ea61b2c4Sdanielk1977 return TCL_OK; 2231ea61b2c4Sdanielk1977 } 2232ea61b2c4Sdanielk1977 2233ea61b2c4Sdanielk1977 /* 223404f2e68dSdanielk1977 ** Usage: sqlite3_column_double STMT column 223504f2e68dSdanielk1977 ** 223604f2e68dSdanielk1977 ** Return the data in column 'column' of the current row cast as a double. 223704f2e68dSdanielk1977 */ 223804f2e68dSdanielk1977 static int test_column_double( 223904f2e68dSdanielk1977 void * clientData, 224004f2e68dSdanielk1977 Tcl_Interp *interp, 224104f2e68dSdanielk1977 int objc, 224204f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 224304f2e68dSdanielk1977 ){ 224404f2e68dSdanielk1977 sqlite3_stmt *pStmt; 224504f2e68dSdanielk1977 int col; 224604f2e68dSdanielk1977 double rVal; 224704f2e68dSdanielk1977 224804f2e68dSdanielk1977 if( objc!=3 ){ 224904f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 225004f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 225104f2e68dSdanielk1977 return TCL_ERROR; 225204f2e68dSdanielk1977 } 225304f2e68dSdanielk1977 225404f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 225504f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 225604f2e68dSdanielk1977 225704f2e68dSdanielk1977 rVal = sqlite3_column_double(pStmt, col); 2258c572ef7fSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rVal)); 22593cf86063Sdanielk1977 return TCL_OK; 22603cf86063Sdanielk1977 } 22613cf86063Sdanielk1977 22623cf86063Sdanielk1977 /* 226317240fd9Sdanielk1977 ** Usage: sqlite3_data_count STMT 226417240fd9Sdanielk1977 ** 226517240fd9Sdanielk1977 ** Return the number of columns returned by the sql statement STMT. 226617240fd9Sdanielk1977 */ 226717240fd9Sdanielk1977 static int test_data_count( 226817240fd9Sdanielk1977 void * clientData, 226917240fd9Sdanielk1977 Tcl_Interp *interp, 227017240fd9Sdanielk1977 int objc, 227117240fd9Sdanielk1977 Tcl_Obj *CONST objv[] 227217240fd9Sdanielk1977 ){ 227317240fd9Sdanielk1977 sqlite3_stmt *pStmt; 227417240fd9Sdanielk1977 227517240fd9Sdanielk1977 if( objc!=2 ){ 227617240fd9Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 227717240fd9Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 227817240fd9Sdanielk1977 return TCL_ERROR; 227917240fd9Sdanielk1977 } 228017240fd9Sdanielk1977 228117240fd9Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 228217240fd9Sdanielk1977 228317240fd9Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_data_count(pStmt))); 228417240fd9Sdanielk1977 return TCL_OK; 228517240fd9Sdanielk1977 } 228617240fd9Sdanielk1977 228717240fd9Sdanielk1977 /* 228804f2e68dSdanielk1977 ** Usage: sqlite3_column_text STMT column 228904f2e68dSdanielk1977 ** 229004f2e68dSdanielk1977 ** Usage: sqlite3_column_decltype STMT column 229104f2e68dSdanielk1977 ** 229204f2e68dSdanielk1977 ** Usage: sqlite3_column_name STMT column 229304f2e68dSdanielk1977 */ 229404f2e68dSdanielk1977 static int test_stmt_utf8( 2295241db313Sdrh void * clientData, /* Pointer to SQLite API function to be invoke */ 229604f2e68dSdanielk1977 Tcl_Interp *interp, 229704f2e68dSdanielk1977 int objc, 229804f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 229904f2e68dSdanielk1977 ){ 230004f2e68dSdanielk1977 sqlite3_stmt *pStmt; 230104f2e68dSdanielk1977 int col; 2302c572ef7fSdanielk1977 const char *(*xFunc)(sqlite3_stmt*, int) = clientData; 2303f93bbbeaSdanielk1977 const char *zRet; 230404f2e68dSdanielk1977 230504f2e68dSdanielk1977 if( objc!=3 ){ 230604f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 230704f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 230804f2e68dSdanielk1977 return TCL_ERROR; 230904f2e68dSdanielk1977 } 231004f2e68dSdanielk1977 231104f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 231204f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2313f93bbbeaSdanielk1977 zRet = xFunc(pStmt, col); 2314f93bbbeaSdanielk1977 if( zRet ){ 2315f93bbbeaSdanielk1977 Tcl_SetResult(interp, (char *)zRet, 0); 2316f93bbbeaSdanielk1977 } 231704f2e68dSdanielk1977 return TCL_OK; 231804f2e68dSdanielk1977 } 231904f2e68dSdanielk1977 23206b456a2bSdanielk1977 static int test_global_recover( 23216b456a2bSdanielk1977 void * clientData, 23226b456a2bSdanielk1977 Tcl_Interp *interp, 23236b456a2bSdanielk1977 int objc, 23246b456a2bSdanielk1977 Tcl_Obj *CONST objv[] 23256b456a2bSdanielk1977 ){ 23266b456a2bSdanielk1977 #ifndef SQLITE_OMIT_GLOBALRECOVER 23276b456a2bSdanielk1977 int rc; 23286b456a2bSdanielk1977 if( objc!=1 ){ 23296b456a2bSdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, ""); 23306b456a2bSdanielk1977 return TCL_ERROR; 23316b456a2bSdanielk1977 } 23326b456a2bSdanielk1977 rc = sqlite3_global_recover(); 23336b456a2bSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 23346b456a2bSdanielk1977 #endif 23356b456a2bSdanielk1977 return TCL_OK; 23366b456a2bSdanielk1977 } 23376b456a2bSdanielk1977 233804f2e68dSdanielk1977 /* 233904f2e68dSdanielk1977 ** Usage: sqlite3_column_text STMT column 234004f2e68dSdanielk1977 ** 234104f2e68dSdanielk1977 ** Usage: sqlite3_column_decltype STMT column 234204f2e68dSdanielk1977 ** 234304f2e68dSdanielk1977 ** Usage: sqlite3_column_name STMT column 234404f2e68dSdanielk1977 */ 234504f2e68dSdanielk1977 static int test_stmt_utf16( 2346241db313Sdrh void * clientData, /* Pointer to SQLite API function to be invoked */ 234704f2e68dSdanielk1977 Tcl_Interp *interp, 234804f2e68dSdanielk1977 int objc, 234904f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 235004f2e68dSdanielk1977 ){ 23515436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 235204f2e68dSdanielk1977 sqlite3_stmt *pStmt; 235304f2e68dSdanielk1977 int col; 235404f2e68dSdanielk1977 Tcl_Obj *pRet; 235504f2e68dSdanielk1977 const void *zName16; 2356c572ef7fSdanielk1977 const void *(*xFunc)(sqlite3_stmt*, int) = clientData; 235704f2e68dSdanielk1977 235804f2e68dSdanielk1977 if( objc!=3 ){ 235904f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 236004f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 236104f2e68dSdanielk1977 return TCL_ERROR; 236204f2e68dSdanielk1977 } 236304f2e68dSdanielk1977 236404f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 236504f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 236604f2e68dSdanielk1977 236704f2e68dSdanielk1977 zName16 = xFunc(pStmt, col); 2368f93bbbeaSdanielk1977 if( zName16 ){ 236904f2e68dSdanielk1977 pRet = Tcl_NewByteArrayObj(zName16, sqlite3utf16ByteLen(zName16, -1)+2); 237004f2e68dSdanielk1977 Tcl_SetObjResult(interp, pRet); 2371f93bbbeaSdanielk1977 } 23725436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 237304f2e68dSdanielk1977 237404f2e68dSdanielk1977 return TCL_OK; 237504f2e68dSdanielk1977 } 237604f2e68dSdanielk1977 237704f2e68dSdanielk1977 /* 237804f2e68dSdanielk1977 ** Usage: sqlite3_column_int STMT column 237904f2e68dSdanielk1977 ** 238004f2e68dSdanielk1977 ** Usage: sqlite3_column_bytes STMT column 238104f2e68dSdanielk1977 ** 238204f2e68dSdanielk1977 ** Usage: sqlite3_column_bytes16 STMT column 238304f2e68dSdanielk1977 ** 238404f2e68dSdanielk1977 */ 238504f2e68dSdanielk1977 static int test_stmt_int( 2386241db313Sdrh void * clientData, /* Pointer to SQLite API function to be invoked */ 238704f2e68dSdanielk1977 Tcl_Interp *interp, 238804f2e68dSdanielk1977 int objc, 238904f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 239004f2e68dSdanielk1977 ){ 239104f2e68dSdanielk1977 sqlite3_stmt *pStmt; 239204f2e68dSdanielk1977 int col; 2393c572ef7fSdanielk1977 int (*xFunc)(sqlite3_stmt*, int) = clientData; 239404f2e68dSdanielk1977 239504f2e68dSdanielk1977 if( objc!=3 ){ 239604f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 239704f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 239804f2e68dSdanielk1977 return TCL_ERROR; 239904f2e68dSdanielk1977 } 240004f2e68dSdanielk1977 240104f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 240204f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 240304f2e68dSdanielk1977 240404f2e68dSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(xFunc(pStmt, col))); 240504f2e68dSdanielk1977 return TCL_OK; 240604f2e68dSdanielk1977 } 240704f2e68dSdanielk1977 240844ee5bf7Sdanielk1977 #ifndef SQLITE_OMIT_DISKIO 24099a1d0abeSdanielk1977 /* 24109a1d0abeSdanielk1977 ** Usage: sqlite3OsOpenReadWrite <filename> 24119a1d0abeSdanielk1977 */ 24129a1d0abeSdanielk1977 static int test_sqlite3OsOpenReadWrite( 24139a1d0abeSdanielk1977 void * clientData, 24149a1d0abeSdanielk1977 Tcl_Interp *interp, 24159a1d0abeSdanielk1977 int objc, 24169a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 24179a1d0abeSdanielk1977 ){ 24189a1d0abeSdanielk1977 OsFile * pFile; 24199a1d0abeSdanielk1977 int rc; 24209a1d0abeSdanielk1977 int dummy; 24219a1d0abeSdanielk1977 char zBuf[100]; 242204f2e68dSdanielk1977 24239a1d0abeSdanielk1977 if( objc!=2 ){ 24249a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 24259a1d0abeSdanielk1977 Tcl_GetString(objv[0]), " filename", 0); 24269a1d0abeSdanielk1977 return TCL_ERROR; 24279a1d0abeSdanielk1977 } 24289a1d0abeSdanielk1977 24299a1d0abeSdanielk1977 pFile = sqliteMalloc(sizeof(OsFile)); 24309a1d0abeSdanielk1977 rc = sqlite3OsOpenReadWrite(Tcl_GetString(objv[1]), pFile, &dummy); 24319a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 24329a1d0abeSdanielk1977 sqliteFree(pFile); 24339a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 24349a1d0abeSdanielk1977 return TCL_ERROR; 24359a1d0abeSdanielk1977 } 24369a1d0abeSdanielk1977 makePointerStr(interp, zBuf, pFile); 24379a1d0abeSdanielk1977 Tcl_SetResult(interp, zBuf, 0); 24389a1d0abeSdanielk1977 return TCL_ERROR; 24399a1d0abeSdanielk1977 } 24409a1d0abeSdanielk1977 24419a1d0abeSdanielk1977 /* 24429a1d0abeSdanielk1977 ** Usage: sqlite3OsClose <file handle> 24439a1d0abeSdanielk1977 */ 24449a1d0abeSdanielk1977 static int test_sqlite3OsClose( 24459a1d0abeSdanielk1977 void * clientData, 24469a1d0abeSdanielk1977 Tcl_Interp *interp, 24479a1d0abeSdanielk1977 int objc, 24489a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 24499a1d0abeSdanielk1977 ){ 24509a1d0abeSdanielk1977 OsFile * pFile; 24519a1d0abeSdanielk1977 int rc; 24529a1d0abeSdanielk1977 24539a1d0abeSdanielk1977 if( objc!=2 ){ 24549a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 24559a1d0abeSdanielk1977 Tcl_GetString(objv[0]), " filehandle", 0); 24569a1d0abeSdanielk1977 return TCL_ERROR; 24579a1d0abeSdanielk1977 } 24589a1d0abeSdanielk1977 24599a1d0abeSdanielk1977 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 24609a1d0abeSdanielk1977 return TCL_ERROR; 24619a1d0abeSdanielk1977 } 24629a1d0abeSdanielk1977 rc = sqlite3OsClose(pFile); 24639a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 24649a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 24659a1d0abeSdanielk1977 return TCL_ERROR; 24669a1d0abeSdanielk1977 } 24679a1d0abeSdanielk1977 sqliteFree(pFile); 24689a1d0abeSdanielk1977 return TCL_OK; 24699a1d0abeSdanielk1977 } 24709a1d0abeSdanielk1977 24719a1d0abeSdanielk1977 /* 24729a1d0abeSdanielk1977 ** Usage: sqlite3OsLock <file handle> <locktype> 24739a1d0abeSdanielk1977 */ 24749a1d0abeSdanielk1977 static int test_sqlite3OsLock( 24759a1d0abeSdanielk1977 void * clientData, 24769a1d0abeSdanielk1977 Tcl_Interp *interp, 24779a1d0abeSdanielk1977 int objc, 24789a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 24799a1d0abeSdanielk1977 ){ 24809a1d0abeSdanielk1977 OsFile * pFile; 24819a1d0abeSdanielk1977 int rc; 24829a1d0abeSdanielk1977 24839a1d0abeSdanielk1977 if( objc!=3 ){ 24849a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 24859a1d0abeSdanielk1977 Tcl_GetString(objv[0]), 24869a1d0abeSdanielk1977 " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0); 24879a1d0abeSdanielk1977 return TCL_ERROR; 24889a1d0abeSdanielk1977 } 24899a1d0abeSdanielk1977 24909a1d0abeSdanielk1977 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 24919a1d0abeSdanielk1977 return TCL_ERROR; 24929a1d0abeSdanielk1977 } 24939a1d0abeSdanielk1977 24949a1d0abeSdanielk1977 if( 0==strcmp("SHARED", Tcl_GetString(objv[2])) ){ 24959a1d0abeSdanielk1977 rc = sqlite3OsLock(pFile, SHARED_LOCK); 24969a1d0abeSdanielk1977 } 24979a1d0abeSdanielk1977 else if( 0==strcmp("RESERVED", Tcl_GetString(objv[2])) ){ 24989a1d0abeSdanielk1977 rc = sqlite3OsLock(pFile, RESERVED_LOCK); 24999a1d0abeSdanielk1977 } 25009a1d0abeSdanielk1977 else if( 0==strcmp("PENDING", Tcl_GetString(objv[2])) ){ 25019a1d0abeSdanielk1977 rc = sqlite3OsLock(pFile, PENDING_LOCK); 25029a1d0abeSdanielk1977 } 25039a1d0abeSdanielk1977 else if( 0==strcmp("EXCLUSIVE", Tcl_GetString(objv[2])) ){ 25049a1d0abeSdanielk1977 rc = sqlite3OsLock(pFile, EXCLUSIVE_LOCK); 25059a1d0abeSdanielk1977 }else{ 25069a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 25079a1d0abeSdanielk1977 Tcl_GetString(objv[0]), 25089a1d0abeSdanielk1977 " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0); 25099a1d0abeSdanielk1977 return TCL_ERROR; 25109a1d0abeSdanielk1977 } 25119a1d0abeSdanielk1977 25129a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 25139a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 25149a1d0abeSdanielk1977 return TCL_ERROR; 25159a1d0abeSdanielk1977 } 25169a1d0abeSdanielk1977 return TCL_OK; 25179a1d0abeSdanielk1977 } 25189a1d0abeSdanielk1977 25199a1d0abeSdanielk1977 /* 25209a1d0abeSdanielk1977 ** Usage: sqlite3OsUnlock <file handle> 25219a1d0abeSdanielk1977 */ 25229a1d0abeSdanielk1977 static int test_sqlite3OsUnlock( 25239a1d0abeSdanielk1977 void * clientData, 25249a1d0abeSdanielk1977 Tcl_Interp *interp, 25259a1d0abeSdanielk1977 int objc, 25269a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 25279a1d0abeSdanielk1977 ){ 25289a1d0abeSdanielk1977 OsFile * pFile; 25299a1d0abeSdanielk1977 int rc; 25309a1d0abeSdanielk1977 25319a1d0abeSdanielk1977 if( objc!=2 ){ 25329a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 25339a1d0abeSdanielk1977 Tcl_GetString(objv[0]), " filehandle", 0); 25349a1d0abeSdanielk1977 return TCL_ERROR; 25359a1d0abeSdanielk1977 } 25369a1d0abeSdanielk1977 25379a1d0abeSdanielk1977 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 25389a1d0abeSdanielk1977 return TCL_ERROR; 25399a1d0abeSdanielk1977 } 2540a6abd041Sdrh rc = sqlite3OsUnlock(pFile, NO_LOCK); 25419a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 25429a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 25439a1d0abeSdanielk1977 return TCL_ERROR; 25449a1d0abeSdanielk1977 } 25459a1d0abeSdanielk1977 return TCL_OK; 25469a1d0abeSdanielk1977 } 2547d3d39e93Sdrh 2548ab3f9feaSdrh /* 2549ab3f9feaSdrh ** Usage: sqlite3OsTempFileName 2550ab3f9feaSdrh */ 2551ab3f9feaSdrh static int test_sqlite3OsTempFileName( 2552ab3f9feaSdrh void * clientData, 2553ab3f9feaSdrh Tcl_Interp *interp, 2554ab3f9feaSdrh int objc, 2555ab3f9feaSdrh Tcl_Obj *CONST objv[] 2556ab3f9feaSdrh ){ 2557ab3f9feaSdrh char zFile[SQLITE_TEMPNAME_SIZE]; 2558ab3f9feaSdrh int rc; 2559ab3f9feaSdrh 2560ab3f9feaSdrh rc = sqlite3OsTempFileName(zFile); 2561ab3f9feaSdrh if( rc!=SQLITE_OK ){ 2562ab3f9feaSdrh Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 2563ab3f9feaSdrh return TCL_ERROR; 2564ab3f9feaSdrh } 2565ab3f9feaSdrh Tcl_AppendResult(interp, zFile, 0); 2566ab3f9feaSdrh return TCL_OK; 2567ab3f9feaSdrh } 256844ee5bf7Sdanielk1977 #endif 2569d8123366Sdanielk1977 25706622cce3Sdanielk1977 /* 2571cacb208eSdrh ** Usage: sqlite_set_magic DB MAGIC-NUMBER 2572cacb208eSdrh ** 2573cacb208eSdrh ** Set the db->magic value. This is used to test error recovery logic. 2574cacb208eSdrh */ 2575cacb208eSdrh static int sqlite_set_magic( 2576cacb208eSdrh void * clientData, 2577cacb208eSdrh Tcl_Interp *interp, 2578cacb208eSdrh int argc, 2579cacb208eSdrh char **argv 2580cacb208eSdrh ){ 2581cacb208eSdrh sqlite3 *db; 2582cacb208eSdrh if( argc!=3 ){ 2583cacb208eSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 2584cacb208eSdrh " DB MAGIC", 0); 2585cacb208eSdrh return TCL_ERROR; 2586cacb208eSdrh } 2587cacb208eSdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 2588cacb208eSdrh if( strcmp(argv[2], "SQLITE_MAGIC_OPEN")==0 ){ 2589cacb208eSdrh db->magic = SQLITE_MAGIC_OPEN; 2590cacb208eSdrh }else if( strcmp(argv[2], "SQLITE_MAGIC_CLOSED")==0 ){ 2591cacb208eSdrh db->magic = SQLITE_MAGIC_CLOSED; 2592cacb208eSdrh }else if( strcmp(argv[2], "SQLITE_MAGIC_BUSY")==0 ){ 2593cacb208eSdrh db->magic = SQLITE_MAGIC_BUSY; 2594cacb208eSdrh }else if( strcmp(argv[2], "SQLITE_MAGIC_ERROR")==0 ){ 2595cacb208eSdrh db->magic = SQLITE_MAGIC_ERROR; 2596cacb208eSdrh }else if( Tcl_GetInt(interp, argv[2], &db->magic) ){ 2597cacb208eSdrh return TCL_ERROR; 2598cacb208eSdrh } 2599cacb208eSdrh return TCL_OK; 2600cacb208eSdrh } 2601cacb208eSdrh 2602cacb208eSdrh /* 2603c5cdca61Sdrh ** Usage: sqlite3_interrupt DB 2604c5cdca61Sdrh ** 2605c5cdca61Sdrh ** Trigger an interrupt on DB 2606c5cdca61Sdrh */ 2607c5cdca61Sdrh static int test_interrupt( 2608c5cdca61Sdrh void * clientData, 2609c5cdca61Sdrh Tcl_Interp *interp, 2610c5cdca61Sdrh int argc, 2611c5cdca61Sdrh char **argv 2612c5cdca61Sdrh ){ 2613c5cdca61Sdrh sqlite3 *db; 2614c5cdca61Sdrh if( argc!=2 ){ 2615c5cdca61Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB", 0); 2616c5cdca61Sdrh return TCL_ERROR; 2617c5cdca61Sdrh } 2618c5cdca61Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 2619c5cdca61Sdrh sqlite3_interrupt(db); 2620c5cdca61Sdrh return TCL_OK; 2621c5cdca61Sdrh } 2622c5cdca61Sdrh 2623c5cdca61Sdrh /* 2624600dd0baSdanielk1977 ** Usage: sqlite3_sleep ms 2625600dd0baSdanielk1977 ** 2626600dd0baSdanielk1977 ** Sleep for the specified number of ms. 2627600dd0baSdanielk1977 */ 2628600dd0baSdanielk1977 #if 0 2629600dd0baSdanielk1977 static int test_sleep( 2630600dd0baSdanielk1977 void * clientData, 2631600dd0baSdanielk1977 Tcl_Interp *interp, 2632600dd0baSdanielk1977 int argc, 2633600dd0baSdanielk1977 char **argv 2634600dd0baSdanielk1977 ){ 2635600dd0baSdanielk1977 sqlite3 *db; 2636600dd0baSdanielk1977 if( argc!=2 ){ 2637600dd0baSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ms", 0); 2638600dd0baSdanielk1977 return TCL_ERROR; 2639600dd0baSdanielk1977 } 2640600dd0baSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_sleep(atoi(argv[1])))); 2641600dd0baSdanielk1977 return TCL_OK; 2642600dd0baSdanielk1977 } 2643600dd0baSdanielk1977 #endif 2644600dd0baSdanielk1977 2645600dd0baSdanielk1977 /* 26469636c4e1Sdanielk1977 ** Usage: sqlite_delete_function DB function-name 26479636c4e1Sdanielk1977 ** 26489636c4e1Sdanielk1977 ** Delete the user function 'function-name' from database handle DB. It 26499636c4e1Sdanielk1977 ** is assumed that the user function was created as UTF8, any number of 26509636c4e1Sdanielk1977 ** arguments (the way the TCL interface does it). 26519636c4e1Sdanielk1977 */ 26529636c4e1Sdanielk1977 static int delete_function( 26539636c4e1Sdanielk1977 void * clientData, 26549636c4e1Sdanielk1977 Tcl_Interp *interp, 26559636c4e1Sdanielk1977 int argc, 26569636c4e1Sdanielk1977 char **argv 26579636c4e1Sdanielk1977 ){ 26589636c4e1Sdanielk1977 int rc; 26599636c4e1Sdanielk1977 sqlite3 *db; 26609636c4e1Sdanielk1977 if( argc!=3 ){ 26619636c4e1Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 26629636c4e1Sdanielk1977 " DB function-name", 0); 26639636c4e1Sdanielk1977 return TCL_ERROR; 26649636c4e1Sdanielk1977 } 26659636c4e1Sdanielk1977 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 26669636c4e1Sdanielk1977 rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 0, 0, 0); 26679636c4e1Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 26689636c4e1Sdanielk1977 return TCL_OK; 26699636c4e1Sdanielk1977 } 26709636c4e1Sdanielk1977 26719636c4e1Sdanielk1977 /* 26729636c4e1Sdanielk1977 ** Usage: sqlite_delete_collation DB collation-name 26739636c4e1Sdanielk1977 ** 26749636c4e1Sdanielk1977 ** Delete the collation sequence 'collation-name' from database handle 26759636c4e1Sdanielk1977 ** DB. It is assumed that the collation sequence was created as UTF8 (the 26769636c4e1Sdanielk1977 ** way the TCL interface does it). 26779636c4e1Sdanielk1977 */ 26789636c4e1Sdanielk1977 static int delete_collation( 26799636c4e1Sdanielk1977 void * clientData, 26809636c4e1Sdanielk1977 Tcl_Interp *interp, 26819636c4e1Sdanielk1977 int argc, 26829636c4e1Sdanielk1977 char **argv 26839636c4e1Sdanielk1977 ){ 26849636c4e1Sdanielk1977 int rc; 26859636c4e1Sdanielk1977 sqlite3 *db; 26869636c4e1Sdanielk1977 if( argc!=3 ){ 26879636c4e1Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 26889636c4e1Sdanielk1977 " DB function-name", 0); 26899636c4e1Sdanielk1977 return TCL_ERROR; 26909636c4e1Sdanielk1977 } 26919636c4e1Sdanielk1977 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 26929636c4e1Sdanielk1977 rc = sqlite3_create_collation(db, argv[2], SQLITE_UTF8, 0, 0); 26939636c4e1Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 26949636c4e1Sdanielk1977 return TCL_OK; 26959636c4e1Sdanielk1977 } 26969636c4e1Sdanielk1977 26979636c4e1Sdanielk1977 /* 26983e1d8e63Sdrh ** Usage: sqlite3_get_autocommit DB 26993e1d8e63Sdrh ** 27003e1d8e63Sdrh ** Return true if the database DB is currently in auto-commit mode. 27013e1d8e63Sdrh ** Return false if not. 27023e1d8e63Sdrh */ 27033e1d8e63Sdrh static int get_autocommit( 27043e1d8e63Sdrh void * clientData, 27053e1d8e63Sdrh Tcl_Interp *interp, 27063e1d8e63Sdrh int argc, 27073e1d8e63Sdrh char **argv 27083e1d8e63Sdrh ){ 27093e1d8e63Sdrh char zBuf[30]; 27103e1d8e63Sdrh sqlite3 *db; 27113e1d8e63Sdrh if( argc!=2 ){ 27123e1d8e63Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 27133e1d8e63Sdrh " DB", 0); 27143e1d8e63Sdrh return TCL_ERROR; 27153e1d8e63Sdrh } 27163e1d8e63Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 27173e1d8e63Sdrh sprintf(zBuf, "%d", sqlite3_get_autocommit(db)); 27183e1d8e63Sdrh Tcl_AppendResult(interp, zBuf, 0); 27193e1d8e63Sdrh return TCL_OK; 27203e1d8e63Sdrh } 27213e1d8e63Sdrh 27223e1d8e63Sdrh /* 272392febd92Sdrh ** Usage: tcl_variable_type VARIABLENAME 272492febd92Sdrh ** 272592febd92Sdrh ** Return the name of the internal representation for the 272692febd92Sdrh ** value of the given variable. 272792febd92Sdrh */ 272892febd92Sdrh static int tcl_variable_type( 272992febd92Sdrh void * clientData, 273092febd92Sdrh Tcl_Interp *interp, 273192febd92Sdrh int objc, 273292febd92Sdrh Tcl_Obj *CONST objv[] 273392febd92Sdrh ){ 273492febd92Sdrh Tcl_Obj *pVar; 273592febd92Sdrh if( objc!=2 ){ 273692febd92Sdrh Tcl_WrongNumArgs(interp, 1, objv, "VARIABLE"); 273792febd92Sdrh return TCL_ERROR; 273892febd92Sdrh } 273992febd92Sdrh pVar = Tcl_GetVar2Ex(interp, Tcl_GetString(objv[1]), 0, TCL_LEAVE_ERR_MSG); 274092febd92Sdrh if( pVar==0 ) return TCL_ERROR; 274192febd92Sdrh if( pVar->typePtr ){ 274292febd92Sdrh Tcl_SetObjResult(interp, Tcl_NewStringObj(pVar->typePtr->name, -1)); 274392febd92Sdrh } 274492febd92Sdrh return TCL_OK; 274592febd92Sdrh } 274692febd92Sdrh 274792febd92Sdrh /* 274827d258a3Sdrh ** This routine sets entries in the global ::sqlite_options() array variable 274927d258a3Sdrh ** according to the compile-time configuration of the database. Test 275027d258a3Sdrh ** procedures use this to determine when tests should be omitted. 275127d258a3Sdrh */ 275227d258a3Sdrh static void set_options(Tcl_Interp *interp){ 275375f86a4bSdrh #ifdef SQLITE_32BIT_ROWID 275475f86a4bSdrh Tcl_SetVar2(interp, "sqlite_options", "rowid32", "1", TCL_GLOBAL_ONLY); 275575f86a4bSdrh #else 275675f86a4bSdrh Tcl_SetVar2(interp, "sqlite_options", "rowid32", "0", TCL_GLOBAL_ONLY); 275775f86a4bSdrh #endif 275875f86a4bSdrh 27599f18e8a0Sdrh #ifdef SQLITE_CASE_SENSITIVE_LIKE 27609f18e8a0Sdrh Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","1",TCL_GLOBAL_ONLY); 27619f18e8a0Sdrh #else 27629f18e8a0Sdrh Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","0",TCL_GLOBAL_ONLY); 27639f18e8a0Sdrh #endif 27649f18e8a0Sdrh 27651c8c23ccSdanielk1977 #ifdef SQLITE_OMIT_ALTERTABLE 27661c8c23ccSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY); 27671c8c23ccSdanielk1977 #else 27681c8c23ccSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY); 27691c8c23ccSdanielk1977 #endif 277013d7042aSdrh 27719f18e8a0Sdrh #ifdef SQLITE_OMIT_ANALYZE 27729f18e8a0Sdrh Tcl_SetVar2(interp, "sqlite_options", "analyze", "0", TCL_GLOBAL_ONLY); 27739f18e8a0Sdrh #else 27749f18e8a0Sdrh Tcl_SetVar2(interp, "sqlite_options", "analyze", "1", TCL_GLOBAL_ONLY); 27759f18e8a0Sdrh #endif 27769f18e8a0Sdrh 277713d7042aSdrh #ifdef SQLITE_OMIT_AUTHORIZATION 277813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "auth", "0", TCL_GLOBAL_ONLY); 277913d7042aSdrh #else 278013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "auth", "1", TCL_GLOBAL_ONLY); 278113d7042aSdrh #endif 278213d7042aSdrh 2783f3388144Sdrh #ifdef SQLITE_OMIT_AUTOINCREMENT 2784f3388144Sdrh Tcl_SetVar2(interp, "sqlite_options", "autoinc", "0", TCL_GLOBAL_ONLY); 2785f3388144Sdrh #else 2786f3388144Sdrh Tcl_SetVar2(interp, "sqlite_options", "autoinc", "1", TCL_GLOBAL_ONLY); 2787f3388144Sdrh #endif 2788f3388144Sdrh 278945901d62Sdanielk1977 #ifdef SQLITE_OMIT_AUTOVACUUM 279045901d62Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "0", TCL_GLOBAL_ONLY); 279145901d62Sdanielk1977 #else 279245901d62Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "1", TCL_GLOBAL_ONLY); 2793f3388144Sdrh #endif /* SQLITE_OMIT_AUTOVACUUM */ 27944d36b81eSdanielk1977 #if !defined(SQLITE_DEFAULT_AUTOVACUUM) || SQLITE_DEFAULT_AUTOVACUUM==0 279545901d62Sdanielk1977 Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","0",TCL_GLOBAL_ONLY); 279645901d62Sdanielk1977 #else 279745901d62Sdanielk1977 Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","1",TCL_GLOBAL_ONLY); 279845901d62Sdanielk1977 #endif 279913d7042aSdrh 280055ef4d97Sdrh #ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION 280155ef4d97Sdrh Tcl_SetVar2(interp, "sqlite_options", "between_opt", "0", TCL_GLOBAL_ONLY); 280255ef4d97Sdrh #else 280355ef4d97Sdrh Tcl_SetVar2(interp, "sqlite_options", "between_opt", "1", TCL_GLOBAL_ONLY); 280455ef4d97Sdrh #endif 280555ef4d97Sdrh 280613d7042aSdrh #ifdef SQLITE_OMIT_BLOB_LITERAL 280713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "bloblit", "0", TCL_GLOBAL_ONLY); 280813d7042aSdrh #else 280913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY); 281013d7042aSdrh #endif 281113d7042aSdrh 2812487e262fSdrh #ifdef SQLITE_OMIT_CAST 2813487e262fSdrh Tcl_SetVar2(interp, "sqlite_options", "cast", "0", TCL_GLOBAL_ONLY); 2814487e262fSdrh #else 2815487e262fSdrh Tcl_SetVar2(interp, "sqlite_options", "cast", "1", TCL_GLOBAL_ONLY); 2816487e262fSdrh #endif 2817487e262fSdrh 2818ccae6026Sdrh #ifdef SQLITE_OMIT_COMPLETE 2819ccae6026Sdrh Tcl_SetVar2(interp, "sqlite_options", "complete", "0", TCL_GLOBAL_ONLY); 2820ccae6026Sdrh #else 2821ccae6026Sdrh Tcl_SetVar2(interp, "sqlite_options", "complete", "1", TCL_GLOBAL_ONLY); 2822ccae6026Sdrh #endif 2823ccae6026Sdrh 282413d7042aSdrh #ifdef SQLITE_OMIT_COMPOUND_SELECT 282513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "compound", "0", TCL_GLOBAL_ONLY); 282613d7042aSdrh #else 282713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "compound", "1", TCL_GLOBAL_ONLY); 282813d7042aSdrh #endif 282913d7042aSdrh 283013d7042aSdrh #ifdef SQLITE_OMIT_CONFLICT_CLAUSE 283113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "conflict", "0", TCL_GLOBAL_ONLY); 283213d7042aSdrh #else 283313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "conflict", "1", TCL_GLOBAL_ONLY); 283413d7042aSdrh #endif 283513d7042aSdrh 283613d7042aSdrh #ifdef SQLITE_OMIT_DATETIME_FUNCS 283713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "datetime", "0", TCL_GLOBAL_ONLY); 283813d7042aSdrh #else 283913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "datetime", "1", TCL_GLOBAL_ONLY); 284013d7042aSdrh #endif 284113d7042aSdrh 28422e66f0b9Sdrh #ifdef SQLITE_OMIT_DISKIO 28432e66f0b9Sdrh Tcl_SetVar2(interp, "sqlite_options", "diskio", "0", TCL_GLOBAL_ONLY); 28442e66f0b9Sdrh #else 28452e66f0b9Sdrh Tcl_SetVar2(interp, "sqlite_options", "diskio", "1", TCL_GLOBAL_ONLY); 28462e66f0b9Sdrh #endif 28472e66f0b9Sdrh 284813d7042aSdrh #ifdef SQLITE_OMIT_EXPLAIN 284913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "explain", "0", TCL_GLOBAL_ONLY); 285013d7042aSdrh #else 285113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "explain", "1", TCL_GLOBAL_ONLY); 285213d7042aSdrh #endif 285313d7042aSdrh 285413d7042aSdrh #ifdef SQLITE_OMIT_FLOATING_POINT 285513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "0", TCL_GLOBAL_ONLY); 285613d7042aSdrh #else 285713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "1", TCL_GLOBAL_ONLY); 285813d7042aSdrh #endif 285913d7042aSdrh 286013d7042aSdrh #ifdef SQLITE_OMIT_FOREIGN_KEY 286113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "0", TCL_GLOBAL_ONLY); 286213d7042aSdrh #else 286313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "1", TCL_GLOBAL_ONLY); 286413d7042aSdrh #endif 286513d7042aSdrh 28666b456a2bSdanielk1977 #ifdef SQLITE_OMIT_GLOBALRECOVER 28676b456a2bSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "0", TCL_GLOBAL_ONLY); 28686b456a2bSdanielk1977 #else 28696b456a2bSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "1", TCL_GLOBAL_ONLY); 28706b456a2bSdanielk1977 #endif 28716b456a2bSdanielk1977 287213d7042aSdrh #ifdef SQLITE_OMIT_INTEGRITY_CHECK 287313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "integrityck", "0", TCL_GLOBAL_ONLY); 287413d7042aSdrh #else 287513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "integrityck", "1", TCL_GLOBAL_ONLY); 287613d7042aSdrh #endif 287713d7042aSdrh 287855ef4d97Sdrh #ifdef SQLITE_OMIT_LIKE_OPTIMIZATION 287955ef4d97Sdrh Tcl_SetVar2(interp, "sqlite_options", "like_opt", "0", TCL_GLOBAL_ONLY); 288055ef4d97Sdrh #else 288155ef4d97Sdrh Tcl_SetVar2(interp, "sqlite_options", "like_opt", "1", TCL_GLOBAL_ONLY); 288255ef4d97Sdrh #endif 288355ef4d97Sdrh 288413d7042aSdrh #ifdef SQLITE_OMIT_MEMORYDB 288513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "memorydb", "0", TCL_GLOBAL_ONLY); 288613d7042aSdrh #else 288713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "memorydb", "1", TCL_GLOBAL_ONLY); 288813d7042aSdrh #endif 288913d7042aSdrh 289055ef4d97Sdrh #ifdef SQLITE_OMIT_OR_OPTIMIZATION 289155ef4d97Sdrh Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY); 289255ef4d97Sdrh #else 289355ef4d97Sdrh Tcl_SetVar2(interp, "sqlite_options", "or_opt", "1", TCL_GLOBAL_ONLY); 289455ef4d97Sdrh #endif 289555ef4d97Sdrh 289613d7042aSdrh #ifdef SQLITE_OMIT_PAGER_PRAGMAS 289713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "0", TCL_GLOBAL_ONLY); 289813d7042aSdrh #else 289913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "1", TCL_GLOBAL_ONLY); 290013d7042aSdrh #endif 290113d7042aSdrh 29022e66f0b9Sdrh #ifdef SQLITE_OMIT_PARSER 29032e66f0b9Sdrh Tcl_SetVar2(interp, "sqlite_options", "parser", "0", TCL_GLOBAL_ONLY); 29042e66f0b9Sdrh #else 29052e66f0b9Sdrh Tcl_SetVar2(interp, "sqlite_options", "parser", "1", TCL_GLOBAL_ONLY); 29062e66f0b9Sdrh #endif 29072e66f0b9Sdrh 2908bf21627bSdrh #if defined(SQLITE_OMIT_PRAGMA) || defined(SQLITE_OMIT_FLAG_PRAGMAS) 290913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pragma", "0", TCL_GLOBAL_ONLY); 291013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "integrityck", "0", TCL_GLOBAL_ONLY); 291113d7042aSdrh #else 291213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pragma", "1", TCL_GLOBAL_ONLY); 291313d7042aSdrh #endif 291413d7042aSdrh 291513d7042aSdrh #ifdef SQLITE_OMIT_PROGRESS_CALLBACK 291613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "progress", "0", TCL_GLOBAL_ONLY); 291713d7042aSdrh #else 291813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "progress", "1", TCL_GLOBAL_ONLY); 291913d7042aSdrh #endif 292013d7042aSdrh 292113d7042aSdrh #ifdef SQLITE_OMIT_REINDEX 292213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "reindex", "0", TCL_GLOBAL_ONLY); 292313d7042aSdrh #else 292413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "reindex", "1", TCL_GLOBAL_ONLY); 292513d7042aSdrh #endif 292613d7042aSdrh 292713d7042aSdrh #ifdef SQLITE_OMIT_SCHEMA_PRAGMAS 292813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "0", TCL_GLOBAL_ONLY); 292913d7042aSdrh #else 293013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "1", TCL_GLOBAL_ONLY); 293113d7042aSdrh #endif 293213d7042aSdrh 293313d7042aSdrh #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS 293413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_version", "0", TCL_GLOBAL_ONLY); 293513d7042aSdrh #else 293613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY); 293713d7042aSdrh #endif 293813d7042aSdrh 29393e8c37e7Sdanielk1977 #ifdef SQLITE_OMIT_SUBQUERY 29403e8c37e7Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "subquery", "0", TCL_GLOBAL_ONLY); 29413e8c37e7Sdanielk1977 #else 29423e8c37e7Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "subquery", "1", TCL_GLOBAL_ONLY); 29433e8c37e7Sdanielk1977 #endif 29443e8c37e7Sdanielk1977 294513d7042aSdrh #ifdef SQLITE_OMIT_TCL_VARIABLE 294613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "tclvar", "0", TCL_GLOBAL_ONLY); 294713d7042aSdrh #else 294813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "tclvar", "1", TCL_GLOBAL_ONLY); 294913d7042aSdrh #endif 295013d7042aSdrh 295113d7042aSdrh #if defined(THREADSAFE) && THREADSAFE 295213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "1", TCL_GLOBAL_ONLY); 295313d7042aSdrh #else 295413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "0", TCL_GLOBAL_ONLY); 295513d7042aSdrh #endif 295613d7042aSdrh 2957*19e2d37fSdrh #ifdef SQLITE_OMIT_TRACE 2958*19e2d37fSdrh Tcl_SetVar2(interp, "sqlite_options", "trace", "0", TCL_GLOBAL_ONLY); 2959*19e2d37fSdrh #else 2960*19e2d37fSdrh Tcl_SetVar2(interp, "sqlite_options", "trace", "1", TCL_GLOBAL_ONLY); 2961*19e2d37fSdrh #endif 2962*19e2d37fSdrh 296313d7042aSdrh #ifdef SQLITE_OMIT_TRIGGER 296413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "trigger", "0", TCL_GLOBAL_ONLY); 296513d7042aSdrh #else 296613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "trigger", "1", TCL_GLOBAL_ONLY); 296713d7042aSdrh #endif 296813d7042aSdrh 296953c0f748Sdanielk1977 #ifdef SQLITE_OMIT_TEMPDB 297053c0f748Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "tempdb", "0", TCL_GLOBAL_ONLY); 297153c0f748Sdanielk1977 #else 297253c0f748Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "tempdb", "1", TCL_GLOBAL_ONLY); 297353c0f748Sdanielk1977 #endif 297453c0f748Sdanielk1977 297513d7042aSdrh #ifdef SQLITE_OMIT_UTF16 297613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY); 297713d7042aSdrh #else 297813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "utf16", "1", TCL_GLOBAL_ONLY); 297913d7042aSdrh #endif 298013d7042aSdrh 298113d7042aSdrh #ifdef SQLITE_OMIT_VACUUM 298213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "vacuum", "0", TCL_GLOBAL_ONLY); 298313d7042aSdrh #else 298413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "vacuum", "1", TCL_GLOBAL_ONLY); 298513d7042aSdrh #endif 298613d7042aSdrh 298713d7042aSdrh #ifdef SQLITE_OMIT_VIEW 298813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "view", "0", TCL_GLOBAL_ONLY); 298913d7042aSdrh #else 299013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "view", "1", TCL_GLOBAL_ONLY); 299113d7042aSdrh #endif 299227d258a3Sdrh } 299327d258a3Sdrh 299427d258a3Sdrh /* 2995d1bf3512Sdrh ** Register commands with the TCL interpreter. 2996d1bf3512Sdrh */ 2997d1bf3512Sdrh int Sqlitetest1_Init(Tcl_Interp *interp){ 29986f8a503dSdanielk1977 extern int sqlite3_search_count; 29996f8a503dSdanielk1977 extern int sqlite3_interrupt_count; 30006f8a503dSdanielk1977 extern int sqlite3_open_file_count; 30016bf89570Sdrh extern int sqlite3_sort_count; 30026f8a503dSdanielk1977 extern int sqlite3_current_time; 3003c2eef3b3Sdrh static struct { 3004c2eef3b3Sdrh char *zName; 3005c2eef3b3Sdrh Tcl_CmdProc *xProc; 3006c2eef3b3Sdrh } aCmd[] = { 30076f8a503dSdanielk1977 { "sqlite3_mprintf_int", (Tcl_CmdProc*)sqlite3_mprintf_int }, 3008e9707671Sdrh { "sqlite3_mprintf_int64", (Tcl_CmdProc*)sqlite3_mprintf_int64 }, 30096f8a503dSdanielk1977 { "sqlite3_mprintf_str", (Tcl_CmdProc*)sqlite3_mprintf_str }, 3010e29b1a05Sdrh { "sqlite3_mprintf_stronly", (Tcl_CmdProc*)sqlite3_mprintf_stronly}, 30116f8a503dSdanielk1977 { "sqlite3_mprintf_double", (Tcl_CmdProc*)sqlite3_mprintf_double }, 30126f8a503dSdanielk1977 { "sqlite3_mprintf_scaled", (Tcl_CmdProc*)sqlite3_mprintf_scaled }, 30136f8a503dSdanielk1977 { "sqlite3_mprintf_z_test", (Tcl_CmdProc*)test_mprintf_z }, 30146f8a503dSdanielk1977 { "sqlite3_last_insert_rowid", (Tcl_CmdProc*)test_last_rowid }, 30156f8a503dSdanielk1977 { "sqlite3_exec_printf", (Tcl_CmdProc*)test_exec_printf }, 30166f8a503dSdanielk1977 { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, 30176f8a503dSdanielk1977 { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, 30186f8a503dSdanielk1977 { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, 30196f8a503dSdanielk1977 { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, 3020c2eef3b3Sdrh { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, 3021c2eef3b3Sdrh { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, 30222c336549Sdanielk1977 #ifdef SQLITE_MEMDEBUG 3023c2eef3b3Sdrh { "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail }, 3024c2eef3b3Sdrh { "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat }, 3025c2eef3b3Sdrh #endif 302696fc5fe6Sdanielk1977 { "sqlite_bind", (Tcl_CmdProc*)test_bind }, 302799ee3600Sdrh { "breakpoint", (Tcl_CmdProc*)test_breakpoint }, 302825d6543dSdrh { "sqlite3_key", (Tcl_CmdProc*)test_key }, 302925d6543dSdrh { "sqlite3_rekey", (Tcl_CmdProc*)test_rekey }, 3030cacb208eSdrh { "sqlite_set_magic", (Tcl_CmdProc*)sqlite_set_magic }, 3031c5cdca61Sdrh { "sqlite3_interrupt", (Tcl_CmdProc*)test_interrupt }, 3032600dd0baSdanielk1977 #if 0 3033600dd0baSdanielk1977 { "sqlite3_sleep", (Tcl_CmdProc*)test_sleep }, 3034600dd0baSdanielk1977 #endif 30359636c4e1Sdanielk1977 { "sqlite_delete_function", (Tcl_CmdProc*)delete_function }, 30363e1d8e63Sdrh { "sqlite_delete_collation", (Tcl_CmdProc*)delete_collation }, 30373e1d8e63Sdrh { "sqlite3_get_autocommit", (Tcl_CmdProc*)get_autocommit }, 3038c2eef3b3Sdrh }; 303951e3d8e2Sdanielk1977 static struct { 304051e3d8e2Sdanielk1977 char *zName; 304151e3d8e2Sdanielk1977 Tcl_ObjCmdProc *xProc; 304204f2e68dSdanielk1977 void *clientData; 304351e3d8e2Sdanielk1977 } aObjCmd[] = { 3044241db313Sdrh { "sqlite3_bind_int", test_bind_int, 0 }, 304504f2e68dSdanielk1977 { "sqlite3_bind_int64", test_bind_int64, 0 }, 304604f2e68dSdanielk1977 { "sqlite3_bind_double", test_bind_double, 0 }, 304704f2e68dSdanielk1977 { "sqlite3_bind_null", test_bind_null ,0 }, 304804f2e68dSdanielk1977 { "sqlite3_bind_text", test_bind_text ,0 }, 304904f2e68dSdanielk1977 { "sqlite3_bind_text16", test_bind_text16 ,0 }, 305004f2e68dSdanielk1977 { "sqlite3_bind_blob", test_bind_blob ,0 }, 305175f6a032Sdrh { "sqlite3_bind_parameter_count", test_bind_parameter_count, 0}, 3052895d7472Sdrh { "sqlite3_bind_parameter_name", test_bind_parameter_name, 0}, 3053fa6bc000Sdrh { "sqlite3_bind_parameter_index", test_bind_parameter_index, 0}, 3054600dd0baSdanielk1977 #if 0 3055600dd0baSdanielk1977 { "sqlite3_clear_bindings", test_clear_bindings, 0}, 3056600dd0baSdanielk1977 #endif 305704f2e68dSdanielk1977 { "sqlite3_errcode", test_errcode ,0 }, 305804f2e68dSdanielk1977 { "sqlite3_errmsg", test_errmsg ,0 }, 305904f2e68dSdanielk1977 { "sqlite3_errmsg16", test_errmsg16 ,0 }, 306004f2e68dSdanielk1977 { "sqlite3_open", test_open ,0 }, 306104f2e68dSdanielk1977 { "sqlite3_open16", test_open16 ,0 }, 3062bc6ada41Sdanielk1977 { "sqlite3_complete16", test_complete16 ,0 }, 306304f2e68dSdanielk1977 306404f2e68dSdanielk1977 { "sqlite3_prepare", test_prepare ,0 }, 306504f2e68dSdanielk1977 { "sqlite3_prepare16", test_prepare16 ,0 }, 306604f2e68dSdanielk1977 { "sqlite3_finalize", test_finalize ,0 }, 306704f2e68dSdanielk1977 { "sqlite3_reset", test_reset ,0 }, 3068d89bd007Sdrh { "sqlite3_expired", test_expired ,0 }, 3069f8db1bc0Sdrh { "sqlite3_transfer_bindings", test_transfer_bind ,0 }, 3070fbcd585fSdanielk1977 { "sqlite3_changes", test_changes ,0 }, 307104f2e68dSdanielk1977 { "sqlite3_step", test_step ,0 }, 307204f2e68dSdanielk1977 307304f2e68dSdanielk1977 /* sqlite3_column_*() API */ 307404f2e68dSdanielk1977 { "sqlite3_column_count", test_column_count ,0 }, 307504f2e68dSdanielk1977 { "sqlite3_data_count", test_data_count ,0 }, 307604f2e68dSdanielk1977 { "sqlite3_column_type", test_column_type ,0 }, 3077ea61b2c4Sdanielk1977 { "sqlite3_column_blob", test_column_blob ,0 }, 307804f2e68dSdanielk1977 { "sqlite3_column_double", test_column_double ,0 }, 307904f2e68dSdanielk1977 { "sqlite3_column_int64", test_column_int64 ,0 }, 308004f2e68dSdanielk1977 { "sqlite3_column_text", test_stmt_utf8, sqlite3_column_text }, 308104f2e68dSdanielk1977 { "sqlite3_column_decltype", test_stmt_utf8, sqlite3_column_decltype }, 308204f2e68dSdanielk1977 { "sqlite3_column_name", test_stmt_utf8, sqlite3_column_name }, 30836c62608fSdrh { "sqlite3_column_int", test_stmt_int, sqlite3_column_int }, 30846c62608fSdrh { "sqlite3_column_bytes", test_stmt_int, sqlite3_column_bytes }, 30856c62608fSdrh #ifndef SQLITE_OMIT_UTF16 30866c62608fSdrh { "sqlite3_column_bytes16", test_stmt_int, sqlite3_column_bytes16 }, 308704f2e68dSdanielk1977 { "sqlite3_column_text16", test_stmt_utf16, sqlite3_column_text16 }, 308804f2e68dSdanielk1977 { "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16}, 308904f2e68dSdanielk1977 { "sqlite3_column_name16", test_stmt_utf16, sqlite3_column_name16 }, 30906c62608fSdrh #endif 30916b456a2bSdanielk1977 { "sqlite3_global_recover", test_global_recover, 0 }, 309204f2e68dSdanielk1977 30939a1d0abeSdanielk1977 /* Functions from os.h */ 309444ee5bf7Sdanielk1977 #ifndef SQLITE_OMIT_DISKIO 30959a1d0abeSdanielk1977 { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 }, 30969a1d0abeSdanielk1977 { "sqlite3OsClose", test_sqlite3OsClose, 0 }, 30979a1d0abeSdanielk1977 { "sqlite3OsLock", test_sqlite3OsLock, 0 }, 3098ab3f9feaSdrh { "sqlite3OsTempFileName", test_sqlite3OsTempFileName, 0 }, 3099312d6b36Sdanielk1977 3100312d6b36Sdanielk1977 /* Custom test interfaces */ 31019a1d0abeSdanielk1977 { "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 }, 310244ee5bf7Sdanielk1977 #endif 31035436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 31044e6af134Sdanielk1977 { "add_test_collate", test_collate, 0 }, 3105312d6b36Sdanielk1977 { "add_test_collate_needed", test_collate_needed, 0 }, 3106c8e9a2dfSdanielk1977 { "add_test_function", test_function, 0 }, 31075436dc2dSdrh #endif 3108c8e9a2dfSdanielk1977 { "sqlite3_crashparams", sqlite3_crashparams, 0 }, 3109312d6b36Sdanielk1977 { "sqlite3_test_errstr", test_errstr, 0 }, 311092febd92Sdrh { "tcl_variable_type", tcl_variable_type, 0 }, 311151e3d8e2Sdanielk1977 }; 31121398ad36Sdrh static int bitmask_size = sizeof(Bitmask)*8; 3113c2eef3b3Sdrh int i; 31142ac3ee97Sdrh extern int sqlite3_os_trace; 311551147baaSdrh extern int sqlite3_where_trace; 3116b851b2c9Sdrh extern int sqlite3_sync_count, sqlite3_fullsync_count; 3117af6df11fSdrh extern int sqlite3_opentemp_count; 311801397205Sdrh extern int sqlite3_memUsed; 311901397205Sdrh extern int sqlite3_memMax; 312084bfda41Sdrh extern char sqlite3_query_plan[]; 312155ef4d97Sdrh extern int sqlite3_like_count; 31228b3d990bSdrh #ifdef SQLITE_DEBUG 31238b3d990bSdrh extern int sqlite3_vdbe_addop_trace; 31248b3d990bSdrh #endif 31259042f395Sdrh static char *query_plan = sqlite3_query_plan; 3126c2eef3b3Sdrh 3127c2eef3b3Sdrh for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ 3128c2eef3b3Sdrh Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); 3129c2eef3b3Sdrh } 313051e3d8e2Sdanielk1977 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ 3131c572ef7fSdanielk1977 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 3132c572ef7fSdanielk1977 aObjCmd[i].xProc, aObjCmd[i].clientData, 0); 313351e3d8e2Sdanielk1977 } 31346490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_search_count", 31356f8a503dSdanielk1977 (char*)&sqlite3_search_count, TCL_LINK_INT); 31366bf89570Sdrh Tcl_LinkVar(interp, "sqlite_sort_count", 31376bf89570Sdrh (char*)&sqlite3_sort_count, TCL_LINK_INT); 313855ef4d97Sdrh Tcl_LinkVar(interp, "sqlite_like_count", 313955ef4d97Sdrh (char*)&sqlite3_like_count, TCL_LINK_INT); 31406490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_interrupt_count", 31416f8a503dSdanielk1977 (char*)&sqlite3_interrupt_count, TCL_LINK_INT); 31426490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_open_file_count", 31436f8a503dSdanielk1977 (char*)&sqlite3_open_file_count, TCL_LINK_INT); 31446490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_current_time", 31456f8a503dSdanielk1977 (char*)&sqlite3_current_time, TCL_LINK_INT); 31462ac3ee97Sdrh Tcl_LinkVar(interp, "sqlite_os_trace", 31472ac3ee97Sdrh (char*)&sqlite3_os_trace, TCL_LINK_INT); 314851147baaSdrh Tcl_LinkVar(interp, "sqlite_where_trace", 314951147baaSdrh (char*)&sqlite3_where_trace, TCL_LINK_INT); 31508b3d990bSdrh #ifdef SQLITE_DEBUG 31518b3d990bSdrh Tcl_LinkVar(interp, "sqlite_addop_trace", 31528b3d990bSdrh (char*)&sqlite3_vdbe_addop_trace, TCL_LINK_INT); 31538b3d990bSdrh #endif 31547018030dSdrh #ifdef SQLITE_MEMDEBUG 315501397205Sdrh Tcl_LinkVar(interp, "sqlite_memused", 315601397205Sdrh (char*)&sqlite3_memUsed, TCL_LINK_INT | TCL_LINK_READ_ONLY); 315701397205Sdrh Tcl_LinkVar(interp, "sqlite_memmax", 315801397205Sdrh (char*)&sqlite3_memMax, TCL_LINK_INT | TCL_LINK_READ_ONLY); 31597018030dSdrh #endif 316084bfda41Sdrh Tcl_LinkVar(interp, "sqlite_query_plan", 31619042f395Sdrh (char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY); 3162cbe21be3Sdanielk1977 #ifndef SQLITE_OMIT_DISKIO 3163af6df11fSdrh Tcl_LinkVar(interp, "sqlite_opentemp_count", 3164af6df11fSdrh (char*)&sqlite3_opentemp_count, TCL_LINK_INT); 3165cbe21be3Sdanielk1977 #endif 31667c972decSdrh Tcl_LinkVar(interp, "sqlite_static_bind_value", 31677c972decSdrh (char*)&sqlite_static_bind_value, TCL_LINK_STRING); 3168ab3f9feaSdrh Tcl_LinkVar(interp, "sqlite_temp_directory", 3169effd02bcSdrh (char*)&sqlite3_temp_directory, TCL_LINK_STRING); 31701398ad36Sdrh Tcl_LinkVar(interp, "bitmask_size", 31711398ad36Sdrh (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); 3172748f763fSdrh #if OS_UNIX 3173b851b2c9Sdrh Tcl_LinkVar(interp, "sqlite_sync_count", 3174b851b2c9Sdrh (char*)&sqlite3_sync_count, TCL_LINK_INT); 3175b851b2c9Sdrh Tcl_LinkVar(interp, "sqlite_fullsync_count", 3176b851b2c9Sdrh (char*)&sqlite3_fullsync_count, TCL_LINK_INT); 3177748f763fSdrh #endif /* OS_UNIX */ 317827d258a3Sdrh set_options(interp); 3179d1bf3512Sdrh return TCL_OK; 3180d1bf3512Sdrh } 3181