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