00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "sqliteInt.h"
00019 #include "tcl.h"
00020 #include "os.h"
00021 #include <stdlib.h>
00022 #include <string.h>
00023
00024 #if OS_WIN
00025 # define PTR_FMT "%x"
00026 #else
00027 # define PTR_FMT "%p"
00028 #endif
00029
00030
00031
00032
00033 static int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite **ppDb){
00034 if( sscanf(zA, PTR_FMT, (void**)ppDb)!=1 &&
00035 (zA[0]!='0' || zA[1]!='x' || sscanf(&zA[2], PTR_FMT, (void**)ppDb)!=1)
00036 ){
00037 Tcl_AppendResult(interp, "\"", zA, "\" is not a valid pointer value", 0);
00038 return TCL_ERROR;
00039 }
00040 return TCL_OK;
00041 }
00042
00043
00044
00045
00046 static int getVmPointer(Tcl_Interp *interp, const char *zArg, sqlite_vm **ppVm){
00047 if( sscanf(zArg, PTR_FMT, (void**)ppVm)!=1 ){
00048 Tcl_AppendResult(interp, "\"", zArg, "\" is not a valid pointer value", 0);
00049 return TCL_ERROR;
00050 }
00051 return TCL_OK;
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 static int makePointerStr(Tcl_Interp *interp, char *zPtr, void *p){
00068 void *p2;
00069 sprintf(zPtr, PTR_FMT, p);
00070 if( sscanf(zPtr, PTR_FMT, &p2)!=1 || p2!=p ){
00071 sprintf(zPtr, "0x" PTR_FMT, p);
00072 if( sscanf(zPtr, PTR_FMT, &p2)!=1 || p2!=p ){
00073 Tcl_AppendResult(interp, "unable to convert a pointer to a string "
00074 "in the file " __FILE__ " in function makePointerStr(). Please "
00075 "report this problem to the SQLite mailing list or as a new but "
00076 "report. Please provide detailed information about how you compiled "
00077 "SQLite and what computer you are running on.", 0);
00078 return TCL_ERROR;
00079 }
00080 }
00081 return TCL_OK;
00082 }
00083
00084
00085
00086
00087
00088
00089 static int sqlite_test_open(
00090 void *NotUsed,
00091 Tcl_Interp *interp,
00092 int argc,
00093 char **argv
00094 ){
00095 sqlite *db;
00096 char *zErr = 0;
00097 char zBuf[100];
00098 if( argc!=2 ){
00099 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00100 " FILENAME\"", 0);
00101 return TCL_ERROR;
00102 }
00103 db = sqlite_open(argv[1], 0666, &zErr);
00104 if( db==0 ){
00105 Tcl_AppendResult(interp, zErr, 0);
00106 free(zErr);
00107 return TCL_ERROR;
00108 }
00109 if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR;
00110 Tcl_AppendResult(interp, zBuf, 0);
00111 return TCL_OK;
00112 }
00113
00114
00115
00116
00117 static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){
00118 Tcl_DString *str = (Tcl_DString*)pArg;
00119 int i;
00120
00121 if( Tcl_DStringLength(str)==0 ){
00122 for(i=0; i<argc; i++){
00123 Tcl_DStringAppendElement(str, name[i] ? name[i] : "NULL");
00124 }
00125 }
00126 for(i=0; i<argc; i++){
00127 Tcl_DStringAppendElement(str, argv[i] ? argv[i] : "NULL");
00128 }
00129 return 0;
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139 static int test_exec_printf(
00140 void *NotUsed,
00141 Tcl_Interp *interp,
00142 int argc,
00143 char **argv
00144 ){
00145 sqlite *db;
00146 Tcl_DString str;
00147 int rc;
00148 char *zErr = 0;
00149 char zBuf[30];
00150 if( argc!=4 ){
00151 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00152 " DB FORMAT STRING", 0);
00153 return TCL_ERROR;
00154 }
00155 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
00156 Tcl_DStringInit(&str);
00157 rc = sqlite_exec_printf(db, argv[2], exec_printf_cb, &str, &zErr, argv[3]);
00158 sprintf(zBuf, "%d", rc);
00159 Tcl_AppendElement(interp, zBuf);
00160 Tcl_AppendElement(interp, rc==SQLITE_OK ? Tcl_DStringValue(&str) : zErr);
00161 Tcl_DStringFree(&str);
00162 if( zErr ) free(zErr);
00163 return TCL_OK;
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173 static int test_mprintf_z(
00174 void *NotUsed,
00175 Tcl_Interp *interp,
00176 int argc,
00177 char **argv
00178 ){
00179 char *zResult = 0;
00180 int i;
00181
00182 for(i=2; i<argc; i++){
00183 zResult = sqliteMPrintf("%z%s%s", zResult, argv[1], argv[i]);
00184 }
00185 Tcl_AppendResult(interp, zResult, 0);
00186 sqliteFree(zResult);
00187 return TCL_OK;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197 static int test_get_table_printf(
00198 void *NotUsed,
00199 Tcl_Interp *interp,
00200 int argc,
00201 char **argv
00202 ){
00203 sqlite *db;
00204 Tcl_DString str;
00205 int rc;
00206 char *zErr = 0;
00207 int nRow, nCol;
00208 char **aResult;
00209 int i;
00210 char zBuf[30];
00211 if( argc!=4 ){
00212 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00213 " DB FORMAT STRING", 0);
00214 return TCL_ERROR;
00215 }
00216 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
00217 Tcl_DStringInit(&str);
00218 rc = sqlite_get_table_printf(db, argv[2], &aResult, &nRow, &nCol,
00219 &zErr, argv[3]);
00220 sprintf(zBuf, "%d", rc);
00221 Tcl_AppendElement(interp, zBuf);
00222 if( rc==SQLITE_OK ){
00223 sprintf(zBuf, "%d", nRow);
00224 Tcl_AppendElement(interp, zBuf);
00225 sprintf(zBuf, "%d", nCol);
00226 Tcl_AppendElement(interp, zBuf);
00227 for(i=0; i<(nRow+1)*nCol; i++){
00228 Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL");
00229 }
00230 }else{
00231 Tcl_AppendElement(interp, zErr);
00232 }
00233 sqlite_free_table(aResult);
00234 if( zErr ) free(zErr);
00235 return TCL_OK;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244 static int test_last_rowid(
00245 void *NotUsed,
00246 Tcl_Interp *interp,
00247 int argc,
00248 char **argv
00249 ){
00250 sqlite *db;
00251 char zBuf[30];
00252
00253 if( argc!=2 ){
00254 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"", 0);
00255 return TCL_ERROR;
00256 }
00257 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
00258 sprintf(zBuf, "%d", sqlite_last_insert_rowid(db));
00259 Tcl_AppendResult(interp, zBuf, 0);
00260 return SQLITE_OK;
00261 }
00262
00263
00264
00265
00266
00267
00268 static int sqlite_test_close(
00269 void *NotUsed,
00270 Tcl_Interp *interp,
00271 int argc,
00272 char **argv
00273 ){
00274 sqlite *db;
00275 if( argc!=2 ){
00276 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00277 " FILENAME\"", 0);
00278 return TCL_ERROR;
00279 }
00280 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
00281 sqlite_close(db);
00282 return TCL_OK;
00283 }
00284
00285
00286
00287
00288
00289 static void ifnullFunc(sqlite_func *context, int argc, const char **argv){
00290 int i;
00291 for(i=0; i<argc; i++){
00292 if( argv[i] ){
00293 sqlite_set_result_string(context, argv[i], -1);
00294 break;
00295 }
00296 }
00297 }
00298
00299
00300
00301
00302 struct dstr {
00303 int nAlloc;
00304 int nUsed;
00305 char *z;
00306 };
00307
00308
00309
00310
00311 static void dstrAppend(struct dstr *p, const char *z, int divider){
00312 int n = strlen(z);
00313 if( p->nUsed + n + 2 > p->nAlloc ){
00314 char *zNew;
00315 p->nAlloc = p->nAlloc*2 + n + 200;
00316 zNew = sqliteRealloc(p->z, p->nAlloc);
00317 if( zNew==0 ){
00318 sqliteFree(p->z);
00319 memset(p, 0, sizeof(*p));
00320 return;
00321 }
00322 p->z = zNew;
00323 }
00324 if( divider && p->nUsed>0 ){
00325 p->z[p->nUsed++] = divider;
00326 }
00327 memcpy(&p->z[p->nUsed], z, n+1);
00328 p->nUsed += n;
00329 }
00330
00331
00332
00333
00334 static int execFuncCallback(void *pData, int argc, char **argv, char **NotUsed){
00335 struct dstr *p = (struct dstr*)pData;
00336 int i;
00337 for(i=0; i<argc; i++){
00338 if( argv[i]==0 ){
00339 dstrAppend(p, "NULL", ' ');
00340 }else{
00341 dstrAppend(p, argv[i], ' ');
00342 }
00343 }
00344 return 0;
00345 }
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 static void sqliteExecFunc(sqlite_func *context, int argc, const char **argv){
00359 struct dstr x;
00360 memset(&x, 0, sizeof(x));
00361 sqlite_exec((sqlite*)sqlite_user_data(context), argv[0],
00362 execFuncCallback, &x, 0);
00363 sqlite_set_result_string(context, x.z, x.nUsed);
00364 sqliteFree(x.z);
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 static int test_create_function(
00383 void *NotUsed,
00384 Tcl_Interp *interp,
00385 int argc,
00386 char **argv
00387 ){
00388 sqlite *db;
00389 extern void Md5_Register(sqlite*);
00390 if( argc!=2 ){
00391 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00392 " FILENAME\"", 0);
00393 return TCL_ERROR;
00394 }
00395 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
00396 sqlite_create_function(db, "x_coalesce", -1, ifnullFunc, 0);
00397 sqlite_create_function(db, "x_sqlite_exec", 1, sqliteExecFunc, db);
00398 return TCL_OK;
00399 }
00400
00401
00402
00403
00404 typedef struct CountCtx CountCtx;
00405 struct CountCtx {
00406 int n;
00407 };
00408 static void countStep(sqlite_func *context, int argc, const char **argv){
00409 CountCtx *p;
00410 p = sqlite_aggregate_context(context, sizeof(*p));
00411 if( (argc==0 || argv[0]) && p ){
00412 p->n++;
00413 }
00414 }
00415 static void countFinalize(sqlite_func *context){
00416 CountCtx *p;
00417 p = sqlite_aggregate_context(context, sizeof(*p));
00418 sqlite_set_result_int(context, p ? p->n : 0);
00419 }
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 static int test_create_aggregate(
00433 void *NotUsed,
00434 Tcl_Interp *interp,
00435 int argc,
00436 char **argv
00437 ){
00438 sqlite *db;
00439 if( argc!=2 ){
00440 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00441 " FILENAME\"", 0);
00442 return TCL_ERROR;
00443 }
00444 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
00445 sqlite_create_aggregate(db, "x_count", 0, countStep, countFinalize, 0);
00446 sqlite_create_aggregate(db, "x_count", 1, countStep, countFinalize, 0);
00447 return TCL_OK;
00448 }
00449
00450
00451
00452
00453
00454
00455
00456
00457 static int sqlite_mprintf_int(
00458 void *NotUsed,
00459 Tcl_Interp *interp,
00460 int argc,
00461 char **argv
00462 ){
00463 int a[3], i;
00464 char *z;
00465 if( argc!=5 ){
00466 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00467 " FORMAT INT INT INT\"", 0);
00468 return TCL_ERROR;
00469 }
00470 for(i=2; i<5; i++){
00471 if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
00472 }
00473 z = sqlite_mprintf(argv[1], a[0], a[1], a[2]);
00474 Tcl_AppendResult(interp, z, 0);
00475 sqlite_freemem(z);
00476 return TCL_OK;
00477 }
00478
00479
00480
00481
00482
00483
00484 static int sqlite_mprintf_str(
00485 void *NotUsed,
00486 Tcl_Interp *interp,
00487 int argc,
00488 char **argv
00489 ){
00490 int a[3], i;
00491 char *z;
00492 if( argc<4 || argc>5 ){
00493 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00494 " FORMAT INT INT ?STRING?\"", 0);
00495 return TCL_ERROR;
00496 }
00497 for(i=2; i<4; i++){
00498 if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
00499 }
00500 z = sqlite_mprintf(argv[1], a[0], a[1], argc>4 ? argv[4] : NULL);
00501 Tcl_AppendResult(interp, z, 0);
00502 sqlite_freemem(z);
00503 return TCL_OK;
00504 }
00505
00506
00507
00508
00509
00510
00511 static int sqlite_mprintf_double(
00512 void *NotUsed,
00513 Tcl_Interp *interp,
00514 int argc,
00515 char **argv
00516 ){
00517 int a[3], i;
00518 double r;
00519 char *z;
00520 if( argc!=5 ){
00521 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00522 " FORMAT INT INT STRING\"", 0);
00523 return TCL_ERROR;
00524 }
00525 for(i=2; i<4; i++){
00526 if( Tcl_GetInt(interp, argv[i], &a[i-2]) ) return TCL_ERROR;
00527 }
00528 if( Tcl_GetDouble(interp, argv[4], &r) ) return TCL_ERROR;
00529 z = sqlite_mprintf(argv[1], a[0], a[1], r);
00530 Tcl_AppendResult(interp, z, 0);
00531 sqlite_freemem(z);
00532 return TCL_OK;
00533 }
00534
00535
00536
00537
00538
00539
00540
00541
00542 static int sqlite_mprintf_scaled(
00543 void *NotUsed,
00544 Tcl_Interp *interp,
00545 int argc,
00546 char **argv
00547 ){
00548 int i;
00549 double r[2];
00550 char *z;
00551 if( argc!=4 ){
00552 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00553 " FORMAT DOUBLE DOUBLE\"", 0);
00554 return TCL_ERROR;
00555 }
00556 for(i=2; i<4; i++){
00557 if( Tcl_GetDouble(interp, argv[i], &r[i-2]) ) return TCL_ERROR;
00558 }
00559 z = sqlite_mprintf(argv[1], r[0]*r[1]);
00560 Tcl_AppendResult(interp, z, 0);
00561 sqlite_freemem(z);
00562 return TCL_OK;
00563 }
00564
00565
00566
00567
00568
00569
00570
00571 #ifdef MEMORY_DEBUG
00572 static int sqlite_malloc_fail(
00573 void *NotUsed,
00574 Tcl_Interp *interp,
00575 int argc,
00576 char **argv
00577 ){
00578 int n;
00579 if( argc!=2 ){
00580 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " N\"", 0);
00581 return TCL_ERROR;
00582 }
00583 if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
00584 sqlite_iMallocFail = n;
00585 sqlite_malloc_failed = 0;
00586 return TCL_OK;
00587 }
00588 #endif
00589
00590
00591
00592
00593
00594
00595 #ifdef MEMORY_DEBUG
00596 static int sqlite_malloc_stat(
00597 void *NotUsed,
00598 Tcl_Interp *interp,
00599 int argc,
00600 char **argv
00601 ){
00602 char zBuf[200];
00603 sprintf(zBuf, "%d %d %d", sqlite_nMalloc, sqlite_nFree, sqlite_iMallocFail);
00604 Tcl_AppendResult(interp, zBuf, 0);
00605 return TCL_OK;
00606 }
00607 #endif
00608
00609
00610
00611
00612
00613
00614
00615
00616 static int sqlite_abort(
00617 void *NotUsed,
00618 Tcl_Interp *interp,
00619 int argc,
00620 char **argv
00621 ){
00622 assert( interp==0 );
00623 return TCL_OK;
00624 }
00625
00626
00627
00628
00629
00630 static void testFunc(sqlite_func *context, int argc, const char **argv){
00631 while( argc>=2 ){
00632 if( argv[0]==0 ){
00633 sqlite_set_result_error(context, "first argument to test function "
00634 "may not be NULL", -1);
00635 }else if( sqliteStrICmp(argv[0],"string")==0 ){
00636 sqlite_set_result_string(context, argv[1], -1);
00637 }else if( argv[1]==0 ){
00638 sqlite_set_result_error(context, "2nd argument may not be NULL if the "
00639 "first argument is not \"string\"", -1);
00640 }else if( sqliteStrICmp(argv[0],"int")==0 ){
00641 sqlite_set_result_int(context, atoi(argv[1]));
00642 }else if( sqliteStrICmp(argv[0],"double")==0 ){
00643 sqlite_set_result_double(context, sqliteAtoF(argv[1], 0));
00644 }else{
00645 sqlite_set_result_error(context,"first argument should be one of: "
00646 "string int double", -1);
00647 }
00648 argc -= 2;
00649 argv += 2;
00650 }
00651 }
00652
00653
00654
00655
00656
00657
00658 static int test_register_func(
00659 void *NotUsed,
00660 Tcl_Interp *interp,
00661 int argc,
00662 char **argv
00663 ){
00664 sqlite *db;
00665 int rc;
00666 if( argc!=3 ){
00667 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00668 " DB FUNCTION-NAME", 0);
00669 return TCL_ERROR;
00670 }
00671 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
00672 rc = sqlite_create_function(db, argv[2], -1, testFunc, 0);
00673 if( rc!=0 ){
00674 Tcl_AppendResult(interp, sqlite_error_string(rc), 0);
00675 return TCL_ERROR;
00676 }
00677 return TCL_OK;
00678 }
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688 static int rememberDataTypes(void *pArg, int nCol, char **argv, char **colv){
00689 int i;
00690 Tcl_Interp *interp = (Tcl_Interp*)pArg;
00691 Tcl_Obj *pList, *pElem;
00692 if( colv[nCol+1]==0 ){
00693 return 1;
00694 }
00695 pList = Tcl_NewObj();
00696 for(i=0; i<nCol; i++){
00697 pElem = Tcl_NewStringObj(colv[i+nCol] ? colv[i+nCol] : "NULL", -1);
00698 Tcl_ListObjAppendElement(interp, pList, pElem);
00699 }
00700 Tcl_SetObjResult(interp, pList);
00701 return 1;
00702 }
00703
00704
00705
00706
00707
00708
00709
00710
00711 static int sqlite_datatypes(
00712 void *NotUsed,
00713 Tcl_Interp *interp,
00714 int argc,
00715 char **argv
00716 ){
00717 sqlite *db;
00718 int rc;
00719 if( argc!=3 ){
00720 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00721 " DB SQL", 0);
00722 return TCL_ERROR;
00723 }
00724 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
00725 rc = sqlite_exec(db, argv[2], rememberDataTypes, interp, 0);
00726 if( rc!=0 && rc!=SQLITE_ABORT ){
00727 Tcl_AppendResult(interp, sqlite_error_string(rc), 0);
00728 return TCL_ERROR;
00729 }
00730 return TCL_OK;
00731 }
00732
00733
00734
00735
00736
00737
00738
00739
00740 static int test_compile(
00741 void *NotUsed,
00742 Tcl_Interp *interp,
00743 int argc,
00744 char **argv
00745 ){
00746 sqlite *db;
00747 sqlite_vm *vm;
00748 int rc;
00749 char *zErr = 0;
00750 const char *zTail;
00751 char zBuf[50];
00752 if( argc!=3 && argc!=4 ){
00753 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00754 " DB SQL TAILVAR", 0);
00755 return TCL_ERROR;
00756 }
00757 if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
00758 rc = sqlite_compile(db, argv[2], argc==4 ? &zTail : 0, &vm, &zErr);
00759 if( argc==4 ) Tcl_SetVar(interp, argv[3], zTail, 0);
00760 if( rc ){
00761 assert( vm==0 );
00762 sprintf(zBuf, "(%d) ", rc);
00763 Tcl_AppendResult(interp, zBuf, zErr, 0);
00764 sqlite_freemem(zErr);
00765 return TCL_ERROR;
00766 }
00767 if( vm ){
00768 if( makePointerStr(interp, zBuf, vm) ) return TCL_ERROR;
00769 Tcl_AppendResult(interp, zBuf, 0);
00770 }
00771 return TCL_OK;
00772 }
00773
00774
00775
00776
00777
00778
00779
00780 static int test_step(
00781 void *NotUsed,
00782 Tcl_Interp *interp,
00783 int argc,
00784 char **argv
00785 ){
00786 sqlite_vm *vm;
00787 int rc, i;
00788 const char **azValue = 0;
00789 const char **azColName = 0;
00790 int N = 0;
00791 char *zRc;
00792 char zBuf[50];
00793 if( argc<2 || argc>5 ){
00794 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00795 " VM NVAR VALUEVAR COLNAMEVAR", 0);
00796 return TCL_ERROR;
00797 }
00798 if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR;
00799 rc = sqlite_step(vm, argc>=3?&N:0, argc>=4?&azValue:0, argc==5?&azColName:0);
00800 if( argc>=3 ){
00801 sprintf(zBuf, "%d", N);
00802 Tcl_SetVar(interp, argv[2], zBuf, 0);
00803 }
00804 if( argc>=4 ){
00805 Tcl_SetVar(interp, argv[3], "", 0);
00806 if( azValue ){
00807 for(i=0; i<N; i++){
00808 Tcl_SetVar(interp, argv[3], azValue[i] ? azValue[i] : "",
00809 TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
00810 }
00811 }
00812 }
00813 if( argc==5 ){
00814 Tcl_SetVar(interp, argv[4], "", 0);
00815 if( azColName ){
00816 for(i=0; i<N*2; i++){
00817 Tcl_SetVar(interp, argv[4], azColName[i] ? azColName[i] : "",
00818 TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
00819 }
00820 }
00821 }
00822 switch( rc ){
00823 case SQLITE_DONE: zRc = "SQLITE_DONE"; break;
00824 case SQLITE_BUSY: zRc = "SQLITE_BUSY"; break;
00825 case SQLITE_ROW: zRc = "SQLITE_ROW"; break;
00826 case SQLITE_ERROR: zRc = "SQLITE_ERROR"; break;
00827 case SQLITE_MISUSE: zRc = "SQLITE_MISUSE"; break;
00828 default: zRc = "unknown"; break;
00829 }
00830 Tcl_AppendResult(interp, zRc, 0);
00831 return TCL_OK;
00832 }
00833
00834
00835
00836
00837
00838
00839 static int test_finalize(
00840 void *NotUsed,
00841 Tcl_Interp *interp,
00842 int argc,
00843 char **argv
00844 ){
00845 sqlite_vm *vm;
00846 int rc;
00847 char *zErrMsg = 0;
00848 if( argc!=2 ){
00849 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00850 " VM\"", 0);
00851 return TCL_ERROR;
00852 }
00853 if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR;
00854 rc = sqlite_finalize(vm, &zErrMsg);
00855 if( rc ){
00856 char zBuf[50];
00857 sprintf(zBuf, "(%d) ", rc);
00858 Tcl_AppendResult(interp, zBuf, zErrMsg, 0);
00859 sqlite_freemem(zErrMsg);
00860 return TCL_ERROR;
00861 }
00862 return TCL_OK;
00863 }
00864
00865
00866
00867
00868
00869
00870 static int test_reset(
00871 void *NotUsed,
00872 Tcl_Interp *interp,
00873 int argc,
00874 char **argv
00875 ){
00876 sqlite_vm *vm;
00877 int rc;
00878 char *zErrMsg = 0;
00879 if( argc!=2 ){
00880 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00881 " VM\"", 0);
00882 return TCL_ERROR;
00883 }
00884 if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR;
00885 rc = sqlite_reset(vm, &zErrMsg);
00886 if( rc ){
00887 char zBuf[50];
00888 sprintf(zBuf, "(%d) ", rc);
00889 Tcl_AppendResult(interp, zBuf, zErrMsg, 0);
00890 sqlite_freemem(zErrMsg);
00891 return TCL_ERROR;
00892 }
00893 return TCL_OK;
00894 }
00895
00896
00897
00898
00899
00900 static char *sqlite_static_bind_value = 0;
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912 static int test_bind(
00913 void *NotUsed,
00914 Tcl_Interp *interp,
00915 int argc,
00916 char **argv
00917 ){
00918 sqlite_vm *vm;
00919 int rc;
00920 int idx;
00921 if( argc!=5 ){
00922 Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
00923 " VM IDX VALUE (null|static|normal)\"", 0);
00924 return TCL_ERROR;
00925 }
00926 if( getVmPointer(interp, argv[1], &vm) ) return TCL_ERROR;
00927 if( Tcl_GetInt(interp, argv[2], &idx) ) return TCL_ERROR;
00928 if( strcmp(argv[4],"null")==0 ){
00929 rc = sqlite_bind(vm, idx, 0, 0, 0);
00930 }else if( strcmp(argv[4],"static")==0 ){
00931 rc = sqlite_bind(vm, idx, sqlite_static_bind_value, -1, 0);
00932 }else if( strcmp(argv[4],"normal")==0 ){
00933 rc = sqlite_bind(vm, idx, argv[3], -1, 1);
00934 }else{
00935 Tcl_AppendResult(interp, "4th argument should be "
00936 "\"null\" or \"static\" or \"normal\"", 0);
00937 return TCL_ERROR;
00938 }
00939 if( rc ){
00940 char zBuf[50];
00941 sprintf(zBuf, "(%d) ", rc);
00942 Tcl_AppendResult(interp, zBuf, sqlite_error_string(rc), 0);
00943 return TCL_ERROR;
00944 }
00945 return TCL_OK;
00946 }
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 static int test_breakpoint(
00962 void *NotUsed,
00963 Tcl_Interp *interp,
00964 int argc,
00965 char **argv
00966 ){
00967 return TCL_OK;
00968 }
00969
00970
00971
00972
00973 int Sqlitetest1_Init(Tcl_Interp *interp){
00974 extern int sqlite_search_count;
00975 extern int sqlite_interrupt_count;
00976 extern int sqlite_open_file_count;
00977 extern int sqlite_current_time;
00978 extern int sqlite_temp_directory;
00979 static struct {
00980 char *zName;
00981 Tcl_CmdProc *xProc;
00982 } aCmd[] = {
00983 { "sqlite_mprintf_int", (Tcl_CmdProc*)sqlite_mprintf_int },
00984 { "sqlite_mprintf_str", (Tcl_CmdProc*)sqlite_mprintf_str },
00985 { "sqlite_mprintf_double", (Tcl_CmdProc*)sqlite_mprintf_double },
00986 { "sqlite_mprintf_scaled", (Tcl_CmdProc*)sqlite_mprintf_scaled },
00987 { "sqlite_mprintf_z_test", (Tcl_CmdProc*)test_mprintf_z },
00988 { "sqlite_open", (Tcl_CmdProc*)sqlite_test_open },
00989 { "sqlite_last_insert_rowid", (Tcl_CmdProc*)test_last_rowid },
00990 { "sqlite_exec_printf", (Tcl_CmdProc*)test_exec_printf },
00991 { "sqlite_get_table_printf", (Tcl_CmdProc*)test_get_table_printf },
00992 { "sqlite_close", (Tcl_CmdProc*)sqlite_test_close },
00993 { "sqlite_create_function", (Tcl_CmdProc*)test_create_function },
00994 { "sqlite_create_aggregate", (Tcl_CmdProc*)test_create_aggregate },
00995 { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func },
00996 { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort },
00997 { "sqlite_datatypes", (Tcl_CmdProc*)sqlite_datatypes },
00998 #ifdef MEMORY_DEBUG
00999 { "sqlite_malloc_fail", (Tcl_CmdProc*)sqlite_malloc_fail },
01000 { "sqlite_malloc_stat", (Tcl_CmdProc*)sqlite_malloc_stat },
01001 #endif
01002 { "sqlite_compile", (Tcl_CmdProc*)test_compile },
01003 { "sqlite_step", (Tcl_CmdProc*)test_step },
01004 { "sqlite_finalize", (Tcl_CmdProc*)test_finalize },
01005 { "sqlite_bind", (Tcl_CmdProc*)test_bind },
01006 { "sqlite_reset", (Tcl_CmdProc*)test_reset },
01007 { "breakpoint", (Tcl_CmdProc*)test_breakpoint },
01008 };
01009 int i;
01010
01011 for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
01012 Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
01013 }
01014 Tcl_LinkVar(interp, "sqlite_search_count",
01015 (char*)&sqlite_search_count, TCL_LINK_INT);
01016 Tcl_LinkVar(interp, "sqlite_interrupt_count",
01017 (char*)&sqlite_interrupt_count, TCL_LINK_INT);
01018 Tcl_LinkVar(interp, "sqlite_open_file_count",
01019 (char*)&sqlite_open_file_count, TCL_LINK_INT);
01020 Tcl_LinkVar(interp, "sqlite_current_time",
01021 (char*)&sqlite_current_time, TCL_LINK_INT);
01022 Tcl_LinkVar(interp, "sqlite_static_bind_value",
01023 (char*)&sqlite_static_bind_value, TCL_LINK_STRING);
01024 Tcl_LinkVar(interp, "sqlite_temp_directory",
01025 (char*)&sqlite_temp_directory, TCL_LINK_STRING);
01026 return TCL_OK;
01027 }