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*51147baaSdrh ** $Id: test1.c,v 1.151 2005/07/23 22:59:56 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_INTERNAL: zName = "SQLITE_INTERNAL"; break; 306622cce3Sdanielk1977 case SQLITE_PERM: zName = "SQLITE_PERM"; break; 316622cce3Sdanielk1977 case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; 326622cce3Sdanielk1977 case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; 336622cce3Sdanielk1977 case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; 346622cce3Sdanielk1977 case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; 356622cce3Sdanielk1977 case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; 366622cce3Sdanielk1977 case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; 376622cce3Sdanielk1977 case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; 386622cce3Sdanielk1977 case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; 396622cce3Sdanielk1977 case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; 406622cce3Sdanielk1977 case SQLITE_FULL: zName = "SQLITE_FULL"; break; 416622cce3Sdanielk1977 case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; 426622cce3Sdanielk1977 case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; 436622cce3Sdanielk1977 case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; 446622cce3Sdanielk1977 case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; 456622cce3Sdanielk1977 case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break; 466622cce3Sdanielk1977 case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; 476622cce3Sdanielk1977 case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; 486622cce3Sdanielk1977 case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; 496622cce3Sdanielk1977 case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; 506622cce3Sdanielk1977 case SQLITE_AUTH: zName = "SQLITE_AUTH"; break; 516622cce3Sdanielk1977 case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break; 526622cce3Sdanielk1977 case SQLITE_RANGE: zName = "SQLITE_RANGE"; break; 536622cce3Sdanielk1977 case SQLITE_ROW: zName = "SQLITE_ROW"; break; 546622cce3Sdanielk1977 case SQLITE_DONE: zName = "SQLITE_DONE"; break; 55312d6b36Sdanielk1977 case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break; 566622cce3Sdanielk1977 default: zName = "SQLITE_Unknown"; break; 576622cce3Sdanielk1977 } 586622cce3Sdanielk1977 return zName; 596622cce3Sdanielk1977 } 602e66f0b9Sdrh #define errorName sqlite3TestErrorName 616622cce3Sdanielk1977 62d1bf3512Sdrh /* 63c60d0446Sdrh ** Convert an sqlite3_stmt* into an sqlite3*. This depends on the 64c60d0446Sdrh ** fact that the sqlite3* is the first field in the Vdbe structure. 65c60d0446Sdrh */ 6651942bc3Sdrh #define StmtToDb(X) sqlite3_db_handle(X) 67c60d0446Sdrh 68c60d0446Sdrh /* 69c60d0446Sdrh ** Check a return value to make sure it agrees with the results 70c60d0446Sdrh ** from sqlite3_errcode. 71c60d0446Sdrh */ 72c60d0446Sdrh int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){ 73c60d0446Sdrh if( rc!=SQLITE_MISUSE && rc!=SQLITE_OK && sqlite3_errcode(db)!=rc ){ 74c60d0446Sdrh char zBuf[200]; 75c60d0446Sdrh int r2 = sqlite3_errcode(db); 76c60d0446Sdrh sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)", 77c60d0446Sdrh errorName(rc), rc, errorName(r2), r2); 78c60d0446Sdrh Tcl_ResetResult(interp); 79c60d0446Sdrh Tcl_AppendResult(interp, zBuf, 0); 80c60d0446Sdrh return 1; 81c60d0446Sdrh } 82c60d0446Sdrh return 0; 83c60d0446Sdrh } 84c60d0446Sdrh 85c60d0446Sdrh /* 869bb575fdSdrh ** Decode a pointer to an sqlite3 object. 87b86ccfb2Sdrh */ 889bb575fdSdrh static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){ 89fe63d1c9Sdrh *ppDb = (sqlite3*)sqlite3TextToPtr(zA); 90b86ccfb2Sdrh return TCL_OK; 91b86ccfb2Sdrh } 92b86ccfb2Sdrh 93b86ccfb2Sdrh /* 9451e3d8e2Sdanielk1977 ** Decode a pointer to an sqlite3_stmt object. 9551e3d8e2Sdanielk1977 */ 9651e3d8e2Sdanielk1977 static int getStmtPointer( 9751e3d8e2Sdanielk1977 Tcl_Interp *interp, 9851e3d8e2Sdanielk1977 const char *zArg, 9951e3d8e2Sdanielk1977 sqlite3_stmt **ppStmt 10051e3d8e2Sdanielk1977 ){ 101fe63d1c9Sdrh *ppStmt = (sqlite3_stmt*)sqlite3TextToPtr(zArg); 10251e3d8e2Sdanielk1977 return TCL_OK; 10351e3d8e2Sdanielk1977 } 10451e3d8e2Sdanielk1977 10551e3d8e2Sdanielk1977 /* 1069a1d0abeSdanielk1977 ** Decode a pointer to an sqlite3_stmt object. 1079a1d0abeSdanielk1977 */ 1089a1d0abeSdanielk1977 static int getFilePointer( 1099a1d0abeSdanielk1977 Tcl_Interp *interp, 1109a1d0abeSdanielk1977 const char *zArg, 1119a1d0abeSdanielk1977 OsFile **ppFile 1129a1d0abeSdanielk1977 ){ 113fe63d1c9Sdrh *ppFile = (OsFile*)sqlite3TextToPtr(zArg); 1149a1d0abeSdanielk1977 return TCL_OK; 1159a1d0abeSdanielk1977 } 1169a1d0abeSdanielk1977 1179a1d0abeSdanielk1977 /* 1187d8085a8Sdrh ** Generate a text representation of a pointer that can be understood 1197d8085a8Sdrh ** by the getDbPointer and getVmPointer routines above. 1207d8085a8Sdrh ** 1217d8085a8Sdrh ** The problem is, on some machines (Solaris) if you do a printf with 1227d8085a8Sdrh ** "%p" you cannot turn around and do a scanf with the same "%p" and 1237d8085a8Sdrh ** get your pointer back. You have to prepend a "0x" before it will 1247d8085a8Sdrh ** work. Or at least that is what is reported to me (drh). But this 1257d8085a8Sdrh ** behavior varies from machine to machine. The solution used her is 1267d8085a8Sdrh ** to test the string right after it is generated to see if it can be 1277d8085a8Sdrh ** understood by scanf, and if not, try prepending an "0x" to see if 1287d8085a8Sdrh ** that helps. If nothing works, a fatal error is generated. 1297d8085a8Sdrh */ 1307d8085a8Sdrh static int makePointerStr(Tcl_Interp *interp, char *zPtr, void *p){ 131fe63d1c9Sdrh sqlite3_snprintf(100, zPtr, "%p", p); 1327d8085a8Sdrh return TCL_OK; 1337d8085a8Sdrh } 1347d8085a8Sdrh 1357d8085a8Sdrh /* 1366f8a503dSdanielk1977 ** The callback routine for sqlite3_exec_printf(). 137d1bf3512Sdrh */ 138d1bf3512Sdrh static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){ 139d1bf3512Sdrh Tcl_DString *str = (Tcl_DString*)pArg; 140d1bf3512Sdrh int i; 141d1bf3512Sdrh 142d1bf3512Sdrh if( Tcl_DStringLength(str)==0 ){ 143d1bf3512Sdrh for(i=0; i<argc; i++){ 144d1bf3512Sdrh Tcl_DStringAppendElement(str, name[i] ? name[i] : "NULL"); 145d1bf3512Sdrh } 146d1bf3512Sdrh } 147d1bf3512Sdrh for(i=0; i<argc; i++){ 148d1bf3512Sdrh Tcl_DStringAppendElement(str, argv[i] ? argv[i] : "NULL"); 149d1bf3512Sdrh } 150d1bf3512Sdrh return 0; 151d1bf3512Sdrh } 152d1bf3512Sdrh 153d1bf3512Sdrh /* 1546f8a503dSdanielk1977 ** Usage: sqlite3_exec_printf DB FORMAT STRING 155d1bf3512Sdrh ** 1566f8a503dSdanielk1977 ** Invoke the sqlite3_exec_printf() interface using the open database 157d1bf3512Sdrh ** DB. The SQL is the string FORMAT. The format string should contain 158d1bf3512Sdrh ** one %s or %q. STRING is the value inserted into %s or %q. 159d1bf3512Sdrh */ 160d1bf3512Sdrh static int test_exec_printf( 161d1bf3512Sdrh void *NotUsed, 162d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 163d1bf3512Sdrh int argc, /* Number of arguments */ 164d1bf3512Sdrh char **argv /* Text of each argument */ 165d1bf3512Sdrh ){ 1669bb575fdSdrh sqlite3 *db; 167d1bf3512Sdrh Tcl_DString str; 168d1bf3512Sdrh int rc; 169d1bf3512Sdrh char *zErr = 0; 1701211de37Sdrh char *zSql; 171d1bf3512Sdrh char zBuf[30]; 172d1bf3512Sdrh if( argc!=4 ){ 173d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 174d1bf3512Sdrh " DB FORMAT STRING", 0); 175d1bf3512Sdrh return TCL_ERROR; 176d1bf3512Sdrh } 177b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 178d1bf3512Sdrh Tcl_DStringInit(&str); 1791211de37Sdrh zSql = sqlite3_mprintf(argv[2], argv[3]); 1801211de37Sdrh rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr); 1811211de37Sdrh sqlite3_free(zSql); 182d1bf3512Sdrh sprintf(zBuf, "%d", rc); 183d1bf3512Sdrh Tcl_AppendElement(interp, zBuf); 184d1bf3512Sdrh Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr); 185d1bf3512Sdrh Tcl_DStringFree(&str); 186d1bf3512Sdrh if( zErr ) free(zErr); 187c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 188d1bf3512Sdrh return TCL_OK; 189d1bf3512Sdrh } 190d1bf3512Sdrh 191d1bf3512Sdrh /* 1926f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_z_test SEPARATOR ARG0 ARG1 ... 193d93d8a81Sdrh ** 194d93d8a81Sdrh ** Test the %z format of mprintf(). Use multiple mprintf() calls to 195d93d8a81Sdrh ** concatenate arg0 through argn using separator as the separator. 196d93d8a81Sdrh ** Return the result. 197d93d8a81Sdrh */ 198d93d8a81Sdrh static int test_mprintf_z( 199d93d8a81Sdrh void *NotUsed, 200d93d8a81Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 201d93d8a81Sdrh int argc, /* Number of arguments */ 202d93d8a81Sdrh char **argv /* Text of each argument */ 203d93d8a81Sdrh ){ 204d93d8a81Sdrh char *zResult = 0; 205d93d8a81Sdrh int i; 206d93d8a81Sdrh 207d93d8a81Sdrh for(i=2; i<argc; i++){ 2084adee20fSdanielk1977 zResult = sqlite3MPrintf("%z%s%s", zResult, argv[1], argv[i]); 209d93d8a81Sdrh } 210d93d8a81Sdrh Tcl_AppendResult(interp, zResult, 0); 2115f968436Sdrh sqliteFree(zResult); 212d93d8a81Sdrh return TCL_OK; 213d93d8a81Sdrh } 214d93d8a81Sdrh 215d93d8a81Sdrh /* 2166f8a503dSdanielk1977 ** Usage: sqlite3_get_table_printf DB FORMAT STRING 217d1bf3512Sdrh ** 2186f8a503dSdanielk1977 ** Invoke the sqlite3_get_table_printf() interface using the open database 219d1bf3512Sdrh ** DB. The SQL is the string FORMAT. The format string should contain 220d1bf3512Sdrh ** one %s or %q. STRING is the value inserted into %s or %q. 221d1bf3512Sdrh */ 222d1bf3512Sdrh static int test_get_table_printf( 223d1bf3512Sdrh void *NotUsed, 224d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 225d1bf3512Sdrh int argc, /* Number of arguments */ 226d1bf3512Sdrh char **argv /* Text of each argument */ 227d1bf3512Sdrh ){ 2289bb575fdSdrh sqlite3 *db; 229d1bf3512Sdrh Tcl_DString str; 230d1bf3512Sdrh int rc; 231d1bf3512Sdrh char *zErr = 0; 232d1bf3512Sdrh int nRow, nCol; 233d1bf3512Sdrh char **aResult; 234d1bf3512Sdrh int i; 235d1bf3512Sdrh char zBuf[30]; 2361211de37Sdrh char *zSql; 237d1bf3512Sdrh if( argc!=4 ){ 238d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 239d1bf3512Sdrh " DB FORMAT STRING", 0); 240d1bf3512Sdrh return TCL_ERROR; 241d1bf3512Sdrh } 242b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 243d1bf3512Sdrh Tcl_DStringInit(&str); 2441211de37Sdrh zSql = sqlite3_mprintf(argv[2],argv[3]); 2451211de37Sdrh rc = sqlite3_get_table(db, zSql, &aResult, &nRow, &nCol, &zErr); 2461211de37Sdrh sqlite3_free(zSql); 247d1bf3512Sdrh sprintf(zBuf, "%d", rc); 248d1bf3512Sdrh Tcl_AppendElement(interp, zBuf); 249d1bf3512Sdrh if( rc==SQLITE_OK ){ 250d1bf3512Sdrh sprintf(zBuf, "%d", nRow); 251d1bf3512Sdrh Tcl_AppendElement(interp, zBuf); 252d1bf3512Sdrh sprintf(zBuf, "%d", nCol); 253d1bf3512Sdrh Tcl_AppendElement(interp, zBuf); 254d1bf3512Sdrh for(i=0; i<(nRow+1)*nCol; i++){ 255d1bf3512Sdrh Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL"); 256d1bf3512Sdrh } 257d1bf3512Sdrh }else{ 258d1bf3512Sdrh Tcl_AppendElement(interp, zErr); 259d1bf3512Sdrh } 2606f8a503dSdanielk1977 sqlite3_free_table(aResult); 261d1bf3512Sdrh if( zErr ) free(zErr); 262c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 263d1bf3512Sdrh return TCL_OK; 264d1bf3512Sdrh } 265d1bf3512Sdrh 266af9ff33aSdrh 267af9ff33aSdrh /* 2686f8a503dSdanielk1977 ** Usage: sqlite3_last_insert_rowid DB 269af9ff33aSdrh ** 270af9ff33aSdrh ** Returns the integer ROWID of the most recent insert. 271af9ff33aSdrh */ 272af9ff33aSdrh static int test_last_rowid( 273af9ff33aSdrh void *NotUsed, 274af9ff33aSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 275af9ff33aSdrh int argc, /* Number of arguments */ 276af9ff33aSdrh char **argv /* Text of each argument */ 277af9ff33aSdrh ){ 2789bb575fdSdrh sqlite3 *db; 279af9ff33aSdrh char zBuf[30]; 280af9ff33aSdrh 281af9ff33aSdrh if( argc!=2 ){ 282af9ff33aSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0); 283af9ff33aSdrh return TCL_ERROR; 284af9ff33aSdrh } 285b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 286c572ef7fSdanielk1977 sprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db)); 287af9ff33aSdrh Tcl_AppendResult(interp, zBuf, 0); 288af9ff33aSdrh return SQLITE_OK; 289af9ff33aSdrh } 290af9ff33aSdrh 291d1bf3512Sdrh /* 29225d6543dSdrh ** Usage: sqlite3_key DB KEY 29325d6543dSdrh ** 29425d6543dSdrh ** Set the codec key. 29525d6543dSdrh */ 29625d6543dSdrh static int test_key( 29725d6543dSdrh void *NotUsed, 29825d6543dSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 29925d6543dSdrh int argc, /* Number of arguments */ 30025d6543dSdrh char **argv /* Text of each argument */ 30125d6543dSdrh ){ 3029bb575fdSdrh sqlite3 *db; 30325d6543dSdrh const char *zKey; 30425d6543dSdrh int nKey; 30525d6543dSdrh if( argc!=3 ){ 30625d6543dSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 30725d6543dSdrh " FILENAME\"", 0); 30825d6543dSdrh return TCL_ERROR; 30925d6543dSdrh } 31025d6543dSdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 31125d6543dSdrh zKey = argv[2]; 31225d6543dSdrh nKey = strlen(zKey); 31325d6543dSdrh #ifdef SQLITE_HAS_CODEC 31425d6543dSdrh sqlite3_key(db, zKey, nKey); 31525d6543dSdrh #endif 31625d6543dSdrh return TCL_OK; 31725d6543dSdrh } 31825d6543dSdrh 31925d6543dSdrh /* 32025d6543dSdrh ** Usage: sqlite3_rekey DB KEY 32125d6543dSdrh ** 32225d6543dSdrh ** Change the codec key. 32325d6543dSdrh */ 32425d6543dSdrh static int test_rekey( 32525d6543dSdrh void *NotUsed, 32625d6543dSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 32725d6543dSdrh int argc, /* Number of arguments */ 32825d6543dSdrh char **argv /* Text of each argument */ 32925d6543dSdrh ){ 3309bb575fdSdrh sqlite3 *db; 33125d6543dSdrh const char *zKey; 33225d6543dSdrh int nKey; 33325d6543dSdrh if( argc!=3 ){ 33425d6543dSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 33525d6543dSdrh " FILENAME\"", 0); 33625d6543dSdrh return TCL_ERROR; 33725d6543dSdrh } 33825d6543dSdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 33925d6543dSdrh zKey = argv[2]; 34025d6543dSdrh nKey = strlen(zKey); 34125d6543dSdrh #ifdef SQLITE_HAS_CODEC 34225d6543dSdrh sqlite3_rekey(db, zKey, nKey); 34325d6543dSdrh #endif 34425d6543dSdrh return TCL_OK; 34525d6543dSdrh } 34625d6543dSdrh 34725d6543dSdrh /* 3486f8a503dSdanielk1977 ** Usage: sqlite3_close DB 349d1bf3512Sdrh ** 3506f8a503dSdanielk1977 ** Closes the database opened by sqlite3_open. 351d1bf3512Sdrh */ 352d1bf3512Sdrh static int sqlite_test_close( 353d1bf3512Sdrh void *NotUsed, 354d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 355d1bf3512Sdrh int argc, /* Number of arguments */ 356d1bf3512Sdrh char **argv /* Text of each argument */ 357d1bf3512Sdrh ){ 3589bb575fdSdrh sqlite3 *db; 35996d81f99Sdanielk1977 int rc; 360d1bf3512Sdrh if( argc!=2 ){ 361d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 362d1bf3512Sdrh " FILENAME\"", 0); 363d1bf3512Sdrh return TCL_ERROR; 364d1bf3512Sdrh } 365b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 36696d81f99Sdanielk1977 rc = sqlite3_close(db); 367f9d64d2cSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 368d1bf3512Sdrh return TCL_OK; 369d1bf3512Sdrh } 370d1bf3512Sdrh 371d1bf3512Sdrh /* 372c22bd47dSdrh ** Implementation of the x_coalesce() function. 373c22bd47dSdrh ** Return the first argument non-NULL argument. 374c22bd47dSdrh */ 3750ae8b831Sdanielk1977 static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 376c22bd47dSdrh int i; 377c22bd47dSdrh for(i=0; i<argc; i++){ 3789c054830Sdrh if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){ 379d8123366Sdanielk1977 sqlite3_result_text(context, sqlite3_value_text(argv[i]), -1, 380d8123366Sdanielk1977 SQLITE_TRANSIENT); 381c22bd47dSdrh break; 382c22bd47dSdrh } 383c22bd47dSdrh } 384c22bd47dSdrh } 385c22bd47dSdrh 386c22bd47dSdrh /* 387d1d9fc33Sdrh ** A structure into which to accumulate text. 388d1d9fc33Sdrh */ 389d1d9fc33Sdrh struct dstr { 390d1d9fc33Sdrh int nAlloc; /* Space allocated */ 391d1d9fc33Sdrh int nUsed; /* Space used */ 392d1d9fc33Sdrh char *z; /* The space */ 393d1d9fc33Sdrh }; 394d1d9fc33Sdrh 395d1d9fc33Sdrh /* 396d1d9fc33Sdrh ** Append text to a dstr 397d1d9fc33Sdrh */ 398d1d9fc33Sdrh static void dstrAppend(struct dstr *p, const char *z, int divider){ 399d1d9fc33Sdrh int n = strlen(z); 400d1d9fc33Sdrh if( p->nUsed + n + 2 > p->nAlloc ){ 401d1d9fc33Sdrh char *zNew; 402d1d9fc33Sdrh p->nAlloc = p->nAlloc*2 + n + 200; 403d1d9fc33Sdrh zNew = sqliteRealloc(p->z, p->nAlloc); 404d1d9fc33Sdrh if( zNew==0 ){ 405d1d9fc33Sdrh sqliteFree(p->z); 406d1d9fc33Sdrh memset(p, 0, sizeof(*p)); 407d1d9fc33Sdrh return; 408d1d9fc33Sdrh } 409d1d9fc33Sdrh p->z = zNew; 410d1d9fc33Sdrh } 411d1d9fc33Sdrh if( divider && p->nUsed>0 ){ 412d1d9fc33Sdrh p->z[p->nUsed++] = divider; 413d1d9fc33Sdrh } 414d1d9fc33Sdrh memcpy(&p->z[p->nUsed], z, n+1); 415d1d9fc33Sdrh p->nUsed += n; 416d1d9fc33Sdrh } 417d1d9fc33Sdrh 418d1d9fc33Sdrh /* 4194adee20fSdanielk1977 ** Invoked for each callback from sqlite3ExecFunc 420d1d9fc33Sdrh */ 421d1d9fc33Sdrh static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){ 422d1d9fc33Sdrh struct dstr *p = (struct dstr*)pData; 423d1d9fc33Sdrh int i; 424d1d9fc33Sdrh for(i=0; i<argc; i++){ 425d1d9fc33Sdrh if( argv[i]==0 ){ 426d1d9fc33Sdrh dstrAppend(p, "NULL", ' '); 427d1d9fc33Sdrh }else{ 428d1d9fc33Sdrh dstrAppend(p, argv[i], ' '); 429d1d9fc33Sdrh } 430d1d9fc33Sdrh } 431d1d9fc33Sdrh return 0; 432d1d9fc33Sdrh } 433d1d9fc33Sdrh 434d1d9fc33Sdrh /* 435e35ee196Sdanielk1977 ** Implementation of the x_sqlite_exec() function. This function takes 436c22bd47dSdrh ** a single argument and attempts to execute that argument as SQL code. 4376cbe1f1bSdrh ** This is illegal and should set the SQLITE_MISUSE flag on the database. 438c22bd47dSdrh ** 4396f8a503dSdanielk1977 ** 2004-Jan-07: We have changed this to make it legal to call sqlite3_exec() 440d1d9fc33Sdrh ** from within a function call. 441d1d9fc33Sdrh ** 442c22bd47dSdrh ** This routine simulates the effect of having two threads attempt to 443c22bd47dSdrh ** use the same database at the same time. 444c22bd47dSdrh */ 44551ad0ecdSdanielk1977 static void sqlite3ExecFunc( 4460ae8b831Sdanielk1977 sqlite3_context *context, 44751ad0ecdSdanielk1977 int argc, 44851ad0ecdSdanielk1977 sqlite3_value **argv 44951ad0ecdSdanielk1977 ){ 450d1d9fc33Sdrh struct dstr x; 451d1d9fc33Sdrh memset(&x, 0, sizeof(x)); 4529bb575fdSdrh sqlite3_exec((sqlite3*)sqlite3_user_data(context), 4534f26d6c4Sdrh sqlite3_value_text(argv[0]), 454d1d9fc33Sdrh execFuncCallback, &x, 0); 455d8123366Sdanielk1977 sqlite3_result_text(context, x.z, x.nUsed, SQLITE_TRANSIENT); 456d1d9fc33Sdrh sqliteFree(x.z); 457c22bd47dSdrh } 458c22bd47dSdrh 459c22bd47dSdrh /* 460c22bd47dSdrh ** Usage: sqlite_test_create_function DB 461c22bd47dSdrh ** 4626f8a503dSdanielk1977 ** Call the sqlite3_create_function API on the given database in order 463c22bd47dSdrh ** to create a function named "x_coalesce". This function does the same thing 464c22bd47dSdrh ** as the "coalesce" function. This function also registers an SQL function 465e35ee196Sdanielk1977 ** named "x_sqlite_exec" that invokes sqlite3_exec(). Invoking sqlite3_exec() 466c22bd47dSdrh ** in this way is illegal recursion and should raise an SQLITE_MISUSE error. 467c22bd47dSdrh ** The effect is similar to trying to use the same database connection from 468c22bd47dSdrh ** two threads at the same time. 469c22bd47dSdrh ** 470c22bd47dSdrh ** The original motivation for this routine was to be able to call the 4716f8a503dSdanielk1977 ** sqlite3_create_function function while a query is in progress in order 472c22bd47dSdrh ** to test the SQLITE_MISUSE detection logic. 473c22bd47dSdrh */ 474c2eef3b3Sdrh static int test_create_function( 475c22bd47dSdrh void *NotUsed, 476c22bd47dSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 477c22bd47dSdrh int argc, /* Number of arguments */ 478c22bd47dSdrh char **argv /* Text of each argument */ 479c22bd47dSdrh ){ 480c60d0446Sdrh int rc; 4819bb575fdSdrh sqlite3 *db; 4829bb575fdSdrh extern void Md5_Register(sqlite3*); 483312d6b36Sdanielk1977 484c22bd47dSdrh if( argc!=2 ){ 485c22bd47dSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 4864397de57Sdanielk1977 " DB\"", 0); 487c22bd47dSdrh return TCL_ERROR; 488c22bd47dSdrh } 489b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 490c60d0446Sdrh rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0, 491d8123366Sdanielk1977 ifnullFunc, 0, 0); 492312d6b36Sdanielk1977 4935436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 494312d6b36Sdanielk1977 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 495312d6b36Sdanielk1977 ** because it is not tested anywhere else. */ 496c60d0446Sdrh if( rc==SQLITE_OK ){ 497576ec6b3Sdanielk1977 sqlite3_value *pVal; 498312d6b36Sdanielk1977 pVal = sqlite3ValueNew(); 499312d6b36Sdanielk1977 sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC); 500c60d0446Sdrh rc = sqlite3_create_function16(db, 501c60d0446Sdrh sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), 502312d6b36Sdanielk1977 1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0); 503312d6b36Sdanielk1977 sqlite3ValueFree(pVal); 504c60d0446Sdrh } 5055436dc2dSdrh #endif 5065436dc2dSdrh 507c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 5084397de57Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), 0); 509c22bd47dSdrh return TCL_OK; 510c22bd47dSdrh } 511c22bd47dSdrh 512c22bd47dSdrh /* 513c22bd47dSdrh ** Routines to implement the x_count() aggregate function. 514c22bd47dSdrh */ 515c22bd47dSdrh typedef struct CountCtx CountCtx; 516c22bd47dSdrh struct CountCtx { 517c22bd47dSdrh int n; 518c22bd47dSdrh }; 5190ae8b831Sdanielk1977 static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ 520c22bd47dSdrh CountCtx *p; 5214f26d6c4Sdrh p = sqlite3_aggregate_context(context, sizeof(*p)); 5229c054830Sdrh if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0]) ) && p ){ 523c22bd47dSdrh p->n++; 524c22bd47dSdrh } 525c22bd47dSdrh } 5260ae8b831Sdanielk1977 static void countFinalize(sqlite3_context *context){ 527c22bd47dSdrh CountCtx *p; 5284f26d6c4Sdrh p = sqlite3_aggregate_context(context, sizeof(*p)); 529c572ef7fSdanielk1977 sqlite3_result_int(context, p ? p->n : 0); 530c22bd47dSdrh } 531c22bd47dSdrh 532c22bd47dSdrh /* 533c22bd47dSdrh ** Usage: sqlite_test_create_aggregate DB 534c22bd47dSdrh ** 5356f8a503dSdanielk1977 ** Call the sqlite3_create_function API on the given database in order 536c22bd47dSdrh ** to create a function named "x_count". This function does the same thing 537c22bd47dSdrh ** as the "md5sum" function. 538c22bd47dSdrh ** 539c22bd47dSdrh ** The original motivation for this routine was to be able to call the 5406f8a503dSdanielk1977 ** sqlite3_create_aggregate function while a query is in progress in order 541c22bd47dSdrh ** to test the SQLITE_MISUSE detection logic. 542c22bd47dSdrh */ 543c2eef3b3Sdrh static int test_create_aggregate( 544c22bd47dSdrh void *NotUsed, 545c22bd47dSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 546c22bd47dSdrh int argc, /* Number of arguments */ 547c22bd47dSdrh char **argv /* Text of each argument */ 548c22bd47dSdrh ){ 5499bb575fdSdrh sqlite3 *db; 550c60d0446Sdrh int rc; 551c22bd47dSdrh if( argc!=2 ){ 552c22bd47dSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 553c22bd47dSdrh " FILENAME\"", 0); 554c22bd47dSdrh return TCL_ERROR; 555c22bd47dSdrh } 556b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 557c60d0446Sdrh rc = sqlite3_create_function(db, "x_count", 0, SQLITE_UTF8, 0, 0, 558d8123366Sdanielk1977 countStep,countFinalize); 559c60d0446Sdrh if( rc==SQLITE_OK ){ 560f9d64d2cSdanielk1977 sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0, 561d8123366Sdanielk1977 countStep,countFinalize); 562c60d0446Sdrh } 563c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 564c22bd47dSdrh return TCL_OK; 565c22bd47dSdrh } 566c22bd47dSdrh 567c22bd47dSdrh 568c22bd47dSdrh 569c22bd47dSdrh /* 5706f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER 571d1bf3512Sdrh ** 572d1bf3512Sdrh ** Call mprintf with three integer arguments 573d1bf3512Sdrh */ 5746f8a503dSdanielk1977 static int sqlite3_mprintf_int( 575d1bf3512Sdrh void *NotUsed, 576d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 577d1bf3512Sdrh int argc, /* Number of arguments */ 578d1bf3512Sdrh char **argv /* Text of each argument */ 579d1bf3512Sdrh ){ 580d1bf3512Sdrh int a[3], i; 581d1bf3512Sdrh char *z; 582d1bf3512Sdrh if( argc!=5 ){ 583d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 584d1bf3512Sdrh " FORMAT INT INT INT\"", 0); 585d1bf3512Sdrh return TCL_ERROR; 586d1bf3512Sdrh } 587d1bf3512Sdrh for(i=2; i<5; i++){ 588d1bf3512Sdrh if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 589d1bf3512Sdrh } 5906f8a503dSdanielk1977 z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]); 591d1bf3512Sdrh Tcl_AppendResult(interp, z, 0); 5923f4fedb2Sdrh sqlite3_free(z); 593d1bf3512Sdrh return TCL_OK; 594d1bf3512Sdrh } 595d1bf3512Sdrh 596d1bf3512Sdrh /* 5979d213ef0Sdrh ** If zNum represents an integer that will fit in 64-bits, then set 5989d213ef0Sdrh ** *pValue to that integer and return true. Otherwise return false. 5999d213ef0Sdrh */ 6009d213ef0Sdrh static int sqlite3GetInt64(const char *zNum, i64 *pValue){ 6019d213ef0Sdrh if( sqlite3FitsIn64Bits(zNum) ){ 6029d213ef0Sdrh sqlite3atoi64(zNum, pValue); 6039d213ef0Sdrh return 1; 6049d213ef0Sdrh } 6059d213ef0Sdrh return 0; 6069d213ef0Sdrh } 6079d213ef0Sdrh 6089d213ef0Sdrh /* 609e9707671Sdrh ** Usage: sqlite3_mprintf_int64 FORMAT INTEGER INTEGER INTEGER 610e9707671Sdrh ** 611e9707671Sdrh ** Call mprintf with three 64-bit integer arguments 612e9707671Sdrh */ 613e9707671Sdrh static int sqlite3_mprintf_int64( 614e9707671Sdrh void *NotUsed, 615e9707671Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 616e9707671Sdrh int argc, /* Number of arguments */ 617e9707671Sdrh char **argv /* Text of each argument */ 618e9707671Sdrh ){ 619e9707671Sdrh int i; 620e9707671Sdrh sqlite_int64 a[3]; 621e9707671Sdrh char *z; 622e9707671Sdrh if( argc!=5 ){ 623e9707671Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 624e9707671Sdrh " FORMAT INT INT INT\"", 0); 625e9707671Sdrh return TCL_ERROR; 626e9707671Sdrh } 627e9707671Sdrh for(i=2; i<5; i++){ 628e9707671Sdrh if( !sqlite3GetInt64(argv[i], &a[i-2]) ){ 629e9707671Sdrh Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0); 630e9707671Sdrh return TCL_ERROR; 631e9707671Sdrh } 632e9707671Sdrh } 633e9707671Sdrh z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]); 634e9707671Sdrh Tcl_AppendResult(interp, z, 0); 635e9707671Sdrh sqlite3_free(z); 636e9707671Sdrh return TCL_OK; 637e9707671Sdrh } 638e9707671Sdrh 639e9707671Sdrh /* 6406f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING 641d1bf3512Sdrh ** 642d1bf3512Sdrh ** Call mprintf with two integer arguments and one string argument 643d1bf3512Sdrh */ 6446f8a503dSdanielk1977 static int sqlite3_mprintf_str( 645d1bf3512Sdrh void *NotUsed, 646d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 647d1bf3512Sdrh int argc, /* Number of arguments */ 648d1bf3512Sdrh char **argv /* Text of each argument */ 649d1bf3512Sdrh ){ 650d1bf3512Sdrh int a[3], i; 651d1bf3512Sdrh char *z; 652f220b24fSchw if( argc<4 || argc>5 ){ 653d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 654f220b24fSchw " FORMAT INT INT ?STRING?\"", 0); 655d1bf3512Sdrh return TCL_ERROR; 656d1bf3512Sdrh } 657d1bf3512Sdrh for(i=2; i<4; i++){ 658d1bf3512Sdrh if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 659d1bf3512Sdrh } 6606f8a503dSdanielk1977 z = sqlite3_mprintf(argv[1], a[0], a[1], argc>4 ? argv[4] : NULL); 661d1bf3512Sdrh Tcl_AppendResult(interp, z, 0); 6623f4fedb2Sdrh sqlite3_free(z); 663d1bf3512Sdrh return TCL_OK; 664d1bf3512Sdrh } 665d1bf3512Sdrh 666d1bf3512Sdrh /* 6676f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_str FORMAT INTEGER INTEGER DOUBLE 668d1bf3512Sdrh ** 669d1bf3512Sdrh ** Call mprintf with two integer arguments and one double argument 670d1bf3512Sdrh */ 6716f8a503dSdanielk1977 static int sqlite3_mprintf_double( 672d1bf3512Sdrh void *NotUsed, 673d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 674d1bf3512Sdrh int argc, /* Number of arguments */ 675d1bf3512Sdrh char **argv /* Text of each argument */ 676d1bf3512Sdrh ){ 677d1bf3512Sdrh int a[3], i; 678d1bf3512Sdrh double r; 679d1bf3512Sdrh char *z; 680d1bf3512Sdrh if( argc!=5 ){ 681d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 682d1bf3512Sdrh " FORMAT INT INT STRING\"", 0); 683d1bf3512Sdrh return TCL_ERROR; 684d1bf3512Sdrh } 685d1bf3512Sdrh for(i=2; i<4; i++){ 686d1bf3512Sdrh if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 687d1bf3512Sdrh } 688d1bf3512Sdrh if( Tcl_GetDouble(interp, argv[4], &r) ) return TCL_ERROR; 6896f8a503dSdanielk1977 z = sqlite3_mprintf(argv[1], a[0], a[1], r); 690d1bf3512Sdrh Tcl_AppendResult(interp, z, 0); 6913f4fedb2Sdrh sqlite3_free(z); 692d1bf3512Sdrh return TCL_OK; 693d1bf3512Sdrh } 694d1bf3512Sdrh 695d1bf3512Sdrh /* 6966f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_str FORMAT DOUBLE DOUBLE 697b621c237Sdrh ** 698b621c237Sdrh ** Call mprintf with a single double argument which is the product of the 699b621c237Sdrh ** two arguments given above. This is used to generate overflow and underflow 700b621c237Sdrh ** doubles to test that they are converted properly. 701b621c237Sdrh */ 7026f8a503dSdanielk1977 static int sqlite3_mprintf_scaled( 703b621c237Sdrh void *NotUsed, 704b621c237Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 705b621c237Sdrh int argc, /* Number of arguments */ 706b621c237Sdrh char **argv /* Text of each argument */ 707b621c237Sdrh ){ 708b621c237Sdrh int i; 709b621c237Sdrh double r[2]; 710b621c237Sdrh char *z; 711b621c237Sdrh if( argc!=4 ){ 712b621c237Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 713b621c237Sdrh " FORMAT DOUBLE DOUBLE\"", 0); 714b621c237Sdrh return TCL_ERROR; 715b621c237Sdrh } 716b621c237Sdrh for(i=2; i<4; i++){ 717b621c237Sdrh if( Tcl_GetDouble(interp, argv[i], &r[i-2]) ) return TCL_ERROR; 718b621c237Sdrh } 7196f8a503dSdanielk1977 z = sqlite3_mprintf(argv[1], r[0]*r[1]); 720b621c237Sdrh Tcl_AppendResult(interp, z, 0); 7213f4fedb2Sdrh sqlite3_free(z); 722b621c237Sdrh return TCL_OK; 723b621c237Sdrh } 724b621c237Sdrh 725b621c237Sdrh /* 726e29b1a05Sdrh ** Usage: sqlite3_mprintf_stronly FORMAT STRING 727e29b1a05Sdrh ** 728e29b1a05Sdrh ** Call mprintf with a single double argument which is the product of the 729e29b1a05Sdrh ** two arguments given above. This is used to generate overflow and underflow 730e29b1a05Sdrh ** doubles to test that they are converted properly. 731e29b1a05Sdrh */ 732e29b1a05Sdrh static int sqlite3_mprintf_stronly( 733e29b1a05Sdrh void *NotUsed, 734e29b1a05Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 735e29b1a05Sdrh int argc, /* Number of arguments */ 736e29b1a05Sdrh char **argv /* Text of each argument */ 737e29b1a05Sdrh ){ 738e29b1a05Sdrh char *z; 739e29b1a05Sdrh if( argc!=3 ){ 740e29b1a05Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 741e29b1a05Sdrh " FORMAT STRING\"", 0); 742e29b1a05Sdrh return TCL_ERROR; 743e29b1a05Sdrh } 744e29b1a05Sdrh z = sqlite3_mprintf(argv[1], argv[2]); 745e29b1a05Sdrh Tcl_AppendResult(interp, z, 0); 746e29b1a05Sdrh sqlite3_free(z); 747e29b1a05Sdrh return TCL_OK; 748e29b1a05Sdrh } 749e29b1a05Sdrh 750e29b1a05Sdrh /* 7514693423bSdrh ** Usage: sqlite_malloc_fail N ?REPEAT-INTERVAL? 752daffd0e5Sdrh ** 7534693423bSdrh ** Rig sqliteMalloc() to fail on the N-th call and every REPEAT-INTERVAL call 7544693423bSdrh ** after that. If REPEAT-INTERVAL is 0 or is omitted, then only a single 7554693423bSdrh ** malloc will fail. If REPEAT-INTERVAL is 1 then all mallocs after the 7564693423bSdrh ** first failure will continue to fail on every call. If REPEAT-INTERVAL is 7574693423bSdrh ** 2 then every other malloc will fail. And so forth. 7584693423bSdrh ** 7594693423bSdrh ** Turn off this mechanism and reset the sqlite3_malloc_failed variable is N==0. 760daffd0e5Sdrh */ 7612c336549Sdanielk1977 #ifdef SQLITE_MEMDEBUG 762daffd0e5Sdrh static int sqlite_malloc_fail( 763daffd0e5Sdrh void *NotUsed, 764daffd0e5Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 765daffd0e5Sdrh int argc, /* Number of arguments */ 766daffd0e5Sdrh char **argv /* Text of each argument */ 767daffd0e5Sdrh ){ 768daffd0e5Sdrh int n; 7694693423bSdrh int rep; 7704693423bSdrh if( argc!=2 && argc!=3 ){ 771daffd0e5Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"", 0); 772daffd0e5Sdrh return TCL_ERROR; 773daffd0e5Sdrh } 774daffd0e5Sdrh if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR; 7754693423bSdrh if( argc==3 ){ 7764693423bSdrh if( Tcl_GetInt(interp, argv[2], &rep) ) return TCL_ERROR; 7774693423bSdrh }else{ 7784693423bSdrh rep = 0; 7794693423bSdrh } 7806f8a503dSdanielk1977 sqlite3_iMallocFail = n; 7814693423bSdrh sqlite3_iMallocReset = rep; 7826f8a503dSdanielk1977 sqlite3_malloc_failed = 0; 783daffd0e5Sdrh return TCL_OK; 784daffd0e5Sdrh } 785daffd0e5Sdrh #endif 786daffd0e5Sdrh 787daffd0e5Sdrh /* 788daffd0e5Sdrh ** Usage: sqlite_malloc_stat 789daffd0e5Sdrh ** 790daffd0e5Sdrh ** Return the number of prior calls to sqliteMalloc() and sqliteFree(). 791daffd0e5Sdrh */ 7922c336549Sdanielk1977 #ifdef SQLITE_MEMDEBUG 793daffd0e5Sdrh static int sqlite_malloc_stat( 794daffd0e5Sdrh void *NotUsed, 795daffd0e5Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 796daffd0e5Sdrh int argc, /* Number of arguments */ 797daffd0e5Sdrh char **argv /* Text of each argument */ 798daffd0e5Sdrh ){ 799daffd0e5Sdrh char zBuf[200]; 8006f8a503dSdanielk1977 sprintf(zBuf, "%d %d %d", sqlite3_nMalloc, sqlite3_nFree, sqlite3_iMallocFail); 801daffd0e5Sdrh Tcl_AppendResult(interp, zBuf, 0); 802daffd0e5Sdrh return TCL_OK; 803daffd0e5Sdrh } 804daffd0e5Sdrh #endif 805daffd0e5Sdrh 806daffd0e5Sdrh /* 80728b4e489Sdrh ** Usage: sqlite_abort 80828b4e489Sdrh ** 80928b4e489Sdrh ** Shutdown the process immediately. This is not a clean shutdown. 81028b4e489Sdrh ** This command is used to test the recoverability of a database in 81128b4e489Sdrh ** the event of a program crash. 81228b4e489Sdrh */ 81328b4e489Sdrh static int sqlite_abort( 81428b4e489Sdrh void *NotUsed, 81528b4e489Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 81628b4e489Sdrh int argc, /* Number of arguments */ 81728b4e489Sdrh char **argv /* Text of each argument */ 81828b4e489Sdrh ){ 81928b4e489Sdrh assert( interp==0 ); /* This will always fail */ 82028b4e489Sdrh return TCL_OK; 82128b4e489Sdrh } 82228b4e489Sdrh 82328b4e489Sdrh /* 8246cbe1f1bSdrh ** The following routine is a user-defined SQL function whose purpose 8256cbe1f1bSdrh ** is to test the sqlite_set_result() API. 8266cbe1f1bSdrh */ 8270ae8b831Sdanielk1977 static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 8286cbe1f1bSdrh while( argc>=2 ){ 8294f26d6c4Sdrh const char *zArg0 = sqlite3_value_text(argv[0]); 8306d88bad4Sdanielk1977 if( zArg0 ){ 8316d88bad4Sdanielk1977 if( 0==sqlite3StrICmp(zArg0, "int") ){ 8326d88bad4Sdanielk1977 sqlite3_result_int(context, sqlite3_value_int(argv[1])); 8336d88bad4Sdanielk1977 }else if( sqlite3StrICmp(zArg0,"int64")==0 ){ 8346d88bad4Sdanielk1977 sqlite3_result_int64(context, sqlite3_value_int64(argv[1])); 83551ad0ecdSdanielk1977 }else if( sqlite3StrICmp(zArg0,"string")==0 ){ 836d8123366Sdanielk1977 sqlite3_result_text(context, sqlite3_value_text(argv[1]), -1, 837d8123366Sdanielk1977 SQLITE_TRANSIENT); 83851ad0ecdSdanielk1977 }else if( sqlite3StrICmp(zArg0,"double")==0 ){ 8396d88bad4Sdanielk1977 sqlite3_result_double(context, sqlite3_value_double(argv[1])); 8406d88bad4Sdanielk1977 }else if( sqlite3StrICmp(zArg0,"null")==0 ){ 8416d88bad4Sdanielk1977 sqlite3_result_null(context); 8426d88bad4Sdanielk1977 }else if( sqlite3StrICmp(zArg0,"value")==0 ){ 8436d88bad4Sdanielk1977 sqlite3_result_value(context, argv[sqlite3_value_int(argv[1])]); 8446cbe1f1bSdrh }else{ 8456d88bad4Sdanielk1977 goto error_out; 8466d88bad4Sdanielk1977 } 8476d88bad4Sdanielk1977 }else{ 8486d88bad4Sdanielk1977 goto error_out; 8496cbe1f1bSdrh } 8506cbe1f1bSdrh argc -= 2; 8516cbe1f1bSdrh argv += 2; 8526cbe1f1bSdrh } 8536d88bad4Sdanielk1977 return; 8546d88bad4Sdanielk1977 8556d88bad4Sdanielk1977 error_out: 8566d88bad4Sdanielk1977 sqlite3_result_error(context,"first argument should be one of: " 8576d88bad4Sdanielk1977 "int int64 string double null value", -1); 8586cbe1f1bSdrh } 8596cbe1f1bSdrh 8606cbe1f1bSdrh /* 8616cbe1f1bSdrh ** Usage: sqlite_register_test_function DB NAME 8626cbe1f1bSdrh ** 8636cbe1f1bSdrh ** Register the test SQL function on the database DB under the name NAME. 8646cbe1f1bSdrh */ 865c2eef3b3Sdrh static int test_register_func( 8666cbe1f1bSdrh void *NotUsed, 8676cbe1f1bSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 8686cbe1f1bSdrh int argc, /* Number of arguments */ 8696cbe1f1bSdrh char **argv /* Text of each argument */ 8706cbe1f1bSdrh ){ 8719bb575fdSdrh sqlite3 *db; 8726cbe1f1bSdrh int rc; 8736cbe1f1bSdrh if( argc!=3 ){ 8746cbe1f1bSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 8756cbe1f1bSdrh " DB FUNCTION-NAME", 0); 8766cbe1f1bSdrh return TCL_ERROR; 8776cbe1f1bSdrh } 878b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 879f9d64d2cSdanielk1977 rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 880d8123366Sdanielk1977 testFunc, 0, 0); 8816cbe1f1bSdrh if( rc!=0 ){ 882f20b21c8Sdanielk1977 Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0); 8836cbe1f1bSdrh return TCL_ERROR; 8846cbe1f1bSdrh } 885c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 8866cbe1f1bSdrh return TCL_OK; 8876cbe1f1bSdrh } 8886cbe1f1bSdrh 8896cbe1f1bSdrh /* 890106bb236Sdanielk1977 ** Usage: sqlite3_finalize STMT 891b86ccfb2Sdrh ** 892106bb236Sdanielk1977 ** Finalize a statement handle. 893b86ccfb2Sdrh */ 894b86ccfb2Sdrh static int test_finalize( 895106bb236Sdanielk1977 void * clientData, 896106bb236Sdanielk1977 Tcl_Interp *interp, 897106bb236Sdanielk1977 int objc, 898106bb236Sdanielk1977 Tcl_Obj *CONST objv[] 899b86ccfb2Sdrh ){ 900106bb236Sdanielk1977 sqlite3_stmt *pStmt; 901b86ccfb2Sdrh int rc; 902c60d0446Sdrh sqlite3 *db; 903106bb236Sdanielk1977 904106bb236Sdanielk1977 if( objc!=2 ){ 905106bb236Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 906106bb236Sdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 907b86ccfb2Sdrh return TCL_ERROR; 908b86ccfb2Sdrh } 909106bb236Sdanielk1977 910106bb236Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 911106bb236Sdanielk1977 9124397de57Sdanielk1977 if( pStmt ){ 913c60d0446Sdrh db = StmtToDb(pStmt); 9144397de57Sdanielk1977 } 915fc57d7bfSdanielk1977 rc = sqlite3_finalize(pStmt); 916b77f5dadSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 9174397de57Sdanielk1977 if( db && sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 918106bb236Sdanielk1977 return TCL_OK; 919106bb236Sdanielk1977 } 920106bb236Sdanielk1977 921106bb236Sdanielk1977 /* 922106bb236Sdanielk1977 ** Usage: sqlite3_reset STMT 923106bb236Sdanielk1977 ** 924106bb236Sdanielk1977 ** Finalize a statement handle. 925106bb236Sdanielk1977 */ 926106bb236Sdanielk1977 static int test_reset( 927106bb236Sdanielk1977 void * clientData, 928106bb236Sdanielk1977 Tcl_Interp *interp, 929106bb236Sdanielk1977 int objc, 930106bb236Sdanielk1977 Tcl_Obj *CONST objv[] 931106bb236Sdanielk1977 ){ 932106bb236Sdanielk1977 sqlite3_stmt *pStmt; 933106bb236Sdanielk1977 int rc; 934106bb236Sdanielk1977 935106bb236Sdanielk1977 if( objc!=2 ){ 936106bb236Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 937106bb236Sdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 938106bb236Sdanielk1977 return TCL_ERROR; 939106bb236Sdanielk1977 } 940106bb236Sdanielk1977 941106bb236Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 942106bb236Sdanielk1977 943fc57d7bfSdanielk1977 rc = sqlite3_reset(pStmt); 9444397de57Sdanielk1977 if( pStmt && 9454397de57Sdanielk1977 sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 9464397de57Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 947106bb236Sdanielk1977 if( rc ){ 948b86ccfb2Sdrh return TCL_ERROR; 949b86ccfb2Sdrh } 950b86ccfb2Sdrh return TCL_OK; 951b86ccfb2Sdrh } 952b86ccfb2Sdrh 9535a38705eSdrh /* 954d89bd007Sdrh ** Usage: sqlite3_expired STMT 955d89bd007Sdrh ** 956d89bd007Sdrh ** Return TRUE if a recompilation of the statement is recommended. 957d89bd007Sdrh */ 958d89bd007Sdrh static int test_expired( 959d89bd007Sdrh void * clientData, 960d89bd007Sdrh Tcl_Interp *interp, 961d89bd007Sdrh int objc, 962d89bd007Sdrh Tcl_Obj *CONST objv[] 963d89bd007Sdrh ){ 964d89bd007Sdrh sqlite3_stmt *pStmt; 965d89bd007Sdrh if( objc!=2 ){ 966d89bd007Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", 967d89bd007Sdrh Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 968d89bd007Sdrh return TCL_ERROR; 969d89bd007Sdrh } 970d89bd007Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 971d89bd007Sdrh Tcl_SetObjResult(interp, Tcl_NewBooleanObj(sqlite3_expired(pStmt))); 972d89bd007Sdrh return TCL_OK; 973d89bd007Sdrh } 974d89bd007Sdrh 975d89bd007Sdrh /* 976f8db1bc0Sdrh ** Usage: sqlite3_transfer_bindings FROMSTMT TOSTMT 977f8db1bc0Sdrh ** 978f8db1bc0Sdrh ** Transfer all bindings from FROMSTMT over to TOSTMT 979f8db1bc0Sdrh */ 980f8db1bc0Sdrh static int test_transfer_bind( 981f8db1bc0Sdrh void * clientData, 982f8db1bc0Sdrh Tcl_Interp *interp, 983f8db1bc0Sdrh int objc, 984f8db1bc0Sdrh Tcl_Obj *CONST objv[] 985f8db1bc0Sdrh ){ 986f8db1bc0Sdrh sqlite3_stmt *pStmt1, *pStmt2; 987f8db1bc0Sdrh if( objc!=3 ){ 988f8db1bc0Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", 989f8db1bc0Sdrh Tcl_GetStringFromObj(objv[0], 0), " FROM-STMT TO-STMT", 0); 990f8db1bc0Sdrh return TCL_ERROR; 991f8db1bc0Sdrh } 992f8db1bc0Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt1)) return TCL_ERROR; 993f8db1bc0Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[2]), &pStmt2)) return TCL_ERROR; 994f8db1bc0Sdrh Tcl_SetObjResult(interp, 995f8db1bc0Sdrh Tcl_NewIntObj(sqlite3_transfer_bindings(pStmt1,pStmt2))); 996f8db1bc0Sdrh return TCL_OK; 997f8db1bc0Sdrh } 998f8db1bc0Sdrh 999f8db1bc0Sdrh /* 1000fbcd585fSdanielk1977 ** Usage: sqlite3_changes DB 100150457896Sdrh ** 1002fbcd585fSdanielk1977 ** Return the number of changes made to the database by the last SQL 1003fbcd585fSdanielk1977 ** execution. 100450457896Sdrh */ 1005fbcd585fSdanielk1977 static int test_changes( 1006fbcd585fSdanielk1977 void * clientData, 1007fbcd585fSdanielk1977 Tcl_Interp *interp, 1008fbcd585fSdanielk1977 int objc, 1009fbcd585fSdanielk1977 Tcl_Obj *CONST objv[] 1010fbcd585fSdanielk1977 ){ 1011fbcd585fSdanielk1977 sqlite3 *db; 1012fbcd585fSdanielk1977 if( objc!=2 ){ 1013fbcd585fSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1014fbcd585fSdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 1015fbcd585fSdanielk1977 return TCL_ERROR; 1016fbcd585fSdanielk1977 } 1017fbcd585fSdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1018fbcd585fSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_changes(db))); 1019fbcd585fSdanielk1977 return TCL_OK; 1020fbcd585fSdanielk1977 } 102150457896Sdrh 102250457896Sdrh /* 10237c972decSdrh ** This is the "static_bind_value" that variables are bound to when 10246f8a503dSdanielk1977 ** the FLAG option of sqlite3_bind is "static" 102550457896Sdrh */ 10267c972decSdrh static char *sqlite_static_bind_value = 0; 10277c972decSdrh 10287c972decSdrh /* 10296f8a503dSdanielk1977 ** Usage: sqlite3_bind VM IDX VALUE FLAGS 10307c972decSdrh ** 10317c972decSdrh ** Sets the value of the IDX-th occurance of "?" in the original SQL 10327c972decSdrh ** string. VALUE is the new value. If FLAGS=="null" then VALUE is 10337c972decSdrh ** ignored and the value is set to NULL. If FLAGS=="static" then 10347c972decSdrh ** the value is set to the value of a static variable named 10357c972decSdrh ** "sqlite_static_bind_value". If FLAGS=="normal" then a copy 10367c972decSdrh ** of the VALUE is made. 10377c972decSdrh */ 10387c972decSdrh static int test_bind( 103950457896Sdrh void *NotUsed, 104050457896Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 104150457896Sdrh int argc, /* Number of arguments */ 104250457896Sdrh char **argv /* Text of each argument */ 104350457896Sdrh ){ 1044fc57d7bfSdanielk1977 sqlite3_stmt *pStmt; 104550457896Sdrh int rc; 10467c972decSdrh int idx; 10477c972decSdrh if( argc!=5 ){ 104850457896Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 10497c972decSdrh " VM IDX VALUE (null|static|normal)\"", 0); 105050457896Sdrh return TCL_ERROR; 105150457896Sdrh } 1052fc57d7bfSdanielk1977 if( getStmtPointer(interp, argv[1], &pStmt) ) return TCL_ERROR; 10537c972decSdrh if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR; 10547c972decSdrh if( strcmp(argv[4],"null")==0 ){ 1055fc57d7bfSdanielk1977 rc = sqlite3_bind_null(pStmt, idx); 10567c972decSdrh }else if( strcmp(argv[4],"static")==0 ){ 1057fc57d7bfSdanielk1977 rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0); 10587c972decSdrh }else if( strcmp(argv[4],"normal")==0 ){ 1059d8123366Sdanielk1977 rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, SQLITE_TRANSIENT); 10607c972decSdrh }else{ 10617c972decSdrh Tcl_AppendResult(interp, "4th argument should be " 10627c972decSdrh "\"null\" or \"static\" or \"normal\"", 0); 10637c972decSdrh return TCL_ERROR; 10647c972decSdrh } 1065c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 106650457896Sdrh if( rc ){ 106750457896Sdrh char zBuf[50]; 106850457896Sdrh sprintf(zBuf, "(%d) ", rc); 1069f20b21c8Sdanielk1977 Tcl_AppendResult(interp, zBuf, sqlite3ErrStr(rc), 0); 107050457896Sdrh return TCL_ERROR; 107150457896Sdrh } 107250457896Sdrh return TCL_OK; 107350457896Sdrh } 107450457896Sdrh 10755436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 10764e6af134Sdanielk1977 /* 10774e6af134Sdanielk1977 ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be> 10784e6af134Sdanielk1977 ** 10794e6af134Sdanielk1977 ** This function is used to test that SQLite selects the correct collation 10804e6af134Sdanielk1977 ** sequence callback when multiple versions (for different text encodings) 10814e6af134Sdanielk1977 ** are available. 10824e6af134Sdanielk1977 ** 10834e6af134Sdanielk1977 ** Calling this routine registers the collation sequence "test_collate" 10844e6af134Sdanielk1977 ** with database handle <db>. The second argument must be a list of three 10854e6af134Sdanielk1977 ** boolean values. If the first is true, then a version of test_collate is 10864e6af134Sdanielk1977 ** registered for UTF-8, if the second is true, a version is registered for 10874e6af134Sdanielk1977 ** UTF-16le, if the third is true, a UTF-16be version is available. 10884e6af134Sdanielk1977 ** Previous versions of test_collate are deleted. 10894e6af134Sdanielk1977 ** 10904e6af134Sdanielk1977 ** The collation sequence test_collate is implemented by calling the 10914e6af134Sdanielk1977 ** following TCL script: 10924e6af134Sdanielk1977 ** 10934e6af134Sdanielk1977 ** "test_collate <enc> <lhs> <rhs>" 10944e6af134Sdanielk1977 ** 10954e6af134Sdanielk1977 ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8. 10964e6af134Sdanielk1977 ** The <enc> parameter is the encoding of the collation function that 10974e6af134Sdanielk1977 ** SQLite selected to call. The TCL test script implements the 10984e6af134Sdanielk1977 ** "test_collate" proc. 10994e6af134Sdanielk1977 ** 11004e6af134Sdanielk1977 ** Note that this will only work with one intepreter at a time, as the 11014e6af134Sdanielk1977 ** interp pointer to use when evaluating the TCL script is stored in 11024e6af134Sdanielk1977 ** pTestCollateInterp. 11034e6af134Sdanielk1977 */ 11044e6af134Sdanielk1977 static Tcl_Interp* pTestCollateInterp; 11054e6af134Sdanielk1977 static int test_collate_func( 11064e6af134Sdanielk1977 void *pCtx, 11074e6af134Sdanielk1977 int nA, const void *zA, 11084e6af134Sdanielk1977 int nB, const void *zB 11094e6af134Sdanielk1977 ){ 11104e6af134Sdanielk1977 Tcl_Interp *i = pTestCollateInterp; 11114e6af134Sdanielk1977 int encin = (int)pCtx; 11124e6af134Sdanielk1977 int res; 11134e6af134Sdanielk1977 11144e6af134Sdanielk1977 sqlite3_value *pVal; 11154e6af134Sdanielk1977 Tcl_Obj *pX; 11164e6af134Sdanielk1977 11174e6af134Sdanielk1977 pX = Tcl_NewStringObj("test_collate", -1); 11184e6af134Sdanielk1977 Tcl_IncrRefCount(pX); 11194e6af134Sdanielk1977 11204e6af134Sdanielk1977 switch( encin ){ 11214e6af134Sdanielk1977 case SQLITE_UTF8: 11224e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-8",-1)); 11234e6af134Sdanielk1977 break; 11244e6af134Sdanielk1977 case SQLITE_UTF16LE: 11254e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16LE",-1)); 11264e6af134Sdanielk1977 break; 11274e6af134Sdanielk1977 case SQLITE_UTF16BE: 11284e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16BE",-1)); 11294e6af134Sdanielk1977 break; 11304e6af134Sdanielk1977 default: 11314e6af134Sdanielk1977 assert(0); 11324e6af134Sdanielk1977 } 11334e6af134Sdanielk1977 11344e6af134Sdanielk1977 pVal = sqlite3ValueNew(); 1135bfd6cce5Sdanielk1977 sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC); 11364e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj(sqlite3_value_text(pVal),-1)); 1137bfd6cce5Sdanielk1977 sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC); 11384e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj(sqlite3_value_text(pVal),-1)); 11394e6af134Sdanielk1977 sqlite3ValueFree(pVal); 11404e6af134Sdanielk1977 11414e6af134Sdanielk1977 Tcl_EvalObjEx(i, pX, 0); 11424e6af134Sdanielk1977 Tcl_DecrRefCount(pX); 11434e6af134Sdanielk1977 Tcl_GetIntFromObj(i, Tcl_GetObjResult(i), &res); 11444e6af134Sdanielk1977 return res; 11454e6af134Sdanielk1977 } 11464e6af134Sdanielk1977 static int test_collate( 11474e6af134Sdanielk1977 void * clientData, 11484e6af134Sdanielk1977 Tcl_Interp *interp, 11494e6af134Sdanielk1977 int objc, 11504e6af134Sdanielk1977 Tcl_Obj *CONST objv[] 11514e6af134Sdanielk1977 ){ 11524e6af134Sdanielk1977 sqlite3 *db; 11534e6af134Sdanielk1977 int val; 1154312d6b36Sdanielk1977 sqlite3_value *pVal; 1155c60d0446Sdrh int rc; 11564e6af134Sdanielk1977 11574e6af134Sdanielk1977 if( objc!=5 ) goto bad_args; 11584e6af134Sdanielk1977 pTestCollateInterp = interp; 11594e6af134Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 11604e6af134Sdanielk1977 11614e6af134Sdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; 1162c60d0446Sdrh rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8, 11634e6af134Sdanielk1977 (void *)SQLITE_UTF8, val?test_collate_func:0); 1164c60d0446Sdrh if( rc==SQLITE_OK ){ 11654e6af134Sdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; 1166c60d0446Sdrh rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE, 11674e6af134Sdanielk1977 (void *)SQLITE_UTF16LE, val?test_collate_func:0); 11684e6af134Sdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR; 1169312d6b36Sdanielk1977 1170312d6b36Sdanielk1977 pVal = sqlite3ValueNew(); 1171312d6b36Sdanielk1977 sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC); 1172312d6b36Sdanielk1977 sqlite3_create_collation16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), 1173312d6b36Sdanielk1977 SQLITE_UTF16BE, (void *)SQLITE_UTF16BE, val?test_collate_func:0); 1174312d6b36Sdanielk1977 sqlite3ValueFree(pVal); 1175c60d0446Sdrh } 1176c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 11774e6af134Sdanielk1977 return TCL_OK; 11784e6af134Sdanielk1977 11794e6af134Sdanielk1977 bad_args: 11804e6af134Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 11814e6af134Sdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); 11824e6af134Sdanielk1977 return TCL_ERROR; 11834e6af134Sdanielk1977 } 11844e6af134Sdanielk1977 1185312d6b36Sdanielk1977 static void test_collate_needed_cb( 1186312d6b36Sdanielk1977 void *pCtx, 1187312d6b36Sdanielk1977 sqlite3 *db, 1188312d6b36Sdanielk1977 int eTextRep, 1189312d6b36Sdanielk1977 const void *notUsed 1190312d6b36Sdanielk1977 ){ 1191312d6b36Sdanielk1977 int enc = db->enc; 1192312d6b36Sdanielk1977 sqlite3_create_collation( 1193312d6b36Sdanielk1977 db, "test_collate", db->enc, (void *)enc, test_collate_func); 1194312d6b36Sdanielk1977 } 1195312d6b36Sdanielk1977 1196312d6b36Sdanielk1977 /* 1197312d6b36Sdanielk1977 ** Usage: add_test_collate_needed DB 1198312d6b36Sdanielk1977 */ 1199312d6b36Sdanielk1977 static int test_collate_needed( 1200312d6b36Sdanielk1977 void * clientData, 1201312d6b36Sdanielk1977 Tcl_Interp *interp, 1202312d6b36Sdanielk1977 int objc, 1203312d6b36Sdanielk1977 Tcl_Obj *CONST objv[] 1204312d6b36Sdanielk1977 ){ 1205312d6b36Sdanielk1977 sqlite3 *db; 1206c60d0446Sdrh int rc; 1207312d6b36Sdanielk1977 1208312d6b36Sdanielk1977 if( objc!=2 ) goto bad_args; 1209312d6b36Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1210c60d0446Sdrh rc = sqlite3_collation_needed16(db, 0, test_collate_needed_cb); 1211c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1212312d6b36Sdanielk1977 return TCL_OK; 1213312d6b36Sdanielk1977 1214312d6b36Sdanielk1977 bad_args: 1215312d6b36Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "DB"); 1216312d6b36Sdanielk1977 return TCL_ERROR; 1217312d6b36Sdanielk1977 } 12185436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 1219312d6b36Sdanielk1977 1220c8e9a2dfSdanielk1977 /* 1221c8e9a2dfSdanielk1977 ** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be> 1222c8e9a2dfSdanielk1977 ** 1223c8e9a2dfSdanielk1977 ** This function is used to test that SQLite selects the correct user 1224c8e9a2dfSdanielk1977 ** function callback when multiple versions (for different text encodings) 1225c8e9a2dfSdanielk1977 ** are available. 1226c8e9a2dfSdanielk1977 ** 1227c8e9a2dfSdanielk1977 ** Calling this routine registers up to three versions of the user function 1228c8e9a2dfSdanielk1977 ** "test_function" with database handle <db>. If the second argument is 1229c8e9a2dfSdanielk1977 ** true, then a version of test_function is registered for UTF-8, if the 1230c8e9a2dfSdanielk1977 ** third is true, a version is registered for UTF-16le, if the fourth is 1231c8e9a2dfSdanielk1977 ** true, a UTF-16be version is available. Previous versions of 1232c8e9a2dfSdanielk1977 ** test_function are deleted. 1233c8e9a2dfSdanielk1977 ** 1234c8e9a2dfSdanielk1977 ** The user function is implemented by calling the following TCL script: 1235c8e9a2dfSdanielk1977 ** 1236c8e9a2dfSdanielk1977 ** "test_function <enc> <arg>" 1237c8e9a2dfSdanielk1977 ** 1238c8e9a2dfSdanielk1977 ** Where <enc> is one of UTF-8, UTF-16LE or UTF16BE, and <arg> is the 1239c8e9a2dfSdanielk1977 ** single argument passed to the SQL function. The value returned by 1240c8e9a2dfSdanielk1977 ** the TCL script is used as the return value of the SQL function. It 1241c8e9a2dfSdanielk1977 ** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8 1242c8e9a2dfSdanielk1977 ** for a UTF-16LE test_function(), and UTF-16LE for an implementation that 1243c8e9a2dfSdanielk1977 ** prefers UTF-16BE. 1244c8e9a2dfSdanielk1977 */ 12455436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 1246c8e9a2dfSdanielk1977 static void test_function_utf8( 1247c8e9a2dfSdanielk1977 sqlite3_context *pCtx, 1248c8e9a2dfSdanielk1977 int nArg, 1249c8e9a2dfSdanielk1977 sqlite3_value **argv 1250c8e9a2dfSdanielk1977 ){ 1251c8e9a2dfSdanielk1977 Tcl_Interp *interp; 1252c8e9a2dfSdanielk1977 Tcl_Obj *pX; 1253c8e9a2dfSdanielk1977 sqlite3_value *pVal; 1254c8e9a2dfSdanielk1977 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1255c8e9a2dfSdanielk1977 pX = Tcl_NewStringObj("test_function", -1); 1256c8e9a2dfSdanielk1977 Tcl_IncrRefCount(pX); 1257c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-8", -1)); 1258c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, 1259c8e9a2dfSdanielk1977 Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); 1260c8e9a2dfSdanielk1977 Tcl_EvalObjEx(interp, pX, 0); 1261c8e9a2dfSdanielk1977 Tcl_DecrRefCount(pX); 1262c8e9a2dfSdanielk1977 sqlite3_result_text(pCtx, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT); 1263c8e9a2dfSdanielk1977 pVal = sqlite3ValueNew(); 1264c8e9a2dfSdanielk1977 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1265c8e9a2dfSdanielk1977 SQLITE_UTF8, SQLITE_STATIC); 1266c8e9a2dfSdanielk1977 sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal), 1267c8e9a2dfSdanielk1977 -1, SQLITE_TRANSIENT); 1268c8e9a2dfSdanielk1977 sqlite3ValueFree(pVal); 1269c8e9a2dfSdanielk1977 } 1270c8e9a2dfSdanielk1977 static void test_function_utf16le( 1271c8e9a2dfSdanielk1977 sqlite3_context *pCtx, 1272c8e9a2dfSdanielk1977 int nArg, 1273c8e9a2dfSdanielk1977 sqlite3_value **argv 1274c8e9a2dfSdanielk1977 ){ 1275c8e9a2dfSdanielk1977 Tcl_Interp *interp; 1276c8e9a2dfSdanielk1977 Tcl_Obj *pX; 1277c8e9a2dfSdanielk1977 sqlite3_value *pVal; 1278c8e9a2dfSdanielk1977 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1279c8e9a2dfSdanielk1977 pX = Tcl_NewStringObj("test_function", -1); 1280c8e9a2dfSdanielk1977 Tcl_IncrRefCount(pX); 1281c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16LE", -1)); 1282c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, 1283c8e9a2dfSdanielk1977 Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); 1284c8e9a2dfSdanielk1977 Tcl_EvalObjEx(interp, pX, 0); 1285c8e9a2dfSdanielk1977 Tcl_DecrRefCount(pX); 1286c8e9a2dfSdanielk1977 pVal = sqlite3ValueNew(); 1287c8e9a2dfSdanielk1977 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1288c8e9a2dfSdanielk1977 SQLITE_UTF8, SQLITE_STATIC); 1289c8e9a2dfSdanielk1977 sqlite3_result_text(pCtx,sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT); 1290c8e9a2dfSdanielk1977 sqlite3ValueFree(pVal); 1291c8e9a2dfSdanielk1977 } 1292c8e9a2dfSdanielk1977 static void test_function_utf16be( 1293c8e9a2dfSdanielk1977 sqlite3_context *pCtx, 1294c8e9a2dfSdanielk1977 int nArg, 1295c8e9a2dfSdanielk1977 sqlite3_value **argv 1296c8e9a2dfSdanielk1977 ){ 1297c8e9a2dfSdanielk1977 Tcl_Interp *interp; 1298c8e9a2dfSdanielk1977 Tcl_Obj *pX; 1299c8e9a2dfSdanielk1977 sqlite3_value *pVal; 1300c8e9a2dfSdanielk1977 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1301c8e9a2dfSdanielk1977 pX = Tcl_NewStringObj("test_function", -1); 1302c8e9a2dfSdanielk1977 Tcl_IncrRefCount(pX); 1303c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16BE", -1)); 1304c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, 1305c8e9a2dfSdanielk1977 Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); 1306c8e9a2dfSdanielk1977 Tcl_EvalObjEx(interp, pX, 0); 1307c8e9a2dfSdanielk1977 Tcl_DecrRefCount(pX); 1308c8e9a2dfSdanielk1977 pVal = sqlite3ValueNew(); 1309c8e9a2dfSdanielk1977 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1310c8e9a2dfSdanielk1977 SQLITE_UTF8, SQLITE_STATIC); 1311c8e9a2dfSdanielk1977 sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal), 1312c8e9a2dfSdanielk1977 -1, SQLITE_TRANSIENT); 1313c8e9a2dfSdanielk1977 sqlite3ValueFree(pVal); 1314c8e9a2dfSdanielk1977 } 13155436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 1316c8e9a2dfSdanielk1977 static int test_function( 1317c8e9a2dfSdanielk1977 void * clientData, 1318c8e9a2dfSdanielk1977 Tcl_Interp *interp, 1319c8e9a2dfSdanielk1977 int objc, 1320c8e9a2dfSdanielk1977 Tcl_Obj *CONST objv[] 1321c8e9a2dfSdanielk1977 ){ 13225436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 1323c8e9a2dfSdanielk1977 sqlite3 *db; 1324c8e9a2dfSdanielk1977 int val; 1325c8e9a2dfSdanielk1977 1326c8e9a2dfSdanielk1977 if( objc!=5 ) goto bad_args; 1327c8e9a2dfSdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1328c8e9a2dfSdanielk1977 1329c8e9a2dfSdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; 1330c8e9a2dfSdanielk1977 if( val ){ 1331c8e9a2dfSdanielk1977 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF8, 1332c8e9a2dfSdanielk1977 interp, test_function_utf8, 0, 0); 1333c8e9a2dfSdanielk1977 } 1334c8e9a2dfSdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; 1335c8e9a2dfSdanielk1977 if( val ){ 1336c8e9a2dfSdanielk1977 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16LE, 1337c8e9a2dfSdanielk1977 interp, test_function_utf16le, 0, 0); 1338c8e9a2dfSdanielk1977 } 1339c8e9a2dfSdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR; 1340c8e9a2dfSdanielk1977 if( val ){ 1341c8e9a2dfSdanielk1977 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16BE, 1342c8e9a2dfSdanielk1977 interp, test_function_utf16be, 0, 0); 1343c8e9a2dfSdanielk1977 } 1344c8e9a2dfSdanielk1977 1345c8e9a2dfSdanielk1977 return TCL_OK; 1346c8e9a2dfSdanielk1977 bad_args: 1347c8e9a2dfSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1348c8e9a2dfSdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); 13495436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 1350c8e9a2dfSdanielk1977 return TCL_ERROR; 1351c8e9a2dfSdanielk1977 } 1352c8e9a2dfSdanielk1977 1353312d6b36Sdanielk1977 /* 1354312d6b36Sdanielk1977 ** Usage: test_errstr <err code> 1355312d6b36Sdanielk1977 ** 1356312d6b36Sdanielk1977 ** Test that the english language string equivalents for sqlite error codes 1357312d6b36Sdanielk1977 ** are sane. The parameter is an integer representing an sqlite error code. 1358312d6b36Sdanielk1977 ** The result is a list of two elements, the string representation of the 1359312d6b36Sdanielk1977 ** error code and the english language explanation. 1360312d6b36Sdanielk1977 */ 1361312d6b36Sdanielk1977 static int test_errstr( 1362312d6b36Sdanielk1977 void * clientData, 1363312d6b36Sdanielk1977 Tcl_Interp *interp, 1364312d6b36Sdanielk1977 int objc, 1365312d6b36Sdanielk1977 Tcl_Obj *CONST objv[] 1366312d6b36Sdanielk1977 ){ 1367312d6b36Sdanielk1977 char *zCode; 1368312d6b36Sdanielk1977 int i; 1369312d6b36Sdanielk1977 if( objc!=1 ){ 1370312d6b36Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "<error code>"); 1371312d6b36Sdanielk1977 } 1372312d6b36Sdanielk1977 1373312d6b36Sdanielk1977 zCode = Tcl_GetString(objv[1]); 1374312d6b36Sdanielk1977 for(i=0; i<200; i++){ 1375312d6b36Sdanielk1977 if( 0==strcmp(errorName(i), zCode) ) break; 1376312d6b36Sdanielk1977 } 1377312d6b36Sdanielk1977 Tcl_SetResult(interp, (char *)sqlite3ErrStr(i), 0); 1378312d6b36Sdanielk1977 return TCL_OK; 1379312d6b36Sdanielk1977 } 1380312d6b36Sdanielk1977 1381c8e9a2dfSdanielk1977 static int sqlite3_crashparams( 13828a6c550dSdanielk1977 void * clientData, 13838a6c550dSdanielk1977 Tcl_Interp *interp, 13848a6c550dSdanielk1977 int objc, 13858a6c550dSdanielk1977 Tcl_Obj *CONST objv[] 13868a6c550dSdanielk1977 ){ 13878a6c550dSdanielk1977 #ifdef OS_TEST 1388c8e9a2dfSdanielk1977 int delay; 1389c8e9a2dfSdanielk1977 if( objc!=3 ) goto bad_args; 1390c8e9a2dfSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[1], &delay) ) return TCL_ERROR; 1391c8e9a2dfSdanielk1977 sqlite3SetCrashParams(delay, Tcl_GetString(objv[2])); 13928a6c550dSdanielk1977 #endif 13938a6c550dSdanielk1977 return TCL_OK; 13948a6c550dSdanielk1977 1395241db313Sdrh #ifdef OS_TEST 13968a6c550dSdanielk1977 bad_args: 13978a6c550dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1398c8e9a2dfSdanielk1977 Tcl_GetStringFromObj(objv[0], 0), "<delay> <filename>", 0); 13998a6c550dSdanielk1977 return TCL_ERROR; 1400241db313Sdrh #endif 14018a6c550dSdanielk1977 } 14028a6c550dSdanielk1977 14038a6c550dSdanielk1977 140450457896Sdrh /* 140599ee3600Sdrh ** Usage: breakpoint 140699ee3600Sdrh ** 140799ee3600Sdrh ** This routine exists for one purpose - to provide a place to put a 140899ee3600Sdrh ** breakpoint with GDB that can be triggered using TCL code. The use 140999ee3600Sdrh ** for this is when a particular test fails on (say) the 1485th iteration. 141099ee3600Sdrh ** In the TCL test script, we can add code like this: 141199ee3600Sdrh ** 141299ee3600Sdrh ** if {$i==1485} breakpoint 141399ee3600Sdrh ** 141499ee3600Sdrh ** Then run testfixture in the debugger and wait for the breakpoint to 141599ee3600Sdrh ** fire. Then additional breakpoints can be set to trace down the bug. 141699ee3600Sdrh */ 141799ee3600Sdrh static int test_breakpoint( 141899ee3600Sdrh void *NotUsed, 141999ee3600Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 142099ee3600Sdrh int argc, /* Number of arguments */ 142199ee3600Sdrh char **argv /* Text of each argument */ 142299ee3600Sdrh ){ 142399ee3600Sdrh return TCL_OK; /* Do nothing */ 142499ee3600Sdrh } 142599ee3600Sdrh 1426241db313Sdrh /* 1427241db313Sdrh ** Usage: sqlite3_bind_int STMT N VALUE 1428241db313Sdrh ** 1429241db313Sdrh ** Test the sqlite3_bind_int interface. STMT is a prepared statement. 1430241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1431241db313Sdrh ** binds a 32-bit integer VALUE to that wildcard. 1432241db313Sdrh */ 1433241db313Sdrh static int test_bind_int( 143451e3d8e2Sdanielk1977 void * clientData, 143551e3d8e2Sdanielk1977 Tcl_Interp *interp, 143651e3d8e2Sdanielk1977 int objc, 143751e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 143851e3d8e2Sdanielk1977 ){ 143951e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 144051e3d8e2Sdanielk1977 int idx; 144151e3d8e2Sdanielk1977 int value; 144251e3d8e2Sdanielk1977 int rc; 144351e3d8e2Sdanielk1977 144451e3d8e2Sdanielk1977 if( objc!=4 ){ 144551e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1446241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 144751e3d8e2Sdanielk1977 return TCL_ERROR; 144851e3d8e2Sdanielk1977 } 144951e3d8e2Sdanielk1977 145051e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 145151e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 145251e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR; 145351e3d8e2Sdanielk1977 1454c572ef7fSdanielk1977 rc = sqlite3_bind_int(pStmt, idx, value); 1455c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 145651e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 145751e3d8e2Sdanielk1977 return TCL_ERROR; 145851e3d8e2Sdanielk1977 } 145951e3d8e2Sdanielk1977 146051e3d8e2Sdanielk1977 return TCL_OK; 146151e3d8e2Sdanielk1977 } 146251e3d8e2Sdanielk1977 1463241db313Sdrh 1464241db313Sdrh /* 1465241db313Sdrh ** Usage: sqlite3_bind_int64 STMT N VALUE 1466241db313Sdrh ** 1467241db313Sdrh ** Test the sqlite3_bind_int64 interface. STMT is a prepared statement. 1468241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1469241db313Sdrh ** binds a 64-bit integer VALUE to that wildcard. 1470241db313Sdrh */ 147151e3d8e2Sdanielk1977 static int test_bind_int64( 147251e3d8e2Sdanielk1977 void * clientData, 147351e3d8e2Sdanielk1977 Tcl_Interp *interp, 147451e3d8e2Sdanielk1977 int objc, 147551e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 147651e3d8e2Sdanielk1977 ){ 147751e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 147851e3d8e2Sdanielk1977 int idx; 147951e3d8e2Sdanielk1977 i64 value; 148051e3d8e2Sdanielk1977 int rc; 148151e3d8e2Sdanielk1977 148251e3d8e2Sdanielk1977 if( objc!=4 ){ 148351e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1484241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 148551e3d8e2Sdanielk1977 return TCL_ERROR; 148651e3d8e2Sdanielk1977 } 148751e3d8e2Sdanielk1977 148851e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 148951e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 149051e3d8e2Sdanielk1977 if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR; 149151e3d8e2Sdanielk1977 149251e3d8e2Sdanielk1977 rc = sqlite3_bind_int64(pStmt, idx, value); 1493c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 149451e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 149551e3d8e2Sdanielk1977 return TCL_ERROR; 149651e3d8e2Sdanielk1977 } 149751e3d8e2Sdanielk1977 149851e3d8e2Sdanielk1977 return TCL_OK; 149951e3d8e2Sdanielk1977 } 150051e3d8e2Sdanielk1977 1501241db313Sdrh 1502241db313Sdrh /* 1503241db313Sdrh ** Usage: sqlite3_bind_double STMT N VALUE 1504241db313Sdrh ** 1505241db313Sdrh ** Test the sqlite3_bind_double interface. STMT is a prepared statement. 1506241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1507241db313Sdrh ** binds a 64-bit integer VALUE to that wildcard. 1508241db313Sdrh */ 150951e3d8e2Sdanielk1977 static int test_bind_double( 151051e3d8e2Sdanielk1977 void * clientData, 151151e3d8e2Sdanielk1977 Tcl_Interp *interp, 151251e3d8e2Sdanielk1977 int objc, 151351e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 151451e3d8e2Sdanielk1977 ){ 151551e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 151651e3d8e2Sdanielk1977 int idx; 151751e3d8e2Sdanielk1977 double value; 151851e3d8e2Sdanielk1977 int rc; 151951e3d8e2Sdanielk1977 152051e3d8e2Sdanielk1977 if( objc!=4 ){ 152151e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1522241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 152351e3d8e2Sdanielk1977 return TCL_ERROR; 152451e3d8e2Sdanielk1977 } 152551e3d8e2Sdanielk1977 152651e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 152751e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 152851e3d8e2Sdanielk1977 if( Tcl_GetDoubleFromObj(interp, objv[3], &value) ) return TCL_ERROR; 152951e3d8e2Sdanielk1977 153051e3d8e2Sdanielk1977 rc = sqlite3_bind_double(pStmt, idx, value); 1531c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 153251e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 153351e3d8e2Sdanielk1977 return TCL_ERROR; 153451e3d8e2Sdanielk1977 } 153551e3d8e2Sdanielk1977 153651e3d8e2Sdanielk1977 return TCL_OK; 153751e3d8e2Sdanielk1977 } 153851e3d8e2Sdanielk1977 1539241db313Sdrh /* 1540241db313Sdrh ** Usage: sqlite3_bind_null STMT N 1541241db313Sdrh ** 1542241db313Sdrh ** Test the sqlite3_bind_null interface. STMT is a prepared statement. 1543241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1544241db313Sdrh ** binds a NULL to the wildcard. 1545241db313Sdrh */ 154651e3d8e2Sdanielk1977 static int test_bind_null( 154751e3d8e2Sdanielk1977 void * clientData, 154851e3d8e2Sdanielk1977 Tcl_Interp *interp, 154951e3d8e2Sdanielk1977 int objc, 155051e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 155151e3d8e2Sdanielk1977 ){ 155251e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 155351e3d8e2Sdanielk1977 int idx; 155451e3d8e2Sdanielk1977 int rc; 155551e3d8e2Sdanielk1977 155651e3d8e2Sdanielk1977 if( objc!=3 ){ 155751e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1558241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N", 0); 155951e3d8e2Sdanielk1977 return TCL_ERROR; 156051e3d8e2Sdanielk1977 } 156151e3d8e2Sdanielk1977 156251e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 156351e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 156451e3d8e2Sdanielk1977 156551e3d8e2Sdanielk1977 rc = sqlite3_bind_null(pStmt, idx); 1566c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 156751e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 156851e3d8e2Sdanielk1977 return TCL_ERROR; 156951e3d8e2Sdanielk1977 } 157051e3d8e2Sdanielk1977 157151e3d8e2Sdanielk1977 return TCL_OK; 157251e3d8e2Sdanielk1977 } 157351e3d8e2Sdanielk1977 1574241db313Sdrh /* 1575241db313Sdrh ** Usage: sqlite3_bind_text STMT N STRING BYTES 1576241db313Sdrh ** 1577241db313Sdrh ** Test the sqlite3_bind_text interface. STMT is a prepared statement. 1578241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1579241db313Sdrh ** binds a UTF-8 string STRING to the wildcard. The string is BYTES bytes 1580241db313Sdrh ** long. 1581241db313Sdrh */ 158251e3d8e2Sdanielk1977 static int test_bind_text( 158351e3d8e2Sdanielk1977 void * clientData, 158451e3d8e2Sdanielk1977 Tcl_Interp *interp, 158551e3d8e2Sdanielk1977 int objc, 158651e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 158751e3d8e2Sdanielk1977 ){ 158851e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 158951e3d8e2Sdanielk1977 int idx; 159051e3d8e2Sdanielk1977 int bytes; 159151e3d8e2Sdanielk1977 char *value; 159251e3d8e2Sdanielk1977 int rc; 159351e3d8e2Sdanielk1977 159451e3d8e2Sdanielk1977 if( objc!=5 ){ 159551e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1596241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0); 159751e3d8e2Sdanielk1977 return TCL_ERROR; 159851e3d8e2Sdanielk1977 } 159951e3d8e2Sdanielk1977 160051e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 160151e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 160251e3d8e2Sdanielk1977 value = Tcl_GetString(objv[3]); 160351e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 160451e3d8e2Sdanielk1977 1605d8123366Sdanielk1977 rc = sqlite3_bind_text(pStmt, idx, value, bytes, SQLITE_TRANSIENT); 1606c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 160751e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 1608473d179dSdrh Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0); 160951e3d8e2Sdanielk1977 return TCL_ERROR; 161051e3d8e2Sdanielk1977 } 161151e3d8e2Sdanielk1977 161251e3d8e2Sdanielk1977 return TCL_OK; 161351e3d8e2Sdanielk1977 } 161451e3d8e2Sdanielk1977 1615241db313Sdrh /* 1616241db313Sdrh ** Usage: sqlite3_bind_text16 STMT N STRING BYTES 1617241db313Sdrh ** 1618241db313Sdrh ** Test the sqlite3_bind_text16 interface. STMT is a prepared statement. 1619241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1620241db313Sdrh ** binds a UTF-16 string STRING to the wildcard. The string is BYTES bytes 1621241db313Sdrh ** long. 1622241db313Sdrh */ 162351e3d8e2Sdanielk1977 static int test_bind_text16( 162451e3d8e2Sdanielk1977 void * clientData, 162551e3d8e2Sdanielk1977 Tcl_Interp *interp, 162651e3d8e2Sdanielk1977 int objc, 162751e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 162851e3d8e2Sdanielk1977 ){ 16295436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 163051e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 163151e3d8e2Sdanielk1977 int idx; 163251e3d8e2Sdanielk1977 int bytes; 163351e3d8e2Sdanielk1977 char *value; 163451e3d8e2Sdanielk1977 int rc; 163551e3d8e2Sdanielk1977 163651e3d8e2Sdanielk1977 if( objc!=5 ){ 163751e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1638241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0); 163951e3d8e2Sdanielk1977 return TCL_ERROR; 164051e3d8e2Sdanielk1977 } 164151e3d8e2Sdanielk1977 164251e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 164351e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 164451e3d8e2Sdanielk1977 value = Tcl_GetByteArrayFromObj(objv[3], 0); 164551e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 164651e3d8e2Sdanielk1977 1647d8123366Sdanielk1977 rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, SQLITE_TRANSIENT); 1648c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 164951e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 165051e3d8e2Sdanielk1977 return TCL_ERROR; 165151e3d8e2Sdanielk1977 } 165251e3d8e2Sdanielk1977 16535436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 165451e3d8e2Sdanielk1977 return TCL_OK; 165551e3d8e2Sdanielk1977 } 165651e3d8e2Sdanielk1977 1657241db313Sdrh /* 1658241db313Sdrh ** Usage: sqlite3_bind_blob STMT N DATA BYTES 1659241db313Sdrh ** 1660241db313Sdrh ** Test the sqlite3_bind_blob interface. STMT is a prepared statement. 1661241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1662241db313Sdrh ** binds a BLOB to the wildcard. The BLOB is BYTES bytes in size. 1663241db313Sdrh */ 166451e3d8e2Sdanielk1977 static int test_bind_blob( 166551e3d8e2Sdanielk1977 void * clientData, 166651e3d8e2Sdanielk1977 Tcl_Interp *interp, 166751e3d8e2Sdanielk1977 int objc, 166851e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 166951e3d8e2Sdanielk1977 ){ 167051e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 167151e3d8e2Sdanielk1977 int idx; 167251e3d8e2Sdanielk1977 int bytes; 167351e3d8e2Sdanielk1977 char *value; 167451e3d8e2Sdanielk1977 int rc; 167551e3d8e2Sdanielk1977 167651e3d8e2Sdanielk1977 if( objc!=5 ){ 167751e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1678241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N DATA BYTES", 0); 167951e3d8e2Sdanielk1977 return TCL_ERROR; 168051e3d8e2Sdanielk1977 } 168151e3d8e2Sdanielk1977 168251e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 168351e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 168451e3d8e2Sdanielk1977 value = Tcl_GetString(objv[3]); 168549e4643eSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 168651e3d8e2Sdanielk1977 1687d8123366Sdanielk1977 rc = sqlite3_bind_blob(pStmt, idx, value, bytes, SQLITE_TRANSIENT); 1688c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 168951e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 169051e3d8e2Sdanielk1977 return TCL_ERROR; 169151e3d8e2Sdanielk1977 } 169251e3d8e2Sdanielk1977 169351e3d8e2Sdanielk1977 return TCL_OK; 169451e3d8e2Sdanielk1977 } 169551e3d8e2Sdanielk1977 169699ee3600Sdrh /* 169775f6a032Sdrh ** Usage: sqlite3_bind_parameter_count STMT 169875f6a032Sdrh ** 169975f6a032Sdrh ** Return the number of wildcards in the given statement. 170075f6a032Sdrh */ 170175f6a032Sdrh static int test_bind_parameter_count( 170275f6a032Sdrh void * clientData, 170375f6a032Sdrh Tcl_Interp *interp, 170475f6a032Sdrh int objc, 170575f6a032Sdrh Tcl_Obj *CONST objv[] 170675f6a032Sdrh ){ 170775f6a032Sdrh sqlite3_stmt *pStmt; 170875f6a032Sdrh 170975f6a032Sdrh if( objc!=2 ){ 171075f6a032Sdrh Tcl_WrongNumArgs(interp, 1, objv, "STMT"); 171175f6a032Sdrh return TCL_ERROR; 171275f6a032Sdrh } 171375f6a032Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 171475f6a032Sdrh Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_bind_parameter_count(pStmt))); 171575f6a032Sdrh return TCL_OK; 171675f6a032Sdrh } 171775f6a032Sdrh 171875f6a032Sdrh /* 1719895d7472Sdrh ** Usage: sqlite3_bind_parameter_name STMT N 1720895d7472Sdrh ** 1721895d7472Sdrh ** Return the name of the Nth wildcard. The first wildcard is 1. 1722895d7472Sdrh ** An empty string is returned if N is out of range or if the wildcard 1723895d7472Sdrh ** is nameless. 1724895d7472Sdrh */ 1725895d7472Sdrh static int test_bind_parameter_name( 1726895d7472Sdrh void * clientData, 1727895d7472Sdrh Tcl_Interp *interp, 1728895d7472Sdrh int objc, 1729895d7472Sdrh Tcl_Obj *CONST objv[] 1730895d7472Sdrh ){ 1731895d7472Sdrh sqlite3_stmt *pStmt; 1732895d7472Sdrh int i; 1733895d7472Sdrh 1734895d7472Sdrh if( objc!=3 ){ 1735895d7472Sdrh Tcl_WrongNumArgs(interp, 1, objv, "STMT N"); 1736895d7472Sdrh return TCL_ERROR; 1737895d7472Sdrh } 1738895d7472Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1739895d7472Sdrh if( Tcl_GetIntFromObj(interp, objv[2], &i) ) return TCL_ERROR; 1740895d7472Sdrh Tcl_SetObjResult(interp, 1741895d7472Sdrh Tcl_NewStringObj(sqlite3_bind_parameter_name(pStmt,i),-1) 1742895d7472Sdrh ); 1743895d7472Sdrh return TCL_OK; 1744895d7472Sdrh } 1745895d7472Sdrh 1746895d7472Sdrh /* 1747fa6bc000Sdrh ** Usage: sqlite3_bind_parameter_index STMT NAME 1748fa6bc000Sdrh ** 1749fa6bc000Sdrh ** Return the index of the wildcard called NAME. Return 0 if there is 1750fa6bc000Sdrh ** no such wildcard. 1751fa6bc000Sdrh */ 1752fa6bc000Sdrh static int test_bind_parameter_index( 1753fa6bc000Sdrh void * clientData, 1754fa6bc000Sdrh Tcl_Interp *interp, 1755fa6bc000Sdrh int objc, 1756fa6bc000Sdrh Tcl_Obj *CONST objv[] 1757fa6bc000Sdrh ){ 1758fa6bc000Sdrh sqlite3_stmt *pStmt; 1759fa6bc000Sdrh 1760fa6bc000Sdrh if( objc!=3 ){ 1761fa6bc000Sdrh Tcl_WrongNumArgs(interp, 1, objv, "STMT NAME"); 1762fa6bc000Sdrh return TCL_ERROR; 1763fa6bc000Sdrh } 1764fa6bc000Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1765fa6bc000Sdrh Tcl_SetObjResult(interp, 1766fa6bc000Sdrh Tcl_NewIntObj( 1767fa6bc000Sdrh sqlite3_bind_parameter_index(pStmt,Tcl_GetString(objv[2])) 1768fa6bc000Sdrh ) 1769fa6bc000Sdrh ); 1770fa6bc000Sdrh return TCL_OK; 1771fa6bc000Sdrh } 1772fa6bc000Sdrh 1773fa6bc000Sdrh /* 1774600dd0baSdanielk1977 ** Usage: sqlite3_clear_bindings STMT 1775600dd0baSdanielk1977 ** 1776600dd0baSdanielk1977 */ 1777600dd0baSdanielk1977 #if 0 1778600dd0baSdanielk1977 static int test_clear_bindings( 1779600dd0baSdanielk1977 void * clientData, 1780600dd0baSdanielk1977 Tcl_Interp *interp, 1781600dd0baSdanielk1977 int objc, 1782600dd0baSdanielk1977 Tcl_Obj *CONST objv[] 1783600dd0baSdanielk1977 ){ 1784600dd0baSdanielk1977 sqlite3_stmt *pStmt; 1785600dd0baSdanielk1977 1786600dd0baSdanielk1977 if( objc!=2 ){ 1787600dd0baSdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "STMT"); 1788600dd0baSdanielk1977 return TCL_ERROR; 1789600dd0baSdanielk1977 } 1790600dd0baSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1791600dd0baSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(pStmt))); 1792600dd0baSdanielk1977 return TCL_OK; 1793600dd0baSdanielk1977 } 1794600dd0baSdanielk1977 #endif 1795600dd0baSdanielk1977 1796600dd0baSdanielk1977 /* 17976622cce3Sdanielk1977 ** Usage: sqlite3_errcode DB 17986622cce3Sdanielk1977 ** 17996622cce3Sdanielk1977 ** Return the string representation of the most recent sqlite3_* API 18006622cce3Sdanielk1977 ** error code. e.g. "SQLITE_ERROR". 18016622cce3Sdanielk1977 */ 18026622cce3Sdanielk1977 static int test_errcode( 18036622cce3Sdanielk1977 void * clientData, 18046622cce3Sdanielk1977 Tcl_Interp *interp, 18056622cce3Sdanielk1977 int objc, 18066622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 18076622cce3Sdanielk1977 ){ 18086622cce3Sdanielk1977 sqlite3 *db; 18096622cce3Sdanielk1977 18106622cce3Sdanielk1977 if( objc!=2 ){ 18116622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 18126622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 18136622cce3Sdanielk1977 return TCL_ERROR; 18146622cce3Sdanielk1977 } 18156622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 18166622cce3Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(sqlite3_errcode(db)), 0); 18176622cce3Sdanielk1977 return TCL_OK; 18186622cce3Sdanielk1977 } 18196622cce3Sdanielk1977 18206622cce3Sdanielk1977 /* 18216622cce3Sdanielk1977 ** Usage: test_errmsg DB 18226622cce3Sdanielk1977 ** 18236622cce3Sdanielk1977 ** Returns the UTF-8 representation of the error message string for the 18246622cce3Sdanielk1977 ** most recent sqlite3_* API call. 18256622cce3Sdanielk1977 */ 18266622cce3Sdanielk1977 static int test_errmsg( 18276622cce3Sdanielk1977 void * clientData, 18286622cce3Sdanielk1977 Tcl_Interp *interp, 18296622cce3Sdanielk1977 int objc, 18306622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 18316622cce3Sdanielk1977 ){ 18329bb575fdSdrh sqlite3 *db; 18336622cce3Sdanielk1977 const char *zErr; 18346622cce3Sdanielk1977 18356622cce3Sdanielk1977 if( objc!=2 ){ 18366622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 18376622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 18386622cce3Sdanielk1977 return TCL_ERROR; 18396622cce3Sdanielk1977 } 18406622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 18416622cce3Sdanielk1977 18426622cce3Sdanielk1977 zErr = sqlite3_errmsg(db); 18436622cce3Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1)); 18446622cce3Sdanielk1977 return TCL_OK; 18456622cce3Sdanielk1977 } 18466622cce3Sdanielk1977 18476622cce3Sdanielk1977 /* 18486622cce3Sdanielk1977 ** Usage: test_errmsg16 DB 18496622cce3Sdanielk1977 ** 18506622cce3Sdanielk1977 ** Returns the UTF-16 representation of the error message string for the 18516622cce3Sdanielk1977 ** most recent sqlite3_* API call. This is a byte array object at the TCL 18526622cce3Sdanielk1977 ** level, and it includes the 0x00 0x00 terminator bytes at the end of the 18536622cce3Sdanielk1977 ** UTF-16 string. 18546622cce3Sdanielk1977 */ 18556622cce3Sdanielk1977 static int test_errmsg16( 18566622cce3Sdanielk1977 void * clientData, 18576622cce3Sdanielk1977 Tcl_Interp *interp, 18586622cce3Sdanielk1977 int objc, 18596622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 18606622cce3Sdanielk1977 ){ 18615436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 18629bb575fdSdrh sqlite3 *db; 18636622cce3Sdanielk1977 const void *zErr; 18646622cce3Sdanielk1977 int bytes; 18656622cce3Sdanielk1977 18666622cce3Sdanielk1977 if( objc!=2 ){ 18676622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 18686622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 18696622cce3Sdanielk1977 return TCL_ERROR; 18706622cce3Sdanielk1977 } 18716622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 18726622cce3Sdanielk1977 18736622cce3Sdanielk1977 zErr = sqlite3_errmsg16(db); 18746622cce3Sdanielk1977 bytes = sqlite3utf16ByteLen(zErr, -1); 18756622cce3Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes)); 18765436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 18776622cce3Sdanielk1977 return TCL_OK; 18786622cce3Sdanielk1977 } 18796622cce3Sdanielk1977 18806622cce3Sdanielk1977 /* 18816622cce3Sdanielk1977 ** Usage: sqlite3_prepare DB sql bytes tailvar 18826622cce3Sdanielk1977 ** 18836622cce3Sdanielk1977 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using 18846622cce3Sdanielk1977 ** database handle <DB>. The parameter <tailval> is the name of a global 18856622cce3Sdanielk1977 ** variable that is set to the unused portion of <sql> (if any). A 18866622cce3Sdanielk1977 ** STMT handle is returned. 18876622cce3Sdanielk1977 */ 18886622cce3Sdanielk1977 static int test_prepare( 18896622cce3Sdanielk1977 void * clientData, 18906622cce3Sdanielk1977 Tcl_Interp *interp, 18916622cce3Sdanielk1977 int objc, 18926622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 18936622cce3Sdanielk1977 ){ 18946622cce3Sdanielk1977 sqlite3 *db; 18956622cce3Sdanielk1977 const char *zSql; 18966622cce3Sdanielk1977 int bytes; 18976622cce3Sdanielk1977 const char *zTail = 0; 18986622cce3Sdanielk1977 sqlite3_stmt *pStmt = 0; 18996622cce3Sdanielk1977 char zBuf[50]; 19004ad1713cSdanielk1977 int rc; 19016622cce3Sdanielk1977 19026622cce3Sdanielk1977 if( objc!=5 ){ 19036622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 19046622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); 19056622cce3Sdanielk1977 return TCL_ERROR; 19066622cce3Sdanielk1977 } 19076622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 19086622cce3Sdanielk1977 zSql = Tcl_GetString(objv[2]); 19096622cce3Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; 19106622cce3Sdanielk1977 19114ad1713cSdanielk1977 rc = sqlite3_prepare(db, zSql, bytes, &pStmt, &zTail); 1912c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 19136622cce3Sdanielk1977 if( zTail ){ 19146622cce3Sdanielk1977 if( bytes>=0 ){ 19156622cce3Sdanielk1977 bytes = bytes - (zTail-zSql); 19166622cce3Sdanielk1977 } 19176622cce3Sdanielk1977 Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0); 19186622cce3Sdanielk1977 } 19194ad1713cSdanielk1977 if( rc!=SQLITE_OK ){ 19204ad1713cSdanielk1977 assert( pStmt==0 ); 19214ad1713cSdanielk1977 sprintf(zBuf, "(%d) ", rc); 19224ad1713cSdanielk1977 Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0); 19234ad1713cSdanielk1977 return TCL_ERROR; 19244ad1713cSdanielk1977 } 19256622cce3Sdanielk1977 19264ad1713cSdanielk1977 if( pStmt ){ 19276622cce3Sdanielk1977 if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; 19286622cce3Sdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 19294ad1713cSdanielk1977 } 19306622cce3Sdanielk1977 return TCL_OK; 19316622cce3Sdanielk1977 } 19326622cce3Sdanielk1977 19336622cce3Sdanielk1977 /* 19346622cce3Sdanielk1977 ** Usage: sqlite3_prepare DB sql bytes tailvar 19356622cce3Sdanielk1977 ** 19366622cce3Sdanielk1977 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using 19376622cce3Sdanielk1977 ** database handle <DB>. The parameter <tailval> is the name of a global 19386622cce3Sdanielk1977 ** variable that is set to the unused portion of <sql> (if any). A 19396622cce3Sdanielk1977 ** STMT handle is returned. 19406622cce3Sdanielk1977 */ 19416622cce3Sdanielk1977 static int test_prepare16( 19426622cce3Sdanielk1977 void * clientData, 19436622cce3Sdanielk1977 Tcl_Interp *interp, 19446622cce3Sdanielk1977 int objc, 19456622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 19466622cce3Sdanielk1977 ){ 19475436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 19486622cce3Sdanielk1977 sqlite3 *db; 19496622cce3Sdanielk1977 const void *zSql; 19506622cce3Sdanielk1977 const void *zTail = 0; 19516622cce3Sdanielk1977 Tcl_Obj *pTail = 0; 19526622cce3Sdanielk1977 sqlite3_stmt *pStmt = 0; 19536622cce3Sdanielk1977 char zBuf[50]; 1954c60d0446Sdrh int rc; 19556622cce3Sdanielk1977 int bytes; /* The integer specified as arg 3 */ 19566622cce3Sdanielk1977 int objlen; /* The byte-array length of arg 2 */ 19576622cce3Sdanielk1977 19586622cce3Sdanielk1977 if( objc!=5 ){ 19596622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 19606622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); 19616622cce3Sdanielk1977 return TCL_ERROR; 19626622cce3Sdanielk1977 } 19636622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 19646622cce3Sdanielk1977 zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen); 19656622cce3Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; 19666622cce3Sdanielk1977 1967c60d0446Sdrh rc = sqlite3_prepare16(db, zSql, bytes, &pStmt, &zTail); 1968c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1969c60d0446Sdrh if( rc ){ 19706622cce3Sdanielk1977 return TCL_ERROR; 19716622cce3Sdanielk1977 } 19726622cce3Sdanielk1977 19736622cce3Sdanielk1977 if( zTail ){ 19746622cce3Sdanielk1977 objlen = objlen - ((u8 *)zTail-(u8 *)zSql); 19756622cce3Sdanielk1977 }else{ 19766622cce3Sdanielk1977 objlen = 0; 19776622cce3Sdanielk1977 } 19786622cce3Sdanielk1977 pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen); 19796622cce3Sdanielk1977 Tcl_IncrRefCount(pTail); 19806622cce3Sdanielk1977 Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0); 19814ad1713cSdanielk1977 Tcl_DecrRefCount(pTail); 19826622cce3Sdanielk1977 19834ad1713cSdanielk1977 if( pStmt ){ 19846622cce3Sdanielk1977 if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; 19854ad1713cSdanielk1977 } 19866622cce3Sdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 19875436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 19886622cce3Sdanielk1977 return TCL_OK; 19896622cce3Sdanielk1977 } 19906622cce3Sdanielk1977 19914ad1713cSdanielk1977 /* 19924ad1713cSdanielk1977 ** Usage: sqlite3_open filename ?options-list? 19934ad1713cSdanielk1977 */ 19944ad1713cSdanielk1977 static int test_open( 19954ad1713cSdanielk1977 void * clientData, 19964ad1713cSdanielk1977 Tcl_Interp *interp, 19974ad1713cSdanielk1977 int objc, 19984ad1713cSdanielk1977 Tcl_Obj *CONST objv[] 19994ad1713cSdanielk1977 ){ 20004ad1713cSdanielk1977 const char *zFilename; 20014ad1713cSdanielk1977 sqlite3 *db; 20024ad1713cSdanielk1977 int rc; 20034ad1713cSdanielk1977 char zBuf[100]; 20044ad1713cSdanielk1977 20054ad1713cSdanielk1977 if( objc!=3 && objc!=2 ){ 20064ad1713cSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 20074ad1713cSdanielk1977 Tcl_GetString(objv[0]), " filename options-list", 0); 20084ad1713cSdanielk1977 return TCL_ERROR; 20094ad1713cSdanielk1977 } 20104ad1713cSdanielk1977 20114ad1713cSdanielk1977 zFilename = Tcl_GetString(objv[1]); 20124f057f90Sdanielk1977 rc = sqlite3_open(zFilename, &db); 20134ad1713cSdanielk1977 20144ad1713cSdanielk1977 if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR; 20154ad1713cSdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 20164ad1713cSdanielk1977 return TCL_OK; 20174ad1713cSdanielk1977 } 20184ad1713cSdanielk1977 20194ad1713cSdanielk1977 /* 20204ad1713cSdanielk1977 ** Usage: sqlite3_open16 filename options 20214ad1713cSdanielk1977 */ 20224ad1713cSdanielk1977 static int test_open16( 20234ad1713cSdanielk1977 void * clientData, 20244ad1713cSdanielk1977 Tcl_Interp *interp, 20254ad1713cSdanielk1977 int objc, 20264ad1713cSdanielk1977 Tcl_Obj *CONST objv[] 20274ad1713cSdanielk1977 ){ 20285436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 20294ad1713cSdanielk1977 const void *zFilename; 20304ad1713cSdanielk1977 sqlite3 *db; 20314ad1713cSdanielk1977 int rc; 20324ad1713cSdanielk1977 char zBuf[100]; 20334ad1713cSdanielk1977 20344ad1713cSdanielk1977 if( objc!=3 ){ 20354ad1713cSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 20364ad1713cSdanielk1977 Tcl_GetString(objv[0]), " filename options-list", 0); 20374ad1713cSdanielk1977 return TCL_ERROR; 20384ad1713cSdanielk1977 } 20394ad1713cSdanielk1977 20404ad1713cSdanielk1977 zFilename = Tcl_GetByteArrayFromObj(objv[1], 0); 20414f057f90Sdanielk1977 rc = sqlite3_open16(zFilename, &db); 20424ad1713cSdanielk1977 20434ad1713cSdanielk1977 if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR; 20444ad1713cSdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 20455436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 20464ad1713cSdanielk1977 return TCL_OK; 20474ad1713cSdanielk1977 } 2048d3d39e93Sdrh 2049d3d39e93Sdrh /* 2050bc6ada41Sdanielk1977 ** Usage: sqlite3_complete16 <UTF-16 string> 2051bc6ada41Sdanielk1977 ** 2052bc6ada41Sdanielk1977 ** Return 1 if the supplied argument is a complete SQL statement, or zero 2053bc6ada41Sdanielk1977 ** otherwise. 2054bc6ada41Sdanielk1977 */ 2055bc6ada41Sdanielk1977 static int test_complete16( 2056bc6ada41Sdanielk1977 void * clientData, 2057bc6ada41Sdanielk1977 Tcl_Interp *interp, 2058bc6ada41Sdanielk1977 int objc, 2059bc6ada41Sdanielk1977 Tcl_Obj *CONST objv[] 2060bc6ada41Sdanielk1977 ){ 2061ccae6026Sdrh #if !defined(SQLITE_OMIT_COMPLETE) && !defined(SQLITE_OMIT_UTF16) 2062bc6ada41Sdanielk1977 char *zBuf; 2063bc6ada41Sdanielk1977 2064bc6ada41Sdanielk1977 if( objc!=2 ){ 2065bc6ada41Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>"); 2066bc6ada41Sdanielk1977 return TCL_ERROR; 2067bc6ada41Sdanielk1977 } 2068bc6ada41Sdanielk1977 2069bc6ada41Sdanielk1977 zBuf = Tcl_GetByteArrayFromObj(objv[1], 0); 2070bc6ada41Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_complete16(zBuf))); 2071ccae6026Sdrh #endif /* SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */ 2072bc6ada41Sdanielk1977 return TCL_OK; 2073bc6ada41Sdanielk1977 } 2074bc6ada41Sdanielk1977 2075bc6ada41Sdanielk1977 /* 2076106bb236Sdanielk1977 ** Usage: sqlite3_step STMT 2077106bb236Sdanielk1977 ** 2078106bb236Sdanielk1977 ** Advance the statement to the next row. 2079106bb236Sdanielk1977 */ 208017240fd9Sdanielk1977 static int test_step( 2081106bb236Sdanielk1977 void * clientData, 2082106bb236Sdanielk1977 Tcl_Interp *interp, 2083106bb236Sdanielk1977 int objc, 2084106bb236Sdanielk1977 Tcl_Obj *CONST objv[] 2085106bb236Sdanielk1977 ){ 2086106bb236Sdanielk1977 sqlite3_stmt *pStmt; 2087106bb236Sdanielk1977 int rc; 2088106bb236Sdanielk1977 2089e1cd9874Sdanielk1977 if( objc!=2 ){ 2090106bb236Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 2091106bb236Sdanielk1977 Tcl_GetString(objv[0]), " STMT", 0); 2092106bb236Sdanielk1977 return TCL_ERROR; 2093106bb236Sdanielk1977 } 2094106bb236Sdanielk1977 2095106bb236Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 209617240fd9Sdanielk1977 rc = sqlite3_step(pStmt); 2097106bb236Sdanielk1977 2098fbcd585fSdanielk1977 /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; */ 20996590493dSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), 0); 2100e1cd9874Sdanielk1977 return TCL_OK; 2101e1cd9874Sdanielk1977 } 2102e1cd9874Sdanielk1977 2103e1cd9874Sdanielk1977 /* 210417240fd9Sdanielk1977 ** Usage: sqlite3_column_count STMT 210517240fd9Sdanielk1977 ** 210617240fd9Sdanielk1977 ** Return the number of columns returned by the sql statement STMT. 210717240fd9Sdanielk1977 */ 210817240fd9Sdanielk1977 static int test_column_count( 210917240fd9Sdanielk1977 void * clientData, 211017240fd9Sdanielk1977 Tcl_Interp *interp, 211117240fd9Sdanielk1977 int objc, 211217240fd9Sdanielk1977 Tcl_Obj *CONST objv[] 211317240fd9Sdanielk1977 ){ 211417240fd9Sdanielk1977 sqlite3_stmt *pStmt; 211517240fd9Sdanielk1977 211617240fd9Sdanielk1977 if( objc!=2 ){ 211717240fd9Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 211817240fd9Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 211917240fd9Sdanielk1977 return TCL_ERROR; 212017240fd9Sdanielk1977 } 212117240fd9Sdanielk1977 212217240fd9Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 212317240fd9Sdanielk1977 212417240fd9Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_column_count(pStmt))); 212517240fd9Sdanielk1977 return TCL_OK; 212617240fd9Sdanielk1977 } 212717240fd9Sdanielk1977 212817240fd9Sdanielk1977 /* 21293cf86063Sdanielk1977 ** Usage: sqlite3_column_type STMT column 21303cf86063Sdanielk1977 ** 21313cf86063Sdanielk1977 ** Return the type of the data in column 'column' of the current row. 21323cf86063Sdanielk1977 */ 21333cf86063Sdanielk1977 static int test_column_type( 21343cf86063Sdanielk1977 void * clientData, 21353cf86063Sdanielk1977 Tcl_Interp *interp, 21363cf86063Sdanielk1977 int objc, 21373cf86063Sdanielk1977 Tcl_Obj *CONST objv[] 21383cf86063Sdanielk1977 ){ 21393cf86063Sdanielk1977 sqlite3_stmt *pStmt; 21403cf86063Sdanielk1977 int col; 21413cf86063Sdanielk1977 int tp; 21423cf86063Sdanielk1977 21433cf86063Sdanielk1977 if( objc!=3 ){ 21443cf86063Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 21453cf86063Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 21463cf86063Sdanielk1977 return TCL_ERROR; 21473cf86063Sdanielk1977 } 21483cf86063Sdanielk1977 21493cf86063Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 21503cf86063Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 21513cf86063Sdanielk1977 21523cf86063Sdanielk1977 tp = sqlite3_column_type(pStmt, col); 21533cf86063Sdanielk1977 switch( tp ){ 21549c054830Sdrh case SQLITE_INTEGER: 21553cf86063Sdanielk1977 Tcl_SetResult(interp, "INTEGER", TCL_STATIC); 21563cf86063Sdanielk1977 break; 21579c054830Sdrh case SQLITE_NULL: 21583cf86063Sdanielk1977 Tcl_SetResult(interp, "NULL", TCL_STATIC); 21593cf86063Sdanielk1977 break; 21609c054830Sdrh case SQLITE_FLOAT: 21613cf86063Sdanielk1977 Tcl_SetResult(interp, "FLOAT", TCL_STATIC); 21623cf86063Sdanielk1977 break; 21639c054830Sdrh case SQLITE_TEXT: 21643cf86063Sdanielk1977 Tcl_SetResult(interp, "TEXT", TCL_STATIC); 21653cf86063Sdanielk1977 break; 21669c054830Sdrh case SQLITE_BLOB: 21673cf86063Sdanielk1977 Tcl_SetResult(interp, "BLOB", TCL_STATIC); 21683cf86063Sdanielk1977 break; 21693cf86063Sdanielk1977 default: 21703cf86063Sdanielk1977 assert(0); 21713cf86063Sdanielk1977 } 21723cf86063Sdanielk1977 21733cf86063Sdanielk1977 return TCL_OK; 21743cf86063Sdanielk1977 } 21753cf86063Sdanielk1977 21763cf86063Sdanielk1977 /* 217704f2e68dSdanielk1977 ** Usage: sqlite3_column_int64 STMT column 21783cf86063Sdanielk1977 ** 21793cf86063Sdanielk1977 ** Return the data in column 'column' of the current row cast as an 218004f2e68dSdanielk1977 ** wide (64-bit) integer. 21813cf86063Sdanielk1977 */ 218204f2e68dSdanielk1977 static int test_column_int64( 21833cf86063Sdanielk1977 void * clientData, 21843cf86063Sdanielk1977 Tcl_Interp *interp, 21853cf86063Sdanielk1977 int objc, 21863cf86063Sdanielk1977 Tcl_Obj *CONST objv[] 21873cf86063Sdanielk1977 ){ 21883cf86063Sdanielk1977 sqlite3_stmt *pStmt; 21893cf86063Sdanielk1977 int col; 219004f2e68dSdanielk1977 i64 iVal; 21913cf86063Sdanielk1977 21923cf86063Sdanielk1977 if( objc!=3 ){ 21933cf86063Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 21943cf86063Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 21953cf86063Sdanielk1977 return TCL_ERROR; 21963cf86063Sdanielk1977 } 21973cf86063Sdanielk1977 21983cf86063Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 21993cf86063Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 22003cf86063Sdanielk1977 220104f2e68dSdanielk1977 iVal = sqlite3_column_int64(pStmt, col); 220204f2e68dSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iVal)); 220304f2e68dSdanielk1977 return TCL_OK; 220404f2e68dSdanielk1977 } 220504f2e68dSdanielk1977 220604f2e68dSdanielk1977 /* 2207ea61b2c4Sdanielk1977 ** Usage: sqlite3_column_blob STMT column 2208ea61b2c4Sdanielk1977 */ 2209ea61b2c4Sdanielk1977 static int test_column_blob( 2210ea61b2c4Sdanielk1977 void * clientData, 2211ea61b2c4Sdanielk1977 Tcl_Interp *interp, 2212ea61b2c4Sdanielk1977 int objc, 2213ea61b2c4Sdanielk1977 Tcl_Obj *CONST objv[] 2214ea61b2c4Sdanielk1977 ){ 2215ea61b2c4Sdanielk1977 sqlite3_stmt *pStmt; 2216ea61b2c4Sdanielk1977 int col; 2217ea61b2c4Sdanielk1977 2218ea61b2c4Sdanielk1977 int len; 2219c572ef7fSdanielk1977 const void *pBlob; 2220ea61b2c4Sdanielk1977 2221ea61b2c4Sdanielk1977 if( objc!=3 ){ 2222ea61b2c4Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 2223ea61b2c4Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 2224ea61b2c4Sdanielk1977 return TCL_ERROR; 2225ea61b2c4Sdanielk1977 } 2226ea61b2c4Sdanielk1977 2227ea61b2c4Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2228ea61b2c4Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2229ea61b2c4Sdanielk1977 2230ea61b2c4Sdanielk1977 pBlob = sqlite3_column_blob(pStmt, col); 2231ea61b2c4Sdanielk1977 len = sqlite3_column_bytes(pStmt, col); 2232ea61b2c4Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len)); 2233ea61b2c4Sdanielk1977 return TCL_OK; 2234ea61b2c4Sdanielk1977 } 2235ea61b2c4Sdanielk1977 2236ea61b2c4Sdanielk1977 /* 223704f2e68dSdanielk1977 ** Usage: sqlite3_column_double STMT column 223804f2e68dSdanielk1977 ** 223904f2e68dSdanielk1977 ** Return the data in column 'column' of the current row cast as a double. 224004f2e68dSdanielk1977 */ 224104f2e68dSdanielk1977 static int test_column_double( 224204f2e68dSdanielk1977 void * clientData, 224304f2e68dSdanielk1977 Tcl_Interp *interp, 224404f2e68dSdanielk1977 int objc, 224504f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 224604f2e68dSdanielk1977 ){ 224704f2e68dSdanielk1977 sqlite3_stmt *pStmt; 224804f2e68dSdanielk1977 int col; 224904f2e68dSdanielk1977 double rVal; 225004f2e68dSdanielk1977 225104f2e68dSdanielk1977 if( objc!=3 ){ 225204f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 225304f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 225404f2e68dSdanielk1977 return TCL_ERROR; 225504f2e68dSdanielk1977 } 225604f2e68dSdanielk1977 225704f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 225804f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 225904f2e68dSdanielk1977 226004f2e68dSdanielk1977 rVal = sqlite3_column_double(pStmt, col); 2261c572ef7fSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rVal)); 22623cf86063Sdanielk1977 return TCL_OK; 22633cf86063Sdanielk1977 } 22643cf86063Sdanielk1977 22653cf86063Sdanielk1977 /* 226617240fd9Sdanielk1977 ** Usage: sqlite3_data_count STMT 226717240fd9Sdanielk1977 ** 226817240fd9Sdanielk1977 ** Return the number of columns returned by the sql statement STMT. 226917240fd9Sdanielk1977 */ 227017240fd9Sdanielk1977 static int test_data_count( 227117240fd9Sdanielk1977 void * clientData, 227217240fd9Sdanielk1977 Tcl_Interp *interp, 227317240fd9Sdanielk1977 int objc, 227417240fd9Sdanielk1977 Tcl_Obj *CONST objv[] 227517240fd9Sdanielk1977 ){ 227617240fd9Sdanielk1977 sqlite3_stmt *pStmt; 227717240fd9Sdanielk1977 227817240fd9Sdanielk1977 if( objc!=2 ){ 227917240fd9Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 228017240fd9Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 228117240fd9Sdanielk1977 return TCL_ERROR; 228217240fd9Sdanielk1977 } 228317240fd9Sdanielk1977 228417240fd9Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 228517240fd9Sdanielk1977 228617240fd9Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_data_count(pStmt))); 228717240fd9Sdanielk1977 return TCL_OK; 228817240fd9Sdanielk1977 } 228917240fd9Sdanielk1977 229017240fd9Sdanielk1977 /* 229104f2e68dSdanielk1977 ** Usage: sqlite3_column_text STMT column 229204f2e68dSdanielk1977 ** 229304f2e68dSdanielk1977 ** Usage: sqlite3_column_decltype STMT column 229404f2e68dSdanielk1977 ** 229504f2e68dSdanielk1977 ** Usage: sqlite3_column_name STMT column 229604f2e68dSdanielk1977 */ 229704f2e68dSdanielk1977 static int test_stmt_utf8( 2298241db313Sdrh void * clientData, /* Pointer to SQLite API function to be invoke */ 229904f2e68dSdanielk1977 Tcl_Interp *interp, 230004f2e68dSdanielk1977 int objc, 230104f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 230204f2e68dSdanielk1977 ){ 230304f2e68dSdanielk1977 sqlite3_stmt *pStmt; 230404f2e68dSdanielk1977 int col; 2305c572ef7fSdanielk1977 const char *(*xFunc)(sqlite3_stmt*, int) = clientData; 2306f93bbbeaSdanielk1977 const char *zRet; 230704f2e68dSdanielk1977 230804f2e68dSdanielk1977 if( objc!=3 ){ 230904f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 231004f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 231104f2e68dSdanielk1977 return TCL_ERROR; 231204f2e68dSdanielk1977 } 231304f2e68dSdanielk1977 231404f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 231504f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2316f93bbbeaSdanielk1977 zRet = xFunc(pStmt, col); 2317f93bbbeaSdanielk1977 if( zRet ){ 2318f93bbbeaSdanielk1977 Tcl_SetResult(interp, (char *)zRet, 0); 2319f93bbbeaSdanielk1977 } 232004f2e68dSdanielk1977 return TCL_OK; 232104f2e68dSdanielk1977 } 232204f2e68dSdanielk1977 23236b456a2bSdanielk1977 static int test_global_recover( 23246b456a2bSdanielk1977 void * clientData, 23256b456a2bSdanielk1977 Tcl_Interp *interp, 23266b456a2bSdanielk1977 int objc, 23276b456a2bSdanielk1977 Tcl_Obj *CONST objv[] 23286b456a2bSdanielk1977 ){ 23296b456a2bSdanielk1977 #ifndef SQLITE_OMIT_GLOBALRECOVER 23306b456a2bSdanielk1977 int rc; 23316b456a2bSdanielk1977 if( objc!=1 ){ 23326b456a2bSdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, ""); 23336b456a2bSdanielk1977 return TCL_ERROR; 23346b456a2bSdanielk1977 } 23356b456a2bSdanielk1977 rc = sqlite3_global_recover(); 23366b456a2bSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 23376b456a2bSdanielk1977 #endif 23386b456a2bSdanielk1977 return TCL_OK; 23396b456a2bSdanielk1977 } 23406b456a2bSdanielk1977 234104f2e68dSdanielk1977 /* 234204f2e68dSdanielk1977 ** Usage: sqlite3_column_text STMT column 234304f2e68dSdanielk1977 ** 234404f2e68dSdanielk1977 ** Usage: sqlite3_column_decltype STMT column 234504f2e68dSdanielk1977 ** 234604f2e68dSdanielk1977 ** Usage: sqlite3_column_name STMT column 234704f2e68dSdanielk1977 */ 234804f2e68dSdanielk1977 static int test_stmt_utf16( 2349241db313Sdrh void * clientData, /* Pointer to SQLite API function to be invoked */ 235004f2e68dSdanielk1977 Tcl_Interp *interp, 235104f2e68dSdanielk1977 int objc, 235204f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 235304f2e68dSdanielk1977 ){ 23545436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 235504f2e68dSdanielk1977 sqlite3_stmt *pStmt; 235604f2e68dSdanielk1977 int col; 235704f2e68dSdanielk1977 Tcl_Obj *pRet; 235804f2e68dSdanielk1977 const void *zName16; 2359c572ef7fSdanielk1977 const void *(*xFunc)(sqlite3_stmt*, int) = clientData; 236004f2e68dSdanielk1977 236104f2e68dSdanielk1977 if( objc!=3 ){ 236204f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 236304f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 236404f2e68dSdanielk1977 return TCL_ERROR; 236504f2e68dSdanielk1977 } 236604f2e68dSdanielk1977 236704f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 236804f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 236904f2e68dSdanielk1977 237004f2e68dSdanielk1977 zName16 = xFunc(pStmt, col); 2371f93bbbeaSdanielk1977 if( zName16 ){ 237204f2e68dSdanielk1977 pRet = Tcl_NewByteArrayObj(zName16, sqlite3utf16ByteLen(zName16, -1)+2); 237304f2e68dSdanielk1977 Tcl_SetObjResult(interp, pRet); 2374f93bbbeaSdanielk1977 } 23755436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 237604f2e68dSdanielk1977 237704f2e68dSdanielk1977 return TCL_OK; 237804f2e68dSdanielk1977 } 237904f2e68dSdanielk1977 238004f2e68dSdanielk1977 /* 238104f2e68dSdanielk1977 ** Usage: sqlite3_column_int STMT column 238204f2e68dSdanielk1977 ** 238304f2e68dSdanielk1977 ** Usage: sqlite3_column_bytes STMT column 238404f2e68dSdanielk1977 ** 238504f2e68dSdanielk1977 ** Usage: sqlite3_column_bytes16 STMT column 238604f2e68dSdanielk1977 ** 238704f2e68dSdanielk1977 */ 238804f2e68dSdanielk1977 static int test_stmt_int( 2389241db313Sdrh void * clientData, /* Pointer to SQLite API function to be invoked */ 239004f2e68dSdanielk1977 Tcl_Interp *interp, 239104f2e68dSdanielk1977 int objc, 239204f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 239304f2e68dSdanielk1977 ){ 239404f2e68dSdanielk1977 sqlite3_stmt *pStmt; 239504f2e68dSdanielk1977 int col; 2396c572ef7fSdanielk1977 int (*xFunc)(sqlite3_stmt*, int) = clientData; 239704f2e68dSdanielk1977 239804f2e68dSdanielk1977 if( objc!=3 ){ 239904f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 240004f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 240104f2e68dSdanielk1977 return TCL_ERROR; 240204f2e68dSdanielk1977 } 240304f2e68dSdanielk1977 240404f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 240504f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 240604f2e68dSdanielk1977 240704f2e68dSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(xFunc(pStmt, col))); 240804f2e68dSdanielk1977 return TCL_OK; 240904f2e68dSdanielk1977 } 241004f2e68dSdanielk1977 241144ee5bf7Sdanielk1977 #ifndef SQLITE_OMIT_DISKIO 24129a1d0abeSdanielk1977 /* 24139a1d0abeSdanielk1977 ** Usage: sqlite3OsOpenReadWrite <filename> 24149a1d0abeSdanielk1977 */ 24159a1d0abeSdanielk1977 static int test_sqlite3OsOpenReadWrite( 24169a1d0abeSdanielk1977 void * clientData, 24179a1d0abeSdanielk1977 Tcl_Interp *interp, 24189a1d0abeSdanielk1977 int objc, 24199a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 24209a1d0abeSdanielk1977 ){ 24219a1d0abeSdanielk1977 OsFile * pFile; 24229a1d0abeSdanielk1977 int rc; 24239a1d0abeSdanielk1977 int dummy; 24249a1d0abeSdanielk1977 char zBuf[100]; 242504f2e68dSdanielk1977 24269a1d0abeSdanielk1977 if( objc!=2 ){ 24279a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 24289a1d0abeSdanielk1977 Tcl_GetString(objv[0]), " filename", 0); 24299a1d0abeSdanielk1977 return TCL_ERROR; 24309a1d0abeSdanielk1977 } 24319a1d0abeSdanielk1977 24329a1d0abeSdanielk1977 pFile = sqliteMalloc(sizeof(OsFile)); 24339a1d0abeSdanielk1977 rc = sqlite3OsOpenReadWrite(Tcl_GetString(objv[1]), pFile, &dummy); 24349a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 24359a1d0abeSdanielk1977 sqliteFree(pFile); 24369a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 24379a1d0abeSdanielk1977 return TCL_ERROR; 24389a1d0abeSdanielk1977 } 24399a1d0abeSdanielk1977 makePointerStr(interp, zBuf, pFile); 24409a1d0abeSdanielk1977 Tcl_SetResult(interp, zBuf, 0); 24419a1d0abeSdanielk1977 return TCL_ERROR; 24429a1d0abeSdanielk1977 } 24439a1d0abeSdanielk1977 24449a1d0abeSdanielk1977 /* 24459a1d0abeSdanielk1977 ** Usage: sqlite3OsClose <file handle> 24469a1d0abeSdanielk1977 */ 24479a1d0abeSdanielk1977 static int test_sqlite3OsClose( 24489a1d0abeSdanielk1977 void * clientData, 24499a1d0abeSdanielk1977 Tcl_Interp *interp, 24509a1d0abeSdanielk1977 int objc, 24519a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 24529a1d0abeSdanielk1977 ){ 24539a1d0abeSdanielk1977 OsFile * pFile; 24549a1d0abeSdanielk1977 int rc; 24559a1d0abeSdanielk1977 24569a1d0abeSdanielk1977 if( objc!=2 ){ 24579a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 24589a1d0abeSdanielk1977 Tcl_GetString(objv[0]), " filehandle", 0); 24599a1d0abeSdanielk1977 return TCL_ERROR; 24609a1d0abeSdanielk1977 } 24619a1d0abeSdanielk1977 24629a1d0abeSdanielk1977 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 24639a1d0abeSdanielk1977 return TCL_ERROR; 24649a1d0abeSdanielk1977 } 24659a1d0abeSdanielk1977 rc = sqlite3OsClose(pFile); 24669a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 24679a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 24689a1d0abeSdanielk1977 return TCL_ERROR; 24699a1d0abeSdanielk1977 } 24709a1d0abeSdanielk1977 sqliteFree(pFile); 24719a1d0abeSdanielk1977 return TCL_OK; 24729a1d0abeSdanielk1977 } 24739a1d0abeSdanielk1977 24749a1d0abeSdanielk1977 /* 24759a1d0abeSdanielk1977 ** Usage: sqlite3OsLock <file handle> <locktype> 24769a1d0abeSdanielk1977 */ 24779a1d0abeSdanielk1977 static int test_sqlite3OsLock( 24789a1d0abeSdanielk1977 void * clientData, 24799a1d0abeSdanielk1977 Tcl_Interp *interp, 24809a1d0abeSdanielk1977 int objc, 24819a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 24829a1d0abeSdanielk1977 ){ 24839a1d0abeSdanielk1977 OsFile * pFile; 24849a1d0abeSdanielk1977 int rc; 24859a1d0abeSdanielk1977 24869a1d0abeSdanielk1977 if( objc!=3 ){ 24879a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 24889a1d0abeSdanielk1977 Tcl_GetString(objv[0]), 24899a1d0abeSdanielk1977 " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0); 24909a1d0abeSdanielk1977 return TCL_ERROR; 24919a1d0abeSdanielk1977 } 24929a1d0abeSdanielk1977 24939a1d0abeSdanielk1977 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 24949a1d0abeSdanielk1977 return TCL_ERROR; 24959a1d0abeSdanielk1977 } 24969a1d0abeSdanielk1977 24979a1d0abeSdanielk1977 if( 0==strcmp("SHARED", Tcl_GetString(objv[2])) ){ 24989a1d0abeSdanielk1977 rc = sqlite3OsLock(pFile, SHARED_LOCK); 24999a1d0abeSdanielk1977 } 25009a1d0abeSdanielk1977 else if( 0==strcmp("RESERVED", Tcl_GetString(objv[2])) ){ 25019a1d0abeSdanielk1977 rc = sqlite3OsLock(pFile, RESERVED_LOCK); 25029a1d0abeSdanielk1977 } 25039a1d0abeSdanielk1977 else if( 0==strcmp("PENDING", Tcl_GetString(objv[2])) ){ 25049a1d0abeSdanielk1977 rc = sqlite3OsLock(pFile, PENDING_LOCK); 25059a1d0abeSdanielk1977 } 25069a1d0abeSdanielk1977 else if( 0==strcmp("EXCLUSIVE", Tcl_GetString(objv[2])) ){ 25079a1d0abeSdanielk1977 rc = sqlite3OsLock(pFile, EXCLUSIVE_LOCK); 25089a1d0abeSdanielk1977 }else{ 25099a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 25109a1d0abeSdanielk1977 Tcl_GetString(objv[0]), 25119a1d0abeSdanielk1977 " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0); 25129a1d0abeSdanielk1977 return TCL_ERROR; 25139a1d0abeSdanielk1977 } 25149a1d0abeSdanielk1977 25159a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 25169a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 25179a1d0abeSdanielk1977 return TCL_ERROR; 25189a1d0abeSdanielk1977 } 25199a1d0abeSdanielk1977 return TCL_OK; 25209a1d0abeSdanielk1977 } 25219a1d0abeSdanielk1977 25229a1d0abeSdanielk1977 /* 25239a1d0abeSdanielk1977 ** Usage: sqlite3OsUnlock <file handle> 25249a1d0abeSdanielk1977 */ 25259a1d0abeSdanielk1977 static int test_sqlite3OsUnlock( 25269a1d0abeSdanielk1977 void * clientData, 25279a1d0abeSdanielk1977 Tcl_Interp *interp, 25289a1d0abeSdanielk1977 int objc, 25299a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 25309a1d0abeSdanielk1977 ){ 25319a1d0abeSdanielk1977 OsFile * pFile; 25329a1d0abeSdanielk1977 int rc; 25339a1d0abeSdanielk1977 25349a1d0abeSdanielk1977 if( objc!=2 ){ 25359a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 25369a1d0abeSdanielk1977 Tcl_GetString(objv[0]), " filehandle", 0); 25379a1d0abeSdanielk1977 return TCL_ERROR; 25389a1d0abeSdanielk1977 } 25399a1d0abeSdanielk1977 25409a1d0abeSdanielk1977 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 25419a1d0abeSdanielk1977 return TCL_ERROR; 25429a1d0abeSdanielk1977 } 2543a6abd041Sdrh rc = sqlite3OsUnlock(pFile, NO_LOCK); 25449a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 25459a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 25469a1d0abeSdanielk1977 return TCL_ERROR; 25479a1d0abeSdanielk1977 } 25489a1d0abeSdanielk1977 return TCL_OK; 25499a1d0abeSdanielk1977 } 2550d3d39e93Sdrh 2551ab3f9feaSdrh /* 2552ab3f9feaSdrh ** Usage: sqlite3OsTempFileName 2553ab3f9feaSdrh */ 2554ab3f9feaSdrh static int test_sqlite3OsTempFileName( 2555ab3f9feaSdrh void * clientData, 2556ab3f9feaSdrh Tcl_Interp *interp, 2557ab3f9feaSdrh int objc, 2558ab3f9feaSdrh Tcl_Obj *CONST objv[] 2559ab3f9feaSdrh ){ 2560ab3f9feaSdrh char zFile[SQLITE_TEMPNAME_SIZE]; 2561ab3f9feaSdrh int rc; 2562ab3f9feaSdrh 2563ab3f9feaSdrh rc = sqlite3OsTempFileName(zFile); 2564ab3f9feaSdrh if( rc!=SQLITE_OK ){ 2565ab3f9feaSdrh Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 2566ab3f9feaSdrh return TCL_ERROR; 2567ab3f9feaSdrh } 2568ab3f9feaSdrh Tcl_AppendResult(interp, zFile, 0); 2569ab3f9feaSdrh return TCL_OK; 2570ab3f9feaSdrh } 257144ee5bf7Sdanielk1977 #endif 2572d8123366Sdanielk1977 25736622cce3Sdanielk1977 /* 2574cacb208eSdrh ** Usage: sqlite_set_magic DB MAGIC-NUMBER 2575cacb208eSdrh ** 2576cacb208eSdrh ** Set the db->magic value. This is used to test error recovery logic. 2577cacb208eSdrh */ 2578cacb208eSdrh static int sqlite_set_magic( 2579cacb208eSdrh void * clientData, 2580cacb208eSdrh Tcl_Interp *interp, 2581cacb208eSdrh int argc, 2582cacb208eSdrh char **argv 2583cacb208eSdrh ){ 2584cacb208eSdrh sqlite3 *db; 2585cacb208eSdrh if( argc!=3 ){ 2586cacb208eSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 2587cacb208eSdrh " DB MAGIC", 0); 2588cacb208eSdrh return TCL_ERROR; 2589cacb208eSdrh } 2590cacb208eSdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 2591cacb208eSdrh if( strcmp(argv[2], "SQLITE_MAGIC_OPEN")==0 ){ 2592cacb208eSdrh db->magic = SQLITE_MAGIC_OPEN; 2593cacb208eSdrh }else if( strcmp(argv[2], "SQLITE_MAGIC_CLOSED")==0 ){ 2594cacb208eSdrh db->magic = SQLITE_MAGIC_CLOSED; 2595cacb208eSdrh }else if( strcmp(argv[2], "SQLITE_MAGIC_BUSY")==0 ){ 2596cacb208eSdrh db->magic = SQLITE_MAGIC_BUSY; 2597cacb208eSdrh }else if( strcmp(argv[2], "SQLITE_MAGIC_ERROR")==0 ){ 2598cacb208eSdrh db->magic = SQLITE_MAGIC_ERROR; 2599cacb208eSdrh }else if( Tcl_GetInt(interp, argv[2], &db->magic) ){ 2600cacb208eSdrh return TCL_ERROR; 2601cacb208eSdrh } 2602cacb208eSdrh return TCL_OK; 2603cacb208eSdrh } 2604cacb208eSdrh 2605cacb208eSdrh /* 2606c5cdca61Sdrh ** Usage: sqlite3_interrupt DB 2607c5cdca61Sdrh ** 2608c5cdca61Sdrh ** Trigger an interrupt on DB 2609c5cdca61Sdrh */ 2610c5cdca61Sdrh static int test_interrupt( 2611c5cdca61Sdrh void * clientData, 2612c5cdca61Sdrh Tcl_Interp *interp, 2613c5cdca61Sdrh int argc, 2614c5cdca61Sdrh char **argv 2615c5cdca61Sdrh ){ 2616c5cdca61Sdrh sqlite3 *db; 2617c5cdca61Sdrh if( argc!=2 ){ 2618c5cdca61Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB", 0); 2619c5cdca61Sdrh return TCL_ERROR; 2620c5cdca61Sdrh } 2621c5cdca61Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 2622c5cdca61Sdrh sqlite3_interrupt(db); 2623c5cdca61Sdrh return TCL_OK; 2624c5cdca61Sdrh } 2625c5cdca61Sdrh 2626c5cdca61Sdrh /* 2627600dd0baSdanielk1977 ** Usage: sqlite3_sleep ms 2628600dd0baSdanielk1977 ** 2629600dd0baSdanielk1977 ** Sleep for the specified number of ms. 2630600dd0baSdanielk1977 */ 2631600dd0baSdanielk1977 #if 0 2632600dd0baSdanielk1977 static int test_sleep( 2633600dd0baSdanielk1977 void * clientData, 2634600dd0baSdanielk1977 Tcl_Interp *interp, 2635600dd0baSdanielk1977 int argc, 2636600dd0baSdanielk1977 char **argv 2637600dd0baSdanielk1977 ){ 2638600dd0baSdanielk1977 sqlite3 *db; 2639600dd0baSdanielk1977 if( argc!=2 ){ 2640600dd0baSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ms", 0); 2641600dd0baSdanielk1977 return TCL_ERROR; 2642600dd0baSdanielk1977 } 2643600dd0baSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_sleep(atoi(argv[1])))); 2644600dd0baSdanielk1977 return TCL_OK; 2645600dd0baSdanielk1977 } 2646600dd0baSdanielk1977 #endif 2647600dd0baSdanielk1977 2648600dd0baSdanielk1977 /* 26499636c4e1Sdanielk1977 ** Usage: sqlite_delete_function DB function-name 26509636c4e1Sdanielk1977 ** 26519636c4e1Sdanielk1977 ** Delete the user function 'function-name' from database handle DB. It 26529636c4e1Sdanielk1977 ** is assumed that the user function was created as UTF8, any number of 26539636c4e1Sdanielk1977 ** arguments (the way the TCL interface does it). 26549636c4e1Sdanielk1977 */ 26559636c4e1Sdanielk1977 static int delete_function( 26569636c4e1Sdanielk1977 void * clientData, 26579636c4e1Sdanielk1977 Tcl_Interp *interp, 26589636c4e1Sdanielk1977 int argc, 26599636c4e1Sdanielk1977 char **argv 26609636c4e1Sdanielk1977 ){ 26619636c4e1Sdanielk1977 int rc; 26629636c4e1Sdanielk1977 sqlite3 *db; 26639636c4e1Sdanielk1977 if( argc!=3 ){ 26649636c4e1Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 26659636c4e1Sdanielk1977 " DB function-name", 0); 26669636c4e1Sdanielk1977 return TCL_ERROR; 26679636c4e1Sdanielk1977 } 26689636c4e1Sdanielk1977 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 26699636c4e1Sdanielk1977 rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 0, 0, 0); 26709636c4e1Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 26719636c4e1Sdanielk1977 return TCL_OK; 26729636c4e1Sdanielk1977 } 26739636c4e1Sdanielk1977 26749636c4e1Sdanielk1977 /* 26759636c4e1Sdanielk1977 ** Usage: sqlite_delete_collation DB collation-name 26769636c4e1Sdanielk1977 ** 26779636c4e1Sdanielk1977 ** Delete the collation sequence 'collation-name' from database handle 26789636c4e1Sdanielk1977 ** DB. It is assumed that the collation sequence was created as UTF8 (the 26799636c4e1Sdanielk1977 ** way the TCL interface does it). 26809636c4e1Sdanielk1977 */ 26819636c4e1Sdanielk1977 static int delete_collation( 26829636c4e1Sdanielk1977 void * clientData, 26839636c4e1Sdanielk1977 Tcl_Interp *interp, 26849636c4e1Sdanielk1977 int argc, 26859636c4e1Sdanielk1977 char **argv 26869636c4e1Sdanielk1977 ){ 26879636c4e1Sdanielk1977 int rc; 26889636c4e1Sdanielk1977 sqlite3 *db; 26899636c4e1Sdanielk1977 if( argc!=3 ){ 26909636c4e1Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 26919636c4e1Sdanielk1977 " DB function-name", 0); 26929636c4e1Sdanielk1977 return TCL_ERROR; 26939636c4e1Sdanielk1977 } 26949636c4e1Sdanielk1977 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 26959636c4e1Sdanielk1977 rc = sqlite3_create_collation(db, argv[2], SQLITE_UTF8, 0, 0); 26969636c4e1Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 26979636c4e1Sdanielk1977 return TCL_OK; 26989636c4e1Sdanielk1977 } 26999636c4e1Sdanielk1977 27009636c4e1Sdanielk1977 /* 27013e1d8e63Sdrh ** Usage: sqlite3_get_autocommit DB 27023e1d8e63Sdrh ** 27033e1d8e63Sdrh ** Return true if the database DB is currently in auto-commit mode. 27043e1d8e63Sdrh ** Return false if not. 27053e1d8e63Sdrh */ 27063e1d8e63Sdrh static int get_autocommit( 27073e1d8e63Sdrh void * clientData, 27083e1d8e63Sdrh Tcl_Interp *interp, 27093e1d8e63Sdrh int argc, 27103e1d8e63Sdrh char **argv 27113e1d8e63Sdrh ){ 27123e1d8e63Sdrh char zBuf[30]; 27133e1d8e63Sdrh sqlite3 *db; 27143e1d8e63Sdrh if( argc!=2 ){ 27153e1d8e63Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 27163e1d8e63Sdrh " DB", 0); 27173e1d8e63Sdrh return TCL_ERROR; 27183e1d8e63Sdrh } 27193e1d8e63Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 27203e1d8e63Sdrh sprintf(zBuf, "%d", sqlite3_get_autocommit(db)); 27213e1d8e63Sdrh Tcl_AppendResult(interp, zBuf, 0); 27223e1d8e63Sdrh return TCL_OK; 27233e1d8e63Sdrh } 27243e1d8e63Sdrh 27253e1d8e63Sdrh /* 272692febd92Sdrh ** Usage: tcl_variable_type VARIABLENAME 272792febd92Sdrh ** 272892febd92Sdrh ** Return the name of the internal representation for the 272992febd92Sdrh ** value of the given variable. 273092febd92Sdrh */ 273192febd92Sdrh static int tcl_variable_type( 273292febd92Sdrh void * clientData, 273392febd92Sdrh Tcl_Interp *interp, 273492febd92Sdrh int objc, 273592febd92Sdrh Tcl_Obj *CONST objv[] 273692febd92Sdrh ){ 273792febd92Sdrh Tcl_Obj *pVar; 273892febd92Sdrh if( objc!=2 ){ 273992febd92Sdrh Tcl_WrongNumArgs(interp, 1, objv, "VARIABLE"); 274092febd92Sdrh return TCL_ERROR; 274192febd92Sdrh } 274292febd92Sdrh pVar = Tcl_GetVar2Ex(interp, Tcl_GetString(objv[1]), 0, TCL_LEAVE_ERR_MSG); 274392febd92Sdrh if( pVar==0 ) return TCL_ERROR; 274492febd92Sdrh if( pVar->typePtr ){ 274592febd92Sdrh Tcl_SetObjResult(interp, Tcl_NewStringObj(pVar->typePtr->name, -1)); 274692febd92Sdrh } 274792febd92Sdrh return TCL_OK; 274892febd92Sdrh } 274992febd92Sdrh 275092febd92Sdrh /* 275127d258a3Sdrh ** This routine sets entries in the global ::sqlite_options() array variable 275227d258a3Sdrh ** according to the compile-time configuration of the database. Test 275327d258a3Sdrh ** procedures use this to determine when tests should be omitted. 275427d258a3Sdrh */ 275527d258a3Sdrh static void set_options(Tcl_Interp *interp){ 275675f86a4bSdrh #ifdef SQLITE_32BIT_ROWID 275775f86a4bSdrh Tcl_SetVar2(interp, "sqlite_options", "rowid32", "1", TCL_GLOBAL_ONLY); 275875f86a4bSdrh #else 275975f86a4bSdrh Tcl_SetVar2(interp, "sqlite_options", "rowid32", "0", TCL_GLOBAL_ONLY); 276075f86a4bSdrh #endif 276175f86a4bSdrh 27629f18e8a0Sdrh #ifdef SQLITE_CASE_SENSITIVE_LIKE 27639f18e8a0Sdrh Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","1",TCL_GLOBAL_ONLY); 27649f18e8a0Sdrh #else 27659f18e8a0Sdrh Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","0",TCL_GLOBAL_ONLY); 27669f18e8a0Sdrh #endif 27679f18e8a0Sdrh 27681c8c23ccSdanielk1977 #ifdef SQLITE_OMIT_ALTERTABLE 27691c8c23ccSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY); 27701c8c23ccSdanielk1977 #else 27711c8c23ccSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY); 27721c8c23ccSdanielk1977 #endif 277313d7042aSdrh 27749f18e8a0Sdrh #ifdef SQLITE_OMIT_ANALYZE 27759f18e8a0Sdrh Tcl_SetVar2(interp, "sqlite_options", "analyze", "0", TCL_GLOBAL_ONLY); 27769f18e8a0Sdrh #else 27779f18e8a0Sdrh Tcl_SetVar2(interp, "sqlite_options", "analyze", "1", TCL_GLOBAL_ONLY); 27789f18e8a0Sdrh #endif 27799f18e8a0Sdrh 278013d7042aSdrh #ifdef SQLITE_OMIT_AUTHORIZATION 278113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "auth", "0", TCL_GLOBAL_ONLY); 278213d7042aSdrh #else 278313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "auth", "1", TCL_GLOBAL_ONLY); 278413d7042aSdrh #endif 278513d7042aSdrh 2786f3388144Sdrh #ifdef SQLITE_OMIT_AUTOINCREMENT 2787f3388144Sdrh Tcl_SetVar2(interp, "sqlite_options", "autoinc", "0", TCL_GLOBAL_ONLY); 2788f3388144Sdrh #else 2789f3388144Sdrh Tcl_SetVar2(interp, "sqlite_options", "autoinc", "1", TCL_GLOBAL_ONLY); 2790f3388144Sdrh #endif 2791f3388144Sdrh 279245901d62Sdanielk1977 #ifdef SQLITE_OMIT_AUTOVACUUM 279345901d62Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "0", TCL_GLOBAL_ONLY); 279445901d62Sdanielk1977 #else 279545901d62Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "1", TCL_GLOBAL_ONLY); 2796f3388144Sdrh #endif /* SQLITE_OMIT_AUTOVACUUM */ 27974d36b81eSdanielk1977 #if !defined(SQLITE_DEFAULT_AUTOVACUUM) || SQLITE_DEFAULT_AUTOVACUUM==0 279845901d62Sdanielk1977 Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","0",TCL_GLOBAL_ONLY); 279945901d62Sdanielk1977 #else 280045901d62Sdanielk1977 Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","1",TCL_GLOBAL_ONLY); 280145901d62Sdanielk1977 #endif 280213d7042aSdrh 280313d7042aSdrh #ifdef SQLITE_OMIT_BLOB_LITERAL 280413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "bloblit", "0", TCL_GLOBAL_ONLY); 280513d7042aSdrh #else 280613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY); 280713d7042aSdrh #endif 280813d7042aSdrh 2809487e262fSdrh #ifdef SQLITE_OMIT_CAST 2810487e262fSdrh Tcl_SetVar2(interp, "sqlite_options", "cast", "0", TCL_GLOBAL_ONLY); 2811487e262fSdrh #else 2812487e262fSdrh Tcl_SetVar2(interp, "sqlite_options", "cast", "1", TCL_GLOBAL_ONLY); 2813487e262fSdrh #endif 2814487e262fSdrh 2815ccae6026Sdrh #ifdef SQLITE_OMIT_COMPLETE 2816ccae6026Sdrh Tcl_SetVar2(interp, "sqlite_options", "complete", "0", TCL_GLOBAL_ONLY); 2817ccae6026Sdrh #else 2818ccae6026Sdrh Tcl_SetVar2(interp, "sqlite_options", "complete", "1", TCL_GLOBAL_ONLY); 2819ccae6026Sdrh #endif 2820ccae6026Sdrh 282113d7042aSdrh #ifdef SQLITE_OMIT_COMPOUND_SELECT 282213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "compound", "0", TCL_GLOBAL_ONLY); 282313d7042aSdrh #else 282413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "compound", "1", TCL_GLOBAL_ONLY); 282513d7042aSdrh #endif 282613d7042aSdrh 282713d7042aSdrh #ifdef SQLITE_OMIT_CONFLICT_CLAUSE 282813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "conflict", "0", TCL_GLOBAL_ONLY); 282913d7042aSdrh #else 283013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "conflict", "1", TCL_GLOBAL_ONLY); 283113d7042aSdrh #endif 283213d7042aSdrh 283313d7042aSdrh #ifdef SQLITE_OMIT_DATETIME_FUNCS 283413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "datetime", "0", TCL_GLOBAL_ONLY); 283513d7042aSdrh #else 283613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "datetime", "1", TCL_GLOBAL_ONLY); 283713d7042aSdrh #endif 283813d7042aSdrh 28392e66f0b9Sdrh #ifdef SQLITE_OMIT_DISKIO 28402e66f0b9Sdrh Tcl_SetVar2(interp, "sqlite_options", "diskio", "0", TCL_GLOBAL_ONLY); 28412e66f0b9Sdrh #else 28422e66f0b9Sdrh Tcl_SetVar2(interp, "sqlite_options", "diskio", "1", TCL_GLOBAL_ONLY); 28432e66f0b9Sdrh #endif 28442e66f0b9Sdrh 284513d7042aSdrh #ifdef SQLITE_OMIT_EXPLAIN 284613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "explain", "0", TCL_GLOBAL_ONLY); 284713d7042aSdrh #else 284813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "explain", "1", TCL_GLOBAL_ONLY); 284913d7042aSdrh #endif 285013d7042aSdrh 285113d7042aSdrh #ifdef SQLITE_OMIT_FLOATING_POINT 285213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "0", TCL_GLOBAL_ONLY); 285313d7042aSdrh #else 285413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "1", TCL_GLOBAL_ONLY); 285513d7042aSdrh #endif 285613d7042aSdrh 285713d7042aSdrh #ifdef SQLITE_OMIT_FOREIGN_KEY 285813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "0", TCL_GLOBAL_ONLY); 285913d7042aSdrh #else 286013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "1", TCL_GLOBAL_ONLY); 286113d7042aSdrh #endif 286213d7042aSdrh 28636b456a2bSdanielk1977 #ifdef SQLITE_OMIT_GLOBALRECOVER 28646b456a2bSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "0", TCL_GLOBAL_ONLY); 28656b456a2bSdanielk1977 #else 28666b456a2bSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "1", TCL_GLOBAL_ONLY); 28676b456a2bSdanielk1977 #endif 28686b456a2bSdanielk1977 286913d7042aSdrh #ifdef SQLITE_OMIT_INTEGRITY_CHECK 287013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "integrityck", "0", TCL_GLOBAL_ONLY); 287113d7042aSdrh #else 287213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "integrityck", "1", TCL_GLOBAL_ONLY); 287313d7042aSdrh #endif 287413d7042aSdrh 287513d7042aSdrh #ifdef SQLITE_OMIT_MEMORYDB 287613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "memorydb", "0", TCL_GLOBAL_ONLY); 287713d7042aSdrh #else 287813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "memorydb", "1", TCL_GLOBAL_ONLY); 287913d7042aSdrh #endif 288013d7042aSdrh 288113d7042aSdrh #ifdef SQLITE_OMIT_PAGER_PRAGMAS 288213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "0", TCL_GLOBAL_ONLY); 288313d7042aSdrh #else 288413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "1", TCL_GLOBAL_ONLY); 288513d7042aSdrh #endif 288613d7042aSdrh 28872e66f0b9Sdrh #ifdef SQLITE_OMIT_PARSER 28882e66f0b9Sdrh Tcl_SetVar2(interp, "sqlite_options", "parser", "0", TCL_GLOBAL_ONLY); 28892e66f0b9Sdrh #else 28902e66f0b9Sdrh Tcl_SetVar2(interp, "sqlite_options", "parser", "1", TCL_GLOBAL_ONLY); 28912e66f0b9Sdrh #endif 28922e66f0b9Sdrh 2893bf21627bSdrh #if defined(SQLITE_OMIT_PRAGMA) || defined(SQLITE_OMIT_FLAG_PRAGMAS) 289413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pragma", "0", TCL_GLOBAL_ONLY); 289513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "integrityck", "0", TCL_GLOBAL_ONLY); 289613d7042aSdrh #else 289713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pragma", "1", TCL_GLOBAL_ONLY); 289813d7042aSdrh #endif 289913d7042aSdrh 290013d7042aSdrh #ifdef SQLITE_OMIT_PROGRESS_CALLBACK 290113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "progress", "0", TCL_GLOBAL_ONLY); 290213d7042aSdrh #else 290313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "progress", "1", TCL_GLOBAL_ONLY); 290413d7042aSdrh #endif 290513d7042aSdrh 290613d7042aSdrh #ifdef SQLITE_OMIT_REINDEX 290713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "reindex", "0", TCL_GLOBAL_ONLY); 290813d7042aSdrh #else 290913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "reindex", "1", TCL_GLOBAL_ONLY); 291013d7042aSdrh #endif 291113d7042aSdrh 291213d7042aSdrh #ifdef SQLITE_OMIT_SCHEMA_PRAGMAS 291313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "0", TCL_GLOBAL_ONLY); 291413d7042aSdrh #else 291513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "1", TCL_GLOBAL_ONLY); 291613d7042aSdrh #endif 291713d7042aSdrh 291813d7042aSdrh #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS 291913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_version", "0", TCL_GLOBAL_ONLY); 292013d7042aSdrh #else 292113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY); 292213d7042aSdrh #endif 292313d7042aSdrh 29243e8c37e7Sdanielk1977 #ifdef SQLITE_OMIT_SUBQUERY 29253e8c37e7Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "subquery", "0", TCL_GLOBAL_ONLY); 29263e8c37e7Sdanielk1977 #else 29273e8c37e7Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "subquery", "1", TCL_GLOBAL_ONLY); 29283e8c37e7Sdanielk1977 #endif 29293e8c37e7Sdanielk1977 293013d7042aSdrh #ifdef SQLITE_OMIT_TCL_VARIABLE 293113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "tclvar", "0", TCL_GLOBAL_ONLY); 293213d7042aSdrh #else 293313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "tclvar", "1", TCL_GLOBAL_ONLY); 293413d7042aSdrh #endif 293513d7042aSdrh 293613d7042aSdrh #if defined(THREADSAFE) && THREADSAFE 293713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "1", TCL_GLOBAL_ONLY); 293813d7042aSdrh #else 293913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "0", TCL_GLOBAL_ONLY); 294013d7042aSdrh #endif 294113d7042aSdrh 294213d7042aSdrh #ifdef SQLITE_OMIT_TRIGGER 294313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "trigger", "0", TCL_GLOBAL_ONLY); 294413d7042aSdrh #else 294513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "trigger", "1", TCL_GLOBAL_ONLY); 294613d7042aSdrh #endif 294713d7042aSdrh 294853c0f748Sdanielk1977 #ifdef SQLITE_OMIT_TEMPDB 294953c0f748Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "tempdb", "0", TCL_GLOBAL_ONLY); 295053c0f748Sdanielk1977 #else 295153c0f748Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "tempdb", "1", TCL_GLOBAL_ONLY); 295253c0f748Sdanielk1977 #endif 295353c0f748Sdanielk1977 295413d7042aSdrh #ifdef SQLITE_OMIT_UTF16 295513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY); 295613d7042aSdrh #else 295713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "utf16", "1", TCL_GLOBAL_ONLY); 295813d7042aSdrh #endif 295913d7042aSdrh 296013d7042aSdrh #ifdef SQLITE_OMIT_VACUUM 296113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "vacuum", "0", TCL_GLOBAL_ONLY); 296213d7042aSdrh #else 296313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "vacuum", "1", TCL_GLOBAL_ONLY); 296413d7042aSdrh #endif 296513d7042aSdrh 296613d7042aSdrh #ifdef SQLITE_OMIT_VIEW 296713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "view", "0", TCL_GLOBAL_ONLY); 296813d7042aSdrh #else 296913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "view", "1", TCL_GLOBAL_ONLY); 297013d7042aSdrh #endif 297127d258a3Sdrh } 297227d258a3Sdrh 297327d258a3Sdrh /* 2974d1bf3512Sdrh ** Register commands with the TCL interpreter. 2975d1bf3512Sdrh */ 2976d1bf3512Sdrh int Sqlitetest1_Init(Tcl_Interp *interp){ 29776f8a503dSdanielk1977 extern int sqlite3_search_count; 29786f8a503dSdanielk1977 extern int sqlite3_interrupt_count; 29796f8a503dSdanielk1977 extern int sqlite3_open_file_count; 29806bf89570Sdrh extern int sqlite3_sort_count; 29816f8a503dSdanielk1977 extern int sqlite3_current_time; 2982c2eef3b3Sdrh static struct { 2983c2eef3b3Sdrh char *zName; 2984c2eef3b3Sdrh Tcl_CmdProc *xProc; 2985c2eef3b3Sdrh } aCmd[] = { 29866f8a503dSdanielk1977 { "sqlite3_mprintf_int", (Tcl_CmdProc*)sqlite3_mprintf_int }, 2987e9707671Sdrh { "sqlite3_mprintf_int64", (Tcl_CmdProc*)sqlite3_mprintf_int64 }, 29886f8a503dSdanielk1977 { "sqlite3_mprintf_str", (Tcl_CmdProc*)sqlite3_mprintf_str }, 2989e29b1a05Sdrh { "sqlite3_mprintf_stronly", (Tcl_CmdProc*)sqlite3_mprintf_stronly}, 29906f8a503dSdanielk1977 { "sqlite3_mprintf_double", (Tcl_CmdProc*)sqlite3_mprintf_double }, 29916f8a503dSdanielk1977 { "sqlite3_mprintf_scaled", (Tcl_CmdProc*)sqlite3_mprintf_scaled }, 29926f8a503dSdanielk1977 { "sqlite3_mprintf_z_test", (Tcl_CmdProc*)test_mprintf_z }, 29936f8a503dSdanielk1977 { "sqlite3_last_insert_rowid", (Tcl_CmdProc*)test_last_rowid }, 29946f8a503dSdanielk1977 { "sqlite3_exec_printf", (Tcl_CmdProc*)test_exec_printf }, 29956f8a503dSdanielk1977 { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, 29966f8a503dSdanielk1977 { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, 29976f8a503dSdanielk1977 { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, 29986f8a503dSdanielk1977 { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, 2999c2eef3b3Sdrh { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, 3000c2eef3b3Sdrh { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, 30012c336549Sdanielk1977 #ifdef SQLITE_MEMDEBUG 3002c2eef3b3Sdrh { "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail }, 3003c2eef3b3Sdrh { "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat }, 3004c2eef3b3Sdrh #endif 300596fc5fe6Sdanielk1977 { "sqlite_bind", (Tcl_CmdProc*)test_bind }, 300699ee3600Sdrh { "breakpoint", (Tcl_CmdProc*)test_breakpoint }, 300725d6543dSdrh { "sqlite3_key", (Tcl_CmdProc*)test_key }, 300825d6543dSdrh { "sqlite3_rekey", (Tcl_CmdProc*)test_rekey }, 3009cacb208eSdrh { "sqlite_set_magic", (Tcl_CmdProc*)sqlite_set_magic }, 3010c5cdca61Sdrh { "sqlite3_interrupt", (Tcl_CmdProc*)test_interrupt }, 3011600dd0baSdanielk1977 #if 0 3012600dd0baSdanielk1977 { "sqlite3_sleep", (Tcl_CmdProc*)test_sleep }, 3013600dd0baSdanielk1977 #endif 30149636c4e1Sdanielk1977 { "sqlite_delete_function", (Tcl_CmdProc*)delete_function }, 30153e1d8e63Sdrh { "sqlite_delete_collation", (Tcl_CmdProc*)delete_collation }, 30163e1d8e63Sdrh { "sqlite3_get_autocommit", (Tcl_CmdProc*)get_autocommit }, 3017c2eef3b3Sdrh }; 301851e3d8e2Sdanielk1977 static struct { 301951e3d8e2Sdanielk1977 char *zName; 302051e3d8e2Sdanielk1977 Tcl_ObjCmdProc *xProc; 302104f2e68dSdanielk1977 void *clientData; 302251e3d8e2Sdanielk1977 } aObjCmd[] = { 3023241db313Sdrh { "sqlite3_bind_int", test_bind_int, 0 }, 302404f2e68dSdanielk1977 { "sqlite3_bind_int64", test_bind_int64, 0 }, 302504f2e68dSdanielk1977 { "sqlite3_bind_double", test_bind_double, 0 }, 302604f2e68dSdanielk1977 { "sqlite3_bind_null", test_bind_null ,0 }, 302704f2e68dSdanielk1977 { "sqlite3_bind_text", test_bind_text ,0 }, 302804f2e68dSdanielk1977 { "sqlite3_bind_text16", test_bind_text16 ,0 }, 302904f2e68dSdanielk1977 { "sqlite3_bind_blob", test_bind_blob ,0 }, 303075f6a032Sdrh { "sqlite3_bind_parameter_count", test_bind_parameter_count, 0}, 3031895d7472Sdrh { "sqlite3_bind_parameter_name", test_bind_parameter_name, 0}, 3032fa6bc000Sdrh { "sqlite3_bind_parameter_index", test_bind_parameter_index, 0}, 3033600dd0baSdanielk1977 #if 0 3034600dd0baSdanielk1977 { "sqlite3_clear_bindings", test_clear_bindings, 0}, 3035600dd0baSdanielk1977 #endif 303604f2e68dSdanielk1977 { "sqlite3_errcode", test_errcode ,0 }, 303704f2e68dSdanielk1977 { "sqlite3_errmsg", test_errmsg ,0 }, 303804f2e68dSdanielk1977 { "sqlite3_errmsg16", test_errmsg16 ,0 }, 303904f2e68dSdanielk1977 { "sqlite3_open", test_open ,0 }, 304004f2e68dSdanielk1977 { "sqlite3_open16", test_open16 ,0 }, 3041bc6ada41Sdanielk1977 { "sqlite3_complete16", test_complete16 ,0 }, 304204f2e68dSdanielk1977 304304f2e68dSdanielk1977 { "sqlite3_prepare", test_prepare ,0 }, 304404f2e68dSdanielk1977 { "sqlite3_prepare16", test_prepare16 ,0 }, 304504f2e68dSdanielk1977 { "sqlite3_finalize", test_finalize ,0 }, 304604f2e68dSdanielk1977 { "sqlite3_reset", test_reset ,0 }, 3047d89bd007Sdrh { "sqlite3_expired", test_expired ,0 }, 3048f8db1bc0Sdrh { "sqlite3_transfer_bindings", test_transfer_bind ,0 }, 3049fbcd585fSdanielk1977 { "sqlite3_changes", test_changes ,0 }, 305004f2e68dSdanielk1977 { "sqlite3_step", test_step ,0 }, 305104f2e68dSdanielk1977 305204f2e68dSdanielk1977 /* sqlite3_column_*() API */ 305304f2e68dSdanielk1977 { "sqlite3_column_count", test_column_count ,0 }, 305404f2e68dSdanielk1977 { "sqlite3_data_count", test_data_count ,0 }, 305504f2e68dSdanielk1977 { "sqlite3_column_type", test_column_type ,0 }, 3056ea61b2c4Sdanielk1977 { "sqlite3_column_blob", test_column_blob ,0 }, 305704f2e68dSdanielk1977 { "sqlite3_column_double", test_column_double ,0 }, 305804f2e68dSdanielk1977 { "sqlite3_column_int64", test_column_int64 ,0 }, 305904f2e68dSdanielk1977 { "sqlite3_column_text", test_stmt_utf8, sqlite3_column_text }, 306004f2e68dSdanielk1977 { "sqlite3_column_decltype", test_stmt_utf8, sqlite3_column_decltype }, 306104f2e68dSdanielk1977 { "sqlite3_column_name", test_stmt_utf8, sqlite3_column_name }, 30626c62608fSdrh { "sqlite3_column_int", test_stmt_int, sqlite3_column_int }, 30636c62608fSdrh { "sqlite3_column_bytes", test_stmt_int, sqlite3_column_bytes }, 30646c62608fSdrh #ifndef SQLITE_OMIT_UTF16 30656c62608fSdrh { "sqlite3_column_bytes16", test_stmt_int, sqlite3_column_bytes16 }, 306604f2e68dSdanielk1977 { "sqlite3_column_text16", test_stmt_utf16, sqlite3_column_text16 }, 306704f2e68dSdanielk1977 { "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16}, 306804f2e68dSdanielk1977 { "sqlite3_column_name16", test_stmt_utf16, sqlite3_column_name16 }, 30696c62608fSdrh #endif 30706b456a2bSdanielk1977 { "sqlite3_global_recover", test_global_recover, 0 }, 307104f2e68dSdanielk1977 30729a1d0abeSdanielk1977 /* Functions from os.h */ 307344ee5bf7Sdanielk1977 #ifndef SQLITE_OMIT_DISKIO 30749a1d0abeSdanielk1977 { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 }, 30759a1d0abeSdanielk1977 { "sqlite3OsClose", test_sqlite3OsClose, 0 }, 30769a1d0abeSdanielk1977 { "sqlite3OsLock", test_sqlite3OsLock, 0 }, 3077ab3f9feaSdrh { "sqlite3OsTempFileName", test_sqlite3OsTempFileName, 0 }, 3078312d6b36Sdanielk1977 3079312d6b36Sdanielk1977 /* Custom test interfaces */ 30809a1d0abeSdanielk1977 { "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 }, 308144ee5bf7Sdanielk1977 #endif 30825436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 30834e6af134Sdanielk1977 { "add_test_collate", test_collate, 0 }, 3084312d6b36Sdanielk1977 { "add_test_collate_needed", test_collate_needed, 0 }, 3085c8e9a2dfSdanielk1977 { "add_test_function", test_function, 0 }, 30865436dc2dSdrh #endif 3087c8e9a2dfSdanielk1977 { "sqlite3_crashparams", sqlite3_crashparams, 0 }, 3088312d6b36Sdanielk1977 { "sqlite3_test_errstr", test_errstr, 0 }, 308992febd92Sdrh { "tcl_variable_type", tcl_variable_type, 0 }, 309051e3d8e2Sdanielk1977 }; 30911398ad36Sdrh static int bitmask_size = sizeof(Bitmask)*8; 3092c2eef3b3Sdrh int i; 30932ac3ee97Sdrh extern int sqlite3_os_trace; 3094*51147baaSdrh extern int sqlite3_where_trace; 3095b851b2c9Sdrh extern int sqlite3_sync_count, sqlite3_fullsync_count; 3096af6df11fSdrh extern int sqlite3_opentemp_count; 309701397205Sdrh extern int sqlite3_memUsed; 309801397205Sdrh extern int sqlite3_memMax; 309984bfda41Sdrh extern char sqlite3_query_plan[]; 31009042f395Sdrh static char *query_plan = sqlite3_query_plan; 3101c2eef3b3Sdrh 3102c2eef3b3Sdrh for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ 3103c2eef3b3Sdrh Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); 3104c2eef3b3Sdrh } 310551e3d8e2Sdanielk1977 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ 3106c572ef7fSdanielk1977 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 3107c572ef7fSdanielk1977 aObjCmd[i].xProc, aObjCmd[i].clientData, 0); 310851e3d8e2Sdanielk1977 } 31096490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_search_count", 31106f8a503dSdanielk1977 (char*)&sqlite3_search_count, TCL_LINK_INT); 31116bf89570Sdrh Tcl_LinkVar(interp, "sqlite_sort_count", 31126bf89570Sdrh (char*)&sqlite3_sort_count, TCL_LINK_INT); 31136490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_interrupt_count", 31146f8a503dSdanielk1977 (char*)&sqlite3_interrupt_count, TCL_LINK_INT); 31156490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_open_file_count", 31166f8a503dSdanielk1977 (char*)&sqlite3_open_file_count, TCL_LINK_INT); 31176490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_current_time", 31186f8a503dSdanielk1977 (char*)&sqlite3_current_time, TCL_LINK_INT); 31192ac3ee97Sdrh Tcl_LinkVar(interp, "sqlite_os_trace", 31202ac3ee97Sdrh (char*)&sqlite3_os_trace, TCL_LINK_INT); 3121*51147baaSdrh Tcl_LinkVar(interp, "sqlite_where_trace", 3122*51147baaSdrh (char*)&sqlite3_where_trace, TCL_LINK_INT); 312301397205Sdrh Tcl_LinkVar(interp, "sqlite_memused", 312401397205Sdrh (char*)&sqlite3_memUsed, TCL_LINK_INT | TCL_LINK_READ_ONLY); 312501397205Sdrh Tcl_LinkVar(interp, "sqlite_memmax", 312601397205Sdrh (char*)&sqlite3_memMax, TCL_LINK_INT | TCL_LINK_READ_ONLY); 312784bfda41Sdrh Tcl_LinkVar(interp, "sqlite_query_plan", 31289042f395Sdrh (char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY); 3129cbe21be3Sdanielk1977 #ifndef SQLITE_OMIT_DISKIO 3130af6df11fSdrh Tcl_LinkVar(interp, "sqlite_opentemp_count", 3131af6df11fSdrh (char*)&sqlite3_opentemp_count, TCL_LINK_INT); 3132cbe21be3Sdanielk1977 #endif 31337c972decSdrh Tcl_LinkVar(interp, "sqlite_static_bind_value", 31347c972decSdrh (char*)&sqlite_static_bind_value, TCL_LINK_STRING); 3135ab3f9feaSdrh Tcl_LinkVar(interp, "sqlite_temp_directory", 3136effd02bcSdrh (char*)&sqlite3_temp_directory, TCL_LINK_STRING); 31371398ad36Sdrh Tcl_LinkVar(interp, "bitmask_size", 31381398ad36Sdrh (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); 3139748f763fSdrh #if OS_UNIX 3140b851b2c9Sdrh Tcl_LinkVar(interp, "sqlite_sync_count", 3141b851b2c9Sdrh (char*)&sqlite3_sync_count, TCL_LINK_INT); 3142b851b2c9Sdrh Tcl_LinkVar(interp, "sqlite_fullsync_count", 3143b851b2c9Sdrh (char*)&sqlite3_fullsync_count, TCL_LINK_INT); 3144748f763fSdrh #endif /* OS_UNIX */ 314527d258a3Sdrh set_options(interp); 3146d1bf3512Sdrh return TCL_OK; 3147d1bf3512Sdrh } 3148