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 the printf() interface to SQLite. 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.162 2005/09/19 13:15:23 drh Exp $ 17 */ 18 #include "sqliteInt.h" 19 #include "tcl.h" 20 #include "os.h" 21 #include <stdlib.h> 22 #include <string.h> 23 24 const char *sqlite3TestErrorName(int rc){ 25 const char *zName = 0; 26 switch( rc ){ 27 case SQLITE_OK: zName = "SQLITE_OK"; break; 28 case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; 29 case SQLITE_PERM: zName = "SQLITE_PERM"; break; 30 case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; 31 case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; 32 case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; 33 case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; 34 case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; 35 case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; 36 case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; 37 case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; 38 case SQLITE_FULL: zName = "SQLITE_FULL"; break; 39 case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; 40 case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; 41 case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; 42 case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; 43 case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; 44 case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; 45 case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; 46 case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; 47 case SQLITE_AUTH: zName = "SQLITE_AUTH"; break; 48 case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break; 49 case SQLITE_RANGE: zName = "SQLITE_RANGE"; break; 50 case SQLITE_ROW: zName = "SQLITE_ROW"; break; 51 case SQLITE_DONE: zName = "SQLITE_DONE"; break; 52 case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break; 53 default: zName = "SQLITE_Unknown"; break; 54 } 55 return zName; 56 } 57 #define errorName sqlite3TestErrorName 58 59 /* 60 ** Convert an sqlite3_stmt* into an sqlite3*. This depends on the 61 ** fact that the sqlite3* is the first field in the Vdbe structure. 62 */ 63 #define StmtToDb(X) sqlite3_db_handle(X) 64 65 /* 66 ** Check a return value to make sure it agrees with the results 67 ** from sqlite3_errcode. 68 */ 69 int sqlite3TestErrCode(Tcl_Interp *interp, sqlite3 *db, int rc){ 70 if( rc!=SQLITE_MISUSE && rc!=SQLITE_OK && sqlite3_errcode(db)!=rc ){ 71 char zBuf[200]; 72 int r2 = sqlite3_errcode(db); 73 sprintf(zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)", 74 errorName(rc), rc, errorName(r2), r2); 75 Tcl_ResetResult(interp); 76 Tcl_AppendResult(interp, zBuf, 0); 77 return 1; 78 } 79 return 0; 80 } 81 82 /* 83 ** Decode a pointer to an sqlite3 object. 84 */ 85 static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){ 86 *ppDb = (sqlite3*)sqlite3TextToPtr(zA); 87 return TCL_OK; 88 } 89 90 /* 91 ** Decode a pointer to an sqlite3_stmt object. 92 */ 93 static int getStmtPointer( 94 Tcl_Interp *interp, 95 const char *zArg, 96 sqlite3_stmt **ppStmt 97 ){ 98 *ppStmt = (sqlite3_stmt*)sqlite3TextToPtr(zArg); 99 return TCL_OK; 100 } 101 102 /* 103 ** Decode a pointer to an sqlite3_stmt object. 104 */ 105 static int getFilePointer( 106 Tcl_Interp *interp, 107 const char *zArg, 108 OsFile **ppFile 109 ){ 110 *ppFile = (OsFile*)sqlite3TextToPtr(zArg); 111 return TCL_OK; 112 } 113 114 /* 115 ** Generate a text representation of a pointer that can be understood 116 ** by the getDbPointer and getVmPointer routines above. 117 ** 118 ** The problem is, on some machines (Solaris) if you do a printf with 119 ** "%p" you cannot turn around and do a scanf with the same "%p" and 120 ** get your pointer back. You have to prepend a "0x" before it will 121 ** work. Or at least that is what is reported to me (drh). But this 122 ** behavior varies from machine to machine. The solution used her is 123 ** to test the string right after it is generated to see if it can be 124 ** understood by scanf, and if not, try prepending an "0x" to see if 125 ** that helps. If nothing works, a fatal error is generated. 126 */ 127 static int makePointerStr(Tcl_Interp *interp, char *zPtr, void *p){ 128 sqlite3_snprintf(100, zPtr, "%p", p); 129 return TCL_OK; 130 } 131 132 /* 133 ** The callback routine for sqlite3_exec_printf(). 134 */ 135 static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){ 136 Tcl_DString *str = (Tcl_DString*)pArg; 137 int i; 138 139 if( Tcl_DStringLength(str)==0 ){ 140 for(i=0; i<argc; i++){ 141 Tcl_DStringAppendElement(str, name[i] ? name[i] : "NULL"); 142 } 143 } 144 for(i=0; i<argc; i++){ 145 Tcl_DStringAppendElement(str, argv[i] ? argv[i] : "NULL"); 146 } 147 return 0; 148 } 149 150 /* 151 ** Usage: sqlite3_exec_printf DB FORMAT STRING 152 ** 153 ** Invoke the sqlite3_exec_printf() interface using the open database 154 ** DB. The SQL is the string FORMAT. The format string should contain 155 ** one %s or %q. STRING is the value inserted into %s or %q. 156 */ 157 static int test_exec_printf( 158 void *NotUsed, 159 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 160 int argc, /* Number of arguments */ 161 char **argv /* Text of each argument */ 162 ){ 163 sqlite3 *db; 164 Tcl_DString str; 165 int rc; 166 char *zErr = 0; 167 char *zSql; 168 char zBuf[30]; 169 if( argc!=4 ){ 170 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 171 " DB FORMAT STRING", 0); 172 return TCL_ERROR; 173 } 174 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 175 Tcl_DStringInit(&str); 176 zSql = sqlite3_mprintf(argv[2], argv[3]); 177 rc = sqlite3_exec(db, zSql, exec_printf_cb, &str, &zErr); 178 sqlite3_free(zSql); 179 sprintf(zBuf, "%d", rc); 180 Tcl_AppendElement(interp, zBuf); 181 Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr); 182 Tcl_DStringFree(&str); 183 if( zErr ) free(zErr); 184 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 185 return TCL_OK; 186 } 187 188 /* 189 ** Usage: sqlite3_mprintf_z_test SEPARATOR ARG0 ARG1 ... 190 ** 191 ** Test the %z format of mprintf(). Use multiple mprintf() calls to 192 ** concatenate arg0 through argn using separator as the separator. 193 ** Return the result. 194 */ 195 static int test_mprintf_z( 196 void *NotUsed, 197 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 198 int argc, /* Number of arguments */ 199 char **argv /* Text of each argument */ 200 ){ 201 char *zResult = 0; 202 int i; 203 204 for(i=2; i<argc; i++){ 205 zResult = sqlite3MPrintf("%z%s%s", zResult, argv[1], argv[i]); 206 } 207 Tcl_AppendResult(interp, zResult, 0); 208 sqliteFree(zResult); 209 return TCL_OK; 210 } 211 212 /* 213 ** Usage: sqlite3_get_table_printf DB FORMAT STRING 214 ** 215 ** Invoke the sqlite3_get_table_printf() interface using the open database 216 ** DB. The SQL is the string FORMAT. The format string should contain 217 ** one %s or %q. STRING is the value inserted into %s or %q. 218 */ 219 static int test_get_table_printf( 220 void *NotUsed, 221 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 222 int argc, /* Number of arguments */ 223 char **argv /* Text of each argument */ 224 ){ 225 sqlite3 *db; 226 Tcl_DString str; 227 int rc; 228 char *zErr = 0; 229 int nRow, nCol; 230 char **aResult; 231 int i; 232 char zBuf[30]; 233 char *zSql; 234 if( argc!=4 ){ 235 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 236 " DB FORMAT STRING", 0); 237 return TCL_ERROR; 238 } 239 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 240 Tcl_DStringInit(&str); 241 zSql = sqlite3_mprintf(argv[2],argv[3]); 242 rc = sqlite3_get_table(db, zSql, &aResult, &nRow, &nCol, &zErr); 243 sqlite3_free(zSql); 244 sprintf(zBuf, "%d", rc); 245 Tcl_AppendElement(interp, zBuf); 246 if( rc==SQLITE_OK ){ 247 sprintf(zBuf, "%d", nRow); 248 Tcl_AppendElement(interp, zBuf); 249 sprintf(zBuf, "%d", nCol); 250 Tcl_AppendElement(interp, zBuf); 251 for(i=0; i<(nRow+1)*nCol; i++){ 252 Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL"); 253 } 254 }else{ 255 Tcl_AppendElement(interp, zErr); 256 } 257 sqlite3_free_table(aResult); 258 if( zErr ) free(zErr); 259 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 260 return TCL_OK; 261 } 262 263 264 /* 265 ** Usage: sqlite3_last_insert_rowid DB 266 ** 267 ** Returns the integer ROWID of the most recent insert. 268 */ 269 static int test_last_rowid( 270 void *NotUsed, 271 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 272 int argc, /* Number of arguments */ 273 char **argv /* Text of each argument */ 274 ){ 275 sqlite3 *db; 276 char zBuf[30]; 277 278 if( argc!=2 ){ 279 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0); 280 return TCL_ERROR; 281 } 282 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 283 sprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db)); 284 Tcl_AppendResult(interp, zBuf, 0); 285 return SQLITE_OK; 286 } 287 288 /* 289 ** Usage: sqlite3_key DB KEY 290 ** 291 ** Set the codec key. 292 */ 293 static int test_key( 294 void *NotUsed, 295 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 296 int argc, /* Number of arguments */ 297 char **argv /* Text of each argument */ 298 ){ 299 sqlite3 *db; 300 const char *zKey; 301 int nKey; 302 if( argc!=3 ){ 303 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 304 " FILENAME\"", 0); 305 return TCL_ERROR; 306 } 307 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 308 zKey = argv[2]; 309 nKey = strlen(zKey); 310 #ifdef SQLITE_HAS_CODEC 311 sqlite3_key(db, zKey, nKey); 312 #endif 313 return TCL_OK; 314 } 315 316 /* 317 ** Usage: sqlite3_rekey DB KEY 318 ** 319 ** Change the codec key. 320 */ 321 static int test_rekey( 322 void *NotUsed, 323 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 324 int argc, /* Number of arguments */ 325 char **argv /* Text of each argument */ 326 ){ 327 sqlite3 *db; 328 const char *zKey; 329 int nKey; 330 if( argc!=3 ){ 331 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 332 " FILENAME\"", 0); 333 return TCL_ERROR; 334 } 335 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 336 zKey = argv[2]; 337 nKey = strlen(zKey); 338 #ifdef SQLITE_HAS_CODEC 339 sqlite3_rekey(db, zKey, nKey); 340 #endif 341 return TCL_OK; 342 } 343 344 /* 345 ** Usage: sqlite3_close DB 346 ** 347 ** Closes the database opened by sqlite3_open. 348 */ 349 static int sqlite_test_close( 350 void *NotUsed, 351 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 352 int argc, /* Number of arguments */ 353 char **argv /* Text of each argument */ 354 ){ 355 sqlite3 *db; 356 int rc; 357 if( argc!=2 ){ 358 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 359 " FILENAME\"", 0); 360 return TCL_ERROR; 361 } 362 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 363 rc = sqlite3_close(db); 364 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 365 return TCL_OK; 366 } 367 368 /* 369 ** Implementation of the x_coalesce() function. 370 ** Return the first argument non-NULL argument. 371 */ 372 static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 373 int i; 374 for(i=0; i<argc; i++){ 375 if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){ 376 sqlite3_result_text(context, sqlite3_value_text(argv[i]), -1, 377 SQLITE_TRANSIENT); 378 break; 379 } 380 } 381 } 382 383 /* 384 ** A structure into which to accumulate text. 385 */ 386 struct dstr { 387 int nAlloc; /* Space allocated */ 388 int nUsed; /* Space used */ 389 char *z; /* The space */ 390 }; 391 392 /* 393 ** Append text to a dstr 394 */ 395 static void dstrAppend(struct dstr *p, const char *z, int divider){ 396 int n = strlen(z); 397 if( p->nUsed + n + 2 > p->nAlloc ){ 398 char *zNew; 399 p->nAlloc = p->nAlloc*2 + n + 200; 400 zNew = sqliteRealloc(p->z, p->nAlloc); 401 if( zNew==0 ){ 402 sqliteFree(p->z); 403 memset(p, 0, sizeof(*p)); 404 return; 405 } 406 p->z = zNew; 407 } 408 if( divider && p->nUsed>0 ){ 409 p->z[p->nUsed++] = divider; 410 } 411 memcpy(&p->z[p->nUsed], z, n+1); 412 p->nUsed += n; 413 } 414 415 /* 416 ** Invoked for each callback from sqlite3ExecFunc 417 */ 418 static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){ 419 struct dstr *p = (struct dstr*)pData; 420 int i; 421 for(i=0; i<argc; i++){ 422 if( argv[i]==0 ){ 423 dstrAppend(p, "NULL", ' '); 424 }else{ 425 dstrAppend(p, argv[i], ' '); 426 } 427 } 428 return 0; 429 } 430 431 /* 432 ** Implementation of the x_sqlite_exec() function. This function takes 433 ** a single argument and attempts to execute that argument as SQL code. 434 ** This is illegal and should set the SQLITE_MISUSE flag on the database. 435 ** 436 ** 2004-Jan-07: We have changed this to make it legal to call sqlite3_exec() 437 ** from within a function call. 438 ** 439 ** This routine simulates the effect of having two threads attempt to 440 ** use the same database at the same time. 441 */ 442 static void sqlite3ExecFunc( 443 sqlite3_context *context, 444 int argc, 445 sqlite3_value **argv 446 ){ 447 struct dstr x; 448 memset(&x, 0, sizeof(x)); 449 sqlite3_exec((sqlite3*)sqlite3_user_data(context), 450 sqlite3_value_text(argv[0]), 451 execFuncCallback, &x, 0); 452 sqlite3_result_text(context, x.z, x.nUsed, SQLITE_TRANSIENT); 453 sqliteFree(x.z); 454 } 455 456 /* 457 ** Usage: sqlite_test_create_function DB 458 ** 459 ** Call the sqlite3_create_function API on the given database in order 460 ** to create a function named "x_coalesce". This function does the same thing 461 ** as the "coalesce" function. This function also registers an SQL function 462 ** named "x_sqlite_exec" that invokes sqlite3_exec(). Invoking sqlite3_exec() 463 ** in this way is illegal recursion and should raise an SQLITE_MISUSE error. 464 ** The effect is similar to trying to use the same database connection from 465 ** two threads at the same time. 466 ** 467 ** The original motivation for this routine was to be able to call the 468 ** sqlite3_create_function function while a query is in progress in order 469 ** to test the SQLITE_MISUSE detection logic. 470 */ 471 static int test_create_function( 472 void *NotUsed, 473 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 474 int argc, /* Number of arguments */ 475 char **argv /* Text of each argument */ 476 ){ 477 int rc; 478 sqlite3 *db; 479 extern void Md5_Register(sqlite3*); 480 481 if( argc!=2 ){ 482 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 483 " DB\"", 0); 484 return TCL_ERROR; 485 } 486 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 487 rc = sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0, 488 ifnullFunc, 0, 0); 489 490 #ifndef SQLITE_OMIT_UTF16 491 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 492 ** because it is not tested anywhere else. */ 493 if( rc==SQLITE_OK ){ 494 sqlite3_value *pVal; 495 pVal = sqlite3ValueNew(); 496 sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC); 497 rc = sqlite3_create_function16(db, 498 sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), 499 1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0); 500 sqlite3ValueFree(pVal); 501 } 502 #endif 503 504 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 505 Tcl_SetResult(interp, (char *)errorName(rc), 0); 506 return TCL_OK; 507 } 508 509 /* 510 ** Routines to implement the x_count() aggregate function. 511 */ 512 typedef struct CountCtx CountCtx; 513 struct CountCtx { 514 int n; 515 }; 516 static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ 517 CountCtx *p; 518 p = sqlite3_aggregate_context(context, sizeof(*p)); 519 if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0]) ) && p ){ 520 p->n++; 521 } 522 } 523 static void countFinalize(sqlite3_context *context){ 524 CountCtx *p; 525 p = sqlite3_aggregate_context(context, sizeof(*p)); 526 sqlite3_result_int(context, p ? p->n : 0); 527 } 528 529 /* 530 ** Usage: sqlite_test_create_aggregate DB 531 ** 532 ** Call the sqlite3_create_function API on the given database in order 533 ** to create a function named "x_count". This function does the same thing 534 ** as the "md5sum" function. 535 ** 536 ** The original motivation for this routine was to be able to call the 537 ** sqlite3_create_aggregate function while a query is in progress in order 538 ** to test the SQLITE_MISUSE detection logic. 539 */ 540 static int test_create_aggregate( 541 void *NotUsed, 542 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 543 int argc, /* Number of arguments */ 544 char **argv /* Text of each argument */ 545 ){ 546 sqlite3 *db; 547 int rc; 548 if( argc!=2 ){ 549 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 550 " FILENAME\"", 0); 551 return TCL_ERROR; 552 } 553 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 554 rc = sqlite3_create_function(db, "x_count", 0, SQLITE_UTF8, 0, 0, 555 countStep,countFinalize); 556 if( rc==SQLITE_OK ){ 557 sqlite3_create_function(db, "x_count", 1, SQLITE_UTF8, 0, 0, 558 countStep,countFinalize); 559 } 560 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 561 return TCL_OK; 562 } 563 564 565 566 /* 567 ** Usage: sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER 568 ** 569 ** Call mprintf with three integer arguments 570 */ 571 static int sqlite3_mprintf_int( 572 void *NotUsed, 573 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 574 int argc, /* Number of arguments */ 575 char **argv /* Text of each argument */ 576 ){ 577 int a[3], i; 578 char *z; 579 if( argc!=5 ){ 580 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 581 " FORMAT INT INT INT\"", 0); 582 return TCL_ERROR; 583 } 584 for(i=2; i<5; i++){ 585 if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 586 } 587 z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]); 588 Tcl_AppendResult(interp, z, 0); 589 sqlite3_free(z); 590 return TCL_OK; 591 } 592 593 /* 594 ** If zNum represents an integer that will fit in 64-bits, then set 595 ** *pValue to that integer and return true. Otherwise return false. 596 */ 597 static int sqlite3GetInt64(const char *zNum, i64 *pValue){ 598 if( sqlite3FitsIn64Bits(zNum) ){ 599 sqlite3atoi64(zNum, pValue); 600 return 1; 601 } 602 return 0; 603 } 604 605 /* 606 ** Usage: sqlite3_mprintf_int64 FORMAT INTEGER INTEGER INTEGER 607 ** 608 ** Call mprintf with three 64-bit integer arguments 609 */ 610 static int sqlite3_mprintf_int64( 611 void *NotUsed, 612 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 613 int argc, /* Number of arguments */ 614 char **argv /* Text of each argument */ 615 ){ 616 int i; 617 sqlite_int64 a[3]; 618 char *z; 619 if( argc!=5 ){ 620 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 621 " FORMAT INT INT INT\"", 0); 622 return TCL_ERROR; 623 } 624 for(i=2; i<5; i++){ 625 if( !sqlite3GetInt64(argv[i], &a[i-2]) ){ 626 Tcl_AppendResult(interp, "argument is not a valid 64-bit integer", 0); 627 return TCL_ERROR; 628 } 629 } 630 z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]); 631 Tcl_AppendResult(interp, z, 0); 632 sqlite3_free(z); 633 return TCL_OK; 634 } 635 636 /* 637 ** Usage: sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING 638 ** 639 ** Call mprintf with two integer arguments and one string argument 640 */ 641 static int sqlite3_mprintf_str( 642 void *NotUsed, 643 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 644 int argc, /* Number of arguments */ 645 char **argv /* Text of each argument */ 646 ){ 647 int a[3], i; 648 char *z; 649 if( argc<4 || argc>5 ){ 650 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 651 " FORMAT INT INT ?STRING?\"", 0); 652 return TCL_ERROR; 653 } 654 for(i=2; i<4; i++){ 655 if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 656 } 657 z = sqlite3_mprintf(argv[1], a[0], a[1], argc>4 ? argv[4] : NULL); 658 Tcl_AppendResult(interp, z, 0); 659 sqlite3_free(z); 660 return TCL_OK; 661 } 662 663 /* 664 ** Usage: sqlite3_mprintf_double FORMAT INTEGER INTEGER DOUBLE 665 ** 666 ** Call mprintf with two integer arguments and one double argument 667 */ 668 static int sqlite3_mprintf_double( 669 void *NotUsed, 670 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 671 int argc, /* Number of arguments */ 672 char **argv /* Text of each argument */ 673 ){ 674 int a[3], i; 675 double r; 676 char *z; 677 if( argc!=5 ){ 678 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 679 " FORMAT INT INT DOUBLE\"", 0); 680 return TCL_ERROR; 681 } 682 for(i=2; i<4; i++){ 683 if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 684 } 685 if( Tcl_GetDouble(interp, argv[4], &r) ) return TCL_ERROR; 686 z = sqlite3_mprintf(argv[1], a[0], a[1], r); 687 Tcl_AppendResult(interp, z, 0); 688 sqlite3_free(z); 689 return TCL_OK; 690 } 691 692 /* 693 ** Usage: sqlite3_mprintf_scaled FORMAT DOUBLE DOUBLE 694 ** 695 ** Call mprintf with a single double argument which is the product of the 696 ** two arguments given above. This is used to generate overflow and underflow 697 ** doubles to test that they are converted properly. 698 */ 699 static int sqlite3_mprintf_scaled( 700 void *NotUsed, 701 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 702 int argc, /* Number of arguments */ 703 char **argv /* Text of each argument */ 704 ){ 705 int i; 706 double r[2]; 707 char *z; 708 if( argc!=4 ){ 709 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 710 " FORMAT DOUBLE DOUBLE\"", 0); 711 return TCL_ERROR; 712 } 713 for(i=2; i<4; i++){ 714 if( Tcl_GetDouble(interp, argv[i], &r[i-2]) ) return TCL_ERROR; 715 } 716 z = sqlite3_mprintf(argv[1], r[0]*r[1]); 717 Tcl_AppendResult(interp, z, 0); 718 sqlite3_free(z); 719 return TCL_OK; 720 } 721 722 /* 723 ** Usage: sqlite3_mprintf_stronly FORMAT STRING 724 ** 725 ** Call mprintf with a single double argument which is the product of the 726 ** two arguments given above. This is used to generate overflow and underflow 727 ** doubles to test that they are converted properly. 728 */ 729 static int sqlite3_mprintf_stronly( 730 void *NotUsed, 731 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 732 int argc, /* Number of arguments */ 733 char **argv /* Text of each argument */ 734 ){ 735 char *z; 736 if( argc!=3 ){ 737 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 738 " FORMAT STRING\"", 0); 739 return TCL_ERROR; 740 } 741 z = sqlite3_mprintf(argv[1], argv[2]); 742 Tcl_AppendResult(interp, z, 0); 743 sqlite3_free(z); 744 return TCL_OK; 745 } 746 747 /* 748 ** Usage: sqlite3_mprintf_hexdouble FORMAT HEX 749 ** 750 ** Call mprintf with a single double argument which is derived from the 751 ** hexadecimal encoding of an IEEE double. 752 */ 753 static int sqlite3_mprintf_hexdouble( 754 void *NotUsed, 755 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 756 int argc, /* Number of arguments */ 757 char **argv /* Text of each argument */ 758 ){ 759 char *z; 760 double r; 761 unsigned x1, x2; 762 long long unsigned d; 763 if( argc!=3 ){ 764 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 765 " FORMAT STRING\"", 0); 766 return TCL_ERROR; 767 } 768 if( sscanf(argv[2], "%08x%08x", &x2, &x1)!=2 ){ 769 Tcl_AppendResult(interp, "2nd argument should be 16-characters of hex", 0); 770 return TCL_ERROR; 771 } 772 d = x2; 773 d = (d<<32) + x1; 774 memcpy(&r, &d, sizeof(r)); 775 z = sqlite3_mprintf(argv[1], r); 776 Tcl_AppendResult(interp, z, 0); 777 sqlite3_free(z); 778 return TCL_OK; 779 } 780 781 /* 782 ** Usage: sqlite_malloc_fail N ?REPEAT-INTERVAL? 783 ** 784 ** Rig sqliteMalloc() to fail on the N-th call and every REPEAT-INTERVAL call 785 ** after that. If REPEAT-INTERVAL is 0 or is omitted, then only a single 786 ** malloc will fail. If REPEAT-INTERVAL is 1 then all mallocs after the 787 ** first failure will continue to fail on every call. If REPEAT-INTERVAL is 788 ** 2 then every other malloc will fail. And so forth. 789 ** 790 ** Turn off this mechanism and reset the sqlite3_malloc_failed variable is N==0. 791 */ 792 #ifdef SQLITE_MEMDEBUG 793 static int sqlite_malloc_fail( 794 void *NotUsed, 795 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 796 int argc, /* Number of arguments */ 797 char **argv /* Text of each argument */ 798 ){ 799 int n; 800 int rep; 801 if( argc!=2 && argc!=3 ){ 802 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"", 0); 803 return TCL_ERROR; 804 } 805 if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR; 806 if( argc==3 ){ 807 if( Tcl_GetInt(interp, argv[2], &rep) ) return TCL_ERROR; 808 }else{ 809 rep = 0; 810 } 811 sqlite3_iMallocFail = n; 812 sqlite3_iMallocReset = rep; 813 sqlite3_malloc_failed = 0; 814 return TCL_OK; 815 } 816 #endif 817 818 /* 819 ** Usage: sqlite_malloc_stat 820 ** 821 ** Return the number of prior calls to sqliteMalloc() and sqliteFree(). 822 */ 823 #ifdef SQLITE_MEMDEBUG 824 static int sqlite_malloc_stat( 825 void *NotUsed, 826 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 827 int argc, /* Number of arguments */ 828 char **argv /* Text of each argument */ 829 ){ 830 char zBuf[200]; 831 sprintf(zBuf, "%d %d %d", sqlite3_nMalloc, sqlite3_nFree, sqlite3_iMallocFail); 832 Tcl_AppendResult(interp, zBuf, 0); 833 return TCL_OK; 834 } 835 #endif 836 837 /* 838 ** Usage: sqlite_abort 839 ** 840 ** Shutdown the process immediately. This is not a clean shutdown. 841 ** This command is used to test the recoverability of a database in 842 ** the event of a program crash. 843 */ 844 static int sqlite_abort( 845 void *NotUsed, 846 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 847 int argc, /* Number of arguments */ 848 char **argv /* Text of each argument */ 849 ){ 850 assert( interp==0 ); /* This will always fail */ 851 return TCL_OK; 852 } 853 854 /* 855 ** The following routine is a user-defined SQL function whose purpose 856 ** is to test the sqlite_set_result() API. 857 */ 858 static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 859 while( argc>=2 ){ 860 const char *zArg0 = sqlite3_value_text(argv[0]); 861 if( zArg0 ){ 862 if( 0==sqlite3StrICmp(zArg0, "int") ){ 863 sqlite3_result_int(context, sqlite3_value_int(argv[1])); 864 }else if( sqlite3StrICmp(zArg0,"int64")==0 ){ 865 sqlite3_result_int64(context, sqlite3_value_int64(argv[1])); 866 }else if( sqlite3StrICmp(zArg0,"string")==0 ){ 867 sqlite3_result_text(context, sqlite3_value_text(argv[1]), -1, 868 SQLITE_TRANSIENT); 869 }else if( sqlite3StrICmp(zArg0,"double")==0 ){ 870 sqlite3_result_double(context, sqlite3_value_double(argv[1])); 871 }else if( sqlite3StrICmp(zArg0,"null")==0 ){ 872 sqlite3_result_null(context); 873 }else if( sqlite3StrICmp(zArg0,"value")==0 ){ 874 sqlite3_result_value(context, argv[sqlite3_value_int(argv[1])]); 875 }else{ 876 goto error_out; 877 } 878 }else{ 879 goto error_out; 880 } 881 argc -= 2; 882 argv += 2; 883 } 884 return; 885 886 error_out: 887 sqlite3_result_error(context,"first argument should be one of: " 888 "int int64 string double null value", -1); 889 } 890 891 /* 892 ** Usage: sqlite_register_test_function DB NAME 893 ** 894 ** Register the test SQL function on the database DB under the name NAME. 895 */ 896 static int test_register_func( 897 void *NotUsed, 898 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 899 int argc, /* Number of arguments */ 900 char **argv /* Text of each argument */ 901 ){ 902 sqlite3 *db; 903 int rc; 904 if( argc!=3 ){ 905 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 906 " DB FUNCTION-NAME", 0); 907 return TCL_ERROR; 908 } 909 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 910 rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 911 testFunc, 0, 0); 912 if( rc!=0 ){ 913 Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0); 914 return TCL_ERROR; 915 } 916 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 917 return TCL_OK; 918 } 919 920 /* 921 ** Usage: sqlite3_finalize STMT 922 ** 923 ** Finalize a statement handle. 924 */ 925 static int test_finalize( 926 void * clientData, 927 Tcl_Interp *interp, 928 int objc, 929 Tcl_Obj *CONST objv[] 930 ){ 931 sqlite3_stmt *pStmt; 932 int rc; 933 sqlite3 *db; 934 935 if( objc!=2 ){ 936 Tcl_AppendResult(interp, "wrong # args: should be \"", 937 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 938 return TCL_ERROR; 939 } 940 941 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 942 943 if( pStmt ){ 944 db = StmtToDb(pStmt); 945 } 946 rc = sqlite3_finalize(pStmt); 947 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 948 if( db && sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 949 return TCL_OK; 950 } 951 952 /* 953 ** Usage: sqlite3_reset STMT 954 ** 955 ** Finalize a statement handle. 956 */ 957 static int test_reset( 958 void * clientData, 959 Tcl_Interp *interp, 960 int objc, 961 Tcl_Obj *CONST objv[] 962 ){ 963 sqlite3_stmt *pStmt; 964 int rc; 965 966 if( objc!=2 ){ 967 Tcl_AppendResult(interp, "wrong # args: should be \"", 968 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 969 return TCL_ERROR; 970 } 971 972 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 973 974 rc = sqlite3_reset(pStmt); 975 if( pStmt && 976 sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 977 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 978 if( rc ){ 979 return TCL_ERROR; 980 } 981 return TCL_OK; 982 } 983 984 /* 985 ** Usage: sqlite3_expired STMT 986 ** 987 ** Return TRUE if a recompilation of the statement is recommended. 988 */ 989 static int test_expired( 990 void * clientData, 991 Tcl_Interp *interp, 992 int objc, 993 Tcl_Obj *CONST objv[] 994 ){ 995 sqlite3_stmt *pStmt; 996 if( objc!=2 ){ 997 Tcl_AppendResult(interp, "wrong # args: should be \"", 998 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 999 return TCL_ERROR; 1000 } 1001 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1002 Tcl_SetObjResult(interp, Tcl_NewBooleanObj(sqlite3_expired(pStmt))); 1003 return TCL_OK; 1004 } 1005 1006 /* 1007 ** Usage: sqlite3_transfer_bindings FROMSTMT TOSTMT 1008 ** 1009 ** Transfer all bindings from FROMSTMT over to TOSTMT 1010 */ 1011 static int test_transfer_bind( 1012 void * clientData, 1013 Tcl_Interp *interp, 1014 int objc, 1015 Tcl_Obj *CONST objv[] 1016 ){ 1017 sqlite3_stmt *pStmt1, *pStmt2; 1018 if( objc!=3 ){ 1019 Tcl_AppendResult(interp, "wrong # args: should be \"", 1020 Tcl_GetStringFromObj(objv[0], 0), " FROM-STMT TO-STMT", 0); 1021 return TCL_ERROR; 1022 } 1023 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt1)) return TCL_ERROR; 1024 if( getStmtPointer(interp, Tcl_GetString(objv[2]), &pStmt2)) return TCL_ERROR; 1025 Tcl_SetObjResult(interp, 1026 Tcl_NewIntObj(sqlite3_transfer_bindings(pStmt1,pStmt2))); 1027 return TCL_OK; 1028 } 1029 1030 /* 1031 ** Usage: sqlite3_changes DB 1032 ** 1033 ** Return the number of changes made to the database by the last SQL 1034 ** execution. 1035 */ 1036 static int test_changes( 1037 void * clientData, 1038 Tcl_Interp *interp, 1039 int objc, 1040 Tcl_Obj *CONST objv[] 1041 ){ 1042 sqlite3 *db; 1043 if( objc!=2 ){ 1044 Tcl_AppendResult(interp, "wrong # args: should be \"", 1045 Tcl_GetString(objv[0]), " DB", 0); 1046 return TCL_ERROR; 1047 } 1048 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1049 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_changes(db))); 1050 return TCL_OK; 1051 } 1052 1053 /* 1054 ** This is the "static_bind_value" that variables are bound to when 1055 ** the FLAG option of sqlite3_bind is "static" 1056 */ 1057 static char *sqlite_static_bind_value = 0; 1058 1059 /* 1060 ** Usage: sqlite3_bind VM IDX VALUE FLAGS 1061 ** 1062 ** Sets the value of the IDX-th occurance of "?" in the original SQL 1063 ** string. VALUE is the new value. If FLAGS=="null" then VALUE is 1064 ** ignored and the value is set to NULL. If FLAGS=="static" then 1065 ** the value is set to the value of a static variable named 1066 ** "sqlite_static_bind_value". If FLAGS=="normal" then a copy 1067 ** of the VALUE is made. 1068 */ 1069 static int test_bind( 1070 void *NotUsed, 1071 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 1072 int argc, /* Number of arguments */ 1073 char **argv /* Text of each argument */ 1074 ){ 1075 sqlite3_stmt *pStmt; 1076 int rc; 1077 int idx; 1078 if( argc!=5 ){ 1079 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 1080 " VM IDX VALUE (null|static|normal)\"", 0); 1081 return TCL_ERROR; 1082 } 1083 if( getStmtPointer(interp, argv[1], &pStmt) ) return TCL_ERROR; 1084 if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR; 1085 if( strcmp(argv[4],"null")==0 ){ 1086 rc = sqlite3_bind_null(pStmt, idx); 1087 }else if( strcmp(argv[4],"static")==0 ){ 1088 rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0); 1089 }else if( strcmp(argv[4],"normal")==0 ){ 1090 rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, SQLITE_TRANSIENT); 1091 }else{ 1092 Tcl_AppendResult(interp, "4th argument should be " 1093 "\"null\" or \"static\" or \"normal\"", 0); 1094 return TCL_ERROR; 1095 } 1096 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 1097 if( rc ){ 1098 char zBuf[50]; 1099 sprintf(zBuf, "(%d) ", rc); 1100 Tcl_AppendResult(interp, zBuf, sqlite3ErrStr(rc), 0); 1101 return TCL_ERROR; 1102 } 1103 return TCL_OK; 1104 } 1105 1106 #ifndef SQLITE_OMIT_UTF16 1107 /* 1108 ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be> 1109 ** 1110 ** This function is used to test that SQLite selects the correct collation 1111 ** sequence callback when multiple versions (for different text encodings) 1112 ** are available. 1113 ** 1114 ** Calling this routine registers the collation sequence "test_collate" 1115 ** with database handle <db>. The second argument must be a list of three 1116 ** boolean values. If the first is true, then a version of test_collate is 1117 ** registered for UTF-8, if the second is true, a version is registered for 1118 ** UTF-16le, if the third is true, a UTF-16be version is available. 1119 ** Previous versions of test_collate are deleted. 1120 ** 1121 ** The collation sequence test_collate is implemented by calling the 1122 ** following TCL script: 1123 ** 1124 ** "test_collate <enc> <lhs> <rhs>" 1125 ** 1126 ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8. 1127 ** The <enc> parameter is the encoding of the collation function that 1128 ** SQLite selected to call. The TCL test script implements the 1129 ** "test_collate" proc. 1130 ** 1131 ** Note that this will only work with one intepreter at a time, as the 1132 ** interp pointer to use when evaluating the TCL script is stored in 1133 ** pTestCollateInterp. 1134 */ 1135 static Tcl_Interp* pTestCollateInterp; 1136 static int test_collate_func( 1137 void *pCtx, 1138 int nA, const void *zA, 1139 int nB, const void *zB 1140 ){ 1141 Tcl_Interp *i = pTestCollateInterp; 1142 int encin = (int)pCtx; 1143 int res; 1144 int n; 1145 1146 sqlite3_value *pVal; 1147 Tcl_Obj *pX; 1148 1149 pX = Tcl_NewStringObj("test_collate", -1); 1150 Tcl_IncrRefCount(pX); 1151 1152 switch( encin ){ 1153 case SQLITE_UTF8: 1154 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-8",-1)); 1155 break; 1156 case SQLITE_UTF16LE: 1157 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16LE",-1)); 1158 break; 1159 case SQLITE_UTF16BE: 1160 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16BE",-1)); 1161 break; 1162 default: 1163 assert(0); 1164 } 1165 1166 pVal = sqlite3ValueNew(); 1167 sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC); 1168 n = sqlite3_value_bytes(pVal); 1169 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj(sqlite3_value_text(pVal),n)); 1170 sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC); 1171 n = sqlite3_value_bytes(pVal); 1172 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj(sqlite3_value_text(pVal),n)); 1173 sqlite3ValueFree(pVal); 1174 1175 Tcl_EvalObjEx(i, pX, 0); 1176 Tcl_DecrRefCount(pX); 1177 Tcl_GetIntFromObj(i, Tcl_GetObjResult(i), &res); 1178 return res; 1179 } 1180 static int test_collate( 1181 void * clientData, 1182 Tcl_Interp *interp, 1183 int objc, 1184 Tcl_Obj *CONST objv[] 1185 ){ 1186 sqlite3 *db; 1187 int val; 1188 sqlite3_value *pVal; 1189 int rc; 1190 1191 if( objc!=5 ) goto bad_args; 1192 pTestCollateInterp = interp; 1193 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1194 1195 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; 1196 rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8, 1197 (void *)SQLITE_UTF8, val?test_collate_func:0); 1198 if( rc==SQLITE_OK ){ 1199 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; 1200 rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE, 1201 (void *)SQLITE_UTF16LE, val?test_collate_func:0); 1202 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR; 1203 1204 pVal = sqlite3ValueNew(); 1205 sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC); 1206 sqlite3_create_collation16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), 1207 SQLITE_UTF16BE, (void *)SQLITE_UTF16BE, val?test_collate_func:0); 1208 sqlite3ValueFree(pVal); 1209 } 1210 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1211 return TCL_OK; 1212 1213 bad_args: 1214 Tcl_AppendResult(interp, "wrong # args: should be \"", 1215 Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); 1216 return TCL_ERROR; 1217 } 1218 1219 static void test_collate_needed_cb( 1220 void *pCtx, 1221 sqlite3 *db, 1222 int eTextRep, 1223 const void *notUsed 1224 ){ 1225 int enc = db->enc; 1226 sqlite3_create_collation( 1227 db, "test_collate", db->enc, (void *)enc, test_collate_func); 1228 } 1229 1230 /* 1231 ** Usage: add_test_collate_needed DB 1232 */ 1233 static int test_collate_needed( 1234 void * clientData, 1235 Tcl_Interp *interp, 1236 int objc, 1237 Tcl_Obj *CONST objv[] 1238 ){ 1239 sqlite3 *db; 1240 int rc; 1241 1242 if( objc!=2 ) goto bad_args; 1243 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1244 rc = sqlite3_collation_needed16(db, 0, test_collate_needed_cb); 1245 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1246 return TCL_OK; 1247 1248 bad_args: 1249 Tcl_WrongNumArgs(interp, 1, objv, "DB"); 1250 return TCL_ERROR; 1251 } 1252 #endif /* SQLITE_OMIT_UTF16 */ 1253 1254 /* 1255 ** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be> 1256 ** 1257 ** This function is used to test that SQLite selects the correct user 1258 ** function callback when multiple versions (for different text encodings) 1259 ** are available. 1260 ** 1261 ** Calling this routine registers up to three versions of the user function 1262 ** "test_function" with database handle <db>. If the second argument is 1263 ** true, then a version of test_function is registered for UTF-8, if the 1264 ** third is true, a version is registered for UTF-16le, if the fourth is 1265 ** true, a UTF-16be version is available. Previous versions of 1266 ** test_function are deleted. 1267 ** 1268 ** The user function is implemented by calling the following TCL script: 1269 ** 1270 ** "test_function <enc> <arg>" 1271 ** 1272 ** Where <enc> is one of UTF-8, UTF-16LE or UTF16BE, and <arg> is the 1273 ** single argument passed to the SQL function. The value returned by 1274 ** the TCL script is used as the return value of the SQL function. It 1275 ** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8 1276 ** for a UTF-16LE test_function(), and UTF-16LE for an implementation that 1277 ** prefers UTF-16BE. 1278 */ 1279 #ifndef SQLITE_OMIT_UTF16 1280 static void test_function_utf8( 1281 sqlite3_context *pCtx, 1282 int nArg, 1283 sqlite3_value **argv 1284 ){ 1285 Tcl_Interp *interp; 1286 Tcl_Obj *pX; 1287 sqlite3_value *pVal; 1288 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1289 pX = Tcl_NewStringObj("test_function", -1); 1290 Tcl_IncrRefCount(pX); 1291 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-8", -1)); 1292 Tcl_ListObjAppendElement(interp, pX, 1293 Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); 1294 Tcl_EvalObjEx(interp, pX, 0); 1295 Tcl_DecrRefCount(pX); 1296 sqlite3_result_text(pCtx, Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT); 1297 pVal = sqlite3ValueNew(); 1298 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1299 SQLITE_UTF8, SQLITE_STATIC); 1300 sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal), 1301 -1, SQLITE_TRANSIENT); 1302 sqlite3ValueFree(pVal); 1303 } 1304 static void test_function_utf16le( 1305 sqlite3_context *pCtx, 1306 int nArg, 1307 sqlite3_value **argv 1308 ){ 1309 Tcl_Interp *interp; 1310 Tcl_Obj *pX; 1311 sqlite3_value *pVal; 1312 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1313 pX = Tcl_NewStringObj("test_function", -1); 1314 Tcl_IncrRefCount(pX); 1315 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16LE", -1)); 1316 Tcl_ListObjAppendElement(interp, pX, 1317 Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); 1318 Tcl_EvalObjEx(interp, pX, 0); 1319 Tcl_DecrRefCount(pX); 1320 pVal = sqlite3ValueNew(); 1321 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1322 SQLITE_UTF8, SQLITE_STATIC); 1323 sqlite3_result_text(pCtx,sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT); 1324 sqlite3ValueFree(pVal); 1325 } 1326 static void test_function_utf16be( 1327 sqlite3_context *pCtx, 1328 int nArg, 1329 sqlite3_value **argv 1330 ){ 1331 Tcl_Interp *interp; 1332 Tcl_Obj *pX; 1333 sqlite3_value *pVal; 1334 interp = (Tcl_Interp *)sqlite3_user_data(pCtx); 1335 pX = Tcl_NewStringObj("test_function", -1); 1336 Tcl_IncrRefCount(pX); 1337 Tcl_ListObjAppendElement(interp, pX, Tcl_NewStringObj("UTF-16BE", -1)); 1338 Tcl_ListObjAppendElement(interp, pX, 1339 Tcl_NewStringObj(sqlite3_value_text(argv[0]), -1)); 1340 Tcl_EvalObjEx(interp, pX, 0); 1341 Tcl_DecrRefCount(pX); 1342 pVal = sqlite3ValueNew(); 1343 sqlite3ValueSetStr(pVal, -1, Tcl_GetStringResult(interp), 1344 SQLITE_UTF8, SQLITE_STATIC); 1345 sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal), 1346 -1, SQLITE_TRANSIENT); 1347 sqlite3ValueFree(pVal); 1348 } 1349 #endif /* SQLITE_OMIT_UTF16 */ 1350 static int test_function( 1351 void * clientData, 1352 Tcl_Interp *interp, 1353 int objc, 1354 Tcl_Obj *CONST objv[] 1355 ){ 1356 #ifndef SQLITE_OMIT_UTF16 1357 sqlite3 *db; 1358 int val; 1359 1360 if( objc!=5 ) goto bad_args; 1361 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1362 1363 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; 1364 if( val ){ 1365 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF8, 1366 interp, test_function_utf8, 0, 0); 1367 } 1368 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; 1369 if( val ){ 1370 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16LE, 1371 interp, test_function_utf16le, 0, 0); 1372 } 1373 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR; 1374 if( val ){ 1375 sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16BE, 1376 interp, test_function_utf16be, 0, 0); 1377 } 1378 1379 return TCL_OK; 1380 bad_args: 1381 Tcl_AppendResult(interp, "wrong # args: should be \"", 1382 Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); 1383 #endif /* SQLITE_OMIT_UTF16 */ 1384 return TCL_ERROR; 1385 } 1386 1387 /* 1388 ** Usage: test_errstr <err code> 1389 ** 1390 ** Test that the english language string equivalents for sqlite error codes 1391 ** are sane. The parameter is an integer representing an sqlite error code. 1392 ** The result is a list of two elements, the string representation of the 1393 ** error code and the english language explanation. 1394 */ 1395 static int test_errstr( 1396 void * clientData, 1397 Tcl_Interp *interp, 1398 int objc, 1399 Tcl_Obj *CONST objv[] 1400 ){ 1401 char *zCode; 1402 int i; 1403 if( objc!=1 ){ 1404 Tcl_WrongNumArgs(interp, 1, objv, "<error code>"); 1405 } 1406 1407 zCode = Tcl_GetString(objv[1]); 1408 for(i=0; i<200; i++){ 1409 if( 0==strcmp(errorName(i), zCode) ) break; 1410 } 1411 Tcl_SetResult(interp, (char *)sqlite3ErrStr(i), 0); 1412 return TCL_OK; 1413 } 1414 1415 static int sqlite3_crashparams( 1416 void * clientData, 1417 Tcl_Interp *interp, 1418 int objc, 1419 Tcl_Obj *CONST objv[] 1420 ){ 1421 #ifdef OS_TEST 1422 int delay; 1423 if( objc!=3 ) goto bad_args; 1424 if( Tcl_GetIntFromObj(interp, objv[1], &delay) ) return TCL_ERROR; 1425 sqlite3SetCrashParams(delay, Tcl_GetString(objv[2])); 1426 #endif 1427 return TCL_OK; 1428 1429 #ifdef OS_TEST 1430 bad_args: 1431 Tcl_AppendResult(interp, "wrong # args: should be \"", 1432 Tcl_GetStringFromObj(objv[0], 0), "<delay> <filename>", 0); 1433 return TCL_ERROR; 1434 #endif 1435 } 1436 1437 1438 /* 1439 ** Usage: breakpoint 1440 ** 1441 ** This routine exists for one purpose - to provide a place to put a 1442 ** breakpoint with GDB that can be triggered using TCL code. The use 1443 ** for this is when a particular test fails on (say) the 1485th iteration. 1444 ** In the TCL test script, we can add code like this: 1445 ** 1446 ** if {$i==1485} breakpoint 1447 ** 1448 ** Then run testfixture in the debugger and wait for the breakpoint to 1449 ** fire. Then additional breakpoints can be set to trace down the bug. 1450 */ 1451 static int test_breakpoint( 1452 void *NotUsed, 1453 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 1454 int argc, /* Number of arguments */ 1455 char **argv /* Text of each argument */ 1456 ){ 1457 return TCL_OK; /* Do nothing */ 1458 } 1459 1460 /* 1461 ** Usage: sqlite3_bind_int STMT N VALUE 1462 ** 1463 ** Test the sqlite3_bind_int interface. STMT is a prepared statement. 1464 ** N is the index of a wildcard in the prepared statement. This command 1465 ** binds a 32-bit integer VALUE to that wildcard. 1466 */ 1467 static int test_bind_int( 1468 void * clientData, 1469 Tcl_Interp *interp, 1470 int objc, 1471 Tcl_Obj *CONST objv[] 1472 ){ 1473 sqlite3_stmt *pStmt; 1474 int idx; 1475 int value; 1476 int rc; 1477 1478 if( objc!=4 ){ 1479 Tcl_AppendResult(interp, "wrong # args: should be \"", 1480 Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 1481 return TCL_ERROR; 1482 } 1483 1484 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1485 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1486 if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR; 1487 1488 rc = sqlite3_bind_int(pStmt, idx, value); 1489 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 1490 if( rc!=SQLITE_OK ){ 1491 return TCL_ERROR; 1492 } 1493 1494 return TCL_OK; 1495 } 1496 1497 1498 /* 1499 ** Usage: sqlite3_bind_int64 STMT N VALUE 1500 ** 1501 ** Test the sqlite3_bind_int64 interface. STMT is a prepared statement. 1502 ** N is the index of a wildcard in the prepared statement. This command 1503 ** binds a 64-bit integer VALUE to that wildcard. 1504 */ 1505 static int test_bind_int64( 1506 void * clientData, 1507 Tcl_Interp *interp, 1508 int objc, 1509 Tcl_Obj *CONST objv[] 1510 ){ 1511 sqlite3_stmt *pStmt; 1512 int idx; 1513 i64 value; 1514 int rc; 1515 1516 if( objc!=4 ){ 1517 Tcl_AppendResult(interp, "wrong # args: should be \"", 1518 Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 1519 return TCL_ERROR; 1520 } 1521 1522 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1523 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1524 if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR; 1525 1526 rc = sqlite3_bind_int64(pStmt, idx, value); 1527 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 1528 if( rc!=SQLITE_OK ){ 1529 return TCL_ERROR; 1530 } 1531 1532 return TCL_OK; 1533 } 1534 1535 1536 /* 1537 ** Usage: sqlite3_bind_double STMT N VALUE 1538 ** 1539 ** Test the sqlite3_bind_double interface. STMT is a prepared statement. 1540 ** N is the index of a wildcard in the prepared statement. This command 1541 ** binds a 64-bit integer VALUE to that wildcard. 1542 */ 1543 static int test_bind_double( 1544 void * clientData, 1545 Tcl_Interp *interp, 1546 int objc, 1547 Tcl_Obj *CONST objv[] 1548 ){ 1549 sqlite3_stmt *pStmt; 1550 int idx; 1551 double value; 1552 int rc; 1553 1554 if( objc!=4 ){ 1555 Tcl_AppendResult(interp, "wrong # args: should be \"", 1556 Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE", 0); 1557 return TCL_ERROR; 1558 } 1559 1560 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1561 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1562 if( Tcl_GetDoubleFromObj(interp, objv[3], &value) ) return TCL_ERROR; 1563 1564 rc = sqlite3_bind_double(pStmt, idx, value); 1565 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 1566 if( rc!=SQLITE_OK ){ 1567 return TCL_ERROR; 1568 } 1569 1570 return TCL_OK; 1571 } 1572 1573 /* 1574 ** Usage: sqlite3_bind_null STMT N 1575 ** 1576 ** Test the sqlite3_bind_null interface. STMT is a prepared statement. 1577 ** N is the index of a wildcard in the prepared statement. This command 1578 ** binds a NULL to the wildcard. 1579 */ 1580 static int test_bind_null( 1581 void * clientData, 1582 Tcl_Interp *interp, 1583 int objc, 1584 Tcl_Obj *CONST objv[] 1585 ){ 1586 sqlite3_stmt *pStmt; 1587 int idx; 1588 int rc; 1589 1590 if( objc!=3 ){ 1591 Tcl_AppendResult(interp, "wrong # args: should be \"", 1592 Tcl_GetStringFromObj(objv[0], 0), " STMT N", 0); 1593 return TCL_ERROR; 1594 } 1595 1596 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1597 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1598 1599 rc = sqlite3_bind_null(pStmt, idx); 1600 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 1601 if( rc!=SQLITE_OK ){ 1602 return TCL_ERROR; 1603 } 1604 1605 return TCL_OK; 1606 } 1607 1608 /* 1609 ** Usage: sqlite3_bind_text STMT N STRING BYTES 1610 ** 1611 ** Test the sqlite3_bind_text interface. STMT is a prepared statement. 1612 ** N is the index of a wildcard in the prepared statement. This command 1613 ** binds a UTF-8 string STRING to the wildcard. The string is BYTES bytes 1614 ** long. 1615 */ 1616 static int test_bind_text( 1617 void * clientData, 1618 Tcl_Interp *interp, 1619 int objc, 1620 Tcl_Obj *CONST objv[] 1621 ){ 1622 sqlite3_stmt *pStmt; 1623 int idx; 1624 int bytes; 1625 char *value; 1626 int rc; 1627 1628 if( objc!=5 ){ 1629 Tcl_AppendResult(interp, "wrong # args: should be \"", 1630 Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0); 1631 return TCL_ERROR; 1632 } 1633 1634 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1635 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1636 value = Tcl_GetString(objv[3]); 1637 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 1638 1639 rc = sqlite3_bind_text(pStmt, idx, value, bytes, SQLITE_TRANSIENT); 1640 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 1641 if( rc!=SQLITE_OK ){ 1642 Tcl_AppendResult(interp, sqlite3TestErrorName(rc), 0); 1643 return TCL_ERROR; 1644 } 1645 1646 return TCL_OK; 1647 } 1648 1649 /* 1650 ** Usage: sqlite3_bind_text16 STMT N STRING BYTES 1651 ** 1652 ** Test the sqlite3_bind_text16 interface. STMT is a prepared statement. 1653 ** N is the index of a wildcard in the prepared statement. This command 1654 ** binds a UTF-16 string STRING to the wildcard. The string is BYTES bytes 1655 ** long. 1656 */ 1657 static int test_bind_text16( 1658 void * clientData, 1659 Tcl_Interp *interp, 1660 int objc, 1661 Tcl_Obj *CONST objv[] 1662 ){ 1663 #ifndef SQLITE_OMIT_UTF16 1664 sqlite3_stmt *pStmt; 1665 int idx; 1666 int bytes; 1667 char *value; 1668 int rc; 1669 1670 if( objc!=5 ){ 1671 Tcl_AppendResult(interp, "wrong # args: should be \"", 1672 Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0); 1673 return TCL_ERROR; 1674 } 1675 1676 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1677 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1678 value = Tcl_GetByteArrayFromObj(objv[3], 0); 1679 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 1680 1681 rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, SQLITE_TRANSIENT); 1682 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 1683 if( rc!=SQLITE_OK ){ 1684 return TCL_ERROR; 1685 } 1686 1687 #endif /* SQLITE_OMIT_UTF16 */ 1688 return TCL_OK; 1689 } 1690 1691 /* 1692 ** Usage: sqlite3_bind_blob STMT N DATA BYTES 1693 ** 1694 ** Test the sqlite3_bind_blob interface. STMT is a prepared statement. 1695 ** N is the index of a wildcard in the prepared statement. This command 1696 ** binds a BLOB to the wildcard. The BLOB is BYTES bytes in size. 1697 */ 1698 static int test_bind_blob( 1699 void * clientData, 1700 Tcl_Interp *interp, 1701 int objc, 1702 Tcl_Obj *CONST objv[] 1703 ){ 1704 sqlite3_stmt *pStmt; 1705 int idx; 1706 int bytes; 1707 char *value; 1708 int rc; 1709 1710 if( objc!=5 ){ 1711 Tcl_AppendResult(interp, "wrong # args: should be \"", 1712 Tcl_GetStringFromObj(objv[0], 0), " STMT N DATA BYTES", 0); 1713 return TCL_ERROR; 1714 } 1715 1716 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1717 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1718 value = Tcl_GetString(objv[3]); 1719 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 1720 1721 rc = sqlite3_bind_blob(pStmt, idx, value, bytes, SQLITE_TRANSIENT); 1722 if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) ) return TCL_ERROR; 1723 if( rc!=SQLITE_OK ){ 1724 return TCL_ERROR; 1725 } 1726 1727 return TCL_OK; 1728 } 1729 1730 /* 1731 ** Usage: sqlite3_bind_parameter_count STMT 1732 ** 1733 ** Return the number of wildcards in the given statement. 1734 */ 1735 static int test_bind_parameter_count( 1736 void * clientData, 1737 Tcl_Interp *interp, 1738 int objc, 1739 Tcl_Obj *CONST objv[] 1740 ){ 1741 sqlite3_stmt *pStmt; 1742 1743 if( objc!=2 ){ 1744 Tcl_WrongNumArgs(interp, 1, objv, "STMT"); 1745 return TCL_ERROR; 1746 } 1747 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1748 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_bind_parameter_count(pStmt))); 1749 return TCL_OK; 1750 } 1751 1752 /* 1753 ** Usage: sqlite3_bind_parameter_name STMT N 1754 ** 1755 ** Return the name of the Nth wildcard. The first wildcard is 1. 1756 ** An empty string is returned if N is out of range or if the wildcard 1757 ** is nameless. 1758 */ 1759 static int test_bind_parameter_name( 1760 void * clientData, 1761 Tcl_Interp *interp, 1762 int objc, 1763 Tcl_Obj *CONST objv[] 1764 ){ 1765 sqlite3_stmt *pStmt; 1766 int i; 1767 1768 if( objc!=3 ){ 1769 Tcl_WrongNumArgs(interp, 1, objv, "STMT N"); 1770 return TCL_ERROR; 1771 } 1772 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1773 if( Tcl_GetIntFromObj(interp, objv[2], &i) ) return TCL_ERROR; 1774 Tcl_SetObjResult(interp, 1775 Tcl_NewStringObj(sqlite3_bind_parameter_name(pStmt,i),-1) 1776 ); 1777 return TCL_OK; 1778 } 1779 1780 /* 1781 ** Usage: sqlite3_bind_parameter_index STMT NAME 1782 ** 1783 ** Return the index of the wildcard called NAME. Return 0 if there is 1784 ** no such wildcard. 1785 */ 1786 static int test_bind_parameter_index( 1787 void * clientData, 1788 Tcl_Interp *interp, 1789 int objc, 1790 Tcl_Obj *CONST objv[] 1791 ){ 1792 sqlite3_stmt *pStmt; 1793 1794 if( objc!=3 ){ 1795 Tcl_WrongNumArgs(interp, 1, objv, "STMT NAME"); 1796 return TCL_ERROR; 1797 } 1798 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1799 Tcl_SetObjResult(interp, 1800 Tcl_NewIntObj( 1801 sqlite3_bind_parameter_index(pStmt,Tcl_GetString(objv[2])) 1802 ) 1803 ); 1804 return TCL_OK; 1805 } 1806 1807 /* 1808 ** Usage: sqlite3_clear_bindings STMT 1809 ** 1810 */ 1811 #if 0 1812 static int test_clear_bindings( 1813 void * clientData, 1814 Tcl_Interp *interp, 1815 int objc, 1816 Tcl_Obj *CONST objv[] 1817 ){ 1818 sqlite3_stmt *pStmt; 1819 1820 if( objc!=2 ){ 1821 Tcl_WrongNumArgs(interp, 1, objv, "STMT"); 1822 return TCL_ERROR; 1823 } 1824 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1825 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(pStmt))); 1826 return TCL_OK; 1827 } 1828 #endif 1829 1830 /* 1831 ** Usage: sqlite3_errcode DB 1832 ** 1833 ** Return the string representation of the most recent sqlite3_* API 1834 ** error code. e.g. "SQLITE_ERROR". 1835 */ 1836 static int test_errcode( 1837 void * clientData, 1838 Tcl_Interp *interp, 1839 int objc, 1840 Tcl_Obj *CONST objv[] 1841 ){ 1842 sqlite3 *db; 1843 1844 if( objc!=2 ){ 1845 Tcl_AppendResult(interp, "wrong # args: should be \"", 1846 Tcl_GetString(objv[0]), " DB", 0); 1847 return TCL_ERROR; 1848 } 1849 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1850 Tcl_SetResult(interp, (char *)errorName(sqlite3_errcode(db)), 0); 1851 return TCL_OK; 1852 } 1853 1854 /* 1855 ** Usage: test_errmsg DB 1856 ** 1857 ** Returns the UTF-8 representation of the error message string for the 1858 ** most recent sqlite3_* API call. 1859 */ 1860 static int test_errmsg( 1861 void * clientData, 1862 Tcl_Interp *interp, 1863 int objc, 1864 Tcl_Obj *CONST objv[] 1865 ){ 1866 sqlite3 *db; 1867 const char *zErr; 1868 1869 if( objc!=2 ){ 1870 Tcl_AppendResult(interp, "wrong # args: should be \"", 1871 Tcl_GetString(objv[0]), " DB", 0); 1872 return TCL_ERROR; 1873 } 1874 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1875 1876 zErr = sqlite3_errmsg(db); 1877 Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1)); 1878 return TCL_OK; 1879 } 1880 1881 /* 1882 ** Usage: test_errmsg16 DB 1883 ** 1884 ** Returns the UTF-16 representation of the error message string for the 1885 ** most recent sqlite3_* API call. This is a byte array object at the TCL 1886 ** level, and it includes the 0x00 0x00 terminator bytes at the end of the 1887 ** UTF-16 string. 1888 */ 1889 static int test_errmsg16( 1890 void * clientData, 1891 Tcl_Interp *interp, 1892 int objc, 1893 Tcl_Obj *CONST objv[] 1894 ){ 1895 #ifndef SQLITE_OMIT_UTF16 1896 sqlite3 *db; 1897 const void *zErr; 1898 int bytes; 1899 1900 if( objc!=2 ){ 1901 Tcl_AppendResult(interp, "wrong # args: should be \"", 1902 Tcl_GetString(objv[0]), " DB", 0); 1903 return TCL_ERROR; 1904 } 1905 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1906 1907 zErr = sqlite3_errmsg16(db); 1908 bytes = sqlite3utf16ByteLen(zErr, -1); 1909 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes)); 1910 #endif /* SQLITE_OMIT_UTF16 */ 1911 return TCL_OK; 1912 } 1913 1914 /* 1915 ** Usage: sqlite3_prepare DB sql bytes tailvar 1916 ** 1917 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using 1918 ** database handle <DB>. The parameter <tailval> is the name of a global 1919 ** variable that is set to the unused portion of <sql> (if any). A 1920 ** STMT handle is returned. 1921 */ 1922 static int test_prepare( 1923 void * clientData, 1924 Tcl_Interp *interp, 1925 int objc, 1926 Tcl_Obj *CONST objv[] 1927 ){ 1928 sqlite3 *db; 1929 const char *zSql; 1930 int bytes; 1931 const char *zTail = 0; 1932 sqlite3_stmt *pStmt = 0; 1933 char zBuf[50]; 1934 int rc; 1935 1936 if( objc!=5 ){ 1937 Tcl_AppendResult(interp, "wrong # args: should be \"", 1938 Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); 1939 return TCL_ERROR; 1940 } 1941 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1942 zSql = Tcl_GetString(objv[2]); 1943 if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; 1944 1945 rc = sqlite3_prepare(db, zSql, bytes, &pStmt, &zTail); 1946 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 1947 if( zTail ){ 1948 if( bytes>=0 ){ 1949 bytes = bytes - (zTail-zSql); 1950 } 1951 Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0); 1952 } 1953 if( rc!=SQLITE_OK ){ 1954 assert( pStmt==0 ); 1955 sprintf(zBuf, "(%d) ", rc); 1956 Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0); 1957 return TCL_ERROR; 1958 } 1959 1960 if( pStmt ){ 1961 if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; 1962 Tcl_AppendResult(interp, zBuf, 0); 1963 } 1964 return TCL_OK; 1965 } 1966 1967 /* 1968 ** Usage: sqlite3_prepare DB sql bytes tailvar 1969 ** 1970 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using 1971 ** database handle <DB>. The parameter <tailval> is the name of a global 1972 ** variable that is set to the unused portion of <sql> (if any). A 1973 ** STMT handle is returned. 1974 */ 1975 static int test_prepare16( 1976 void * clientData, 1977 Tcl_Interp *interp, 1978 int objc, 1979 Tcl_Obj *CONST objv[] 1980 ){ 1981 #ifndef SQLITE_OMIT_UTF16 1982 sqlite3 *db; 1983 const void *zSql; 1984 const void *zTail = 0; 1985 Tcl_Obj *pTail = 0; 1986 sqlite3_stmt *pStmt = 0; 1987 char zBuf[50]; 1988 int rc; 1989 int bytes; /* The integer specified as arg 3 */ 1990 int objlen; /* The byte-array length of arg 2 */ 1991 1992 if( objc!=5 ){ 1993 Tcl_AppendResult(interp, "wrong # args: should be \"", 1994 Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); 1995 return TCL_ERROR; 1996 } 1997 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1998 zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen); 1999 if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; 2000 2001 rc = sqlite3_prepare16(db, zSql, bytes, &pStmt, &zTail); 2002 if( sqlite3TestErrCode(interp, db, rc) ) return TCL_ERROR; 2003 if( rc ){ 2004 return TCL_ERROR; 2005 } 2006 2007 if( zTail ){ 2008 objlen = objlen - ((u8 *)zTail-(u8 *)zSql); 2009 }else{ 2010 objlen = 0; 2011 } 2012 pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen); 2013 Tcl_IncrRefCount(pTail); 2014 Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0); 2015 Tcl_DecrRefCount(pTail); 2016 2017 if( pStmt ){ 2018 if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; 2019 } 2020 Tcl_AppendResult(interp, zBuf, 0); 2021 #endif /* SQLITE_OMIT_UTF16 */ 2022 return TCL_OK; 2023 } 2024 2025 /* 2026 ** Usage: sqlite3_open filename ?options-list? 2027 */ 2028 static int test_open( 2029 void * clientData, 2030 Tcl_Interp *interp, 2031 int objc, 2032 Tcl_Obj *CONST objv[] 2033 ){ 2034 const char *zFilename; 2035 sqlite3 *db; 2036 int rc; 2037 char zBuf[100]; 2038 2039 if( objc!=3 && objc!=2 ){ 2040 Tcl_AppendResult(interp, "wrong # args: should be \"", 2041 Tcl_GetString(objv[0]), " filename options-list", 0); 2042 return TCL_ERROR; 2043 } 2044 2045 zFilename = Tcl_GetString(objv[1]); 2046 rc = sqlite3_open(zFilename, &db); 2047 2048 if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR; 2049 Tcl_AppendResult(interp, zBuf, 0); 2050 return TCL_OK; 2051 } 2052 2053 /* 2054 ** Usage: sqlite3_open16 filename options 2055 */ 2056 static int test_open16( 2057 void * clientData, 2058 Tcl_Interp *interp, 2059 int objc, 2060 Tcl_Obj *CONST objv[] 2061 ){ 2062 #ifndef SQLITE_OMIT_UTF16 2063 const void *zFilename; 2064 sqlite3 *db; 2065 int rc; 2066 char zBuf[100]; 2067 2068 if( objc!=3 ){ 2069 Tcl_AppendResult(interp, "wrong # args: should be \"", 2070 Tcl_GetString(objv[0]), " filename options-list", 0); 2071 return TCL_ERROR; 2072 } 2073 2074 zFilename = Tcl_GetByteArrayFromObj(objv[1], 0); 2075 rc = sqlite3_open16(zFilename, &db); 2076 2077 if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR; 2078 Tcl_AppendResult(interp, zBuf, 0); 2079 #endif /* SQLITE_OMIT_UTF16 */ 2080 return TCL_OK; 2081 } 2082 2083 /* 2084 ** Usage: sqlite3_complete16 <UTF-16 string> 2085 ** 2086 ** Return 1 if the supplied argument is a complete SQL statement, or zero 2087 ** otherwise. 2088 */ 2089 static int test_complete16( 2090 void * clientData, 2091 Tcl_Interp *interp, 2092 int objc, 2093 Tcl_Obj *CONST objv[] 2094 ){ 2095 #if !defined(SQLITE_OMIT_COMPLETE) && !defined(SQLITE_OMIT_UTF16) 2096 char *zBuf; 2097 2098 if( objc!=2 ){ 2099 Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>"); 2100 return TCL_ERROR; 2101 } 2102 2103 zBuf = Tcl_GetByteArrayFromObj(objv[1], 0); 2104 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_complete16(zBuf))); 2105 #endif /* SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */ 2106 return TCL_OK; 2107 } 2108 2109 /* 2110 ** Usage: sqlite3_step STMT 2111 ** 2112 ** Advance the statement to the next row. 2113 */ 2114 static int test_step( 2115 void * clientData, 2116 Tcl_Interp *interp, 2117 int objc, 2118 Tcl_Obj *CONST objv[] 2119 ){ 2120 sqlite3_stmt *pStmt; 2121 int rc; 2122 2123 if( objc!=2 ){ 2124 Tcl_AppendResult(interp, "wrong # args: should be \"", 2125 Tcl_GetString(objv[0]), " STMT", 0); 2126 return TCL_ERROR; 2127 } 2128 2129 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2130 rc = sqlite3_step(pStmt); 2131 2132 /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; */ 2133 Tcl_SetResult(interp, (char *)errorName(rc), 0); 2134 return TCL_OK; 2135 } 2136 2137 /* 2138 ** Usage: sqlite3_column_count STMT 2139 ** 2140 ** Return the number of columns returned by the sql statement STMT. 2141 */ 2142 static int test_column_count( 2143 void * clientData, 2144 Tcl_Interp *interp, 2145 int objc, 2146 Tcl_Obj *CONST objv[] 2147 ){ 2148 sqlite3_stmt *pStmt; 2149 2150 if( objc!=2 ){ 2151 Tcl_AppendResult(interp, "wrong # args: should be \"", 2152 Tcl_GetString(objv[0]), " STMT column", 0); 2153 return TCL_ERROR; 2154 } 2155 2156 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2157 2158 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_column_count(pStmt))); 2159 return TCL_OK; 2160 } 2161 2162 /* 2163 ** Usage: sqlite3_column_type STMT column 2164 ** 2165 ** Return the type of the data in column 'column' of the current row. 2166 */ 2167 static int test_column_type( 2168 void * clientData, 2169 Tcl_Interp *interp, 2170 int objc, 2171 Tcl_Obj *CONST objv[] 2172 ){ 2173 sqlite3_stmt *pStmt; 2174 int col; 2175 int tp; 2176 2177 if( objc!=3 ){ 2178 Tcl_AppendResult(interp, "wrong # args: should be \"", 2179 Tcl_GetString(objv[0]), " STMT column", 0); 2180 return TCL_ERROR; 2181 } 2182 2183 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2184 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2185 2186 tp = sqlite3_column_type(pStmt, col); 2187 switch( tp ){ 2188 case SQLITE_INTEGER: 2189 Tcl_SetResult(interp, "INTEGER", TCL_STATIC); 2190 break; 2191 case SQLITE_NULL: 2192 Tcl_SetResult(interp, "NULL", TCL_STATIC); 2193 break; 2194 case SQLITE_FLOAT: 2195 Tcl_SetResult(interp, "FLOAT", TCL_STATIC); 2196 break; 2197 case SQLITE_TEXT: 2198 Tcl_SetResult(interp, "TEXT", TCL_STATIC); 2199 break; 2200 case SQLITE_BLOB: 2201 Tcl_SetResult(interp, "BLOB", TCL_STATIC); 2202 break; 2203 default: 2204 assert(0); 2205 } 2206 2207 return TCL_OK; 2208 } 2209 2210 /* 2211 ** Usage: sqlite3_column_int64 STMT column 2212 ** 2213 ** Return the data in column 'column' of the current row cast as an 2214 ** wide (64-bit) integer. 2215 */ 2216 static int test_column_int64( 2217 void * clientData, 2218 Tcl_Interp *interp, 2219 int objc, 2220 Tcl_Obj *CONST objv[] 2221 ){ 2222 sqlite3_stmt *pStmt; 2223 int col; 2224 i64 iVal; 2225 2226 if( objc!=3 ){ 2227 Tcl_AppendResult(interp, "wrong # args: should be \"", 2228 Tcl_GetString(objv[0]), " STMT column", 0); 2229 return TCL_ERROR; 2230 } 2231 2232 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2233 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2234 2235 iVal = sqlite3_column_int64(pStmt, col); 2236 Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iVal)); 2237 return TCL_OK; 2238 } 2239 2240 /* 2241 ** Usage: sqlite3_column_blob STMT column 2242 */ 2243 static int test_column_blob( 2244 void * clientData, 2245 Tcl_Interp *interp, 2246 int objc, 2247 Tcl_Obj *CONST objv[] 2248 ){ 2249 sqlite3_stmt *pStmt; 2250 int col; 2251 2252 int len; 2253 const void *pBlob; 2254 2255 if( objc!=3 ){ 2256 Tcl_AppendResult(interp, "wrong # args: should be \"", 2257 Tcl_GetString(objv[0]), " STMT column", 0); 2258 return TCL_ERROR; 2259 } 2260 2261 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2262 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2263 2264 pBlob = sqlite3_column_blob(pStmt, col); 2265 len = sqlite3_column_bytes(pStmt, col); 2266 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len)); 2267 return TCL_OK; 2268 } 2269 2270 /* 2271 ** Usage: sqlite3_column_double STMT column 2272 ** 2273 ** Return the data in column 'column' of the current row cast as a double. 2274 */ 2275 static int test_column_double( 2276 void * clientData, 2277 Tcl_Interp *interp, 2278 int objc, 2279 Tcl_Obj *CONST objv[] 2280 ){ 2281 sqlite3_stmt *pStmt; 2282 int col; 2283 double rVal; 2284 2285 if( objc!=3 ){ 2286 Tcl_AppendResult(interp, "wrong # args: should be \"", 2287 Tcl_GetString(objv[0]), " STMT column", 0); 2288 return TCL_ERROR; 2289 } 2290 2291 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2292 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2293 2294 rVal = sqlite3_column_double(pStmt, col); 2295 Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rVal)); 2296 return TCL_OK; 2297 } 2298 2299 /* 2300 ** Usage: sqlite3_data_count STMT 2301 ** 2302 ** Return the number of columns returned by the sql statement STMT. 2303 */ 2304 static int test_data_count( 2305 void * clientData, 2306 Tcl_Interp *interp, 2307 int objc, 2308 Tcl_Obj *CONST objv[] 2309 ){ 2310 sqlite3_stmt *pStmt; 2311 2312 if( objc!=2 ){ 2313 Tcl_AppendResult(interp, "wrong # args: should be \"", 2314 Tcl_GetString(objv[0]), " STMT column", 0); 2315 return TCL_ERROR; 2316 } 2317 2318 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2319 2320 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_data_count(pStmt))); 2321 return TCL_OK; 2322 } 2323 2324 /* 2325 ** Usage: sqlite3_column_text STMT column 2326 ** 2327 ** Usage: sqlite3_column_decltype STMT column 2328 ** 2329 ** Usage: sqlite3_column_name STMT column 2330 */ 2331 static int test_stmt_utf8( 2332 void * clientData, /* Pointer to SQLite API function to be invoke */ 2333 Tcl_Interp *interp, 2334 int objc, 2335 Tcl_Obj *CONST objv[] 2336 ){ 2337 sqlite3_stmt *pStmt; 2338 int col; 2339 const char *(*xFunc)(sqlite3_stmt*, int) = clientData; 2340 const char *zRet; 2341 2342 if( objc!=3 ){ 2343 Tcl_AppendResult(interp, "wrong # args: should be \"", 2344 Tcl_GetString(objv[0]), " STMT column", 0); 2345 return TCL_ERROR; 2346 } 2347 2348 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2349 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2350 zRet = xFunc(pStmt, col); 2351 if( zRet ){ 2352 Tcl_SetResult(interp, (char *)zRet, 0); 2353 } 2354 return TCL_OK; 2355 } 2356 2357 static int test_global_recover( 2358 void * clientData, 2359 Tcl_Interp *interp, 2360 int objc, 2361 Tcl_Obj *CONST objv[] 2362 ){ 2363 #ifndef SQLITE_OMIT_GLOBALRECOVER 2364 int rc; 2365 if( objc!=1 ){ 2366 Tcl_WrongNumArgs(interp, 1, objv, ""); 2367 return TCL_ERROR; 2368 } 2369 rc = sqlite3_global_recover(); 2370 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 2371 #endif 2372 return TCL_OK; 2373 } 2374 2375 /* 2376 ** Usage: sqlite3_column_text STMT column 2377 ** 2378 ** Usage: sqlite3_column_decltype STMT column 2379 ** 2380 ** Usage: sqlite3_column_name STMT column 2381 */ 2382 static int test_stmt_utf16( 2383 void * clientData, /* Pointer to SQLite API function to be invoked */ 2384 Tcl_Interp *interp, 2385 int objc, 2386 Tcl_Obj *CONST objv[] 2387 ){ 2388 #ifndef SQLITE_OMIT_UTF16 2389 sqlite3_stmt *pStmt; 2390 int col; 2391 Tcl_Obj *pRet; 2392 const void *zName16; 2393 const void *(*xFunc)(sqlite3_stmt*, int) = clientData; 2394 2395 if( objc!=3 ){ 2396 Tcl_AppendResult(interp, "wrong # args: should be \"", 2397 Tcl_GetString(objv[0]), " STMT column", 0); 2398 return TCL_ERROR; 2399 } 2400 2401 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2402 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2403 2404 zName16 = xFunc(pStmt, col); 2405 if( zName16 ){ 2406 pRet = Tcl_NewByteArrayObj(zName16, sqlite3utf16ByteLen(zName16, -1)+2); 2407 Tcl_SetObjResult(interp, pRet); 2408 } 2409 #endif /* SQLITE_OMIT_UTF16 */ 2410 2411 return TCL_OK; 2412 } 2413 2414 /* 2415 ** Usage: sqlite3_column_int STMT column 2416 ** 2417 ** Usage: sqlite3_column_bytes STMT column 2418 ** 2419 ** Usage: sqlite3_column_bytes16 STMT column 2420 ** 2421 */ 2422 static int test_stmt_int( 2423 void * clientData, /* Pointer to SQLite API function to be invoked */ 2424 Tcl_Interp *interp, 2425 int objc, 2426 Tcl_Obj *CONST objv[] 2427 ){ 2428 sqlite3_stmt *pStmt; 2429 int col; 2430 int (*xFunc)(sqlite3_stmt*, int) = clientData; 2431 2432 if( objc!=3 ){ 2433 Tcl_AppendResult(interp, "wrong # args: should be \"", 2434 Tcl_GetString(objv[0]), " STMT column", 0); 2435 return TCL_ERROR; 2436 } 2437 2438 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 2439 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 2440 2441 Tcl_SetObjResult(interp, Tcl_NewIntObj(xFunc(pStmt, col))); 2442 return TCL_OK; 2443 } 2444 2445 #ifndef SQLITE_OMIT_DISKIO 2446 /* 2447 ** Usage: sqlite3OsOpenReadWrite <filename> 2448 */ 2449 static int test_sqlite3OsOpenReadWrite( 2450 void * clientData, 2451 Tcl_Interp *interp, 2452 int objc, 2453 Tcl_Obj *CONST objv[] 2454 ){ 2455 OsFile * pFile; 2456 int rc; 2457 int dummy; 2458 char zBuf[100]; 2459 2460 if( objc!=2 ){ 2461 Tcl_AppendResult(interp, "wrong # args: should be \"", 2462 Tcl_GetString(objv[0]), " filename", 0); 2463 return TCL_ERROR; 2464 } 2465 2466 pFile = sqliteMalloc(sizeof(OsFile)); 2467 rc = sqlite3OsOpenReadWrite(Tcl_GetString(objv[1]), pFile, &dummy); 2468 if( rc!=SQLITE_OK ){ 2469 sqliteFree(pFile); 2470 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 2471 return TCL_ERROR; 2472 } 2473 makePointerStr(interp, zBuf, pFile); 2474 Tcl_SetResult(interp, zBuf, 0); 2475 return TCL_ERROR; 2476 } 2477 2478 /* 2479 ** Usage: sqlite3OsClose <file handle> 2480 */ 2481 static int test_sqlite3OsClose( 2482 void * clientData, 2483 Tcl_Interp *interp, 2484 int objc, 2485 Tcl_Obj *CONST objv[] 2486 ){ 2487 OsFile * pFile; 2488 int rc; 2489 2490 if( objc!=2 ){ 2491 Tcl_AppendResult(interp, "wrong # args: should be \"", 2492 Tcl_GetString(objv[0]), " filehandle", 0); 2493 return TCL_ERROR; 2494 } 2495 2496 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 2497 return TCL_ERROR; 2498 } 2499 rc = sqlite3OsClose(pFile); 2500 if( rc!=SQLITE_OK ){ 2501 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 2502 return TCL_ERROR; 2503 } 2504 sqliteFree(pFile); 2505 return TCL_OK; 2506 } 2507 2508 /* 2509 ** Usage: sqlite3OsLock <file handle> <locktype> 2510 */ 2511 static int test_sqlite3OsLock( 2512 void * clientData, 2513 Tcl_Interp *interp, 2514 int objc, 2515 Tcl_Obj *CONST objv[] 2516 ){ 2517 OsFile * pFile; 2518 int rc; 2519 2520 if( objc!=3 ){ 2521 Tcl_AppendResult(interp, "wrong # args: should be \"", 2522 Tcl_GetString(objv[0]), 2523 " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0); 2524 return TCL_ERROR; 2525 } 2526 2527 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 2528 return TCL_ERROR; 2529 } 2530 2531 if( 0==strcmp("SHARED", Tcl_GetString(objv[2])) ){ 2532 rc = sqlite3OsLock(pFile, SHARED_LOCK); 2533 } 2534 else if( 0==strcmp("RESERVED", Tcl_GetString(objv[2])) ){ 2535 rc = sqlite3OsLock(pFile, RESERVED_LOCK); 2536 } 2537 else if( 0==strcmp("PENDING", Tcl_GetString(objv[2])) ){ 2538 rc = sqlite3OsLock(pFile, PENDING_LOCK); 2539 } 2540 else if( 0==strcmp("EXCLUSIVE", Tcl_GetString(objv[2])) ){ 2541 rc = sqlite3OsLock(pFile, EXCLUSIVE_LOCK); 2542 }else{ 2543 Tcl_AppendResult(interp, "wrong # args: should be \"", 2544 Tcl_GetString(objv[0]), 2545 " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0); 2546 return TCL_ERROR; 2547 } 2548 2549 if( rc!=SQLITE_OK ){ 2550 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 2551 return TCL_ERROR; 2552 } 2553 return TCL_OK; 2554 } 2555 2556 /* 2557 ** Usage: sqlite3OsUnlock <file handle> 2558 */ 2559 static int test_sqlite3OsUnlock( 2560 void * clientData, 2561 Tcl_Interp *interp, 2562 int objc, 2563 Tcl_Obj *CONST objv[] 2564 ){ 2565 OsFile * pFile; 2566 int rc; 2567 2568 if( objc!=2 ){ 2569 Tcl_AppendResult(interp, "wrong # args: should be \"", 2570 Tcl_GetString(objv[0]), " filehandle", 0); 2571 return TCL_ERROR; 2572 } 2573 2574 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 2575 return TCL_ERROR; 2576 } 2577 rc = sqlite3OsUnlock(pFile, NO_LOCK); 2578 if( rc!=SQLITE_OK ){ 2579 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 2580 return TCL_ERROR; 2581 } 2582 return TCL_OK; 2583 } 2584 2585 /* 2586 ** Usage: sqlite3OsTempFileName 2587 */ 2588 static int test_sqlite3OsTempFileName( 2589 void * clientData, 2590 Tcl_Interp *interp, 2591 int objc, 2592 Tcl_Obj *CONST objv[] 2593 ){ 2594 char zFile[SQLITE_TEMPNAME_SIZE]; 2595 int rc; 2596 2597 rc = sqlite3OsTempFileName(zFile); 2598 if( rc!=SQLITE_OK ){ 2599 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 2600 return TCL_ERROR; 2601 } 2602 Tcl_AppendResult(interp, zFile, 0); 2603 return TCL_OK; 2604 } 2605 #endif 2606 2607 /* 2608 ** Usage: sqlite_set_magic DB MAGIC-NUMBER 2609 ** 2610 ** Set the db->magic value. This is used to test error recovery logic. 2611 */ 2612 static int sqlite_set_magic( 2613 void * clientData, 2614 Tcl_Interp *interp, 2615 int argc, 2616 char **argv 2617 ){ 2618 sqlite3 *db; 2619 if( argc!=3 ){ 2620 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 2621 " DB MAGIC", 0); 2622 return TCL_ERROR; 2623 } 2624 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 2625 if( strcmp(argv[2], "SQLITE_MAGIC_OPEN")==0 ){ 2626 db->magic = SQLITE_MAGIC_OPEN; 2627 }else if( strcmp(argv[2], "SQLITE_MAGIC_CLOSED")==0 ){ 2628 db->magic = SQLITE_MAGIC_CLOSED; 2629 }else if( strcmp(argv[2], "SQLITE_MAGIC_BUSY")==0 ){ 2630 db->magic = SQLITE_MAGIC_BUSY; 2631 }else if( strcmp(argv[2], "SQLITE_MAGIC_ERROR")==0 ){ 2632 db->magic = SQLITE_MAGIC_ERROR; 2633 }else if( Tcl_GetInt(interp, argv[2], &db->magic) ){ 2634 return TCL_ERROR; 2635 } 2636 return TCL_OK; 2637 } 2638 2639 /* 2640 ** Usage: sqlite3_interrupt DB 2641 ** 2642 ** Trigger an interrupt on DB 2643 */ 2644 static int test_interrupt( 2645 void * clientData, 2646 Tcl_Interp *interp, 2647 int argc, 2648 char **argv 2649 ){ 2650 sqlite3 *db; 2651 if( argc!=2 ){ 2652 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB", 0); 2653 return TCL_ERROR; 2654 } 2655 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 2656 sqlite3_interrupt(db); 2657 return TCL_OK; 2658 } 2659 2660 static u8 *sqlite3_stack_baseline = 0; 2661 2662 /* 2663 ** Fill the stack with a known bitpattern. 2664 */ 2665 static void prepStack(void){ 2666 int i; 2667 u32 bigBuf[65536]; 2668 for(i=0; i<sizeof(bigBuf); i++) bigBuf[i] = 0xdeadbeef; 2669 sqlite3_stack_baseline = (u8*)&bigBuf[65536]; 2670 } 2671 2672 /* 2673 ** Get the current stack depth. Used for debugging only. 2674 */ 2675 u64 sqlite3StackDepth(void){ 2676 u8 x; 2677 return (u64)(sqlite3_stack_baseline - &x); 2678 } 2679 2680 /* 2681 ** Usage: sqlite3_stack_used DB SQL 2682 ** 2683 ** Try to measure the amount of stack space used by a call to sqlite3_exec 2684 */ 2685 static int test_stack_used( 2686 void * clientData, 2687 Tcl_Interp *interp, 2688 int argc, 2689 char **argv 2690 ){ 2691 sqlite3 *db; 2692 int i; 2693 if( argc!=3 ){ 2694 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 2695 " DB SQL", 0); 2696 return TCL_ERROR; 2697 } 2698 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 2699 prepStack(); 2700 sqlite3_exec(db, argv[2], 0, 0, 0); 2701 for(i=65535; i>=0 && ((u32*)sqlite3_stack_baseline)[-i]==0xdeadbeef; i--){} 2702 Tcl_SetObjResult(interp, Tcl_NewIntObj(i*4)); 2703 return TCL_OK; 2704 } 2705 2706 /* 2707 ** Usage: sqlite_delete_function DB function-name 2708 ** 2709 ** Delete the user function 'function-name' from database handle DB. It 2710 ** is assumed that the user function was created as UTF8, any number of 2711 ** arguments (the way the TCL interface does it). 2712 */ 2713 static int delete_function( 2714 void * clientData, 2715 Tcl_Interp *interp, 2716 int argc, 2717 char **argv 2718 ){ 2719 int rc; 2720 sqlite3 *db; 2721 if( argc!=3 ){ 2722 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 2723 " DB function-name", 0); 2724 return TCL_ERROR; 2725 } 2726 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 2727 rc = sqlite3_create_function(db, argv[2], -1, SQLITE_UTF8, 0, 0, 0, 0); 2728 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 2729 return TCL_OK; 2730 } 2731 2732 /* 2733 ** Usage: sqlite_delete_collation DB collation-name 2734 ** 2735 ** Delete the collation sequence 'collation-name' from database handle 2736 ** DB. It is assumed that the collation sequence was created as UTF8 (the 2737 ** way the TCL interface does it). 2738 */ 2739 static int delete_collation( 2740 void * clientData, 2741 Tcl_Interp *interp, 2742 int argc, 2743 char **argv 2744 ){ 2745 int rc; 2746 sqlite3 *db; 2747 if( argc!=3 ){ 2748 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 2749 " DB function-name", 0); 2750 return TCL_ERROR; 2751 } 2752 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 2753 rc = sqlite3_create_collation(db, argv[2], SQLITE_UTF8, 0, 0); 2754 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 2755 return TCL_OK; 2756 } 2757 2758 /* 2759 ** Usage: sqlite3_get_autocommit DB 2760 ** 2761 ** Return true if the database DB is currently in auto-commit mode. 2762 ** Return false if not. 2763 */ 2764 static int get_autocommit( 2765 void * clientData, 2766 Tcl_Interp *interp, 2767 int argc, 2768 char **argv 2769 ){ 2770 char zBuf[30]; 2771 sqlite3 *db; 2772 if( argc!=2 ){ 2773 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 2774 " DB", 0); 2775 return TCL_ERROR; 2776 } 2777 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 2778 sprintf(zBuf, "%d", sqlite3_get_autocommit(db)); 2779 Tcl_AppendResult(interp, zBuf, 0); 2780 return TCL_OK; 2781 } 2782 2783 /* 2784 ** Usage: tcl_variable_type VARIABLENAME 2785 ** 2786 ** Return the name of the internal representation for the 2787 ** value of the given variable. 2788 */ 2789 static int tcl_variable_type( 2790 void * clientData, 2791 Tcl_Interp *interp, 2792 int objc, 2793 Tcl_Obj *CONST objv[] 2794 ){ 2795 Tcl_Obj *pVar; 2796 if( objc!=2 ){ 2797 Tcl_WrongNumArgs(interp, 1, objv, "VARIABLE"); 2798 return TCL_ERROR; 2799 } 2800 pVar = Tcl_GetVar2Ex(interp, Tcl_GetString(objv[1]), 0, TCL_LEAVE_ERR_MSG); 2801 if( pVar==0 ) return TCL_ERROR; 2802 if( pVar->typePtr ){ 2803 Tcl_SetObjResult(interp, Tcl_NewStringObj(pVar->typePtr->name, -1)); 2804 } 2805 return TCL_OK; 2806 } 2807 2808 /* 2809 ** This routine sets entries in the global ::sqlite_options() array variable 2810 ** according to the compile-time configuration of the database. Test 2811 ** procedures use this to determine when tests should be omitted. 2812 */ 2813 static void set_options(Tcl_Interp *interp){ 2814 #ifdef SQLITE_32BIT_ROWID 2815 Tcl_SetVar2(interp, "sqlite_options", "rowid32", "1", TCL_GLOBAL_ONLY); 2816 #else 2817 Tcl_SetVar2(interp, "sqlite_options", "rowid32", "0", TCL_GLOBAL_ONLY); 2818 #endif 2819 2820 #ifdef SQLITE_CASE_SENSITIVE_LIKE 2821 Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","1",TCL_GLOBAL_ONLY); 2822 #else 2823 Tcl_SetVar2(interp, "sqlite_options","casesensitivelike","0",TCL_GLOBAL_ONLY); 2824 #endif 2825 2826 #ifdef SQLITE_OMIT_ALTERTABLE 2827 Tcl_SetVar2(interp, "sqlite_options", "altertable", "0", TCL_GLOBAL_ONLY); 2828 #else 2829 Tcl_SetVar2(interp, "sqlite_options", "altertable", "1", TCL_GLOBAL_ONLY); 2830 #endif 2831 2832 #ifdef SQLITE_OMIT_ANALYZE 2833 Tcl_SetVar2(interp, "sqlite_options", "analyze", "0", TCL_GLOBAL_ONLY); 2834 #else 2835 Tcl_SetVar2(interp, "sqlite_options", "analyze", "1", TCL_GLOBAL_ONLY); 2836 #endif 2837 2838 #ifdef SQLITE_OMIT_AUTHORIZATION 2839 Tcl_SetVar2(interp, "sqlite_options", "auth", "0", TCL_GLOBAL_ONLY); 2840 #else 2841 Tcl_SetVar2(interp, "sqlite_options", "auth", "1", TCL_GLOBAL_ONLY); 2842 #endif 2843 2844 #ifdef SQLITE_OMIT_AUTOINCREMENT 2845 Tcl_SetVar2(interp, "sqlite_options", "autoinc", "0", TCL_GLOBAL_ONLY); 2846 #else 2847 Tcl_SetVar2(interp, "sqlite_options", "autoinc", "1", TCL_GLOBAL_ONLY); 2848 #endif 2849 2850 #ifdef SQLITE_OMIT_AUTOVACUUM 2851 Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "0", TCL_GLOBAL_ONLY); 2852 #else 2853 Tcl_SetVar2(interp, "sqlite_options", "autovacuum", "1", TCL_GLOBAL_ONLY); 2854 #endif /* SQLITE_OMIT_AUTOVACUUM */ 2855 #if !defined(SQLITE_DEFAULT_AUTOVACUUM) || SQLITE_DEFAULT_AUTOVACUUM==0 2856 Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","0",TCL_GLOBAL_ONLY); 2857 #else 2858 Tcl_SetVar2(interp,"sqlite_options","default_autovacuum","1",TCL_GLOBAL_ONLY); 2859 #endif 2860 2861 #ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION 2862 Tcl_SetVar2(interp, "sqlite_options", "between_opt", "0", TCL_GLOBAL_ONLY); 2863 #else 2864 Tcl_SetVar2(interp, "sqlite_options", "between_opt", "1", TCL_GLOBAL_ONLY); 2865 #endif 2866 2867 #ifdef SQLITE_OMIT_BLOB_LITERAL 2868 Tcl_SetVar2(interp, "sqlite_options", "bloblit", "0", TCL_GLOBAL_ONLY); 2869 #else 2870 Tcl_SetVar2(interp, "sqlite_options", "bloblit", "1", TCL_GLOBAL_ONLY); 2871 #endif 2872 2873 #ifdef SQLITE_OMIT_CAST 2874 Tcl_SetVar2(interp, "sqlite_options", "cast", "0", TCL_GLOBAL_ONLY); 2875 #else 2876 Tcl_SetVar2(interp, "sqlite_options", "cast", "1", TCL_GLOBAL_ONLY); 2877 #endif 2878 2879 #ifdef SQLITE_OMIT_COMPLETE 2880 Tcl_SetVar2(interp, "sqlite_options", "complete", "0", TCL_GLOBAL_ONLY); 2881 #else 2882 Tcl_SetVar2(interp, "sqlite_options", "complete", "1", TCL_GLOBAL_ONLY); 2883 #endif 2884 2885 #ifdef SQLITE_OMIT_COMPOUND_SELECT 2886 Tcl_SetVar2(interp, "sqlite_options", "compound", "0", TCL_GLOBAL_ONLY); 2887 #else 2888 Tcl_SetVar2(interp, "sqlite_options", "compound", "1", TCL_GLOBAL_ONLY); 2889 #endif 2890 2891 #ifdef SQLITE_OMIT_CONFLICT_CLAUSE 2892 Tcl_SetVar2(interp, "sqlite_options", "conflict", "0", TCL_GLOBAL_ONLY); 2893 #else 2894 Tcl_SetVar2(interp, "sqlite_options", "conflict", "1", TCL_GLOBAL_ONLY); 2895 #endif 2896 2897 #ifdef SQLITE_OMIT_DATETIME_FUNCS 2898 Tcl_SetVar2(interp, "sqlite_options", "datetime", "0", TCL_GLOBAL_ONLY); 2899 #else 2900 Tcl_SetVar2(interp, "sqlite_options", "datetime", "1", TCL_GLOBAL_ONLY); 2901 #endif 2902 2903 #ifdef SQLITE_OMIT_DISKIO 2904 Tcl_SetVar2(interp, "sqlite_options", "diskio", "0", TCL_GLOBAL_ONLY); 2905 #else 2906 Tcl_SetVar2(interp, "sqlite_options", "diskio", "1", TCL_GLOBAL_ONLY); 2907 #endif 2908 2909 #ifdef SQLITE_OMIT_EXPLAIN 2910 Tcl_SetVar2(interp, "sqlite_options", "explain", "0", TCL_GLOBAL_ONLY); 2911 #else 2912 Tcl_SetVar2(interp, "sqlite_options", "explain", "1", TCL_GLOBAL_ONLY); 2913 #endif 2914 2915 #ifdef SQLITE_OMIT_FLOATING_POINT 2916 Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "0", TCL_GLOBAL_ONLY); 2917 #else 2918 Tcl_SetVar2(interp, "sqlite_options", "floatingpoint", "1", TCL_GLOBAL_ONLY); 2919 #endif 2920 2921 #ifdef SQLITE_OMIT_FOREIGN_KEY 2922 Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "0", TCL_GLOBAL_ONLY); 2923 #else 2924 Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "1", TCL_GLOBAL_ONLY); 2925 #endif 2926 2927 #ifdef SQLITE_OMIT_GLOBALRECOVER 2928 Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "0", TCL_GLOBAL_ONLY); 2929 #else 2930 Tcl_SetVar2(interp, "sqlite_options", "globalrecover", "1", TCL_GLOBAL_ONLY); 2931 #endif 2932 2933 #ifdef SQLITE_OMIT_INTEGRITY_CHECK 2934 Tcl_SetVar2(interp, "sqlite_options", "integrityck", "0", TCL_GLOBAL_ONLY); 2935 #else 2936 Tcl_SetVar2(interp, "sqlite_options", "integrityck", "1", TCL_GLOBAL_ONLY); 2937 #endif 2938 2939 #ifdef SQLITE_OMIT_LIKE_OPTIMIZATION 2940 Tcl_SetVar2(interp, "sqlite_options", "like_opt", "0", TCL_GLOBAL_ONLY); 2941 #else 2942 Tcl_SetVar2(interp, "sqlite_options", "like_opt", "1", TCL_GLOBAL_ONLY); 2943 #endif 2944 2945 #ifdef SQLITE_OMIT_MEMORYDB 2946 Tcl_SetVar2(interp, "sqlite_options", "memorydb", "0", TCL_GLOBAL_ONLY); 2947 #else 2948 Tcl_SetVar2(interp, "sqlite_options", "memorydb", "1", TCL_GLOBAL_ONLY); 2949 #endif 2950 2951 #ifdef SQLITE_OMIT_OR_OPTIMIZATION 2952 Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY); 2953 #else 2954 Tcl_SetVar2(interp, "sqlite_options", "or_opt", "1", TCL_GLOBAL_ONLY); 2955 #endif 2956 2957 #ifdef SQLITE_OMIT_PAGER_PRAGMAS 2958 Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "0", TCL_GLOBAL_ONLY); 2959 #else 2960 Tcl_SetVar2(interp, "sqlite_options", "pager_pragmas", "1", TCL_GLOBAL_ONLY); 2961 #endif 2962 2963 #ifdef SQLITE_OMIT_PARSER 2964 Tcl_SetVar2(interp, "sqlite_options", "parser", "0", TCL_GLOBAL_ONLY); 2965 #else 2966 Tcl_SetVar2(interp, "sqlite_options", "parser", "1", TCL_GLOBAL_ONLY); 2967 #endif 2968 2969 #if defined(SQLITE_OMIT_PRAGMA) || defined(SQLITE_OMIT_FLAG_PRAGMAS) 2970 Tcl_SetVar2(interp, "sqlite_options", "pragma", "0", TCL_GLOBAL_ONLY); 2971 Tcl_SetVar2(interp, "sqlite_options", "integrityck", "0", TCL_GLOBAL_ONLY); 2972 #else 2973 Tcl_SetVar2(interp, "sqlite_options", "pragma", "1", TCL_GLOBAL_ONLY); 2974 #endif 2975 2976 #ifdef SQLITE_OMIT_PROGRESS_CALLBACK 2977 Tcl_SetVar2(interp, "sqlite_options", "progress", "0", TCL_GLOBAL_ONLY); 2978 #else 2979 Tcl_SetVar2(interp, "sqlite_options", "progress", "1", TCL_GLOBAL_ONLY); 2980 #endif 2981 2982 #ifdef SQLITE_OMIT_REINDEX 2983 Tcl_SetVar2(interp, "sqlite_options", "reindex", "0", TCL_GLOBAL_ONLY); 2984 #else 2985 Tcl_SetVar2(interp, "sqlite_options", "reindex", "1", TCL_GLOBAL_ONLY); 2986 #endif 2987 2988 #ifdef SQLITE_OMIT_SCHEMA_PRAGMAS 2989 Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "0", TCL_GLOBAL_ONLY); 2990 #else 2991 Tcl_SetVar2(interp, "sqlite_options", "schema_pragmas", "1", TCL_GLOBAL_ONLY); 2992 #endif 2993 2994 #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS 2995 Tcl_SetVar2(interp, "sqlite_options", "schema_version", "0", TCL_GLOBAL_ONLY); 2996 #else 2997 Tcl_SetVar2(interp, "sqlite_options", "schema_version", "1", TCL_GLOBAL_ONLY); 2998 #endif 2999 3000 #ifdef SQLITE_OMIT_SUBQUERY 3001 Tcl_SetVar2(interp, "sqlite_options", "subquery", "0", TCL_GLOBAL_ONLY); 3002 #else 3003 Tcl_SetVar2(interp, "sqlite_options", "subquery", "1", TCL_GLOBAL_ONLY); 3004 #endif 3005 3006 #ifdef SQLITE_OMIT_TCL_VARIABLE 3007 Tcl_SetVar2(interp, "sqlite_options", "tclvar", "0", TCL_GLOBAL_ONLY); 3008 #else 3009 Tcl_SetVar2(interp, "sqlite_options", "tclvar", "1", TCL_GLOBAL_ONLY); 3010 #endif 3011 3012 #if defined(THREADSAFE) && THREADSAFE 3013 Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "1", TCL_GLOBAL_ONLY); 3014 #else 3015 Tcl_SetVar2(interp, "sqlite_options", "threadsafe", "0", TCL_GLOBAL_ONLY); 3016 #endif 3017 3018 #ifdef SQLITE_OMIT_TRACE 3019 Tcl_SetVar2(interp, "sqlite_options", "trace", "0", TCL_GLOBAL_ONLY); 3020 #else 3021 Tcl_SetVar2(interp, "sqlite_options", "trace", "1", TCL_GLOBAL_ONLY); 3022 #endif 3023 3024 #ifdef SQLITE_OMIT_TRIGGER 3025 Tcl_SetVar2(interp, "sqlite_options", "trigger", "0", TCL_GLOBAL_ONLY); 3026 #else 3027 Tcl_SetVar2(interp, "sqlite_options", "trigger", "1", TCL_GLOBAL_ONLY); 3028 #endif 3029 3030 #ifdef SQLITE_OMIT_TEMPDB 3031 Tcl_SetVar2(interp, "sqlite_options", "tempdb", "0", TCL_GLOBAL_ONLY); 3032 #else 3033 Tcl_SetVar2(interp, "sqlite_options", "tempdb", "1", TCL_GLOBAL_ONLY); 3034 #endif 3035 3036 #ifdef SQLITE_OMIT_UTF16 3037 Tcl_SetVar2(interp, "sqlite_options", "utf16", "0", TCL_GLOBAL_ONLY); 3038 #else 3039 Tcl_SetVar2(interp, "sqlite_options", "utf16", "1", TCL_GLOBAL_ONLY); 3040 #endif 3041 3042 #ifdef SQLITE_OMIT_VACUUM 3043 Tcl_SetVar2(interp, "sqlite_options", "vacuum", "0", TCL_GLOBAL_ONLY); 3044 #else 3045 Tcl_SetVar2(interp, "sqlite_options", "vacuum", "1", TCL_GLOBAL_ONLY); 3046 #endif 3047 3048 #ifdef SQLITE_OMIT_VIEW 3049 Tcl_SetVar2(interp, "sqlite_options", "view", "0", TCL_GLOBAL_ONLY); 3050 #else 3051 Tcl_SetVar2(interp, "sqlite_options", "view", "1", TCL_GLOBAL_ONLY); 3052 #endif 3053 } 3054 3055 /* 3056 ** Register commands with the TCL interpreter. 3057 */ 3058 int Sqlitetest1_Init(Tcl_Interp *interp){ 3059 extern int sqlite3_search_count; 3060 extern int sqlite3_interrupt_count; 3061 extern int sqlite3_open_file_count; 3062 extern int sqlite3_sort_count; 3063 extern int sqlite3_current_time; 3064 static struct { 3065 char *zName; 3066 Tcl_CmdProc *xProc; 3067 } aCmd[] = { 3068 { "sqlite3_mprintf_int", (Tcl_CmdProc*)sqlite3_mprintf_int }, 3069 { "sqlite3_mprintf_int64", (Tcl_CmdProc*)sqlite3_mprintf_int64 }, 3070 { "sqlite3_mprintf_str", (Tcl_CmdProc*)sqlite3_mprintf_str }, 3071 { "sqlite3_mprintf_stronly", (Tcl_CmdProc*)sqlite3_mprintf_stronly}, 3072 { "sqlite3_mprintf_double", (Tcl_CmdProc*)sqlite3_mprintf_double }, 3073 { "sqlite3_mprintf_scaled", (Tcl_CmdProc*)sqlite3_mprintf_scaled }, 3074 { "sqlite3_mprintf_hexdouble", (Tcl_CmdProc*)sqlite3_mprintf_hexdouble}, 3075 { "sqlite3_mprintf_z_test", (Tcl_CmdProc*)test_mprintf_z }, 3076 { "sqlite3_last_insert_rowid", (Tcl_CmdProc*)test_last_rowid }, 3077 { "sqlite3_exec_printf", (Tcl_CmdProc*)test_exec_printf }, 3078 { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, 3079 { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, 3080 { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, 3081 { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, 3082 { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, 3083 { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, 3084 #ifdef SQLITE_MEMDEBUG 3085 { "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail }, 3086 { "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat }, 3087 #endif 3088 { "sqlite_bind", (Tcl_CmdProc*)test_bind }, 3089 { "breakpoint", (Tcl_CmdProc*)test_breakpoint }, 3090 { "sqlite3_key", (Tcl_CmdProc*)test_key }, 3091 { "sqlite3_rekey", (Tcl_CmdProc*)test_rekey }, 3092 { "sqlite_set_magic", (Tcl_CmdProc*)sqlite_set_magic }, 3093 { "sqlite3_interrupt", (Tcl_CmdProc*)test_interrupt }, 3094 #if 0 3095 { "sqlite3_sleep", (Tcl_CmdProc*)test_sleep }, 3096 #endif 3097 { "sqlite_delete_function", (Tcl_CmdProc*)delete_function }, 3098 { "sqlite_delete_collation", (Tcl_CmdProc*)delete_collation }, 3099 { "sqlite3_get_autocommit", (Tcl_CmdProc*)get_autocommit }, 3100 { "sqlite3_stack_used", (Tcl_CmdProc*)test_stack_used }, 3101 }; 3102 static struct { 3103 char *zName; 3104 Tcl_ObjCmdProc *xProc; 3105 void *clientData; 3106 } aObjCmd[] = { 3107 { "sqlite3_bind_int", test_bind_int, 0 }, 3108 { "sqlite3_bind_int64", test_bind_int64, 0 }, 3109 { "sqlite3_bind_double", test_bind_double, 0 }, 3110 { "sqlite3_bind_null", test_bind_null ,0 }, 3111 { "sqlite3_bind_text", test_bind_text ,0 }, 3112 { "sqlite3_bind_text16", test_bind_text16 ,0 }, 3113 { "sqlite3_bind_blob", test_bind_blob ,0 }, 3114 { "sqlite3_bind_parameter_count", test_bind_parameter_count, 0}, 3115 { "sqlite3_bind_parameter_name", test_bind_parameter_name, 0}, 3116 { "sqlite3_bind_parameter_index", test_bind_parameter_index, 0}, 3117 #if 0 3118 { "sqlite3_clear_bindings", test_clear_bindings, 0}, 3119 #endif 3120 { "sqlite3_errcode", test_errcode ,0 }, 3121 { "sqlite3_errmsg", test_errmsg ,0 }, 3122 { "sqlite3_errmsg16", test_errmsg16 ,0 }, 3123 { "sqlite3_open", test_open ,0 }, 3124 { "sqlite3_open16", test_open16 ,0 }, 3125 { "sqlite3_complete16", test_complete16 ,0 }, 3126 3127 { "sqlite3_prepare", test_prepare ,0 }, 3128 { "sqlite3_prepare16", test_prepare16 ,0 }, 3129 { "sqlite3_finalize", test_finalize ,0 }, 3130 { "sqlite3_reset", test_reset ,0 }, 3131 { "sqlite3_expired", test_expired ,0 }, 3132 { "sqlite3_transfer_bindings", test_transfer_bind ,0 }, 3133 { "sqlite3_changes", test_changes ,0 }, 3134 { "sqlite3_step", test_step ,0 }, 3135 3136 /* sqlite3_column_*() API */ 3137 { "sqlite3_column_count", test_column_count ,0 }, 3138 { "sqlite3_data_count", test_data_count ,0 }, 3139 { "sqlite3_column_type", test_column_type ,0 }, 3140 { "sqlite3_column_blob", test_column_blob ,0 }, 3141 { "sqlite3_column_double", test_column_double ,0 }, 3142 { "sqlite3_column_int64", test_column_int64 ,0 }, 3143 { "sqlite3_column_text", test_stmt_utf8, sqlite3_column_text }, 3144 { "sqlite3_column_decltype", test_stmt_utf8, sqlite3_column_decltype }, 3145 { "sqlite3_column_name", test_stmt_utf8, sqlite3_column_name }, 3146 { "sqlite3_column_int", test_stmt_int, sqlite3_column_int }, 3147 { "sqlite3_column_bytes", test_stmt_int, sqlite3_column_bytes }, 3148 #ifndef SQLITE_OMIT_UTF16 3149 { "sqlite3_column_bytes16", test_stmt_int, sqlite3_column_bytes16 }, 3150 { "sqlite3_column_text16", test_stmt_utf16, sqlite3_column_text16 }, 3151 { "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16}, 3152 { "sqlite3_column_name16", test_stmt_utf16, sqlite3_column_name16 }, 3153 #endif 3154 { "sqlite3_global_recover", test_global_recover, 0 }, 3155 3156 /* Functions from os.h */ 3157 #ifndef SQLITE_OMIT_DISKIO 3158 { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 }, 3159 { "sqlite3OsClose", test_sqlite3OsClose, 0 }, 3160 { "sqlite3OsLock", test_sqlite3OsLock, 0 }, 3161 { "sqlite3OsTempFileName", test_sqlite3OsTempFileName, 0 }, 3162 3163 /* Custom test interfaces */ 3164 { "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 }, 3165 #endif 3166 #ifndef SQLITE_OMIT_UTF16 3167 { "add_test_collate", test_collate, 0 }, 3168 { "add_test_collate_needed", test_collate_needed, 0 }, 3169 { "add_test_function", test_function, 0 }, 3170 #endif 3171 { "sqlite3_crashparams", sqlite3_crashparams, 0 }, 3172 { "sqlite3_test_errstr", test_errstr, 0 }, 3173 { "tcl_variable_type", tcl_variable_type, 0 }, 3174 }; 3175 static int bitmask_size = sizeof(Bitmask)*8; 3176 int i; 3177 extern int sqlite3_os_trace; 3178 extern int sqlite3_where_trace; 3179 extern int sqlite3_sync_count, sqlite3_fullsync_count; 3180 extern int sqlite3_opentemp_count; 3181 extern int sqlite3_memUsed; 3182 extern int sqlite3_memMax; 3183 extern int sqlite3_like_count; 3184 #if OS_WIN 3185 extern int sqlite3_os_type; 3186 #endif 3187 #ifdef SQLITE_DEBUG 3188 extern int sqlite3_vdbe_addop_trace; 3189 #endif 3190 #ifdef SQLITE_TEST 3191 extern char sqlite3_query_plan[]; 3192 static char *query_plan = sqlite3_query_plan; 3193 #endif 3194 3195 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ 3196 Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); 3197 } 3198 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ 3199 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 3200 aObjCmd[i].xProc, aObjCmd[i].clientData, 0); 3201 } 3202 Tcl_LinkVar(interp, "sqlite_search_count", 3203 (char*)&sqlite3_search_count, TCL_LINK_INT); 3204 Tcl_LinkVar(interp, "sqlite_sort_count", 3205 (char*)&sqlite3_sort_count, TCL_LINK_INT); 3206 Tcl_LinkVar(interp, "sqlite_like_count", 3207 (char*)&sqlite3_like_count, TCL_LINK_INT); 3208 Tcl_LinkVar(interp, "sqlite_interrupt_count", 3209 (char*)&sqlite3_interrupt_count, TCL_LINK_INT); 3210 Tcl_LinkVar(interp, "sqlite_open_file_count", 3211 (char*)&sqlite3_open_file_count, TCL_LINK_INT); 3212 Tcl_LinkVar(interp, "sqlite_current_time", 3213 (char*)&sqlite3_current_time, TCL_LINK_INT); 3214 Tcl_LinkVar(interp, "sqlite_os_trace", 3215 (char*)&sqlite3_os_trace, TCL_LINK_INT); 3216 #if OS_WIN 3217 Tcl_LinkVar(interp, "sqlite_os_type", 3218 (char*)&sqlite3_os_type, TCL_LINK_INT); 3219 #endif 3220 #ifdef SQLITE_TEST 3221 Tcl_LinkVar(interp, "sqlite_query_plan", 3222 (char*)&query_plan, TCL_LINK_STRING|TCL_LINK_READ_ONLY); 3223 #endif 3224 #ifdef SQLITE_DEBUG 3225 Tcl_LinkVar(interp, "sqlite_addop_trace", 3226 (char*)&sqlite3_vdbe_addop_trace, TCL_LINK_INT); 3227 Tcl_LinkVar(interp, "sqlite_where_trace", 3228 (char*)&sqlite3_where_trace, TCL_LINK_INT); 3229 #endif 3230 #ifdef SQLITE_MEMDEBUG 3231 Tcl_LinkVar(interp, "sqlite_memused", 3232 (char*)&sqlite3_memUsed, TCL_LINK_INT | TCL_LINK_READ_ONLY); 3233 Tcl_LinkVar(interp, "sqlite_memmax", 3234 (char*)&sqlite3_memMax, TCL_LINK_INT | TCL_LINK_READ_ONLY); 3235 #endif 3236 #ifndef SQLITE_OMIT_DISKIO 3237 Tcl_LinkVar(interp, "sqlite_opentemp_count", 3238 (char*)&sqlite3_opentemp_count, TCL_LINK_INT); 3239 #endif 3240 Tcl_LinkVar(interp, "sqlite_static_bind_value", 3241 (char*)&sqlite_static_bind_value, TCL_LINK_STRING); 3242 Tcl_LinkVar(interp, "sqlite_temp_directory", 3243 (char*)&sqlite3_temp_directory, TCL_LINK_STRING); 3244 Tcl_LinkVar(interp, "bitmask_size", 3245 (char*)&bitmask_size, TCL_LINK_INT|TCL_LINK_READ_ONLY); 3246 #if OS_UNIX 3247 Tcl_LinkVar(interp, "sqlite_sync_count", 3248 (char*)&sqlite3_sync_count, TCL_LINK_INT); 3249 Tcl_LinkVar(interp, "sqlite_fullsync_count", 3250 (char*)&sqlite3_fullsync_count, TCL_LINK_INT); 3251 #endif /* OS_UNIX */ 3252 set_options(interp); 3253 return TCL_OK; 3254 } 3255