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 ** A TCL Interface to SQLite 13 ** 14 ** $Id: tclsqlite.c,v 1.50 2003/08/19 14:31:02 drh Exp $ 15 */ 16 #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ 17 18 #include "sqliteInt.h" 19 #include "tcl.h" 20 #include <stdlib.h> 21 #include <string.h> 22 #include <assert.h> 23 24 /* 25 ** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we 26 ** have to do a translation when going between the two. Set the 27 ** UTF_TRANSLATION_NEEDED macro to indicate that we need to do 28 ** this translation. 29 */ 30 #if defined(TCL_UTF_MAX) && !defined(SQLITE_UTF8) 31 # define UTF_TRANSLATION_NEEDED 1 32 #endif 33 34 /* 35 ** New SQL functions can be created as TCL scripts. Each such function 36 ** is described by an instance of the following structure. 37 */ 38 typedef struct SqlFunc SqlFunc; 39 struct SqlFunc { 40 Tcl_Interp *interp; /* The TCL interpret to execute the function */ 41 char *zScript; /* The script to be run */ 42 SqlFunc *pNext; /* Next function on the list of them all */ 43 }; 44 45 /* 46 ** There is one instance of this structure for each SQLite database 47 ** that has been opened by the SQLite TCL interface. 48 */ 49 typedef struct SqliteDb SqliteDb; 50 struct SqliteDb { 51 sqlite *db; /* The "real" database structure */ 52 Tcl_Interp *interp; /* The interpreter used for this database */ 53 char *zBusy; /* The busy callback routine */ 54 char *zTrace; /* The trace callback routine */ 55 char *zAuth; /* The authorization callback routine */ 56 SqlFunc *pFunc; /* List of SQL functions */ 57 int rc; /* Return code of most recent sqlite_exec() */ 58 }; 59 60 /* 61 ** An instance of this structure passes information thru the sqlite 62 ** logic from the original TCL command into the callback routine. 63 */ 64 typedef struct CallbackData CallbackData; 65 struct CallbackData { 66 Tcl_Interp *interp; /* The TCL interpreter */ 67 char *zArray; /* The array into which data is written */ 68 Tcl_Obj *pCode; /* The code to execute for each row */ 69 int once; /* Set for first callback only */ 70 int tcl_rc; /* Return code from TCL script */ 71 int nColName; /* Number of entries in the azColName[] array */ 72 char **azColName; /* Column names translated to UTF-8 */ 73 }; 74 75 #ifdef UTF_TRANSLATION_NEEDED 76 /* 77 ** Called for each row of the result. 78 ** 79 ** This version is used when TCL expects UTF-8 data but the database 80 ** uses the ISO8859 format. A translation must occur from ISO8859 into 81 ** UTF-8. 82 */ 83 static int DbEvalCallback( 84 void *clientData, /* An instance of CallbackData */ 85 int nCol, /* Number of columns in the result */ 86 char ** azCol, /* Data for each column */ 87 char ** azN /* Name for each column */ 88 ){ 89 CallbackData *cbData = (CallbackData*)clientData; 90 int i, rc; 91 Tcl_DString dCol; 92 Tcl_DStringInit(&dCol); 93 if( cbData->azColName==0 ){ 94 assert( cbData->once ); 95 cbData->once = 0; 96 if( cbData->zArray[0] ){ 97 Tcl_SetVar2(cbData->interp, cbData->zArray, "*", "", 0); 98 } 99 cbData->azColName = malloc( nCol*sizeof(char*) ); 100 if( cbData->azColName==0 ){ return 1; } 101 cbData->nColName = nCol; 102 for(i=0; i<nCol; i++){ 103 Tcl_ExternalToUtfDString(NULL, azN[i], -1, &dCol); 104 cbData->azColName[i] = malloc( Tcl_DStringLength(&dCol) + 1 ); 105 if( cbData->azColName[i] ){ 106 strcpy(cbData->azColName[i], Tcl_DStringValue(&dCol)); 107 }else{ 108 return 1; 109 } 110 if( cbData->zArray[0] ){ 111 Tcl_SetVar2(cbData->interp, cbData->zArray, "*", 112 Tcl_DStringValue(&dCol), TCL_LIST_ELEMENT|TCL_APPEND_VALUE); 113 if( azN[nCol]!=0 ){ 114 Tcl_DString dType; 115 Tcl_DStringInit(&dType); 116 Tcl_DStringAppend(&dType, "typeof:", -1); 117 Tcl_DStringAppend(&dType, Tcl_DStringValue(&dCol), -1); 118 Tcl_DStringFree(&dCol); 119 Tcl_ExternalToUtfDString(NULL, azN[i+nCol], -1, &dCol); 120 Tcl_SetVar2(cbData->interp, cbData->zArray, 121 Tcl_DStringValue(&dType), Tcl_DStringValue(&dCol), 122 TCL_LIST_ELEMENT|TCL_APPEND_VALUE); 123 Tcl_DStringFree(&dType); 124 } 125 } 126 127 Tcl_DStringFree(&dCol); 128 } 129 } 130 if( azCol!=0 ){ 131 if( cbData->zArray[0] ){ 132 for(i=0; i<nCol; i++){ 133 char *z = azCol[i]; 134 if( z==0 ) z = ""; 135 Tcl_DStringInit(&dCol); 136 Tcl_ExternalToUtfDString(NULL, z, -1, &dCol); 137 Tcl_SetVar2(cbData->interp, cbData->zArray, cbData->azColName[i], 138 Tcl_DStringValue(&dCol), 0); 139 Tcl_DStringFree(&dCol); 140 } 141 }else{ 142 for(i=0; i<nCol; i++){ 143 char *z = azCol[i]; 144 if( z==0 ) z = ""; 145 Tcl_DStringInit(&dCol); 146 Tcl_ExternalToUtfDString(NULL, z, -1, &dCol); 147 Tcl_SetVar(cbData->interp, cbData->azColName[i], 148 Tcl_DStringValue(&dCol), 0); 149 Tcl_DStringFree(&dCol); 150 } 151 } 152 } 153 rc = Tcl_EvalObj(cbData->interp, cbData->pCode); 154 if( rc==TCL_CONTINUE ) rc = TCL_OK; 155 cbData->tcl_rc = rc; 156 return rc!=TCL_OK; 157 } 158 #endif /* UTF_TRANSLATION_NEEDED */ 159 160 #ifndef UTF_TRANSLATION_NEEDED 161 /* 162 ** Called for each row of the result. 163 ** 164 ** This version is used when either of the following is true: 165 ** 166 ** (1) This version of TCL uses UTF-8 and the data in the 167 ** SQLite database is already in the UTF-8 format. 168 ** 169 ** (2) This version of TCL uses ISO8859 and the data in the 170 ** SQLite database is already in the ISO8859 format. 171 */ 172 static int DbEvalCallback( 173 void *clientData, /* An instance of CallbackData */ 174 int nCol, /* Number of columns in the result */ 175 char ** azCol, /* Data for each column */ 176 char ** azN /* Name for each column */ 177 ){ 178 CallbackData *cbData = (CallbackData*)clientData; 179 int i, rc; 180 if( azCol==0 || (cbData->once && cbData->zArray[0]) ){ 181 Tcl_SetVar2(cbData->interp, cbData->zArray, "*", "", 0); 182 for(i=0; i<nCol; i++){ 183 Tcl_SetVar2(cbData->interp, cbData->zArray, "*", azN[i], 184 TCL_LIST_ELEMENT|TCL_APPEND_VALUE); 185 if( azN[nCol] ){ 186 char *z = sqlite_mprintf("typeof:%s", azN[i]); 187 Tcl_SetVar2(cbData->interp, cbData->zArray, z, azN[i+nCol], 188 TCL_LIST_ELEMENT|TCL_APPEND_VALUE); 189 sqlite_freemem(z); 190 } 191 } 192 cbData->once = 0; 193 } 194 if( azCol!=0 ){ 195 if( cbData->zArray[0] ){ 196 for(i=0; i<nCol; i++){ 197 char *z = azCol[i]; 198 if( z==0 ) z = ""; 199 Tcl_SetVar2(cbData->interp, cbData->zArray, azN[i], z, 0); 200 } 201 }else{ 202 for(i=0; i<nCol; i++){ 203 char *z = azCol[i]; 204 if( z==0 ) z = ""; 205 Tcl_SetVar(cbData->interp, azN[i], z, 0); 206 } 207 } 208 } 209 rc = Tcl_EvalObj(cbData->interp, cbData->pCode); 210 if( rc==TCL_CONTINUE ) rc = TCL_OK; 211 cbData->tcl_rc = rc; 212 return rc!=TCL_OK; 213 } 214 #endif 215 216 /* 217 ** This is an alternative callback for database queries. Instead 218 ** of invoking a TCL script to handle the result, this callback just 219 ** appends each column of the result to a list. After the query 220 ** is complete, the list is returned. 221 */ 222 static int DbEvalCallback2( 223 void *clientData, /* An instance of CallbackData */ 224 int nCol, /* Number of columns in the result */ 225 char ** azCol, /* Data for each column */ 226 char ** azN /* Name for each column */ 227 ){ 228 Tcl_Obj *pList = (Tcl_Obj*)clientData; 229 int i; 230 if( azCol==0 ) return 0; 231 for(i=0; i<nCol; i++){ 232 Tcl_Obj *pElem; 233 if( azCol[i] && *azCol[i] ){ 234 #ifdef UTF_TRANSLATION_NEEDED 235 Tcl_DString dCol; 236 Tcl_DStringInit(&dCol); 237 Tcl_ExternalToUtfDString(NULL, azCol[i], -1, &dCol); 238 pElem = Tcl_NewStringObj(Tcl_DStringValue(&dCol), -1); 239 Tcl_DStringFree(&dCol); 240 #else 241 pElem = Tcl_NewStringObj(azCol[i], -1); 242 #endif 243 }else{ 244 pElem = Tcl_NewObj(); 245 } 246 Tcl_ListObjAppendElement(0, pList, pElem); 247 } 248 return 0; 249 } 250 251 /* 252 ** This is a second alternative callback for database queries. A the 253 ** first column of the first row of the result is made the TCL result. 254 */ 255 static int DbEvalCallback3( 256 void *clientData, /* An instance of CallbackData */ 257 int nCol, /* Number of columns in the result */ 258 char ** azCol, /* Data for each column */ 259 char ** azN /* Name for each column */ 260 ){ 261 Tcl_Interp *interp = (Tcl_Interp*)clientData; 262 Tcl_Obj *pElem; 263 if( azCol==0 ) return 1; 264 if( nCol==0 ) return 1; 265 #ifdef UTF_TRANSLATION_NEEDED 266 { 267 Tcl_DString dCol; 268 Tcl_DStringInit(&dCol); 269 Tcl_ExternalToUtfDString(NULL, azCol[0], -1, &dCol); 270 pElem = Tcl_NewStringObj(Tcl_DStringValue(&dCol), -1); 271 Tcl_DStringFree(&dCol); 272 } 273 #else 274 pElem = Tcl_NewStringObj(azCol[0], -1); 275 #endif 276 Tcl_SetObjResult(interp, pElem); 277 return 1; 278 } 279 280 /* 281 ** Called when the command is deleted. 282 */ 283 static void DbDeleteCmd(void *db){ 284 SqliteDb *pDb = (SqliteDb*)db; 285 sqlite_close(pDb->db); 286 while( pDb->pFunc ){ 287 SqlFunc *pFunc = pDb->pFunc; 288 pDb->pFunc = pFunc->pNext; 289 Tcl_Free((char*)pFunc); 290 } 291 if( pDb->zBusy ){ 292 Tcl_Free(pDb->zBusy); 293 } 294 if( pDb->zTrace ){ 295 Tcl_Free(pDb->zTrace); 296 } 297 if( pDb->zAuth ){ 298 Tcl_Free(pDb->zAuth); 299 } 300 Tcl_Free((char*)pDb); 301 } 302 303 /* 304 ** This routine is called when a database file is locked while trying 305 ** to execute SQL. 306 */ 307 static int DbBusyHandler(void *cd, const char *zTable, int nTries){ 308 SqliteDb *pDb = (SqliteDb*)cd; 309 int rc; 310 char zVal[30]; 311 char *zCmd; 312 Tcl_DString cmd; 313 314 Tcl_DStringInit(&cmd); 315 Tcl_DStringAppend(&cmd, pDb->zBusy, -1); 316 Tcl_DStringAppendElement(&cmd, zTable); 317 sprintf(zVal, " %d", nTries); 318 Tcl_DStringAppend(&cmd, zVal, -1); 319 zCmd = Tcl_DStringValue(&cmd); 320 rc = Tcl_Eval(pDb->interp, zCmd); 321 Tcl_DStringFree(&cmd); 322 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ 323 return 0; 324 } 325 return 1; 326 } 327 328 /* 329 ** This routine is called by the SQLite trace handler whenever a new 330 ** block of SQL is executed. The TCL script in pDb->zTrace is executed. 331 */ 332 static void DbTraceHandler(void *cd, const char *zSql){ 333 SqliteDb *pDb = (SqliteDb*)cd; 334 Tcl_DString str; 335 336 Tcl_DStringInit(&str); 337 Tcl_DStringAppend(&str, pDb->zTrace, -1); 338 Tcl_DStringAppendElement(&str, zSql); 339 Tcl_Eval(pDb->interp, Tcl_DStringValue(&str)); 340 Tcl_DStringFree(&str); 341 Tcl_ResetResult(pDb->interp); 342 } 343 344 /* 345 ** This routine is called to evaluate an SQL function implemented 346 ** using TCL script. 347 */ 348 static void tclSqlFunc(sqlite_func *context, int argc, const char **argv){ 349 SqlFunc *p = sqlite_user_data(context); 350 Tcl_DString cmd; 351 int i; 352 int rc; 353 354 Tcl_DStringInit(&cmd); 355 Tcl_DStringAppend(&cmd, p->zScript, -1); 356 for(i=0; i<argc; i++){ 357 Tcl_DStringAppendElement(&cmd, argv[i] ? argv[i] : ""); 358 } 359 rc = Tcl_Eval(p->interp, Tcl_DStringValue(&cmd)); 360 if( rc ){ 361 sqlite_set_result_error(context, Tcl_GetStringResult(p->interp), -1); 362 }else{ 363 sqlite_set_result_string(context, Tcl_GetStringResult(p->interp), -1); 364 } 365 } 366 #ifndef SQLITE_OMIT_AUTHORIZATION 367 /* 368 ** This is the authentication function. It appends the authentication 369 ** type code and the two arguments to zCmd[] then invokes the result 370 ** on the interpreter. The reply is examined to determine if the 371 ** authentication fails or succeeds. 372 */ 373 static int auth_callback( 374 void *pArg, 375 int code, 376 const char *zArg1, 377 const char *zArg2, 378 const char *zArg3, 379 const char *zArg4 380 ){ 381 char *zCode; 382 Tcl_DString str; 383 int rc; 384 const char *zReply; 385 SqliteDb *pDb = (SqliteDb*)pArg; 386 387 switch( code ){ 388 case SQLITE_COPY : zCode="SQLITE_COPY"; break; 389 case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break; 390 case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break; 391 case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break; 392 case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break; 393 case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break; 394 case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break; 395 case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break; 396 case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break; 397 case SQLITE_DELETE : zCode="SQLITE_DELETE"; break; 398 case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break; 399 case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break; 400 case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break; 401 case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break; 402 case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break; 403 case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break; 404 case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break; 405 case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break; 406 case SQLITE_INSERT : zCode="SQLITE_INSERT"; break; 407 case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break; 408 case SQLITE_READ : zCode="SQLITE_READ"; break; 409 case SQLITE_SELECT : zCode="SQLITE_SELECT"; break; 410 case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break; 411 case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break; 412 case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break; 413 case SQLITE_DETACH : zCode="SQLITE_DETACH"; break; 414 default : zCode="????"; break; 415 } 416 Tcl_DStringInit(&str); 417 Tcl_DStringAppend(&str, pDb->zAuth, -1); 418 Tcl_DStringAppendElement(&str, zCode); 419 Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : ""); 420 Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : ""); 421 Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : ""); 422 Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : ""); 423 rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str)); 424 Tcl_DStringFree(&str); 425 zReply = Tcl_GetStringResult(pDb->interp); 426 if( strcmp(zReply,"SQLITE_OK")==0 ){ 427 rc = SQLITE_OK; 428 }else if( strcmp(zReply,"SQLITE_DENY")==0 ){ 429 rc = SQLITE_DENY; 430 }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){ 431 rc = SQLITE_IGNORE; 432 }else{ 433 rc = 999; 434 } 435 return rc; 436 } 437 #endif /* SQLITE_OMIT_AUTHORIZATION */ 438 439 /* 440 ** The "sqlite" command below creates a new Tcl command for each 441 ** connection it opens to an SQLite database. This routine is invoked 442 ** whenever one of those connection-specific commands is executed 443 ** in Tcl. For example, if you run Tcl code like this: 444 ** 445 ** sqlite db1 "my_database" 446 ** db1 close 447 ** 448 ** The first command opens a connection to the "my_database" database 449 ** and calls that connection "db1". The second command causes this 450 ** subroutine to be invoked. 451 */ 452 static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ 453 SqliteDb *pDb = (SqliteDb*)cd; 454 int choice; 455 static const char *DB_strs[] = { 456 "authorizer", "busy", "changes", 457 "close", "complete", "errorcode", 458 "eval", "function", "last_insert_rowid", 459 "onecolumn", "timeout", "trace", 460 0 461 }; 462 enum DB_enum { 463 DB_AUTHORIZER, DB_BUSY, DB_CHANGES, 464 DB_CLOSE, DB_COMPLETE, DB_ERRORCODE, 465 DB_EVAL, DB_FUNCTION, DB_LAST_INSERT_ROWID, 466 DB_ONECOLUMN, DB_TIMEOUT, DB_TRACE, 467 }; 468 469 if( objc<2 ){ 470 Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); 471 return TCL_ERROR; 472 } 473 if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){ 474 return TCL_ERROR; 475 } 476 477 switch( (enum DB_enum)choice ){ 478 479 /* $db authorizer ?CALLBACK? 480 ** 481 ** Invoke the given callback to authorize each SQL operation as it is 482 ** compiled. 5 arguments are appended to the callback before it is 483 ** invoked: 484 ** 485 ** (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...) 486 ** (2) First descriptive name (depends on authorization type) 487 ** (3) Second descriptive name 488 ** (4) Name of the database (ex: "main", "temp") 489 ** (5) Name of trigger that is doing the access 490 ** 491 ** The callback should return on of the following strings: SQLITE_OK, 492 ** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error. 493 ** 494 ** If this method is invoked with no arguments, the current authorization 495 ** callback string is returned. 496 */ 497 case DB_AUTHORIZER: { 498 if( objc>3 ){ 499 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 500 }else if( objc==2 ){ 501 if( pDb->zAuth ){ 502 Tcl_AppendResult(interp, pDb->zAuth, 0); 503 } 504 }else{ 505 char *zAuth; 506 int len; 507 if( pDb->zAuth ){ 508 Tcl_Free(pDb->zAuth); 509 } 510 zAuth = Tcl_GetStringFromObj(objv[2], &len); 511 if( zAuth && len>0 ){ 512 pDb->zAuth = Tcl_Alloc( len + 1 ); 513 strcpy(pDb->zAuth, zAuth); 514 }else{ 515 pDb->zAuth = 0; 516 } 517 #ifndef SQLITE_OMIT_AUTHORIZATION 518 if( pDb->zAuth ){ 519 pDb->interp = interp; 520 sqlite_set_authorizer(pDb->db, auth_callback, pDb); 521 }else{ 522 sqlite_set_authorizer(pDb->db, 0, 0); 523 } 524 #endif 525 } 526 break; 527 } 528 529 /* $db busy ?CALLBACK? 530 ** 531 ** Invoke the given callback if an SQL statement attempts to open 532 ** a locked database file. 533 */ 534 case DB_BUSY: { 535 if( objc>3 ){ 536 Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK"); 537 return TCL_ERROR; 538 }else if( objc==2 ){ 539 if( pDb->zBusy ){ 540 Tcl_AppendResult(interp, pDb->zBusy, 0); 541 } 542 }else{ 543 char *zBusy; 544 int len; 545 if( pDb->zBusy ){ 546 Tcl_Free(pDb->zBusy); 547 } 548 zBusy = Tcl_GetStringFromObj(objv[2], &len); 549 if( zBusy && len>0 ){ 550 pDb->zBusy = Tcl_Alloc( len + 1 ); 551 strcpy(pDb->zBusy, zBusy); 552 }else{ 553 pDb->zBusy = 0; 554 } 555 if( pDb->zBusy ){ 556 pDb->interp = interp; 557 sqlite_busy_handler(pDb->db, DbBusyHandler, pDb); 558 }else{ 559 sqlite_busy_handler(pDb->db, 0, 0); 560 } 561 } 562 break; 563 } 564 565 /* 566 ** $db changes 567 ** 568 ** Return the number of rows that were modified, inserted, or deleted by 569 ** the most recent "eval". 570 */ 571 case DB_CHANGES: { 572 Tcl_Obj *pResult; 573 int nChange; 574 if( objc!=2 ){ 575 Tcl_WrongNumArgs(interp, 2, objv, ""); 576 return TCL_ERROR; 577 } 578 nChange = sqlite_changes(pDb->db); 579 pResult = Tcl_GetObjResult(interp); 580 Tcl_SetIntObj(pResult, nChange); 581 break; 582 } 583 584 /* $db close 585 ** 586 ** Shutdown the database 587 */ 588 case DB_CLOSE: { 589 Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0)); 590 break; 591 } 592 593 /* $db complete SQL 594 ** 595 ** Return TRUE if SQL is a complete SQL statement. Return FALSE if 596 ** additional lines of input are needed. This is similar to the 597 ** built-in "info complete" command of Tcl. 598 */ 599 case DB_COMPLETE: { 600 Tcl_Obj *pResult; 601 int isComplete; 602 if( objc!=3 ){ 603 Tcl_WrongNumArgs(interp, 2, objv, "SQL"); 604 return TCL_ERROR; 605 } 606 isComplete = sqlite_complete( Tcl_GetStringFromObj(objv[2], 0) ); 607 pResult = Tcl_GetObjResult(interp); 608 Tcl_SetBooleanObj(pResult, isComplete); 609 break; 610 } 611 612 /* 613 ** $db errorcode 614 ** 615 ** Return the numeric error code that was returned by the most recent 616 ** call to sqlite_exec(). 617 */ 618 case DB_ERRORCODE: { 619 Tcl_SetObjResult(interp, Tcl_NewIntObj(pDb->rc)); 620 break; 621 } 622 623 /* 624 ** $db eval $sql ?array { ...code... }? 625 ** 626 ** The SQL statement in $sql is evaluated. For each row, the values are 627 ** placed in elements of the array named "array" and ...code... is executed. 628 ** If "array" and "code" are omitted, then no callback is every invoked. 629 ** If "array" is an empty string, then the values are placed in variables 630 ** that have the same name as the fields extracted by the query. 631 */ 632 case DB_EVAL: { 633 CallbackData cbData; 634 char *zErrMsg; 635 char *zSql; 636 int rc; 637 #ifdef UTF_TRANSLATION_NEEDED 638 Tcl_DString dSql; 639 int i; 640 #endif 641 642 if( objc!=5 && objc!=3 ){ 643 Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME CODE?"); 644 return TCL_ERROR; 645 } 646 pDb->interp = interp; 647 zSql = Tcl_GetStringFromObj(objv[2], 0); 648 #ifdef UTF_TRANSLATION_NEEDED 649 Tcl_DStringInit(&dSql); 650 Tcl_UtfToExternalDString(NULL, zSql, -1, &dSql); 651 zSql = Tcl_DStringValue(&dSql); 652 #endif 653 Tcl_IncrRefCount(objv[2]); 654 if( objc==5 ){ 655 cbData.interp = interp; 656 cbData.once = 1; 657 cbData.zArray = Tcl_GetStringFromObj(objv[3], 0); 658 cbData.pCode = objv[4]; 659 cbData.tcl_rc = TCL_OK; 660 cbData.nColName = 0; 661 cbData.azColName = 0; 662 zErrMsg = 0; 663 Tcl_IncrRefCount(objv[3]); 664 Tcl_IncrRefCount(objv[4]); 665 rc = sqlite_exec(pDb->db, zSql, DbEvalCallback, &cbData, &zErrMsg); 666 Tcl_DecrRefCount(objv[4]); 667 Tcl_DecrRefCount(objv[3]); 668 if( cbData.tcl_rc==TCL_BREAK ){ cbData.tcl_rc = TCL_OK; } 669 }else{ 670 Tcl_Obj *pList = Tcl_NewObj(); 671 cbData.tcl_rc = TCL_OK; 672 rc = sqlite_exec(pDb->db, zSql, DbEvalCallback2, pList, &zErrMsg); 673 Tcl_SetObjResult(interp, pList); 674 } 675 pDb->rc = rc; 676 if( rc==SQLITE_ABORT ){ 677 if( zErrMsg ) free(zErrMsg); 678 rc = cbData.tcl_rc; 679 }else if( zErrMsg ){ 680 Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE); 681 free(zErrMsg); 682 rc = TCL_ERROR; 683 }else if( rc!=SQLITE_OK ){ 684 Tcl_AppendResult(interp, sqlite_error_string(rc), 0); 685 rc = TCL_ERROR; 686 }else{ 687 } 688 Tcl_DecrRefCount(objv[2]); 689 #ifdef UTF_TRANSLATION_NEEDED 690 Tcl_DStringFree(&dSql); 691 if( objc==5 && cbData.azColName ){ 692 for(i=0; i<cbData.nColName; i++){ 693 if( cbData.azColName[i] ) free(cbData.azColName[i]); 694 } 695 free(cbData.azColName); 696 cbData.azColName = 0; 697 } 698 #endif 699 return rc; 700 } 701 702 /* 703 ** $db function NAME SCRIPT 704 ** 705 ** Create a new SQL function called NAME. Whenever that function is 706 ** called, invoke SCRIPT to evaluate the function. 707 */ 708 case DB_FUNCTION: { 709 SqlFunc *pFunc; 710 char *zName; 711 char *zScript; 712 int nScript; 713 if( objc!=4 ){ 714 Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT"); 715 return TCL_ERROR; 716 } 717 zName = Tcl_GetStringFromObj(objv[2], 0); 718 zScript = Tcl_GetStringFromObj(objv[3], &nScript); 719 pFunc = (SqlFunc*)Tcl_Alloc( sizeof(*pFunc) + nScript + 1 ); 720 if( pFunc==0 ) return TCL_ERROR; 721 pFunc->interp = interp; 722 pFunc->pNext = pDb->pFunc; 723 pFunc->zScript = (char*)&pFunc[1]; 724 strcpy(pFunc->zScript, zScript); 725 sqlite_create_function(pDb->db, zName, -1, tclSqlFunc, pFunc); 726 sqlite_function_type(pDb->db, zName, SQLITE_NUMERIC); 727 break; 728 } 729 730 /* 731 ** $db last_insert_rowid 732 ** 733 ** Return an integer which is the ROWID for the most recent insert. 734 */ 735 case DB_LAST_INSERT_ROWID: { 736 Tcl_Obj *pResult; 737 int rowid; 738 if( objc!=2 ){ 739 Tcl_WrongNumArgs(interp, 2, objv, ""); 740 return TCL_ERROR; 741 } 742 rowid = sqlite_last_insert_rowid(pDb->db); 743 pResult = Tcl_GetObjResult(interp); 744 Tcl_SetIntObj(pResult, rowid); 745 break; 746 } 747 748 /* 749 ** $db onecolumn SQL 750 ** 751 ** Return a single column from a single row of the given SQL query. 752 */ 753 case DB_ONECOLUMN: { 754 int rc; 755 char *zSql; 756 char *zErrMsg = 0; 757 if( objc!=3 ){ 758 Tcl_WrongNumArgs(interp, 2, objv, "SQL"); 759 return TCL_ERROR; 760 } 761 zSql = Tcl_GetStringFromObj(objv[2], 0); 762 rc = sqlite_exec(pDb->db, zSql, DbEvalCallback3, interp, &zErrMsg); 763 if( rc==SQLITE_ABORT ){ 764 /* Do nothing. This is normal. */ 765 }else if( zErrMsg ){ 766 Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE); 767 free(zErrMsg); 768 rc = TCL_ERROR; 769 }else if( rc!=SQLITE_OK ){ 770 Tcl_AppendResult(interp, sqlite_error_string(rc), 0); 771 rc = TCL_ERROR; 772 } 773 break; 774 } 775 776 /* 777 ** $db timeout MILLESECONDS 778 ** 779 ** Delay for the number of milliseconds specified when a file is locked. 780 */ 781 case DB_TIMEOUT: { 782 int ms; 783 if( objc!=3 ){ 784 Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS"); 785 return TCL_ERROR; 786 } 787 if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR; 788 sqlite_busy_timeout(pDb->db, ms); 789 break; 790 } 791 792 /* $db trace ?CALLBACK? 793 ** 794 ** Make arrangements to invoke the CALLBACK routine for each SQL statement 795 ** that is executed. The text of the SQL is appended to CALLBACK before 796 ** it is executed. 797 */ 798 case DB_TRACE: { 799 if( objc>3 ){ 800 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 801 }else if( objc==2 ){ 802 if( pDb->zTrace ){ 803 Tcl_AppendResult(interp, pDb->zTrace, 0); 804 } 805 }else{ 806 char *zTrace; 807 int len; 808 if( pDb->zTrace ){ 809 Tcl_Free(pDb->zTrace); 810 } 811 zTrace = Tcl_GetStringFromObj(objv[2], &len); 812 if( zTrace && len>0 ){ 813 pDb->zTrace = Tcl_Alloc( len + 1 ); 814 strcpy(pDb->zTrace, zTrace); 815 }else{ 816 pDb->zTrace = 0; 817 } 818 if( pDb->zTrace ){ 819 pDb->interp = interp; 820 sqlite_trace(pDb->db, DbTraceHandler, pDb); 821 }else{ 822 sqlite_trace(pDb->db, 0, 0); 823 } 824 } 825 break; 826 } 827 828 } /* End of the SWITCH statement */ 829 return TCL_OK; 830 } 831 832 /* 833 ** sqlite DBNAME FILENAME ?MODE? 834 ** 835 ** This is the main Tcl command. When the "sqlite" Tcl command is 836 ** invoked, this routine runs to process that command. 837 ** 838 ** The first argument, DBNAME, is an arbitrary name for a new 839 ** database connection. This command creates a new command named 840 ** DBNAME that is used to control that connection. The database 841 ** connection is deleted when the DBNAME command is deleted. 842 ** 843 ** The second argument is the name of the directory that contains 844 ** the sqlite database that is to be accessed. 845 ** 846 ** For testing purposes, we also support the following: 847 ** 848 ** sqlite -encoding 849 ** 850 ** Return the encoding used by LIKE and GLOB operators. Choices 851 ** are UTF-8 and iso8859. 852 ** 853 ** sqlite -version 854 ** 855 ** Return the version number of the SQLite library. 856 ** 857 ** sqlite -tcl-uses-utf 858 ** 859 ** Return "1" if compiled with a Tcl uses UTF-8. Return "0" if 860 ** not. Used by tests to make sure the library was compiled 861 ** correctly. 862 */ 863 static int DbMain(void *cd, Tcl_Interp *interp, int argc, char **argv){ 864 int mode; 865 SqliteDb *p; 866 char *zErrMsg; 867 char zBuf[80]; 868 if( argc==2 ){ 869 if( strcmp(argv[1],"-encoding")==0 ){ 870 Tcl_AppendResult(interp,sqlite_encoding,0); 871 return TCL_OK; 872 } 873 if( strcmp(argv[1],"-version")==0 ){ 874 Tcl_AppendResult(interp,sqlite_version,0); 875 return TCL_OK; 876 } 877 if( strcmp(argv[1],"-tcl-uses-utf")==0 ){ 878 #ifdef TCL_UTF_MAX 879 Tcl_AppendResult(interp,"1",0); 880 #else 881 Tcl_AppendResult(interp,"0",0); 882 #endif 883 return TCL_OK; 884 } 885 } 886 if( argc!=3 && argc!=4 ){ 887 Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], 888 " HANDLE FILENAME ?MODE?\"", 0); 889 return TCL_ERROR; 890 } 891 if( argc==3 ){ 892 mode = 0666; 893 }else if( Tcl_GetInt(interp, argv[3], &mode)!=TCL_OK ){ 894 return TCL_ERROR; 895 } 896 zErrMsg = 0; 897 p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); 898 if( p==0 ){ 899 Tcl_SetResult(interp, "malloc failed", TCL_STATIC); 900 return TCL_ERROR; 901 } 902 memset(p, 0, sizeof(*p)); 903 p->db = sqlite_open(argv[2], mode, &zErrMsg); 904 if( p->db==0 ){ 905 Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE); 906 Tcl_Free((char*)p); 907 free(zErrMsg); 908 return TCL_ERROR; 909 } 910 Tcl_CreateObjCommand(interp, argv[1], DbObjCmd, (char*)p, DbDeleteCmd); 911 912 /* The return value is the value of the sqlite* pointer 913 */ 914 sprintf(zBuf, "%p", p->db); 915 if( strncmp(zBuf,"0x",2) ){ 916 sprintf(zBuf, "0x%p", p->db); 917 } 918 Tcl_AppendResult(interp, zBuf, 0); 919 920 /* If compiled with SQLITE_TEST turned on, then register the "md5sum" 921 ** SQL function. 922 */ 923 #ifdef SQLITE_TEST 924 { 925 extern void Md5_Register(sqlite*); 926 Md5_Register(p->db); 927 } 928 #endif 929 return TCL_OK; 930 } 931 932 /* 933 ** Provide a dummy Tcl_InitStubs if we are using this as a static 934 ** library. 935 */ 936 #ifndef USE_TCL_STUBS 937 # undef Tcl_InitStubs 938 # define Tcl_InitStubs(a,b,c) 939 #endif 940 941 /* 942 ** Initialize this module. 943 ** 944 ** This Tcl module contains only a single new Tcl command named "sqlite". 945 ** (Hence there is no namespace. There is no point in using a namespace 946 ** if the extension only supplies one new name!) The "sqlite" command is 947 ** used to open a new SQLite database. See the DbMain() routine above 948 ** for additional information. 949 */ 950 int Sqlite_Init(Tcl_Interp *interp){ 951 Tcl_InitStubs(interp, "8.0", 0); 952 Tcl_CreateCommand(interp, "sqlite", (Tcl_CmdProc*)DbMain, 0, 0); 953 Tcl_PkgProvide(interp, "sqlite", "2.0"); 954 return TCL_OK; 955 } 956 int Tclsqlite_Init(Tcl_Interp *interp){ 957 Tcl_InitStubs(interp, "8.0", 0); 958 Tcl_CreateCommand(interp, "sqlite", (Tcl_CmdProc*)DbMain, 0, 0); 959 Tcl_PkgProvide(interp, "sqlite", "2.0"); 960 return TCL_OK; 961 } 962 int Sqlite_SafeInit(Tcl_Interp *interp){ 963 return TCL_OK; 964 } 965 int Tclsqlite_SafeInit(Tcl_Interp *interp){ 966 return TCL_OK; 967 } 968 969 #if 0 970 /* 971 ** If compiled using mktclapp, this routine runs to initialize 972 ** everything. 973 */ 974 int Et_AppInit(Tcl_Interp *interp){ 975 return Sqlite_Init(interp); 976 } 977 #endif 978 979 /* 980 ** If the macro TCLSH is defined and is one, then put in code for the 981 ** "main" routine that will initialize Tcl. 982 */ 983 #if defined(TCLSH) && TCLSH==1 984 static char zMainloop[] = 985 "set line {}\n" 986 "while {![eof stdin]} {\n" 987 "if {$line!=\"\"} {\n" 988 "puts -nonewline \"> \"\n" 989 "} else {\n" 990 "puts -nonewline \"% \"\n" 991 "}\n" 992 "flush stdout\n" 993 "append line [gets stdin]\n" 994 "if {[info complete $line]} {\n" 995 "if {[catch {uplevel #0 $line} result]} {\n" 996 "puts stderr \"Error: $result\"\n" 997 "} elseif {$result!=\"\"} {\n" 998 "puts $result\n" 999 "}\n" 1000 "set line {}\n" 1001 "} else {\n" 1002 "append line \\n\n" 1003 "}\n" 1004 "}\n" 1005 ; 1006 1007 #define TCLSH_MAIN main /* Needed to fake out mktclapp */ 1008 int TCLSH_MAIN(int argc, char **argv){ 1009 Tcl_Interp *interp; 1010 Tcl_FindExecutable(argv[0]); 1011 interp = Tcl_CreateInterp(); 1012 Sqlite_Init(interp); 1013 #ifdef SQLITE_TEST 1014 { 1015 extern int Sqlitetest1_Init(Tcl_Interp*); 1016 extern int Sqlitetest2_Init(Tcl_Interp*); 1017 extern int Sqlitetest3_Init(Tcl_Interp*); 1018 extern int Md5_Init(Tcl_Interp*); 1019 Sqlitetest1_Init(interp); 1020 Sqlitetest2_Init(interp); 1021 Sqlitetest3_Init(interp); 1022 Md5_Init(interp); 1023 } 1024 #endif 1025 if( argc>=2 ){ 1026 int i; 1027 Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY); 1028 Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY); 1029 for(i=2; i<argc; i++){ 1030 Tcl_SetVar(interp, "argv", argv[i], 1031 TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE); 1032 } 1033 if( Tcl_EvalFile(interp, argv[1])!=TCL_OK ){ 1034 const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); 1035 if( zInfo==0 ) zInfo = interp->result; 1036 fprintf(stderr,"%s: %s\n", *argv, zInfo); 1037 return 1; 1038 } 1039 }else{ 1040 Tcl_GlobalEval(interp, zMainloop); 1041 } 1042 return 0; 1043 } 1044 #endif /* TCLSH */ 1045 1046 #endif /* !defined(NO_TCL) */ 1047