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 the printf() interface to SQLite. 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.75 2004/06/10 14:01:08 danielk1977 Exp $ 17 */ 18 #include "sqliteInt.h" 19 #include "tcl.h" 20 #include "os.h" 21 #include <stdlib.h> 22 #include <string.h> 23 24 #if OS_WIN 25 # define PTR_FMT "%x" 26 #else 27 # define PTR_FMT "%p" 28 #endif 29 30 int sqlite3_exec_printf( 31 sqlite *db, /* An open database */ 32 const char *sqlFormat, /* printf-style format string for the SQL */ 33 sqlite_callback xCallback, /* Callback function */ 34 void *pArg, /* 1st argument to callback function */ 35 char **errmsg, /* Error msg written here */ 36 ... /* Arguments to the format string. */ 37 ); 38 int sqlite3_exec_printf( 39 sqlite *db, /* An open database */ 40 const char *sqlFormat, /* printf-style format string for the SQL */ 41 sqlite_callback xCallback, /* Callback function */ 42 void *pArg, /* 1st argument to callback function */ 43 char **errmsg, /* Error msg written here */ 44 ... /* Arguments to the format string. */ 45 ); 46 int sqlite3_get_table_printf( 47 sqlite *db, /* An open database */ 48 const char *sqlFormat, /* printf-style format string for the SQL */ 49 char ***resultp, /* Result written to a char *[] that this points to */ 50 int *nrow, /* Number of result rows written here */ 51 int *ncol, /* Number of result columns written here */ 52 char **errmsg, /* Error msg written here */ 53 ... /* Arguments to the format string */ 54 ); 55 56 static const char * errorName(int rc){ 57 const char *zName = 0; 58 switch( rc ){ 59 case SQLITE_OK: zName = "SQLITE_OK"; break; 60 case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; 61 case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break; 62 case SQLITE_PERM: zName = "SQLITE_PERM"; break; 63 case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; 64 case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; 65 case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; 66 case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; 67 case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; 68 case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; 69 case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; 70 case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; 71 case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; 72 case SQLITE_FULL: zName = "SQLITE_FULL"; break; 73 case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; 74 case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; 75 case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; 76 case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; 77 case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break; 78 case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; 79 case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; 80 case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; 81 case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; 82 case SQLITE_AUTH: zName = "SQLITE_AUTH"; break; 83 case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break; 84 case SQLITE_RANGE: zName = "SQLITE_RANGE"; break; 85 case SQLITE_ROW: zName = "SQLITE_ROW"; break; 86 case SQLITE_DONE: zName = "SQLITE_DONE"; break; 87 default: zName = "SQLITE_Unknown"; break; 88 } 89 return zName; 90 } 91 92 /* 93 ** Decode a pointer to an sqlite object. 94 */ 95 static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite **ppDb){ 96 if( sscanf(zA, PTR_FMT, (void**)ppDb)!=1 && 97 (zA[0]!='0' || zA[1]!='x' || sscanf(&zA[2], PTR_FMT, (void**)ppDb)!=1) 98 ){ 99 Tcl_AppendResult(interp, "\"", zA, "\" is not a valid pointer value", 0); 100 return TCL_ERROR; 101 } 102 return TCL_OK; 103 } 104 105 /* 106 ** Decode a pointer to an sqlite3_stmt object. 107 */ 108 static int getStmtPointer( 109 Tcl_Interp *interp, 110 const char *zArg, 111 sqlite3_stmt **ppStmt 112 ){ 113 if( sscanf(zArg, PTR_FMT, (void**)ppStmt)!=1 ){ 114 Tcl_AppendResult(interp, "\"", zArg, "\" is not a valid pointer value", 0); 115 return TCL_ERROR; 116 } 117 return TCL_OK; 118 } 119 120 /* 121 ** Decode a pointer to an sqlite3_stmt object. 122 */ 123 static int getFilePointer( 124 Tcl_Interp *interp, 125 const char *zArg, 126 OsFile **ppFile 127 ){ 128 if( sscanf(zArg, PTR_FMT, (void**)ppFile)!=1 ){ 129 Tcl_AppendResult(interp, "\"", zArg, "\" is not a valid pointer value", 0); 130 return TCL_ERROR; 131 } 132 return TCL_OK; 133 } 134 135 /* 136 ** Generate a text representation of a pointer that can be understood 137 ** by the getDbPointer and getVmPointer routines above. 138 ** 139 ** The problem is, on some machines (Solaris) if you do a printf with 140 ** "%p" you cannot turn around and do a scanf with the same "%p" and 141 ** get your pointer back. You have to prepend a "0x" before it will 142 ** work. Or at least that is what is reported to me (drh). But this 143 ** behavior varies from machine to machine. The solution used her is 144 ** to test the string right after it is generated to see if it can be 145 ** understood by scanf, and if not, try prepending an "0x" to see if 146 ** that helps. If nothing works, a fatal error is generated. 147 */ 148 static int makePointerStr(Tcl_Interp *interp, char *zPtr, void *p){ 149 void *p2; 150 sprintf(zPtr, PTR_FMT, p); 151 if( sscanf(zPtr, PTR_FMT, &p2)!=1 || p2!=p ){ 152 sprintf(zPtr, "0x" PTR_FMT, p); 153 if( sscanf(zPtr, PTR_FMT, &p2)!=1 || p2!=p ){ 154 Tcl_AppendResult(interp, "unable to convert a pointer to a string " 155 "in the file " __FILE__ " in function makePointerStr(). Please " 156 "report this problem to the SQLite mailing list or as a new but " 157 "report. Please provide detailed information about how you compiled " 158 "SQLite and what computer you are running on.", 0); 159 return TCL_ERROR; 160 } 161 } 162 return TCL_OK; 163 } 164 165 /* 166 ** The callback routine for sqlite3_exec_printf(). 167 */ 168 static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){ 169 Tcl_DString *str = (Tcl_DString*)pArg; 170 int i; 171 172 if( Tcl_DStringLength(str)==0 ){ 173 for(i=0; i<argc; i++){ 174 Tcl_DStringAppendElement(str, name[i] ? name[i] : "NULL"); 175 } 176 } 177 for(i=0; i<argc; i++){ 178 Tcl_DStringAppendElement(str, argv[i] ? argv[i] : "NULL"); 179 } 180 return 0; 181 } 182 183 /* 184 ** Usage: sqlite3_exec_printf DB FORMAT STRING 185 ** 186 ** Invoke the sqlite3_exec_printf() interface using the open database 187 ** DB. The SQL is the string FORMAT. The format string should contain 188 ** one %s or %q. STRING is the value inserted into %s or %q. 189 */ 190 static int test_exec_printf( 191 void *NotUsed, 192 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 193 int argc, /* Number of arguments */ 194 char **argv /* Text of each argument */ 195 ){ 196 sqlite *db; 197 Tcl_DString str; 198 int rc; 199 char *zErr = 0; 200 char zBuf[30]; 201 if( argc!=4 ){ 202 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 203 " DB FORMAT STRING", 0); 204 return TCL_ERROR; 205 } 206 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 207 Tcl_DStringInit(&str); 208 rc = sqlite3_exec_printf(db, argv[2], exec_printf_cb, &str, &zErr, argv[3]); 209 sprintf(zBuf, "%d", rc); 210 Tcl_AppendElement(interp, zBuf); 211 Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr); 212 Tcl_DStringFree(&str); 213 if( zErr ) free(zErr); 214 return TCL_OK; 215 } 216 217 /* 218 ** Usage: sqlite3_mprintf_z_test SEPARATOR ARG0 ARG1 ... 219 ** 220 ** Test the %z format of mprintf(). Use multiple mprintf() calls to 221 ** concatenate arg0 through argn using separator as the separator. 222 ** Return the result. 223 */ 224 static int test_mprintf_z( 225 void *NotUsed, 226 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 227 int argc, /* Number of arguments */ 228 char **argv /* Text of each argument */ 229 ){ 230 char *zResult = 0; 231 int i; 232 233 for(i=2; i<argc; i++){ 234 zResult = sqlite3MPrintf("%z%s%s", zResult, argv[1], argv[i]); 235 } 236 Tcl_AppendResult(interp, zResult, 0); 237 sqliteFree(zResult); 238 return TCL_OK; 239 } 240 241 /* 242 ** Usage: sqlite3_get_table_printf DB FORMAT STRING 243 ** 244 ** Invoke the sqlite3_get_table_printf() interface using the open database 245 ** DB. The SQL is the string FORMAT. The format string should contain 246 ** one %s or %q. STRING is the value inserted into %s or %q. 247 */ 248 static int test_get_table_printf( 249 void *NotUsed, 250 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 251 int argc, /* Number of arguments */ 252 char **argv /* Text of each argument */ 253 ){ 254 sqlite *db; 255 Tcl_DString str; 256 int rc; 257 char *zErr = 0; 258 int nRow, nCol; 259 char **aResult; 260 int i; 261 char zBuf[30]; 262 if( argc!=4 ){ 263 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 264 " DB FORMAT STRING", 0); 265 return TCL_ERROR; 266 } 267 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 268 Tcl_DStringInit(&str); 269 rc = sqlite3_get_table_printf(db, argv[2], &aResult, &nRow, &nCol, 270 &zErr, argv[3]); 271 sprintf(zBuf, "%d", rc); 272 Tcl_AppendElement(interp, zBuf); 273 if( rc==SQLITE_OK ){ 274 sprintf(zBuf, "%d", nRow); 275 Tcl_AppendElement(interp, zBuf); 276 sprintf(zBuf, "%d", nCol); 277 Tcl_AppendElement(interp, zBuf); 278 for(i=0; i<(nRow+1)*nCol; i++){ 279 Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL"); 280 } 281 }else{ 282 Tcl_AppendElement(interp, zErr); 283 } 284 sqlite3_free_table(aResult); 285 if( zErr ) free(zErr); 286 return TCL_OK; 287 } 288 289 290 /* 291 ** Usage: sqlite3_last_insert_rowid DB 292 ** 293 ** Returns the integer ROWID of the most recent insert. 294 */ 295 static int test_last_rowid( 296 void *NotUsed, 297 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 298 int argc, /* Number of arguments */ 299 char **argv /* Text of each argument */ 300 ){ 301 sqlite *db; 302 char zBuf[30]; 303 304 if( argc!=2 ){ 305 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0); 306 return TCL_ERROR; 307 } 308 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 309 sprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db)); 310 Tcl_AppendResult(interp, zBuf, 0); 311 return SQLITE_OK; 312 } 313 314 /* 315 ** Usage: sqlite3_close DB 316 ** 317 ** Closes the database opened by sqlite3_open. 318 */ 319 static int sqlite_test_close( 320 void *NotUsed, 321 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 322 int argc, /* Number of arguments */ 323 char **argv /* Text of each argument */ 324 ){ 325 sqlite *db; 326 if( argc!=2 ){ 327 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 328 " FILENAME\"", 0); 329 return TCL_ERROR; 330 } 331 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 332 sqlite3_close(db); 333 return TCL_OK; 334 } 335 336 /* 337 ** Implementation of the x_coalesce() function. 338 ** Return the first argument non-NULL argument. 339 */ 340 static void ifnullFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 341 int i; 342 for(i=0; i<argc; i++){ 343 if( SQLITE_NULL!=sqlite3_value_type(argv[i]) ){ 344 sqlite3_result_text(context, sqlite3_value_text(argv[i]), -1, 1); 345 break; 346 } 347 } 348 } 349 350 /* 351 ** A structure into which to accumulate text. 352 */ 353 struct dstr { 354 int nAlloc; /* Space allocated */ 355 int nUsed; /* Space used */ 356 char *z; /* The space */ 357 }; 358 359 /* 360 ** Append text to a dstr 361 */ 362 static void dstrAppend(struct dstr *p, const char *z, int divider){ 363 int n = strlen(z); 364 if( p->nUsed + n + 2 > p->nAlloc ){ 365 char *zNew; 366 p->nAlloc = p->nAlloc*2 + n + 200; 367 zNew = sqliteRealloc(p->z, p->nAlloc); 368 if( zNew==0 ){ 369 sqliteFree(p->z); 370 memset(p, 0, sizeof(*p)); 371 return; 372 } 373 p->z = zNew; 374 } 375 if( divider && p->nUsed>0 ){ 376 p->z[p->nUsed++] = divider; 377 } 378 memcpy(&p->z[p->nUsed], z, n+1); 379 p->nUsed += n; 380 } 381 382 /* 383 ** Invoked for each callback from sqlite3ExecFunc 384 */ 385 static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){ 386 struct dstr *p = (struct dstr*)pData; 387 int i; 388 for(i=0; i<argc; i++){ 389 if( argv[i]==0 ){ 390 dstrAppend(p, "NULL", ' '); 391 }else{ 392 dstrAppend(p, argv[i], ' '); 393 } 394 } 395 return 0; 396 } 397 398 /* 399 ** Implementation of the x_sqlite3_exec() function. This function takes 400 ** a single argument and attempts to execute that argument as SQL code. 401 ** This is illegal and should set the SQLITE_MISUSE flag on the database. 402 ** 403 ** 2004-Jan-07: We have changed this to make it legal to call sqlite3_exec() 404 ** from within a function call. 405 ** 406 ** This routine simulates the effect of having two threads attempt to 407 ** use the same database at the same time. 408 */ 409 static void sqlite3ExecFunc( 410 sqlite3_context *context, 411 int argc, 412 sqlite3_value **argv 413 ){ 414 struct dstr x; 415 memset(&x, 0, sizeof(x)); 416 sqlite3_exec((sqlite*)sqlite3_user_data(context), 417 sqlite3_value_text(argv[0]), 418 execFuncCallback, &x, 0); 419 sqlite3_result_text(context, x.z, x.nUsed, 1); 420 sqliteFree(x.z); 421 } 422 423 /* 424 ** Usage: sqlite_test_create_function DB 425 ** 426 ** Call the sqlite3_create_function API on the given database in order 427 ** to create a function named "x_coalesce". This function does the same thing 428 ** as the "coalesce" function. This function also registers an SQL function 429 ** named "x_sqlite3_exec" that invokes sqlite3_exec(). Invoking sqlite3_exec() 430 ** in this way is illegal recursion and should raise an SQLITE_MISUSE error. 431 ** The effect is similar to trying to use the same database connection from 432 ** two threads at the same time. 433 ** 434 ** The original motivation for this routine was to be able to call the 435 ** sqlite3_create_function function while a query is in progress in order 436 ** to test the SQLITE_MISUSE detection logic. 437 */ 438 static int test_create_function( 439 void *NotUsed, 440 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 441 int argc, /* Number of arguments */ 442 char **argv /* Text of each argument */ 443 ){ 444 sqlite *db; 445 extern void Md5_Register(sqlite*); 446 if( argc!=2 ){ 447 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 448 " FILENAME\"", 0); 449 return TCL_ERROR; 450 } 451 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 452 sqlite3_create_function(db, "x_coalesce", -1, 0, 0, 0, ifnullFunc, 0, 0); 453 sqlite3_create_function(db, "x_sqlite3_exec", 1, 0, 0, db, 454 sqlite3ExecFunc, 0, 0); 455 return TCL_OK; 456 } 457 458 /* 459 ** Routines to implement the x_count() aggregate function. 460 */ 461 typedef struct CountCtx CountCtx; 462 struct CountCtx { 463 int n; 464 }; 465 static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ 466 CountCtx *p; 467 p = sqlite3_aggregate_context(context, sizeof(*p)); 468 if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0]) ) && p ){ 469 p->n++; 470 } 471 } 472 static void countFinalize(sqlite3_context *context){ 473 CountCtx *p; 474 p = sqlite3_aggregate_context(context, sizeof(*p)); 475 sqlite3_result_int(context, p ? p->n : 0); 476 } 477 478 /* 479 ** Usage: sqlite_test_create_aggregate DB 480 ** 481 ** Call the sqlite3_create_function API on the given database in order 482 ** to create a function named "x_count". This function does the same thing 483 ** as the "md5sum" function. 484 ** 485 ** The original motivation for this routine was to be able to call the 486 ** sqlite3_create_aggregate function while a query is in progress in order 487 ** to test the SQLITE_MISUSE detection logic. 488 */ 489 static int test_create_aggregate( 490 void *NotUsed, 491 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 492 int argc, /* Number of arguments */ 493 char **argv /* Text of each argument */ 494 ){ 495 sqlite *db; 496 if( argc!=2 ){ 497 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 498 " FILENAME\"", 0); 499 return TCL_ERROR; 500 } 501 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 502 sqlite3_create_function(db, "x_count", 0, 0, 0, 0, 0,countStep,countFinalize); 503 sqlite3_create_function(db, "x_count", 1, 0, 0, 0, 0,countStep,countFinalize); 504 return TCL_OK; 505 } 506 507 508 509 /* 510 ** Usage: sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER 511 ** 512 ** Call mprintf with three integer arguments 513 */ 514 static int sqlite3_mprintf_int( 515 void *NotUsed, 516 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 517 int argc, /* Number of arguments */ 518 char **argv /* Text of each argument */ 519 ){ 520 int a[3], i; 521 char *z; 522 if( argc!=5 ){ 523 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 524 " FORMAT INT INT INT\"", 0); 525 return TCL_ERROR; 526 } 527 for(i=2; i<5; i++){ 528 if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 529 } 530 z = sqlite3_mprintf(argv[1], a[0], a[1], a[2]); 531 Tcl_AppendResult(interp, z, 0); 532 sqlite3_free(z); 533 return TCL_OK; 534 } 535 536 /* 537 ** Usage: sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING 538 ** 539 ** Call mprintf with two integer arguments and one string argument 540 */ 541 static int sqlite3_mprintf_str( 542 void *NotUsed, 543 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 544 int argc, /* Number of arguments */ 545 char **argv /* Text of each argument */ 546 ){ 547 int a[3], i; 548 char *z; 549 if( argc<4 || argc>5 ){ 550 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 551 " FORMAT INT INT ?STRING?\"", 0); 552 return TCL_ERROR; 553 } 554 for(i=2; i<4; i++){ 555 if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 556 } 557 z = sqlite3_mprintf(argv[1], a[0], a[1], argc>4 ? argv[4] : NULL); 558 Tcl_AppendResult(interp, z, 0); 559 sqlite3_free(z); 560 return TCL_OK; 561 } 562 563 /* 564 ** Usage: sqlite3_mprintf_str FORMAT INTEGER INTEGER DOUBLE 565 ** 566 ** Call mprintf with two integer arguments and one double argument 567 */ 568 static int sqlite3_mprintf_double( 569 void *NotUsed, 570 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 571 int argc, /* Number of arguments */ 572 char **argv /* Text of each argument */ 573 ){ 574 int a[3], i; 575 double r; 576 char *z; 577 if( argc!=5 ){ 578 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 579 " FORMAT INT INT STRING\"", 0); 580 return TCL_ERROR; 581 } 582 for(i=2; i<4; i++){ 583 if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR; 584 } 585 if( Tcl_GetDouble(interp, argv[4], &r) ) return TCL_ERROR; 586 z = sqlite3_mprintf(argv[1], a[0], a[1], r); 587 Tcl_AppendResult(interp, z, 0); 588 sqlite3_free(z); 589 return TCL_OK; 590 } 591 592 /* 593 ** Usage: sqlite3_mprintf_str FORMAT DOUBLE DOUBLE 594 ** 595 ** Call mprintf with a single double argument which is the product of the 596 ** two arguments given above. This is used to generate overflow and underflow 597 ** doubles to test that they are converted properly. 598 */ 599 static int sqlite3_mprintf_scaled( 600 void *NotUsed, 601 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 602 int argc, /* Number of arguments */ 603 char **argv /* Text of each argument */ 604 ){ 605 int i; 606 double r[2]; 607 char *z; 608 if( argc!=4 ){ 609 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 610 " FORMAT DOUBLE DOUBLE\"", 0); 611 return TCL_ERROR; 612 } 613 for(i=2; i<4; i++){ 614 if( Tcl_GetDouble(interp, argv[i], &r[i-2]) ) return TCL_ERROR; 615 } 616 z = sqlite3_mprintf(argv[1], r[0]*r[1]); 617 Tcl_AppendResult(interp, z, 0); 618 sqlite3_free(z); 619 return TCL_OK; 620 } 621 622 /* 623 ** Usage: sqlite_malloc_fail N 624 ** 625 ** Rig sqliteMalloc() to fail on the N-th call. Turn off this mechanism 626 ** and reset the sqlite3_malloc_failed variable is N==0. 627 */ 628 #ifdef SQLITE_DEBUG 629 static int sqlite_malloc_fail( 630 void *NotUsed, 631 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 632 int argc, /* Number of arguments */ 633 char **argv /* Text of each argument */ 634 ){ 635 int n; 636 if( argc!=2 ){ 637 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"", 0); 638 return TCL_ERROR; 639 } 640 if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR; 641 sqlite3_iMallocFail = n; 642 sqlite3_malloc_failed = 0; 643 return TCL_OK; 644 } 645 #endif 646 647 /* 648 ** Usage: sqlite_malloc_stat 649 ** 650 ** Return the number of prior calls to sqliteMalloc() and sqliteFree(). 651 */ 652 #ifdef SQLITE_DEBUG 653 static int sqlite_malloc_stat( 654 void *NotUsed, 655 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 656 int argc, /* Number of arguments */ 657 char **argv /* Text of each argument */ 658 ){ 659 char zBuf[200]; 660 sprintf(zBuf, "%d %d %d", sqlite3_nMalloc, sqlite3_nFree, sqlite3_iMallocFail); 661 Tcl_AppendResult(interp, zBuf, 0); 662 return TCL_OK; 663 } 664 #endif 665 666 /* 667 ** Usage: sqlite_abort 668 ** 669 ** Shutdown the process immediately. This is not a clean shutdown. 670 ** This command is used to test the recoverability of a database in 671 ** the event of a program crash. 672 */ 673 static int sqlite_abort( 674 void *NotUsed, 675 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 676 int argc, /* Number of arguments */ 677 char **argv /* Text of each argument */ 678 ){ 679 assert( interp==0 ); /* This will always fail */ 680 return TCL_OK; 681 } 682 683 /* 684 ** The following routine is a user-defined SQL function whose purpose 685 ** is to test the sqlite_set_result() API. 686 */ 687 static void testFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ 688 while( argc>=2 ){ 689 const char *zArg0 = sqlite3_value_text(argv[0]); 690 if( zArg0 ){ 691 if( 0==sqlite3StrICmp(zArg0, "int") ){ 692 sqlite3_result_int(context, sqlite3_value_int(argv[1])); 693 }else if( sqlite3StrICmp(zArg0,"int64")==0 ){ 694 sqlite3_result_int64(context, sqlite3_value_int64(argv[1])); 695 }else if( sqlite3StrICmp(zArg0,"string")==0 ){ 696 sqlite3_result_text(context, sqlite3_value_text(argv[1]), -1, 1); 697 }else if( sqlite3StrICmp(zArg0,"double")==0 ){ 698 sqlite3_result_double(context, sqlite3_value_double(argv[1])); 699 }else if( sqlite3StrICmp(zArg0,"null")==0 ){ 700 sqlite3_result_null(context); 701 }else if( sqlite3StrICmp(zArg0,"value")==0 ){ 702 sqlite3_result_value(context, argv[sqlite3_value_int(argv[1])]); 703 }else{ 704 goto error_out; 705 } 706 }else{ 707 goto error_out; 708 } 709 argc -= 2; 710 argv += 2; 711 } 712 return; 713 714 error_out: 715 sqlite3_result_error(context,"first argument should be one of: " 716 "int int64 string double null value", -1); 717 } 718 719 /* 720 ** Usage: sqlite_register_test_function DB NAME 721 ** 722 ** Register the test SQL function on the database DB under the name NAME. 723 */ 724 static int test_register_func( 725 void *NotUsed, 726 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 727 int argc, /* Number of arguments */ 728 char **argv /* Text of each argument */ 729 ){ 730 sqlite *db; 731 int rc; 732 if( argc!=3 ){ 733 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 734 " DB FUNCTION-NAME", 0); 735 return TCL_ERROR; 736 } 737 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; 738 rc = sqlite3_create_function(db, argv[2], -1, 0, 0, 0, testFunc, 0, 0); 739 if( rc!=0 ){ 740 Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0); 741 return TCL_ERROR; 742 } 743 return TCL_OK; 744 } 745 746 /* 747 ** Usage: sqlite3_finalize STMT 748 ** 749 ** Finalize a statement handle. 750 */ 751 static int test_finalize( 752 void * clientData, 753 Tcl_Interp *interp, 754 int objc, 755 Tcl_Obj *CONST objv[] 756 ){ 757 sqlite3_stmt *pStmt; 758 int rc; 759 760 if( objc!=2 ){ 761 Tcl_AppendResult(interp, "wrong # args: should be \"", 762 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 763 return TCL_ERROR; 764 } 765 766 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 767 768 rc = sqlite3_finalize(pStmt); 769 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 770 if( rc ){ 771 return TCL_ERROR; 772 } 773 return TCL_OK; 774 } 775 776 /* 777 ** Usage: sqlite3_reset STMT 778 ** 779 ** Finalize a statement handle. 780 */ 781 static int test_reset( 782 void * clientData, 783 Tcl_Interp *interp, 784 int objc, 785 Tcl_Obj *CONST objv[] 786 ){ 787 sqlite3_stmt *pStmt; 788 int rc; 789 790 if( objc!=2 ){ 791 Tcl_AppendResult(interp, "wrong # args: should be \"", 792 Tcl_GetStringFromObj(objv[0], 0), " <STMT>", 0); 793 return TCL_ERROR; 794 } 795 796 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 797 798 rc = sqlite3_reset(pStmt); 799 if( rc ){ 800 return TCL_ERROR; 801 } 802 return TCL_OK; 803 } 804 805 /* 806 ** Usage: sqlite3_reset VM 807 ** 808 ** Reset a virtual machine and prepare it to be run again. 809 */ 810 811 /* 812 ** This is the "static_bind_value" that variables are bound to when 813 ** the FLAG option of sqlite3_bind is "static" 814 */ 815 static char *sqlite_static_bind_value = 0; 816 817 /* 818 ** Usage: sqlite3_bind VM IDX VALUE FLAGS 819 ** 820 ** Sets the value of the IDX-th occurance of "?" in the original SQL 821 ** string. VALUE is the new value. If FLAGS=="null" then VALUE is 822 ** ignored and the value is set to NULL. If FLAGS=="static" then 823 ** the value is set to the value of a static variable named 824 ** "sqlite_static_bind_value". If FLAGS=="normal" then a copy 825 ** of the VALUE is made. 826 */ 827 static int test_bind( 828 void *NotUsed, 829 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 830 int argc, /* Number of arguments */ 831 char **argv /* Text of each argument */ 832 ){ 833 sqlite3_stmt *pStmt; 834 int rc; 835 int idx; 836 if( argc!=5 ){ 837 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 838 " VM IDX VALUE (null|static|normal)\"", 0); 839 return TCL_ERROR; 840 } 841 if( getStmtPointer(interp, argv[1], &pStmt) ) return TCL_ERROR; 842 if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR; 843 if( strcmp(argv[4],"null")==0 ){ 844 rc = sqlite3_bind_null(pStmt, idx); 845 }else if( strcmp(argv[4],"static")==0 ){ 846 rc = sqlite3_bind_text(pStmt, idx, sqlite_static_bind_value, -1, 0); 847 }else if( strcmp(argv[4],"normal")==0 ){ 848 rc = sqlite3_bind_text(pStmt, idx, argv[3], -1, 1); 849 }else{ 850 Tcl_AppendResult(interp, "4th argument should be " 851 "\"null\" or \"static\" or \"normal\"", 0); 852 return TCL_ERROR; 853 } 854 if( rc ){ 855 char zBuf[50]; 856 sprintf(zBuf, "(%d) ", rc); 857 Tcl_AppendResult(interp, zBuf, sqlite3ErrStr(rc), 0); 858 return TCL_ERROR; 859 } 860 return TCL_OK; 861 } 862 863 864 /* 865 ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be> 866 ** 867 ** This function is used to test that SQLite selects the correct collation 868 ** sequence callback when multiple versions (for different text encodings) 869 ** are available. 870 ** 871 ** Calling this routine registers the collation sequence "test_collate" 872 ** with database handle <db>. The second argument must be a list of three 873 ** boolean values. If the first is true, then a version of test_collate is 874 ** registered for UTF-8, if the second is true, a version is registered for 875 ** UTF-16le, if the third is true, a UTF-16be version is available. 876 ** Previous versions of test_collate are deleted. 877 ** 878 ** The collation sequence test_collate is implemented by calling the 879 ** following TCL script: 880 ** 881 ** "test_collate <enc> <lhs> <rhs>" 882 ** 883 ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8. 884 ** The <enc> parameter is the encoding of the collation function that 885 ** SQLite selected to call. The TCL test script implements the 886 ** "test_collate" proc. 887 ** 888 ** Note that this will only work with one intepreter at a time, as the 889 ** interp pointer to use when evaluating the TCL script is stored in 890 ** pTestCollateInterp. 891 */ 892 static Tcl_Interp* pTestCollateInterp; 893 static int test_collate_func( 894 void *pCtx, 895 int nA, const void *zA, 896 int nB, const void *zB 897 ){ 898 Tcl_Interp *i = pTestCollateInterp; 899 int encin = (int)pCtx; 900 int res; 901 902 sqlite3_value *pVal; 903 Tcl_Obj *pX; 904 905 pX = Tcl_NewStringObj("test_collate", -1); 906 Tcl_IncrRefCount(pX); 907 908 switch( encin ){ 909 case SQLITE_UTF8: 910 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-8",-1)); 911 break; 912 case SQLITE_UTF16LE: 913 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16LE",-1)); 914 break; 915 case SQLITE_UTF16BE: 916 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj("UTF-16BE",-1)); 917 break; 918 default: 919 assert(0); 920 } 921 922 pVal = sqlite3ValueNew(); 923 sqlite3ValueSetStr(pVal, nA, zA, encin); 924 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj(sqlite3_value_text(pVal),-1)); 925 sqlite3ValueSetStr(pVal, nB, zB, encin); 926 Tcl_ListObjAppendElement(i,pX,Tcl_NewStringObj(sqlite3_value_text(pVal),-1)); 927 sqlite3ValueFree(pVal); 928 929 Tcl_EvalObjEx(i, pX, 0); 930 Tcl_DecrRefCount(pX); 931 Tcl_GetIntFromObj(i, Tcl_GetObjResult(i), &res); 932 return res; 933 } 934 static int test_collate( 935 void * clientData, 936 Tcl_Interp *interp, 937 int objc, 938 Tcl_Obj *CONST objv[] 939 ){ 940 sqlite3 *db; 941 int val; 942 943 if( objc!=5 ) goto bad_args; 944 pTestCollateInterp = interp; 945 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 946 947 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR; 948 sqlite3_create_collation(db, "test_collate", SQLITE_UTF8, 949 (void *)SQLITE_UTF8, val?test_collate_func:0); 950 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; 951 sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE, 952 (void *)SQLITE_UTF16LE, val?test_collate_func:0); 953 if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR; 954 sqlite3_create_collation(db, "test_collate", SQLITE_UTF16BE, 955 (void *)SQLITE_UTF16BE, val?test_collate_func:0); 956 957 return TCL_OK; 958 959 bad_args: 960 Tcl_AppendResult(interp, "wrong # args: should be \"", 961 Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); 962 return TCL_ERROR; 963 } 964 965 /* 966 ** Usage: breakpoint 967 ** 968 ** This routine exists for one purpose - to provide a place to put a 969 ** breakpoint with GDB that can be triggered using TCL code. The use 970 ** for this is when a particular test fails on (say) the 1485th iteration. 971 ** In the TCL test script, we can add code like this: 972 ** 973 ** if {$i==1485} breakpoint 974 ** 975 ** Then run testfixture in the debugger and wait for the breakpoint to 976 ** fire. Then additional breakpoints can be set to trace down the bug. 977 */ 978 static int test_breakpoint( 979 void *NotUsed, 980 Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 981 int argc, /* Number of arguments */ 982 char **argv /* Text of each argument */ 983 ){ 984 return TCL_OK; /* Do nothing */ 985 } 986 987 static int test_bind_int32( 988 void * clientData, 989 Tcl_Interp *interp, 990 int objc, 991 Tcl_Obj *CONST objv[] 992 ){ 993 sqlite3_stmt *pStmt; 994 int idx; 995 int value; 996 int rc; 997 998 if( objc!=4 ){ 999 Tcl_AppendResult(interp, "wrong # args: should be \"", 1000 Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>", 0); 1001 return TCL_ERROR; 1002 } 1003 1004 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1005 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1006 if( Tcl_GetIntFromObj(interp, objv[3], &value) ) return TCL_ERROR; 1007 1008 rc = sqlite3_bind_int(pStmt, idx, value); 1009 if( rc!=SQLITE_OK ){ 1010 return TCL_ERROR; 1011 } 1012 1013 return TCL_OK; 1014 } 1015 1016 static int test_bind_int64( 1017 void * clientData, 1018 Tcl_Interp *interp, 1019 int objc, 1020 Tcl_Obj *CONST objv[] 1021 ){ 1022 sqlite3_stmt *pStmt; 1023 int idx; 1024 i64 value; 1025 int rc; 1026 1027 if( objc!=4 ){ 1028 Tcl_AppendResult(interp, "wrong # args: should be \"", 1029 Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>", 0); 1030 return TCL_ERROR; 1031 } 1032 1033 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1034 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1035 if( Tcl_GetWideIntFromObj(interp, objv[3], &value) ) return TCL_ERROR; 1036 1037 rc = sqlite3_bind_int64(pStmt, idx, value); 1038 if( rc!=SQLITE_OK ){ 1039 return TCL_ERROR; 1040 } 1041 1042 return TCL_OK; 1043 } 1044 1045 static int test_bind_double( 1046 void * clientData, 1047 Tcl_Interp *interp, 1048 int objc, 1049 Tcl_Obj *CONST objv[] 1050 ){ 1051 sqlite3_stmt *pStmt; 1052 int idx; 1053 double value; 1054 int rc; 1055 1056 if( objc!=4 ){ 1057 Tcl_AppendResult(interp, "wrong # args: should be \"", 1058 Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>", 0); 1059 return TCL_ERROR; 1060 } 1061 1062 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1063 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1064 if( Tcl_GetDoubleFromObj(interp, objv[3], &value) ) return TCL_ERROR; 1065 1066 rc = sqlite3_bind_double(pStmt, idx, value); 1067 if( rc!=SQLITE_OK ){ 1068 return TCL_ERROR; 1069 } 1070 1071 return TCL_OK; 1072 } 1073 1074 static int test_bind_null( 1075 void * clientData, 1076 Tcl_Interp *interp, 1077 int objc, 1078 Tcl_Obj *CONST objv[] 1079 ){ 1080 sqlite3_stmt *pStmt; 1081 int idx; 1082 int rc; 1083 1084 if( objc!=3 ){ 1085 Tcl_AppendResult(interp, "wrong # args: should be \"", 1086 Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.>", 0); 1087 return TCL_ERROR; 1088 } 1089 1090 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1091 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1092 1093 rc = sqlite3_bind_null(pStmt, idx); 1094 if( rc!=SQLITE_OK ){ 1095 return TCL_ERROR; 1096 } 1097 1098 return TCL_OK; 1099 } 1100 1101 static int test_bind_text( 1102 void * clientData, 1103 Tcl_Interp *interp, 1104 int objc, 1105 Tcl_Obj *CONST objv[] 1106 ){ 1107 sqlite3_stmt *pStmt; 1108 int idx; 1109 int bytes; 1110 char *value; 1111 int rc; 1112 1113 if( objc!=5 ){ 1114 Tcl_AppendResult(interp, "wrong # args: should be \"", 1115 Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>" 1116 " <bytes>", 0); 1117 return TCL_ERROR; 1118 } 1119 1120 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1121 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1122 value = Tcl_GetString(objv[3]); 1123 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 1124 1125 rc = sqlite3_bind_text(pStmt, idx, value, bytes, 1); 1126 if( rc!=SQLITE_OK ){ 1127 return TCL_ERROR; 1128 } 1129 1130 return TCL_OK; 1131 } 1132 1133 static int test_bind_text16( 1134 void * clientData, 1135 Tcl_Interp *interp, 1136 int objc, 1137 Tcl_Obj *CONST objv[] 1138 ){ 1139 sqlite3_stmt *pStmt; 1140 int idx; 1141 int bytes; 1142 char *value; 1143 int rc; 1144 1145 if( objc!=5 ){ 1146 Tcl_AppendResult(interp, "wrong # args: should be \"", 1147 Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>" 1148 " <bytes>", 0); 1149 return TCL_ERROR; 1150 } 1151 1152 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1153 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1154 value = Tcl_GetByteArrayFromObj(objv[3], 0); 1155 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 1156 1157 rc = sqlite3_bind_text16(pStmt, idx, (void *)value, bytes, 1); 1158 if( rc!=SQLITE_OK ){ 1159 return TCL_ERROR; 1160 } 1161 1162 return TCL_OK; 1163 } 1164 1165 static int test_bind_blob( 1166 void * clientData, 1167 Tcl_Interp *interp, 1168 int objc, 1169 Tcl_Obj *CONST objv[] 1170 ){ 1171 sqlite3_stmt *pStmt; 1172 int idx; 1173 int bytes; 1174 char *value; 1175 int rc; 1176 1177 if( objc!=5 ){ 1178 Tcl_AppendResult(interp, "wrong # args: should be \"", 1179 Tcl_GetStringFromObj(objv[0], 0), " <STMT> <param no.> <value>" 1180 " <bytes>", 0); 1181 return TCL_ERROR; 1182 } 1183 1184 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1185 if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; 1186 value = Tcl_GetString(objv[3]); 1187 if( Tcl_GetIntFromObj(interp, objv[4], &bytes) ) return TCL_ERROR; 1188 1189 rc = sqlite3_bind_blob(pStmt, idx, value, bytes, 1); 1190 if( rc!=SQLITE_OK ){ 1191 return TCL_ERROR; 1192 } 1193 1194 return TCL_OK; 1195 } 1196 1197 /* 1198 ** Usage: sqlite3_errcode DB 1199 ** 1200 ** Return the string representation of the most recent sqlite3_* API 1201 ** error code. e.g. "SQLITE_ERROR". 1202 */ 1203 static int test_errcode( 1204 void * clientData, 1205 Tcl_Interp *interp, 1206 int objc, 1207 Tcl_Obj *CONST objv[] 1208 ){ 1209 sqlite3 *db; 1210 1211 if( objc!=2 ){ 1212 Tcl_AppendResult(interp, "wrong # args: should be \"", 1213 Tcl_GetString(objv[0]), " DB", 0); 1214 return TCL_ERROR; 1215 } 1216 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1217 Tcl_SetResult(interp, (char *)errorName(sqlite3_errcode(db)), 0); 1218 return TCL_OK; 1219 } 1220 1221 /* 1222 ** Usage: test_errmsg DB 1223 ** 1224 ** Returns the UTF-8 representation of the error message string for the 1225 ** most recent sqlite3_* API call. 1226 */ 1227 static int test_errmsg( 1228 void * clientData, 1229 Tcl_Interp *interp, 1230 int objc, 1231 Tcl_Obj *CONST objv[] 1232 ){ 1233 sqlite *db; 1234 const char *zErr; 1235 1236 if( objc!=2 ){ 1237 Tcl_AppendResult(interp, "wrong # args: should be \"", 1238 Tcl_GetString(objv[0]), " DB", 0); 1239 return TCL_ERROR; 1240 } 1241 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1242 1243 zErr = sqlite3_errmsg(db); 1244 Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1)); 1245 return TCL_OK; 1246 } 1247 1248 /* 1249 ** Usage: test_errmsg16 DB 1250 ** 1251 ** Returns the UTF-16 representation of the error message string for the 1252 ** most recent sqlite3_* API call. This is a byte array object at the TCL 1253 ** level, and it includes the 0x00 0x00 terminator bytes at the end of the 1254 ** UTF-16 string. 1255 */ 1256 static int test_errmsg16( 1257 void * clientData, 1258 Tcl_Interp *interp, 1259 int objc, 1260 Tcl_Obj *CONST objv[] 1261 ){ 1262 sqlite *db; 1263 const void *zErr; 1264 int bytes; 1265 1266 if( objc!=2 ){ 1267 Tcl_AppendResult(interp, "wrong # args: should be \"", 1268 Tcl_GetString(objv[0]), " DB", 0); 1269 return TCL_ERROR; 1270 } 1271 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1272 1273 zErr = sqlite3_errmsg16(db); 1274 bytes = sqlite3utf16ByteLen(zErr, -1); 1275 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(zErr, bytes)); 1276 return TCL_OK; 1277 } 1278 1279 /* 1280 ** Usage: sqlite3_prepare DB sql bytes tailvar 1281 ** 1282 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using 1283 ** database handle <DB>. The parameter <tailval> is the name of a global 1284 ** variable that is set to the unused portion of <sql> (if any). A 1285 ** STMT handle is returned. 1286 */ 1287 static int test_prepare( 1288 void * clientData, 1289 Tcl_Interp *interp, 1290 int objc, 1291 Tcl_Obj *CONST objv[] 1292 ){ 1293 sqlite3 *db; 1294 const char *zSql; 1295 int bytes; 1296 const char *zTail = 0; 1297 sqlite3_stmt *pStmt = 0; 1298 char zBuf[50]; 1299 int rc; 1300 1301 if( objc!=5 ){ 1302 Tcl_AppendResult(interp, "wrong # args: should be \"", 1303 Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); 1304 return TCL_ERROR; 1305 } 1306 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1307 zSql = Tcl_GetString(objv[2]); 1308 if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; 1309 1310 rc = sqlite3_prepare(db, zSql, bytes, &pStmt, &zTail); 1311 if( zTail ){ 1312 if( bytes>=0 ){ 1313 bytes = bytes - (zTail-zSql); 1314 } 1315 Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0); 1316 } 1317 if( rc!=SQLITE_OK ){ 1318 assert( pStmt==0 ); 1319 sprintf(zBuf, "(%d) ", rc); 1320 Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0); 1321 return TCL_ERROR; 1322 } 1323 1324 if( pStmt ){ 1325 if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; 1326 Tcl_AppendResult(interp, zBuf, 0); 1327 } 1328 return TCL_OK; 1329 } 1330 1331 /* 1332 ** Usage: sqlite3_prepare DB sql bytes tailvar 1333 ** 1334 ** Compile up to <bytes> bytes of the supplied SQL string <sql> using 1335 ** database handle <DB>. The parameter <tailval> is the name of a global 1336 ** variable that is set to the unused portion of <sql> (if any). A 1337 ** STMT handle is returned. 1338 */ 1339 static int test_prepare16( 1340 void * clientData, 1341 Tcl_Interp *interp, 1342 int objc, 1343 Tcl_Obj *CONST objv[] 1344 ){ 1345 sqlite3 *db; 1346 const void *zSql; 1347 const void *zTail = 0; 1348 Tcl_Obj *pTail = 0; 1349 sqlite3_stmt *pStmt = 0; 1350 char zBuf[50]; 1351 int bytes; /* The integer specified as arg 3 */ 1352 int objlen; /* The byte-array length of arg 2 */ 1353 1354 if( objc!=5 ){ 1355 Tcl_AppendResult(interp, "wrong # args: should be \"", 1356 Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0); 1357 return TCL_ERROR; 1358 } 1359 if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 1360 zSql = Tcl_GetByteArrayFromObj(objv[2], &objlen); 1361 if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR; 1362 1363 if( SQLITE_OK!=sqlite3_prepare16(db, zSql, bytes, &pStmt, &zTail) ){ 1364 return TCL_ERROR; 1365 } 1366 1367 if( zTail ){ 1368 objlen = objlen - ((u8 *)zTail-(u8 *)zSql); 1369 }else{ 1370 objlen = 0; 1371 } 1372 pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen); 1373 Tcl_IncrRefCount(pTail); 1374 Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0); 1375 Tcl_DecrRefCount(pTail); 1376 1377 if( pStmt ){ 1378 if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR; 1379 } 1380 Tcl_AppendResult(interp, zBuf, 0); 1381 return TCL_OK; 1382 } 1383 1384 /* 1385 ** Usage: sqlite3_open filename ?options-list? 1386 */ 1387 static int test_open( 1388 void * clientData, 1389 Tcl_Interp *interp, 1390 int objc, 1391 Tcl_Obj *CONST objv[] 1392 ){ 1393 const char *zFilename; 1394 sqlite3 *db; 1395 int rc; 1396 char zBuf[100]; 1397 1398 if( objc!=3 && objc!=2 ){ 1399 Tcl_AppendResult(interp, "wrong # args: should be \"", 1400 Tcl_GetString(objv[0]), " filename options-list", 0); 1401 return TCL_ERROR; 1402 } 1403 1404 zFilename = Tcl_GetString(objv[1]); 1405 rc = sqlite3_open(zFilename, &db); 1406 1407 if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR; 1408 Tcl_AppendResult(interp, zBuf, 0); 1409 return TCL_OK; 1410 } 1411 1412 /* 1413 ** Usage: sqlite3_open16 filename options 1414 */ 1415 static int test_open16( 1416 void * clientData, 1417 Tcl_Interp *interp, 1418 int objc, 1419 Tcl_Obj *CONST objv[] 1420 ){ 1421 const void *zFilename; 1422 sqlite3 *db; 1423 int rc; 1424 char zBuf[100]; 1425 1426 if( objc!=3 ){ 1427 Tcl_AppendResult(interp, "wrong # args: should be \"", 1428 Tcl_GetString(objv[0]), " filename options-list", 0); 1429 return TCL_ERROR; 1430 } 1431 1432 zFilename = Tcl_GetByteArrayFromObj(objv[1], 0); 1433 rc = sqlite3_open16(zFilename, &db); 1434 1435 if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR; 1436 Tcl_AppendResult(interp, zBuf, 0); 1437 return TCL_OK; 1438 } 1439 1440 /* 1441 ** Usage: sqlite3_step STMT 1442 ** 1443 ** Advance the statement to the next row. 1444 */ 1445 static int test_step( 1446 void * clientData, 1447 Tcl_Interp *interp, 1448 int objc, 1449 Tcl_Obj *CONST objv[] 1450 ){ 1451 sqlite3_stmt *pStmt; 1452 int rc; 1453 1454 if( objc!=2 ){ 1455 Tcl_AppendResult(interp, "wrong # args: should be \"", 1456 Tcl_GetString(objv[0]), " STMT", 0); 1457 return TCL_ERROR; 1458 } 1459 1460 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1461 rc = sqlite3_step(pStmt); 1462 1463 if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL_ERROR; 1464 Tcl_SetResult(interp, (char *)errorName(rc), 0); 1465 return TCL_OK; 1466 } 1467 1468 /* 1469 ** Usage: sqlite3_column_count STMT 1470 ** 1471 ** Return the number of columns returned by the sql statement STMT. 1472 */ 1473 static int test_column_count( 1474 void * clientData, 1475 Tcl_Interp *interp, 1476 int objc, 1477 Tcl_Obj *CONST objv[] 1478 ){ 1479 sqlite3_stmt *pStmt; 1480 1481 if( objc!=2 ){ 1482 Tcl_AppendResult(interp, "wrong # args: should be \"", 1483 Tcl_GetString(objv[0]), " STMT column", 0); 1484 return TCL_ERROR; 1485 } 1486 1487 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1488 1489 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_column_count(pStmt))); 1490 return TCL_OK; 1491 } 1492 1493 /* 1494 ** Usage: sqlite3_column_type STMT column 1495 ** 1496 ** Return the type of the data in column 'column' of the current row. 1497 */ 1498 static int test_column_type( 1499 void * clientData, 1500 Tcl_Interp *interp, 1501 int objc, 1502 Tcl_Obj *CONST objv[] 1503 ){ 1504 sqlite3_stmt *pStmt; 1505 int col; 1506 int tp; 1507 1508 if( objc!=3 ){ 1509 Tcl_AppendResult(interp, "wrong # args: should be \"", 1510 Tcl_GetString(objv[0]), " STMT column", 0); 1511 return TCL_ERROR; 1512 } 1513 1514 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1515 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 1516 1517 tp = sqlite3_column_type(pStmt, col); 1518 switch( tp ){ 1519 case SQLITE_INTEGER: 1520 Tcl_SetResult(interp, "INTEGER", TCL_STATIC); 1521 break; 1522 case SQLITE_NULL: 1523 Tcl_SetResult(interp, "NULL", TCL_STATIC); 1524 break; 1525 case SQLITE_FLOAT: 1526 Tcl_SetResult(interp, "FLOAT", TCL_STATIC); 1527 break; 1528 case SQLITE_TEXT: 1529 Tcl_SetResult(interp, "TEXT", TCL_STATIC); 1530 break; 1531 case SQLITE_BLOB: 1532 Tcl_SetResult(interp, "BLOB", TCL_STATIC); 1533 break; 1534 default: 1535 assert(0); 1536 } 1537 1538 return TCL_OK; 1539 } 1540 1541 /* 1542 ** Usage: sqlite3_column_int64 STMT column 1543 ** 1544 ** Return the data in column 'column' of the current row cast as an 1545 ** wide (64-bit) integer. 1546 */ 1547 static int test_column_int64( 1548 void * clientData, 1549 Tcl_Interp *interp, 1550 int objc, 1551 Tcl_Obj *CONST objv[] 1552 ){ 1553 sqlite3_stmt *pStmt; 1554 int col; 1555 i64 iVal; 1556 1557 if( objc!=3 ){ 1558 Tcl_AppendResult(interp, "wrong # args: should be \"", 1559 Tcl_GetString(objv[0]), " STMT column", 0); 1560 return TCL_ERROR; 1561 } 1562 1563 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1564 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 1565 1566 iVal = sqlite3_column_int64(pStmt, col); 1567 Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iVal)); 1568 return TCL_OK; 1569 } 1570 1571 /* 1572 ** Usage: sqlite3_column_blob STMT column 1573 */ 1574 static int test_column_blob( 1575 void * clientData, 1576 Tcl_Interp *interp, 1577 int objc, 1578 Tcl_Obj *CONST objv[] 1579 ){ 1580 sqlite3_stmt *pStmt; 1581 int col; 1582 1583 int len; 1584 const void *pBlob; 1585 1586 if( objc!=3 ){ 1587 Tcl_AppendResult(interp, "wrong # args: should be \"", 1588 Tcl_GetString(objv[0]), " STMT column", 0); 1589 return TCL_ERROR; 1590 } 1591 1592 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1593 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 1594 1595 pBlob = sqlite3_column_blob(pStmt, col); 1596 len = sqlite3_column_bytes(pStmt, col); 1597 Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBlob, len)); 1598 return TCL_OK; 1599 } 1600 1601 /* 1602 ** Usage: sqlite3_column_double STMT column 1603 ** 1604 ** Return the data in column 'column' of the current row cast as a double. 1605 */ 1606 static int test_column_double( 1607 void * clientData, 1608 Tcl_Interp *interp, 1609 int objc, 1610 Tcl_Obj *CONST objv[] 1611 ){ 1612 sqlite3_stmt *pStmt; 1613 int col; 1614 double rVal; 1615 1616 if( objc!=3 ){ 1617 Tcl_AppendResult(interp, "wrong # args: should be \"", 1618 Tcl_GetString(objv[0]), " STMT column", 0); 1619 return TCL_ERROR; 1620 } 1621 1622 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1623 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 1624 1625 rVal = sqlite3_column_double(pStmt, col); 1626 Tcl_SetObjResult(interp, Tcl_NewDoubleObj(rVal)); 1627 return TCL_OK; 1628 } 1629 1630 /* 1631 ** Usage: sqlite3_data_count STMT 1632 ** 1633 ** Return the number of columns returned by the sql statement STMT. 1634 */ 1635 static int test_data_count( 1636 void * clientData, 1637 Tcl_Interp *interp, 1638 int objc, 1639 Tcl_Obj *CONST objv[] 1640 ){ 1641 sqlite3_stmt *pStmt; 1642 1643 if( objc!=2 ){ 1644 Tcl_AppendResult(interp, "wrong # args: should be \"", 1645 Tcl_GetString(objv[0]), " STMT column", 0); 1646 return TCL_ERROR; 1647 } 1648 1649 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1650 1651 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_data_count(pStmt))); 1652 return TCL_OK; 1653 } 1654 1655 /* 1656 ** Usage: sqlite3_column_text STMT column 1657 ** 1658 ** Usage: sqlite3_column_decltype STMT column 1659 ** 1660 ** Usage: sqlite3_column_name STMT column 1661 */ 1662 static int test_stmt_utf8( 1663 void * clientData, 1664 Tcl_Interp *interp, 1665 int objc, 1666 Tcl_Obj *CONST objv[] 1667 ){ 1668 sqlite3_stmt *pStmt; 1669 int col; 1670 const char *(*xFunc)(sqlite3_stmt*, int) = clientData; 1671 const char *zRet; 1672 1673 if( objc!=3 ){ 1674 Tcl_AppendResult(interp, "wrong # args: should be \"", 1675 Tcl_GetString(objv[0]), " STMT column", 0); 1676 return TCL_ERROR; 1677 } 1678 1679 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1680 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 1681 zRet = xFunc(pStmt, col); 1682 if( zRet ){ 1683 Tcl_SetResult(interp, (char *)zRet, 0); 1684 } 1685 return TCL_OK; 1686 } 1687 1688 /* 1689 ** Usage: sqlite3_column_text STMT column 1690 ** 1691 ** Usage: sqlite3_column_decltype STMT column 1692 ** 1693 ** Usage: sqlite3_column_name STMT column 1694 */ 1695 static int test_stmt_utf16( 1696 void * clientData, 1697 Tcl_Interp *interp, 1698 int objc, 1699 Tcl_Obj *CONST objv[] 1700 ){ 1701 sqlite3_stmt *pStmt; 1702 int col; 1703 Tcl_Obj *pRet; 1704 const void *zName16; 1705 const void *(*xFunc)(sqlite3_stmt*, int) = clientData; 1706 1707 if( objc!=3 ){ 1708 Tcl_AppendResult(interp, "wrong # args: should be \"", 1709 Tcl_GetString(objv[0]), " STMT column", 0); 1710 return TCL_ERROR; 1711 } 1712 1713 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1714 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 1715 1716 zName16 = xFunc(pStmt, col); 1717 if( zName16 ){ 1718 pRet = Tcl_NewByteArrayObj(zName16, sqlite3utf16ByteLen(zName16, -1)+2); 1719 Tcl_SetObjResult(interp, pRet); 1720 } 1721 1722 return TCL_OK; 1723 } 1724 1725 /* 1726 ** Usage: sqlite3_column_int STMT column 1727 ** 1728 ** Usage: sqlite3_column_bytes STMT column 1729 ** 1730 ** Usage: sqlite3_column_bytes16 STMT column 1731 ** 1732 */ 1733 static int test_stmt_int( 1734 void * clientData, 1735 Tcl_Interp *interp, 1736 int objc, 1737 Tcl_Obj *CONST objv[] 1738 ){ 1739 sqlite3_stmt *pStmt; 1740 int col; 1741 int (*xFunc)(sqlite3_stmt*, int) = clientData; 1742 1743 if( objc!=3 ){ 1744 Tcl_AppendResult(interp, "wrong # args: should be \"", 1745 Tcl_GetString(objv[0]), " STMT column", 0); 1746 return TCL_ERROR; 1747 } 1748 1749 if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; 1750 if( Tcl_GetIntFromObj(interp, objv[2], &col) ) return TCL_ERROR; 1751 1752 Tcl_SetObjResult(interp, Tcl_NewIntObj(xFunc(pStmt, col))); 1753 return TCL_OK; 1754 } 1755 1756 /* 1757 ** Usage: sqlite3OsOpenReadWrite <filename> 1758 */ 1759 static int test_sqlite3OsOpenReadWrite( 1760 void * clientData, 1761 Tcl_Interp *interp, 1762 int objc, 1763 Tcl_Obj *CONST objv[] 1764 ){ 1765 OsFile * pFile; 1766 int rc; 1767 int dummy; 1768 char zBuf[100]; 1769 1770 if( objc!=2 ){ 1771 Tcl_AppendResult(interp, "wrong # args: should be \"", 1772 Tcl_GetString(objv[0]), " filename", 0); 1773 return TCL_ERROR; 1774 } 1775 1776 pFile = sqliteMalloc(sizeof(OsFile)); 1777 rc = sqlite3OsOpenReadWrite(Tcl_GetString(objv[1]), pFile, &dummy); 1778 if( rc!=SQLITE_OK ){ 1779 sqliteFree(pFile); 1780 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 1781 return TCL_ERROR; 1782 } 1783 makePointerStr(interp, zBuf, pFile); 1784 Tcl_SetResult(interp, zBuf, 0); 1785 return TCL_ERROR; 1786 } 1787 1788 /* 1789 ** Usage: sqlite3OsClose <file handle> 1790 */ 1791 static int test_sqlite3OsClose( 1792 void * clientData, 1793 Tcl_Interp *interp, 1794 int objc, 1795 Tcl_Obj *CONST objv[] 1796 ){ 1797 OsFile * pFile; 1798 int rc; 1799 1800 if( objc!=2 ){ 1801 Tcl_AppendResult(interp, "wrong # args: should be \"", 1802 Tcl_GetString(objv[0]), " filehandle", 0); 1803 return TCL_ERROR; 1804 } 1805 1806 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 1807 return TCL_ERROR; 1808 } 1809 rc = sqlite3OsClose(pFile); 1810 if( rc!=SQLITE_OK ){ 1811 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 1812 return TCL_ERROR; 1813 } 1814 sqliteFree(pFile); 1815 return TCL_OK; 1816 } 1817 1818 /* 1819 ** Usage: sqlite3OsLock <file handle> <locktype> 1820 */ 1821 static int test_sqlite3OsLock( 1822 void * clientData, 1823 Tcl_Interp *interp, 1824 int objc, 1825 Tcl_Obj *CONST objv[] 1826 ){ 1827 OsFile * pFile; 1828 int rc; 1829 1830 if( objc!=3 ){ 1831 Tcl_AppendResult(interp, "wrong # args: should be \"", 1832 Tcl_GetString(objv[0]), 1833 " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0); 1834 return TCL_ERROR; 1835 } 1836 1837 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 1838 return TCL_ERROR; 1839 } 1840 1841 if( 0==strcmp("SHARED", Tcl_GetString(objv[2])) ){ 1842 rc = sqlite3OsLock(pFile, SHARED_LOCK); 1843 } 1844 else if( 0==strcmp("RESERVED", Tcl_GetString(objv[2])) ){ 1845 rc = sqlite3OsLock(pFile, RESERVED_LOCK); 1846 } 1847 else if( 0==strcmp("PENDING", Tcl_GetString(objv[2])) ){ 1848 rc = sqlite3OsLock(pFile, PENDING_LOCK); 1849 } 1850 else if( 0==strcmp("EXCLUSIVE", Tcl_GetString(objv[2])) ){ 1851 rc = sqlite3OsLock(pFile, EXCLUSIVE_LOCK); 1852 }else{ 1853 Tcl_AppendResult(interp, "wrong # args: should be \"", 1854 Tcl_GetString(objv[0]), 1855 " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0); 1856 return TCL_ERROR; 1857 } 1858 1859 if( rc!=SQLITE_OK ){ 1860 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 1861 return TCL_ERROR; 1862 } 1863 return TCL_OK; 1864 } 1865 1866 /* 1867 ** Usage: sqlite3OsUnlock <file handle> 1868 */ 1869 static int test_sqlite3OsUnlock( 1870 void * clientData, 1871 Tcl_Interp *interp, 1872 int objc, 1873 Tcl_Obj *CONST objv[] 1874 ){ 1875 OsFile * pFile; 1876 int rc; 1877 1878 if( objc!=2 ){ 1879 Tcl_AppendResult(interp, "wrong # args: should be \"", 1880 Tcl_GetString(objv[0]), " filehandle", 0); 1881 return TCL_ERROR; 1882 } 1883 1884 if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){ 1885 return TCL_ERROR; 1886 } 1887 rc = sqlite3OsUnlock(pFile, NO_LOCK); 1888 if( rc!=SQLITE_OK ){ 1889 Tcl_SetResult(interp, (char *)errorName(rc), TCL_STATIC); 1890 return TCL_ERROR; 1891 } 1892 return TCL_OK; 1893 } 1894 1895 /* 1896 ** Register commands with the TCL interpreter. 1897 */ 1898 int Sqlitetest1_Init(Tcl_Interp *interp){ 1899 extern int sqlite3_search_count; 1900 extern int sqlite3_interrupt_count; 1901 extern int sqlite3_open_file_count; 1902 extern int sqlite3_current_time; 1903 static struct { 1904 char *zName; 1905 Tcl_CmdProc *xProc; 1906 } aCmd[] = { 1907 { "sqlite3_mprintf_int", (Tcl_CmdProc*)sqlite3_mprintf_int }, 1908 { "sqlite3_mprintf_str", (Tcl_CmdProc*)sqlite3_mprintf_str }, 1909 { "sqlite3_mprintf_double", (Tcl_CmdProc*)sqlite3_mprintf_double }, 1910 { "sqlite3_mprintf_scaled", (Tcl_CmdProc*)sqlite3_mprintf_scaled }, 1911 { "sqlite3_mprintf_z_test", (Tcl_CmdProc*)test_mprintf_z }, 1912 { "sqlite3_last_insert_rowid", (Tcl_CmdProc*)test_last_rowid }, 1913 { "sqlite3_exec_printf", (Tcl_CmdProc*)test_exec_printf }, 1914 { "sqlite3_get_table_printf", (Tcl_CmdProc*)test_get_table_printf }, 1915 { "sqlite3_close", (Tcl_CmdProc*)sqlite_test_close }, 1916 { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, 1917 { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, 1918 { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, 1919 { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, 1920 #ifdef SQLITE_DEBUG 1921 { "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail }, 1922 { "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat }, 1923 #endif 1924 { "sqlite_bind", (Tcl_CmdProc*)test_bind }, 1925 { "breakpoint", (Tcl_CmdProc*)test_breakpoint }, 1926 }; 1927 static struct { 1928 char *zName; 1929 Tcl_ObjCmdProc *xProc; 1930 void *clientData; 1931 } aObjCmd[] = { 1932 { "sqlite3_bind_int32", test_bind_int32, 0 }, 1933 { "sqlite3_bind_int64", test_bind_int64 , 0 }, 1934 { "sqlite3_bind_double", test_bind_double, 0 }, 1935 { "sqlite3_bind_null", test_bind_null ,0 }, 1936 { "sqlite3_bind_text", test_bind_text ,0 }, 1937 { "sqlite3_bind_text16", test_bind_text16 ,0 }, 1938 { "sqlite3_bind_blob", test_bind_blob ,0 }, 1939 { "sqlite3_errcode", test_errcode ,0 }, 1940 { "sqlite3_errmsg", test_errmsg ,0 }, 1941 { "sqlite3_errmsg16", test_errmsg16 ,0 }, 1942 { "sqlite3_open", test_open ,0 }, 1943 { "sqlite3_open16", test_open16 ,0 }, 1944 1945 { "sqlite3_prepare", test_prepare ,0 }, 1946 { "sqlite3_prepare16", test_prepare16 ,0 }, 1947 { "sqlite3_finalize", test_finalize ,0 }, 1948 { "sqlite3_reset", test_reset ,0 }, 1949 { "sqlite3_step", test_step,0 }, 1950 1951 /* sqlite3_column_*() API */ 1952 { "sqlite3_column_count", test_column_count ,0 }, 1953 { "sqlite3_data_count", test_data_count ,0 }, 1954 { "sqlite3_column_type", test_column_type ,0 }, 1955 { "sqlite3_column_blob", test_column_blob ,0 }, 1956 { "sqlite3_column_double", test_column_double ,0 }, 1957 { "sqlite3_column_int64", test_column_int64 ,0 }, 1958 { "sqlite3_column_int", test_stmt_int ,sqlite3_column_int }, 1959 { "sqlite3_column_bytes", test_stmt_int ,sqlite3_column_bytes }, 1960 { "sqlite3_column_bytes16", test_stmt_int ,sqlite3_column_bytes16 }, 1961 { "sqlite3_column_text", test_stmt_utf8, sqlite3_column_text}, 1962 { "sqlite3_column_decltype", test_stmt_utf8, sqlite3_column_decltype}, 1963 { "sqlite3_column_name", test_stmt_utf8, sqlite3_column_name}, 1964 { "sqlite3_column_text16", test_stmt_utf16, sqlite3_column_text16}, 1965 { "sqlite3_column_decltype16", test_stmt_utf16,sqlite3_column_decltype16}, 1966 { "sqlite3_column_name16", test_stmt_utf16, sqlite3_column_name16}, 1967 1968 /* Functions from os.h */ 1969 { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 }, 1970 { "sqlite3OsClose", test_sqlite3OsClose, 0 }, 1971 { "sqlite3OsLock", test_sqlite3OsLock, 0 }, 1972 { "sqlite3OsUnlock", test_sqlite3OsUnlock, 0 }, 1973 { "add_test_collate", test_collate, 0 }, 1974 1975 }; 1976 int i; 1977 extern int sqlite3_os_trace; 1978 1979 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){ 1980 Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0); 1981 } 1982 for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ 1983 Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 1984 aObjCmd[i].xProc, aObjCmd[i].clientData, 0); 1985 } 1986 Tcl_LinkVar(interp, "sqlite_search_count", 1987 (char*)&sqlite3_search_count, TCL_LINK_INT); 1988 Tcl_LinkVar(interp, "sqlite_interrupt_count", 1989 (char*)&sqlite3_interrupt_count, TCL_LINK_INT); 1990 Tcl_LinkVar(interp, "sqlite_open_file_count", 1991 (char*)&sqlite3_open_file_count, TCL_LINK_INT); 1992 Tcl_LinkVar(interp, "sqlite_current_time", 1993 (char*)&sqlite3_current_time, TCL_LINK_INT); 1994 Tcl_LinkVar(interp, "sqlite_os_trace", 1995 (char*)&sqlite3_os_trace, TCL_LINK_INT); 1996 Tcl_LinkVar(interp, "sqlite_static_bind_value", 1997 (char*)&sqlite_static_bind_value, TCL_LINK_STRING); 1998 return TCL_OK; 1999 } 2000