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