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