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