1 /* 2 ** 2001 September 15 3 ** 4 ** The author disclaims copyright to this source code. In place of 5 ** a legal notice, here is a blessing: 6 ** 7 ** May you do good and not evil. 8 ** May you find forgiveness for yourself and forgive others. 9 ** May you share freely, never taking more than you give. 10 ** 11 ************************************************************************* 12 ** Code for testing all sorts of SQLite interfaces. This code 13 ** is not included in the SQLite library. It is used for automated 14 ** testing of the SQLite library. 15 ** 16 ** $Id: test1.c,v 1.223 2006/10/19 20:27:59 shess Exp $ 17 */ 18 #include "sqliteInt.h" 19 #include "tcl.h" 20 #include "os.h" 21 #include <stdlib.h> 22 #include <string.h> 23 24 /* 25 ** This is a copy of the first part of the SqliteDb structure in 26 ** tclsqlite.c. We need it here so that the get_sqlite_pointer routine 27 ** can extract the sqlite3* pointer from an existing Tcl SQLite 28 ** connection. 29 */ 30 struct SqliteDb { 31 sqlite3 *db; 32 }; 33 34 /* 35 ** A TCL command that returns the address of the sqlite* pointer 36 ** for an sqlite connection instance. Bad things happen if the 37 ** input is not an sqlite connection. 38 */ 39 static int get_sqlite_pointer( 40 void * clientData, 41 Tcl_Interp *interp, 42 int objc, 43 Tcl_Obj *CONST objv[] 44 ){ 45 struct SqliteDb *p; 46 Tcl_CmdInfo cmdInfo; 47 char zBuf[100]; 48 if( objc!=2 ){ 49 Tcl_WrongNumArgs(interp, 1, objv, "SQLITE-CONNECTION"); 50 return TCL_ERROR; 51 } 52 if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){ 53 Tcl_AppendResult(interp, "command not found: ", 54 Tcl_GetString(objv[1]), (char*)0); 55 return TCL_ERROR; 56 } 57 p = (struct SqliteDb*)cmdInfo.objClientData; 58 sprintf(zBuf, "%p", p->db); 59 if( strncmp(zBuf,"0x",2) ){ 60 sprintf(zBuf, "0x%p", p->db); 61 } 62 Tcl_AppendResult(interp, zBuf, 0); 63 return TCL_OK; 64 } 65 66 const char *sqlite3TestErrorName(int rc){ 67 const char *zName = 0; 68 switch( rc & 0xff ){ 69 case SQLITE_OK: zName = "SQLITE_OK"; break; 70 case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; 71 case SQLITE_PERM: zName = "SQLITE_PERM"; break; 72 case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; 73 case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; 74 case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; 75 case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; 76 case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; 77 case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; 78 case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; 79 case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; 80 case SQLITE_FULL: zName = "SQLITE_FULL"; break; 81 case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; 82 case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; 83 case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; 84 case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; 85 case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; 86 case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; 87 case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; 88 case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; 89 case SQLITE_AUTH: zName = "SQLITE_AUTH"; break; 90 case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break; 91 case SQLITE_RANGE: zName = "SQLITE_RANGE"; break; 92 case SQLITE_ROW: zName = "SQLITE_ROW"; break; 93 case SQLITE_DONE: zName = "SQLITE_DONE"; break; 94 case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break; 95 default: zName = "SQLITE_Unknown"; break; 96 } 97 return zName; 98 } 99 #define errorName sqlite3TestErrorName 100 101 /* 102 ** Convert an sqlite3_stmt* into an sqlite3*. This depends on the 103 ** fact that the sqlite3* is the first field in the Vdbe structure. 104 */ 105 #define StmtToDb(X) sqlite3_db_handle(X) 106 107 /* 108 ** Check a return value to make sure it agrees with the results 109 ** from sqlite3_errcode. 110 */ 111 int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){ 112 if( rc!=SQLITE_MISUSE && rc!=SQLITE_OK && sqlite3_errcode(db)!=rc ){ 113 char zBuf[200]; 114 int r2 = sqlite3_errcode(db); 115 sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)", 116 errorName(rc), rc, errorName(r2), r2); 117 Tcl_ResetResult(interp); 118 Tcl_AppendResult(interp, zBuf, 0); 119 return 1; 120 } 121 return 0; 122 } 123 124 /* 125 ** Decode a pointer to an sqlite3 object. 126 */ 127 static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){ 128 *ppDb = (sqlite3*)sqlite3TextToPtr(zA); 129 return TCL_OK; 130 } 131 132 /* 133 ** Decode a pointer to an sqlite3_stmt object. 134 */ 135 static int getStmtPointer( 136 Tcl_Interp *interp, 137 const char *zArg, 138 sqlite3_stmt **ppStmt 139 ){ 140 *ppStmt = (sqlite3_stmt*)sqlite3TextToPtr(zArg); 141 return TCL_OK; 142 } 143 144 /* 145 ** Decode a pointer to an sqlite3_stmt object. 146 */ 147 static int getFilePointer( 148 Tcl_Interp *interp, 149 const char *zArg, 150 OsFile **ppFile 151 ){ 152 *ppFile = (OsFile*)sqlite3TextToPtr(zArg); 153 return TCL_OK; 154 } 155 156 /* 157 ** Generate a text representation of a pointer that can be understood 158 ** by the getDbPointer and getVmPointer routines above. 159 ** 160 ** The problem is, on some machines (Solaris) if you do a printf with 161 ** "%p" you cannot turn around and do a scanf with the same "%p" and 162 ** get your pointer back. You have to prepend a "0x" before it will 163 ** work. Or at least that is what is reported to me (drh). But this 164 ** behavior varies from machine to machine. The solution used her is 165 ** to test the string right after it is generated to see if it can be 166 ** understood by scanf, and if not, try prepending an "0x" to see if 167 ** that helps. If nothing works, a fatal error is generated. 168 */ 169 int sqlite3TestMakePointerStr(Tcl_Interp *interp, char *zPtr, void *p){ 170 sqlite3_snprintf(100, zPtr, "%p", p); 171 return TCL_OK; 172 } 173 174 /* 175 ** The callback routine for sqlite3_exec_printf(). 176 */ 177 static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){ 178 Tcl_DString *str = (Tcl_DString*)pArg; 179 int i; 180 181 if( Tcl_DStringLength(str)==0 ){ 182 for(i=0; i<argc; i++){ 183 Tcl_DStringAppendElement(str, name[i] ? name[i] : "NULL"); 184 } 185 } 186 for(i=0; i<argc; i++){ 187 Tcl_DStringAppendElement(str, argv[i] ? argv[i] : "NULL"); 188 } 189 return 0; 190 } 191 192 /* 193 ** Usage: sqlite3_exec_printf DB FORMAT STRING 194 ** 195 ** Invoke the sqlite3_exec_printf() interface using the open database 196 ** DB. The SQL is the string FORMAT. The format string should contain 197 ** one %s or %q. STRING is the value inserted into %s or %q. 198 */ 199 static int test_exec_printf( 200 void *NotUsed, 201 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 202 int argc, /* Number of arguments */ 203 char **argv /* Text of each argument */ 204 ){ 205 sqlite3 *db; 206 Tcl_DString str; 207 int rc; 208 char *zErr = 0; 209 char *zSql; 210 char zBuf[30]; 211 if( argc!=4 ){ 212 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 213 " DB FORMAT STRING", 0); 214 return TCL_ERROR; 215 } 216 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 217 Tcl_DStringInit(&str); 218 zSql = sqlite3_mprintf(argv[2], argv[3]); 219 rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr); 220 sqlite3_free(zSql); 221 sprintf(zBuf, "%d", rc); 222 Tcl_AppendElement(interp, zBuf); 223 Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr); 224 Tcl_DStringFree(&str); 225 if( zErr ) sqlite3_free(zErr); 226 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 227 return TCL_OK; 228 } 229 230 /* 231 ** Usage: sqlite3_mprintf_z_test SEPARATOR ARG0 ARG1 ... 232 ** 233 ** Test the %z format of sqliteMPrintf(). Use multiple mprintf() calls to 234 ** concatenate arg0 through argn using separator as the separator. 235 ** Return the result. 236 */ 237 static int test_mprintf_z( 238 void *NotUsed, 239 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 240 int argc, /* Number of arguments */ 241 char **argv /* Text of each argument */ 242 ){ 243 char *zResult = 0; 244 int i; 245 246 for(i=2; i<argc; i++){ 247 zResult = sqlite3MPrintf("%z%s%s", zResult, argv[1], argv[i]); 248 } 249 Tcl_AppendResult(interp, zResult, 0); 250 sqliteFree(zResult); 251 return TCL_OK; 252 } 253 254 /* 255 ** Usage: sqlite3_mprintf_n_test STRING 256 ** 257 ** Test the %n format of sqliteMPrintf(). Return the length of the 258 ** input string. 259 */ 260 static int test_mprintf_n( 261 void *NotUsed, 262 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 263 int argc, /* Number of arguments */ 264 char **argv /* Text of each argument */ 265 ){ 266 char *zStr; 267 int n = 0; 268 zStr = sqlite3MPrintf("%s%n", argv[1], &n); 269 sqliteFree(zStr); 270 Tcl_SetObjResult(interp, Tcl_NewIntObj(n)); 271 return TCL_OK; 272 } 273 274 /* 275 ** Usage: sqlite3_get_table_printf DB FORMAT STRING 276 ** 277 ** Invoke the sqlite3_get_table_printf() interface using the open database 278 ** DB. The SQL is the string FORMAT. The format string should contain 279 ** one %s or %q. STRING is the value inserted into %s or %q. 280 */ 281 static int test_get_table_printf( 282 void *NotUsed, 283 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 284 int argc, /* Number of arguments */ 285 char **argv /* Text of each argument */ 286 ){ 287 sqlite3 *db; 288 Tcl_DString str; 289 int rc; 290 char *zErr = 0; 291 int nRow, nCol; 292 char **aResult; 293 int i; 294 char zBuf[30]; 295 char *zSql; 296 if( argc!=4 ){ 297 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 298 " DB FORMAT STRING", 0); 299 return TCL_ERROR; 300 } 301 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 302 Tcl_DStringInit(&str); 303 zSql = sqlite3_mprintf(argv[2],argv[3]); 304 rc = sqlite3_get_table(db, zSql, &aResult, &nRow, &nCol, &zErr); 305 sqlite3_free(zSql); 306 sprintf(zBuf, "%d", rc); 307 Tcl_AppendElement(interp, zBuf); 308 if( rc==SQLITE_OK ){ 309 sprintf(zBuf, "%d", nRow); 310 Tcl_AppendElement(interp, zBuf); 311 sprintf(zBuf, "%d", nCol); 312 Tcl_AppendElement(interp, zBuf); 313 for(i=0; i<(nRow+1)*nCol; i++){ 314 Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL"); 315 } 316 }else{ 317 Tcl_AppendElement(interp, zErr); 318 } 319 sqlite3_free_table(aResult); 320 if( zErr ) sqlite3_free(zErr); 321 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 322 return TCL_OK; 323 } 324 325 326 /* 327 ** Usage: sqlite3_last_insert_rowid DB 328 ** 329 ** Returns the integer ROWID of the most recent insert. 330 */ 331 static int test_last_rowid( 332 void *NotUsed, 333 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 334 int argc, /* Number of arguments */ 335 char **argv /* Text of each argument */ 336 ){ 337 sqlite3 *db; 338 char zBuf[30]; 339 340 if( argc!=2 ){ 341 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0); 342 return TCL_ERROR; 343 } 344 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 345 sprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db)); 346 Tcl_AppendResult(interp, zBuf, 0); 347 return SQLITE_OK; 348 } 349 350 /* 351 ** Usage: sqlite3_key DB KEY 352 ** 353 ** Set the codec key. 354 */ 355 static int test_key( 356 void *NotUsed, 357 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 358 int argc, /* Number of arguments */ 359 char **argv /* Text of each argument */ 360 ){ 361 sqlite3 *db; 362 const char *zKey; 363 int nKey; 364 if( argc!=3 ){ 365 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 366 " FILENAME\"", 0); 367 return TCL_ERROR; 368 } 369 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 370 zKey = argv[2]; 371 nKey = strlen(zKey); 372 #ifdef SQLITE_HAS_CODEC 373 sqlite3_key(db, zKey, nKey); 374 #endif 375 return TCL_OK; 376 } 377 378 /* 379 ** Usage: sqlite3_rekey DB KEY 380 ** 381 ** Change the codec key. 382 */ 383 static int test_rekey( 384 void *NotUsed, 385 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 386 int argc, /* Number of arguments */ 387 char **argv /* Text of each argument */ 388 ){ 389 sqlite3 *db; 390 const char *zKey; 391 int nKey; 392 if( argc!=3 ){ 393 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 394 " FILENAME\"", 0); 395 return TCL_ERROR; 396 } 397 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 398 zKey = argv[2]; 399 nKey = strlen(zKey); 400 #ifdef SQLITE_HAS_CODEC 401 sqlite3_rekey(db, zKey, nKey); 402 #endif 403 return TCL_OK; 404 } 405 406 /* 407 ** Usage: sqlite3_close DB 408 ** 409 ** Closes the database opened by sqlite3_open. 410 */ 411 static int sqlite_test_close( 412 void *NotUsed, 413 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 414 int argc, /* Number of arguments */ 415 char **argv /* Text of each argument */ 416 ){ 417 sqlite3 *db; 418 int rc; 419 if( argc!=2 ){ 420 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 421 " FILENAME\"", 0); 422 return TCL_ERROR; 423 } 424 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 425 rc = sqlite3_close(db); 426 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 427 return TCL_OK; 428 } 429 430 /* 431 ** Implementation of the x_coalesce() function. 432 ** Return the first argument non-NULL argument. 433 */ 434 static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 435 int i; 436 for(i=0; i<argc; i++){ 437 if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){ 438 sqlite3_result_text(context, (char*)sqlite3_value_text(argv[i]), 439 sqlite3_value_bytes(argv[i]), SQLITE_TRANSIENT); 440 break; 441 } 442 } 443 } 444 445 /* 446 ** These are test functions. hex8() interprets its argument as 447 ** UTF8 and returns a hex encoding. hex16le() interprets its argument 448 ** as UTF16le and returns a hex encoding. 449 */ 450 static void hex8Func(sqlite3_context *p, int argc, sqlite3_value **argv){ 451 const unsigned char *z; 452 int i; 453 char zBuf[200]; 454 z = sqlite3_value_text(argv[0]); 455 for(i=0; i<sizeof(zBuf)/2 - 2 && z[i]; i++){ 456 sprintf(&zBuf[i*2], "%02x", z[i]&0xff); 457 } 458 zBuf[i*2] = 0; 459 sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT); 460 } 461 static void hex16Func(sqlite3_context *p, int argc, sqlite3_value **argv){ 462 const unsigned short int *z; 463 int i; 464 char zBuf[400]; 465 z = sqlite3_value_text16(argv[0]); 466 for(i=0; i<sizeof(zBuf)/4 - 4 && z[i]; i++){ 467 sprintf(&zBuf[i*4], "%04x", z[i]&0xff); 468 } 469 zBuf[i*4] = 0; 470 sqlite3_result_text(p, (char*)zBuf, -1, SQLITE_TRANSIENT); 471 } 472 473 /* 474 ** A structure into which to accumulate text. 475 */ 476 struct dstr { 477 int nAlloc; /* Space allocated */ 478 int nUsed; /* Space used */ 479 char *z; /* The space */ 480 }; 481 482 /* 483 ** Append text to a dstr 484 */ 485 static void dstrAppend(struct dstr *p, const char *z, int divider){ 486 int n = strlen(z); 487 if( p->nUsed + n + 2 > p->nAlloc ){ 488 char *zNew; 489 p->nAlloc = p->nAlloc*2 + n + 200; 490 zNew = sqliteRealloc(p->z, p->nAlloc); 491 if( zNew==0 ){ 492 sqliteFree(p->z); 493 memset(p, 0, sizeof(*p)); 494 return; 495 } 496 p->z = zNew; 497 } 498 if( divider && p->nUsed>0 ){ 499 p->z[p->nUsed++] = divider; 500 } 501 memcpy(&p->z[p->nUsed], z, n+1); 502 p->nUsed += n; 503 } 504 505 /* 506 ** Invoked for each callback from sqlite3ExecFunc 507 */ 508 static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){ 509 struct dstr *p = (struct dstr*)pData; 510 int i; 511 for(i=0; i<argc; i++){ 512 if( argv[i]==0 ){ 513 dstrAppend(p, "NULL", ' '); 514 }else{ 515 dstrAppend(p, argv[i], ' '); 516 } 517 } 518 return 0; 519 } 520 521 /* 522 ** Implementation of the x_sqlite_exec() function. This function takes 523 ** a single argument and attempts to execute that argument as SQL code. 524 ** This is illegal and should set the SQLITE_MISUSE flag on the database. 525 ** 526 ** 2004-Jan-07: We have changed this to make it legal to call sqlite3_exec() 527 ** from within a function call. 528 ** 529 ** This routine simulates the effect of having two threads attempt to 530 ** use the same database at the same time. 531 */ 532 static void sqlite3ExecFunc( 533 sqlite3_context *context, 534 int argc, 535 sqlite3_value **argv 536 ){ 537 struct dstr x; 538 memset(&x, 0, sizeof(x)); 539 (void)sqlite3_exec((sqlite3*)sqlite3_user_data(context), 540 (char*)sqlite3_value_text(argv[0]), 541 execFuncCallback, &x, 0); 542 sqlite3_result_text(context, x.z, x.nUsed, SQLITE_TRANSIENT); 543 sqliteFree(x.z); 544 } 545 546 /* 547 ** Usage: sqlite_test_create_function DB 548 ** 549 ** Call the sqlite3_create_function API on the given database in order 550 ** to create a function named "x_coalesce". This function does the same thing 551 ** as the "coalesce" function. This function also registers an SQL function 552 ** named "x_sqlite_exec" that invokes sqlite3_exec(). Invoking sqlite3_exec() 553 ** in this way is illegal recursion and should raise an SQLITE_MISUSE error. 554 ** The effect is similar to trying to use the same database connection from 555 ** two threads at the same time. 556 ** 557 ** The original motivation for this routine was to be able to call the 558 ** sqlite3_create_function function while a query is in progress in order 559 ** to test the SQLITE_MISUSE detection logic. 560 */ 561 static int test_create_function( 562 void *NotUsed, 563 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 564 int argc, /* Number of arguments */ 565 char **argv /* Text of each argument */ 566 ){ 567 int rc; 568 sqlite3 *db; 569 extern void Md5_Register(sqlite3*); 570 571 if( argc!=2 ){ 572 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 573 " DB\"", 0); 574 return TCL_ERROR; 575 } 576 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 577 rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0, 578 ifnullFunc, 0, 0); 579 if( rc==SQLITE_OK ){ 580 rc = sqlite3_create_function(db, "hex8", 1, SQLITE_ANY, 0, 581 hex8Func, 0, 0); 582 } 583 if( rc==SQLITE_OK ){ 584 rc = sqlite3_create_function(db, "hex16", 1, SQLITE_ANY, 0, 585 hex16Func, 0, 0); 586 } 587 588 #ifndef SQLITE_OMIT_UTF16 589 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 590 ** because it is not tested anywhere else. */ 591 if( rc==SQLITE_OK ){ 592 sqlite3_value *pVal; 593 #ifdef SQLITE_MEMDEBUG 594 if( sqlite3_iMallocFail>0 ){ 595 sqlite3_iMallocFail++; 596 } 597 #endif 598 pVal = sqlite3ValueNew(); 599 sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC); 600 rc = sqlite3_create_function16(db, 601 sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), 602 1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0); 603 sqlite3ValueFree(pVal); 604 } 605 #endif 606 607 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 608 Tcl_SetResult(interp, (char *)errorName(rc), 0); 609 return TCL_OK; 610 } 611 612 /* 613 ** Routines to implement the x_count() aggregate function. 614 ** 615 ** x_count() counts the number of non-null arguments. But there are 616 ** some twists for testing purposes. 617 ** 618 ** If the argument to x_count() is 40 then a UTF-8 error is reported 619 ** on the step function. If x_count(41) is seen, then a UTF-16 error 620 ** is reported on the step function. If the total count is 42, then 621 ** a UTF-8 error is reported on the finalize function. 622 */ 623 typedef struct CountCtx CountCtx; 624 struct CountCtx { 625 int n; 626 }; 627 static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ 628 CountCtx *p; 629 p = sqlite3_aggregate_context(context, sizeof(*p)); 630 if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0]) ) && p ){ 631 p->n++; 632 } 633 if( argc>0 ){ 634 int v = sqlite3_value_int(argv[0]); 635 if( v==40 ){ 636 sqlite3_result_error(context, "value of 40 handed to x_count", -1); 637 #ifndef SQLITE_OMIT_UTF16 638 }else if( v==41 ){ 639 const char zUtf16ErrMsg[] = { 0, 0x61, 0, 0x62, 0, 0x63, 0, 0, 0}; 640 sqlite3_result_error16(context, &zUtf16ErrMsg[1-SQLITE_BIGENDIAN], -1); 641 #endif 642 } 643 } 644 } 645 static void countFinalize(sqlite3_context *context){ 646 CountCtx *p; 647 p = sqlite3_aggregate_context(context, sizeof(*p)); 648 if( p ){ 649 if( p->n==42 ){ 650 sqlite3_result_error(context, "x_count totals to 42", -1); 651 }else{ 652 sqlite3_result_int(context, p ? p->n : 0); 653 } 654 } 655 } 656 657 /* 658 ** Usage: sqlite_test_create_aggregate DB 659 ** 660 ** Call the sqlite3_create_function API on the given database in order 661 ** to create a function named "x_count". This function does the same thing 662 ** as the "md5sum" function. 663 ** 664 ** The original motivation for this routine was to be able to call the 665 ** sqlite3_create_aggregate function while a query is in progress in order 666 ** to test the SQLITE_MISUSE detection logic. See misuse.test. 667 ** 668 ** This routine was later extended to test the use of sqlite3_result_error() 669 ** within aggregate functions. 670 */ 671 static int test_create_aggregate( 672 void *NotUsed, 673 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 674 int argc, /* Number of arguments */ 675 char **argv /* Text of each argument */ 676 ){ 677 sqlite3 *db; 678 int rc; 679 if( argc!=2 ){ 680 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 681 " FILENAME\"", 0); 682 return TCL_ERROR; 683 } 684 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 685 rc = sqlite3_create_function(db, "x_count", 0, SQLITE_UTF8, 0, 0, 686 countStep,countFinalize); 687 if( rc==SQLITE_OK ){ 688 sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0, 689 countStep,countFinalize); 690 } 691 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 692 return TCL_OK; 693 } 694 695 696 697 /* 698 ** Usage: sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER 699 ** 700 ** Call mprintf with three integer arguments 701 */ 702 static int sqlite3_mprintf_int( 703 void *NotUsed, 704 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 705 int argc, /* Number of arguments */ 706 char **argv /* Text of each argument */ 707 ){ 708 int a[3], i; 709 char *z; 710 if( argc!=5 ){ 711 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 712 " FORMAT INT INT INT\"", 0); 713 return TCL_ERROR; 714 } 715 for(i=2; i<5; i++){ 716 if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 717 } 718 z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]); 719 Tcl_AppendResult(interp, z, 0); 720 sqlite3_free(z); 721 return TCL_OK; 722 } 723 724 /* 725 ** If zNum represents an integer that will fit in 64-bits, then set 726 ** *pValue to that integer and return true. Otherwise return false. 727 */ 728 static int sqlite3GetInt64(const char *zNum, i64 *pValue){ 729 if( sqlite3FitsIn64Bits(zNum) ){ 730 sqlite3atoi64(zNum, pValue); 731 return 1; 732 } 733 return 0; 734 } 735 736 /* 737 ** Usage: sqlite3_mprintf_int64 FORMAT INTEGER INTEGER INTEGER 738 ** 739 ** Call mprintf with three 64-bit integer arguments 740 */ 741 static int sqlite3_mprintf_int64( 742 void *NotUsed, 743 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 744 int argc, /* Number of arguments */ 745 char **argv /* Text of each argument */ 746 ){ 747 int i; 748 sqlite_int64 a[3]; 749 char *z; 750 if( argc!=5 ){ 751 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 752 " FORMAT INT INT INT\"", 0); 753 return TCL_ERROR; 754 } 755 for(i=2; i<5; i++){ 756 if( !sqlite3GetInt64(argv[i], &a[i-2]) ){ 757 Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0); 758 return TCL_ERROR; 759 } 760 } 761 z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]); 762 Tcl_AppendResult(interp, z, 0); 763 sqlite3_free(z); 764 return TCL_OK; 765 } 766 767 /* 768 ** Usage: sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING 769 ** 770 ** Call mprintf with two integer arguments and one string argument 771 */ 772 static int sqlite3_mprintf_str( 773 void *NotUsed, 774 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 775 int argc, /* Number of arguments */ 776 char **argv /* Text of each argument */ 777 ){ 778 int a[3], i; 779 char *z; 780 if( argc<4 || argc>5 ){ 781 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 782 " FORMAT INT INT ?STRING?\"", 0); 783 return TCL_ERROR; 784 } 785 for(i=2; i<4; i++){ 786 if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 787 } 788 z = sqlite3_mprintf(argv[1], a[0], a[1], argc>4 ? argv[4] : NULL); 789 Tcl_AppendResult(interp, z, 0); 790 sqlite3_free(z); 791 return TCL_OK; 792 } 793 794 /* 795 ** Usage: sqlite3_mprintf_double FORMAT INTEGER INTEGER DOUBLE 796 ** 797 ** Call mprintf with two integer arguments and one double argument 798 */ 799 static int sqlite3_mprintf_double( 800 void *NotUsed, 801 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 802 int argc, /* Number of arguments */ 803 char **argv /* Text of each argument */ 804 ){ 805 int a[3], i; 806 double r; 807 char *z; 808 if( argc!=5 ){ 809 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 810 " FORMAT INT INT DOUBLE\"", 0); 811 return TCL_ERROR; 812 } 813 for(i=2; i<4; i++){ 814 if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 815 } 816 if( Tcl_GetDouble(interp, argv[4], &r) ) return TCL_ERROR; 817 z = sqlite3_mprintf(argv[1], a[0], a[1], r); 818 Tcl_AppendResult(interp, z, 0); 819 sqlite3_free(z); 820 return TCL_OK; 821 } 822 823 /* 824 ** Usage: sqlite3_mprintf_scaled FORMAT DOUBLE DOUBLE 825 ** 826 ** Call mprintf with a single double argument which is the product of the 827 ** two arguments given above. This is used to generate overflow and underflow 828 ** doubles to test that they are converted properly. 829 */ 830 static int sqlite3_mprintf_scaled( 831 void *NotUsed, 832 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 833 int argc, /* Number of arguments */ 834 char **argv /* Text of each argument */ 835 ){ 836 int i; 837 double r[2]; 838 char *z; 839 if( argc!=4 ){ 840 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 841 " FORMAT DOUBLE DOUBLE\"", 0); 842 return TCL_ERROR; 843 } 844 for(i=2; i<4; i++){ 845 if( Tcl_GetDouble(interp, argv[i], &r[i-2]) ) return TCL_ERROR; 846 } 847 z = sqlite3_mprintf(argv[1], r[0]*r[1]); 848 Tcl_AppendResult(interp, z, 0); 849 sqlite3_free(z); 850 return TCL_OK; 851 } 852 853 /* 854 ** Usage: sqlite3_mprintf_stronly FORMAT STRING 855 ** 856 ** Call mprintf with a single double argument which is the product of the 857 ** two arguments given above. This is used to generate overflow and underflow 858 ** doubles to test that they are converted properly. 859 */ 860 static int sqlite3_mprintf_stronly( 861 void *NotUsed, 862 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 863 int argc, /* Number of arguments */ 864 char **argv /* Text of each argument */ 865 ){ 866 char *z; 867 if( argc!=3 ){ 868 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 869 " FORMAT STRING\"", 0); 870 return TCL_ERROR; 871 } 872 z = sqlite3_mprintf(argv[1], argv[2]); 873 Tcl_AppendResult(interp, z, 0); 874 sqlite3_free(z); 875 return TCL_OK; 876 } 877 878 /* 879 ** Usage: sqlite3_mprintf_hexdouble FORMAT HEX 880 ** 881 ** Call mprintf with a single double argument which is derived from the 882 ** hexadecimal encoding of an IEEE double. 883 */ 884 static int sqlite3_mprintf_hexdouble( 885 void *NotUsed, 886 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 887 int argc, /* Number of arguments */ 888 char **argv /* Text of each argument */ 889 ){ 890 char *z; 891 double r; 892 unsigned x1, x2; 893 long long unsigned d; 894 if( argc!=3 ){ 895 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 896 " FORMAT STRING\"", 0); 897 return TCL_ERROR; 898 } 899 if( sscanf(argv[2], "%08x%08x", &x2, &x1)!=2 ){ 900 Tcl_AppendResult(interp, "2nd argument should be 16-characters of hex", 0); 901 return TCL_ERROR; 902 } 903 d = x2; 904 d = (d<<32) + x1; 905 memcpy(&r, &d, sizeof(r)); 906 z = sqlite3_mprintf(argv[1], r); 907 Tcl_AppendResult(interp, z, 0); 908 sqlite3_free(z); 909 return TCL_OK; 910 } 911 912 /* 913 ** Usage: sqlite_malloc_fail N ?REPEAT-INTERVAL? 914 ** 915 ** Rig sqliteMalloc() to fail on the N-th call and every REPEAT-INTERVAL call 916 ** after that. If REPEAT-INTERVAL is 0 or is omitted, then only a single 917 ** malloc will fail. If REPEAT-INTERVAL is 1 then all mallocs after the 918 ** first failure will continue to fail on every call. If REPEAT-INTERVAL is 919 ** 2 then every other malloc will fail. And so forth. 920 ** 921 ** Turn off this mechanism and reset the sqlite3ThreadData()->mallocFailed 922 ** variable if N==0. 923 */ 924 #ifdef SQLITE_MEMDEBUG 925 static int sqlite_malloc_fail( 926 void *NotUsed, 927 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 928 int argc, /* Number of arguments */ 929 char **argv /* Text of each argument */ 930 ){ 931 int n; 932 int rep; 933 if( argc!=2 && argc!=3 ){ 934 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"", 0); 935 return TCL_ERROR; 936 } 937 if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR; 938 if( argc==3 ){ 939 if( Tcl_GetInt(interp, argv[2], &rep) ) return TCL_ERROR; 940 }else{ 941 rep = 0; 942 } 943 sqlite3_iMallocFail = n; 944 sqlite3_iMallocReset = rep; 945 return TCL_OK; 946 } 947 #endif 948 949 /* 950 ** Usage: sqlite_malloc_stat 951 ** 952 ** Return the number of prior calls to sqliteMalloc() and sqliteFree(). 953 */ 954 #ifdef SQLITE_MEMDEBUG 955 static int sqlite_malloc_stat( 956 void *NotUsed, 957 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 958 int argc, /* Number of arguments */ 959 char **argv /* Text of each argument */ 960 ){ 961 char zBuf[200]; 962 sprintf(zBuf, "%d %d %d", sqlite3_nMalloc,sqlite3_nFree,sqlite3_iMallocFail); 963 Tcl_AppendResult(interp, zBuf, 0); 964 return TCL_OK; 965 } 966 967 /* 968 ** This function implements a Tcl command that may be invoked using any of 969 ** the four forms enumerated below. 970 ** 971 ** sqlite_malloc_outstanding 972 ** Return a summary of all unfreed blocks of memory allocated by the 973 ** current thread. See comments above function sqlite3OutstandingMallocs() 974 ** in util.c for a description of the returned value. 975 ** 976 ** sqlite_malloc_outstanding -bytes 977 ** Return the total amount of unfreed memory (in bytes) allocated by 978 ** this thread. 979 ** 980 ** sqlite_malloc_outstanding -maxbytes 981 ** Return the maximum amount of dynamic memory in use at one time 982 ** by this thread. 983 ** 984 ** sqlite_malloc_outstanding -clearmaxbytes 985 ** Set the value returned by [sqlite_malloc_outstanding -maxbytes] 986 ** to the current value of [sqlite_malloc_outstanding -bytes]. 987 */ 988 static int sqlite_malloc_outstanding( 989 ClientData clientData, 990 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 991 int objc, /* Number of arguments */ 992 Tcl_Obj *CONST objv[] /* Command arguments */ 993 ){ 994 extern int sqlite3OutstandingMallocs(Tcl_Interp *interp); 995 996 #if defined(SQLITE_DEBUG) && defined(SQLITE_MEMDEBUG) && SQLITE_MEMDEBUG>1 997 if( objc==2 ){ 998 const char *zArg = Tcl_GetString(objv[1]); 999 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT 1000 ThreadData const *pTd = sqlite3ThreadDataReadOnly(); 1001 if( 0==strcmp(zArg, "-bytes") ){ 1002 Tcl_SetObjResult(interp, Tcl_NewIntObj(pTd->nAlloc)); 1003 }else if( 0==strcmp(zArg, "-clearmaxbytes") ){ 1004 sqlite3_nMaxAlloc = pTd->nAlloc; 1005 }else 1006 #endif 1007 if( 0==strcmp(zArg, "-maxbytes") ){ 1008 Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sqlite3_nMaxAlloc)); 1009 }else{ 1010 Tcl_AppendResult(interp, "bad option \"", zArg, 1011 "\": must be -bytes, -maxbytes or -clearmaxbytes", 0 1012 ); 1013 return TCL_ERROR; 1014 } 1015 1016 return TCL_OK; 1017 } 1018 1019 if( objc!=1 ){ 1020 Tcl_WrongNumArgs(interp, 1, objv, "?-bytes?"); 1021 return TCL_ERROR; 1022 } 1023 1024 return sqlite3OutstandingMallocs(interp); 1025 #else 1026 return TCL_OK; 1027 #endif 1028 } 1029 #endif 1030 1031 /* 1032 ** Usage: sqlite3_enable_shared_cache BOOLEAN 1033 ** 1034 */ 1035 #if !defined(SQLITE_OMIT_SHARED_CACHE) 1036 static int test_enable_shared( 1037 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ 1038 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 1039 int objc, /* Number of arguments */ 1040 Tcl_Obj *CONST objv[] /* Command arguments */ 1041 ){ 1042 int rc; 1043 int enable; 1044 int ret = 0; 1045 1046 if( objc!=2 ){ 1047 Tcl_WrongNumArgs(interp, 1, objv, "BOOLEAN"); 1048 return TCL_ERROR; 1049 } 1050 if( Tcl_GetBooleanFromObj(interp, objv[1], &enable) ){ 1051 return TCL_ERROR; 1052 } 1053 ret = sqlite3ThreadDataReadOnly()->useSharedData; 1054 rc = sqlite3_enable_shared_cache(enable); 1055 if( rc!=SQLITE_OK ){ 1056 Tcl_SetResult(interp, (char *)sqlite3ErrStr(rc), TCL_STATIC); 1057 return TCL_ERROR; 1058 } 1059 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(ret)); 1060 return TCL_OK; 1061 } 1062 #endif 1063 1064 /* 1065 ** Usage: sqlite3_extended_result_codes DB BOOLEAN 1066 ** 1067 */ 1068 static int test_extended_result_codes( 1069 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ 1070 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 1071 int objc, /* Number of arguments */ 1072 Tcl_Obj *CONST objv[] /* Command arguments */ 1073 ){ 1074 int enable; 1075 sqlite3 *db; 1076 1077 if( objc!=3 ){ 1078 Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN"); 1079 return TCL_ERROR; 1080 } 1081 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1082 if( Tcl_GetBooleanFromObj(interp, objv[2], &enable) ) return TCL_ERROR; 1083 sqlite3_extended_result_codes(db, enable); 1084 return TCL_OK; 1085 } 1086 1087 /* 1088 ** Usage: sqlite3_libversion_number 1089 ** 1090 */ 1091 static int test_libversion_number( 1092 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ 1093 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 1094 int objc, /* Number of arguments */ 1095 Tcl_Obj *CONST objv[] /* Command arguments */ 1096 ){ 1097 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_libversion_number())); 1098 return TCL_OK; 1099 } 1100 1101 /* 1102 ** Usage: sqlite3_table_column_metadata DB dbname tblname colname 1103 ** 1104 */ 1105 #ifdef SQLITE_ENABLE_COLUMN_METADATA 1106 static int test_table_column_metadata( 1107 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ 1108 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 1109 int objc, /* Number of arguments */ 1110 Tcl_Obj *CONST objv[] /* Command arguments */ 1111 ){ 1112 sqlite3 *db; 1113 const char *zDb; 1114 const char *zTbl; 1115 const char *zCol; 1116 int rc; 1117 Tcl_Obj *pRet; 1118 1119 const char *zDatatype; 1120 const char *zCollseq; 1121 int notnull; 1122 int primarykey; 1123 int autoincrement; 1124 1125 if( objc!=5 ){ 1126 Tcl_WrongNumArgs(interp, 1, objv, "DB dbname tblname colname"); 1127 return TCL_ERROR; 1128 } 1129 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1130 zDb = Tcl_GetString(objv[2]); 1131 zTbl = Tcl_GetString(objv[3]); 1132 zCol = Tcl_GetString(objv[4]); 1133 1134 if( strlen(zDb)==0 ) zDb = 0; 1135 1136 rc = sqlite3_table_column_metadata(db, zDb, zTbl, zCol, 1137 &zDatatype, &zCollseq, ¬null, &primarykey, &autoincrement); 1138 1139 if( rc!=SQLITE_OK ){ 1140 Tcl_AppendResult(interp, sqlite3_errmsg(db), 0); 1141 return TCL_ERROR; 1142 } 1143 1144 pRet = Tcl_NewObj(); 1145 Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zDatatype, -1)); 1146 Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj(zCollseq, -1)); 1147 Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(notnull)); 1148 Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(primarykey)); 1149 Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(autoincrement)); 1150 Tcl_SetObjResult(interp, pRet); 1151 1152 return TCL_OK; 1153 } 1154 #endif 1155 1156 1157 /* 1158 ** Usage: sqlite3_load_extension DB-HANDLE FILE ?PROC? 1159 */ 1160 static int test_load_extension( 1161 ClientData clientData, /* Not used */ 1162 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 1163 int objc, /* Number of arguments */ 1164 Tcl_Obj *CONST objv[] /* Command arguments */ 1165 ){ 1166 Tcl_CmdInfo cmdInfo; 1167 sqlite3 *db; 1168 int rc; 1169 char *zDb; 1170 char *zFile; 1171 char *zProc = 0; 1172 char *zErr = 0; 1173 1174 if( objc!=4 && objc!=3 ){ 1175 Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE FILE ?PROC?"); 1176 return TCL_ERROR; 1177 } 1178 zDb = Tcl_GetString(objv[1]); 1179 zFile = Tcl_GetString(objv[2]); 1180 if( objc==4 ){ 1181 zProc = Tcl_GetString(objv[3]); 1182 } 1183 1184 /* Extract the C database handle from the Tcl command name */ 1185 if( !Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){ 1186 Tcl_AppendResult(interp, "command not found: ", zDb, (char*)0); 1187 return TCL_ERROR; 1188 } 1189 db = ((struct SqliteDb*)cmdInfo.objClientData)->db; 1190 assert(db); 1191 1192 /* Call the underlying C function. If an error occurs, set rc to 1193 ** TCL_ERROR and load any error string into the interpreter. If no 1194 ** error occurs, set rc to TCL_OK. 1195 */ 1196 #ifdef SQLITE_OMIT_LOAD_EXTENSION 1197 rc = SQLITE_ERROR; 1198 zErr = sqlite3_mprintf("this build omits sqlite3_load_extension()"); 1199 #else 1200 rc = sqlite3_load_extension(db, zFile, zProc, &zErr); 1201 #endif 1202 if( rc!=SQLITE_OK ){ 1203 Tcl_SetResult(interp, zErr ? zErr : "", TCL_VOLATILE); 1204 rc = TCL_ERROR; 1205 }else{ 1206 rc = TCL_OK; 1207 } 1208 sqlite3_free(zErr); 1209 1210 return rc; 1211 } 1212 1213 /* 1214 ** Usage: sqlite3_enable_load_extension DB-HANDLE ONOFF 1215 */ 1216 static int test_enable_load( 1217 ClientData clientData, /* Not used */ 1218 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 1219 int objc, /* Number of arguments */ 1220 Tcl_Obj *CONST objv[] /* Command arguments */ 1221 ){ 1222 Tcl_CmdInfo cmdInfo; 1223 sqlite3 *db; 1224 char *zDb; 1225 int onoff; 1226 1227 if( objc!=3 ){ 1228 Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE ONOFF"); 1229 return TCL_ERROR; 1230 } 1231 zDb = Tcl_GetString(objv[1]); 1232 1233 /* Extract the C database handle from the Tcl command name */ 1234 if( !Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){ 1235 Tcl_AppendResult(interp, "command not found: ", zDb, (char*)0); 1236 return TCL_ERROR; 1237 } 1238 db = ((struct SqliteDb*)cmdInfo.objClientData)->db; 1239 assert(db); 1240 1241 /* Get the onoff parameter */ 1242 if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){ 1243 return TCL_ERROR; 1244 } 1245 1246 #ifdef SQLITE_OMIT_LOAD_EXTENSION 1247 Tcl_AppendResult(interp, "this build omits sqlite3_load_extension()"); 1248 return TCL_ERROR; 1249 #else 1250 sqlite3_enable_load_extension(db, onoff); 1251 return TCL_OK; 1252 #endif 1253 } 1254 1255 /* 1256 ** Usage: sqlite_abort 1257 ** 1258 ** Shutdown the process immediately. This is not a clean shutdown. 1259 ** This command is used to test the recoverability of a database in 1260 ** the event of a program crash. 1261 */ 1262 static int sqlite_abort( 1263 void *NotUsed, 1264 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 1265 int argc, /* Number of arguments */ 1266 char **argv /* Text of each argument */ 1267 ){ 1268 assert( interp==0 ); /* This will always fail */ 1269 return TCL_OK; 1270 } 1271 1272 /* 1273 ** The following routine is a user-defined SQL function whose purpose 1274 ** is to test the sqlite_set_result() API. 1275 */ 1276 static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 1277 while( argc>=2 ){ 1278 const char *zArg0 = (char*)sqlite3_value_text(argv[0]); 1279 if( zArg0 ){ 1280 if( 0==sqlite3StrICmp(zArg0, "int") ){ 1281 sqlite3_result_int(context, sqlite3_value_int(argv[1])); 1282 }else if( sqlite3StrICmp(zArg0,"int64")==0 ){ 1283 sqlite3_result_int64(context, sqlite3_value_int64(argv[1])); 1284 }else if( sqlite3StrICmp(zArg0,"string")==0 ){ 1285 sqlite3_result_text(context, (char*)sqlite3_value_text(argv[1]), -1, 1286 SQLITE_TRANSIENT); 1287 }else if( sqlite3StrICmp(zArg0,"double")==0 ){ 1288 sqlite3_result_double(context, sqlite3_value_double(argv[1])); 1289 }else if( sqlite3StrICmp(zArg0,"null")==0 ){ 1290 sqlite3_result_null(context); 1291 }else if( sqlite3StrICmp(zArg0,"value")==0 ){ 1292 sqlite3_result_value(context, argv[sqlite3_value_int(argv[1])]); 1293 }else{ 1294 goto error_out; 1295 } 1296 }else{ 1297 goto error_out; 1298 } 1299 argc -= 2; 1300 argv += 2; 1301 } 1302 return; 1303 1304 error_out: 1305 sqlite3_result_error(context,"first argument should be one of: " 1306 "int int64 string double null value", -1); 1307 } 1308 1309 /* 1310 ** Usage: sqlite_register_test_function DB NAME 1311 ** 1312 ** Register the test SQL function on the database DB under the name NAME. 1313 */ 1314 static int test_register_func( 1315 void *NotUsed, 1316 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 1317 int argc, /* Number of arguments */ 1318 char **argv /* Text of each argument */ 1319 ){ 1320 sqlite3 *db; 1321 int rc; 1322 if( argc!=3 ){ 1323 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 1324 " DB FUNCTION-NAME", 0); 1325 return TCL_ERROR; 1326 } 1327 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 1328 rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 1329 testFunc, 0, 0); 1330 if( rc!=0 ){ 1331 Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0); 1332 return TCL_ERROR; 1333 } 1334 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1335 return TCL_OK; 1336 } 1337 1338 /* 1339 ** Usage: sqlite3_finalize STMT 1340 ** 1341 ** Finalize a statement handle. 1342 */ 1343 static int test_finalize( 1344 void * clientData, 1345 Tcl_Interp *interp, 1346 int objc, 1347 Tcl_Obj *CONST objv[] 1348 ){ 1349 sqlite3_stmt *pStmt; 1350 int rc; 1351 sqlite3 *db; 1352 1353 if( objc!=2 ){ 1354 Tcl_AppendResult(interp, "wrong # args: should be \"", 1355 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 1356 return TCL_ERROR; 1357 } 1358 1359 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1360 1361 if( pStmt ){ 1362 db = StmtToDb(pStmt); 1363 } 1364 rc = sqlite3_finalize(pStmt); 1365 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 1366 if( db && sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1367 return TCL_OK; 1368 } 1369 1370 /* 1371 ** Usage: sqlite3_reset STMT 1372 ** 1373 ** Reset a statement handle. 1374 */ 1375 static int test_reset( 1376 void * clientData, 1377 Tcl_Interp *interp, 1378 int objc, 1379 Tcl_Obj *CONST objv[] 1380 ){ 1381 sqlite3_stmt *pStmt; 1382 int rc; 1383 1384 if( objc!=2 ){ 1385 Tcl_AppendResult(interp, "wrong # args: should be \"", 1386 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 1387 return TCL_ERROR; 1388 } 1389 1390 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1391 1392 rc = sqlite3_reset(pStmt); 1393 if( pStmt && sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ){ 1394 return TCL_ERROR; 1395 } 1396 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 1397 /* 1398 if( rc ){ 1399 return TCL_ERROR; 1400 } 1401 */ 1402 return TCL_OK; 1403 } 1404 1405 /* 1406 ** Usage: sqlite3_expired STMT 1407 ** 1408 ** Return TRUE if a recompilation of the statement is recommended. 1409 */ 1410 static int test_expired( 1411 void * clientData, 1412 Tcl_Interp *interp, 1413 int objc, 1414 Tcl_Obj *CONST objv[] 1415 ){ 1416 sqlite3_stmt *pStmt; 1417 if( objc!=2 ){ 1418 Tcl_AppendResult(interp, "wrong # args: should be \"", 1419 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 1420 return TCL_ERROR; 1421 } 1422 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1423 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(sqlite3_expired(pStmt))); 1424 return TCL_OK; 1425 } 1426 1427 /* 1428 ** Usage: sqlite3_transfer_bindings FROMSTMT TOSTMT 1429 ** 1430 ** Transfer all bindings from FROMSTMT over to TOSTMT 1431 */ 1432 static int test_transfer_bind( 1433 void * clientData, 1434 Tcl_Interp *interp, 1435 int objc, 1436 Tcl_Obj *CONST objv[] 1437 ){ 1438 sqlite3_stmt *pStmt1, *pStmt2; 1439 if( objc!=3 ){ 1440 Tcl_AppendResult(interp, "wrong # args: should be \"", 1441 Tcl_GetStringFromObj(objv[0], 0), " FROM-STMT TO-STMT", 0); 1442 return TCL_ERROR; 1443 } 1444 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt1)) return TCL_ERROR; 1445 if( getStmtPointer(interp, Tcl_GetString(objv[2]), &pStmt2)) return TCL_ERROR; 1446 Tcl_SetObjResult(interp, 1447 Tcl_NewIntObj(sqlite3_transfer_bindings(pStmt1,pStmt2))); 1448 return TCL_OK; 1449 } 1450 1451 /* 1452 ** Usage: sqlite3_changes DB 1453 ** 1454 ** Return the number of changes made to the database by the last SQL 1455 ** execution. 1456 */ 1457 static int test_changes( 1458 void * clientData, 1459 Tcl_Interp *interp, 1460 int objc, 1461 Tcl_Obj *CONST objv[] 1462 ){ 1463 sqlite3 *db; 1464 if( objc!=2 ){ 1465 Tcl_AppendResult(interp, "wrong # args: should be \"", 1466 Tcl_GetString(objv[0]), " DB", 0); 1467 return TCL_ERROR; 1468 } 1469 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1470 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_changes(db))); 1471 return TCL_OK; 1472 } 1473 1474 /* 1475 ** This is the "static_bind_value" that variables are bound to when 1476 ** the FLAG option of sqlite3_bind is "static" 1477 */ 1478 static char *sqlite_static_bind_value = 0; 1479 static int sqlite_static_bind_nbyte = 0; 1480 1481 /* 1482 ** Usage: sqlite3_bind VM IDX VALUE FLAGS 1483 ** 1484 ** Sets the value of the IDX-th occurance of "?" in the original SQL 1485 ** string. VALUE is the new value. If FLAGS=="null" then VALUE is 1486 ** ignored and the value is set to NULL. If FLAGS=="static" then 1487 ** the value is set to the value of a static variable named 1488 ** "sqlite_static_bind_value". If FLAGS=="normal" then a copy 1489 ** of the VALUE is made. If FLAGS=="blob10" then a VALUE is ignored 1490 ** an a 10-byte blob "abc\000xyz\000pq" is inserted. 1491 */ 1492 static int test_bind( 1493 void *NotUsed, 1494 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 1495 int argc, /* Number of arguments */ 1496 char **argv /* Text of each argument */ 1497 ){ 1498 sqlite3_stmt *pStmt; 1499 int rc; 1500 int idx; 1501 if( argc!=5 ){ 1502 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 1503 " VM IDX VALUE (null|static|normal)\"", 0); 1504 return TCL_ERROR; 1505 } 1506 if( getStmtPointer(interp, argv[1], &pStmt) ) return TCL_ERROR; 1507 if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR; 1508 if( strcmp(argv[4],"null")==0 ){ 1509 rc = sqlite3_bind_null(pStmt, idx); 1510 }else if( strcmp(argv[4],"static")==0 ){ 1511 rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0); 1512 }else if( strcmp(argv[4],"static-nbytes")==0 ){ 1513 rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, 1514 sqlite_static_bind_nbyte, 0); 1515 }else if( strcmp(argv[4],"normal")==0 ){ 1516 rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, SQLITE_TRANSIENT); 1517 }else if( strcmp(argv[4],"blob10")==0 ){ 1518 rc = sqlite3_bind_text(pStmt, idx, "abc\000xyz\000pq", 10, SQLITE_STATIC); 1519 }else{ 1520 Tcl_AppendResult(interp, "4th argument should be " 1521 "\"null\" or \"static\" or \"normal\"", 0); 1522 return TCL_ERROR; 1523 } 1524 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 1525 if( rc ){ 1526 char zBuf[50]; 1527 sprintf(zBuf, "(%d) ", rc); 1528 Tcl_AppendResult(interp, zBuf, sqlite3ErrStr(rc), 0); 1529 return TCL_ERROR; 1530 } 1531 return TCL_OK; 1532 } 1533 1534 #ifndef SQLITE_OMIT_UTF16 1535 /* 1536 ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be> 1537 ** 1538 ** This function is used to test that SQLite selects the correct collation 1539 ** sequence callback when multiple versions (for different text encodings) 1540 ** are available. 1541 ** 1542 ** Calling this routine registers the collation sequence "test_collate" 1543 ** with database handle <db>. The second argument must be a list of three 1544 ** boolean values. If the first is true, then a version of test_collate is 1545 ** registered for UTF-8, if the second is true, a version is registered for 1546 ** UTF-16le, if the third is true, a UTF-16be version is available. 1547 ** Previous versions of test_collate are deleted. 1548 ** 1549 ** The collation sequence test_collate is implemented by calling the 1550 ** following TCL script: 1551 ** 1552 ** "test_collate <enc> <lhs> <rhs>" 1553 ** 1554 ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8. 1555 ** The <enc> parameter is the encoding of the collation function that 1556 ** SQLite selected to call. The TCL test script implements the 1557 ** "test_collate" proc. 1558 ** 1559 ** Note that this will only work with one intepreter at a time, as the 1560 ** interp pointer to use when evaluating the TCL script is stored in 1561 ** pTestCollateInterp. 1562 */ 1563 static Tcl_Interp* pTestCollateInterp; 1564 static int test_collate_func( 1565 void *pCtx, 1566 int nA, const void *zA, 1567 int nB, const void *zB 1568 ){ 1569 Tcl_Interp *i = pTestCollateInterp; 1570 int encin = (int)pCtx; 1571 int res; 1572 int n; 1573 1574 sqlite3_value *pVal; 1575 Tcl_Obj *pX; 1576 1577 pX = Tcl_NewStringObj("test_collate", -1); 1578 Tcl_IncrRefCount(pX); 1579 1580 switch( encin ){ 1581 case SQLITE_UTF8: 1582 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-8",-1)); 1583 break; 1584 case SQLITE_UTF16LE: 1585 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16LE",-1)); 1586 break; 1587 case SQLITE_UTF16BE: 1588 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16BE",-1)); 1589 break; 1590 default: 1591 assert(0); 1592 } 1593 1594 pVal = sqlite3ValueNew(); 1595 sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC); 1596 n = sqlite3_value_bytes(pVal); 1597 Tcl_ListObjAppendElement(i,pX, 1598 Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n)); 1599 sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC); 1600 n = sqlite3_value_bytes(pVal); 1601 Tcl_ListObjAppendElement(i,pX, 1602 Tcl_NewStringObj((char*)sqlite3_value_text(pVal),n)); 1603 sqlite3ValueFree(pVal); 1604 1605 Tcl_EvalObjEx(i, pX, 0); 1606 Tcl_DecrRefCount(pX); 1607 Tcl_GetIntFromObj(i, Tcl_GetObjResult(i), &res); 1608 return res; 1609 } 1610 static int test_collate( 1611 void * clientData, 1612 Tcl_Interp *interp, 1613 int objc, 1614 Tcl_Obj *CONST objv[] 1615 ){ 1616 sqlite3 *db; 1617 int val; 1618 sqlite3_value *pVal; 1619 int rc; 1620 1621 if( objc!=5 ) goto bad_args; 1622 pTestCollateInterp = interp; 1623 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1624 1625 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; 1626 rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8, 1627 (void *)SQLITE_UTF8, val?test_collate_func:0); 1628 if( rc==SQLITE_OK ){ 1629 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; 1630 rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE, 1631 (void *)SQLITE_UTF16LE, val?test_collate_func:0); 1632 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR; 1633 1634 #ifdef SQLITE_MEMDEBUG 1635 if( sqlite3_iMallocFail>0 ){ 1636 sqlite3_iMallocFail++; 1637 } 1638 #endif 1639 pVal = sqlite3ValueNew(); 1640 sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC); 1641 rc = sqlite3_create_collation16(db, 1642 sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), SQLITE_UTF16BE, 1643 (void *)SQLITE_UTF16BE, val?test_collate_func:0); 1644 sqlite3ValueFree(pVal); 1645 } 1646 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1647 1648 if( rc!=SQLITE_OK ){ 1649 Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0); 1650 return TCL_ERROR; 1651 } 1652 return TCL_OK; 1653 1654 bad_args: 1655 Tcl_AppendResult(interp, "wrong # args: should be \"", 1656 Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); 1657 return TCL_ERROR; 1658 } 1659 1660 /* 1661 ** When the collation needed callback is invoked, record the name of 1662 ** the requested collating function here. The recorded name is linked 1663 ** to a TCL variable and used to make sure that the requested collation 1664 ** name is correct. 1665 */ 1666 static char zNeededCollation[200]; 1667 static char *pzNeededCollation = zNeededCollation; 1668 1669 1670 /* 1671 ** Called when a collating sequence is needed. Registered using 1672 ** sqlite3_collation_needed16(). 1673 */ 1674 static void test_collate_needed_cb( 1675 void *pCtx, 1676 sqlite3 *db, 1677 int eTextRep, 1678 const void *pName 1679 ){ 1680 int enc = ENC(db); 1681 int i; 1682 char *z; 1683 for(z = (char*)pName, i=0; *z || z[1]; z++){ 1684 if( *z ) zNeededCollation[i++] = *z; 1685 } 1686 zNeededCollation[i] = 0; 1687 sqlite3_create_collation( 1688 db, "test_collate", ENC(db), (void *)enc, test_collate_func); 1689 } 1690 1691 /* 1692 ** Usage: add_test_collate_needed DB 1693 */ 1694 static int test_collate_needed( 1695 void * clientData, 1696 Tcl_Interp *interp, 1697 int objc, 1698 Tcl_Obj *CONST objv[] 1699 ){ 1700 sqlite3 *db; 1701 int rc; 1702 1703 if( objc!=2 ) goto bad_args; 1704 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1705 rc = sqlite3_collation_needed16(db, 0, test_collate_needed_cb); 1706 zNeededCollation[0] = 0; 1707 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1708 return TCL_OK; 1709 1710 bad_args: 1711 Tcl_WrongNumArgs(interp, 1, objv, "DB"); 1712 return TCL_ERROR; 1713 } 1714 1715 /* 1716 ** tclcmd: add_alignment_test_collations DB 1717 ** 1718 ** Add two new collating sequences to the database DB 1719 ** 1720 ** utf16_aligned 1721 ** utf16_unaligned 1722 ** 1723 ** Both collating sequences use the same sort order as BINARY. 1724 ** The only difference is that the utf16_aligned collating 1725 ** sequence is declared with the SQLITE_UTF16_ALIGNED flag. 1726 ** Both collating functions increment the unaligned utf16 counter 1727 ** whenever they see a string that begins on an odd byte boundary. 1728 */ 1729 static int unaligned_string_counter = 0; 1730 static int alignmentCollFunc( 1731 void *NotUsed, 1732 int nKey1, const void *pKey1, 1733 int nKey2, const void *pKey2 1734 ){ 1735 int rc, n; 1736 n = nKey1<nKey2 ? nKey1 : nKey2; 1737 if( nKey1>0 && 1==(1&(int)pKey1) ) unaligned_string_counter++; 1738 if( nKey2>0 && 1==(1&(int)pKey2) ) unaligned_string_counter++; 1739 rc = memcmp(pKey1, pKey2, n); 1740 if( rc==0 ){ 1741 rc = nKey1 - nKey2; 1742 } 1743 return rc; 1744 } 1745 static int add_alignment_test_collations( 1746 void * clientData, 1747 Tcl_Interp *interp, 1748 int objc, 1749 Tcl_Obj *CONST objv[] 1750 ){ 1751 sqlite3 *db; 1752 if( objc>=2 ){ 1753 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1754 sqlite3_create_collation(db, "utf16_unaligned", 1755 SQLITE_UTF16, 1756 0, alignmentCollFunc); 1757 sqlite3_create_collation(db, "utf16_aligned", 1758 SQLITE_UTF16 | SQLITE_UTF16_ALIGNED, 1759 0, alignmentCollFunc); 1760 } 1761 return SQLITE_OK; 1762 } 1763 #endif /* !defined(SQLITE_OMIT_UTF16) */ 1764 1765 /* 1766 ** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be> 1767 ** 1768 ** This function is used to test that SQLite selects the correct user 1769 ** function callback when multiple versions (for different text encodings) 1770 ** are available. 1771 ** 1772 ** Calling this routine registers up to three versions of the user function 1773 ** "test_function" with database handle <db>. If the second argument is 1774 ** true, then a version of test_function is registered for UTF-8, if the 1775 ** third is true, a version is registered for UTF-16le, if the fourth is 1776 ** true, a UTF-16be version is available. Previous versions of 1777 ** test_function are deleted. 1778 ** 1779 ** The user function is implemented by calling the following TCL script: 1780 ** 1781 ** "test_function <enc> <arg>" 1782 ** 1783 ** Where <enc> is one of UTF-8, UTF-16LE or UTF16BE, and <arg> is the 1784 ** single argument passed to the SQL function. The value returned by 1785 ** the TCL script is used as the return value of the SQL function. It 1786 ** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8 1787 ** for a UTF-16LE test_function(), and UTF-16LE for an implementation that 1788 ** prefers UTF-16BE. 1789 */ 1790 #ifndef SQLITE_OMIT_UTF16 1791 static void test_function_utf8( 1792 sqlite3_context *pCtx, 1793 int nArg, 1794 sqlite3_value **argv 1795 ){ 1796 Tcl_Interp *interp; 1797 Tcl_Obj *pX; 1798 sqlite3_value *pVal; 1799 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1800 pX = Tcl_NewStringObj("test_function", -1); 1801 Tcl_IncrRefCount(pX); 1802 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-8", -1)); 1803 Tcl_ListObjAppendElement(interp, pX, 1804 Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1)); 1805 Tcl_EvalObjEx(interp, pX, 0); 1806 Tcl_DecrRefCount(pX); 1807 sqlite3_result_text(pCtx, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT); 1808 pVal = sqlite3ValueNew(); 1809 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1810 SQLITE_UTF8, SQLITE_STATIC); 1811 sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal), 1812 -1, SQLITE_TRANSIENT); 1813 sqlite3ValueFree(pVal); 1814 } 1815 static void test_function_utf16le( 1816 sqlite3_context *pCtx, 1817 int nArg, 1818 sqlite3_value **argv 1819 ){ 1820 Tcl_Interp *interp; 1821 Tcl_Obj *pX; 1822 sqlite3_value *pVal; 1823 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1824 pX = Tcl_NewStringObj("test_function", -1); 1825 Tcl_IncrRefCount(pX); 1826 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16LE", -1)); 1827 Tcl_ListObjAppendElement(interp, pX, 1828 Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1)); 1829 Tcl_EvalObjEx(interp, pX, 0); 1830 Tcl_DecrRefCount(pX); 1831 pVal = sqlite3ValueNew(); 1832 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1833 SQLITE_UTF8, SQLITE_STATIC); 1834 sqlite3_result_text(pCtx,(char*)sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT); 1835 sqlite3ValueFree(pVal); 1836 } 1837 static void test_function_utf16be( 1838 sqlite3_context *pCtx, 1839 int nArg, 1840 sqlite3_value **argv 1841 ){ 1842 Tcl_Interp *interp; 1843 Tcl_Obj *pX; 1844 sqlite3_value *pVal; 1845 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1846 pX = Tcl_NewStringObj("test_function", -1); 1847 Tcl_IncrRefCount(pX); 1848 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16BE", -1)); 1849 Tcl_ListObjAppendElement(interp, pX, 1850 Tcl_NewStringObj((char*)sqlite3_value_text(argv[0]), -1)); 1851 Tcl_EvalObjEx(interp, pX, 0); 1852 Tcl_DecrRefCount(pX); 1853 pVal = sqlite3ValueNew(); 1854 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1855 SQLITE_UTF8, SQLITE_STATIC); 1856 sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal), 1857 -1, SQLITE_TRANSIENT); 1858 sqlite3ValueFree(pVal); 1859 } 1860 #endif /* SQLITE_OMIT_UTF16 */ 1861 static int test_function( 1862 void * clientData, 1863 Tcl_Interp *interp, 1864 int objc, 1865 Tcl_Obj *CONST objv[] 1866 ){ 1867 #ifndef SQLITE_OMIT_UTF16 1868 sqlite3 *db; 1869 int val; 1870 1871 if( objc!=5 ) goto bad_args; 1872 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1873 1874 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; 1875 if( val ){ 1876 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF8, 1877 interp, test_function_utf8, 0, 0); 1878 } 1879 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; 1880 if( val ){ 1881 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16LE, 1882 interp, test_function_utf16le, 0, 0); 1883 } 1884 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR; 1885 if( val ){ 1886 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16BE, 1887 interp, test_function_utf16be, 0, 0); 1888 } 1889 1890 return TCL_OK; 1891 bad_args: 1892 Tcl_AppendResult(interp, "wrong # args: should be \"", 1893 Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); 1894 #endif /* SQLITE_OMIT_UTF16 */ 1895 return TCL_ERROR; 1896 } 1897 1898 /* 1899 ** Usage: test_errstr <err code> 1900 ** 1901 ** Test that the english language string equivalents for sqlite error codes 1902 ** are sane. The parameter is an integer representing an sqlite error code. 1903 ** The result is a list of two elements, the string representation of the 1904 ** error code and the english language explanation. 1905 */ 1906 static int test_errstr( 1907 void * clientData, 1908 Tcl_Interp *interp, 1909 int objc, 1910 Tcl_Obj *CONST objv[] 1911 ){ 1912 char *zCode; 1913 int i; 1914 if( objc!=1 ){ 1915 Tcl_WrongNumArgs(interp, 1, objv, "<error code>"); 1916 } 1917 1918 zCode = Tcl_GetString(objv[1]); 1919 for(i=0; i<200; i++){ 1920 if( 0==strcmp(errorName(i), zCode) ) break; 1921 } 1922 Tcl_SetResult(interp, (char *)sqlite3ErrStr(i), 0); 1923 return TCL_OK; 1924 } 1925 1926 /* 1927 ** Usage: breakpoint 1928 ** 1929 ** This routine exists for one purpose - to provide a place to put a 1930 ** breakpoint with GDB that can be triggered using TCL code. The use 1931 ** for this is when a particular test fails on (say) the 1485th iteration. 1932 ** In the TCL test script, we can add code like this: 1933 ** 1934 ** if {$i==1485} breakpoint 1935 ** 1936 ** Then run testfixture in the debugger and wait for the breakpoint to 1937 ** fire. Then additional breakpoints can be set to trace down the bug. 1938 */ 1939 static int test_breakpoint( 1940 void *NotUsed, 1941 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 1942 int argc, /* Number of arguments */ 1943 char **argv /* Text of each argument */ 1944 ){ 1945 return TCL_OK; /* Do nothing */ 1946 } 1947 1948 /* 1949 ** Usage: sqlite3_bind_int STMT N VALUE 1950 ** 1951 ** Test the sqlite3_bind_int interface. STMT is a prepared statement. 1952 ** N is the index of a wildcard in the prepared statement. This command 1953 ** binds a 32-bit integer VALUE to that wildcard. 1954 */ 1955 static int test_bind_int( 1956 void * clientData, 1957 Tcl_Interp *interp, 1958 int objc, 1959 Tcl_Obj *CONST objv[] 1960 ){ 1961 sqlite3_stmt *pStmt; 1962 int idx; 1963 int value; 1964 int rc; 1965 1966 if( objc!=4 ){ 1967 Tcl_AppendResult(interp, "wrong # args: should be \"", 1968 Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 1969 return TCL_ERROR; 1970 } 1971 1972 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1973 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1974 if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR; 1975 1976 rc = sqlite3_bind_int(pStmt, idx, value); 1977 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 1978 if( rc!=SQLITE_OK ){ 1979 return TCL_ERROR; 1980 } 1981 1982 return TCL_OK; 1983 } 1984 1985 1986 /* 1987 ** Usage: sqlite3_bind_int64 STMT N VALUE 1988 ** 1989 ** Test the sqlite3_bind_int64 interface. STMT is a prepared statement. 1990 ** N is the index of a wildcard in the prepared statement. This command 1991 ** binds a 64-bit integer VALUE to that wildcard. 1992 */ 1993 static int test_bind_int64( 1994 void * clientData, 1995 Tcl_Interp *interp, 1996 int objc, 1997 Tcl_Obj *CONST objv[] 1998 ){ 1999 sqlite3_stmt *pStmt; 2000 int idx; 2001 i64 value; 2002 int rc; 2003 2004 if( objc!=4 ){ 2005 Tcl_AppendResult(interp, "wrong # args: should be \"", 2006 Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 2007 return TCL_ERROR; 2008 } 2009 2010 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2011 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 2012 if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR; 2013 2014 rc = sqlite3_bind_int64(pStmt, idx, value); 2015 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 2016 if( rc!=SQLITE_OK ){ 2017 return TCL_ERROR; 2018 } 2019 2020 return TCL_OK; 2021 } 2022 2023 2024 /* 2025 ** Usage: sqlite3_bind_double STMT N VALUE 2026 ** 2027 ** Test the sqlite3_bind_double interface. STMT is a prepared statement. 2028 ** N is the index of a wildcard in the prepared statement. This command 2029 ** binds a 64-bit integer VALUE to that wildcard. 2030 */ 2031 static int test_bind_double( 2032 void * clientData, 2033 Tcl_Interp *interp, 2034 int objc, 2035 Tcl_Obj *CONST objv[] 2036 ){ 2037 sqlite3_stmt *pStmt; 2038 int idx; 2039 double value; 2040 int rc; 2041 2042 if( objc!=4 ){ 2043 Tcl_AppendResult(interp, "wrong # args: should be \"", 2044 Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 2045 return TCL_ERROR; 2046 } 2047 2048 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2049 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 2050 if( Tcl_GetDoubleFromObj(interp, objv[3], &value) ) return TCL_ERROR; 2051 2052 rc = sqlite3_bind_double(pStmt, idx, value); 2053 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 2054 if( rc!=SQLITE_OK ){ 2055 return TCL_ERROR; 2056 } 2057 2058 return TCL_OK; 2059 } 2060 2061 /* 2062 ** Usage: sqlite3_bind_null STMT N 2063 ** 2064 ** Test the sqlite3_bind_null interface. STMT is a prepared statement. 2065 ** N is the index of a wildcard in the prepared statement. This command 2066 ** binds a NULL to the wildcard. 2067 */ 2068 static int test_bind_null( 2069 void * clientData, 2070 Tcl_Interp *interp, 2071 int objc, 2072 Tcl_Obj *CONST objv[] 2073 ){ 2074 sqlite3_stmt *pStmt; 2075 int idx; 2076 int rc; 2077 2078 if( objc!=3 ){ 2079 Tcl_AppendResult(interp, "wrong # args: should be \"", 2080 Tcl_GetStringFromObj(objv[0], 0), " STMT N", 0); 2081 return TCL_ERROR; 2082 } 2083 2084 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2085 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 2086 2087 rc = sqlite3_bind_null(pStmt, idx); 2088 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 2089 if( rc!=SQLITE_OK ){ 2090 return TCL_ERROR; 2091 } 2092 2093 return TCL_OK; 2094 } 2095 2096 /* 2097 ** Usage: sqlite3_bind_text STMT N STRING BYTES 2098 ** 2099 ** Test the sqlite3_bind_text interface. STMT is a prepared statement. 2100 ** N is the index of a wildcard in the prepared statement. This command 2101 ** binds a UTF-8 string STRING to the wildcard. The string is BYTES bytes 2102 ** long. 2103 */ 2104 static int test_bind_text( 2105 void * clientData, 2106 Tcl_Interp *interp, 2107 int objc, 2108 Tcl_Obj *CONST objv[] 2109 ){ 2110 sqlite3_stmt *pStmt; 2111 int idx; 2112 int bytes; 2113 char *value; 2114 int rc; 2115 2116 if( objc!=5 ){ 2117 Tcl_AppendResult(interp, "wrong # args: should be \"", 2118 Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0); 2119 return TCL_ERROR; 2120 } 2121 2122 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2123 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 2124 value = Tcl_GetString(objv[3]); 2125 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 2126 2127 rc = sqlite3_bind_text(pStmt, idx, value, bytes, SQLITE_TRANSIENT); 2128 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 2129 if( rc!=SQLITE_OK ){ 2130 Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0); 2131 return TCL_ERROR; 2132 } 2133 2134 return TCL_OK; 2135 } 2136 2137 /* 2138 ** Usage: sqlite3_bind_text16 ?-static? STMT N STRING BYTES 2139 ** 2140 ** Test the sqlite3_bind_text16 interface. STMT is a prepared statement. 2141 ** N is the index of a wildcard in the prepared statement. This command 2142 ** binds a UTF-16 string STRING to the wildcard. The string is BYTES bytes 2143 ** long. 2144 */ 2145 static int test_bind_text16( 2146 void * clientData, 2147 Tcl_Interp *interp, 2148 int objc, 2149 Tcl_Obj *CONST objv[] 2150 ){ 2151 #ifndef SQLITE_OMIT_UTF16 2152 sqlite3_stmt *pStmt; 2153 int idx; 2154 int bytes; 2155 char *value; 2156 int rc; 2157 2158 void (*xDel)() = (objc==6?SQLITE_STATIC:SQLITE_TRANSIENT); 2159 Tcl_Obj *oStmt = objv[objc-4]; 2160 Tcl_Obj *oN = objv[objc-3]; 2161 Tcl_Obj *oString = objv[objc-2]; 2162 Tcl_Obj *oBytes = objv[objc-1]; 2163 2164 if( objc!=5 && objc!=6){ 2165 Tcl_AppendResult(interp, "wrong # args: should be \"", 2166 Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0); 2167 return TCL_ERROR; 2168 } 2169 2170 if( getStmtPointer(interp, Tcl_GetString(oStmt), &pStmt) ) return TCL_ERROR; 2171 if( Tcl_GetIntFromObj(interp, oN, &idx) ) return TCL_ERROR; 2172 value = (char*)Tcl_GetByteArrayFromObj(oString, 0); 2173 if( Tcl_GetIntFromObj(interp, oBytes, &bytes) ) return TCL_ERROR; 2174 2175 rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, xDel); 2176 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 2177 if( rc!=SQLITE_OK ){ 2178 return TCL_ERROR; 2179 } 2180 2181 #endif /* SQLITE_OMIT_UTF16 */ 2182 return TCL_OK; 2183 } 2184 2185 /* 2186 ** Usage: sqlite3_bind_blob STMT N DATA BYTES 2187 ** 2188 ** Test the sqlite3_bind_blob interface. STMT is a prepared statement. 2189 ** N is the index of a wildcard in the prepared statement. This command 2190 ** binds a BLOB to the wildcard. The BLOB is BYTES bytes in size. 2191 */ 2192 static int test_bind_blob( 2193 void * clientData, 2194 Tcl_Interp *interp, 2195 int objc, 2196 Tcl_Obj *CONST objv[] 2197 ){ 2198 sqlite3_stmt *pStmt; 2199 int idx; 2200 int bytes; 2201 char *value; 2202 int rc; 2203 2204 if( objc!=5 ){ 2205 Tcl_AppendResult(interp, "wrong # args: should be \"", 2206 Tcl_GetStringFromObj(objv[0], 0), " STMT N DATA BYTES", 0); 2207 return TCL_ERROR; 2208 } 2209 2210 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2211 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 2212 value = Tcl_GetString(objv[3]); 2213 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 2214 2215 rc = sqlite3_bind_blob(pStmt, idx, value, bytes, SQLITE_TRANSIENT); 2216 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 2217 if( rc!=SQLITE_OK ){ 2218 return TCL_ERROR; 2219 } 2220 2221 return TCL_OK; 2222 } 2223 2224 /* 2225 ** Usage: sqlite3_bind_parameter_count STMT 2226 ** 2227 ** Return the number of wildcards in the given statement. 2228 */ 2229 static int test_bind_parameter_count( 2230 void * clientData, 2231 Tcl_Interp *interp, 2232 int objc, 2233 Tcl_Obj *CONST objv[] 2234 ){ 2235 sqlite3_stmt *pStmt; 2236 2237 if( objc!=2 ){ 2238 Tcl_WrongNumArgs(interp, 1, objv, "STMT"); 2239 return TCL_ERROR; 2240 } 2241 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2242 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_bind_parameter_count(pStmt))); 2243 return TCL_OK; 2244 } 2245 2246 /* 2247 ** Usage: sqlite3_bind_parameter_name STMT N 2248 ** 2249 ** Return the name of the Nth wildcard. The first wildcard is 1. 2250 ** An empty string is returned if N is out of range or if the wildcard 2251 ** is nameless. 2252 */ 2253 static int test_bind_parameter_name( 2254 void * clientData, 2255 Tcl_Interp *interp, 2256 int objc, 2257 Tcl_Obj *CONST objv[] 2258 ){ 2259 sqlite3_stmt *pStmt; 2260 int i; 2261 2262 if( objc!=3 ){ 2263 Tcl_WrongNumArgs(interp, 1, objv, "STMT N"); 2264 return TCL_ERROR; 2265 } 2266 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2267 if( Tcl_GetIntFromObj(interp, objv[2], &i) ) return TCL_ERROR; 2268 Tcl_SetObjResult(interp, 2269 Tcl_NewStringObj(sqlite3_bind_parameter_name(pStmt,i),-1) 2270 ); 2271 return TCL_OK; 2272 } 2273 2274 /* 2275 ** Usage: sqlite3_bind_parameter_index STMT NAME 2276 ** 2277 ** Return the index of the wildcard called NAME. Return 0 if there is 2278 ** no such wildcard. 2279 */ 2280 static int test_bind_parameter_index( 2281 void * clientData, 2282 Tcl_Interp *interp, 2283 int objc, 2284 Tcl_Obj *CONST objv[] 2285 ){ 2286 sqlite3_stmt *pStmt; 2287 2288 if( objc!=3 ){ 2289 Tcl_WrongNumArgs(interp, 1, objv, "STMT NAME"); 2290 return TCL_ERROR; 2291 } 2292 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2293 Tcl_SetObjResult(interp, 2294 Tcl_NewIntObj( 2295 sqlite3_bind_parameter_index(pStmt,Tcl_GetString(objv[2])) 2296 ) 2297 ); 2298 return TCL_OK; 2299 } 2300 2301 /* 2302 ** Usage: sqlite3_clear_bindings STMT 2303 ** 2304 */ 2305 static int test_clear_bindings( 2306 void * clientData, 2307 Tcl_Interp *interp, 2308 int objc, 2309 Tcl_Obj *CONST objv[] 2310 ){ 2311 sqlite3_stmt *pStmt; 2312 2313 if( objc!=2 ){ 2314 Tcl_WrongNumArgs(interp, 1, objv, "STMT"); 2315 return TCL_ERROR; 2316 } 2317 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2318 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(pStmt))); 2319 return TCL_OK; 2320 } 2321 2322 /* 2323 ** Usage: sqlite3_sleep MILLISECONDS 2324 */ 2325 static int test_sleep( 2326 void * clientData, 2327 Tcl_Interp *interp, 2328 int objc, 2329 Tcl_Obj *CONST objv[] 2330 ){ 2331 int ms; 2332 2333 if( objc!=2 ){ 2334 Tcl_WrongNumArgs(interp, 1, objv, "MILLISECONDS"); 2335 return TCL_ERROR; 2336 } 2337 if( Tcl_GetIntFromObj(interp, objv[1], &ms) ){ 2338 return TCL_ERROR; 2339 } 2340 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_sleep(ms))); 2341 return TCL_OK; 2342 } 2343 2344 /* 2345 ** Usage: sqlite3_errcode DB 2346 ** 2347 ** Return the string representation of the most recent sqlite3_* API 2348 ** error code. e.g. "SQLITE_ERROR". 2349 */ 2350 static int test_errcode( 2351 void * clientData, 2352 Tcl_Interp *interp, 2353 int objc, 2354 Tcl_Obj *CONST objv[] 2355 ){ 2356 sqlite3 *db; 2357 int rc; 2358 char zBuf[30]; 2359 2360 if( objc!=2 ){ 2361 Tcl_AppendResult(interp, "wrong # args: should be \"", 2362 Tcl_GetString(objv[0]), " DB", 0); 2363 return TCL_ERROR; 2364 } 2365 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 2366 rc = sqlite3_errcode(db); 2367 if( (rc&0xff)==rc ){ 2368 zBuf[0] = 0; 2369 }else{ 2370 sprintf(zBuf,"+%d", rc>>8); 2371 } 2372 Tcl_AppendResult(interp, (char *)errorName(rc), zBuf, 0); 2373 return TCL_OK; 2374 } 2375 2376 /* 2377 ** Usage: test_errmsg DB 2378 ** 2379 ** Returns the UTF-8 representation of the error message string for the 2380 ** most recent sqlite3_* API call. 2381 */ 2382 static int test_errmsg( 2383 void * clientData, 2384 Tcl_Interp *interp, 2385 int objc, 2386 Tcl_Obj *CONST objv[] 2387 ){ 2388 sqlite3 *db; 2389 const char *zErr; 2390 2391 if( objc!=2 ){ 2392 Tcl_AppendResult(interp, "wrong # args: should be \"", 2393 Tcl_GetString(objv[0]), " DB", 0); 2394 return TCL_ERROR; 2395 } 2396 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 2397 2398 zErr = sqlite3_errmsg(db); 2399 Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1)); 2400 return TCL_OK; 2401 } 2402 2403 /* 2404 ** Usage: test_errmsg16 DB 2405 ** 2406 ** Returns the UTF-16 representation of the error message string for the 2407 ** most recent sqlite3_* API call. This is a byte array object at the TCL 2408 ** level, and it includes the 0x00 0x00 terminator bytes at the end of the 2409 ** UTF-16 string. 2410 */ 2411 static int test_errmsg16( 2412 void * clientData, 2413 Tcl_Interp *interp, 2414 int objc, 2415 Tcl_Obj *CONST objv[] 2416 ){ 2417 #ifndef SQLITE_OMIT_UTF16 2418 sqlite3 *db; 2419 const void *zErr; 2420 int bytes = 0; 2421 2422 if( objc!=2 ){ 2423 Tcl_AppendResult(interp, "wrong # args: should be \"", 2424 Tcl_GetString(objv[0]), " DB", 0); 2425 return TCL_ERROR; 2426 } 2427 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 2428 2429 zErr = sqlite3_errmsg16(db); 2430 if( zErr ){ 2431 bytes = sqlite3utf16ByteLen(zErr, -1); 2432 } 2433 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes)); 2434 #endif /* SQLITE_OMIT_UTF16 */ 2435 return TCL_OK; 2436 } 2437 2438 /* 2439 ** Usage: sqlite3_prepare DB sql bytes tailvar 2440 ** 2441 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using 2442 ** database handle <DB>. The parameter <tailval> is the name of a global 2443 ** variable that is set to the unused portion of <sql> (if any). A 2444 ** STMT handle is returned. 2445 */ 2446 static int test_prepare( 2447 void * clientData, 2448 Tcl_Interp *interp, 2449 int objc, 2450 Tcl_Obj *CONST objv[] 2451 ){ 2452 sqlite3 *db; 2453 const char *zSql; 2454 int bytes; 2455 const char *zTail = 0; 2456 sqlite3_stmt *pStmt = 0; 2457 char zBuf[50]; 2458 int rc; 2459 2460 if( objc!=5 ){ 2461 Tcl_AppendResult(interp, "wrong # args: should be \"", 2462 Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); 2463 return TCL_ERROR; 2464 } 2465 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 2466 zSql = Tcl_GetString(objv[2]); 2467 if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; 2468 2469 rc = sqlite3_prepare(db, zSql, bytes, &pStmt, &zTail); 2470 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 2471 if( zTail ){ 2472 if( bytes>=0 ){ 2473 bytes = bytes - (zTail-zSql); 2474 } 2475 Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0); 2476 } 2477 if( rc!=SQLITE_OK ){ 2478 assert( pStmt==0 ); 2479 sprintf(zBuf, "(%d) ", rc); 2480 Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0); 2481 return TCL_ERROR; 2482 } 2483 2484 if( pStmt ){ 2485 if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; 2486 Tcl_AppendResult(interp, zBuf, 0); 2487 } 2488 return TCL_OK; 2489 } 2490 2491 /* 2492 ** Usage: sqlite3_prepare DB sql bytes tailvar 2493 ** 2494 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using 2495 ** database handle <DB>. The parameter <tailval> is the name of a global 2496 ** variable that is set to the unused portion of <sql> (if any). A 2497 ** STMT handle is returned. 2498 */ 2499 static int test_prepare16( 2500 void * clientData, 2501 Tcl_Interp *interp, 2502 int objc, 2503 Tcl_Obj *CONST objv[] 2504 ){ 2505 #ifndef SQLITE_OMIT_UTF16 2506 sqlite3 *db; 2507 const void *zSql; 2508 const void *zTail = 0; 2509 Tcl_Obj *pTail = 0; 2510 sqlite3_stmt *pStmt = 0; 2511 char zBuf[50]; 2512 int rc; 2513 int bytes; /* The integer specified as arg 3 */ 2514 int objlen; /* The byte-array length of arg 2 */ 2515 2516 if( objc!=5 ){ 2517 Tcl_AppendResult(interp, "wrong # args: should be \"", 2518 Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); 2519 return TCL_ERROR; 2520 } 2521 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 2522 zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen); 2523 if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; 2524 2525 rc = sqlite3_prepare16(db, zSql, bytes, &pStmt, &zTail); 2526 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 2527 if( rc ){ 2528 return TCL_ERROR; 2529 } 2530 2531 if( zTail ){ 2532 objlen = objlen - ((u8 *)zTail-(u8 *)zSql); 2533 }else{ 2534 objlen = 0; 2535 } 2536 pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen); 2537 Tcl_IncrRefCount(pTail); 2538 Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0); 2539 Tcl_DecrRefCount(pTail); 2540 2541 if( pStmt ){ 2542 if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; 2543 } 2544 Tcl_AppendResult(interp, zBuf, 0); 2545 #endif /* SQLITE_OMIT_UTF16 */ 2546 return TCL_OK; 2547 } 2548 2549 /* 2550 ** Usage: sqlite3_open filename ?options-list? 2551 */ 2552 static int test_open( 2553 void * clientData, 2554 Tcl_Interp *interp, 2555 int objc, 2556 Tcl_Obj *CONST objv[] 2557 ){ 2558 const char *zFilename; 2559 sqlite3 *db; 2560 int rc; 2561 char zBuf[100]; 2562 2563 if( objc!=3 && objc!=2 ){ 2564 Tcl_AppendResult(interp, "wrong # args: should be \"", 2565 Tcl_GetString(objv[0]), " filename options-list", 0); 2566 return TCL_ERROR; 2567 } 2568 2569 zFilename = Tcl_GetString(objv[1]); 2570 rc = sqlite3_open(zFilename, &db); 2571 2572 if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR; 2573 Tcl_AppendResult(interp, zBuf, 0); 2574 return TCL_OK; 2575 } 2576 2577 /* 2578 ** Usage: sqlite3_open16 filename options 2579 */ 2580 static int test_open16( 2581 void * clientData, 2582 Tcl_Interp *interp, 2583 int objc, 2584 Tcl_Obj *CONST objv[] 2585 ){ 2586 #ifndef SQLITE_OMIT_UTF16 2587 const void *zFilename; 2588 sqlite3 *db; 2589 int rc; 2590 char zBuf[100]; 2591 2592 if( objc!=3 ){ 2593 Tcl_AppendResult(interp, "wrong # args: should be \"", 2594 Tcl_GetString(objv[0]), " filename options-list", 0); 2595 return TCL_ERROR; 2596 } 2597 2598 zFilename = Tcl_GetByteArrayFromObj(objv[1], 0); 2599 rc = sqlite3_open16(zFilename, &db); 2600 2601 if( sqlite3TestMakePointerStr(interp, zBuf, db) ) return TCL_ERROR; 2602 Tcl_AppendResult(interp, zBuf, 0); 2603 #endif /* SQLITE_OMIT_UTF16 */ 2604 return TCL_OK; 2605 } 2606 2607 /* 2608 ** Usage: sqlite3_complete16 <UTF-16 string> 2609 ** 2610 ** Return 1 if the supplied argument is a complete SQL statement, or zero 2611 ** otherwise. 2612 */ 2613 static int test_complete16( 2614 void * clientData, 2615 Tcl_Interp *interp, 2616 int objc, 2617 Tcl_Obj *CONST objv[] 2618 ){ 2619 #if !defined(SQLITE_OMIT_COMPLETE) && !defined(SQLITE_OMIT_UTF16) 2620 char *zBuf; 2621 2622 if( objc!=2 ){ 2623 Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>"); 2624 return TCL_ERROR; 2625 } 2626 2627 zBuf = (char*)Tcl_GetByteArrayFromObj(objv[1], 0); 2628 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_complete16(zBuf))); 2629 #endif /* SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */ 2630 return TCL_OK; 2631 } 2632 2633 /* 2634 ** Usage: sqlite3_step STMT 2635 ** 2636 ** Advance the statement to the next row. 2637 */ 2638 static int test_step( 2639 void * clientData, 2640 Tcl_Interp *interp, 2641 int objc, 2642 Tcl_Obj *CONST objv[] 2643 ){ 2644 sqlite3_stmt *pStmt; 2645 int rc; 2646 2647 if( objc!=2 ){ 2648 Tcl_AppendResult(interp, "wrong # args: should be \"", 2649 Tcl_GetString(objv[0]), " STMT", 0); 2650 return TCL_ERROR; 2651 } 2652 2653 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2654 rc = sqlite3_step(pStmt); 2655 2656 /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; */ 2657 Tcl_SetResult(interp, (char *)errorName(rc), 0); 2658 return TCL_OK; 2659 } 2660 2661 /* 2662 ** Usage: sqlite3_column_count STMT 2663 ** 2664 ** Return the number of columns returned by the sql statement STMT. 2665 */ 2666 static int test_column_count( 2667 void * clientData, 2668 Tcl_Interp *interp, 2669 int objc, 2670 Tcl_Obj *CONST objv[] 2671 ){ 2672 sqlite3_stmt *pStmt; 2673 2674 if( objc!=2 ){ 2675 Tcl_AppendResult(interp, "wrong # args: should be \"", 2676 Tcl_GetString(objv[0]), " STMT column", 0); 2677 return TCL_ERROR; 2678 } 2679 2680 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2681 2682 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_column_count(pStmt))); 2683 return TCL_OK; 2684 } 2685 2686 /* 2687 ** Usage: sqlite3_column_type STMT column 2688 ** 2689 ** Return the type of the data in column 'column' of the current row. 2690 */ 2691 static int test_column_type( 2692 void * clientData, 2693 Tcl_Interp *interp, 2694 int objc, 2695 Tcl_Obj *CONST objv[] 2696 ){ 2697 sqlite3_stmt *pStmt; 2698 int col; 2699 int tp; 2700 2701 if( objc!=3 ){ 2702 Tcl_AppendResult(interp, "wrong # args: should be \"", 2703 Tcl_GetString(objv[0]), " STMT column", 0); 2704 return TCL_ERROR; 2705 } 2706 2707 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2708 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2709 2710 tp = sqlite3_column_type(pStmt, col); 2711 switch( tp ){ 2712 case SQLITE_INTEGER: 2713 Tcl_SetResult(interp, "INTEGER", TCL_STATIC); 2714 break; 2715 case SQLITE_NULL: 2716 Tcl_SetResult(interp, "NULL", TCL_STATIC); 2717 break; 2718 case SQLITE_FLOAT: 2719 Tcl_SetResult(interp, "FLOAT", TCL_STATIC); 2720 break; 2721 case SQLITE_TEXT: 2722 Tcl_SetResult(interp, "TEXT", TCL_STATIC); 2723 break; 2724 case SQLITE_BLOB: 2725 Tcl_SetResult(interp, "BLOB", TCL_STATIC); 2726 break; 2727 default: 2728 assert(0); 2729 } 2730 2731 return TCL_OK; 2732 } 2733 2734 /* 2735 ** Usage: sqlite3_column_int64 STMT column 2736 ** 2737 ** Return the data in column 'column' of the current row cast as an 2738 ** wide (64-bit) integer. 2739 */ 2740 static int test_column_int64( 2741 void * clientData, 2742 Tcl_Interp *interp, 2743 int objc, 2744 Tcl_Obj *CONST objv[] 2745 ){ 2746 sqlite3_stmt *pStmt; 2747 int col; 2748 i64 iVal; 2749 2750 if( objc!=3 ){ 2751 Tcl_AppendResult(interp, "wrong # args: should be \"", 2752 Tcl_GetString(objv[0]), " STMT column", 0); 2753 return TCL_ERROR; 2754 } 2755 2756 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2757 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2758 2759 iVal = sqlite3_column_int64(pStmt, col); 2760 Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iVal)); 2761 return TCL_OK; 2762 } 2763 2764 /* 2765 ** Usage: sqlite3_column_blob STMT column 2766 */ 2767 static int test_column_blob( 2768 void * clientData, 2769 Tcl_Interp *interp, 2770 int objc, 2771 Tcl_Obj *CONST objv[] 2772 ){ 2773 sqlite3_stmt *pStmt; 2774 int col; 2775 2776 int len; 2777 const void *pBlob; 2778 2779 if( objc!=3 ){ 2780 Tcl_AppendResult(interp, "wrong # args: should be \"", 2781 Tcl_GetString(objv[0]), " STMT column", 0); 2782 return TCL_ERROR; 2783 } 2784 2785 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2786 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2787 2788 pBlob = sqlite3_column_blob(pStmt, col); 2789 len = sqlite3_column_bytes(pStmt, col); 2790 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len)); 2791 return TCL_OK; 2792 } 2793 2794 /* 2795 ** Usage: sqlite3_column_double STMT column 2796 ** 2797 ** Return the data in column 'column' of the current row cast as a double. 2798 */ 2799 static int test_column_double( 2800 void * clientData, 2801 Tcl_Interp *interp, 2802 int objc, 2803 Tcl_Obj *CONST objv[] 2804 ){ 2805 sqlite3_stmt *pStmt; 2806 int col; 2807 double rVal; 2808 2809 if( objc!=3 ){ 2810 Tcl_AppendResult(interp, "wrong # args: should be \"", 2811 Tcl_GetString(objv[0]), " STMT column", 0); 2812 return TCL_ERROR; 2813 } 2814 2815 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2816 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2817 2818 rVal = sqlite3_column_double(pStmt, col); 2819 Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rVal)); 2820 return TCL_OK; 2821 } 2822 2823 /* 2824 ** Usage: sqlite3_data_count STMT 2825 ** 2826 ** Return the number of columns returned by the sql statement STMT. 2827 */ 2828 static int test_data_count( 2829 void * clientData, 2830 Tcl_Interp *interp, 2831 int objc, 2832 Tcl_Obj *CONST objv[] 2833 ){ 2834 sqlite3_stmt *pStmt; 2835 2836 if( objc!=2 ){ 2837 Tcl_AppendResult(interp, "wrong # args: should be \"", 2838 Tcl_GetString(objv[0]), " STMT column", 0); 2839 return TCL_ERROR; 2840 } 2841 2842 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2843 2844 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_data_count(pStmt))); 2845 return TCL_OK; 2846 } 2847 2848 /* 2849 ** Usage: sqlite3_column_text STMT column 2850 ** 2851 ** Usage: sqlite3_column_decltype STMT column 2852 ** 2853 ** Usage: sqlite3_column_name STMT column 2854 */ 2855 static int test_stmt_utf8( 2856 void * clientData, /* Pointer to SQLite API function to be invoke */ 2857 Tcl_Interp *interp, 2858 int objc, 2859 Tcl_Obj *CONST objv[] 2860 ){ 2861 sqlite3_stmt *pStmt; 2862 int col; 2863 const char *(*xFunc)(sqlite3_stmt*, int) = clientData; 2864 const char *zRet; 2865 2866 if( objc!=3 ){ 2867 Tcl_AppendResult(interp, "wrong # args: should be \"", 2868 Tcl_GetString(objv[0]), " STMT column", 0); 2869 return TCL_ERROR; 2870 } 2871 2872 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2873 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2874 zRet = xFunc(pStmt, col); 2875 if( zRet ){ 2876 Tcl_SetResult(interp, (char *)zRet, 0); 2877 } 2878 return TCL_OK; 2879 } 2880 2881 static int test_global_recover( 2882 void * clientData, 2883 Tcl_Interp *interp, 2884 int objc, 2885 Tcl_Obj *CONST objv[] 2886 ){ 2887 #ifndef SQLITE_OMIT_GLOBALRECOVER 2888 int rc; 2889 if( objc!=1 ){ 2890 Tcl_WrongNumArgs(interp, 1, objv, ""); 2891 return TCL_ERROR; 2892 } 2893 rc = sqlite3_global_recover(); 2894 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 2895 #endif 2896 return TCL_OK; 2897 } 2898 2899 /* 2900 ** Usage: sqlite3_column_text STMT column 2901 ** 2902 ** Usage: sqlite3_column_decltype STMT column 2903 ** 2904 ** Usage: sqlite3_column_name STMT column 2905 */ 2906 static int test_stmt_utf16( 2907 void * clientData, /* Pointer to SQLite API function to be invoked */ 2908 Tcl_Interp *interp, 2909 int objc, 2910 Tcl_Obj *CONST objv[] 2911 ){ 2912 #ifndef SQLITE_OMIT_UTF16 2913 sqlite3_stmt *pStmt; 2914 int col; 2915 Tcl_Obj *pRet; 2916 const void *zName16; 2917 const void *(*xFunc)(sqlite3_stmt*, int) = clientData; 2918 2919 if( objc!=3 ){ 2920 Tcl_AppendResult(interp, "wrong # args: should be \"", 2921 Tcl_GetString(objv[0]), " STMT column", 0); 2922 return TCL_ERROR; 2923 } 2924 2925 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2926 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2927 2928 zName16 = xFunc(pStmt, col); 2929 if( zName16 ){ 2930 pRet = Tcl_NewByteArrayObj(zName16, sqlite3utf16ByteLen(zName16, -1)+2); 2931 Tcl_SetObjResult(interp, pRet); 2932 } 2933 #endif /* SQLITE_OMIT_UTF16 */ 2934 2935 return TCL_OK; 2936 } 2937 2938 /* 2939 ** Usage: sqlite3_column_int STMT column 2940 ** 2941 ** Usage: sqlite3_column_bytes STMT column 2942 ** 2943 ** Usage: sqlite3_column_bytes16 STMT column 2944 ** 2945 */ 2946 static int test_stmt_int( 2947 void * clientData, /* Pointer to SQLite API function to be invoked */ 2948 Tcl_Interp *interp, 2949 int objc, 2950 Tcl_Obj *CONST objv[] 2951 ){ 2952 sqlite3_stmt *pStmt; 2953 int col; 2954 int (*xFunc)(sqlite3_stmt*, int) = clientData; 2955 2956 if( objc!=3 ){ 2957 Tcl_AppendResult(interp, "wrong # args: should be \"", 2958 Tcl_GetString(objv[0]), " STMT column", 0); 2959 return TCL_ERROR; 2960 } 2961 2962 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2963 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2964 2965 Tcl_SetObjResult(interp, Tcl_NewIntObj(xFunc(pStmt, col))); 2966 return TCL_OK; 2967 } 2968 2969 #ifndef SQLITE_OMIT_DISKIO 2970 /* 2971 ** Usage: sqlite3OsOpenReadWrite <filename> 2972 */ 2973 static int test_sqlite3OsOpenReadWrite( 2974 void * clientData, 2975 Tcl_Interp *interp, 2976 int objc, 2977 Tcl_Obj *CONST objv[] 2978 ){ 2979 OsFile *pFile; 2980 int rc; 2981 int dummy; 2982 char zBuf[100]; 2983 2984 if( objc!=2 ){ 2985 Tcl_AppendResult(interp, "wrong # args: should be \"", 2986 Tcl_GetString(objv[0]), " filename", 0); 2987 return TCL_ERROR; 2988 } 2989 2990 rc = sqlite3OsOpenReadWrite(Tcl_GetString(objv[1]), &pFile, &dummy); 2991 if( rc!=SQLITE_OK ){ 2992 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 2993 return TCL_ERROR; 2994 } 2995 sqlite3TestMakePointerStr(interp, zBuf, pFile); 2996 Tcl_SetResult(interp, zBuf, 0); 2997 return TCL_ERROR; 2998 } 2999 3000 /* 3001 ** Usage: sqlite3OsClose <file handle> 3002 */ 3003 static int test_sqlite3OsClose( 3004 void * clientData, 3005 Tcl_Interp *interp, 3006 int objc, 3007 Tcl_Obj *CONST objv[] 3008 ){ 3009 OsFile *pFile; 3010 int rc; 3011 3012 if( objc!=2 ){ 3013 Tcl_AppendResult(interp, "wrong # args: should be \"", 3014 Tcl_GetString(objv[0]), " filehandle", 0); 3015 return TCL_ERROR; 3016 } 3017 3018 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 3019 return TCL_ERROR; 3020 } 3021 rc = sqlite3OsClose(&pFile); 3022 if( rc!=SQLITE_OK ){ 3023 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 3024 return TCL_ERROR; 3025 } 3026 return TCL_OK; 3027 } 3028 3029 /* 3030 ** Usage: sqlite3OsLock <file handle> <locktype> 3031 */ 3032 static int test_sqlite3OsLock( 3033 void * clientData, 3034 Tcl_Interp *interp, 3035 int objc, 3036 Tcl_Obj *CONST objv[] 3037 ){ 3038 OsFile * pFile; 3039 int rc; 3040 3041 if( objc!=3 ){ 3042 Tcl_AppendResult(interp, "wrong # args: should be \"", 3043 Tcl_GetString(objv[0]), 3044 " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0); 3045 return TCL_ERROR; 3046 } 3047 3048 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 3049 return TCL_ERROR; 3050 } 3051 3052 if( 0==strcmp("SHARED", Tcl_GetString(objv[2])) ){ 3053 rc = sqlite3OsLock(pFile, SHARED_LOCK); 3054 } 3055 else if( 0==strcmp("RESERVED", Tcl_GetString(objv[2])) ){ 3056 rc = sqlite3OsLock(pFile, RESERVED_LOCK); 3057 } 3058 else if( 0==strcmp("PENDING", Tcl_GetString(objv[2])) ){ 3059 rc = sqlite3OsLock(pFile, PENDING_LOCK); 3060 } 3061 else if( 0==strcmp("EXCLUSIVE", Tcl_GetString(objv[2])) ){ 3062 rc = sqlite3OsLock(pFile, EXCLUSIVE_LOCK); 3063 }else{ 3064 Tcl_AppendResult(interp, "wrong # args: should be \"", 3065 Tcl_GetString(objv[0]), 3066 " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0); 3067 return TCL_ERROR; 3068 } 3069 3070 if( rc!=SQLITE_OK ){ 3071 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 3072 return TCL_ERROR; 3073 } 3074 return TCL_OK; 3075 } 3076 3077 /* 3078 ** Usage: sqlite3OsUnlock <file handle> 3079 */ 3080 static int test_sqlite3OsUnlock( 3081 void * clientData, 3082 Tcl_Interp *interp, 3083 int objc, 3084 Tcl_Obj *CONST objv[] 3085 ){ 3086 OsFile * pFile; 3087 int rc; 3088 3089 if( objc!=2 ){ 3090 Tcl_AppendResult(interp, "wrong # args: should be \"", 3091 Tcl_GetString(objv[0]), " filehandle", 0); 3092 return TCL_ERROR; 3093 } 3094 3095 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 3096 return TCL_ERROR; 3097 } 3098 rc = sqlite3OsUnlock(pFile, NO_LOCK); 3099 if( rc!=SQLITE_OK ){ 3100 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 3101 return TCL_ERROR; 3102 } 3103 return TCL_OK; 3104 } 3105 3106 /* 3107 ** Usage: sqlite3OsTempFileName 3108 */ 3109 static int test_sqlite3OsTempFileName( 3110 void * clientData, 3111 Tcl_Interp *interp, 3112 int objc, 3113 Tcl_Obj *CONST objv[] 3114 ){ 3115 char zFile[SQLITE_TEMPNAME_SIZE]; 3116 int rc; 3117 3118 rc = sqlite3OsTempFileName(zFile); 3119 if( rc!=SQLITE_OK ){ 3120 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 3121 return TCL_ERROR; 3122 } 3123 Tcl_AppendResult(interp, zFile, 0); 3124 return TCL_OK; 3125 } 3126 #endif 3127 3128 /* 3129 ** Usage: sqlite_set_magic DB MAGIC-NUMBER 3130 ** 3131 ** Set the db->magic value. This is used to test error recovery logic. 3132 */ 3133 static int sqlite_set_magic( 3134 void * clientData, 3135 Tcl_Interp *interp, 3136 int argc, 3137 char **argv 3138 ){ 3139 sqlite3 *db; 3140 if( argc!=3 ){ 3141 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 3142 " DB MAGIC", 0); 3143 return TCL_ERROR; 3144 } 3145 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 3146 if( strcmp(argv[2], "SQLITE_MAGIC_OPEN")==0 ){ 3147 db->magic = SQLITE_MAGIC_OPEN; 3148 }else if( strcmp(argv[2], "SQLITE_MAGIC_CLOSED")==0 ){ 3149 db->magic = SQLITE_MAGIC_CLOSED; 3150 }else if( strcmp(argv[2], "SQLITE_MAGIC_BUSY")==0 ){ 3151 db->magic = SQLITE_MAGIC_BUSY; 3152 }else if( strcmp(argv[2], "SQLITE_MAGIC_ERROR")==0 ){ 3153 db->magic = SQLITE_MAGIC_ERROR; 3154 }else if( Tcl_GetInt(interp, argv[2], &db->magic) ){ 3155 return TCL_ERROR; 3156 } 3157 return TCL_OK; 3158 } 3159 3160 /* 3161 ** Usage: sqlite3_interrupt DB 3162 ** 3163 ** Trigger an interrupt on DB 3164 */ 3165 static int test_interrupt( 3166 void * clientData, 3167 Tcl_Interp *interp, 3168 int argc, 3169 char **argv 3170 ){ 3171 sqlite3 *db; 3172 if( argc!=2 ){ 3173 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB", 0); 3174 return TCL_ERROR; 3175 } 3176 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 3177 sqlite3_interrupt(db); 3178 return TCL_OK; 3179 } 3180 3181 static u8 *sqlite3_stack_baseline = 0; 3182 3183 /* 3184 ** Fill the stack with a known bitpattern. 3185 */ 3186 static void prepStack(void){ 3187 int i; 3188 u32 bigBuf[65536]; 3189 for(i=0; i<sizeof(bigBuf); i++) bigBuf[i] = 0xdeadbeef; 3190 sqlite3_stack_baseline = (u8*)&bigBuf[65536]; 3191 } 3192 3193 /* 3194 ** Get the current stack depth. Used for debugging only. 3195 */ 3196 u64 sqlite3StackDepth(void){ 3197 u8 x; 3198 return (u64)(sqlite3_stack_baseline - &x); 3199 } 3200 3201 /* 3202 ** Usage: sqlite3_stack_used DB SQL 3203 ** 3204 ** Try to measure the amount of stack space used by a call to sqlite3_exec 3205 */ 3206 static int test_stack_used( 3207 void * clientData, 3208 Tcl_Interp *interp, 3209 int argc, 3210 char **argv 3211 ){ 3212 sqlite3 *db; 3213 int i; 3214 if( argc!=3 ){ 3215 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 3216 " DB SQL", 0); 3217 return TCL_ERROR; 3218 } 3219 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 3220 prepStack(); 3221 (void)sqlite3_exec(db, argv[2], 0, 0, 0); 3222 for(i=65535; i>=0 && ((u32*)sqlite3_stack_baseline)[-i]==0xdeadbeef; i--){} 3223 Tcl_SetObjResult(interp, Tcl_NewIntObj(i*4)); 3224 return TCL_OK; 3225 } 3226 3227 /* 3228 ** Usage: sqlite_delete_function DB function-name 3229 ** 3230 ** Delete the user function 'function-name' from database handle DB. It 3231 ** is assumed that the user function was created as UTF8, any number of 3232 ** arguments (the way the TCL interface does it). 3233 */ 3234 static int delete_function( 3235 void * clientData, 3236 Tcl_Interp *interp, 3237 int argc, 3238 char **argv 3239 ){ 3240 int rc; 3241 sqlite3 *db; 3242 if( argc!=3 ){ 3243 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 3244 " DB function-name", 0); 3245 return TCL_ERROR; 3246 } 3247 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 3248 rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 0, 0, 0); 3249 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 3250 return TCL_OK; 3251 } 3252 3253 /* 3254 ** Usage: sqlite_delete_collation DB collation-name 3255 ** 3256 ** Delete the collation sequence 'collation-name' from database handle 3257 ** DB. It is assumed that the collation sequence was created as UTF8 (the 3258 ** way the TCL interface does it). 3259 */ 3260 static int delete_collation( 3261 void * clientData, 3262 Tcl_Interp *interp, 3263 int argc, 3264 char **argv 3265 ){ 3266 int rc; 3267 sqlite3 *db; 3268 if( argc!=3 ){ 3269 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 3270 " DB function-name", 0); 3271 return TCL_ERROR; 3272 } 3273 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 3274 rc = sqlite3_create_collation(db, argv[2], SQLITE_UTF8, 0, 0); 3275 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 3276 return TCL_OK; 3277 } 3278 3279 /* 3280 ** Usage: sqlite3_get_autocommit DB 3281 ** 3282 ** Return true if the database DB is currently in auto-commit mode. 3283 ** Return false if not. 3284 */ 3285 static int get_autocommit( 3286 void * clientData, 3287 Tcl_Interp *interp, 3288 int argc, 3289 char **argv 3290 ){ 3291 char zBuf[30]; 3292 sqlite3 *db; 3293 if( argc!=2 ){ 3294 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 3295 " DB", 0); 3296 return TCL_ERROR; 3297 } 3298 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 3299 sprintf(zBuf, "%d", sqlite3_get_autocommit(db)); 3300 Tcl_AppendResult(interp, zBuf, 0); 3301 return TCL_OK; 3302 } 3303 3304 /* 3305 ** Usage: sqlite3_busy_timeout DB MS 3306 ** 3307 ** Set the busy timeout. This is more easily done using the timeout 3308 ** method of the TCL interface. But we need a way to test the case 3309 ** where it returns SQLITE_MISUSE. 3310 */ 3311 static int test_busy_timeout( 3312 void * clientData, 3313 Tcl_Interp *interp, 3314 int argc, 3315 char **argv 3316 ){ 3317 int rc, ms; 3318 sqlite3 *db; 3319 if( argc!=3 ){ 3320 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 3321 " DB", 0); 3322 return TCL_ERROR; 3323 } 3324 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 3325 if( Tcl_GetInt(interp, argv[2], &ms) ) return TCL_ERROR; 3326 rc = sqlite3_busy_timeout(db, ms); 3327 Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0); 3328 return TCL_OK; 3329 } 3330 3331 /* 3332 ** Usage: tcl_variable_type VARIABLENAME 3333 ** 3334 ** Return the name of the internal representation for the 3335 ** value of the given variable. 3336 */ 3337 static int tcl_variable_type( 3338 void * clientData, 3339 Tcl_Interp *interp, 3340 int objc, 3341 Tcl_Obj *CONST objv[] 3342 ){ 3343 Tcl_Obj *pVar; 3344 if( objc!=2 ){ 3345 Tcl_WrongNumArgs(interp, 1, objv, "VARIABLE"); 3346 return TCL_ERROR; 3347 } 3348 pVar = Tcl_GetVar2Ex(interp, Tcl_GetString(objv[1]), 0, TCL_LEAVE_ERR_MSG); 3349 if( pVar==0 ) return TCL_ERROR; 3350 if( pVar->typePtr ){ 3351 Tcl_SetObjResult(interp, Tcl_NewStringObj(pVar->typePtr->name, -1)); 3352 } 3353 return TCL_OK; 3354 } 3355 3356 /* 3357 ** Usage: sqlite3_release_memory ?N? 3358 ** 3359 ** Attempt to release memory currently held but not actually required. 3360 ** The integer N is the number of bytes we are trying to release. The 3361 ** return value is the amount of memory actually released. 3362 */ 3363 static int test_release_memory( 3364 void * clientData, 3365 Tcl_Interp *interp, 3366 int objc, 3367 Tcl_Obj *CONST objv[] 3368 ){ 3369 #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO) 3370 int N; 3371 int amt; 3372 if( objc!=1 && objc!=2 ){ 3373 Tcl_WrongNumArgs(interp, 1, objv, "?N?"); 3374 return TCL_ERROR; 3375 } 3376 if( objc==2 ){ 3377 if( Tcl_GetIntFromObj(interp, objv[1], &N) ) return TCL_ERROR; 3378 }else{ 3379 N = -1; 3380 } 3381 amt = sqlite3_release_memory(N); 3382 Tcl_SetObjResult(interp, Tcl_NewIntObj(amt)); 3383 #endif 3384 return TCL_OK; 3385 } 3386 3387 /* 3388 ** Usage: sqlite3_soft_heap_limit ?N? 3389 ** 3390 ** Query or set the soft heap limit for the current thread. The 3391 ** limit is only changed if the N is present. The previous limit 3392 ** is returned. 3393 */ 3394 static int test_soft_heap_limit( 3395 void * clientData, 3396 Tcl_Interp *interp, 3397 int objc, 3398 Tcl_Obj *CONST objv[] 3399 ){ 3400 #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) && !defined(SQLITE_OMIT_DISKIO) 3401 int amt; 3402 if( objc!=1 && objc!=2 ){ 3403 Tcl_WrongNumArgs(interp, 1, objv, "?N?"); 3404 return TCL_ERROR; 3405 } 3406 amt = sqlite3ThreadDataReadOnly()->nSoftHeapLimit; 3407 if( objc==2 ){ 3408 int N; 3409 if( Tcl_GetIntFromObj(interp, objv[1], &N) ) return TCL_ERROR; 3410 sqlite3_soft_heap_limit(N); 3411 } 3412 Tcl_SetObjResult(interp, Tcl_NewIntObj(amt)); 3413 #endif 3414 return TCL_OK; 3415 } 3416 3417 /* 3418 ** Usage: sqlite3_clear_tsd_memdebug 3419 ** 3420 ** Clear all of the MEMDEBUG information out of thread-specific data. 3421 ** This will allow it to be deallocated. 3422 */ 3423 static int test_clear_tsd_memdebug( 3424 void * clientData, 3425 Tcl_Interp *interp, 3426 int objc, 3427 Tcl_Obj *CONST objv[] 3428 ){ 3429 return TCL_OK; 3430 } 3431 3432 /* 3433 ** Usage: sqlite3_tsd_release 3434 ** 3435 ** Call sqlite3ReleaseThreadData. 3436 */ 3437 static int test_tsd_release( 3438 void * clientData, 3439 Tcl_Interp *interp, 3440 int objc, 3441 Tcl_Obj *CONST objv[] 3442 ){ 3443 #if defined(SQLITE_MEMDEBUG) 3444 sqlite3ReleaseThreadData(); 3445 #endif 3446 return TCL_OK; 3447 } 3448 3449 /* 3450 ** Usage: sqlite3_thread_cleanup 3451 ** 3452 ** Call the sqlite3_thread_cleanup API. 3453 */ 3454 static int test_thread_cleanup( 3455 void * clientData, 3456 Tcl_Interp *interp, 3457 int objc, 3458 Tcl_Obj *CONST objv[] 3459 ){ 3460 sqlite3_thread_cleanup(); 3461 return TCL_OK; 3462 } 3463 3464 3465 /* 3466 ** This routine sets entries in the global ::sqlite_options() array variable 3467 ** according to the compile-time configuration of the database. Test 3468 ** procedures use this to determine when tests should be omitted. 3469 */ 3470 static void set_options(Tcl_Interp *interp){ 3471 #ifdef SQLITE_32BIT_ROWID 3472 Tcl_SetVar2(interp, "sqlite_options", "rowid32", "1", TCL_GLOBAL_ONLY); 3473 #else 3474 Tcl_SetVar2(interp, "sqlite_options", "rowid32", "0", TCL_GLOBAL_ONLY); 3475 #endif 3476 3477 #ifdef SQLITE_CASE_SENSITIVE_LIKE 3478 Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","1",TCL_GLOBAL_ONLY); 3479 #else 3480 Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","0",TCL_GLOBAL_ONLY); 3481 #endif 3482 3483 #ifdef SQLITE_DISABLE_DIRSYNC 3484 Tcl_SetVar2(interp, "sqlite_options", "dirsync", "0", TCL_GLOBAL_ONLY); 3485 #else 3486 Tcl_SetVar2(interp, "sqlite_options", "dirsync", "1", TCL_GLOBAL_ONLY); 3487 #endif 3488 3489 #ifdef SQLITE_DISABLE_LFS 3490 Tcl_SetVar2(interp, "sqlite_options", "lfs", "0", TCL_GLOBAL_ONLY); 3491 #else 3492 Tcl_SetVar2(interp, "sqlite_options", "lfs", "1", TCL_GLOBAL_ONLY); 3493 #endif 3494 3495 #ifdef SQLITE_OMIT_ALTERTABLE 3496 Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY); 3497 #else 3498 Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY); 3499 #endif 3500 3501 #ifdef SQLITE_OMIT_ANALYZE 3502 Tcl_SetVar2(interp, "sqlite_options", "analyze", "0", TCL_GLOBAL_ONLY); 3503 #else 3504 Tcl_SetVar2(interp, "sqlite_options", "analyze", "1", TCL_GLOBAL_ONLY); 3505 #endif 3506 3507 #ifdef SQLITE_OMIT_AUTHORIZATION 3508 Tcl_SetVar2(interp, "sqlite_options", "auth", "0", TCL_GLOBAL_ONLY); 3509 #else 3510 Tcl_SetVar2(interp, "sqlite_options", "auth", "1", TCL_GLOBAL_ONLY); 3511 #endif 3512 3513 #ifdef SQLITE_OMIT_AUTOINCREMENT 3514 Tcl_SetVar2(interp, "sqlite_options", "autoinc", "0", TCL_GLOBAL_ONLY); 3515 #else 3516 Tcl_SetVar2(interp, "sqlite_options", "autoinc", "1", TCL_GLOBAL_ONLY); 3517 #endif 3518 3519 #ifdef SQLITE_OMIT_AUTOVACUUM 3520 Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "0", TCL_GLOBAL_ONLY); 3521 #else 3522 Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "1", TCL_GLOBAL_ONLY); 3523 #endif /* SQLITE_OMIT_AUTOVACUUM */ 3524 #if !defined(SQLITE_DEFAULT_AUTOVACUUM) || SQLITE_DEFAULT_AUTOVACUUM==0 3525 Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","0",TCL_GLOBAL_ONLY); 3526 #else 3527 Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","1",TCL_GLOBAL_ONLY); 3528 #endif 3529 3530 #ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION 3531 Tcl_SetVar2(interp, "sqlite_options", "between_opt", "0", TCL_GLOBAL_ONLY); 3532 #else 3533 Tcl_SetVar2(interp, "sqlite_options", "between_opt", "1", TCL_GLOBAL_ONLY); 3534 #endif 3535 3536 #ifdef SQLITE_OMIT_BLOB_LITERAL 3537 Tcl_SetVar2(interp, "sqlite_options", "bloblit", "0", TCL_GLOBAL_ONLY); 3538 #else 3539 Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY); 3540 #endif 3541 3542 #ifdef SQLITE_OMIT_CAST 3543 Tcl_SetVar2(interp, "sqlite_options", "cast", "0", TCL_GLOBAL_ONLY); 3544 #else 3545 Tcl_SetVar2(interp, "sqlite_options", "cast", "1", TCL_GLOBAL_ONLY); 3546 #endif 3547 3548 #ifdef SQLITE_OMIT_CHECK 3549 Tcl_SetVar2(interp, "sqlite_options", "check", "0", TCL_GLOBAL_ONLY); 3550 #else 3551 Tcl_SetVar2(interp, "sqlite_options", "check", "1", TCL_GLOBAL_ONLY); 3552 #endif 3553 3554 #ifdef SQLITE_ENABLE_COLUMN_METADATA 3555 Tcl_SetVar2(interp, "sqlite_options", "columnmetadata", "1", TCL_GLOBAL_ONLY); 3556 #else 3557 Tcl_SetVar2(interp, "sqlite_options", "columnmetadata", "0", TCL_GLOBAL_ONLY); 3558 #endif 3559 3560 #ifdef SQLITE_OMIT_COMPLETE 3561 Tcl_SetVar2(interp, "sqlite_options", "complete", "0", TCL_GLOBAL_ONLY); 3562 #else 3563 Tcl_SetVar2(interp, "sqlite_options", "complete", "1", TCL_GLOBAL_ONLY); 3564 #endif 3565 3566 #ifdef SQLITE_OMIT_COMPOUND_SELECT 3567 Tcl_SetVar2(interp, "sqlite_options", "compound", "0", TCL_GLOBAL_ONLY); 3568 #else 3569 Tcl_SetVar2(interp, "sqlite_options", "compound", "1", TCL_GLOBAL_ONLY); 3570 #endif 3571 3572 #ifdef SQLITE_OMIT_CONFLICT_CLAUSE 3573 Tcl_SetVar2(interp, "sqlite_options", "conflict", "0", TCL_GLOBAL_ONLY); 3574 #else 3575 Tcl_SetVar2(interp, "sqlite_options", "conflict", "1", TCL_GLOBAL_ONLY); 3576 #endif 3577 3578 #if OS_UNIX 3579 Tcl_SetVar2(interp, "sqlite_options", "crashtest", "1", TCL_GLOBAL_ONLY); 3580 #else 3581 Tcl_SetVar2(interp, "sqlite_options", "crashtest", "0", TCL_GLOBAL_ONLY); 3582 #endif 3583 3584 #ifdef SQLITE_OMIT_DATETIME_FUNCS 3585 Tcl_SetVar2(interp, "sqlite_options", "datetime", "0", TCL_GLOBAL_ONLY); 3586 #else 3587 Tcl_SetVar2(interp, "sqlite_options", "datetime", "1", TCL_GLOBAL_ONLY); 3588 #endif 3589 3590 #ifdef SQLITE_OMIT_DISKIO 3591 Tcl_SetVar2(interp, "sqlite_options", "diskio", "0", TCL_GLOBAL_ONLY); 3592 #else 3593 Tcl_SetVar2(interp, "sqlite_options", "diskio", "1", TCL_GLOBAL_ONLY); 3594 #endif 3595 3596 #ifdef SQLITE_OMIT_EXPLAIN 3597 Tcl_SetVar2(interp, "sqlite_options", "explain", "0", TCL_GLOBAL_ONLY); 3598 #else 3599 Tcl_SetVar2(interp, "sqlite_options", "explain", "1", TCL_GLOBAL_ONLY); 3600 #endif 3601 3602 #ifdef SQLITE_OMIT_FLOATING_POINT 3603 Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "0", TCL_GLOBAL_ONLY); 3604 #else 3605 Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "1", TCL_GLOBAL_ONLY); 3606 #endif 3607 3608 #ifdef SQLITE_OMIT_FOREIGN_KEY 3609 Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "0", TCL_GLOBAL_ONLY); 3610 #else 3611 Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "1", TCL_GLOBAL_ONLY); 3612 #endif 3613 3614 #ifdef SQLITE_ENABLE_FTS1 3615 Tcl_SetVar2(interp, "sqlite_options", "fts1", "1", TCL_GLOBAL_ONLY); 3616 #else 3617 Tcl_SetVar2(interp, "sqlite_options", "fts1", "0", TCL_GLOBAL_ONLY); 3618 #endif 3619 3620 #ifdef SQLITE_ENABLE_FTS2 3621 Tcl_SetVar2(interp, "sqlite_options", "fts2", "1", TCL_GLOBAL_ONLY); 3622 #else 3623 Tcl_SetVar2(interp, "sqlite_options", "fts2", "0", TCL_GLOBAL_ONLY); 3624 #endif 3625 3626 #ifdef SQLITE_OMIT_GLOBALRECOVER 3627 Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "0", TCL_GLOBAL_ONLY); 3628 #else 3629 Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "1", TCL_GLOBAL_ONLY); 3630 #endif 3631 3632 #ifdef SQLITE_OMIT_INTEGRITY_CHECK 3633 Tcl_SetVar2(interp, "sqlite_options", "integrityck", "0", TCL_GLOBAL_ONLY); 3634 #else 3635 Tcl_SetVar2(interp, "sqlite_options", "integrityck", "1", TCL_GLOBAL_ONLY); 3636 #endif 3637 3638 #if defined(SQLITE_DEFAULT_FILE_FORMAT) && SQLITE_DEFAULT_FILE_FORMAT==1 3639 Tcl_SetVar2(interp, "sqlite_options", "legacyformat", "1", TCL_GLOBAL_ONLY); 3640 #else 3641 Tcl_SetVar2(interp, "sqlite_options", "legacyformat", "0", TCL_GLOBAL_ONLY); 3642 #endif 3643 3644 #ifdef SQLITE_OMIT_LIKE_OPTIMIZATION 3645 Tcl_SetVar2(interp, "sqlite_options", "like_opt", "0", TCL_GLOBAL_ONLY); 3646 #else 3647 Tcl_SetVar2(interp, "sqlite_options", "like_opt", "1", TCL_GLOBAL_ONLY); 3648 #endif 3649 3650 #ifdef SQLITE_OMIT_MEMORYDB 3651 Tcl_SetVar2(interp, "sqlite_options", "memorydb", "0", TCL_GLOBAL_ONLY); 3652 #else 3653 Tcl_SetVar2(interp, "sqlite_options", "memorydb", "1", TCL_GLOBAL_ONLY); 3654 #endif 3655 3656 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT 3657 Tcl_SetVar2(interp, "sqlite_options", "memorymanage", "1", TCL_GLOBAL_ONLY); 3658 #else 3659 Tcl_SetVar2(interp, "sqlite_options", "memorymanage", "0", TCL_GLOBAL_ONLY); 3660 #endif 3661 3662 #ifdef SQLITE_OMIT_OR_OPTIMIZATION 3663 Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY); 3664 #else 3665 Tcl_SetVar2(interp, "sqlite_options", "or_opt", "1", TCL_GLOBAL_ONLY); 3666 #endif 3667 3668 #ifdef SQLITE_OMIT_PAGER_PRAGMAS 3669 Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "0", TCL_GLOBAL_ONLY); 3670 #else 3671 Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "1", TCL_GLOBAL_ONLY); 3672 #endif 3673 3674 #ifdef SQLITE_OMIT_PARSER 3675 Tcl_SetVar2(interp, "sqlite_options", "parser", "0", TCL_GLOBAL_ONLY); 3676 #else 3677 Tcl_SetVar2(interp, "sqlite_options", "parser", "1", TCL_GLOBAL_ONLY); 3678 #endif 3679 3680 #if defined(SQLITE_OMIT_PRAGMA) || defined(SQLITE_OMIT_FLAG_PRAGMAS) 3681 Tcl_SetVar2(interp, "sqlite_options", "pragma", "0", TCL_GLOBAL_ONLY); 3682 Tcl_SetVar2(interp, "sqlite_options", "integrityck", "0", TCL_GLOBAL_ONLY); 3683 #else 3684 Tcl_SetVar2(interp, "sqlite_options", "pragma", "1", TCL_GLOBAL_ONLY); 3685 #endif 3686 3687 #ifdef SQLITE_OMIT_PROGRESS_CALLBACK 3688 Tcl_SetVar2(interp, "sqlite_options", "progress", "0", TCL_GLOBAL_ONLY); 3689 #else 3690 Tcl_SetVar2(interp, "sqlite_options", "progress", "1", TCL_GLOBAL_ONLY); 3691 #endif 3692 3693 #ifdef SQLITE_ENABLE_REDEF_IO 3694 Tcl_SetVar2(interp, "sqlite_options", "redefio", "1", TCL_GLOBAL_ONLY); 3695 #else 3696 Tcl_SetVar2(interp, "sqlite_options", "redefio", "0", TCL_GLOBAL_ONLY); 3697 #endif 3698 3699 #ifdef SQLITE_OMIT_REINDEX 3700 Tcl_SetVar2(interp, "sqlite_options", "reindex", "0", TCL_GLOBAL_ONLY); 3701 #else 3702 Tcl_SetVar2(interp, "sqlite_options", "reindex", "1", TCL_GLOBAL_ONLY); 3703 #endif 3704 3705 #ifdef SQLITE_OMIT_SCHEMA_PRAGMAS 3706 Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "0", TCL_GLOBAL_ONLY); 3707 #else 3708 Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "1", TCL_GLOBAL_ONLY); 3709 #endif 3710 3711 #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS 3712 Tcl_SetVar2(interp, "sqlite_options", "schema_version", "0", TCL_GLOBAL_ONLY); 3713 #else 3714 Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY); 3715 #endif 3716 3717 #ifdef SQLITE_OMIT_SHARED_CACHE 3718 Tcl_SetVar2(interp, "sqlite_options", "shared_cache", "0", TCL_GLOBAL_ONLY); 3719 #else 3720 Tcl_SetVar2(interp, "sqlite_options", "shared_cache", "1", TCL_GLOBAL_ONLY); 3721 #endif 3722 3723 #ifdef SQLITE_OMIT_SUBQUERY 3724 Tcl_SetVar2(interp, "sqlite_options", "subquery", "0", TCL_GLOBAL_ONLY); 3725 #else 3726 Tcl_SetVar2(interp, "sqlite_options", "subquery", "1", TCL_GLOBAL_ONLY); 3727 #endif 3728 3729 #ifdef SQLITE_OMIT_TCL_VARIABLE 3730 Tcl_SetVar2(interp, "sqlite_options", "tclvar", "0", TCL_GLOBAL_ONLY); 3731 #else 3732 Tcl_SetVar2(interp, "sqlite_options", "tclvar", "1", TCL_GLOBAL_ONLY); 3733 #endif 3734 3735 #if defined(THREADSAFE) && THREADSAFE 3736 Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "1", TCL_GLOBAL_ONLY); 3737 #else 3738 Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "0", TCL_GLOBAL_ONLY); 3739 #endif 3740 3741 #ifdef SQLITE_OMIT_TRACE 3742 Tcl_SetVar2(interp, "sqlite_options", "trace", "0", TCL_GLOBAL_ONLY); 3743 #else 3744 Tcl_SetVar2(interp, "sqlite_options", "trace", "1", TCL_GLOBAL_ONLY); 3745 #endif 3746 3747 #ifdef SQLITE_OMIT_TRIGGER 3748 Tcl_SetVar2(interp, "sqlite_options", "trigger", "0", TCL_GLOBAL_ONLY); 3749 #else 3750 Tcl_SetVar2(interp, "sqlite_options", "trigger", "1", TCL_GLOBAL_ONLY); 3751 #endif 3752 3753 #ifdef SQLITE_OMIT_TEMPDB 3754 Tcl_SetVar2(interp, "sqlite_options", "tempdb", "0", TCL_GLOBAL_ONLY); 3755 #else 3756 Tcl_SetVar2(interp, "sqlite_options", "tempdb", "1", TCL_GLOBAL_ONLY); 3757 #endif 3758 3759 #ifdef SQLITE_OMIT_UTF16 3760 Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY); 3761 #else 3762 Tcl_SetVar2(interp, "sqlite_options", "utf16", "1", TCL_GLOBAL_ONLY); 3763 #endif 3764 3765 #ifdef SQLITE_OMIT_VACUUM 3766 Tcl_SetVar2(interp, "sqlite_options", "vacuum", "0", TCL_GLOBAL_ONLY); 3767 #else 3768 Tcl_SetVar2(interp, "sqlite_options", "vacuum", "1", TCL_GLOBAL_ONLY); 3769 #endif 3770 3771 #ifdef SQLITE_OMIT_VIEW 3772 Tcl_SetVar2(interp, "sqlite_options", "view", "0", TCL_GLOBAL_ONLY); 3773 #else 3774 Tcl_SetVar2(interp, "sqlite_options", "view", "1", TCL_GLOBAL_ONLY); 3775 #endif 3776 3777 #ifdef SQLITE_OMIT_VIRTUALTABLE 3778 Tcl_SetVar2(interp, "sqlite_options", "vtab", "0", TCL_GLOBAL_ONLY); 3779 #else 3780 Tcl_SetVar2(interp, "sqlite_options", "vtab", "1", TCL_GLOBAL_ONLY); 3781 #endif 3782 } 3783 3784 /* 3785 ** tclcmd: working_64bit_int 3786 ** 3787 ** Some TCL builds (ex: cygwin) do not support 64-bit integers. This 3788 ** leads to a number of test failures. The present command checks the 3789 ** TCL build to see whether or not it supports 64-bit integers. It 3790 ** returns TRUE if it does and FALSE if not. 3791 ** 3792 ** This command is used to warn users that their TCL build is defective 3793 ** and that the errors they are seeing in the test scripts might be 3794 ** a result of their defective TCL rather than problems in SQLite. 3795 */ 3796 static int working_64bit_int( 3797 ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ 3798 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 3799 int objc, /* Number of arguments */ 3800 Tcl_Obj *CONST objv[] /* Command arguments */ 3801 ){ 3802 Tcl_Obj *pTestObj; 3803 int working = 0; 3804 3805 pTestObj = Tcl_NewWideIntObj(1000000*(i64)1234567890); 3806 working = strcmp(Tcl_GetString(pTestObj), "1234567890000000")==0; 3807 Tcl_DecrRefCount(pTestObj); 3808 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(working)); 3809 return TCL_OK; 3810 } 3811 3812 3813 /* 3814 ** Register commands with the TCL interpreter. 3815 */ 3816 int Sqlitetest1_Init(Tcl_Interp *interp){ 3817 extern int sqlite3_search_count; 3818 extern int sqlite3_interrupt_count; 3819 extern int sqlite3_open_file_count; 3820 extern int sqlite3_sort_count; 3821 extern int sqlite3_current_time; 3822 static struct { 3823 char *zName; 3824 Tcl_CmdProc *xProc; 3825 } aCmd[] = { 3826 { "sqlite3_mprintf_int", (Tcl_CmdProc*)sqlite3_mprintf_int }, 3827 { "sqlite3_mprintf_int64", (Tcl_CmdProc*)sqlite3_mprintf_int64 }, 3828 { "sqlite3_mprintf_str", (Tcl_CmdProc*)sqlite3_mprintf_str }, 3829 { "sqlite3_mprintf_stronly", (Tcl_CmdProc*)sqlite3_mprintf_stronly}, 3830 { "sqlite3_mprintf_double", (Tcl_CmdProc*)sqlite3_mprintf_double }, 3831 { "sqlite3_mprintf_scaled", (Tcl_CmdProc*)sqlite3_mprintf_scaled }, 3832 { "sqlite3_mprintf_hexdouble", (Tcl_CmdProc*)sqlite3_mprintf_hexdouble}, 3833 { "sqlite3_mprintf_z_test", (Tcl_CmdProc*)test_mprintf_z }, 3834 { "sqlite3_mprintf_n_test", (Tcl_CmdProc*)test_mprintf_n }, 3835 { "sqlite3_last_insert_rowid", (Tcl_CmdProc*)test_last_rowid }, 3836 { "sqlite3_exec_printf", (Tcl_CmdProc*)test_exec_printf }, 3837 { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, 3838 { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, 3839 { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, 3840 { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, 3841 { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, 3842 { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, 3843 #ifdef SQLITE_MEMDEBUG 3844 { "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail }, 3845 { "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat }, 3846 #endif 3847 { "sqlite_bind", (Tcl_CmdProc*)test_bind }, 3848 { "breakpoint", (Tcl_CmdProc*)test_breakpoint }, 3849 { "sqlite3_key", (Tcl_CmdProc*)test_key }, 3850 { "sqlite3_rekey", (Tcl_CmdProc*)test_rekey }, 3851 { "sqlite_set_magic", (Tcl_CmdProc*)sqlite_set_magic }, 3852 { "sqlite3_interrupt", (Tcl_CmdProc*)test_interrupt }, 3853 { "sqlite_delete_function", (Tcl_CmdProc*)delete_function }, 3854 { "sqlite_delete_collation", (Tcl_CmdProc*)delete_collation }, 3855 { "sqlite3_get_autocommit", (Tcl_CmdProc*)get_autocommit }, 3856 { "sqlite3_stack_used", (Tcl_CmdProc*)test_stack_used }, 3857 { "sqlite3_busy_timeout", (Tcl_CmdProc*)test_busy_timeout }, 3858 }; 3859 static struct { 3860 char *zName; 3861 Tcl_ObjCmdProc *xProc; 3862 void *clientData; 3863 } aObjCmd[] = { 3864 { "sqlite3_connection_pointer", get_sqlite_pointer, 0 }, 3865 { "sqlite3_bind_int", test_bind_int, 0 }, 3866 { "sqlite3_bind_int64", test_bind_int64, 0 }, 3867 { "sqlite3_bind_double", test_bind_double, 0 }, 3868 { "sqlite3_bind_null", test_bind_null ,0 }, 3869 { "sqlite3_bind_text", test_bind_text ,0 }, 3870 { "sqlite3_bind_text16", test_bind_text16 ,0 }, 3871 { "sqlite3_bind_blob", test_bind_blob ,0 }, 3872 { "sqlite3_bind_parameter_count", test_bind_parameter_count, 0}, 3873 { "sqlite3_bind_parameter_name", test_bind_parameter_name, 0}, 3874 { "sqlite3_bind_parameter_index", test_bind_parameter_index, 0}, 3875 { "sqlite3_clear_bindings", test_clear_bindings, 0}, 3876 { "sqlite3_sleep", test_sleep, 0}, 3877 { "sqlite3_errcode", test_errcode ,0 }, 3878 { "sqlite3_errmsg", test_errmsg ,0 }, 3879 { "sqlite3_errmsg16", test_errmsg16 ,0 }, 3880 { "sqlite3_open", test_open ,0 }, 3881 { "sqlite3_open16", test_open16 ,0 }, 3882 { "sqlite3_complete16", test_complete16 ,0 }, 3883 3884 { "sqlite3_prepare", test_prepare ,0 }, 3885 { "sqlite3_prepare16", test_prepare16 ,0 }, 3886 { "sqlite3_finalize", test_finalize ,0 }, 3887 { "sqlite3_reset", test_reset ,0 }, 3888 { "sqlite3_expired", test_expired ,0 }, 3889 { "sqlite3_transfer_bindings", test_transfer_bind ,0 }, 3890 { "sqlite3_changes", test_changes ,0 }, 3891 { "sqlite3_step", test_step ,0 }, 3892 3893 { "sqlite3_release_memory", test_release_memory, 0}, 3894 { "sqlite3_soft_heap_limit", test_soft_heap_limit, 0}, 3895 { "sqlite3_clear_tsd_memdebug", test_clear_tsd_memdebug, 0}, 3896 { "sqlite3_tsd_release", test_tsd_release, 0}, 3897 { "sqlite3_thread_cleanup", test_thread_cleanup, 0}, 3898 3899 { "sqlite3_load_extension", test_load_extension, 0}, 3900 { "sqlite3_enable_load_extension", test_enable_load, 0}, 3901 { "sqlite3_extended_result_codes", test_extended_result_codes, 0}, 3902 3903 /* sqlite3_column_*() API */ 3904 { "sqlite3_column_count", test_column_count ,0 }, 3905 { "sqlite3_data_count", test_data_count ,0 }, 3906 { "sqlite3_column_type", test_column_type ,0 }, 3907 { "sqlite3_column_blob", test_column_blob ,0 }, 3908 { "sqlite3_column_double", test_column_double ,0 }, 3909 { "sqlite3_column_int64", test_column_int64 ,0 }, 3910 { "sqlite3_column_text", test_stmt_utf8, sqlite3_column_text }, 3911 { "sqlite3_column_decltype", test_stmt_utf8, sqlite3_column_decltype }, 3912 { "sqlite3_column_name", test_stmt_utf8, sqlite3_column_name }, 3913 { "sqlite3_column_int", test_stmt_int, sqlite3_column_int }, 3914 { "sqlite3_column_bytes", test_stmt_int, sqlite3_column_bytes }, 3915 #ifdef SQLITE_ENABLE_COLUMN_METADATA 3916 { "sqlite3_column_database_name", test_stmt_utf8, sqlite3_column_database_name}, 3917 { "sqlite3_column_table_name", test_stmt_utf8, sqlite3_column_table_name}, 3918 { "sqlite3_column_origin_name", test_stmt_utf8, sqlite3_column_origin_name}, 3919 #endif 3920 3921 #ifndef SQLITE_OMIT_UTF16 3922 { "sqlite3_column_bytes16", test_stmt_int, sqlite3_column_bytes16 }, 3923 { "sqlite3_column_text16", test_stmt_utf16, sqlite3_column_text16 }, 3924 { "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16}, 3925 { "sqlite3_column_name16", test_stmt_utf16, sqlite3_column_name16 }, 3926 { "add_alignment_test_collations", add_alignment_test_collations, 0 }, 3927 #ifdef SQLITE_ENABLE_COLUMN_METADATA 3928 {"sqlite3_column_database_name16", 3929 test_stmt_utf16, sqlite3_column_database_name16}, 3930 {"sqlite3_column_table_name16", test_stmt_utf16, sqlite3_column_table_name16}, 3931 {"sqlite3_column_origin_name16", test_stmt_utf16, sqlite3_column_origin_name16}, 3932 #endif 3933 #endif 3934 { "sqlite3_global_recover", test_global_recover, 0 }, 3935 { "working_64bit_int", working_64bit_int, 0 }, 3936 3937 /* Functions from os.h */ 3938 #ifndef SQLITE_OMIT_DISKIO 3939 { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 }, 3940 { "sqlite3OsClose", test_sqlite3OsClose, 0 }, 3941 { "sqlite3OsLock", test_sqlite3OsLock, 0 }, 3942 { "sqlite3OsTempFileName", test_sqlite3OsTempFileName, 0 }, 3943 3944 /* Custom test interfaces */ 3945 { "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 }, 3946 #endif 3947 #ifndef SQLITE_OMIT_UTF16 3948 { "add_test_collate", test_collate, 0 }, 3949 { "add_test_collate_needed", test_collate_needed, 0 }, 3950 { "add_test_function", test_function, 0 }, 3951 #endif 3952 #ifdef SQLITE_MEMDEBUG 3953 { "sqlite_malloc_outstanding", sqlite_malloc_outstanding, 0}, 3954 #endif 3955 { "sqlite3_test_errstr", test_errstr, 0 }, 3956 { "tcl_variable_type", tcl_variable_type, 0 }, 3957 #ifndef SQLITE_OMIT_SHARED_CACHE 3958 { "sqlite3_enable_shared_cache", test_enable_shared, 0 }, 3959 #endif 3960 { "sqlite3_libversion_number", test_libversion_number, 0 }, 3961 #ifdef SQLITE_ENABLE_COLUMN_METADATA 3962 { "sqlite3_table_column_metadata", test_table_column_metadata, 0 }, 3963 #endif 3964 }; 3965 static int bitmask_size = sizeof(Bitmask)*8; 3966 int i; 3967 extern int sqlite3_os_trace; 3968 extern int sqlite3_where_trace; 3969 extern int sqlite3_sync_count, sqlite3_fullsync_count; 3970 extern int sqlite3_opentemp_count; 3971 extern int sqlite3_memUsed; 3972 extern int sqlite3_malloc_id; 3973 extern int sqlite3_memMax; 3974 extern int sqlite3_like_count; 3975 extern int sqlite3_tsd_count; 3976 #if OS_UNIX && defined(SQLITE_TEST) && defined(THREADSAFE) && THREADSAFE 3977 extern int threadsOverrideEachOthersLocks; 3978 #endif 3979 #if OS_WIN 3980 extern int sqlite3_os_type; 3981 #endif 3982 #ifdef SQLITE_DEBUG 3983 extern int sqlite3_vdbe_addop_trace; 3984 #endif 3985 #ifdef SQLITE_TEST 3986 extern char sqlite3_query_plan[]; 3987 static char *query_plan = sqlite3_query_plan; 3988 #endif 3989 3990 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ 3991 Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); 3992 } 3993 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ 3994 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 3995 aObjCmd[i].xProc, aObjCmd[i].clientData, 0); 3996 } 3997 Tcl_LinkVar(interp, "sqlite_search_count", 3998 (char*)&sqlite3_search_count, TCL_LINK_INT); 3999 Tcl_LinkVar(interp, "sqlite_sort_count", 4000 (char*)&sqlite3_sort_count, TCL_LINK_INT); 4001 Tcl_LinkVar(interp, "sqlite_like_count", 4002 (char*)&sqlite3_like_count, TCL_LINK_INT); 4003 Tcl_LinkVar(interp, "sqlite_interrupt_count", 4004 (char*)&sqlite3_interrupt_count, TCL_LINK_INT); 4005 Tcl_LinkVar(interp, "sqlite_open_file_count", 4006 (char*)&sqlite3_open_file_count, TCL_LINK_INT); 4007 Tcl_LinkVar(interp, "sqlite_current_time", 4008 (char*)&sqlite3_current_time, TCL_LINK_INT); 4009 Tcl_LinkVar(interp, "sqlite_os_trace", 4010 (char*)&sqlite3_os_trace, TCL_LINK_INT); 4011 Tcl_LinkVar(interp, "sqlite3_tsd_count", 4012 (char*)&sqlite3_tsd_count, TCL_LINK_INT); 4013 #ifndef SQLITE_OMIT_UTF16 4014 Tcl_LinkVar(interp, "unaligned_string_counter", 4015 (char*)&unaligned_string_counter, TCL_LINK_INT); 4016 #endif 4017 #if OS_UNIX && defined(SQLITE_TEST) && defined(THREADSAFE) && THREADSAFE 4018 Tcl_LinkVar(interp, "threadsOverrideEachOthersLocks", 4019 (char*)&threadsOverrideEachOthersLocks, TCL_LINK_INT); 4020 #endif 4021 #ifndef SQLITE_OMIT_UTF16 4022 Tcl_LinkVar(interp, "sqlite_last_needed_collation", 4023 (char*)&pzNeededCollation, TCL_LINK_STRING|TCL_LINK_READ_ONLY); 4024 #endif 4025 #ifdef SQLITE_MEMDEBUG 4026 Tcl_LinkVar(interp, "sqlite_malloc_id", 4027 (char*)&sqlite3_malloc_id, TCL_LINK_STRING); 4028 #endif 4029 #if OS_WIN 4030 Tcl_LinkVar(interp, "sqlite_os_type", 4031 (char*)&sqlite3_os_type, TCL_LINK_INT); 4032 #endif 4033 #ifdef SQLITE_TEST 4034 Tcl_LinkVar(interp, "sqlite_query_plan", 4035 (char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY); 4036 #endif 4037 #ifdef SQLITE_DEBUG 4038 Tcl_LinkVar(interp, "sqlite_addop_trace", 4039 (char*)&sqlite3_vdbe_addop_trace, TCL_LINK_INT); 4040 Tcl_LinkVar(interp, "sqlite_where_trace", 4041 (char*)&sqlite3_where_trace, TCL_LINK_INT); 4042 #endif 4043 #ifdef SQLITE_MEMDEBUG 4044 Tcl_LinkVar(interp, "sqlite_memused", 4045 (char*)&sqlite3_memUsed, TCL_LINK_INT | TCL_LINK_READ_ONLY); 4046 Tcl_LinkVar(interp, "sqlite_memmax", 4047 (char*)&sqlite3_memMax, TCL_LINK_INT | TCL_LINK_READ_ONLY); 4048 #endif 4049 #ifndef SQLITE_OMIT_DISKIO 4050 Tcl_LinkVar(interp, "sqlite_opentemp_count", 4051 (char*)&sqlite3_opentemp_count, TCL_LINK_INT); 4052 #endif 4053 Tcl_LinkVar(interp, "sqlite_static_bind_value", 4054 (char*)&sqlite_static_bind_value, TCL_LINK_STRING); 4055 Tcl_LinkVar(interp, "sqlite_static_bind_nbyte", 4056 (char*)&sqlite_static_bind_nbyte, TCL_LINK_INT); 4057 Tcl_LinkVar(interp, "sqlite_temp_directory", 4058 (char*)&sqlite3_temp_directory, TCL_LINK_STRING); 4059 Tcl_LinkVar(interp, "bitmask_size", 4060 (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); 4061 #if OS_UNIX 4062 Tcl_LinkVar(interp, "sqlite_sync_count", 4063 (char*)&sqlite3_sync_count, TCL_LINK_INT); 4064 Tcl_LinkVar(interp, "sqlite_fullsync_count", 4065 (char*)&sqlite3_fullsync_count, TCL_LINK_INT); 4066 #endif /* OS_UNIX */ 4067 set_options(interp); 4068 4069 { 4070 #ifdef SQLITE_DEBUG 4071 extern int sqlite3_shared_cache_report(void *, Tcl_Interp *, 4072 int, Tcl_Obj *CONST[]); 4073 Tcl_CreateObjCommand(interp, "sqlite_shared_cache_report", 4074 sqlite3_shared_cache_report, 0, 0); 4075 #endif 4076 } 4077 return TCL_OK; 4078 } 4079