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