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