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*53c0f748Sdanielk1977 ** $Id: test1.c,v 1.136 2005/03/29 03:11:00 danielk1977 Exp $ 17d1bf3512Sdrh */ 18d1bf3512Sdrh #include "sqliteInt.h" 19d1bf3512Sdrh #include "tcl.h" 2094e92032Sdrh #include "os.h" 21d1bf3512Sdrh #include <stdlib.h> 22d1bf3512Sdrh #include <string.h> 23d1bf3512Sdrh 246622cce3Sdanielk1977 static const char * errorName(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 } 606622cce3Sdanielk1977 61d1bf3512Sdrh /* 62c60d0446Sdrh ** Convert an sqlite3_stmt* into an sqlite3*. This depends on the 63c60d0446Sdrh ** fact that the sqlite3* is the first field in the Vdbe structure. 64c60d0446Sdrh */ 65c60d0446Sdrh #define StmtToDb(X) (*(sqlite3**)(X)) 66c60d0446Sdrh 67c60d0446Sdrh /* 68c60d0446Sdrh ** Check a return value to make sure it agrees with the results 69c60d0446Sdrh ** from sqlite3_errcode. 70c60d0446Sdrh */ 71c60d0446Sdrh int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){ 72c60d0446Sdrh if( rc!=SQLITE_MISUSE && rc!=SQLITE_OK && sqlite3_errcode(db)!=rc ){ 73c60d0446Sdrh char zBuf[200]; 74c60d0446Sdrh int r2 = sqlite3_errcode(db); 75c60d0446Sdrh sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)", 76c60d0446Sdrh errorName(rc), rc, errorName(r2), r2); 77c60d0446Sdrh Tcl_ResetResult(interp); 78c60d0446Sdrh Tcl_AppendResult(interp, zBuf, 0); 79c60d0446Sdrh return 1; 80c60d0446Sdrh } 81c60d0446Sdrh return 0; 82c60d0446Sdrh } 83c60d0446Sdrh 84c60d0446Sdrh /* 859bb575fdSdrh ** Decode a pointer to an sqlite3 object. 86b86ccfb2Sdrh */ 879bb575fdSdrh static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){ 88fe63d1c9Sdrh *ppDb = (sqlite3*)sqlite3TextToPtr(zA); 89b86ccfb2Sdrh return TCL_OK; 90b86ccfb2Sdrh } 91b86ccfb2Sdrh 92b86ccfb2Sdrh /* 9351e3d8e2Sdanielk1977 ** Decode a pointer to an sqlite3_stmt object. 9451e3d8e2Sdanielk1977 */ 9551e3d8e2Sdanielk1977 static int getStmtPointer( 9651e3d8e2Sdanielk1977 Tcl_Interp *interp, 9751e3d8e2Sdanielk1977 const char *zArg, 9851e3d8e2Sdanielk1977 sqlite3_stmt **ppStmt 9951e3d8e2Sdanielk1977 ){ 100fe63d1c9Sdrh *ppStmt = (sqlite3_stmt*)sqlite3TextToPtr(zArg); 10151e3d8e2Sdanielk1977 return TCL_OK; 10251e3d8e2Sdanielk1977 } 10351e3d8e2Sdanielk1977 10451e3d8e2Sdanielk1977 /* 1059a1d0abeSdanielk1977 ** Decode a pointer to an sqlite3_stmt object. 1069a1d0abeSdanielk1977 */ 1079a1d0abeSdanielk1977 static int getFilePointer( 1089a1d0abeSdanielk1977 Tcl_Interp *interp, 1099a1d0abeSdanielk1977 const char *zArg, 1109a1d0abeSdanielk1977 OsFile **ppFile 1119a1d0abeSdanielk1977 ){ 112fe63d1c9Sdrh *ppFile = (OsFile*)sqlite3TextToPtr(zArg); 1139a1d0abeSdanielk1977 return TCL_OK; 1149a1d0abeSdanielk1977 } 1159a1d0abeSdanielk1977 1169a1d0abeSdanielk1977 /* 1177d8085a8Sdrh ** Generate a text representation of a pointer that can be understood 1187d8085a8Sdrh ** by the getDbPointer and getVmPointer routines above. 1197d8085a8Sdrh ** 1207d8085a8Sdrh ** The problem is, on some machines (Solaris) if you do a printf with 1217d8085a8Sdrh ** "%p" you cannot turn around and do a scanf with the same "%p" and 1227d8085a8Sdrh ** get your pointer back. You have to prepend a "0x" before it will 1237d8085a8Sdrh ** work. Or at least that is what is reported to me (drh). But this 1247d8085a8Sdrh ** behavior varies from machine to machine. The solution used her is 1257d8085a8Sdrh ** to test the string right after it is generated to see if it can be 1267d8085a8Sdrh ** understood by scanf, and if not, try prepending an "0x" to see if 1277d8085a8Sdrh ** that helps. If nothing works, a fatal error is generated. 1287d8085a8Sdrh */ 1297d8085a8Sdrh static int makePointerStr(Tcl_Interp *interp, char *zPtr, void *p){ 130fe63d1c9Sdrh sqlite3_snprintf(100, zPtr, "%p", p); 1317d8085a8Sdrh return TCL_OK; 1327d8085a8Sdrh } 1337d8085a8Sdrh 1347d8085a8Sdrh /* 1356f8a503dSdanielk1977 ** The callback routine for sqlite3_exec_printf(). 136d1bf3512Sdrh */ 137d1bf3512Sdrh static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){ 138d1bf3512Sdrh Tcl_DString *str = (Tcl_DString*)pArg; 139d1bf3512Sdrh int i; 140d1bf3512Sdrh 141d1bf3512Sdrh if( Tcl_DStringLength(str)==0 ){ 142d1bf3512Sdrh for(i=0; i<argc; i++){ 143d1bf3512Sdrh Tcl_DStringAppendElement(str, name[i] ? name[i] : "NULL"); 144d1bf3512Sdrh } 145d1bf3512Sdrh } 146d1bf3512Sdrh for(i=0; i<argc; i++){ 147d1bf3512Sdrh Tcl_DStringAppendElement(str, argv[i] ? argv[i] : "NULL"); 148d1bf3512Sdrh } 149d1bf3512Sdrh return 0; 150d1bf3512Sdrh } 151d1bf3512Sdrh 152d1bf3512Sdrh /* 1536f8a503dSdanielk1977 ** Usage: sqlite3_exec_printf DB FORMAT STRING 154d1bf3512Sdrh ** 1556f8a503dSdanielk1977 ** Invoke the sqlite3_exec_printf() interface using the open database 156d1bf3512Sdrh ** DB. The SQL is the string FORMAT. The format string should contain 157d1bf3512Sdrh ** one %s or %q. STRING is the value inserted into %s or %q. 158d1bf3512Sdrh */ 159d1bf3512Sdrh static int test_exec_printf( 160d1bf3512Sdrh void *NotUsed, 161d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 162d1bf3512Sdrh int argc, /* Number of arguments */ 163d1bf3512Sdrh char **argv /* Text of each argument */ 164d1bf3512Sdrh ){ 1659bb575fdSdrh sqlite3 *db; 166d1bf3512Sdrh Tcl_DString str; 167d1bf3512Sdrh int rc; 168d1bf3512Sdrh char *zErr = 0; 1691211de37Sdrh char *zSql; 170d1bf3512Sdrh char zBuf[30]; 171d1bf3512Sdrh if( argc!=4 ){ 172d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 173d1bf3512Sdrh " DB FORMAT STRING", 0); 174d1bf3512Sdrh return TCL_ERROR; 175d1bf3512Sdrh } 176b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 177d1bf3512Sdrh Tcl_DStringInit(&str); 1781211de37Sdrh zSql = sqlite3_mprintf(argv[2], argv[3]); 1791211de37Sdrh rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr); 1801211de37Sdrh sqlite3_free(zSql); 181d1bf3512Sdrh sprintf(zBuf, "%d", rc); 182d1bf3512Sdrh Tcl_AppendElement(interp, zBuf); 183d1bf3512Sdrh Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr); 184d1bf3512Sdrh Tcl_DStringFree(&str); 185d1bf3512Sdrh if( zErr ) free(zErr); 186c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 187d1bf3512Sdrh return TCL_OK; 188d1bf3512Sdrh } 189d1bf3512Sdrh 190d1bf3512Sdrh /* 1916f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_z_test SEPARATOR ARG0 ARG1 ... 192d93d8a81Sdrh ** 193d93d8a81Sdrh ** Test the %z format of mprintf(). Use multiple mprintf() calls to 194d93d8a81Sdrh ** concatenate arg0 through argn using separator as the separator. 195d93d8a81Sdrh ** Return the result. 196d93d8a81Sdrh */ 197d93d8a81Sdrh static int test_mprintf_z( 198d93d8a81Sdrh void *NotUsed, 199d93d8a81Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 200d93d8a81Sdrh int argc, /* Number of arguments */ 201d93d8a81Sdrh char **argv /* Text of each argument */ 202d93d8a81Sdrh ){ 203d93d8a81Sdrh char *zResult = 0; 204d93d8a81Sdrh int i; 205d93d8a81Sdrh 206d93d8a81Sdrh for(i=2; i<argc; i++){ 2074adee20fSdanielk1977 zResult = sqlite3MPrintf("%z%s%s", zResult, argv[1], argv[i]); 208d93d8a81Sdrh } 209d93d8a81Sdrh Tcl_AppendResult(interp, zResult, 0); 2105f968436Sdrh sqliteFree(zResult); 211d93d8a81Sdrh return TCL_OK; 212d93d8a81Sdrh } 213d93d8a81Sdrh 214d93d8a81Sdrh /* 2156f8a503dSdanielk1977 ** Usage: sqlite3_get_table_printf DB FORMAT STRING 216d1bf3512Sdrh ** 2176f8a503dSdanielk1977 ** Invoke the sqlite3_get_table_printf() interface using the open database 218d1bf3512Sdrh ** DB. The SQL is the string FORMAT. The format string should contain 219d1bf3512Sdrh ** one %s or %q. STRING is the value inserted into %s or %q. 220d1bf3512Sdrh */ 221d1bf3512Sdrh static int test_get_table_printf( 222d1bf3512Sdrh void *NotUsed, 223d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 224d1bf3512Sdrh int argc, /* Number of arguments */ 225d1bf3512Sdrh char **argv /* Text of each argument */ 226d1bf3512Sdrh ){ 2279bb575fdSdrh sqlite3 *db; 228d1bf3512Sdrh Tcl_DString str; 229d1bf3512Sdrh int rc; 230d1bf3512Sdrh char *zErr = 0; 231d1bf3512Sdrh int nRow, nCol; 232d1bf3512Sdrh char **aResult; 233d1bf3512Sdrh int i; 234d1bf3512Sdrh char zBuf[30]; 2351211de37Sdrh char *zSql; 236d1bf3512Sdrh if( argc!=4 ){ 237d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 238d1bf3512Sdrh " DB FORMAT STRING", 0); 239d1bf3512Sdrh return TCL_ERROR; 240d1bf3512Sdrh } 241b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 242d1bf3512Sdrh Tcl_DStringInit(&str); 2431211de37Sdrh zSql = sqlite3_mprintf(argv[2],argv[3]); 2441211de37Sdrh rc = sqlite3_get_table(db, zSql, &aResult, &nRow, &nCol, &zErr); 2451211de37Sdrh sqlite3_free(zSql); 246d1bf3512Sdrh sprintf(zBuf, "%d", rc); 247d1bf3512Sdrh Tcl_AppendElement(interp, zBuf); 248d1bf3512Sdrh if( rc==SQLITE_OK ){ 249d1bf3512Sdrh sprintf(zBuf, "%d", nRow); 250d1bf3512Sdrh Tcl_AppendElement(interp, zBuf); 251d1bf3512Sdrh sprintf(zBuf, "%d", nCol); 252d1bf3512Sdrh Tcl_AppendElement(interp, zBuf); 253d1bf3512Sdrh for(i=0; i<(nRow+1)*nCol; i++){ 254d1bf3512Sdrh Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL"); 255d1bf3512Sdrh } 256d1bf3512Sdrh }else{ 257d1bf3512Sdrh Tcl_AppendElement(interp, zErr); 258d1bf3512Sdrh } 2596f8a503dSdanielk1977 sqlite3_free_table(aResult); 260d1bf3512Sdrh if( zErr ) free(zErr); 261c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 262d1bf3512Sdrh return TCL_OK; 263d1bf3512Sdrh } 264d1bf3512Sdrh 265af9ff33aSdrh 266af9ff33aSdrh /* 2676f8a503dSdanielk1977 ** Usage: sqlite3_last_insert_rowid DB 268af9ff33aSdrh ** 269af9ff33aSdrh ** Returns the integer ROWID of the most recent insert. 270af9ff33aSdrh */ 271af9ff33aSdrh static int test_last_rowid( 272af9ff33aSdrh void *NotUsed, 273af9ff33aSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 274af9ff33aSdrh int argc, /* Number of arguments */ 275af9ff33aSdrh char **argv /* Text of each argument */ 276af9ff33aSdrh ){ 2779bb575fdSdrh sqlite3 *db; 278af9ff33aSdrh char zBuf[30]; 279af9ff33aSdrh 280af9ff33aSdrh if( argc!=2 ){ 281af9ff33aSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0); 282af9ff33aSdrh return TCL_ERROR; 283af9ff33aSdrh } 284b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 285c572ef7fSdanielk1977 sprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db)); 286af9ff33aSdrh Tcl_AppendResult(interp, zBuf, 0); 287af9ff33aSdrh return SQLITE_OK; 288af9ff33aSdrh } 289af9ff33aSdrh 290d1bf3512Sdrh /* 29125d6543dSdrh ** Usage: sqlite3_key DB KEY 29225d6543dSdrh ** 29325d6543dSdrh ** Set the codec key. 29425d6543dSdrh */ 29525d6543dSdrh static int test_key( 29625d6543dSdrh void *NotUsed, 29725d6543dSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 29825d6543dSdrh int argc, /* Number of arguments */ 29925d6543dSdrh char **argv /* Text of each argument */ 30025d6543dSdrh ){ 3019bb575fdSdrh sqlite3 *db; 30225d6543dSdrh const char *zKey; 30325d6543dSdrh int nKey; 30425d6543dSdrh if( argc!=3 ){ 30525d6543dSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 30625d6543dSdrh " FILENAME\"", 0); 30725d6543dSdrh return TCL_ERROR; 30825d6543dSdrh } 30925d6543dSdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 31025d6543dSdrh zKey = argv[2]; 31125d6543dSdrh nKey = strlen(zKey); 31225d6543dSdrh #ifdef SQLITE_HAS_CODEC 31325d6543dSdrh sqlite3_key(db, zKey, nKey); 31425d6543dSdrh #endif 31525d6543dSdrh return TCL_OK; 31625d6543dSdrh } 31725d6543dSdrh 31825d6543dSdrh /* 31925d6543dSdrh ** Usage: sqlite3_rekey DB KEY 32025d6543dSdrh ** 32125d6543dSdrh ** Change the codec key. 32225d6543dSdrh */ 32325d6543dSdrh static int test_rekey( 32425d6543dSdrh void *NotUsed, 32525d6543dSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 32625d6543dSdrh int argc, /* Number of arguments */ 32725d6543dSdrh char **argv /* Text of each argument */ 32825d6543dSdrh ){ 3299bb575fdSdrh sqlite3 *db; 33025d6543dSdrh const char *zKey; 33125d6543dSdrh int nKey; 33225d6543dSdrh if( argc!=3 ){ 33325d6543dSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 33425d6543dSdrh " FILENAME\"", 0); 33525d6543dSdrh return TCL_ERROR; 33625d6543dSdrh } 33725d6543dSdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 33825d6543dSdrh zKey = argv[2]; 33925d6543dSdrh nKey = strlen(zKey); 34025d6543dSdrh #ifdef SQLITE_HAS_CODEC 34125d6543dSdrh sqlite3_rekey(db, zKey, nKey); 34225d6543dSdrh #endif 34325d6543dSdrh return TCL_OK; 34425d6543dSdrh } 34525d6543dSdrh 34625d6543dSdrh /* 3476f8a503dSdanielk1977 ** Usage: sqlite3_close DB 348d1bf3512Sdrh ** 3496f8a503dSdanielk1977 ** Closes the database opened by sqlite3_open. 350d1bf3512Sdrh */ 351d1bf3512Sdrh static int sqlite_test_close( 352d1bf3512Sdrh void *NotUsed, 353d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 354d1bf3512Sdrh int argc, /* Number of arguments */ 355d1bf3512Sdrh char **argv /* Text of each argument */ 356d1bf3512Sdrh ){ 3579bb575fdSdrh sqlite3 *db; 35896d81f99Sdanielk1977 int rc; 359d1bf3512Sdrh if( argc!=2 ){ 360d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 361d1bf3512Sdrh " FILENAME\"", 0); 362d1bf3512Sdrh return TCL_ERROR; 363d1bf3512Sdrh } 364b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 36596d81f99Sdanielk1977 rc = sqlite3_close(db); 366f9d64d2cSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 367d1bf3512Sdrh return TCL_OK; 368d1bf3512Sdrh } 369d1bf3512Sdrh 370d1bf3512Sdrh /* 371c22bd47dSdrh ** Implementation of the x_coalesce() function. 372c22bd47dSdrh ** Return the first argument non-NULL argument. 373c22bd47dSdrh */ 3740ae8b831Sdanielk1977 static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 375c22bd47dSdrh int i; 376c22bd47dSdrh for(i=0; i<argc; i++){ 3779c054830Sdrh if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){ 378d8123366Sdanielk1977 sqlite3_result_text(context, sqlite3_value_text(argv[i]), -1, 379d8123366Sdanielk1977 SQLITE_TRANSIENT); 380c22bd47dSdrh break; 381c22bd47dSdrh } 382c22bd47dSdrh } 383c22bd47dSdrh } 384c22bd47dSdrh 385c22bd47dSdrh /* 386d1d9fc33Sdrh ** A structure into which to accumulate text. 387d1d9fc33Sdrh */ 388d1d9fc33Sdrh struct dstr { 389d1d9fc33Sdrh int nAlloc; /* Space allocated */ 390d1d9fc33Sdrh int nUsed; /* Space used */ 391d1d9fc33Sdrh char *z; /* The space */ 392d1d9fc33Sdrh }; 393d1d9fc33Sdrh 394d1d9fc33Sdrh /* 395d1d9fc33Sdrh ** Append text to a dstr 396d1d9fc33Sdrh */ 397d1d9fc33Sdrh static void dstrAppend(struct dstr *p, const char *z, int divider){ 398d1d9fc33Sdrh int n = strlen(z); 399d1d9fc33Sdrh if( p->nUsed + n + 2 > p->nAlloc ){ 400d1d9fc33Sdrh char *zNew; 401d1d9fc33Sdrh p->nAlloc = p->nAlloc*2 + n + 200; 402d1d9fc33Sdrh zNew = sqliteRealloc(p->z, p->nAlloc); 403d1d9fc33Sdrh if( zNew==0 ){ 404d1d9fc33Sdrh sqliteFree(p->z); 405d1d9fc33Sdrh memset(p, 0, sizeof(*p)); 406d1d9fc33Sdrh return; 407d1d9fc33Sdrh } 408d1d9fc33Sdrh p->z = zNew; 409d1d9fc33Sdrh } 410d1d9fc33Sdrh if( divider && p->nUsed>0 ){ 411d1d9fc33Sdrh p->z[p->nUsed++] = divider; 412d1d9fc33Sdrh } 413d1d9fc33Sdrh memcpy(&p->z[p->nUsed], z, n+1); 414d1d9fc33Sdrh p->nUsed += n; 415d1d9fc33Sdrh } 416d1d9fc33Sdrh 417d1d9fc33Sdrh /* 4184adee20fSdanielk1977 ** Invoked for each callback from sqlite3ExecFunc 419d1d9fc33Sdrh */ 420d1d9fc33Sdrh static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){ 421d1d9fc33Sdrh struct dstr *p = (struct dstr*)pData; 422d1d9fc33Sdrh int i; 423d1d9fc33Sdrh for(i=0; i<argc; i++){ 424d1d9fc33Sdrh if( argv[i]==0 ){ 425d1d9fc33Sdrh dstrAppend(p, "NULL", ' '); 426d1d9fc33Sdrh }else{ 427d1d9fc33Sdrh dstrAppend(p, argv[i], ' '); 428d1d9fc33Sdrh } 429d1d9fc33Sdrh } 430d1d9fc33Sdrh return 0; 431d1d9fc33Sdrh } 432d1d9fc33Sdrh 433d1d9fc33Sdrh /* 434e35ee196Sdanielk1977 ** Implementation of the x_sqlite_exec() function. This function takes 435c22bd47dSdrh ** a single argument and attempts to execute that argument as SQL code. 4366cbe1f1bSdrh ** This is illegal and should set the SQLITE_MISUSE flag on the database. 437c22bd47dSdrh ** 4386f8a503dSdanielk1977 ** 2004-Jan-07: We have changed this to make it legal to call sqlite3_exec() 439d1d9fc33Sdrh ** from within a function call. 440d1d9fc33Sdrh ** 441c22bd47dSdrh ** This routine simulates the effect of having two threads attempt to 442c22bd47dSdrh ** use the same database at the same time. 443c22bd47dSdrh */ 44451ad0ecdSdanielk1977 static void sqlite3ExecFunc( 4450ae8b831Sdanielk1977 sqlite3_context *context, 44651ad0ecdSdanielk1977 int argc, 44751ad0ecdSdanielk1977 sqlite3_value **argv 44851ad0ecdSdanielk1977 ){ 449d1d9fc33Sdrh struct dstr x; 450d1d9fc33Sdrh memset(&x, 0, sizeof(x)); 4519bb575fdSdrh sqlite3_exec((sqlite3*)sqlite3_user_data(context), 4524f26d6c4Sdrh sqlite3_value_text(argv[0]), 453d1d9fc33Sdrh execFuncCallback, &x, 0); 454d8123366Sdanielk1977 sqlite3_result_text(context, x.z, x.nUsed, SQLITE_TRANSIENT); 455d1d9fc33Sdrh sqliteFree(x.z); 456c22bd47dSdrh } 457c22bd47dSdrh 458c22bd47dSdrh /* 459c22bd47dSdrh ** Usage: sqlite_test_create_function DB 460c22bd47dSdrh ** 4616f8a503dSdanielk1977 ** Call the sqlite3_create_function API on the given database in order 462c22bd47dSdrh ** to create a function named "x_coalesce". This function does the same thing 463c22bd47dSdrh ** as the "coalesce" function. This function also registers an SQL function 464e35ee196Sdanielk1977 ** named "x_sqlite_exec" that invokes sqlite3_exec(). Invoking sqlite3_exec() 465c22bd47dSdrh ** in this way is illegal recursion and should raise an SQLITE_MISUSE error. 466c22bd47dSdrh ** The effect is similar to trying to use the same database connection from 467c22bd47dSdrh ** two threads at the same time. 468c22bd47dSdrh ** 469c22bd47dSdrh ** The original motivation for this routine was to be able to call the 4706f8a503dSdanielk1977 ** sqlite3_create_function function while a query is in progress in order 471c22bd47dSdrh ** to test the SQLITE_MISUSE detection logic. 472c22bd47dSdrh */ 473c2eef3b3Sdrh static int test_create_function( 474c22bd47dSdrh void *NotUsed, 475c22bd47dSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 476c22bd47dSdrh int argc, /* Number of arguments */ 477c22bd47dSdrh char **argv /* Text of each argument */ 478c22bd47dSdrh ){ 479c60d0446Sdrh int rc; 4809bb575fdSdrh sqlite3 *db; 4819bb575fdSdrh extern void Md5_Register(sqlite3*); 482312d6b36Sdanielk1977 483c22bd47dSdrh if( argc!=2 ){ 484c22bd47dSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 4854397de57Sdanielk1977 " DB\"", 0); 486c22bd47dSdrh return TCL_ERROR; 487c22bd47dSdrh } 488b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 489c60d0446Sdrh rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0, 490d8123366Sdanielk1977 ifnullFunc, 0, 0); 491312d6b36Sdanielk1977 4925436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 493312d6b36Sdanielk1977 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 494312d6b36Sdanielk1977 ** because it is not tested anywhere else. */ 495c60d0446Sdrh if( rc==SQLITE_OK ){ 496576ec6b3Sdanielk1977 sqlite3_value *pVal; 497312d6b36Sdanielk1977 pVal = sqlite3ValueNew(); 498312d6b36Sdanielk1977 sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC); 499c60d0446Sdrh rc = sqlite3_create_function16(db, 500c60d0446Sdrh sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), 501312d6b36Sdanielk1977 1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0); 502312d6b36Sdanielk1977 sqlite3ValueFree(pVal); 503c60d0446Sdrh } 5045436dc2dSdrh #endif 5055436dc2dSdrh 506c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 5074397de57Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), 0); 508c22bd47dSdrh return TCL_OK; 509c22bd47dSdrh } 510c22bd47dSdrh 511c22bd47dSdrh /* 512c22bd47dSdrh ** Routines to implement the x_count() aggregate function. 513c22bd47dSdrh */ 514c22bd47dSdrh typedef struct CountCtx CountCtx; 515c22bd47dSdrh struct CountCtx { 516c22bd47dSdrh int n; 517c22bd47dSdrh }; 5180ae8b831Sdanielk1977 static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ 519c22bd47dSdrh CountCtx *p; 5204f26d6c4Sdrh p = sqlite3_aggregate_context(context, sizeof(*p)); 5219c054830Sdrh if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0]) ) && p ){ 522c22bd47dSdrh p->n++; 523c22bd47dSdrh } 524c22bd47dSdrh } 5250ae8b831Sdanielk1977 static void countFinalize(sqlite3_context *context){ 526c22bd47dSdrh CountCtx *p; 5274f26d6c4Sdrh p = sqlite3_aggregate_context(context, sizeof(*p)); 528c572ef7fSdanielk1977 sqlite3_result_int(context, p ? p->n : 0); 529c22bd47dSdrh } 530c22bd47dSdrh 531c22bd47dSdrh /* 532c22bd47dSdrh ** Usage: sqlite_test_create_aggregate DB 533c22bd47dSdrh ** 5346f8a503dSdanielk1977 ** Call the sqlite3_create_function API on the given database in order 535c22bd47dSdrh ** to create a function named "x_count". This function does the same thing 536c22bd47dSdrh ** as the "md5sum" function. 537c22bd47dSdrh ** 538c22bd47dSdrh ** The original motivation for this routine was to be able to call the 5396f8a503dSdanielk1977 ** sqlite3_create_aggregate function while a query is in progress in order 540c22bd47dSdrh ** to test the SQLITE_MISUSE detection logic. 541c22bd47dSdrh */ 542c2eef3b3Sdrh static int test_create_aggregate( 543c22bd47dSdrh void *NotUsed, 544c22bd47dSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 545c22bd47dSdrh int argc, /* Number of arguments */ 546c22bd47dSdrh char **argv /* Text of each argument */ 547c22bd47dSdrh ){ 5489bb575fdSdrh sqlite3 *db; 549c60d0446Sdrh int rc; 550c22bd47dSdrh if( argc!=2 ){ 551c22bd47dSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 552c22bd47dSdrh " FILENAME\"", 0); 553c22bd47dSdrh return TCL_ERROR; 554c22bd47dSdrh } 555b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 556c60d0446Sdrh rc = sqlite3_create_function(db, "x_count", 0, SQLITE_UTF8, 0, 0, 557d8123366Sdanielk1977 countStep,countFinalize); 558c60d0446Sdrh if( rc==SQLITE_OK ){ 559f9d64d2cSdanielk1977 sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0, 560d8123366Sdanielk1977 countStep,countFinalize); 561c60d0446Sdrh } 562c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 563c22bd47dSdrh return TCL_OK; 564c22bd47dSdrh } 565c22bd47dSdrh 566c22bd47dSdrh 567c22bd47dSdrh 568c22bd47dSdrh /* 5696f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER 570d1bf3512Sdrh ** 571d1bf3512Sdrh ** Call mprintf with three integer arguments 572d1bf3512Sdrh */ 5736f8a503dSdanielk1977 static int sqlite3_mprintf_int( 574d1bf3512Sdrh void *NotUsed, 575d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 576d1bf3512Sdrh int argc, /* Number of arguments */ 577d1bf3512Sdrh char **argv /* Text of each argument */ 578d1bf3512Sdrh ){ 579d1bf3512Sdrh int a[3], i; 580d1bf3512Sdrh char *z; 581d1bf3512Sdrh if( argc!=5 ){ 582d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 583d1bf3512Sdrh " FORMAT INT INT INT\"", 0); 584d1bf3512Sdrh return TCL_ERROR; 585d1bf3512Sdrh } 586d1bf3512Sdrh for(i=2; i<5; i++){ 587d1bf3512Sdrh if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 588d1bf3512Sdrh } 5896f8a503dSdanielk1977 z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]); 590d1bf3512Sdrh Tcl_AppendResult(interp, z, 0); 5913f4fedb2Sdrh sqlite3_free(z); 592d1bf3512Sdrh return TCL_OK; 593d1bf3512Sdrh } 594d1bf3512Sdrh 595d1bf3512Sdrh /* 5969d213ef0Sdrh ** If zNum represents an integer that will fit in 64-bits, then set 5979d213ef0Sdrh ** *pValue to that integer and return true. Otherwise return false. 5989d213ef0Sdrh */ 5999d213ef0Sdrh static int sqlite3GetInt64(const char *zNum, i64 *pValue){ 6009d213ef0Sdrh if( sqlite3FitsIn64Bits(zNum) ){ 6019d213ef0Sdrh sqlite3atoi64(zNum, pValue); 6029d213ef0Sdrh return 1; 6039d213ef0Sdrh } 6049d213ef0Sdrh return 0; 6059d213ef0Sdrh } 6069d213ef0Sdrh 6079d213ef0Sdrh /* 608e9707671Sdrh ** Usage: sqlite3_mprintf_int64 FORMAT INTEGER INTEGER INTEGER 609e9707671Sdrh ** 610e9707671Sdrh ** Call mprintf with three 64-bit integer arguments 611e9707671Sdrh */ 612e9707671Sdrh static int sqlite3_mprintf_int64( 613e9707671Sdrh void *NotUsed, 614e9707671Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 615e9707671Sdrh int argc, /* Number of arguments */ 616e9707671Sdrh char **argv /* Text of each argument */ 617e9707671Sdrh ){ 618e9707671Sdrh int i; 619e9707671Sdrh sqlite_int64 a[3]; 620e9707671Sdrh char *z; 621e9707671Sdrh if( argc!=5 ){ 622e9707671Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 623e9707671Sdrh " FORMAT INT INT INT\"", 0); 624e9707671Sdrh return TCL_ERROR; 625e9707671Sdrh } 626e9707671Sdrh for(i=2; i<5; i++){ 627e9707671Sdrh if( !sqlite3GetInt64(argv[i], &a[i-2]) ){ 628e9707671Sdrh Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0); 629e9707671Sdrh return TCL_ERROR; 630e9707671Sdrh } 631e9707671Sdrh } 632e9707671Sdrh z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]); 633e9707671Sdrh Tcl_AppendResult(interp, z, 0); 634e9707671Sdrh sqlite3_free(z); 635e9707671Sdrh return TCL_OK; 636e9707671Sdrh } 637e9707671Sdrh 638e9707671Sdrh /* 6396f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING 640d1bf3512Sdrh ** 641d1bf3512Sdrh ** Call mprintf with two integer arguments and one string argument 642d1bf3512Sdrh */ 6436f8a503dSdanielk1977 static int sqlite3_mprintf_str( 644d1bf3512Sdrh void *NotUsed, 645d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 646d1bf3512Sdrh int argc, /* Number of arguments */ 647d1bf3512Sdrh char **argv /* Text of each argument */ 648d1bf3512Sdrh ){ 649d1bf3512Sdrh int a[3], i; 650d1bf3512Sdrh char *z; 651f220b24fSchw if( argc<4 || argc>5 ){ 652d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 653f220b24fSchw " FORMAT INT INT ?STRING?\"", 0); 654d1bf3512Sdrh return TCL_ERROR; 655d1bf3512Sdrh } 656d1bf3512Sdrh for(i=2; i<4; i++){ 657d1bf3512Sdrh if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 658d1bf3512Sdrh } 6596f8a503dSdanielk1977 z = sqlite3_mprintf(argv[1], a[0], a[1], argc>4 ? argv[4] : NULL); 660d1bf3512Sdrh Tcl_AppendResult(interp, z, 0); 6613f4fedb2Sdrh sqlite3_free(z); 662d1bf3512Sdrh return TCL_OK; 663d1bf3512Sdrh } 664d1bf3512Sdrh 665d1bf3512Sdrh /* 6666f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_str FORMAT INTEGER INTEGER DOUBLE 667d1bf3512Sdrh ** 668d1bf3512Sdrh ** Call mprintf with two integer arguments and one double argument 669d1bf3512Sdrh */ 6706f8a503dSdanielk1977 static int sqlite3_mprintf_double( 671d1bf3512Sdrh void *NotUsed, 672d1bf3512Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 673d1bf3512Sdrh int argc, /* Number of arguments */ 674d1bf3512Sdrh char **argv /* Text of each argument */ 675d1bf3512Sdrh ){ 676d1bf3512Sdrh int a[3], i; 677d1bf3512Sdrh double r; 678d1bf3512Sdrh char *z; 679d1bf3512Sdrh if( argc!=5 ){ 680d1bf3512Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 681d1bf3512Sdrh " FORMAT INT INT STRING\"", 0); 682d1bf3512Sdrh return TCL_ERROR; 683d1bf3512Sdrh } 684d1bf3512Sdrh for(i=2; i<4; i++){ 685d1bf3512Sdrh if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 686d1bf3512Sdrh } 687d1bf3512Sdrh if( Tcl_GetDouble(interp, argv[4], &r) ) return TCL_ERROR; 6886f8a503dSdanielk1977 z = sqlite3_mprintf(argv[1], a[0], a[1], r); 689d1bf3512Sdrh Tcl_AppendResult(interp, z, 0); 6903f4fedb2Sdrh sqlite3_free(z); 691d1bf3512Sdrh return TCL_OK; 692d1bf3512Sdrh } 693d1bf3512Sdrh 694d1bf3512Sdrh /* 6956f8a503dSdanielk1977 ** Usage: sqlite3_mprintf_str FORMAT DOUBLE DOUBLE 696b621c237Sdrh ** 697b621c237Sdrh ** Call mprintf with a single double argument which is the product of the 698b621c237Sdrh ** two arguments given above. This is used to generate overflow and underflow 699b621c237Sdrh ** doubles to test that they are converted properly. 700b621c237Sdrh */ 7016f8a503dSdanielk1977 static int sqlite3_mprintf_scaled( 702b621c237Sdrh void *NotUsed, 703b621c237Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 704b621c237Sdrh int argc, /* Number of arguments */ 705b621c237Sdrh char **argv /* Text of each argument */ 706b621c237Sdrh ){ 707b621c237Sdrh int i; 708b621c237Sdrh double r[2]; 709b621c237Sdrh char *z; 710b621c237Sdrh if( argc!=4 ){ 711b621c237Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 712b621c237Sdrh " FORMAT DOUBLE DOUBLE\"", 0); 713b621c237Sdrh return TCL_ERROR; 714b621c237Sdrh } 715b621c237Sdrh for(i=2; i<4; i++){ 716b621c237Sdrh if( Tcl_GetDouble(interp, argv[i], &r[i-2]) ) return TCL_ERROR; 717b621c237Sdrh } 7186f8a503dSdanielk1977 z = sqlite3_mprintf(argv[1], r[0]*r[1]); 719b621c237Sdrh Tcl_AppendResult(interp, z, 0); 7203f4fedb2Sdrh sqlite3_free(z); 721b621c237Sdrh return TCL_OK; 722b621c237Sdrh } 723b621c237Sdrh 724b621c237Sdrh /* 725e29b1a05Sdrh ** Usage: sqlite3_mprintf_stronly FORMAT STRING 726e29b1a05Sdrh ** 727e29b1a05Sdrh ** Call mprintf with a single double argument which is the product of the 728e29b1a05Sdrh ** two arguments given above. This is used to generate overflow and underflow 729e29b1a05Sdrh ** doubles to test that they are converted properly. 730e29b1a05Sdrh */ 731e29b1a05Sdrh static int sqlite3_mprintf_stronly( 732e29b1a05Sdrh void *NotUsed, 733e29b1a05Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 734e29b1a05Sdrh int argc, /* Number of arguments */ 735e29b1a05Sdrh char **argv /* Text of each argument */ 736e29b1a05Sdrh ){ 737e29b1a05Sdrh char *z; 738e29b1a05Sdrh if( argc!=3 ){ 739e29b1a05Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 740e29b1a05Sdrh " FORMAT STRING\"", 0); 741e29b1a05Sdrh return TCL_ERROR; 742e29b1a05Sdrh } 743e29b1a05Sdrh z = sqlite3_mprintf(argv[1], argv[2]); 744e29b1a05Sdrh Tcl_AppendResult(interp, z, 0); 745e29b1a05Sdrh sqlite3_free(z); 746e29b1a05Sdrh return TCL_OK; 747e29b1a05Sdrh } 748e29b1a05Sdrh 749e29b1a05Sdrh /* 7504693423bSdrh ** Usage: sqlite_malloc_fail N ?REPEAT-INTERVAL? 751daffd0e5Sdrh ** 7524693423bSdrh ** Rig sqliteMalloc() to fail on the N-th call and every REPEAT-INTERVAL call 7534693423bSdrh ** after that. If REPEAT-INTERVAL is 0 or is omitted, then only a single 7544693423bSdrh ** malloc will fail. If REPEAT-INTERVAL is 1 then all mallocs after the 7554693423bSdrh ** first failure will continue to fail on every call. If REPEAT-INTERVAL is 7564693423bSdrh ** 2 then every other malloc will fail. And so forth. 7574693423bSdrh ** 7584693423bSdrh ** Turn off this mechanism and reset the sqlite3_malloc_failed variable is N==0. 759daffd0e5Sdrh */ 7602c336549Sdanielk1977 #ifdef SQLITE_MEMDEBUG 761daffd0e5Sdrh static int sqlite_malloc_fail( 762daffd0e5Sdrh void *NotUsed, 763daffd0e5Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 764daffd0e5Sdrh int argc, /* Number of arguments */ 765daffd0e5Sdrh char **argv /* Text of each argument */ 766daffd0e5Sdrh ){ 767daffd0e5Sdrh int n; 7684693423bSdrh int rep; 7694693423bSdrh if( argc!=2 && argc!=3 ){ 770daffd0e5Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"", 0); 771daffd0e5Sdrh return TCL_ERROR; 772daffd0e5Sdrh } 773daffd0e5Sdrh if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR; 7744693423bSdrh if( argc==3 ){ 7754693423bSdrh if( Tcl_GetInt(interp, argv[2], &rep) ) return TCL_ERROR; 7764693423bSdrh }else{ 7774693423bSdrh rep = 0; 7784693423bSdrh } 7796f8a503dSdanielk1977 sqlite3_iMallocFail = n; 7804693423bSdrh sqlite3_iMallocReset = rep; 7816f8a503dSdanielk1977 sqlite3_malloc_failed = 0; 782daffd0e5Sdrh return TCL_OK; 783daffd0e5Sdrh } 784daffd0e5Sdrh #endif 785daffd0e5Sdrh 786daffd0e5Sdrh /* 787daffd0e5Sdrh ** Usage: sqlite_malloc_stat 788daffd0e5Sdrh ** 789daffd0e5Sdrh ** Return the number of prior calls to sqliteMalloc() and sqliteFree(). 790daffd0e5Sdrh */ 7912c336549Sdanielk1977 #ifdef SQLITE_MEMDEBUG 792daffd0e5Sdrh static int sqlite_malloc_stat( 793daffd0e5Sdrh void *NotUsed, 794daffd0e5Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 795daffd0e5Sdrh int argc, /* Number of arguments */ 796daffd0e5Sdrh char **argv /* Text of each argument */ 797daffd0e5Sdrh ){ 798daffd0e5Sdrh char zBuf[200]; 7996f8a503dSdanielk1977 sprintf(zBuf, "%d %d %d", sqlite3_nMalloc, sqlite3_nFree, sqlite3_iMallocFail); 800daffd0e5Sdrh Tcl_AppendResult(interp, zBuf, 0); 801daffd0e5Sdrh return TCL_OK; 802daffd0e5Sdrh } 803daffd0e5Sdrh #endif 804daffd0e5Sdrh 805daffd0e5Sdrh /* 80628b4e489Sdrh ** Usage: sqlite_abort 80728b4e489Sdrh ** 80828b4e489Sdrh ** Shutdown the process immediately. This is not a clean shutdown. 80928b4e489Sdrh ** This command is used to test the recoverability of a database in 81028b4e489Sdrh ** the event of a program crash. 81128b4e489Sdrh */ 81228b4e489Sdrh static int sqlite_abort( 81328b4e489Sdrh void *NotUsed, 81428b4e489Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 81528b4e489Sdrh int argc, /* Number of arguments */ 81628b4e489Sdrh char **argv /* Text of each argument */ 81728b4e489Sdrh ){ 81828b4e489Sdrh assert( interp==0 ); /* This will always fail */ 81928b4e489Sdrh return TCL_OK; 82028b4e489Sdrh } 82128b4e489Sdrh 82228b4e489Sdrh /* 8236cbe1f1bSdrh ** The following routine is a user-defined SQL function whose purpose 8246cbe1f1bSdrh ** is to test the sqlite_set_result() API. 8256cbe1f1bSdrh */ 8260ae8b831Sdanielk1977 static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 8276cbe1f1bSdrh while( argc>=2 ){ 8284f26d6c4Sdrh const char *zArg0 = sqlite3_value_text(argv[0]); 8296d88bad4Sdanielk1977 if( zArg0 ){ 8306d88bad4Sdanielk1977 if( 0==sqlite3StrICmp(zArg0, "int") ){ 8316d88bad4Sdanielk1977 sqlite3_result_int(context, sqlite3_value_int(argv[1])); 8326d88bad4Sdanielk1977 }else if( sqlite3StrICmp(zArg0,"int64")==0 ){ 8336d88bad4Sdanielk1977 sqlite3_result_int64(context, sqlite3_value_int64(argv[1])); 83451ad0ecdSdanielk1977 }else if( sqlite3StrICmp(zArg0,"string")==0 ){ 835d8123366Sdanielk1977 sqlite3_result_text(context, sqlite3_value_text(argv[1]), -1, 836d8123366Sdanielk1977 SQLITE_TRANSIENT); 83751ad0ecdSdanielk1977 }else if( sqlite3StrICmp(zArg0,"double")==0 ){ 8386d88bad4Sdanielk1977 sqlite3_result_double(context, sqlite3_value_double(argv[1])); 8396d88bad4Sdanielk1977 }else if( sqlite3StrICmp(zArg0,"null")==0 ){ 8406d88bad4Sdanielk1977 sqlite3_result_null(context); 8416d88bad4Sdanielk1977 }else if( sqlite3StrICmp(zArg0,"value")==0 ){ 8426d88bad4Sdanielk1977 sqlite3_result_value(context, argv[sqlite3_value_int(argv[1])]); 8436cbe1f1bSdrh }else{ 8446d88bad4Sdanielk1977 goto error_out; 8456d88bad4Sdanielk1977 } 8466d88bad4Sdanielk1977 }else{ 8476d88bad4Sdanielk1977 goto error_out; 8486cbe1f1bSdrh } 8496cbe1f1bSdrh argc -= 2; 8506cbe1f1bSdrh argv += 2; 8516cbe1f1bSdrh } 8526d88bad4Sdanielk1977 return; 8536d88bad4Sdanielk1977 8546d88bad4Sdanielk1977 error_out: 8556d88bad4Sdanielk1977 sqlite3_result_error(context,"first argument should be one of: " 8566d88bad4Sdanielk1977 "int int64 string double null value", -1); 8576cbe1f1bSdrh } 8586cbe1f1bSdrh 8596cbe1f1bSdrh /* 8606cbe1f1bSdrh ** Usage: sqlite_register_test_function DB NAME 8616cbe1f1bSdrh ** 8626cbe1f1bSdrh ** Register the test SQL function on the database DB under the name NAME. 8636cbe1f1bSdrh */ 864c2eef3b3Sdrh static int test_register_func( 8656cbe1f1bSdrh void *NotUsed, 8666cbe1f1bSdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 8676cbe1f1bSdrh int argc, /* Number of arguments */ 8686cbe1f1bSdrh char **argv /* Text of each argument */ 8696cbe1f1bSdrh ){ 8709bb575fdSdrh sqlite3 *db; 8716cbe1f1bSdrh int rc; 8726cbe1f1bSdrh if( argc!=3 ){ 8736cbe1f1bSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 8746cbe1f1bSdrh " DB FUNCTION-NAME", 0); 8756cbe1f1bSdrh return TCL_ERROR; 8766cbe1f1bSdrh } 877b86ccfb2Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 878f9d64d2cSdanielk1977 rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 879d8123366Sdanielk1977 testFunc, 0, 0); 8806cbe1f1bSdrh if( rc!=0 ){ 881f20b21c8Sdanielk1977 Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0); 8826cbe1f1bSdrh return TCL_ERROR; 8836cbe1f1bSdrh } 884c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 8856cbe1f1bSdrh return TCL_OK; 8866cbe1f1bSdrh } 8876cbe1f1bSdrh 8886cbe1f1bSdrh /* 889106bb236Sdanielk1977 ** Usage: sqlite3_finalize STMT 890b86ccfb2Sdrh ** 891106bb236Sdanielk1977 ** Finalize a statement handle. 892b86ccfb2Sdrh */ 893b86ccfb2Sdrh static int test_finalize( 894106bb236Sdanielk1977 void * clientData, 895106bb236Sdanielk1977 Tcl_Interp *interp, 896106bb236Sdanielk1977 int objc, 897106bb236Sdanielk1977 Tcl_Obj *CONST objv[] 898b86ccfb2Sdrh ){ 899106bb236Sdanielk1977 sqlite3_stmt *pStmt; 900b86ccfb2Sdrh int rc; 901c60d0446Sdrh sqlite3 *db; 902106bb236Sdanielk1977 903106bb236Sdanielk1977 if( objc!=2 ){ 904106bb236Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 905106bb236Sdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 906b86ccfb2Sdrh return TCL_ERROR; 907b86ccfb2Sdrh } 908106bb236Sdanielk1977 909106bb236Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 910106bb236Sdanielk1977 9114397de57Sdanielk1977 if( pStmt ){ 912c60d0446Sdrh db = StmtToDb(pStmt); 9134397de57Sdanielk1977 } 914fc57d7bfSdanielk1977 rc = sqlite3_finalize(pStmt); 915b77f5dadSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 9164397de57Sdanielk1977 if( db && sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 917106bb236Sdanielk1977 return TCL_OK; 918106bb236Sdanielk1977 } 919106bb236Sdanielk1977 920106bb236Sdanielk1977 /* 921106bb236Sdanielk1977 ** Usage: sqlite3_reset STMT 922106bb236Sdanielk1977 ** 923106bb236Sdanielk1977 ** Finalize a statement handle. 924106bb236Sdanielk1977 */ 925106bb236Sdanielk1977 static int test_reset( 926106bb236Sdanielk1977 void * clientData, 927106bb236Sdanielk1977 Tcl_Interp *interp, 928106bb236Sdanielk1977 int objc, 929106bb236Sdanielk1977 Tcl_Obj *CONST objv[] 930106bb236Sdanielk1977 ){ 931106bb236Sdanielk1977 sqlite3_stmt *pStmt; 932106bb236Sdanielk1977 int rc; 933106bb236Sdanielk1977 934106bb236Sdanielk1977 if( objc!=2 ){ 935106bb236Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 936106bb236Sdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 937106bb236Sdanielk1977 return TCL_ERROR; 938106bb236Sdanielk1977 } 939106bb236Sdanielk1977 940106bb236Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 941106bb236Sdanielk1977 942fc57d7bfSdanielk1977 rc = sqlite3_reset(pStmt); 9434397de57Sdanielk1977 if( pStmt && 9444397de57Sdanielk1977 sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 9454397de57Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 946106bb236Sdanielk1977 if( rc ){ 947b86ccfb2Sdrh return TCL_ERROR; 948b86ccfb2Sdrh } 949b86ccfb2Sdrh return TCL_OK; 950b86ccfb2Sdrh } 951b86ccfb2Sdrh 9525a38705eSdrh /* 953d89bd007Sdrh ** Usage: sqlite3_expired STMT 954d89bd007Sdrh ** 955d89bd007Sdrh ** Return TRUE if a recompilation of the statement is recommended. 956d89bd007Sdrh */ 957d89bd007Sdrh static int test_expired( 958d89bd007Sdrh void * clientData, 959d89bd007Sdrh Tcl_Interp *interp, 960d89bd007Sdrh int objc, 961d89bd007Sdrh Tcl_Obj *CONST objv[] 962d89bd007Sdrh ){ 963d89bd007Sdrh sqlite3_stmt *pStmt; 964d89bd007Sdrh if( objc!=2 ){ 965d89bd007Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", 966d89bd007Sdrh Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 967d89bd007Sdrh return TCL_ERROR; 968d89bd007Sdrh } 969d89bd007Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 970d89bd007Sdrh Tcl_SetObjResult(interp, Tcl_NewBooleanObj(sqlite3_expired(pStmt))); 971d89bd007Sdrh return TCL_OK; 972d89bd007Sdrh } 973d89bd007Sdrh 974d89bd007Sdrh /* 975fbcd585fSdanielk1977 ** Usage: sqlite3_changes DB 97650457896Sdrh ** 977fbcd585fSdanielk1977 ** Return the number of changes made to the database by the last SQL 978fbcd585fSdanielk1977 ** execution. 97950457896Sdrh */ 980fbcd585fSdanielk1977 static int test_changes( 981fbcd585fSdanielk1977 void * clientData, 982fbcd585fSdanielk1977 Tcl_Interp *interp, 983fbcd585fSdanielk1977 int objc, 984fbcd585fSdanielk1977 Tcl_Obj *CONST objv[] 985fbcd585fSdanielk1977 ){ 986fbcd585fSdanielk1977 sqlite3 *db; 987fbcd585fSdanielk1977 if( objc!=2 ){ 988fbcd585fSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 989fbcd585fSdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 990fbcd585fSdanielk1977 return TCL_ERROR; 991fbcd585fSdanielk1977 } 992fbcd585fSdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 993fbcd585fSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_changes(db))); 994fbcd585fSdanielk1977 return TCL_OK; 995fbcd585fSdanielk1977 } 99650457896Sdrh 99750457896Sdrh /* 9987c972decSdrh ** This is the "static_bind_value" that variables are bound to when 9996f8a503dSdanielk1977 ** the FLAG option of sqlite3_bind is "static" 100050457896Sdrh */ 10017c972decSdrh static char *sqlite_static_bind_value = 0; 10027c972decSdrh 10037c972decSdrh /* 10046f8a503dSdanielk1977 ** Usage: sqlite3_bind VM IDX VALUE FLAGS 10057c972decSdrh ** 10067c972decSdrh ** Sets the value of the IDX-th occurance of "?" in the original SQL 10077c972decSdrh ** string. VALUE is the new value. If FLAGS=="null" then VALUE is 10087c972decSdrh ** ignored and the value is set to NULL. If FLAGS=="static" then 10097c972decSdrh ** the value is set to the value of a static variable named 10107c972decSdrh ** "sqlite_static_bind_value". If FLAGS=="normal" then a copy 10117c972decSdrh ** of the VALUE is made. 10127c972decSdrh */ 10137c972decSdrh static int test_bind( 101450457896Sdrh void *NotUsed, 101550457896Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 101650457896Sdrh int argc, /* Number of arguments */ 101750457896Sdrh char **argv /* Text of each argument */ 101850457896Sdrh ){ 1019fc57d7bfSdanielk1977 sqlite3_stmt *pStmt; 102050457896Sdrh int rc; 10217c972decSdrh int idx; 10227c972decSdrh if( argc!=5 ){ 102350457896Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 10247c972decSdrh " VM IDX VALUE (null|static|normal)\"", 0); 102550457896Sdrh return TCL_ERROR; 102650457896Sdrh } 1027fc57d7bfSdanielk1977 if( getStmtPointer(interp, argv[1], &pStmt) ) return TCL_ERROR; 10287c972decSdrh if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR; 10297c972decSdrh if( strcmp(argv[4],"null")==0 ){ 1030fc57d7bfSdanielk1977 rc = sqlite3_bind_null(pStmt, idx); 10317c972decSdrh }else if( strcmp(argv[4],"static")==0 ){ 1032fc57d7bfSdanielk1977 rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0); 10337c972decSdrh }else if( strcmp(argv[4],"normal")==0 ){ 1034d8123366Sdanielk1977 rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, SQLITE_TRANSIENT); 10357c972decSdrh }else{ 10367c972decSdrh Tcl_AppendResult(interp, "4th argument should be " 10377c972decSdrh "\"null\" or \"static\" or \"normal\"", 0); 10387c972decSdrh return TCL_ERROR; 10397c972decSdrh } 1040c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 104150457896Sdrh if( rc ){ 104250457896Sdrh char zBuf[50]; 104350457896Sdrh sprintf(zBuf, "(%d) ", rc); 1044f20b21c8Sdanielk1977 Tcl_AppendResult(interp, zBuf, sqlite3ErrStr(rc), 0); 104550457896Sdrh return TCL_ERROR; 104650457896Sdrh } 104750457896Sdrh return TCL_OK; 104850457896Sdrh } 104950457896Sdrh 10505436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 10514e6af134Sdanielk1977 /* 10524e6af134Sdanielk1977 ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be> 10534e6af134Sdanielk1977 ** 10544e6af134Sdanielk1977 ** This function is used to test that SQLite selects the correct collation 10554e6af134Sdanielk1977 ** sequence callback when multiple versions (for different text encodings) 10564e6af134Sdanielk1977 ** are available. 10574e6af134Sdanielk1977 ** 10584e6af134Sdanielk1977 ** Calling this routine registers the collation sequence "test_collate" 10594e6af134Sdanielk1977 ** with database handle <db>. The second argument must be a list of three 10604e6af134Sdanielk1977 ** boolean values. If the first is true, then a version of test_collate is 10614e6af134Sdanielk1977 ** registered for UTF-8, if the second is true, a version is registered for 10624e6af134Sdanielk1977 ** UTF-16le, if the third is true, a UTF-16be version is available. 10634e6af134Sdanielk1977 ** Previous versions of test_collate are deleted. 10644e6af134Sdanielk1977 ** 10654e6af134Sdanielk1977 ** The collation sequence test_collate is implemented by calling the 10664e6af134Sdanielk1977 ** following TCL script: 10674e6af134Sdanielk1977 ** 10684e6af134Sdanielk1977 ** "test_collate <enc> <lhs> <rhs>" 10694e6af134Sdanielk1977 ** 10704e6af134Sdanielk1977 ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8. 10714e6af134Sdanielk1977 ** The <enc> parameter is the encoding of the collation function that 10724e6af134Sdanielk1977 ** SQLite selected to call. The TCL test script implements the 10734e6af134Sdanielk1977 ** "test_collate" proc. 10744e6af134Sdanielk1977 ** 10754e6af134Sdanielk1977 ** Note that this will only work with one intepreter at a time, as the 10764e6af134Sdanielk1977 ** interp pointer to use when evaluating the TCL script is stored in 10774e6af134Sdanielk1977 ** pTestCollateInterp. 10784e6af134Sdanielk1977 */ 10794e6af134Sdanielk1977 static Tcl_Interp* pTestCollateInterp; 10804e6af134Sdanielk1977 static int test_collate_func( 10814e6af134Sdanielk1977 void *pCtx, 10824e6af134Sdanielk1977 int nA, const void *zA, 10834e6af134Sdanielk1977 int nB, const void *zB 10844e6af134Sdanielk1977 ){ 10854e6af134Sdanielk1977 Tcl_Interp *i = pTestCollateInterp; 10864e6af134Sdanielk1977 int encin = (int)pCtx; 10874e6af134Sdanielk1977 int res; 10884e6af134Sdanielk1977 10894e6af134Sdanielk1977 sqlite3_value *pVal; 10904e6af134Sdanielk1977 Tcl_Obj *pX; 10914e6af134Sdanielk1977 10924e6af134Sdanielk1977 pX = Tcl_NewStringObj("test_collate", -1); 10934e6af134Sdanielk1977 Tcl_IncrRefCount(pX); 10944e6af134Sdanielk1977 10954e6af134Sdanielk1977 switch( encin ){ 10964e6af134Sdanielk1977 case SQLITE_UTF8: 10974e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-8",-1)); 10984e6af134Sdanielk1977 break; 10994e6af134Sdanielk1977 case SQLITE_UTF16LE: 11004e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16LE",-1)); 11014e6af134Sdanielk1977 break; 11024e6af134Sdanielk1977 case SQLITE_UTF16BE: 11034e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16BE",-1)); 11044e6af134Sdanielk1977 break; 11054e6af134Sdanielk1977 default: 11064e6af134Sdanielk1977 assert(0); 11074e6af134Sdanielk1977 } 11084e6af134Sdanielk1977 11094e6af134Sdanielk1977 pVal = sqlite3ValueNew(); 1110bfd6cce5Sdanielk1977 sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC); 11114e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj(sqlite3_value_text(pVal),-1)); 1112bfd6cce5Sdanielk1977 sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC); 11134e6af134Sdanielk1977 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj(sqlite3_value_text(pVal),-1)); 11144e6af134Sdanielk1977 sqlite3ValueFree(pVal); 11154e6af134Sdanielk1977 11164e6af134Sdanielk1977 Tcl_EvalObjEx(i, pX, 0); 11174e6af134Sdanielk1977 Tcl_DecrRefCount(pX); 11184e6af134Sdanielk1977 Tcl_GetIntFromObj(i, Tcl_GetObjResult(i), &res); 11194e6af134Sdanielk1977 return res; 11204e6af134Sdanielk1977 } 11214e6af134Sdanielk1977 static int test_collate( 11224e6af134Sdanielk1977 void * clientData, 11234e6af134Sdanielk1977 Tcl_Interp *interp, 11244e6af134Sdanielk1977 int objc, 11254e6af134Sdanielk1977 Tcl_Obj *CONST objv[] 11264e6af134Sdanielk1977 ){ 11274e6af134Sdanielk1977 sqlite3 *db; 11284e6af134Sdanielk1977 int val; 1129312d6b36Sdanielk1977 sqlite3_value *pVal; 1130c60d0446Sdrh int rc; 11314e6af134Sdanielk1977 11324e6af134Sdanielk1977 if( objc!=5 ) goto bad_args; 11334e6af134Sdanielk1977 pTestCollateInterp = interp; 11344e6af134Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 11354e6af134Sdanielk1977 11364e6af134Sdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; 1137c60d0446Sdrh rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8, 11384e6af134Sdanielk1977 (void *)SQLITE_UTF8, val?test_collate_func:0); 1139c60d0446Sdrh if( rc==SQLITE_OK ){ 11404e6af134Sdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; 1141c60d0446Sdrh rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE, 11424e6af134Sdanielk1977 (void *)SQLITE_UTF16LE, val?test_collate_func:0); 11434e6af134Sdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR; 1144312d6b36Sdanielk1977 1145312d6b36Sdanielk1977 pVal = sqlite3ValueNew(); 1146312d6b36Sdanielk1977 sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC); 1147312d6b36Sdanielk1977 sqlite3_create_collation16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), 1148312d6b36Sdanielk1977 SQLITE_UTF16BE, (void *)SQLITE_UTF16BE, val?test_collate_func:0); 1149312d6b36Sdanielk1977 sqlite3ValueFree(pVal); 1150c60d0446Sdrh } 1151c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 11524e6af134Sdanielk1977 return TCL_OK; 11534e6af134Sdanielk1977 11544e6af134Sdanielk1977 bad_args: 11554e6af134Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 11564e6af134Sdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); 11574e6af134Sdanielk1977 return TCL_ERROR; 11584e6af134Sdanielk1977 } 11594e6af134Sdanielk1977 1160312d6b36Sdanielk1977 static void test_collate_needed_cb( 1161312d6b36Sdanielk1977 void *pCtx, 1162312d6b36Sdanielk1977 sqlite3 *db, 1163312d6b36Sdanielk1977 int eTextRep, 1164312d6b36Sdanielk1977 const void *notUsed 1165312d6b36Sdanielk1977 ){ 1166312d6b36Sdanielk1977 int enc = db->enc; 1167312d6b36Sdanielk1977 sqlite3_create_collation( 1168312d6b36Sdanielk1977 db, "test_collate", db->enc, (void *)enc, test_collate_func); 1169312d6b36Sdanielk1977 } 1170312d6b36Sdanielk1977 1171312d6b36Sdanielk1977 /* 1172312d6b36Sdanielk1977 ** Usage: add_test_collate_needed DB 1173312d6b36Sdanielk1977 */ 1174312d6b36Sdanielk1977 static int test_collate_needed( 1175312d6b36Sdanielk1977 void * clientData, 1176312d6b36Sdanielk1977 Tcl_Interp *interp, 1177312d6b36Sdanielk1977 int objc, 1178312d6b36Sdanielk1977 Tcl_Obj *CONST objv[] 1179312d6b36Sdanielk1977 ){ 1180312d6b36Sdanielk1977 sqlite3 *db; 1181c60d0446Sdrh int rc; 1182312d6b36Sdanielk1977 1183312d6b36Sdanielk1977 if( objc!=2 ) goto bad_args; 1184312d6b36Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1185c60d0446Sdrh rc = sqlite3_collation_needed16(db, 0, test_collate_needed_cb); 1186c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1187312d6b36Sdanielk1977 return TCL_OK; 1188312d6b36Sdanielk1977 1189312d6b36Sdanielk1977 bad_args: 1190312d6b36Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "DB"); 1191312d6b36Sdanielk1977 return TCL_ERROR; 1192312d6b36Sdanielk1977 } 11935436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 1194312d6b36Sdanielk1977 1195c8e9a2dfSdanielk1977 /* 1196c8e9a2dfSdanielk1977 ** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be> 1197c8e9a2dfSdanielk1977 ** 1198c8e9a2dfSdanielk1977 ** This function is used to test that SQLite selects the correct user 1199c8e9a2dfSdanielk1977 ** function callback when multiple versions (for different text encodings) 1200c8e9a2dfSdanielk1977 ** are available. 1201c8e9a2dfSdanielk1977 ** 1202c8e9a2dfSdanielk1977 ** Calling this routine registers up to three versions of the user function 1203c8e9a2dfSdanielk1977 ** "test_function" with database handle <db>. If the second argument is 1204c8e9a2dfSdanielk1977 ** true, then a version of test_function is registered for UTF-8, if the 1205c8e9a2dfSdanielk1977 ** third is true, a version is registered for UTF-16le, if the fourth is 1206c8e9a2dfSdanielk1977 ** true, a UTF-16be version is available. Previous versions of 1207c8e9a2dfSdanielk1977 ** test_function are deleted. 1208c8e9a2dfSdanielk1977 ** 1209c8e9a2dfSdanielk1977 ** The user function is implemented by calling the following TCL script: 1210c8e9a2dfSdanielk1977 ** 1211c8e9a2dfSdanielk1977 ** "test_function <enc> <arg>" 1212c8e9a2dfSdanielk1977 ** 1213c8e9a2dfSdanielk1977 ** Where <enc> is one of UTF-8, UTF-16LE or UTF16BE, and <arg> is the 1214c8e9a2dfSdanielk1977 ** single argument passed to the SQL function. The value returned by 1215c8e9a2dfSdanielk1977 ** the TCL script is used as the return value of the SQL function. It 1216c8e9a2dfSdanielk1977 ** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8 1217c8e9a2dfSdanielk1977 ** for a UTF-16LE test_function(), and UTF-16LE for an implementation that 1218c8e9a2dfSdanielk1977 ** prefers UTF-16BE. 1219c8e9a2dfSdanielk1977 */ 12205436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 1221c8e9a2dfSdanielk1977 static void test_function_utf8( 1222c8e9a2dfSdanielk1977 sqlite3_context *pCtx, 1223c8e9a2dfSdanielk1977 int nArg, 1224c8e9a2dfSdanielk1977 sqlite3_value **argv 1225c8e9a2dfSdanielk1977 ){ 1226c8e9a2dfSdanielk1977 Tcl_Interp *interp; 1227c8e9a2dfSdanielk1977 Tcl_Obj *pX; 1228c8e9a2dfSdanielk1977 sqlite3_value *pVal; 1229c8e9a2dfSdanielk1977 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1230c8e9a2dfSdanielk1977 pX = Tcl_NewStringObj("test_function", -1); 1231c8e9a2dfSdanielk1977 Tcl_IncrRefCount(pX); 1232c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-8", -1)); 1233c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, 1234c8e9a2dfSdanielk1977 Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); 1235c8e9a2dfSdanielk1977 Tcl_EvalObjEx(interp, pX, 0); 1236c8e9a2dfSdanielk1977 Tcl_DecrRefCount(pX); 1237c8e9a2dfSdanielk1977 sqlite3_result_text(pCtx, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT); 1238c8e9a2dfSdanielk1977 pVal = sqlite3ValueNew(); 1239c8e9a2dfSdanielk1977 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1240c8e9a2dfSdanielk1977 SQLITE_UTF8, SQLITE_STATIC); 1241c8e9a2dfSdanielk1977 sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal), 1242c8e9a2dfSdanielk1977 -1, SQLITE_TRANSIENT); 1243c8e9a2dfSdanielk1977 sqlite3ValueFree(pVal); 1244c8e9a2dfSdanielk1977 } 1245c8e9a2dfSdanielk1977 static void test_function_utf16le( 1246c8e9a2dfSdanielk1977 sqlite3_context *pCtx, 1247c8e9a2dfSdanielk1977 int nArg, 1248c8e9a2dfSdanielk1977 sqlite3_value **argv 1249c8e9a2dfSdanielk1977 ){ 1250c8e9a2dfSdanielk1977 Tcl_Interp *interp; 1251c8e9a2dfSdanielk1977 Tcl_Obj *pX; 1252c8e9a2dfSdanielk1977 sqlite3_value *pVal; 1253c8e9a2dfSdanielk1977 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1254c8e9a2dfSdanielk1977 pX = Tcl_NewStringObj("test_function", -1); 1255c8e9a2dfSdanielk1977 Tcl_IncrRefCount(pX); 1256c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16LE", -1)); 1257c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, 1258c8e9a2dfSdanielk1977 Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); 1259c8e9a2dfSdanielk1977 Tcl_EvalObjEx(interp, pX, 0); 1260c8e9a2dfSdanielk1977 Tcl_DecrRefCount(pX); 1261c8e9a2dfSdanielk1977 pVal = sqlite3ValueNew(); 1262c8e9a2dfSdanielk1977 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1263c8e9a2dfSdanielk1977 SQLITE_UTF8, SQLITE_STATIC); 1264c8e9a2dfSdanielk1977 sqlite3_result_text(pCtx,sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT); 1265c8e9a2dfSdanielk1977 sqlite3ValueFree(pVal); 1266c8e9a2dfSdanielk1977 } 1267c8e9a2dfSdanielk1977 static void test_function_utf16be( 1268c8e9a2dfSdanielk1977 sqlite3_context *pCtx, 1269c8e9a2dfSdanielk1977 int nArg, 1270c8e9a2dfSdanielk1977 sqlite3_value **argv 1271c8e9a2dfSdanielk1977 ){ 1272c8e9a2dfSdanielk1977 Tcl_Interp *interp; 1273c8e9a2dfSdanielk1977 Tcl_Obj *pX; 1274c8e9a2dfSdanielk1977 sqlite3_value *pVal; 1275c8e9a2dfSdanielk1977 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1276c8e9a2dfSdanielk1977 pX = Tcl_NewStringObj("test_function", -1); 1277c8e9a2dfSdanielk1977 Tcl_IncrRefCount(pX); 1278c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16BE", -1)); 1279c8e9a2dfSdanielk1977 Tcl_ListObjAppendElement(interp, pX, 1280c8e9a2dfSdanielk1977 Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); 1281c8e9a2dfSdanielk1977 Tcl_EvalObjEx(interp, pX, 0); 1282c8e9a2dfSdanielk1977 Tcl_DecrRefCount(pX); 1283c8e9a2dfSdanielk1977 pVal = sqlite3ValueNew(); 1284c8e9a2dfSdanielk1977 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1285c8e9a2dfSdanielk1977 SQLITE_UTF8, SQLITE_STATIC); 1286c8e9a2dfSdanielk1977 sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal), 1287c8e9a2dfSdanielk1977 -1, SQLITE_TRANSIENT); 1288c8e9a2dfSdanielk1977 sqlite3ValueFree(pVal); 1289c8e9a2dfSdanielk1977 } 12905436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 1291c8e9a2dfSdanielk1977 static int test_function( 1292c8e9a2dfSdanielk1977 void * clientData, 1293c8e9a2dfSdanielk1977 Tcl_Interp *interp, 1294c8e9a2dfSdanielk1977 int objc, 1295c8e9a2dfSdanielk1977 Tcl_Obj *CONST objv[] 1296c8e9a2dfSdanielk1977 ){ 12975436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 1298c8e9a2dfSdanielk1977 sqlite3 *db; 1299c8e9a2dfSdanielk1977 int val; 1300c8e9a2dfSdanielk1977 1301c8e9a2dfSdanielk1977 if( objc!=5 ) goto bad_args; 1302c8e9a2dfSdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1303c8e9a2dfSdanielk1977 1304c8e9a2dfSdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; 1305c8e9a2dfSdanielk1977 if( val ){ 1306c8e9a2dfSdanielk1977 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF8, 1307c8e9a2dfSdanielk1977 interp, test_function_utf8, 0, 0); 1308c8e9a2dfSdanielk1977 } 1309c8e9a2dfSdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; 1310c8e9a2dfSdanielk1977 if( val ){ 1311c8e9a2dfSdanielk1977 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16LE, 1312c8e9a2dfSdanielk1977 interp, test_function_utf16le, 0, 0); 1313c8e9a2dfSdanielk1977 } 1314c8e9a2dfSdanielk1977 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR; 1315c8e9a2dfSdanielk1977 if( val ){ 1316c8e9a2dfSdanielk1977 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16BE, 1317c8e9a2dfSdanielk1977 interp, test_function_utf16be, 0, 0); 1318c8e9a2dfSdanielk1977 } 1319c8e9a2dfSdanielk1977 1320c8e9a2dfSdanielk1977 return TCL_OK; 1321c8e9a2dfSdanielk1977 bad_args: 1322c8e9a2dfSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1323c8e9a2dfSdanielk1977 Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); 13245436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 1325c8e9a2dfSdanielk1977 return TCL_ERROR; 1326c8e9a2dfSdanielk1977 } 1327c8e9a2dfSdanielk1977 1328312d6b36Sdanielk1977 /* 1329312d6b36Sdanielk1977 ** Usage: test_errstr <err code> 1330312d6b36Sdanielk1977 ** 1331312d6b36Sdanielk1977 ** Test that the english language string equivalents for sqlite error codes 1332312d6b36Sdanielk1977 ** are sane. The parameter is an integer representing an sqlite error code. 1333312d6b36Sdanielk1977 ** The result is a list of two elements, the string representation of the 1334312d6b36Sdanielk1977 ** error code and the english language explanation. 1335312d6b36Sdanielk1977 */ 1336312d6b36Sdanielk1977 static int test_errstr( 1337312d6b36Sdanielk1977 void * clientData, 1338312d6b36Sdanielk1977 Tcl_Interp *interp, 1339312d6b36Sdanielk1977 int objc, 1340312d6b36Sdanielk1977 Tcl_Obj *CONST objv[] 1341312d6b36Sdanielk1977 ){ 1342312d6b36Sdanielk1977 char *zCode; 1343312d6b36Sdanielk1977 int i; 1344312d6b36Sdanielk1977 if( objc!=1 ){ 1345312d6b36Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "<error code>"); 1346312d6b36Sdanielk1977 } 1347312d6b36Sdanielk1977 1348312d6b36Sdanielk1977 zCode = Tcl_GetString(objv[1]); 1349312d6b36Sdanielk1977 for(i=0; i<200; i++){ 1350312d6b36Sdanielk1977 if( 0==strcmp(errorName(i), zCode) ) break; 1351312d6b36Sdanielk1977 } 1352312d6b36Sdanielk1977 Tcl_SetResult(interp, (char *)sqlite3ErrStr(i), 0); 1353312d6b36Sdanielk1977 return TCL_OK; 1354312d6b36Sdanielk1977 } 1355312d6b36Sdanielk1977 1356c8e9a2dfSdanielk1977 static int sqlite3_crashparams( 13578a6c550dSdanielk1977 void * clientData, 13588a6c550dSdanielk1977 Tcl_Interp *interp, 13598a6c550dSdanielk1977 int objc, 13608a6c550dSdanielk1977 Tcl_Obj *CONST objv[] 13618a6c550dSdanielk1977 ){ 13628a6c550dSdanielk1977 #ifdef OS_TEST 1363c8e9a2dfSdanielk1977 int delay; 1364c8e9a2dfSdanielk1977 if( objc!=3 ) goto bad_args; 1365c8e9a2dfSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[1], &delay) ) return TCL_ERROR; 1366c8e9a2dfSdanielk1977 sqlite3SetCrashParams(delay, Tcl_GetString(objv[2])); 13678a6c550dSdanielk1977 #endif 13688a6c550dSdanielk1977 return TCL_OK; 13698a6c550dSdanielk1977 1370241db313Sdrh #ifdef OS_TEST 13718a6c550dSdanielk1977 bad_args: 13728a6c550dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1373c8e9a2dfSdanielk1977 Tcl_GetStringFromObj(objv[0], 0), "<delay> <filename>", 0); 13748a6c550dSdanielk1977 return TCL_ERROR; 1375241db313Sdrh #endif 13768a6c550dSdanielk1977 } 13778a6c550dSdanielk1977 13788a6c550dSdanielk1977 137950457896Sdrh /* 138099ee3600Sdrh ** Usage: breakpoint 138199ee3600Sdrh ** 138299ee3600Sdrh ** This routine exists for one purpose - to provide a place to put a 138399ee3600Sdrh ** breakpoint with GDB that can be triggered using TCL code. The use 138499ee3600Sdrh ** for this is when a particular test fails on (say) the 1485th iteration. 138599ee3600Sdrh ** In the TCL test script, we can add code like this: 138699ee3600Sdrh ** 138799ee3600Sdrh ** if {$i==1485} breakpoint 138899ee3600Sdrh ** 138999ee3600Sdrh ** Then run testfixture in the debugger and wait for the breakpoint to 139099ee3600Sdrh ** fire. Then additional breakpoints can be set to trace down the bug. 139199ee3600Sdrh */ 139299ee3600Sdrh static int test_breakpoint( 139399ee3600Sdrh void *NotUsed, 139499ee3600Sdrh Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 139599ee3600Sdrh int argc, /* Number of arguments */ 139699ee3600Sdrh char **argv /* Text of each argument */ 139799ee3600Sdrh ){ 139899ee3600Sdrh return TCL_OK; /* Do nothing */ 139999ee3600Sdrh } 140099ee3600Sdrh 1401241db313Sdrh /* 1402241db313Sdrh ** Usage: sqlite3_bind_int STMT N VALUE 1403241db313Sdrh ** 1404241db313Sdrh ** Test the sqlite3_bind_int interface. STMT is a prepared statement. 1405241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1406241db313Sdrh ** binds a 32-bit integer VALUE to that wildcard. 1407241db313Sdrh */ 1408241db313Sdrh static int test_bind_int( 140951e3d8e2Sdanielk1977 void * clientData, 141051e3d8e2Sdanielk1977 Tcl_Interp *interp, 141151e3d8e2Sdanielk1977 int objc, 141251e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 141351e3d8e2Sdanielk1977 ){ 141451e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 141551e3d8e2Sdanielk1977 int idx; 141651e3d8e2Sdanielk1977 int value; 141751e3d8e2Sdanielk1977 int rc; 141851e3d8e2Sdanielk1977 141951e3d8e2Sdanielk1977 if( objc!=4 ){ 142051e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1421241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 142251e3d8e2Sdanielk1977 return TCL_ERROR; 142351e3d8e2Sdanielk1977 } 142451e3d8e2Sdanielk1977 142551e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 142651e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 142751e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR; 142851e3d8e2Sdanielk1977 1429c572ef7fSdanielk1977 rc = sqlite3_bind_int(pStmt, idx, value); 1430c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 143151e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 143251e3d8e2Sdanielk1977 return TCL_ERROR; 143351e3d8e2Sdanielk1977 } 143451e3d8e2Sdanielk1977 143551e3d8e2Sdanielk1977 return TCL_OK; 143651e3d8e2Sdanielk1977 } 143751e3d8e2Sdanielk1977 1438241db313Sdrh 1439241db313Sdrh /* 1440241db313Sdrh ** Usage: sqlite3_bind_int64 STMT N VALUE 1441241db313Sdrh ** 1442241db313Sdrh ** Test the sqlite3_bind_int64 interface. STMT is a prepared statement. 1443241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1444241db313Sdrh ** binds a 64-bit integer VALUE to that wildcard. 1445241db313Sdrh */ 144651e3d8e2Sdanielk1977 static int test_bind_int64( 144751e3d8e2Sdanielk1977 void * clientData, 144851e3d8e2Sdanielk1977 Tcl_Interp *interp, 144951e3d8e2Sdanielk1977 int objc, 145051e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 145151e3d8e2Sdanielk1977 ){ 145251e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 145351e3d8e2Sdanielk1977 int idx; 145451e3d8e2Sdanielk1977 i64 value; 145551e3d8e2Sdanielk1977 int rc; 145651e3d8e2Sdanielk1977 145751e3d8e2Sdanielk1977 if( objc!=4 ){ 145851e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1459241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 146051e3d8e2Sdanielk1977 return TCL_ERROR; 146151e3d8e2Sdanielk1977 } 146251e3d8e2Sdanielk1977 146351e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 146451e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 146551e3d8e2Sdanielk1977 if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR; 146651e3d8e2Sdanielk1977 146751e3d8e2Sdanielk1977 rc = sqlite3_bind_int64(pStmt, idx, value); 1468c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 146951e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 147051e3d8e2Sdanielk1977 return TCL_ERROR; 147151e3d8e2Sdanielk1977 } 147251e3d8e2Sdanielk1977 147351e3d8e2Sdanielk1977 return TCL_OK; 147451e3d8e2Sdanielk1977 } 147551e3d8e2Sdanielk1977 1476241db313Sdrh 1477241db313Sdrh /* 1478241db313Sdrh ** Usage: sqlite3_bind_double STMT N VALUE 1479241db313Sdrh ** 1480241db313Sdrh ** Test the sqlite3_bind_double interface. STMT is a prepared statement. 1481241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1482241db313Sdrh ** binds a 64-bit integer VALUE to that wildcard. 1483241db313Sdrh */ 148451e3d8e2Sdanielk1977 static int test_bind_double( 148551e3d8e2Sdanielk1977 void * clientData, 148651e3d8e2Sdanielk1977 Tcl_Interp *interp, 148751e3d8e2Sdanielk1977 int objc, 148851e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 148951e3d8e2Sdanielk1977 ){ 149051e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 149151e3d8e2Sdanielk1977 int idx; 149251e3d8e2Sdanielk1977 double value; 149351e3d8e2Sdanielk1977 int rc; 149451e3d8e2Sdanielk1977 149551e3d8e2Sdanielk1977 if( objc!=4 ){ 149651e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1497241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 149851e3d8e2Sdanielk1977 return TCL_ERROR; 149951e3d8e2Sdanielk1977 } 150051e3d8e2Sdanielk1977 150151e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 150251e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 150351e3d8e2Sdanielk1977 if( Tcl_GetDoubleFromObj(interp, objv[3], &value) ) return TCL_ERROR; 150451e3d8e2Sdanielk1977 150551e3d8e2Sdanielk1977 rc = sqlite3_bind_double(pStmt, idx, value); 1506c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 150751e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 150851e3d8e2Sdanielk1977 return TCL_ERROR; 150951e3d8e2Sdanielk1977 } 151051e3d8e2Sdanielk1977 151151e3d8e2Sdanielk1977 return TCL_OK; 151251e3d8e2Sdanielk1977 } 151351e3d8e2Sdanielk1977 1514241db313Sdrh /* 1515241db313Sdrh ** Usage: sqlite3_bind_null STMT N 1516241db313Sdrh ** 1517241db313Sdrh ** Test the sqlite3_bind_null interface. STMT is a prepared statement. 1518241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1519241db313Sdrh ** binds a NULL to the wildcard. 1520241db313Sdrh */ 152151e3d8e2Sdanielk1977 static int test_bind_null( 152251e3d8e2Sdanielk1977 void * clientData, 152351e3d8e2Sdanielk1977 Tcl_Interp *interp, 152451e3d8e2Sdanielk1977 int objc, 152551e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 152651e3d8e2Sdanielk1977 ){ 152751e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 152851e3d8e2Sdanielk1977 int idx; 152951e3d8e2Sdanielk1977 int rc; 153051e3d8e2Sdanielk1977 153151e3d8e2Sdanielk1977 if( objc!=3 ){ 153251e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1533241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N", 0); 153451e3d8e2Sdanielk1977 return TCL_ERROR; 153551e3d8e2Sdanielk1977 } 153651e3d8e2Sdanielk1977 153751e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 153851e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 153951e3d8e2Sdanielk1977 154051e3d8e2Sdanielk1977 rc = sqlite3_bind_null(pStmt, idx); 1541c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 154251e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 154351e3d8e2Sdanielk1977 return TCL_ERROR; 154451e3d8e2Sdanielk1977 } 154551e3d8e2Sdanielk1977 154651e3d8e2Sdanielk1977 return TCL_OK; 154751e3d8e2Sdanielk1977 } 154851e3d8e2Sdanielk1977 1549241db313Sdrh /* 1550241db313Sdrh ** Usage: sqlite3_bind_text STMT N STRING BYTES 1551241db313Sdrh ** 1552241db313Sdrh ** Test the sqlite3_bind_text interface. STMT is a prepared statement. 1553241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1554241db313Sdrh ** binds a UTF-8 string STRING to the wildcard. The string is BYTES bytes 1555241db313Sdrh ** long. 1556241db313Sdrh */ 155751e3d8e2Sdanielk1977 static int test_bind_text( 155851e3d8e2Sdanielk1977 void * clientData, 155951e3d8e2Sdanielk1977 Tcl_Interp *interp, 156051e3d8e2Sdanielk1977 int objc, 156151e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 156251e3d8e2Sdanielk1977 ){ 156351e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 156451e3d8e2Sdanielk1977 int idx; 156551e3d8e2Sdanielk1977 int bytes; 156651e3d8e2Sdanielk1977 char *value; 156751e3d8e2Sdanielk1977 int rc; 156851e3d8e2Sdanielk1977 156951e3d8e2Sdanielk1977 if( objc!=5 ){ 157051e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1571241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0); 157251e3d8e2Sdanielk1977 return TCL_ERROR; 157351e3d8e2Sdanielk1977 } 157451e3d8e2Sdanielk1977 157551e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 157651e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 157751e3d8e2Sdanielk1977 value = Tcl_GetString(objv[3]); 157851e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 157951e3d8e2Sdanielk1977 1580d8123366Sdanielk1977 rc = sqlite3_bind_text(pStmt, idx, value, bytes, SQLITE_TRANSIENT); 1581c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 158251e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 158351e3d8e2Sdanielk1977 return TCL_ERROR; 158451e3d8e2Sdanielk1977 } 158551e3d8e2Sdanielk1977 158651e3d8e2Sdanielk1977 return TCL_OK; 158751e3d8e2Sdanielk1977 } 158851e3d8e2Sdanielk1977 1589241db313Sdrh /* 1590241db313Sdrh ** Usage: sqlite3_bind_text16 STMT N STRING BYTES 1591241db313Sdrh ** 1592241db313Sdrh ** Test the sqlite3_bind_text16 interface. STMT is a prepared statement. 1593241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1594241db313Sdrh ** binds a UTF-16 string STRING to the wildcard. The string is BYTES bytes 1595241db313Sdrh ** long. 1596241db313Sdrh */ 159751e3d8e2Sdanielk1977 static int test_bind_text16( 159851e3d8e2Sdanielk1977 void * clientData, 159951e3d8e2Sdanielk1977 Tcl_Interp *interp, 160051e3d8e2Sdanielk1977 int objc, 160151e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 160251e3d8e2Sdanielk1977 ){ 16035436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 160451e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 160551e3d8e2Sdanielk1977 int idx; 160651e3d8e2Sdanielk1977 int bytes; 160751e3d8e2Sdanielk1977 char *value; 160851e3d8e2Sdanielk1977 int rc; 160951e3d8e2Sdanielk1977 161051e3d8e2Sdanielk1977 if( objc!=5 ){ 161151e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1612241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0); 161351e3d8e2Sdanielk1977 return TCL_ERROR; 161451e3d8e2Sdanielk1977 } 161551e3d8e2Sdanielk1977 161651e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 161751e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 161851e3d8e2Sdanielk1977 value = Tcl_GetByteArrayFromObj(objv[3], 0); 161951e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 162051e3d8e2Sdanielk1977 1621d8123366Sdanielk1977 rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, SQLITE_TRANSIENT); 1622c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 162351e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 162451e3d8e2Sdanielk1977 return TCL_ERROR; 162551e3d8e2Sdanielk1977 } 162651e3d8e2Sdanielk1977 16275436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 162851e3d8e2Sdanielk1977 return TCL_OK; 162951e3d8e2Sdanielk1977 } 163051e3d8e2Sdanielk1977 1631241db313Sdrh /* 1632241db313Sdrh ** Usage: sqlite3_bind_blob STMT N DATA BYTES 1633241db313Sdrh ** 1634241db313Sdrh ** Test the sqlite3_bind_blob interface. STMT is a prepared statement. 1635241db313Sdrh ** N is the index of a wildcard in the prepared statement. This command 1636241db313Sdrh ** binds a BLOB to the wildcard. The BLOB is BYTES bytes in size. 1637241db313Sdrh */ 163851e3d8e2Sdanielk1977 static int test_bind_blob( 163951e3d8e2Sdanielk1977 void * clientData, 164051e3d8e2Sdanielk1977 Tcl_Interp *interp, 164151e3d8e2Sdanielk1977 int objc, 164251e3d8e2Sdanielk1977 Tcl_Obj *CONST objv[] 164351e3d8e2Sdanielk1977 ){ 164451e3d8e2Sdanielk1977 sqlite3_stmt *pStmt; 164551e3d8e2Sdanielk1977 int idx; 164651e3d8e2Sdanielk1977 int bytes; 164751e3d8e2Sdanielk1977 char *value; 164851e3d8e2Sdanielk1977 int rc; 164951e3d8e2Sdanielk1977 165051e3d8e2Sdanielk1977 if( objc!=5 ){ 165151e3d8e2Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 1652241db313Sdrh Tcl_GetStringFromObj(objv[0], 0), " STMT N DATA BYTES", 0); 165351e3d8e2Sdanielk1977 return TCL_ERROR; 165451e3d8e2Sdanielk1977 } 165551e3d8e2Sdanielk1977 165651e3d8e2Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 165751e3d8e2Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 165851e3d8e2Sdanielk1977 value = Tcl_GetString(objv[3]); 165949e4643eSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 166051e3d8e2Sdanielk1977 1661d8123366Sdanielk1977 rc = sqlite3_bind_blob(pStmt, idx, value, bytes, SQLITE_TRANSIENT); 1662c60d0446Sdrh if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 166351e3d8e2Sdanielk1977 if( rc!=SQLITE_OK ){ 166451e3d8e2Sdanielk1977 return TCL_ERROR; 166551e3d8e2Sdanielk1977 } 166651e3d8e2Sdanielk1977 166751e3d8e2Sdanielk1977 return TCL_OK; 166851e3d8e2Sdanielk1977 } 166951e3d8e2Sdanielk1977 167099ee3600Sdrh /* 167175f6a032Sdrh ** Usage: sqlite3_bind_parameter_count STMT 167275f6a032Sdrh ** 167375f6a032Sdrh ** Return the number of wildcards in the given statement. 167475f6a032Sdrh */ 167575f6a032Sdrh static int test_bind_parameter_count( 167675f6a032Sdrh void * clientData, 167775f6a032Sdrh Tcl_Interp *interp, 167875f6a032Sdrh int objc, 167975f6a032Sdrh Tcl_Obj *CONST objv[] 168075f6a032Sdrh ){ 168175f6a032Sdrh sqlite3_stmt *pStmt; 168275f6a032Sdrh 168375f6a032Sdrh if( objc!=2 ){ 168475f6a032Sdrh Tcl_WrongNumArgs(interp, 1, objv, "STMT"); 168575f6a032Sdrh return TCL_ERROR; 168675f6a032Sdrh } 168775f6a032Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 168875f6a032Sdrh Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_bind_parameter_count(pStmt))); 168975f6a032Sdrh return TCL_OK; 169075f6a032Sdrh } 169175f6a032Sdrh 169275f6a032Sdrh /* 1693895d7472Sdrh ** Usage: sqlite3_bind_parameter_name STMT N 1694895d7472Sdrh ** 1695895d7472Sdrh ** Return the name of the Nth wildcard. The first wildcard is 1. 1696895d7472Sdrh ** An empty string is returned if N is out of range or if the wildcard 1697895d7472Sdrh ** is nameless. 1698895d7472Sdrh */ 1699895d7472Sdrh static int test_bind_parameter_name( 1700895d7472Sdrh void * clientData, 1701895d7472Sdrh Tcl_Interp *interp, 1702895d7472Sdrh int objc, 1703895d7472Sdrh Tcl_Obj *CONST objv[] 1704895d7472Sdrh ){ 1705895d7472Sdrh sqlite3_stmt *pStmt; 1706895d7472Sdrh int i; 1707895d7472Sdrh 1708895d7472Sdrh if( objc!=3 ){ 1709895d7472Sdrh Tcl_WrongNumArgs(interp, 1, objv, "STMT N"); 1710895d7472Sdrh return TCL_ERROR; 1711895d7472Sdrh } 1712895d7472Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1713895d7472Sdrh if( Tcl_GetIntFromObj(interp, objv[2], &i) ) return TCL_ERROR; 1714895d7472Sdrh Tcl_SetObjResult(interp, 1715895d7472Sdrh Tcl_NewStringObj(sqlite3_bind_parameter_name(pStmt,i),-1) 1716895d7472Sdrh ); 1717895d7472Sdrh return TCL_OK; 1718895d7472Sdrh } 1719895d7472Sdrh 1720895d7472Sdrh /* 1721fa6bc000Sdrh ** Usage: sqlite3_bind_parameter_index STMT NAME 1722fa6bc000Sdrh ** 1723fa6bc000Sdrh ** Return the index of the wildcard called NAME. Return 0 if there is 1724fa6bc000Sdrh ** no such wildcard. 1725fa6bc000Sdrh */ 1726fa6bc000Sdrh static int test_bind_parameter_index( 1727fa6bc000Sdrh void * clientData, 1728fa6bc000Sdrh Tcl_Interp *interp, 1729fa6bc000Sdrh int objc, 1730fa6bc000Sdrh Tcl_Obj *CONST objv[] 1731fa6bc000Sdrh ){ 1732fa6bc000Sdrh sqlite3_stmt *pStmt; 1733fa6bc000Sdrh 1734fa6bc000Sdrh if( objc!=3 ){ 1735fa6bc000Sdrh Tcl_WrongNumArgs(interp, 1, objv, "STMT NAME"); 1736fa6bc000Sdrh return TCL_ERROR; 1737fa6bc000Sdrh } 1738fa6bc000Sdrh if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1739fa6bc000Sdrh Tcl_SetObjResult(interp, 1740fa6bc000Sdrh Tcl_NewIntObj( 1741fa6bc000Sdrh sqlite3_bind_parameter_index(pStmt,Tcl_GetString(objv[2])) 1742fa6bc000Sdrh ) 1743fa6bc000Sdrh ); 1744fa6bc000Sdrh return TCL_OK; 1745fa6bc000Sdrh } 1746fa6bc000Sdrh 1747fa6bc000Sdrh /* 1748600dd0baSdanielk1977 ** Usage: sqlite3_clear_bindings STMT 1749600dd0baSdanielk1977 ** 1750600dd0baSdanielk1977 */ 1751600dd0baSdanielk1977 #if 0 1752600dd0baSdanielk1977 static int test_clear_bindings( 1753600dd0baSdanielk1977 void * clientData, 1754600dd0baSdanielk1977 Tcl_Interp *interp, 1755600dd0baSdanielk1977 int objc, 1756600dd0baSdanielk1977 Tcl_Obj *CONST objv[] 1757600dd0baSdanielk1977 ){ 1758600dd0baSdanielk1977 sqlite3_stmt *pStmt; 1759600dd0baSdanielk1977 1760600dd0baSdanielk1977 if( objc!=2 ){ 1761600dd0baSdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "STMT"); 1762600dd0baSdanielk1977 return TCL_ERROR; 1763600dd0baSdanielk1977 } 1764600dd0baSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1765600dd0baSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(pStmt))); 1766600dd0baSdanielk1977 return TCL_OK; 1767600dd0baSdanielk1977 } 1768600dd0baSdanielk1977 #endif 1769600dd0baSdanielk1977 1770600dd0baSdanielk1977 /* 17716622cce3Sdanielk1977 ** Usage: sqlite3_errcode DB 17726622cce3Sdanielk1977 ** 17736622cce3Sdanielk1977 ** Return the string representation of the most recent sqlite3_* API 17746622cce3Sdanielk1977 ** error code. e.g. "SQLITE_ERROR". 17756622cce3Sdanielk1977 */ 17766622cce3Sdanielk1977 static int test_errcode( 17776622cce3Sdanielk1977 void * clientData, 17786622cce3Sdanielk1977 Tcl_Interp *interp, 17796622cce3Sdanielk1977 int objc, 17806622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 17816622cce3Sdanielk1977 ){ 17826622cce3Sdanielk1977 sqlite3 *db; 17836622cce3Sdanielk1977 17846622cce3Sdanielk1977 if( objc!=2 ){ 17856622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 17866622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 17876622cce3Sdanielk1977 return TCL_ERROR; 17886622cce3Sdanielk1977 } 17896622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 17906622cce3Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(sqlite3_errcode(db)), 0); 17916622cce3Sdanielk1977 return TCL_OK; 17926622cce3Sdanielk1977 } 17936622cce3Sdanielk1977 17946622cce3Sdanielk1977 /* 17956622cce3Sdanielk1977 ** Usage: test_errmsg DB 17966622cce3Sdanielk1977 ** 17976622cce3Sdanielk1977 ** Returns the UTF-8 representation of the error message string for the 17986622cce3Sdanielk1977 ** most recent sqlite3_* API call. 17996622cce3Sdanielk1977 */ 18006622cce3Sdanielk1977 static int test_errmsg( 18016622cce3Sdanielk1977 void * clientData, 18026622cce3Sdanielk1977 Tcl_Interp *interp, 18036622cce3Sdanielk1977 int objc, 18046622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 18056622cce3Sdanielk1977 ){ 18069bb575fdSdrh sqlite3 *db; 18076622cce3Sdanielk1977 const char *zErr; 18086622cce3Sdanielk1977 18096622cce3Sdanielk1977 if( objc!=2 ){ 18106622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 18116622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 18126622cce3Sdanielk1977 return TCL_ERROR; 18136622cce3Sdanielk1977 } 18146622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 18156622cce3Sdanielk1977 18166622cce3Sdanielk1977 zErr = sqlite3_errmsg(db); 18176622cce3Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1)); 18186622cce3Sdanielk1977 return TCL_OK; 18196622cce3Sdanielk1977 } 18206622cce3Sdanielk1977 18216622cce3Sdanielk1977 /* 18226622cce3Sdanielk1977 ** Usage: test_errmsg16 DB 18236622cce3Sdanielk1977 ** 18246622cce3Sdanielk1977 ** Returns the UTF-16 representation of the error message string for the 18256622cce3Sdanielk1977 ** most recent sqlite3_* API call. This is a byte array object at the TCL 18266622cce3Sdanielk1977 ** level, and it includes the 0x00 0x00 terminator bytes at the end of the 18276622cce3Sdanielk1977 ** UTF-16 string. 18286622cce3Sdanielk1977 */ 18296622cce3Sdanielk1977 static int test_errmsg16( 18306622cce3Sdanielk1977 void * clientData, 18316622cce3Sdanielk1977 Tcl_Interp *interp, 18326622cce3Sdanielk1977 int objc, 18336622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 18346622cce3Sdanielk1977 ){ 18355436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 18369bb575fdSdrh sqlite3 *db; 18376622cce3Sdanielk1977 const void *zErr; 18386622cce3Sdanielk1977 int bytes; 18396622cce3Sdanielk1977 18406622cce3Sdanielk1977 if( objc!=2 ){ 18416622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 18426622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB", 0); 18436622cce3Sdanielk1977 return TCL_ERROR; 18446622cce3Sdanielk1977 } 18456622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 18466622cce3Sdanielk1977 18476622cce3Sdanielk1977 zErr = sqlite3_errmsg16(db); 18486622cce3Sdanielk1977 bytes = sqlite3utf16ByteLen(zErr, -1); 18496622cce3Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes)); 18505436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 18516622cce3Sdanielk1977 return TCL_OK; 18526622cce3Sdanielk1977 } 18536622cce3Sdanielk1977 18546622cce3Sdanielk1977 /* 18556622cce3Sdanielk1977 ** Usage: sqlite3_prepare DB sql bytes tailvar 18566622cce3Sdanielk1977 ** 18576622cce3Sdanielk1977 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using 18586622cce3Sdanielk1977 ** database handle <DB>. The parameter <tailval> is the name of a global 18596622cce3Sdanielk1977 ** variable that is set to the unused portion of <sql> (if any). A 18606622cce3Sdanielk1977 ** STMT handle is returned. 18616622cce3Sdanielk1977 */ 18626622cce3Sdanielk1977 static int test_prepare( 18636622cce3Sdanielk1977 void * clientData, 18646622cce3Sdanielk1977 Tcl_Interp *interp, 18656622cce3Sdanielk1977 int objc, 18666622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 18676622cce3Sdanielk1977 ){ 18686622cce3Sdanielk1977 sqlite3 *db; 18696622cce3Sdanielk1977 const char *zSql; 18706622cce3Sdanielk1977 int bytes; 18716622cce3Sdanielk1977 const char *zTail = 0; 18726622cce3Sdanielk1977 sqlite3_stmt *pStmt = 0; 18736622cce3Sdanielk1977 char zBuf[50]; 18744ad1713cSdanielk1977 int rc; 18756622cce3Sdanielk1977 18766622cce3Sdanielk1977 if( objc!=5 ){ 18776622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 18786622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); 18796622cce3Sdanielk1977 return TCL_ERROR; 18806622cce3Sdanielk1977 } 18816622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 18826622cce3Sdanielk1977 zSql = Tcl_GetString(objv[2]); 18836622cce3Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; 18846622cce3Sdanielk1977 18854ad1713cSdanielk1977 rc = sqlite3_prepare(db, zSql, bytes, &pStmt, &zTail); 1886c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 18876622cce3Sdanielk1977 if( zTail ){ 18886622cce3Sdanielk1977 if( bytes>=0 ){ 18896622cce3Sdanielk1977 bytes = bytes - (zTail-zSql); 18906622cce3Sdanielk1977 } 18916622cce3Sdanielk1977 Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0); 18926622cce3Sdanielk1977 } 18934ad1713cSdanielk1977 if( rc!=SQLITE_OK ){ 18944ad1713cSdanielk1977 assert( pStmt==0 ); 18954ad1713cSdanielk1977 sprintf(zBuf, "(%d) ", rc); 18964ad1713cSdanielk1977 Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0); 18974ad1713cSdanielk1977 return TCL_ERROR; 18984ad1713cSdanielk1977 } 18996622cce3Sdanielk1977 19004ad1713cSdanielk1977 if( pStmt ){ 19016622cce3Sdanielk1977 if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; 19026622cce3Sdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 19034ad1713cSdanielk1977 } 19046622cce3Sdanielk1977 return TCL_OK; 19056622cce3Sdanielk1977 } 19066622cce3Sdanielk1977 19076622cce3Sdanielk1977 /* 19086622cce3Sdanielk1977 ** Usage: sqlite3_prepare DB sql bytes tailvar 19096622cce3Sdanielk1977 ** 19106622cce3Sdanielk1977 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using 19116622cce3Sdanielk1977 ** database handle <DB>. The parameter <tailval> is the name of a global 19126622cce3Sdanielk1977 ** variable that is set to the unused portion of <sql> (if any). A 19136622cce3Sdanielk1977 ** STMT handle is returned. 19146622cce3Sdanielk1977 */ 19156622cce3Sdanielk1977 static int test_prepare16( 19166622cce3Sdanielk1977 void * clientData, 19176622cce3Sdanielk1977 Tcl_Interp *interp, 19186622cce3Sdanielk1977 int objc, 19196622cce3Sdanielk1977 Tcl_Obj *CONST objv[] 19206622cce3Sdanielk1977 ){ 19215436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 19226622cce3Sdanielk1977 sqlite3 *db; 19236622cce3Sdanielk1977 const void *zSql; 19246622cce3Sdanielk1977 const void *zTail = 0; 19256622cce3Sdanielk1977 Tcl_Obj *pTail = 0; 19266622cce3Sdanielk1977 sqlite3_stmt *pStmt = 0; 19276622cce3Sdanielk1977 char zBuf[50]; 1928c60d0446Sdrh int rc; 19296622cce3Sdanielk1977 int bytes; /* The integer specified as arg 3 */ 19306622cce3Sdanielk1977 int objlen; /* The byte-array length of arg 2 */ 19316622cce3Sdanielk1977 19326622cce3Sdanielk1977 if( objc!=5 ){ 19336622cce3Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 19346622cce3Sdanielk1977 Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); 19356622cce3Sdanielk1977 return TCL_ERROR; 19366622cce3Sdanielk1977 } 19376622cce3Sdanielk1977 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 19386622cce3Sdanielk1977 zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen); 19396622cce3Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; 19406622cce3Sdanielk1977 1941c60d0446Sdrh rc = sqlite3_prepare16(db, zSql, bytes, &pStmt, &zTail); 1942c60d0446Sdrh if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1943c60d0446Sdrh if( rc ){ 19446622cce3Sdanielk1977 return TCL_ERROR; 19456622cce3Sdanielk1977 } 19466622cce3Sdanielk1977 19476622cce3Sdanielk1977 if( zTail ){ 19486622cce3Sdanielk1977 objlen = objlen - ((u8 *)zTail-(u8 *)zSql); 19496622cce3Sdanielk1977 }else{ 19506622cce3Sdanielk1977 objlen = 0; 19516622cce3Sdanielk1977 } 19526622cce3Sdanielk1977 pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen); 19536622cce3Sdanielk1977 Tcl_IncrRefCount(pTail); 19546622cce3Sdanielk1977 Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0); 19554ad1713cSdanielk1977 Tcl_DecrRefCount(pTail); 19566622cce3Sdanielk1977 19574ad1713cSdanielk1977 if( pStmt ){ 19586622cce3Sdanielk1977 if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; 19594ad1713cSdanielk1977 } 19606622cce3Sdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 19615436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 19626622cce3Sdanielk1977 return TCL_OK; 19636622cce3Sdanielk1977 } 19646622cce3Sdanielk1977 19654ad1713cSdanielk1977 /* 19664ad1713cSdanielk1977 ** Usage: sqlite3_open filename ?options-list? 19674ad1713cSdanielk1977 */ 19684ad1713cSdanielk1977 static int test_open( 19694ad1713cSdanielk1977 void * clientData, 19704ad1713cSdanielk1977 Tcl_Interp *interp, 19714ad1713cSdanielk1977 int objc, 19724ad1713cSdanielk1977 Tcl_Obj *CONST objv[] 19734ad1713cSdanielk1977 ){ 19744ad1713cSdanielk1977 const char *zFilename; 19754ad1713cSdanielk1977 sqlite3 *db; 19764ad1713cSdanielk1977 int rc; 19774ad1713cSdanielk1977 char zBuf[100]; 19784ad1713cSdanielk1977 19794ad1713cSdanielk1977 if( objc!=3 && objc!=2 ){ 19804ad1713cSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 19814ad1713cSdanielk1977 Tcl_GetString(objv[0]), " filename options-list", 0); 19824ad1713cSdanielk1977 return TCL_ERROR; 19834ad1713cSdanielk1977 } 19844ad1713cSdanielk1977 19854ad1713cSdanielk1977 zFilename = Tcl_GetString(objv[1]); 19864f057f90Sdanielk1977 rc = sqlite3_open(zFilename, &db); 19874ad1713cSdanielk1977 19884ad1713cSdanielk1977 if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR; 19894ad1713cSdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 19904ad1713cSdanielk1977 return TCL_OK; 19914ad1713cSdanielk1977 } 19924ad1713cSdanielk1977 19934ad1713cSdanielk1977 /* 19944ad1713cSdanielk1977 ** Usage: sqlite3_open16 filename options 19954ad1713cSdanielk1977 */ 19964ad1713cSdanielk1977 static int test_open16( 19974ad1713cSdanielk1977 void * clientData, 19984ad1713cSdanielk1977 Tcl_Interp *interp, 19994ad1713cSdanielk1977 int objc, 20004ad1713cSdanielk1977 Tcl_Obj *CONST objv[] 20014ad1713cSdanielk1977 ){ 20025436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 20034ad1713cSdanielk1977 const void *zFilename; 20044ad1713cSdanielk1977 sqlite3 *db; 20054ad1713cSdanielk1977 int rc; 20064ad1713cSdanielk1977 char zBuf[100]; 20074ad1713cSdanielk1977 20084ad1713cSdanielk1977 if( objc!=3 ){ 20094ad1713cSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 20104ad1713cSdanielk1977 Tcl_GetString(objv[0]), " filename options-list", 0); 20114ad1713cSdanielk1977 return TCL_ERROR; 20124ad1713cSdanielk1977 } 20134ad1713cSdanielk1977 20144ad1713cSdanielk1977 zFilename = Tcl_GetByteArrayFromObj(objv[1], 0); 20154f057f90Sdanielk1977 rc = sqlite3_open16(zFilename, &db); 20164ad1713cSdanielk1977 20174ad1713cSdanielk1977 if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR; 20184ad1713cSdanielk1977 Tcl_AppendResult(interp, zBuf, 0); 20195436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 20204ad1713cSdanielk1977 return TCL_OK; 20214ad1713cSdanielk1977 } 2022d3d39e93Sdrh 2023d3d39e93Sdrh /* 2024bc6ada41Sdanielk1977 ** Usage: sqlite3_complete16 <UTF-16 string> 2025bc6ada41Sdanielk1977 ** 2026bc6ada41Sdanielk1977 ** Return 1 if the supplied argument is a complete SQL statement, or zero 2027bc6ada41Sdanielk1977 ** otherwise. 2028bc6ada41Sdanielk1977 */ 2029bc6ada41Sdanielk1977 static int test_complete16( 2030bc6ada41Sdanielk1977 void * clientData, 2031bc6ada41Sdanielk1977 Tcl_Interp *interp, 2032bc6ada41Sdanielk1977 int objc, 2033bc6ada41Sdanielk1977 Tcl_Obj *CONST objv[] 2034bc6ada41Sdanielk1977 ){ 2035ccae6026Sdrh #if !defined(SQLITE_OMIT_COMPLETE) && !defined(SQLITE_OMIT_UTF16) 2036bc6ada41Sdanielk1977 char *zBuf; 2037bc6ada41Sdanielk1977 2038bc6ada41Sdanielk1977 if( objc!=2 ){ 2039bc6ada41Sdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>"); 2040bc6ada41Sdanielk1977 return TCL_ERROR; 2041bc6ada41Sdanielk1977 } 2042bc6ada41Sdanielk1977 2043bc6ada41Sdanielk1977 zBuf = Tcl_GetByteArrayFromObj(objv[1], 0); 2044bc6ada41Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_complete16(zBuf))); 2045ccae6026Sdrh #endif /* SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */ 2046bc6ada41Sdanielk1977 return TCL_OK; 2047bc6ada41Sdanielk1977 } 2048bc6ada41Sdanielk1977 2049bc6ada41Sdanielk1977 /* 2050106bb236Sdanielk1977 ** Usage: sqlite3_step STMT 2051106bb236Sdanielk1977 ** 2052106bb236Sdanielk1977 ** Advance the statement to the next row. 2053106bb236Sdanielk1977 */ 205417240fd9Sdanielk1977 static int test_step( 2055106bb236Sdanielk1977 void * clientData, 2056106bb236Sdanielk1977 Tcl_Interp *interp, 2057106bb236Sdanielk1977 int objc, 2058106bb236Sdanielk1977 Tcl_Obj *CONST objv[] 2059106bb236Sdanielk1977 ){ 2060106bb236Sdanielk1977 sqlite3_stmt *pStmt; 2061106bb236Sdanielk1977 int rc; 2062106bb236Sdanielk1977 2063e1cd9874Sdanielk1977 if( objc!=2 ){ 2064106bb236Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 2065106bb236Sdanielk1977 Tcl_GetString(objv[0]), " STMT", 0); 2066106bb236Sdanielk1977 return TCL_ERROR; 2067106bb236Sdanielk1977 } 2068106bb236Sdanielk1977 2069106bb236Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 207017240fd9Sdanielk1977 rc = sqlite3_step(pStmt); 2071106bb236Sdanielk1977 2072fbcd585fSdanielk1977 /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; */ 20736590493dSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), 0); 2074e1cd9874Sdanielk1977 return TCL_OK; 2075e1cd9874Sdanielk1977 } 2076e1cd9874Sdanielk1977 2077e1cd9874Sdanielk1977 /* 207817240fd9Sdanielk1977 ** Usage: sqlite3_column_count STMT 207917240fd9Sdanielk1977 ** 208017240fd9Sdanielk1977 ** Return the number of columns returned by the sql statement STMT. 208117240fd9Sdanielk1977 */ 208217240fd9Sdanielk1977 static int test_column_count( 208317240fd9Sdanielk1977 void * clientData, 208417240fd9Sdanielk1977 Tcl_Interp *interp, 208517240fd9Sdanielk1977 int objc, 208617240fd9Sdanielk1977 Tcl_Obj *CONST objv[] 208717240fd9Sdanielk1977 ){ 208817240fd9Sdanielk1977 sqlite3_stmt *pStmt; 208917240fd9Sdanielk1977 209017240fd9Sdanielk1977 if( objc!=2 ){ 209117240fd9Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 209217240fd9Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 209317240fd9Sdanielk1977 return TCL_ERROR; 209417240fd9Sdanielk1977 } 209517240fd9Sdanielk1977 209617240fd9Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 209717240fd9Sdanielk1977 209817240fd9Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_column_count(pStmt))); 209917240fd9Sdanielk1977 return TCL_OK; 210017240fd9Sdanielk1977 } 210117240fd9Sdanielk1977 210217240fd9Sdanielk1977 /* 21033cf86063Sdanielk1977 ** Usage: sqlite3_column_type STMT column 21043cf86063Sdanielk1977 ** 21053cf86063Sdanielk1977 ** Return the type of the data in column 'column' of the current row. 21063cf86063Sdanielk1977 */ 21073cf86063Sdanielk1977 static int test_column_type( 21083cf86063Sdanielk1977 void * clientData, 21093cf86063Sdanielk1977 Tcl_Interp *interp, 21103cf86063Sdanielk1977 int objc, 21113cf86063Sdanielk1977 Tcl_Obj *CONST objv[] 21123cf86063Sdanielk1977 ){ 21133cf86063Sdanielk1977 sqlite3_stmt *pStmt; 21143cf86063Sdanielk1977 int col; 21153cf86063Sdanielk1977 int tp; 21163cf86063Sdanielk1977 21173cf86063Sdanielk1977 if( objc!=3 ){ 21183cf86063Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 21193cf86063Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 21203cf86063Sdanielk1977 return TCL_ERROR; 21213cf86063Sdanielk1977 } 21223cf86063Sdanielk1977 21233cf86063Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 21243cf86063Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 21253cf86063Sdanielk1977 21263cf86063Sdanielk1977 tp = sqlite3_column_type(pStmt, col); 21273cf86063Sdanielk1977 switch( tp ){ 21289c054830Sdrh case SQLITE_INTEGER: 21293cf86063Sdanielk1977 Tcl_SetResult(interp, "INTEGER", TCL_STATIC); 21303cf86063Sdanielk1977 break; 21319c054830Sdrh case SQLITE_NULL: 21323cf86063Sdanielk1977 Tcl_SetResult(interp, "NULL", TCL_STATIC); 21333cf86063Sdanielk1977 break; 21349c054830Sdrh case SQLITE_FLOAT: 21353cf86063Sdanielk1977 Tcl_SetResult(interp, "FLOAT", TCL_STATIC); 21363cf86063Sdanielk1977 break; 21379c054830Sdrh case SQLITE_TEXT: 21383cf86063Sdanielk1977 Tcl_SetResult(interp, "TEXT", TCL_STATIC); 21393cf86063Sdanielk1977 break; 21409c054830Sdrh case SQLITE_BLOB: 21413cf86063Sdanielk1977 Tcl_SetResult(interp, "BLOB", TCL_STATIC); 21423cf86063Sdanielk1977 break; 21433cf86063Sdanielk1977 default: 21443cf86063Sdanielk1977 assert(0); 21453cf86063Sdanielk1977 } 21463cf86063Sdanielk1977 21473cf86063Sdanielk1977 return TCL_OK; 21483cf86063Sdanielk1977 } 21493cf86063Sdanielk1977 21503cf86063Sdanielk1977 /* 215104f2e68dSdanielk1977 ** Usage: sqlite3_column_int64 STMT column 21523cf86063Sdanielk1977 ** 21533cf86063Sdanielk1977 ** Return the data in column 'column' of the current row cast as an 215404f2e68dSdanielk1977 ** wide (64-bit) integer. 21553cf86063Sdanielk1977 */ 215604f2e68dSdanielk1977 static int test_column_int64( 21573cf86063Sdanielk1977 void * clientData, 21583cf86063Sdanielk1977 Tcl_Interp *interp, 21593cf86063Sdanielk1977 int objc, 21603cf86063Sdanielk1977 Tcl_Obj *CONST objv[] 21613cf86063Sdanielk1977 ){ 21623cf86063Sdanielk1977 sqlite3_stmt *pStmt; 21633cf86063Sdanielk1977 int col; 216404f2e68dSdanielk1977 i64 iVal; 21653cf86063Sdanielk1977 21663cf86063Sdanielk1977 if( objc!=3 ){ 21673cf86063Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 21683cf86063Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 21693cf86063Sdanielk1977 return TCL_ERROR; 21703cf86063Sdanielk1977 } 21713cf86063Sdanielk1977 21723cf86063Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 21733cf86063Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 21743cf86063Sdanielk1977 217504f2e68dSdanielk1977 iVal = sqlite3_column_int64(pStmt, col); 217604f2e68dSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iVal)); 217704f2e68dSdanielk1977 return TCL_OK; 217804f2e68dSdanielk1977 } 217904f2e68dSdanielk1977 218004f2e68dSdanielk1977 /* 2181ea61b2c4Sdanielk1977 ** Usage: sqlite3_column_blob STMT column 2182ea61b2c4Sdanielk1977 */ 2183ea61b2c4Sdanielk1977 static int test_column_blob( 2184ea61b2c4Sdanielk1977 void * clientData, 2185ea61b2c4Sdanielk1977 Tcl_Interp *interp, 2186ea61b2c4Sdanielk1977 int objc, 2187ea61b2c4Sdanielk1977 Tcl_Obj *CONST objv[] 2188ea61b2c4Sdanielk1977 ){ 2189ea61b2c4Sdanielk1977 sqlite3_stmt *pStmt; 2190ea61b2c4Sdanielk1977 int col; 2191ea61b2c4Sdanielk1977 2192ea61b2c4Sdanielk1977 int len; 2193c572ef7fSdanielk1977 const void *pBlob; 2194ea61b2c4Sdanielk1977 2195ea61b2c4Sdanielk1977 if( objc!=3 ){ 2196ea61b2c4Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 2197ea61b2c4Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 2198ea61b2c4Sdanielk1977 return TCL_ERROR; 2199ea61b2c4Sdanielk1977 } 2200ea61b2c4Sdanielk1977 2201ea61b2c4Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2202ea61b2c4Sdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2203ea61b2c4Sdanielk1977 2204ea61b2c4Sdanielk1977 pBlob = sqlite3_column_blob(pStmt, col); 2205ea61b2c4Sdanielk1977 len = sqlite3_column_bytes(pStmt, col); 2206ea61b2c4Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len)); 2207ea61b2c4Sdanielk1977 return TCL_OK; 2208ea61b2c4Sdanielk1977 } 2209ea61b2c4Sdanielk1977 2210ea61b2c4Sdanielk1977 /* 221104f2e68dSdanielk1977 ** Usage: sqlite3_column_double STMT column 221204f2e68dSdanielk1977 ** 221304f2e68dSdanielk1977 ** Return the data in column 'column' of the current row cast as a double. 221404f2e68dSdanielk1977 */ 221504f2e68dSdanielk1977 static int test_column_double( 221604f2e68dSdanielk1977 void * clientData, 221704f2e68dSdanielk1977 Tcl_Interp *interp, 221804f2e68dSdanielk1977 int objc, 221904f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 222004f2e68dSdanielk1977 ){ 222104f2e68dSdanielk1977 sqlite3_stmt *pStmt; 222204f2e68dSdanielk1977 int col; 222304f2e68dSdanielk1977 double rVal; 222404f2e68dSdanielk1977 222504f2e68dSdanielk1977 if( objc!=3 ){ 222604f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 222704f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 222804f2e68dSdanielk1977 return TCL_ERROR; 222904f2e68dSdanielk1977 } 223004f2e68dSdanielk1977 223104f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 223204f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 223304f2e68dSdanielk1977 223404f2e68dSdanielk1977 rVal = sqlite3_column_double(pStmt, col); 2235c572ef7fSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rVal)); 22363cf86063Sdanielk1977 return TCL_OK; 22373cf86063Sdanielk1977 } 22383cf86063Sdanielk1977 22393cf86063Sdanielk1977 /* 224017240fd9Sdanielk1977 ** Usage: sqlite3_data_count STMT 224117240fd9Sdanielk1977 ** 224217240fd9Sdanielk1977 ** Return the number of columns returned by the sql statement STMT. 224317240fd9Sdanielk1977 */ 224417240fd9Sdanielk1977 static int test_data_count( 224517240fd9Sdanielk1977 void * clientData, 224617240fd9Sdanielk1977 Tcl_Interp *interp, 224717240fd9Sdanielk1977 int objc, 224817240fd9Sdanielk1977 Tcl_Obj *CONST objv[] 224917240fd9Sdanielk1977 ){ 225017240fd9Sdanielk1977 sqlite3_stmt *pStmt; 225117240fd9Sdanielk1977 225217240fd9Sdanielk1977 if( objc!=2 ){ 225317240fd9Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 225417240fd9Sdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 225517240fd9Sdanielk1977 return TCL_ERROR; 225617240fd9Sdanielk1977 } 225717240fd9Sdanielk1977 225817240fd9Sdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 225917240fd9Sdanielk1977 226017240fd9Sdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_data_count(pStmt))); 226117240fd9Sdanielk1977 return TCL_OK; 226217240fd9Sdanielk1977 } 226317240fd9Sdanielk1977 226417240fd9Sdanielk1977 /* 226504f2e68dSdanielk1977 ** Usage: sqlite3_column_text STMT column 226604f2e68dSdanielk1977 ** 226704f2e68dSdanielk1977 ** Usage: sqlite3_column_decltype STMT column 226804f2e68dSdanielk1977 ** 226904f2e68dSdanielk1977 ** Usage: sqlite3_column_name STMT column 227004f2e68dSdanielk1977 */ 227104f2e68dSdanielk1977 static int test_stmt_utf8( 2272241db313Sdrh void * clientData, /* Pointer to SQLite API function to be invoke */ 227304f2e68dSdanielk1977 Tcl_Interp *interp, 227404f2e68dSdanielk1977 int objc, 227504f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 227604f2e68dSdanielk1977 ){ 227704f2e68dSdanielk1977 sqlite3_stmt *pStmt; 227804f2e68dSdanielk1977 int col; 2279c572ef7fSdanielk1977 const char *(*xFunc)(sqlite3_stmt*, int) = clientData; 2280f93bbbeaSdanielk1977 const char *zRet; 228104f2e68dSdanielk1977 228204f2e68dSdanielk1977 if( objc!=3 ){ 228304f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 228404f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 228504f2e68dSdanielk1977 return TCL_ERROR; 228604f2e68dSdanielk1977 } 228704f2e68dSdanielk1977 228804f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 228904f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2290f93bbbeaSdanielk1977 zRet = xFunc(pStmt, col); 2291f93bbbeaSdanielk1977 if( zRet ){ 2292f93bbbeaSdanielk1977 Tcl_SetResult(interp, (char *)zRet, 0); 2293f93bbbeaSdanielk1977 } 229404f2e68dSdanielk1977 return TCL_OK; 229504f2e68dSdanielk1977 } 229604f2e68dSdanielk1977 22976b456a2bSdanielk1977 static int test_global_recover( 22986b456a2bSdanielk1977 void * clientData, 22996b456a2bSdanielk1977 Tcl_Interp *interp, 23006b456a2bSdanielk1977 int objc, 23016b456a2bSdanielk1977 Tcl_Obj *CONST objv[] 23026b456a2bSdanielk1977 ){ 23036b456a2bSdanielk1977 #ifndef SQLITE_OMIT_GLOBALRECOVER 23046b456a2bSdanielk1977 int rc; 23056b456a2bSdanielk1977 if( objc!=1 ){ 23066b456a2bSdanielk1977 Tcl_WrongNumArgs(interp, 1, objv, ""); 23076b456a2bSdanielk1977 return TCL_ERROR; 23086b456a2bSdanielk1977 } 23096b456a2bSdanielk1977 rc = sqlite3_global_recover(); 23106b456a2bSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 23116b456a2bSdanielk1977 #endif 23126b456a2bSdanielk1977 return TCL_OK; 23136b456a2bSdanielk1977 } 23146b456a2bSdanielk1977 231504f2e68dSdanielk1977 /* 231604f2e68dSdanielk1977 ** Usage: sqlite3_column_text STMT column 231704f2e68dSdanielk1977 ** 231804f2e68dSdanielk1977 ** Usage: sqlite3_column_decltype STMT column 231904f2e68dSdanielk1977 ** 232004f2e68dSdanielk1977 ** Usage: sqlite3_column_name STMT column 232104f2e68dSdanielk1977 */ 232204f2e68dSdanielk1977 static int test_stmt_utf16( 2323241db313Sdrh void * clientData, /* Pointer to SQLite API function to be invoked */ 232404f2e68dSdanielk1977 Tcl_Interp *interp, 232504f2e68dSdanielk1977 int objc, 232604f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 232704f2e68dSdanielk1977 ){ 23285436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 232904f2e68dSdanielk1977 sqlite3_stmt *pStmt; 233004f2e68dSdanielk1977 int col; 233104f2e68dSdanielk1977 Tcl_Obj *pRet; 233204f2e68dSdanielk1977 const void *zName16; 2333c572ef7fSdanielk1977 const void *(*xFunc)(sqlite3_stmt*, int) = clientData; 233404f2e68dSdanielk1977 233504f2e68dSdanielk1977 if( objc!=3 ){ 233604f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 233704f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 233804f2e68dSdanielk1977 return TCL_ERROR; 233904f2e68dSdanielk1977 } 234004f2e68dSdanielk1977 234104f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 234204f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 234304f2e68dSdanielk1977 234404f2e68dSdanielk1977 zName16 = xFunc(pStmt, col); 2345f93bbbeaSdanielk1977 if( zName16 ){ 234604f2e68dSdanielk1977 pRet = Tcl_NewByteArrayObj(zName16, sqlite3utf16ByteLen(zName16, -1)+2); 234704f2e68dSdanielk1977 Tcl_SetObjResult(interp, pRet); 2348f93bbbeaSdanielk1977 } 23495436dc2dSdrh #endif /* SQLITE_OMIT_UTF16 */ 235004f2e68dSdanielk1977 235104f2e68dSdanielk1977 return TCL_OK; 235204f2e68dSdanielk1977 } 235304f2e68dSdanielk1977 235404f2e68dSdanielk1977 /* 235504f2e68dSdanielk1977 ** Usage: sqlite3_column_int STMT column 235604f2e68dSdanielk1977 ** 235704f2e68dSdanielk1977 ** Usage: sqlite3_column_bytes STMT column 235804f2e68dSdanielk1977 ** 235904f2e68dSdanielk1977 ** Usage: sqlite3_column_bytes16 STMT column 236004f2e68dSdanielk1977 ** 236104f2e68dSdanielk1977 */ 236204f2e68dSdanielk1977 static int test_stmt_int( 2363241db313Sdrh void * clientData, /* Pointer to SQLite API function to be invoked */ 236404f2e68dSdanielk1977 Tcl_Interp *interp, 236504f2e68dSdanielk1977 int objc, 236604f2e68dSdanielk1977 Tcl_Obj *CONST objv[] 236704f2e68dSdanielk1977 ){ 236804f2e68dSdanielk1977 sqlite3_stmt *pStmt; 236904f2e68dSdanielk1977 int col; 2370c572ef7fSdanielk1977 int (*xFunc)(sqlite3_stmt*, int) = clientData; 237104f2e68dSdanielk1977 237204f2e68dSdanielk1977 if( objc!=3 ){ 237304f2e68dSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 237404f2e68dSdanielk1977 Tcl_GetString(objv[0]), " STMT column", 0); 237504f2e68dSdanielk1977 return TCL_ERROR; 237604f2e68dSdanielk1977 } 237704f2e68dSdanielk1977 237804f2e68dSdanielk1977 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 237904f2e68dSdanielk1977 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 238004f2e68dSdanielk1977 238104f2e68dSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(xFunc(pStmt, col))); 238204f2e68dSdanielk1977 return TCL_OK; 238304f2e68dSdanielk1977 } 238404f2e68dSdanielk1977 23859a1d0abeSdanielk1977 /* 23869a1d0abeSdanielk1977 ** Usage: sqlite3OsOpenReadWrite <filename> 23879a1d0abeSdanielk1977 */ 23889a1d0abeSdanielk1977 static int test_sqlite3OsOpenReadWrite( 23899a1d0abeSdanielk1977 void * clientData, 23909a1d0abeSdanielk1977 Tcl_Interp *interp, 23919a1d0abeSdanielk1977 int objc, 23929a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 23939a1d0abeSdanielk1977 ){ 23949a1d0abeSdanielk1977 OsFile * pFile; 23959a1d0abeSdanielk1977 int rc; 23969a1d0abeSdanielk1977 int dummy; 23979a1d0abeSdanielk1977 char zBuf[100]; 239804f2e68dSdanielk1977 23999a1d0abeSdanielk1977 if( objc!=2 ){ 24009a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 24019a1d0abeSdanielk1977 Tcl_GetString(objv[0]), " filename", 0); 24029a1d0abeSdanielk1977 return TCL_ERROR; 24039a1d0abeSdanielk1977 } 24049a1d0abeSdanielk1977 24059a1d0abeSdanielk1977 pFile = sqliteMalloc(sizeof(OsFile)); 24069a1d0abeSdanielk1977 rc = sqlite3OsOpenReadWrite(Tcl_GetString(objv[1]), pFile, &dummy); 24079a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 24089a1d0abeSdanielk1977 sqliteFree(pFile); 24099a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 24109a1d0abeSdanielk1977 return TCL_ERROR; 24119a1d0abeSdanielk1977 } 24129a1d0abeSdanielk1977 makePointerStr(interp, zBuf, pFile); 24139a1d0abeSdanielk1977 Tcl_SetResult(interp, zBuf, 0); 24149a1d0abeSdanielk1977 return TCL_ERROR; 24159a1d0abeSdanielk1977 } 24169a1d0abeSdanielk1977 24179a1d0abeSdanielk1977 /* 24189a1d0abeSdanielk1977 ** Usage: sqlite3OsClose <file handle> 24199a1d0abeSdanielk1977 */ 24209a1d0abeSdanielk1977 static int test_sqlite3OsClose( 24219a1d0abeSdanielk1977 void * clientData, 24229a1d0abeSdanielk1977 Tcl_Interp *interp, 24239a1d0abeSdanielk1977 int objc, 24249a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 24259a1d0abeSdanielk1977 ){ 24269a1d0abeSdanielk1977 OsFile * pFile; 24279a1d0abeSdanielk1977 int rc; 24289a1d0abeSdanielk1977 24299a1d0abeSdanielk1977 if( objc!=2 ){ 24309a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 24319a1d0abeSdanielk1977 Tcl_GetString(objv[0]), " filehandle", 0); 24329a1d0abeSdanielk1977 return TCL_ERROR; 24339a1d0abeSdanielk1977 } 24349a1d0abeSdanielk1977 24359a1d0abeSdanielk1977 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 24369a1d0abeSdanielk1977 return TCL_ERROR; 24379a1d0abeSdanielk1977 } 24389a1d0abeSdanielk1977 rc = sqlite3OsClose(pFile); 24399a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 24409a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 24419a1d0abeSdanielk1977 return TCL_ERROR; 24429a1d0abeSdanielk1977 } 24439a1d0abeSdanielk1977 sqliteFree(pFile); 24449a1d0abeSdanielk1977 return TCL_OK; 24459a1d0abeSdanielk1977 } 24469a1d0abeSdanielk1977 24479a1d0abeSdanielk1977 /* 24489a1d0abeSdanielk1977 ** Usage: sqlite3OsLock <file handle> <locktype> 24499a1d0abeSdanielk1977 */ 24509a1d0abeSdanielk1977 static int test_sqlite3OsLock( 24519a1d0abeSdanielk1977 void * clientData, 24529a1d0abeSdanielk1977 Tcl_Interp *interp, 24539a1d0abeSdanielk1977 int objc, 24549a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 24559a1d0abeSdanielk1977 ){ 24569a1d0abeSdanielk1977 OsFile * pFile; 24579a1d0abeSdanielk1977 int rc; 24589a1d0abeSdanielk1977 24599a1d0abeSdanielk1977 if( objc!=3 ){ 24609a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 24619a1d0abeSdanielk1977 Tcl_GetString(objv[0]), 24629a1d0abeSdanielk1977 " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0); 24639a1d0abeSdanielk1977 return TCL_ERROR; 24649a1d0abeSdanielk1977 } 24659a1d0abeSdanielk1977 24669a1d0abeSdanielk1977 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 24679a1d0abeSdanielk1977 return TCL_ERROR; 24689a1d0abeSdanielk1977 } 24699a1d0abeSdanielk1977 24709a1d0abeSdanielk1977 if( 0==strcmp("SHARED", Tcl_GetString(objv[2])) ){ 24719a1d0abeSdanielk1977 rc = sqlite3OsLock(pFile, SHARED_LOCK); 24729a1d0abeSdanielk1977 } 24739a1d0abeSdanielk1977 else if( 0==strcmp("RESERVED", Tcl_GetString(objv[2])) ){ 24749a1d0abeSdanielk1977 rc = sqlite3OsLock(pFile, RESERVED_LOCK); 24759a1d0abeSdanielk1977 } 24769a1d0abeSdanielk1977 else if( 0==strcmp("PENDING", Tcl_GetString(objv[2])) ){ 24779a1d0abeSdanielk1977 rc = sqlite3OsLock(pFile, PENDING_LOCK); 24789a1d0abeSdanielk1977 } 24799a1d0abeSdanielk1977 else if( 0==strcmp("EXCLUSIVE", Tcl_GetString(objv[2])) ){ 24809a1d0abeSdanielk1977 rc = sqlite3OsLock(pFile, EXCLUSIVE_LOCK); 24819a1d0abeSdanielk1977 }else{ 24829a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 24839a1d0abeSdanielk1977 Tcl_GetString(objv[0]), 24849a1d0abeSdanielk1977 " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0); 24859a1d0abeSdanielk1977 return TCL_ERROR; 24869a1d0abeSdanielk1977 } 24879a1d0abeSdanielk1977 24889a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 24899a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 24909a1d0abeSdanielk1977 return TCL_ERROR; 24919a1d0abeSdanielk1977 } 24929a1d0abeSdanielk1977 return TCL_OK; 24939a1d0abeSdanielk1977 } 24949a1d0abeSdanielk1977 24959a1d0abeSdanielk1977 /* 24969a1d0abeSdanielk1977 ** Usage: sqlite3OsUnlock <file handle> 24979a1d0abeSdanielk1977 */ 24989a1d0abeSdanielk1977 static int test_sqlite3OsUnlock( 24999a1d0abeSdanielk1977 void * clientData, 25009a1d0abeSdanielk1977 Tcl_Interp *interp, 25019a1d0abeSdanielk1977 int objc, 25029a1d0abeSdanielk1977 Tcl_Obj *CONST objv[] 25039a1d0abeSdanielk1977 ){ 25049a1d0abeSdanielk1977 OsFile * pFile; 25059a1d0abeSdanielk1977 int rc; 25069a1d0abeSdanielk1977 25079a1d0abeSdanielk1977 if( objc!=2 ){ 25089a1d0abeSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", 25099a1d0abeSdanielk1977 Tcl_GetString(objv[0]), " filehandle", 0); 25109a1d0abeSdanielk1977 return TCL_ERROR; 25119a1d0abeSdanielk1977 } 25129a1d0abeSdanielk1977 25139a1d0abeSdanielk1977 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 25149a1d0abeSdanielk1977 return TCL_ERROR; 25159a1d0abeSdanielk1977 } 2516a6abd041Sdrh rc = sqlite3OsUnlock(pFile, NO_LOCK); 25179a1d0abeSdanielk1977 if( rc!=SQLITE_OK ){ 25189a1d0abeSdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 25199a1d0abeSdanielk1977 return TCL_ERROR; 25209a1d0abeSdanielk1977 } 25219a1d0abeSdanielk1977 return TCL_OK; 25229a1d0abeSdanielk1977 } 2523d3d39e93Sdrh 2524ab3f9feaSdrh /* 2525ab3f9feaSdrh ** Usage: sqlite3OsTempFileName 2526ab3f9feaSdrh */ 2527ab3f9feaSdrh static int test_sqlite3OsTempFileName( 2528ab3f9feaSdrh void * clientData, 2529ab3f9feaSdrh Tcl_Interp *interp, 2530ab3f9feaSdrh int objc, 2531ab3f9feaSdrh Tcl_Obj *CONST objv[] 2532ab3f9feaSdrh ){ 2533ab3f9feaSdrh char zFile[SQLITE_TEMPNAME_SIZE]; 2534ab3f9feaSdrh int rc; 2535ab3f9feaSdrh 2536ab3f9feaSdrh rc = sqlite3OsTempFileName(zFile); 2537ab3f9feaSdrh if( rc!=SQLITE_OK ){ 2538ab3f9feaSdrh Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 2539ab3f9feaSdrh return TCL_ERROR; 2540ab3f9feaSdrh } 2541ab3f9feaSdrh Tcl_AppendResult(interp, zFile, 0); 2542ab3f9feaSdrh return TCL_OK; 2543ab3f9feaSdrh } 2544d8123366Sdanielk1977 25456622cce3Sdanielk1977 /* 2546cacb208eSdrh ** Usage: sqlite_set_magic DB MAGIC-NUMBER 2547cacb208eSdrh ** 2548cacb208eSdrh ** Set the db->magic value. This is used to test error recovery logic. 2549cacb208eSdrh */ 2550cacb208eSdrh static int sqlite_set_magic( 2551cacb208eSdrh void * clientData, 2552cacb208eSdrh Tcl_Interp *interp, 2553cacb208eSdrh int argc, 2554cacb208eSdrh char **argv 2555cacb208eSdrh ){ 2556cacb208eSdrh sqlite3 *db; 2557cacb208eSdrh if( argc!=3 ){ 2558cacb208eSdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 2559cacb208eSdrh " DB MAGIC", 0); 2560cacb208eSdrh return TCL_ERROR; 2561cacb208eSdrh } 2562cacb208eSdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 2563cacb208eSdrh if( strcmp(argv[2], "SQLITE_MAGIC_OPEN")==0 ){ 2564cacb208eSdrh db->magic = SQLITE_MAGIC_OPEN; 2565cacb208eSdrh }else if( strcmp(argv[2], "SQLITE_MAGIC_CLOSED")==0 ){ 2566cacb208eSdrh db->magic = SQLITE_MAGIC_CLOSED; 2567cacb208eSdrh }else if( strcmp(argv[2], "SQLITE_MAGIC_BUSY")==0 ){ 2568cacb208eSdrh db->magic = SQLITE_MAGIC_BUSY; 2569cacb208eSdrh }else if( strcmp(argv[2], "SQLITE_MAGIC_ERROR")==0 ){ 2570cacb208eSdrh db->magic = SQLITE_MAGIC_ERROR; 2571cacb208eSdrh }else if( Tcl_GetInt(interp, argv[2], &db->magic) ){ 2572cacb208eSdrh return TCL_ERROR; 2573cacb208eSdrh } 2574cacb208eSdrh return TCL_OK; 2575cacb208eSdrh } 2576cacb208eSdrh 2577cacb208eSdrh /* 2578c5cdca61Sdrh ** Usage: sqlite3_interrupt DB 2579c5cdca61Sdrh ** 2580c5cdca61Sdrh ** Trigger an interrupt on DB 2581c5cdca61Sdrh */ 2582c5cdca61Sdrh static int test_interrupt( 2583c5cdca61Sdrh void * clientData, 2584c5cdca61Sdrh Tcl_Interp *interp, 2585c5cdca61Sdrh int argc, 2586c5cdca61Sdrh char **argv 2587c5cdca61Sdrh ){ 2588c5cdca61Sdrh sqlite3 *db; 2589c5cdca61Sdrh if( argc!=2 ){ 2590c5cdca61Sdrh Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB", 0); 2591c5cdca61Sdrh return TCL_ERROR; 2592c5cdca61Sdrh } 2593c5cdca61Sdrh if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 2594c5cdca61Sdrh sqlite3_interrupt(db); 2595c5cdca61Sdrh return TCL_OK; 2596c5cdca61Sdrh } 2597c5cdca61Sdrh 2598c5cdca61Sdrh /* 2599600dd0baSdanielk1977 ** Usage: sqlite3_sleep ms 2600600dd0baSdanielk1977 ** 2601600dd0baSdanielk1977 ** Sleep for the specified number of ms. 2602600dd0baSdanielk1977 */ 2603600dd0baSdanielk1977 #if 0 2604600dd0baSdanielk1977 static int test_sleep( 2605600dd0baSdanielk1977 void * clientData, 2606600dd0baSdanielk1977 Tcl_Interp *interp, 2607600dd0baSdanielk1977 int argc, 2608600dd0baSdanielk1977 char **argv 2609600dd0baSdanielk1977 ){ 2610600dd0baSdanielk1977 sqlite3 *db; 2611600dd0baSdanielk1977 if( argc!=2 ){ 2612600dd0baSdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ms", 0); 2613600dd0baSdanielk1977 return TCL_ERROR; 2614600dd0baSdanielk1977 } 2615600dd0baSdanielk1977 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_sleep(atoi(argv[1])))); 2616600dd0baSdanielk1977 return TCL_OK; 2617600dd0baSdanielk1977 } 2618600dd0baSdanielk1977 #endif 2619600dd0baSdanielk1977 2620600dd0baSdanielk1977 /* 26219636c4e1Sdanielk1977 ** Usage: sqlite_delete_function DB function-name 26229636c4e1Sdanielk1977 ** 26239636c4e1Sdanielk1977 ** Delete the user function 'function-name' from database handle DB. It 26249636c4e1Sdanielk1977 ** is assumed that the user function was created as UTF8, any number of 26259636c4e1Sdanielk1977 ** arguments (the way the TCL interface does it). 26269636c4e1Sdanielk1977 */ 26279636c4e1Sdanielk1977 static int delete_function( 26289636c4e1Sdanielk1977 void * clientData, 26299636c4e1Sdanielk1977 Tcl_Interp *interp, 26309636c4e1Sdanielk1977 int argc, 26319636c4e1Sdanielk1977 char **argv 26329636c4e1Sdanielk1977 ){ 26339636c4e1Sdanielk1977 int rc; 26349636c4e1Sdanielk1977 sqlite3 *db; 26359636c4e1Sdanielk1977 if( argc!=3 ){ 26369636c4e1Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 26379636c4e1Sdanielk1977 " DB function-name", 0); 26389636c4e1Sdanielk1977 return TCL_ERROR; 26399636c4e1Sdanielk1977 } 26409636c4e1Sdanielk1977 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 26419636c4e1Sdanielk1977 rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 0, 0, 0); 26429636c4e1Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 26439636c4e1Sdanielk1977 return TCL_OK; 26449636c4e1Sdanielk1977 } 26459636c4e1Sdanielk1977 26469636c4e1Sdanielk1977 /* 26479636c4e1Sdanielk1977 ** Usage: sqlite_delete_collation DB collation-name 26489636c4e1Sdanielk1977 ** 26499636c4e1Sdanielk1977 ** Delete the collation sequence 'collation-name' from database handle 26509636c4e1Sdanielk1977 ** DB. It is assumed that the collation sequence was created as UTF8 (the 26519636c4e1Sdanielk1977 ** way the TCL interface does it). 26529636c4e1Sdanielk1977 */ 26539636c4e1Sdanielk1977 static int delete_collation( 26549636c4e1Sdanielk1977 void * clientData, 26559636c4e1Sdanielk1977 Tcl_Interp *interp, 26569636c4e1Sdanielk1977 int argc, 26579636c4e1Sdanielk1977 char **argv 26589636c4e1Sdanielk1977 ){ 26599636c4e1Sdanielk1977 int rc; 26609636c4e1Sdanielk1977 sqlite3 *db; 26619636c4e1Sdanielk1977 if( argc!=3 ){ 26629636c4e1Sdanielk1977 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 26639636c4e1Sdanielk1977 " DB function-name", 0); 26649636c4e1Sdanielk1977 return TCL_ERROR; 26659636c4e1Sdanielk1977 } 26669636c4e1Sdanielk1977 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 26679636c4e1Sdanielk1977 rc = sqlite3_create_collation(db, argv[2], SQLITE_UTF8, 0, 0); 26689636c4e1Sdanielk1977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 26699636c4e1Sdanielk1977 return TCL_OK; 26709636c4e1Sdanielk1977 } 26719636c4e1Sdanielk1977 26729636c4e1Sdanielk1977 /* 267392febd92Sdrh ** Usage: tcl_variable_type VARIABLENAME 267492febd92Sdrh ** 267592febd92Sdrh ** Return the name of the internal representation for the 267692febd92Sdrh ** value of the given variable. 267792febd92Sdrh */ 267892febd92Sdrh static int tcl_variable_type( 267992febd92Sdrh void * clientData, 268092febd92Sdrh Tcl_Interp *interp, 268192febd92Sdrh int objc, 268292febd92Sdrh Tcl_Obj *CONST objv[] 268392febd92Sdrh ){ 268492febd92Sdrh Tcl_Obj *pVar; 268592febd92Sdrh if( objc!=2 ){ 268692febd92Sdrh Tcl_WrongNumArgs(interp, 1, objv, "VARIABLE"); 268792febd92Sdrh return TCL_ERROR; 268892febd92Sdrh } 268992febd92Sdrh pVar = Tcl_GetVar2Ex(interp, Tcl_GetString(objv[1]), 0, TCL_LEAVE_ERR_MSG); 269092febd92Sdrh if( pVar==0 ) return TCL_ERROR; 269192febd92Sdrh if( pVar->typePtr ){ 269292febd92Sdrh Tcl_SetObjResult(interp, Tcl_NewStringObj(pVar->typePtr->name, -1)); 269392febd92Sdrh } 269492febd92Sdrh return TCL_OK; 269592febd92Sdrh } 269692febd92Sdrh 269792febd92Sdrh /* 269827d258a3Sdrh ** This routine sets entries in the global ::sqlite_options() array variable 269927d258a3Sdrh ** according to the compile-time configuration of the database. Test 270027d258a3Sdrh ** procedures use this to determine when tests should be omitted. 270127d258a3Sdrh */ 270227d258a3Sdrh static void set_options(Tcl_Interp *interp){ 270375f86a4bSdrh #ifdef SQLITE_32BIT_ROWID 270475f86a4bSdrh Tcl_SetVar2(interp, "sqlite_options", "rowid32", "1", TCL_GLOBAL_ONLY); 270575f86a4bSdrh #else 270675f86a4bSdrh Tcl_SetVar2(interp, "sqlite_options", "rowid32", "0", TCL_GLOBAL_ONLY); 270775f86a4bSdrh #endif 270875f86a4bSdrh 27091c8c23ccSdanielk1977 #ifdef SQLITE_OMIT_ALTERTABLE 27101c8c23ccSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY); 27111c8c23ccSdanielk1977 #else 27121c8c23ccSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY); 27131c8c23ccSdanielk1977 #endif 271413d7042aSdrh 271513d7042aSdrh #ifdef SQLITE_OMIT_AUTHORIZATION 271613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "auth", "0", TCL_GLOBAL_ONLY); 271713d7042aSdrh #else 271813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "auth", "1", TCL_GLOBAL_ONLY); 271913d7042aSdrh #endif 272013d7042aSdrh 2721f3388144Sdrh #ifdef SQLITE_OMIT_AUTOINCREMENT 2722f3388144Sdrh Tcl_SetVar2(interp, "sqlite_options", "autoinc", "0", TCL_GLOBAL_ONLY); 2723f3388144Sdrh #else 2724f3388144Sdrh Tcl_SetVar2(interp, "sqlite_options", "autoinc", "1", TCL_GLOBAL_ONLY); 2725f3388144Sdrh #endif 2726f3388144Sdrh 272745901d62Sdanielk1977 #ifdef SQLITE_OMIT_AUTOVACUUM 272845901d62Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "0", TCL_GLOBAL_ONLY); 272945901d62Sdanielk1977 #else 273045901d62Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "1", TCL_GLOBAL_ONLY); 2731f3388144Sdrh #endif /* SQLITE_OMIT_AUTOVACUUM */ 27324d36b81eSdanielk1977 #if !defined(SQLITE_DEFAULT_AUTOVACUUM) || SQLITE_DEFAULT_AUTOVACUUM==0 273345901d62Sdanielk1977 Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","0",TCL_GLOBAL_ONLY); 273445901d62Sdanielk1977 #else 273545901d62Sdanielk1977 Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","1",TCL_GLOBAL_ONLY); 273645901d62Sdanielk1977 #endif 273713d7042aSdrh 273813d7042aSdrh #ifdef SQLITE_OMIT_BLOB_LITERAL 273913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "bloblit", "0", TCL_GLOBAL_ONLY); 274013d7042aSdrh #else 274113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY); 274213d7042aSdrh #endif 274313d7042aSdrh 2744ccae6026Sdrh #ifdef SQLITE_OMIT_COMPLETE 2745ccae6026Sdrh Tcl_SetVar2(interp, "sqlite_options", "complete", "0", TCL_GLOBAL_ONLY); 2746ccae6026Sdrh #else 2747ccae6026Sdrh Tcl_SetVar2(interp, "sqlite_options", "complete", "1", TCL_GLOBAL_ONLY); 2748ccae6026Sdrh #endif 2749ccae6026Sdrh 275013d7042aSdrh #ifdef SQLITE_OMIT_COMPOUND_SELECT 275113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "compound", "0", TCL_GLOBAL_ONLY); 275213d7042aSdrh #else 275313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "compound", "1", TCL_GLOBAL_ONLY); 275413d7042aSdrh #endif 275513d7042aSdrh 275613d7042aSdrh #ifdef SQLITE_OMIT_CONFLICT_CLAUSE 275713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "conflict", "0", TCL_GLOBAL_ONLY); 275813d7042aSdrh #else 275913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "conflict", "1", TCL_GLOBAL_ONLY); 276013d7042aSdrh #endif 276113d7042aSdrh 276213d7042aSdrh #ifdef SQLITE_OMIT_DATETIME_FUNCS 276313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "datetime", "0", TCL_GLOBAL_ONLY); 276413d7042aSdrh #else 276513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "datetime", "1", TCL_GLOBAL_ONLY); 276613d7042aSdrh #endif 276713d7042aSdrh 276813d7042aSdrh #ifdef SQLITE_OMIT_EXPLAIN 276913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "explain", "0", TCL_GLOBAL_ONLY); 277013d7042aSdrh #else 277113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "explain", "1", TCL_GLOBAL_ONLY); 277213d7042aSdrh #endif 277313d7042aSdrh 277413d7042aSdrh #ifdef SQLITE_OMIT_FLOATING_POINT 277513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "0", TCL_GLOBAL_ONLY); 277613d7042aSdrh #else 277713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "1", TCL_GLOBAL_ONLY); 277813d7042aSdrh #endif 277913d7042aSdrh 278013d7042aSdrh #ifdef SQLITE_OMIT_FOREIGN_KEY 278113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "0", TCL_GLOBAL_ONLY); 278213d7042aSdrh #else 278313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "1", TCL_GLOBAL_ONLY); 278413d7042aSdrh #endif 278513d7042aSdrh 27866b456a2bSdanielk1977 #ifdef SQLITE_OMIT_GLOBALRECOVER 27876b456a2bSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "0", TCL_GLOBAL_ONLY); 27886b456a2bSdanielk1977 #else 27896b456a2bSdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "1", TCL_GLOBAL_ONLY); 27906b456a2bSdanielk1977 #endif 27916b456a2bSdanielk1977 279213d7042aSdrh #ifdef SQLITE_OMIT_INTEGRITY_CHECK 279313d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "integrityck", "0", TCL_GLOBAL_ONLY); 279413d7042aSdrh #else 279513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "integrityck", "1", TCL_GLOBAL_ONLY); 279613d7042aSdrh #endif 279713d7042aSdrh 279813d7042aSdrh #ifdef SQLITE_OMIT_MEMORYDB 279913d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "memorydb", "0", TCL_GLOBAL_ONLY); 280013d7042aSdrh #else 280113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "memorydb", "1", TCL_GLOBAL_ONLY); 280213d7042aSdrh #endif 280313d7042aSdrh 280413d7042aSdrh #ifdef SQLITE_OMIT_PAGER_PRAGMAS 280513d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "0", TCL_GLOBAL_ONLY); 280613d7042aSdrh #else 280713d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "1", TCL_GLOBAL_ONLY); 280813d7042aSdrh #endif 280913d7042aSdrh 2810bf21627bSdrh #if defined(SQLITE_OMIT_PRAGMA) || defined(SQLITE_OMIT_FLAG_PRAGMAS) 281113d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pragma", "0", TCL_GLOBAL_ONLY); 281213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "integrityck", "0", TCL_GLOBAL_ONLY); 281313d7042aSdrh #else 281413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "pragma", "1", TCL_GLOBAL_ONLY); 281513d7042aSdrh #endif 281613d7042aSdrh 281713d7042aSdrh #ifdef SQLITE_OMIT_PROGRESS_CALLBACK 281813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "progress", "0", TCL_GLOBAL_ONLY); 281913d7042aSdrh #else 282013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "progress", "1", TCL_GLOBAL_ONLY); 282113d7042aSdrh #endif 282213d7042aSdrh 282313d7042aSdrh #ifdef SQLITE_OMIT_REINDEX 282413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "reindex", "0", TCL_GLOBAL_ONLY); 282513d7042aSdrh #else 282613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "reindex", "1", TCL_GLOBAL_ONLY); 282713d7042aSdrh #endif 282813d7042aSdrh 282913d7042aSdrh #ifdef SQLITE_OMIT_SCHEMA_PRAGMAS 283013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "0", TCL_GLOBAL_ONLY); 283113d7042aSdrh #else 283213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "1", TCL_GLOBAL_ONLY); 283313d7042aSdrh #endif 283413d7042aSdrh 283513d7042aSdrh #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS 283613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_version", "0", TCL_GLOBAL_ONLY); 283713d7042aSdrh #else 283813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY); 283913d7042aSdrh #endif 284013d7042aSdrh 28413e8c37e7Sdanielk1977 #ifdef SQLITE_OMIT_SUBQUERY 28423e8c37e7Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "subquery", "0", TCL_GLOBAL_ONLY); 28433e8c37e7Sdanielk1977 #else 28443e8c37e7Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "subquery", "1", TCL_GLOBAL_ONLY); 28453e8c37e7Sdanielk1977 #endif 28463e8c37e7Sdanielk1977 284713d7042aSdrh #ifdef SQLITE_OMIT_TCL_VARIABLE 284813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "tclvar", "0", TCL_GLOBAL_ONLY); 284913d7042aSdrh #else 285013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "tclvar", "1", TCL_GLOBAL_ONLY); 285113d7042aSdrh #endif 285213d7042aSdrh 285313d7042aSdrh #if defined(THREADSAFE) && THREADSAFE 285413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "1", TCL_GLOBAL_ONLY); 285513d7042aSdrh #else 285613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "0", TCL_GLOBAL_ONLY); 285713d7042aSdrh #endif 285813d7042aSdrh 285913d7042aSdrh #ifdef SQLITE_OMIT_TRIGGER 286013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "trigger", "0", TCL_GLOBAL_ONLY); 286113d7042aSdrh #else 286213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "trigger", "1", TCL_GLOBAL_ONLY); 286313d7042aSdrh #endif 286413d7042aSdrh 2865*53c0f748Sdanielk1977 #ifdef SQLITE_OMIT_TEMPDB 2866*53c0f748Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "tempdb", "0", TCL_GLOBAL_ONLY); 2867*53c0f748Sdanielk1977 #else 2868*53c0f748Sdanielk1977 Tcl_SetVar2(interp, "sqlite_options", "tempdb", "1", TCL_GLOBAL_ONLY); 2869*53c0f748Sdanielk1977 #endif 2870*53c0f748Sdanielk1977 287113d7042aSdrh #ifdef SQLITE_OMIT_UTF16 287213d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY); 287313d7042aSdrh #else 287413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "utf16", "1", TCL_GLOBAL_ONLY); 287513d7042aSdrh #endif 287613d7042aSdrh 287713d7042aSdrh #ifdef SQLITE_OMIT_VACUUM 287813d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "vacuum", "0", TCL_GLOBAL_ONLY); 287913d7042aSdrh #else 288013d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "vacuum", "1", TCL_GLOBAL_ONLY); 288113d7042aSdrh #endif 288213d7042aSdrh 288313d7042aSdrh #ifdef SQLITE_OMIT_VIEW 288413d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "view", "0", TCL_GLOBAL_ONLY); 288513d7042aSdrh #else 288613d7042aSdrh Tcl_SetVar2(interp, "sqlite_options", "view", "1", TCL_GLOBAL_ONLY); 288713d7042aSdrh #endif 288827d258a3Sdrh } 288927d258a3Sdrh 289027d258a3Sdrh /* 2891d1bf3512Sdrh ** Register commands with the TCL interpreter. 2892d1bf3512Sdrh */ 2893d1bf3512Sdrh int Sqlitetest1_Init(Tcl_Interp *interp){ 28946f8a503dSdanielk1977 extern int sqlite3_search_count; 28956f8a503dSdanielk1977 extern int sqlite3_interrupt_count; 28966f8a503dSdanielk1977 extern int sqlite3_open_file_count; 28976bf89570Sdrh extern int sqlite3_sort_count; 28986f8a503dSdanielk1977 extern int sqlite3_current_time; 2899c2eef3b3Sdrh static struct { 2900c2eef3b3Sdrh char *zName; 2901c2eef3b3Sdrh Tcl_CmdProc *xProc; 2902c2eef3b3Sdrh } aCmd[] = { 29036f8a503dSdanielk1977 { "sqlite3_mprintf_int", (Tcl_CmdProc*)sqlite3_mprintf_int }, 2904e9707671Sdrh { "sqlite3_mprintf_int64", (Tcl_CmdProc*)sqlite3_mprintf_int64 }, 29056f8a503dSdanielk1977 { "sqlite3_mprintf_str", (Tcl_CmdProc*)sqlite3_mprintf_str }, 2906e29b1a05Sdrh { "sqlite3_mprintf_stronly", (Tcl_CmdProc*)sqlite3_mprintf_stronly}, 29076f8a503dSdanielk1977 { "sqlite3_mprintf_double", (Tcl_CmdProc*)sqlite3_mprintf_double }, 29086f8a503dSdanielk1977 { "sqlite3_mprintf_scaled", (Tcl_CmdProc*)sqlite3_mprintf_scaled }, 29096f8a503dSdanielk1977 { "sqlite3_mprintf_z_test", (Tcl_CmdProc*)test_mprintf_z }, 29106f8a503dSdanielk1977 { "sqlite3_last_insert_rowid", (Tcl_CmdProc*)test_last_rowid }, 29116f8a503dSdanielk1977 { "sqlite3_exec_printf", (Tcl_CmdProc*)test_exec_printf }, 29126f8a503dSdanielk1977 { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, 29136f8a503dSdanielk1977 { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, 29146f8a503dSdanielk1977 { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, 29156f8a503dSdanielk1977 { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, 2916c2eef3b3Sdrh { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, 2917c2eef3b3Sdrh { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, 29182c336549Sdanielk1977 #ifdef SQLITE_MEMDEBUG 2919c2eef3b3Sdrh { "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail }, 2920c2eef3b3Sdrh { "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat }, 2921c2eef3b3Sdrh #endif 292296fc5fe6Sdanielk1977 { "sqlite_bind", (Tcl_CmdProc*)test_bind }, 292399ee3600Sdrh { "breakpoint", (Tcl_CmdProc*)test_breakpoint }, 292425d6543dSdrh { "sqlite3_key", (Tcl_CmdProc*)test_key }, 292525d6543dSdrh { "sqlite3_rekey", (Tcl_CmdProc*)test_rekey }, 2926cacb208eSdrh { "sqlite_set_magic", (Tcl_CmdProc*)sqlite_set_magic }, 2927c5cdca61Sdrh { "sqlite3_interrupt", (Tcl_CmdProc*)test_interrupt }, 2928600dd0baSdanielk1977 #if 0 2929600dd0baSdanielk1977 { "sqlite3_sleep", (Tcl_CmdProc*)test_sleep }, 2930600dd0baSdanielk1977 #endif 29319636c4e1Sdanielk1977 { "sqlite_delete_function", (Tcl_CmdProc*)delete_function }, 29329636c4e1Sdanielk1977 { "sqlite_delete_collation", (Tcl_CmdProc*)delete_collation } 2933c2eef3b3Sdrh }; 293451e3d8e2Sdanielk1977 static struct { 293551e3d8e2Sdanielk1977 char *zName; 293651e3d8e2Sdanielk1977 Tcl_ObjCmdProc *xProc; 293704f2e68dSdanielk1977 void *clientData; 293851e3d8e2Sdanielk1977 } aObjCmd[] = { 2939241db313Sdrh { "sqlite3_bind_int", test_bind_int, 0 }, 294004f2e68dSdanielk1977 { "sqlite3_bind_int64", test_bind_int64, 0 }, 294104f2e68dSdanielk1977 { "sqlite3_bind_double", test_bind_double, 0 }, 294204f2e68dSdanielk1977 { "sqlite3_bind_null", test_bind_null ,0 }, 294304f2e68dSdanielk1977 { "sqlite3_bind_text", test_bind_text ,0 }, 294404f2e68dSdanielk1977 { "sqlite3_bind_text16", test_bind_text16 ,0 }, 294504f2e68dSdanielk1977 { "sqlite3_bind_blob", test_bind_blob ,0 }, 294675f6a032Sdrh { "sqlite3_bind_parameter_count", test_bind_parameter_count, 0}, 2947895d7472Sdrh { "sqlite3_bind_parameter_name", test_bind_parameter_name, 0}, 2948fa6bc000Sdrh { "sqlite3_bind_parameter_index", test_bind_parameter_index, 0}, 2949600dd0baSdanielk1977 #if 0 2950600dd0baSdanielk1977 { "sqlite3_clear_bindings", test_clear_bindings, 0}, 2951600dd0baSdanielk1977 #endif 295204f2e68dSdanielk1977 { "sqlite3_errcode", test_errcode ,0 }, 295304f2e68dSdanielk1977 { "sqlite3_errmsg", test_errmsg ,0 }, 295404f2e68dSdanielk1977 { "sqlite3_errmsg16", test_errmsg16 ,0 }, 295504f2e68dSdanielk1977 { "sqlite3_open", test_open ,0 }, 295604f2e68dSdanielk1977 { "sqlite3_open16", test_open16 ,0 }, 2957bc6ada41Sdanielk1977 { "sqlite3_complete16", test_complete16 ,0 }, 295804f2e68dSdanielk1977 295904f2e68dSdanielk1977 { "sqlite3_prepare", test_prepare ,0 }, 296004f2e68dSdanielk1977 { "sqlite3_prepare16", test_prepare16 ,0 }, 296104f2e68dSdanielk1977 { "sqlite3_finalize", test_finalize ,0 }, 296204f2e68dSdanielk1977 { "sqlite3_reset", test_reset ,0 }, 2963d89bd007Sdrh { "sqlite3_expired", test_expired ,0 }, 2964fbcd585fSdanielk1977 { "sqlite3_changes", test_changes ,0 }, 296504f2e68dSdanielk1977 { "sqlite3_step", test_step ,0 }, 296604f2e68dSdanielk1977 296704f2e68dSdanielk1977 /* sqlite3_column_*() API */ 296804f2e68dSdanielk1977 { "sqlite3_column_count", test_column_count ,0 }, 296904f2e68dSdanielk1977 { "sqlite3_data_count", test_data_count ,0 }, 297004f2e68dSdanielk1977 { "sqlite3_column_type", test_column_type ,0 }, 2971ea61b2c4Sdanielk1977 { "sqlite3_column_blob", test_column_blob ,0 }, 297204f2e68dSdanielk1977 { "sqlite3_column_double", test_column_double ,0 }, 297304f2e68dSdanielk1977 { "sqlite3_column_int64", test_column_int64 ,0 }, 297404f2e68dSdanielk1977 { "sqlite3_column_text", test_stmt_utf8, sqlite3_column_text }, 297504f2e68dSdanielk1977 { "sqlite3_column_decltype", test_stmt_utf8, sqlite3_column_decltype }, 297604f2e68dSdanielk1977 { "sqlite3_column_name", test_stmt_utf8, sqlite3_column_name }, 29776c62608fSdrh { "sqlite3_column_int", test_stmt_int, sqlite3_column_int }, 29786c62608fSdrh { "sqlite3_column_bytes", test_stmt_int, sqlite3_column_bytes }, 29796c62608fSdrh #ifndef SQLITE_OMIT_UTF16 29806c62608fSdrh { "sqlite3_column_bytes16", test_stmt_int, sqlite3_column_bytes16 }, 298104f2e68dSdanielk1977 { "sqlite3_column_text16", test_stmt_utf16, sqlite3_column_text16 }, 298204f2e68dSdanielk1977 { "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16}, 298304f2e68dSdanielk1977 { "sqlite3_column_name16", test_stmt_utf16, sqlite3_column_name16 }, 29846c62608fSdrh #endif 29856b456a2bSdanielk1977 { "sqlite3_global_recover", test_global_recover, 0 }, 298604f2e68dSdanielk1977 29879a1d0abeSdanielk1977 /* Functions from os.h */ 29889a1d0abeSdanielk1977 { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 }, 29899a1d0abeSdanielk1977 { "sqlite3OsClose", test_sqlite3OsClose, 0 }, 29909a1d0abeSdanielk1977 { "sqlite3OsLock", test_sqlite3OsLock, 0 }, 2991ab3f9feaSdrh { "sqlite3OsTempFileName", test_sqlite3OsTempFileName, 0 }, 2992312d6b36Sdanielk1977 2993312d6b36Sdanielk1977 /* Custom test interfaces */ 29949a1d0abeSdanielk1977 { "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 }, 29955436dc2dSdrh #ifndef SQLITE_OMIT_UTF16 29964e6af134Sdanielk1977 { "add_test_collate", test_collate, 0 }, 2997312d6b36Sdanielk1977 { "add_test_collate_needed", test_collate_needed, 0 }, 2998c8e9a2dfSdanielk1977 { "add_test_function", test_function, 0 }, 29995436dc2dSdrh #endif 3000c8e9a2dfSdanielk1977 { "sqlite3_crashparams", sqlite3_crashparams, 0 }, 3001312d6b36Sdanielk1977 { "sqlite3_test_errstr", test_errstr, 0 }, 300292febd92Sdrh { "tcl_variable_type", tcl_variable_type, 0 }, 300351e3d8e2Sdanielk1977 }; 30041398ad36Sdrh static int bitmask_size = sizeof(Bitmask)*8; 3005c2eef3b3Sdrh int i; 30062ac3ee97Sdrh extern int sqlite3_os_trace; 3007b851b2c9Sdrh extern int sqlite3_sync_count, sqlite3_fullsync_count; 3008c2eef3b3Sdrh 30091398ad36Sdrh 3010c2eef3b3Sdrh for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ 3011c2eef3b3Sdrh Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); 3012c2eef3b3Sdrh } 301351e3d8e2Sdanielk1977 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ 3014c572ef7fSdanielk1977 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 3015c572ef7fSdanielk1977 aObjCmd[i].xProc, aObjCmd[i].clientData, 0); 301651e3d8e2Sdanielk1977 } 30176490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_search_count", 30186f8a503dSdanielk1977 (char*)&sqlite3_search_count, TCL_LINK_INT); 30196bf89570Sdrh Tcl_LinkVar(interp, "sqlite_sort_count", 30206bf89570Sdrh (char*)&sqlite3_sort_count, TCL_LINK_INT); 30216490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_interrupt_count", 30226f8a503dSdanielk1977 (char*)&sqlite3_interrupt_count, TCL_LINK_INT); 30236490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_open_file_count", 30246f8a503dSdanielk1977 (char*)&sqlite3_open_file_count, TCL_LINK_INT); 30256490bebdSdanielk1977 Tcl_LinkVar(interp, "sqlite_current_time", 30266f8a503dSdanielk1977 (char*)&sqlite3_current_time, TCL_LINK_INT); 30272ac3ee97Sdrh Tcl_LinkVar(interp, "sqlite_os_trace", 30282ac3ee97Sdrh (char*)&sqlite3_os_trace, TCL_LINK_INT); 30297c972decSdrh Tcl_LinkVar(interp, "sqlite_static_bind_value", 30307c972decSdrh (char*)&sqlite_static_bind_value, TCL_LINK_STRING); 3031ab3f9feaSdrh Tcl_LinkVar(interp, "sqlite_temp_directory", 3032effd02bcSdrh (char*)&sqlite3_temp_directory, TCL_LINK_STRING); 30331398ad36Sdrh Tcl_LinkVar(interp, "bitmask_size", 30341398ad36Sdrh (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); 3035748f763fSdrh #if OS_UNIX 3036b851b2c9Sdrh Tcl_LinkVar(interp, "sqlite_sync_count", 3037b851b2c9Sdrh (char*)&sqlite3_sync_count, TCL_LINK_INT); 3038b851b2c9Sdrh Tcl_LinkVar(interp, "sqlite_fullsync_count", 3039b851b2c9Sdrh (char*)&sqlite3_fullsync_count, TCL_LINK_INT); 3040748f763fSdrh #endif /* OS_UNIX */ 304127d258a3Sdrh set_options(interp); 3042d1bf3512Sdrh return TCL_OK; 3043d1bf3512Sdrh } 3044