00001 /* 00002 ** 2001 September 15 00003 ** 00004 ** The author disclaims copyright to this source code. In place of 00005 ** a legal notice, here is a blessing: 00006 ** 00007 ** May you do good and not evil. 00008 ** May you find forgiveness for yourself and forgive others. 00009 ** May you share freely, never taking more than you give. 00010 ** 00011 ************************************************************************* 00012 ** A TCL Interface to SQLite. Append this file to sqlite3.c and 00013 ** compile the whole thing to build a TCL-enabled version of SQLite. 00014 ** 00015 ** $Id: tclsqlite.c,v 1.228 2008/10/09 14:45:26 drh Exp $ 00016 */ 00017 #include "tcl.h" 00018 #include <errno.h> 00019 00020 /* 00021 ** Some additional include files are needed if this file is not 00022 ** appended to the amalgamation. 00023 */ 00024 #ifndef SQLITE_AMALGAMATION 00025 # include "sqliteInt.h" 00026 # include <stdlib.h> 00027 # include <string.h> 00028 # include <assert.h> 00029 # include <ctype.h> 00030 #endif 00031 00032 /* 00033 * Windows needs to know which symbols to export. Unix does not. 00034 * BUILD_sqlite should be undefined for Unix. 00035 */ 00036 #ifdef BUILD_sqlite 00037 #undef TCL_STORAGE_CLASS 00038 #define TCL_STORAGE_CLASS DLLEXPORT 00039 #endif /* BUILD_sqlite */ 00040 00041 #define NUM_PREPARED_STMTS 10 00042 #define MAX_PREPARED_STMTS 100 00043 00044 /* 00045 ** If TCL uses UTF-8 and SQLite is configured to use iso8859, then we 00046 ** have to do a translation when going between the two. Set the 00047 ** UTF_TRANSLATION_NEEDED macro to indicate that we need to do 00048 ** this translation. 00049 */ 00050 #if defined(TCL_UTF_MAX) && !defined(SQLITE_UTF8) 00051 # define UTF_TRANSLATION_NEEDED 1 00052 #endif 00053 00054 /* 00055 ** New SQL functions can be created as TCL scripts. Each such function 00056 ** is described by an instance of the following structure. 00057 */ 00058 typedef struct SqlFunc SqlFunc; 00059 struct SqlFunc { 00060 Tcl_Interp *interp; /* The TCL interpret to execute the function */ 00061 Tcl_Obj *pScript; /* The Tcl_Obj representation of the script */ 00062 int useEvalObjv; /* True if it is safe to use Tcl_EvalObjv */ 00063 char *zName; /* Name of this function */ 00064 SqlFunc *pNext; /* Next function on the list of them all */ 00065 }; 00066 00067 /* 00068 ** New collation sequences function can be created as TCL scripts. Each such 00069 ** function is described by an instance of the following structure. 00070 */ 00071 typedef struct SqlCollate SqlCollate; 00072 struct SqlCollate { 00073 Tcl_Interp *interp; /* The TCL interpret to execute the function */ 00074 char *zScript; /* The script to be run */ 00075 SqlCollate *pNext; /* Next function on the list of them all */ 00076 }; 00077 00078 /* 00079 ** Prepared statements are cached for faster execution. Each prepared 00080 ** statement is described by an instance of the following structure. 00081 */ 00082 typedef struct SqlPreparedStmt SqlPreparedStmt; 00083 struct SqlPreparedStmt { 00084 SqlPreparedStmt *pNext; /* Next in linked list */ 00085 SqlPreparedStmt *pPrev; /* Previous on the list */ 00086 sqlite3_stmt *pStmt; /* The prepared statement */ 00087 int nSql; /* chars in zSql[] */ 00088 const char *zSql; /* Text of the SQL statement */ 00089 }; 00090 00091 typedef struct IncrblobChannel IncrblobChannel; 00092 00093 /* 00094 ** There is one instance of this structure for each SQLite database 00095 ** that has been opened by the SQLite TCL interface. 00096 */ 00097 typedef struct SqliteDb SqliteDb; 00098 struct SqliteDb { 00099 sqlite3 *db; /* The "real" database structure. MUST BE FIRST */ 00100 Tcl_Interp *interp; /* The interpreter used for this database */ 00101 char *zBusy; /* The busy callback routine */ 00102 char *zCommit; /* The commit hook callback routine */ 00103 char *zTrace; /* The trace callback routine */ 00104 char *zProfile; /* The profile callback routine */ 00105 char *zProgress; /* The progress callback routine */ 00106 char *zAuth; /* The authorization callback routine */ 00107 int disableAuth; /* Disable the authorizer if it exists */ 00108 char *zNull; /* Text to substitute for an SQL NULL value */ 00109 SqlFunc *pFunc; /* List of SQL functions */ 00110 Tcl_Obj *pUpdateHook; /* Update hook script (if any) */ 00111 Tcl_Obj *pRollbackHook; /* Rollback hook script (if any) */ 00112 SqlCollate *pCollate; /* List of SQL collation functions */ 00113 int rc; /* Return code of most recent sqlite3_exec() */ 00114 Tcl_Obj *pCollateNeeded; /* Collation needed script */ 00115 SqlPreparedStmt *stmtList; /* List of prepared statements*/ 00116 SqlPreparedStmt *stmtLast; /* Last statement in the list */ 00117 int maxStmt; /* The next maximum number of stmtList */ 00118 int nStmt; /* Number of statements in stmtList */ 00119 IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */ 00120 int nStep, nSort; /* Statistics for most recent operation */ 00121 }; 00122 00123 struct IncrblobChannel { 00124 sqlite3_blob *pBlob; /* sqlite3 blob handle */ 00125 SqliteDb *pDb; /* Associated database connection */ 00126 int iSeek; /* Current seek offset */ 00127 Tcl_Channel channel; /* Channel identifier */ 00128 IncrblobChannel *pNext; /* Linked list of all open incrblob channels */ 00129 IncrblobChannel *pPrev; /* Linked list of all open incrblob channels */ 00130 }; 00131 00132 #ifndef SQLITE_OMIT_INCRBLOB 00133 /* 00134 ** Close all incrblob channels opened using database connection pDb. 00135 ** This is called when shutting down the database connection. 00136 */ 00137 static void closeIncrblobChannels(SqliteDb *pDb){ 00138 IncrblobChannel *p; 00139 IncrblobChannel *pNext; 00140 00141 for(p=pDb->pIncrblob; p; p=pNext){ 00142 pNext = p->pNext; 00143 00144 /* Note: Calling unregister here call Tcl_Close on the incrblob channel, 00145 ** which deletes the IncrblobChannel structure at *p. So do not 00146 ** call Tcl_Free() here. 00147 */ 00148 Tcl_UnregisterChannel(pDb->interp, p->channel); 00149 } 00150 } 00151 00152 /* 00153 ** Close an incremental blob channel. 00154 */ 00155 static int incrblobClose(ClientData instanceData, Tcl_Interp *interp){ 00156 IncrblobChannel *p = (IncrblobChannel *)instanceData; 00157 int rc = sqlite3_blob_close(p->pBlob); 00158 sqlite3 *db = p->pDb->db; 00159 00160 /* Remove the channel from the SqliteDb.pIncrblob list. */ 00161 if( p->pNext ){ 00162 p->pNext->pPrev = p->pPrev; 00163 } 00164 if( p->pPrev ){ 00165 p->pPrev->pNext = p->pNext; 00166 } 00167 if( p->pDb->pIncrblob==p ){ 00168 p->pDb->pIncrblob = p->pNext; 00169 } 00170 00171 /* Free the IncrblobChannel structure */ 00172 Tcl_Free((char *)p); 00173 00174 if( rc!=SQLITE_OK ){ 00175 Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE); 00176 return TCL_ERROR; 00177 } 00178 return TCL_OK; 00179 } 00180 00181 /* 00182 ** Read data from an incremental blob channel. 00183 */ 00184 static int incrblobInput( 00185 ClientData instanceData, 00186 char *buf, 00187 int bufSize, 00188 int *errorCodePtr 00189 ){ 00190 IncrblobChannel *p = (IncrblobChannel *)instanceData; 00191 int nRead = bufSize; /* Number of bytes to read */ 00192 int nBlob; /* Total size of the blob */ 00193 int rc; /* sqlite error code */ 00194 00195 nBlob = sqlite3_blob_bytes(p->pBlob); 00196 if( (p->iSeek+nRead)>nBlob ){ 00197 nRead = nBlob-p->iSeek; 00198 } 00199 if( nRead<=0 ){ 00200 return 0; 00201 } 00202 00203 rc = sqlite3_blob_read(p->pBlob, (void *)buf, nRead, p->iSeek); 00204 if( rc!=SQLITE_OK ){ 00205 *errorCodePtr = rc; 00206 return -1; 00207 } 00208 00209 p->iSeek += nRead; 00210 return nRead; 00211 } 00212 00213 /* 00214 ** Write data to an incremental blob channel. 00215 */ 00216 static int incrblobOutput( 00217 ClientData instanceData, 00218 CONST char *buf, 00219 int toWrite, 00220 int *errorCodePtr 00221 ){ 00222 IncrblobChannel *p = (IncrblobChannel *)instanceData; 00223 int nWrite = toWrite; /* Number of bytes to write */ 00224 int nBlob; /* Total size of the blob */ 00225 int rc; /* sqlite error code */ 00226 00227 nBlob = sqlite3_blob_bytes(p->pBlob); 00228 if( (p->iSeek+nWrite)>nBlob ){ 00229 *errorCodePtr = EINVAL; 00230 return -1; 00231 } 00232 if( nWrite<=0 ){ 00233 return 0; 00234 } 00235 00236 rc = sqlite3_blob_write(p->pBlob, (void *)buf, nWrite, p->iSeek); 00237 if( rc!=SQLITE_OK ){ 00238 *errorCodePtr = EIO; 00239 return -1; 00240 } 00241 00242 p->iSeek += nWrite; 00243 return nWrite; 00244 } 00245 00246 /* 00247 ** Seek an incremental blob channel. 00248 */ 00249 static int incrblobSeek( 00250 ClientData instanceData, 00251 long offset, 00252 int seekMode, 00253 int *errorCodePtr 00254 ){ 00255 IncrblobChannel *p = (IncrblobChannel *)instanceData; 00256 00257 switch( seekMode ){ 00258 case SEEK_SET: 00259 p->iSeek = offset; 00260 break; 00261 case SEEK_CUR: 00262 p->iSeek += offset; 00263 break; 00264 case SEEK_END: 00265 p->iSeek = sqlite3_blob_bytes(p->pBlob) + offset; 00266 break; 00267 00268 default: assert(!"Bad seekMode"); 00269 } 00270 00271 return p->iSeek; 00272 } 00273 00274 00275 static void incrblobWatch(ClientData instanceData, int mode){ 00276 /* NO-OP */ 00277 } 00278 static int incrblobHandle(ClientData instanceData, int dir, ClientData *hPtr){ 00279 return TCL_ERROR; 00280 } 00281 00282 static Tcl_ChannelType IncrblobChannelType = { 00283 "incrblob", /* typeName */ 00284 TCL_CHANNEL_VERSION_2, /* version */ 00285 incrblobClose, /* closeProc */ 00286 incrblobInput, /* inputProc */ 00287 incrblobOutput, /* outputProc */ 00288 incrblobSeek, /* seekProc */ 00289 0, /* setOptionProc */ 00290 0, /* getOptionProc */ 00291 incrblobWatch, /* watchProc (this is a no-op) */ 00292 incrblobHandle, /* getHandleProc (always returns error) */ 00293 0, /* close2Proc */ 00294 0, /* blockModeProc */ 00295 0, /* flushProc */ 00296 0, /* handlerProc */ 00297 0, /* wideSeekProc */ 00298 }; 00299 00300 /* 00301 ** Create a new incrblob channel. 00302 */ 00303 static int createIncrblobChannel( 00304 Tcl_Interp *interp, 00305 SqliteDb *pDb, 00306 const char *zDb, 00307 const char *zTable, 00308 const char *zColumn, 00309 sqlite_int64 iRow, 00310 int isReadonly 00311 ){ 00312 IncrblobChannel *p; 00313 sqlite3 *db = pDb->db; 00314 sqlite3_blob *pBlob; 00315 int rc; 00316 int flags = TCL_READABLE|(isReadonly ? 0 : TCL_WRITABLE); 00317 00318 /* This variable is used to name the channels: "incrblob_[incr count]" */ 00319 static int count = 0; 00320 char zChannel[64]; 00321 00322 rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob); 00323 if( rc!=SQLITE_OK ){ 00324 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); 00325 return TCL_ERROR; 00326 } 00327 00328 p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel)); 00329 p->iSeek = 0; 00330 p->pBlob = pBlob; 00331 00332 sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count); 00333 p->channel = Tcl_CreateChannel(&IncrblobChannelType, zChannel, p, flags); 00334 Tcl_RegisterChannel(interp, p->channel); 00335 00336 /* Link the new channel into the SqliteDb.pIncrblob list. */ 00337 p->pNext = pDb->pIncrblob; 00338 p->pPrev = 0; 00339 if( p->pNext ){ 00340 p->pNext->pPrev = p; 00341 } 00342 pDb->pIncrblob = p; 00343 p->pDb = pDb; 00344 00345 Tcl_SetResult(interp, (char *)Tcl_GetChannelName(p->channel), TCL_VOLATILE); 00346 return TCL_OK; 00347 } 00348 #else /* else clause for "#ifndef SQLITE_OMIT_INCRBLOB" */ 00349 #define closeIncrblobChannels(pDb) 00350 #endif 00351 00352 /* 00353 ** Look at the script prefix in pCmd. We will be executing this script 00354 ** after first appending one or more arguments. This routine analyzes 00355 ** the script to see if it is safe to use Tcl_EvalObjv() on the script 00356 ** rather than the more general Tcl_EvalEx(). Tcl_EvalObjv() is much 00357 ** faster. 00358 ** 00359 ** Scripts that are safe to use with Tcl_EvalObjv() consists of a 00360 ** command name followed by zero or more arguments with no [...] or $ 00361 ** or {...} or ; to be seen anywhere. Most callback scripts consist 00362 ** of just a single procedure name and they meet this requirement. 00363 */ 00364 static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){ 00365 /* We could try to do something with Tcl_Parse(). But we will instead 00366 ** just do a search for forbidden characters. If any of the forbidden 00367 ** characters appear in pCmd, we will report the string as unsafe. 00368 */ 00369 const char *z; 00370 int n; 00371 z = Tcl_GetStringFromObj(pCmd, &n); 00372 while( n-- > 0 ){ 00373 int c = *(z++); 00374 if( c=='$' || c=='[' || c==';' ) return 0; 00375 } 00376 return 1; 00377 } 00378 00379 /* 00380 ** Find an SqlFunc structure with the given name. Or create a new 00381 ** one if an existing one cannot be found. Return a pointer to the 00382 ** structure. 00383 */ 00384 static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){ 00385 SqlFunc *p, *pNew; 00386 int i; 00387 pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + strlen(zName) + 1 ); 00388 pNew->zName = (char*)&pNew[1]; 00389 for(i=0; zName[i]; i++){ pNew->zName[i] = tolower(zName[i]); } 00390 pNew->zName[i] = 0; 00391 for(p=pDb->pFunc; p; p=p->pNext){ 00392 if( strcmp(p->zName, pNew->zName)==0 ){ 00393 Tcl_Free((char*)pNew); 00394 return p; 00395 } 00396 } 00397 pNew->interp = pDb->interp; 00398 pNew->pScript = 0; 00399 pNew->pNext = pDb->pFunc; 00400 pDb->pFunc = pNew; 00401 return pNew; 00402 } 00403 00404 /* 00405 ** Finalize and free a list of prepared statements 00406 */ 00407 static void flushStmtCache( SqliteDb *pDb ){ 00408 SqlPreparedStmt *pPreStmt; 00409 00410 while( pDb->stmtList ){ 00411 sqlite3_finalize( pDb->stmtList->pStmt ); 00412 pPreStmt = pDb->stmtList; 00413 pDb->stmtList = pDb->stmtList->pNext; 00414 Tcl_Free( (char*)pPreStmt ); 00415 } 00416 pDb->nStmt = 0; 00417 pDb->stmtLast = 0; 00418 } 00419 00420 /* 00421 ** TCL calls this procedure when an sqlite3 database command is 00422 ** deleted. 00423 */ 00424 static void DbDeleteCmd(void *db){ 00425 SqliteDb *pDb = (SqliteDb*)db; 00426 flushStmtCache(pDb); 00427 closeIncrblobChannels(pDb); 00428 sqlite3_close(pDb->db); 00429 while( pDb->pFunc ){ 00430 SqlFunc *pFunc = pDb->pFunc; 00431 pDb->pFunc = pFunc->pNext; 00432 Tcl_DecrRefCount(pFunc->pScript); 00433 Tcl_Free((char*)pFunc); 00434 } 00435 while( pDb->pCollate ){ 00436 SqlCollate *pCollate = pDb->pCollate; 00437 pDb->pCollate = pCollate->pNext; 00438 Tcl_Free((char*)pCollate); 00439 } 00440 if( pDb->zBusy ){ 00441 Tcl_Free(pDb->zBusy); 00442 } 00443 if( pDb->zTrace ){ 00444 Tcl_Free(pDb->zTrace); 00445 } 00446 if( pDb->zProfile ){ 00447 Tcl_Free(pDb->zProfile); 00448 } 00449 if( pDb->zAuth ){ 00450 Tcl_Free(pDb->zAuth); 00451 } 00452 if( pDb->zNull ){ 00453 Tcl_Free(pDb->zNull); 00454 } 00455 if( pDb->pUpdateHook ){ 00456 Tcl_DecrRefCount(pDb->pUpdateHook); 00457 } 00458 if( pDb->pRollbackHook ){ 00459 Tcl_DecrRefCount(pDb->pRollbackHook); 00460 } 00461 if( pDb->pCollateNeeded ){ 00462 Tcl_DecrRefCount(pDb->pCollateNeeded); 00463 } 00464 Tcl_Free((char*)pDb); 00465 } 00466 00467 /* 00468 ** This routine is called when a database file is locked while trying 00469 ** to execute SQL. 00470 */ 00471 static int DbBusyHandler(void *cd, int nTries){ 00472 SqliteDb *pDb = (SqliteDb*)cd; 00473 int rc; 00474 char zVal[30]; 00475 00476 sqlite3_snprintf(sizeof(zVal), zVal, "%d", nTries); 00477 rc = Tcl_VarEval(pDb->interp, pDb->zBusy, " ", zVal, (char*)0); 00478 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ 00479 return 0; 00480 } 00481 return 1; 00482 } 00483 00484 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK 00485 /* 00486 ** This routine is invoked as the 'progress callback' for the database. 00487 */ 00488 static int DbProgressHandler(void *cd){ 00489 SqliteDb *pDb = (SqliteDb*)cd; 00490 int rc; 00491 00492 assert( pDb->zProgress ); 00493 rc = Tcl_Eval(pDb->interp, pDb->zProgress); 00494 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ 00495 return 1; 00496 } 00497 return 0; 00498 } 00499 #endif 00500 00501 #ifndef SQLITE_OMIT_TRACE 00502 /* 00503 ** This routine is called by the SQLite trace handler whenever a new 00504 ** block of SQL is executed. The TCL script in pDb->zTrace is executed. 00505 */ 00506 static void DbTraceHandler(void *cd, const char *zSql){ 00507 SqliteDb *pDb = (SqliteDb*)cd; 00508 Tcl_DString str; 00509 00510 Tcl_DStringInit(&str); 00511 Tcl_DStringAppend(&str, pDb->zTrace, -1); 00512 Tcl_DStringAppendElement(&str, zSql); 00513 Tcl_Eval(pDb->interp, Tcl_DStringValue(&str)); 00514 Tcl_DStringFree(&str); 00515 Tcl_ResetResult(pDb->interp); 00516 } 00517 #endif 00518 00519 #ifndef SQLITE_OMIT_TRACE 00520 /* 00521 ** This routine is called by the SQLite profile handler after a statement 00522 ** SQL has executed. The TCL script in pDb->zProfile is evaluated. 00523 */ 00524 static void DbProfileHandler(void *cd, const char *zSql, sqlite_uint64 tm){ 00525 SqliteDb *pDb = (SqliteDb*)cd; 00526 Tcl_DString str; 00527 char zTm[100]; 00528 00529 sqlite3_snprintf(sizeof(zTm)-1, zTm, "%lld", tm); 00530 Tcl_DStringInit(&str); 00531 Tcl_DStringAppend(&str, pDb->zProfile, -1); 00532 Tcl_DStringAppendElement(&str, zSql); 00533 Tcl_DStringAppendElement(&str, zTm); 00534 Tcl_Eval(pDb->interp, Tcl_DStringValue(&str)); 00535 Tcl_DStringFree(&str); 00536 Tcl_ResetResult(pDb->interp); 00537 } 00538 #endif 00539 00540 /* 00541 ** This routine is called when a transaction is committed. The 00542 ** TCL script in pDb->zCommit is executed. If it returns non-zero or 00543 ** if it throws an exception, the transaction is rolled back instead 00544 ** of being committed. 00545 */ 00546 static int DbCommitHandler(void *cd){ 00547 SqliteDb *pDb = (SqliteDb*)cd; 00548 int rc; 00549 00550 rc = Tcl_Eval(pDb->interp, pDb->zCommit); 00551 if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){ 00552 return 1; 00553 } 00554 return 0; 00555 } 00556 00557 static void DbRollbackHandler(void *clientData){ 00558 SqliteDb *pDb = (SqliteDb*)clientData; 00559 assert(pDb->pRollbackHook); 00560 if( TCL_OK!=Tcl_EvalObjEx(pDb->interp, pDb->pRollbackHook, 0) ){ 00561 Tcl_BackgroundError(pDb->interp); 00562 } 00563 } 00564 00565 static void DbUpdateHandler( 00566 void *p, 00567 int op, 00568 const char *zDb, 00569 const char *zTbl, 00570 sqlite_int64 rowid 00571 ){ 00572 SqliteDb *pDb = (SqliteDb *)p; 00573 Tcl_Obj *pCmd; 00574 00575 assert( pDb->pUpdateHook ); 00576 assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE ); 00577 00578 pCmd = Tcl_DuplicateObj(pDb->pUpdateHook); 00579 Tcl_IncrRefCount(pCmd); 00580 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj( 00581 ( (op==SQLITE_INSERT)?"INSERT":(op==SQLITE_UPDATE)?"UPDATE":"DELETE"), -1)); 00582 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1)); 00583 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1)); 00584 Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(rowid)); 00585 Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); 00586 } 00587 00588 static void tclCollateNeeded( 00589 void *pCtx, 00590 sqlite3 *db, 00591 int enc, 00592 const char *zName 00593 ){ 00594 SqliteDb *pDb = (SqliteDb *)pCtx; 00595 Tcl_Obj *pScript = Tcl_DuplicateObj(pDb->pCollateNeeded); 00596 Tcl_IncrRefCount(pScript); 00597 Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zName, -1)); 00598 Tcl_EvalObjEx(pDb->interp, pScript, 0); 00599 Tcl_DecrRefCount(pScript); 00600 } 00601 00602 /* 00603 ** This routine is called to evaluate an SQL collation function implemented 00604 ** using TCL script. 00605 */ 00606 static int tclSqlCollate( 00607 void *pCtx, 00608 int nA, 00609 const void *zA, 00610 int nB, 00611 const void *zB 00612 ){ 00613 SqlCollate *p = (SqlCollate *)pCtx; 00614 Tcl_Obj *pCmd; 00615 00616 pCmd = Tcl_NewStringObj(p->zScript, -1); 00617 Tcl_IncrRefCount(pCmd); 00618 Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA)); 00619 Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB)); 00620 Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT); 00621 Tcl_DecrRefCount(pCmd); 00622 return (atoi(Tcl_GetStringResult(p->interp))); 00623 } 00624 00625 /* 00626 ** This routine is called to evaluate an SQL function implemented 00627 ** using TCL script. 00628 */ 00629 static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){ 00630 SqlFunc *p = sqlite3_user_data(context); 00631 Tcl_Obj *pCmd; 00632 int i; 00633 int rc; 00634 00635 if( argc==0 ){ 00636 /* If there are no arguments to the function, call Tcl_EvalObjEx on the 00637 ** script object directly. This allows the TCL compiler to generate 00638 ** bytecode for the command on the first invocation and thus make 00639 ** subsequent invocations much faster. */ 00640 pCmd = p->pScript; 00641 Tcl_IncrRefCount(pCmd); 00642 rc = Tcl_EvalObjEx(p->interp, pCmd, 0); 00643 Tcl_DecrRefCount(pCmd); 00644 }else{ 00645 /* If there are arguments to the function, make a shallow copy of the 00646 ** script object, lappend the arguments, then evaluate the copy. 00647 ** 00648 ** By "shallow" copy, we mean a only the outer list Tcl_Obj is duplicated. 00649 ** The new Tcl_Obj contains pointers to the original list elements. 00650 ** That way, when Tcl_EvalObjv() is run and shimmers the first element 00651 ** of the list to tclCmdNameType, that alternate representation will 00652 ** be preserved and reused on the next invocation. 00653 */ 00654 Tcl_Obj **aArg; 00655 int nArg; 00656 if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){ 00657 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 00658 return; 00659 } 00660 pCmd = Tcl_NewListObj(nArg, aArg); 00661 Tcl_IncrRefCount(pCmd); 00662 for(i=0; i<argc; i++){ 00663 sqlite3_value *pIn = argv[i]; 00664 Tcl_Obj *pVal; 00665 00666 /* Set pVal to contain the i'th column of this row. */ 00667 switch( sqlite3_value_type(pIn) ){ 00668 case SQLITE_BLOB: { 00669 int bytes = sqlite3_value_bytes(pIn); 00670 pVal = Tcl_NewByteArrayObj(sqlite3_value_blob(pIn), bytes); 00671 break; 00672 } 00673 case SQLITE_INTEGER: { 00674 sqlite_int64 v = sqlite3_value_int64(pIn); 00675 if( v>=-2147483647 && v<=2147483647 ){ 00676 pVal = Tcl_NewIntObj(v); 00677 }else{ 00678 pVal = Tcl_NewWideIntObj(v); 00679 } 00680 break; 00681 } 00682 case SQLITE_FLOAT: { 00683 double r = sqlite3_value_double(pIn); 00684 pVal = Tcl_NewDoubleObj(r); 00685 break; 00686 } 00687 case SQLITE_NULL: { 00688 pVal = Tcl_NewStringObj("", 0); 00689 break; 00690 } 00691 default: { 00692 int bytes = sqlite3_value_bytes(pIn); 00693 pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes); 00694 break; 00695 } 00696 } 00697 rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal); 00698 if( rc ){ 00699 Tcl_DecrRefCount(pCmd); 00700 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 00701 return; 00702 } 00703 } 00704 if( !p->useEvalObjv ){ 00705 /* Tcl_EvalObjEx() will automatically call Tcl_EvalObjv() if pCmd 00706 ** is a list without a string representation. To prevent this from 00707 ** happening, make sure pCmd has a valid string representation */ 00708 Tcl_GetString(pCmd); 00709 } 00710 rc = Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT); 00711 Tcl_DecrRefCount(pCmd); 00712 } 00713 00714 if( rc && rc!=TCL_RETURN ){ 00715 sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 00716 }else{ 00717 Tcl_Obj *pVar = Tcl_GetObjResult(p->interp); 00718 int n; 00719 u8 *data; 00720 char *zType = pVar->typePtr ? pVar->typePtr->name : ""; 00721 char c = zType[0]; 00722 if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){ 00723 /* Only return a BLOB type if the Tcl variable is a bytearray and 00724 ** has no string representation. */ 00725 data = Tcl_GetByteArrayFromObj(pVar, &n); 00726 sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT); 00727 }else if( c=='b' && strcmp(zType,"boolean")==0 ){ 00728 Tcl_GetIntFromObj(0, pVar, &n); 00729 sqlite3_result_int(context, n); 00730 }else if( c=='d' && strcmp(zType,"double")==0 ){ 00731 double r; 00732 Tcl_GetDoubleFromObj(0, pVar, &r); 00733 sqlite3_result_double(context, r); 00734 }else if( (c=='w' && strcmp(zType,"wideInt")==0) || 00735 (c=='i' && strcmp(zType,"int")==0) ){ 00736 Tcl_WideInt v; 00737 Tcl_GetWideIntFromObj(0, pVar, &v); 00738 sqlite3_result_int64(context, v); 00739 }else{ 00740 data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n); 00741 sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT); 00742 } 00743 } 00744 } 00745 00746 #ifndef SQLITE_OMIT_AUTHORIZATION 00747 /* 00748 ** This is the authentication function. It appends the authentication 00749 ** type code and the two arguments to zCmd[] then invokes the result 00750 ** on the interpreter. The reply is examined to determine if the 00751 ** authentication fails or succeeds. 00752 */ 00753 static int auth_callback( 00754 void *pArg, 00755 int code, 00756 const char *zArg1, 00757 const char *zArg2, 00758 const char *zArg3, 00759 const char *zArg4 00760 ){ 00761 char *zCode; 00762 Tcl_DString str; 00763 int rc; 00764 const char *zReply; 00765 SqliteDb *pDb = (SqliteDb*)pArg; 00766 if( pDb->disableAuth ) return SQLITE_OK; 00767 00768 switch( code ){ 00769 case SQLITE_COPY : zCode="SQLITE_COPY"; break; 00770 case SQLITE_CREATE_INDEX : zCode="SQLITE_CREATE_INDEX"; break; 00771 case SQLITE_CREATE_TABLE : zCode="SQLITE_CREATE_TABLE"; break; 00772 case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break; 00773 case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break; 00774 case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break; 00775 case SQLITE_CREATE_TEMP_VIEW : zCode="SQLITE_CREATE_TEMP_VIEW"; break; 00776 case SQLITE_CREATE_TRIGGER : zCode="SQLITE_CREATE_TRIGGER"; break; 00777 case SQLITE_CREATE_VIEW : zCode="SQLITE_CREATE_VIEW"; break; 00778 case SQLITE_DELETE : zCode="SQLITE_DELETE"; break; 00779 case SQLITE_DROP_INDEX : zCode="SQLITE_DROP_INDEX"; break; 00780 case SQLITE_DROP_TABLE : zCode="SQLITE_DROP_TABLE"; break; 00781 case SQLITE_DROP_TEMP_INDEX : zCode="SQLITE_DROP_TEMP_INDEX"; break; 00782 case SQLITE_DROP_TEMP_TABLE : zCode="SQLITE_DROP_TEMP_TABLE"; break; 00783 case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break; 00784 case SQLITE_DROP_TEMP_VIEW : zCode="SQLITE_DROP_TEMP_VIEW"; break; 00785 case SQLITE_DROP_TRIGGER : zCode="SQLITE_DROP_TRIGGER"; break; 00786 case SQLITE_DROP_VIEW : zCode="SQLITE_DROP_VIEW"; break; 00787 case SQLITE_INSERT : zCode="SQLITE_INSERT"; break; 00788 case SQLITE_PRAGMA : zCode="SQLITE_PRAGMA"; break; 00789 case SQLITE_READ : zCode="SQLITE_READ"; break; 00790 case SQLITE_SELECT : zCode="SQLITE_SELECT"; break; 00791 case SQLITE_TRANSACTION : zCode="SQLITE_TRANSACTION"; break; 00792 case SQLITE_UPDATE : zCode="SQLITE_UPDATE"; break; 00793 case SQLITE_ATTACH : zCode="SQLITE_ATTACH"; break; 00794 case SQLITE_DETACH : zCode="SQLITE_DETACH"; break; 00795 case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break; 00796 case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break; 00797 case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break; 00798 case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break; 00799 case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break; 00800 case SQLITE_FUNCTION : zCode="SQLITE_FUNCTION"; break; 00801 default : zCode="????"; break; 00802 } 00803 Tcl_DStringInit(&str); 00804 Tcl_DStringAppend(&str, pDb->zAuth, -1); 00805 Tcl_DStringAppendElement(&str, zCode); 00806 Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : ""); 00807 Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : ""); 00808 Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : ""); 00809 Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : ""); 00810 rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str)); 00811 Tcl_DStringFree(&str); 00812 zReply = Tcl_GetStringResult(pDb->interp); 00813 if( strcmp(zReply,"SQLITE_OK")==0 ){ 00814 rc = SQLITE_OK; 00815 }else if( strcmp(zReply,"SQLITE_DENY")==0 ){ 00816 rc = SQLITE_DENY; 00817 }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){ 00818 rc = SQLITE_IGNORE; 00819 }else{ 00820 rc = 999; 00821 } 00822 return rc; 00823 } 00824 #endif /* SQLITE_OMIT_AUTHORIZATION */ 00825 00826 /* 00827 ** zText is a pointer to text obtained via an sqlite3_result_text() 00828 ** or similar interface. This routine returns a Tcl string object, 00829 ** reference count set to 0, containing the text. If a translation 00830 ** between iso8859 and UTF-8 is required, it is preformed. 00831 */ 00832 static Tcl_Obj *dbTextToObj(char const *zText){ 00833 Tcl_Obj *pVal; 00834 #ifdef UTF_TRANSLATION_NEEDED 00835 Tcl_DString dCol; 00836 Tcl_DStringInit(&dCol); 00837 Tcl_ExternalToUtfDString(NULL, zText, -1, &dCol); 00838 pVal = Tcl_NewStringObj(Tcl_DStringValue(&dCol), -1); 00839 Tcl_DStringFree(&dCol); 00840 #else 00841 pVal = Tcl_NewStringObj(zText, -1); 00842 #endif 00843 return pVal; 00844 } 00845 00846 /* 00847 ** This routine reads a line of text from FILE in, stores 00848 ** the text in memory obtained from malloc() and returns a pointer 00849 ** to the text. NULL is returned at end of file, or if malloc() 00850 ** fails. 00851 ** 00852 ** The interface is like "readline" but no command-line editing 00853 ** is done. 00854 ** 00855 ** copied from shell.c from '.import' command 00856 */ 00857 static char *local_getline(char *zPrompt, FILE *in){ 00858 char *zLine; 00859 int nLine; 00860 int n; 00861 int eol; 00862 00863 nLine = 100; 00864 zLine = malloc( nLine ); 00865 if( zLine==0 ) return 0; 00866 n = 0; 00867 eol = 0; 00868 while( !eol ){ 00869 if( n+100>nLine ){ 00870 nLine = nLine*2 + 100; 00871 zLine = realloc(zLine, nLine); 00872 if( zLine==0 ) return 0; 00873 } 00874 if( fgets(&zLine[n], nLine - n, in)==0 ){ 00875 if( n==0 ){ 00876 free(zLine); 00877 return 0; 00878 } 00879 zLine[n] = 0; 00880 eol = 1; 00881 break; 00882 } 00883 while( zLine[n] ){ n++; } 00884 if( n>0 && zLine[n-1]=='\n' ){ 00885 n--; 00886 zLine[n] = 0; 00887 eol = 1; 00888 } 00889 } 00890 zLine = realloc( zLine, n+1 ); 00891 return zLine; 00892 } 00893 00894 00895 /* 00896 ** Figure out the column names for the data returned by the statement 00897 ** passed as the second argument. 00898 ** 00899 ** If parameter papColName is not NULL, then *papColName is set to point 00900 ** at an array allocated using Tcl_Alloc(). It is the callers responsibility 00901 ** to free this array using Tcl_Free(), and to decrement the reference 00902 ** count of each Tcl_Obj* member of the array. 00903 ** 00904 ** The return value of this function is the number of columns of data 00905 ** returned by pStmt (and hence the size of the *papColName array). 00906 ** 00907 ** If pArray is not NULL, then it contains the name of a Tcl array 00908 ** variable. The "*" member of this array is set to a list containing 00909 ** the names of the columns returned by the statement, in order from 00910 ** left to right. e.g. if the names of the returned columns are a, b and 00911 ** c, it does the equivalent of the tcl command: 00912 ** 00913 ** set ${pArray}(*) {a b c} 00914 */ 00915 static int 00916 computeColumnNames( 00917 Tcl_Interp *interp, 00918 sqlite3_stmt *pStmt, /* SQL statement */ 00919 Tcl_Obj ***papColName, /* OUT: Array of column names */ 00920 Tcl_Obj *pArray /* Name of array variable (may be null) */ 00921 ){ 00922 int nCol; 00923 00924 /* Compute column names */ 00925 nCol = sqlite3_column_count(pStmt); 00926 if( papColName ){ 00927 int i; 00928 Tcl_Obj **apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol ); 00929 for(i=0; i<nCol; i++){ 00930 apColName[i] = dbTextToObj(sqlite3_column_name(pStmt,i)); 00931 Tcl_IncrRefCount(apColName[i]); 00932 } 00933 00934 /* If results are being stored in an array variable, then create 00935 ** the array(*) entry for that array 00936 */ 00937 if( pArray ){ 00938 Tcl_Obj *pColList = Tcl_NewObj(); 00939 Tcl_Obj *pStar = Tcl_NewStringObj("*", -1); 00940 Tcl_IncrRefCount(pColList); 00941 for(i=0; i<nCol; i++){ 00942 Tcl_ListObjAppendElement(interp, pColList, apColName[i]); 00943 } 00944 Tcl_IncrRefCount(pStar); 00945 Tcl_ObjSetVar2(interp, pArray, pStar, pColList,0); 00946 Tcl_DecrRefCount(pColList); 00947 Tcl_DecrRefCount(pStar); 00948 } 00949 *papColName = apColName; 00950 } 00951 00952 return nCol; 00953 } 00954 00955 /* 00956 ** The "sqlite" command below creates a new Tcl command for each 00957 ** connection it opens to an SQLite database. This routine is invoked 00958 ** whenever one of those connection-specific commands is executed 00959 ** in Tcl. For example, if you run Tcl code like this: 00960 ** 00961 ** sqlite3 db1 "my_database" 00962 ** db1 close 00963 ** 00964 ** The first command opens a connection to the "my_database" database 00965 ** and calls that connection "db1". The second command causes this 00966 ** subroutine to be invoked. 00967 */ 00968 static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ 00969 SqliteDb *pDb = (SqliteDb*)cd; 00970 int choice; 00971 int rc = TCL_OK; 00972 static const char *DB_strs[] = { 00973 "authorizer", "busy", "cache", 00974 "changes", "close", "collate", 00975 "collation_needed", "commit_hook", "complete", 00976 "copy", "enable_load_extension","errorcode", 00977 "eval", "exists", "function", 00978 "incrblob", "interrupt", "last_insert_rowid", 00979 "nullvalue", "onecolumn", "profile", 00980 "progress", "rekey", "rollback_hook", 00981 "status", "timeout", "total_changes", 00982 "trace", "transaction", "update_hook", 00983 "version", 0 00984 }; 00985 enum DB_enum { 00986 DB_AUTHORIZER, DB_BUSY, DB_CACHE, 00987 DB_CHANGES, DB_CLOSE, DB_COLLATE, 00988 DB_COLLATION_NEEDED, DB_COMMIT_HOOK, DB_COMPLETE, 00989 DB_COPY, DB_ENABLE_LOAD_EXTENSION,DB_ERRORCODE, 00990 DB_EVAL, DB_EXISTS, DB_FUNCTION, 00991 DB_INCRBLOB, DB_INTERRUPT, DB_LAST_INSERT_ROWID, 00992 DB_NULLVALUE, DB_ONECOLUMN, DB_PROFILE, 00993 DB_PROGRESS, DB_REKEY, DB_ROLLBACK_HOOK, 00994 DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, 00995 DB_TRACE, DB_TRANSACTION, DB_UPDATE_HOOK, 00996 DB_VERSION 00997 }; 00998 /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ 00999 01000 if( objc<2 ){ 01001 Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); 01002 return TCL_ERROR; 01003 } 01004 if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){ 01005 return TCL_ERROR; 01006 } 01007 01008 switch( (enum DB_enum)choice ){ 01009 01010 /* $db authorizer ?CALLBACK? 01011 ** 01012 ** Invoke the given callback to authorize each SQL operation as it is 01013 ** compiled. 5 arguments are appended to the callback before it is 01014 ** invoked: 01015 ** 01016 ** (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...) 01017 ** (2) First descriptive name (depends on authorization type) 01018 ** (3) Second descriptive name 01019 ** (4) Name of the database (ex: "main", "temp") 01020 ** (5) Name of trigger that is doing the access 01021 ** 01022 ** The callback should return on of the following strings: SQLITE_OK, 01023 ** SQLITE_IGNORE, or SQLITE_DENY. Any other return value is an error. 01024 ** 01025 ** If this method is invoked with no arguments, the current authorization 01026 ** callback string is returned. 01027 */ 01028 case DB_AUTHORIZER: { 01029 #ifdef SQLITE_OMIT_AUTHORIZATION 01030 Tcl_AppendResult(interp, "authorization not available in this build", 0); 01031 return TCL_ERROR; 01032 #else 01033 if( objc>3 ){ 01034 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 01035 return TCL_ERROR; 01036 }else if( objc==2 ){ 01037 if( pDb->zAuth ){ 01038 Tcl_AppendResult(interp, pDb->zAuth, 0); 01039 } 01040 }else{ 01041 char *zAuth; 01042 int len; 01043 if( pDb->zAuth ){ 01044 Tcl_Free(pDb->zAuth); 01045 } 01046 zAuth = Tcl_GetStringFromObj(objv[2], &len); 01047 if( zAuth && len>0 ){ 01048 pDb->zAuth = Tcl_Alloc( len + 1 ); 01049 memcpy(pDb->zAuth, zAuth, len+1); 01050 }else{ 01051 pDb->zAuth = 0; 01052 } 01053 if( pDb->zAuth ){ 01054 pDb->interp = interp; 01055 sqlite3_set_authorizer(pDb->db, auth_callback, pDb); 01056 }else{ 01057 sqlite3_set_authorizer(pDb->db, 0, 0); 01058 } 01059 } 01060 #endif 01061 break; 01062 } 01063 01064 /* $db busy ?CALLBACK? 01065 ** 01066 ** Invoke the given callback if an SQL statement attempts to open 01067 ** a locked database file. 01068 */ 01069 case DB_BUSY: { 01070 if( objc>3 ){ 01071 Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK"); 01072 return TCL_ERROR; 01073 }else if( objc==2 ){ 01074 if( pDb->zBusy ){ 01075 Tcl_AppendResult(interp, pDb->zBusy, 0); 01076 } 01077 }else{ 01078 char *zBusy; 01079 int len; 01080 if( pDb->zBusy ){ 01081 Tcl_Free(pDb->zBusy); 01082 } 01083 zBusy = Tcl_GetStringFromObj(objv[2], &len); 01084 if( zBusy && len>0 ){ 01085 pDb->zBusy = Tcl_Alloc( len + 1 ); 01086 memcpy(pDb->zBusy, zBusy, len+1); 01087 }else{ 01088 pDb->zBusy = 0; 01089 } 01090 if( pDb->zBusy ){ 01091 pDb->interp = interp; 01092 sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb); 01093 }else{ 01094 sqlite3_busy_handler(pDb->db, 0, 0); 01095 } 01096 } 01097 break; 01098 } 01099 01100 /* $db cache flush 01101 ** $db cache size n 01102 ** 01103 ** Flush the prepared statement cache, or set the maximum number of 01104 ** cached statements. 01105 */ 01106 case DB_CACHE: { 01107 char *subCmd; 01108 int n; 01109 01110 if( objc<=2 ){ 01111 Tcl_WrongNumArgs(interp, 1, objv, "cache option ?arg?"); 01112 return TCL_ERROR; 01113 } 01114 subCmd = Tcl_GetStringFromObj( objv[2], 0 ); 01115 if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){ 01116 if( objc!=3 ){ 01117 Tcl_WrongNumArgs(interp, 2, objv, "flush"); 01118 return TCL_ERROR; 01119 }else{ 01120 flushStmtCache( pDb ); 01121 } 01122 }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){ 01123 if( objc!=4 ){ 01124 Tcl_WrongNumArgs(interp, 2, objv, "size n"); 01125 return TCL_ERROR; 01126 }else{ 01127 if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){ 01128 Tcl_AppendResult( interp, "cannot convert \"", 01129 Tcl_GetStringFromObj(objv[3],0), "\" to integer", 0); 01130 return TCL_ERROR; 01131 }else{ 01132 if( n<0 ){ 01133 flushStmtCache( pDb ); 01134 n = 0; 01135 }else if( n>MAX_PREPARED_STMTS ){ 01136 n = MAX_PREPARED_STMTS; 01137 } 01138 pDb->maxStmt = n; 01139 } 01140 } 01141 }else{ 01142 Tcl_AppendResult( interp, "bad option \"", 01143 Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", 0); 01144 return TCL_ERROR; 01145 } 01146 break; 01147 } 01148 01149 /* $db changes 01150 ** 01151 ** Return the number of rows that were modified, inserted, or deleted by 01152 ** the most recent INSERT, UPDATE or DELETE statement, not including 01153 ** any changes made by trigger programs. 01154 */ 01155 case DB_CHANGES: { 01156 Tcl_Obj *pResult; 01157 if( objc!=2 ){ 01158 Tcl_WrongNumArgs(interp, 2, objv, ""); 01159 return TCL_ERROR; 01160 } 01161 pResult = Tcl_GetObjResult(interp); 01162 Tcl_SetIntObj(pResult, sqlite3_changes(pDb->db)); 01163 break; 01164 } 01165 01166 /* $db close 01167 ** 01168 ** Shutdown the database 01169 */ 01170 case DB_CLOSE: { 01171 Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0)); 01172 break; 01173 } 01174 01175 /* 01176 ** $db collate NAME SCRIPT 01177 ** 01178 ** Create a new SQL collation function called NAME. Whenever 01179 ** that function is called, invoke SCRIPT to evaluate the function. 01180 */ 01181 case DB_COLLATE: { 01182 SqlCollate *pCollate; 01183 char *zName; 01184 char *zScript; 01185 int nScript; 01186 if( objc!=4 ){ 01187 Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT"); 01188 return TCL_ERROR; 01189 } 01190 zName = Tcl_GetStringFromObj(objv[2], 0); 01191 zScript = Tcl_GetStringFromObj(objv[3], &nScript); 01192 pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 ); 01193 if( pCollate==0 ) return TCL_ERROR; 01194 pCollate->interp = interp; 01195 pCollate->pNext = pDb->pCollate; 01196 pCollate->zScript = (char*)&pCollate[1]; 01197 pDb->pCollate = pCollate; 01198 memcpy(pCollate->zScript, zScript, nScript+1); 01199 if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8, 01200 pCollate, tclSqlCollate) ){ 01201 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); 01202 return TCL_ERROR; 01203 } 01204 break; 01205 } 01206 01207 /* 01208 ** $db collation_needed SCRIPT 01209 ** 01210 ** Create a new SQL collation function called NAME. Whenever 01211 ** that function is called, invoke SCRIPT to evaluate the function. 01212 */ 01213 case DB_COLLATION_NEEDED: { 01214 if( objc!=3 ){ 01215 Tcl_WrongNumArgs(interp, 2, objv, "SCRIPT"); 01216 return TCL_ERROR; 01217 } 01218 if( pDb->pCollateNeeded ){ 01219 Tcl_DecrRefCount(pDb->pCollateNeeded); 01220 } 01221 pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]); 01222 Tcl_IncrRefCount(pDb->pCollateNeeded); 01223 sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded); 01224 break; 01225 } 01226 01227 /* $db commit_hook ?CALLBACK? 01228 ** 01229 ** Invoke the given callback just before committing every SQL transaction. 01230 ** If the callback throws an exception or returns non-zero, then the 01231 ** transaction is aborted. If CALLBACK is an empty string, the callback 01232 ** is disabled. 01233 */ 01234 case DB_COMMIT_HOOK: { 01235 if( objc>3 ){ 01236 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 01237 return TCL_ERROR; 01238 }else if( objc==2 ){ 01239 if( pDb->zCommit ){ 01240 Tcl_AppendResult(interp, pDb->zCommit, 0); 01241 } 01242 }else{ 01243 char *zCommit; 01244 int len; 01245 if( pDb->zCommit ){ 01246 Tcl_Free(pDb->zCommit); 01247 } 01248 zCommit = Tcl_GetStringFromObj(objv[2], &len); 01249 if( zCommit && len>0 ){ 01250 pDb->zCommit = Tcl_Alloc( len + 1 ); 01251 memcpy(pDb->zCommit, zCommit, len+1); 01252 }else{ 01253 pDb->zCommit = 0; 01254 } 01255 if( pDb->zCommit ){ 01256 pDb->interp = interp; 01257 sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb); 01258 }else{ 01259 sqlite3_commit_hook(pDb->db, 0, 0); 01260 } 01261 } 01262 break; 01263 } 01264 01265 /* $db complete SQL 01266 ** 01267 ** Return TRUE if SQL is a complete SQL statement. Return FALSE if 01268 ** additional lines of input are needed. This is similar to the 01269 ** built-in "info complete" command of Tcl. 01270 */ 01271 case DB_COMPLETE: { 01272 #ifndef SQLITE_OMIT_COMPLETE 01273 Tcl_Obj *pResult; 01274 int isComplete; 01275 if( objc!=3 ){ 01276 Tcl_WrongNumArgs(interp, 2, objv, "SQL"); 01277 return TCL_ERROR; 01278 } 01279 isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) ); 01280 pResult = Tcl_GetObjResult(interp); 01281 Tcl_SetBooleanObj(pResult, isComplete); 01282 #endif 01283 break; 01284 } 01285 01286 /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR? 01287 ** 01288 ** Copy data into table from filename, optionally using SEPARATOR 01289 ** as column separators. If a column contains a null string, or the 01290 ** value of NULLINDICATOR, a NULL is inserted for the column. 01291 ** conflict-algorithm is one of the sqlite conflict algorithms: 01292 ** rollback, abort, fail, ignore, replace 01293 ** On success, return the number of lines processed, not necessarily same 01294 ** as 'db changes' due to conflict-algorithm selected. 01295 ** 01296 ** This code is basically an implementation/enhancement of 01297 ** the sqlite3 shell.c ".import" command. 01298 ** 01299 ** This command usage is equivalent to the sqlite2.x COPY statement, 01300 ** which imports file data into a table using the PostgreSQL COPY file format: 01301 ** $db copy $conflit_algo $table_name $filename \t \\N 01302 */ 01303 case DB_COPY: { 01304 char *zTable; /* Insert data into this table */ 01305 char *zFile; /* The file from which to extract data */ 01306 char *zConflict; /* The conflict algorithm to use */ 01307 sqlite3_stmt *pStmt; /* A statement */ 01308 int nCol; /* Number of columns in the table */ 01309 int nByte; /* Number of bytes in an SQL string */ 01310 int i, j; /* Loop counters */ 01311 int nSep; /* Number of bytes in zSep[] */ 01312 int nNull; /* Number of bytes in zNull[] */ 01313 char *zSql; /* An SQL statement */ 01314 char *zLine; /* A single line of input from the file */ 01315 char **azCol; /* zLine[] broken up into columns */ 01316 char *zCommit; /* How to commit changes */ 01317 FILE *in; /* The input file */ 01318 int lineno = 0; /* Line number of input file */ 01319 char zLineNum[80]; /* Line number print buffer */ 01320 Tcl_Obj *pResult; /* interp result */ 01321 01322 char *zSep; 01323 char *zNull; 01324 if( objc<5 || objc>7 ){ 01325 Tcl_WrongNumArgs(interp, 2, objv, 01326 "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?"); 01327 return TCL_ERROR; 01328 } 01329 if( objc>=6 ){ 01330 zSep = Tcl_GetStringFromObj(objv[5], 0); 01331 }else{ 01332 zSep = "\t"; 01333 } 01334 if( objc>=7 ){ 01335 zNull = Tcl_GetStringFromObj(objv[6], 0); 01336 }else{ 01337 zNull = ""; 01338 } 01339 zConflict = Tcl_GetStringFromObj(objv[2], 0); 01340 zTable = Tcl_GetStringFromObj(objv[3], 0); 01341 zFile = Tcl_GetStringFromObj(objv[4], 0); 01342 nSep = strlen(zSep); 01343 nNull = strlen(zNull); 01344 if( nSep==0 ){ 01345 Tcl_AppendResult(interp,"Error: non-null separator required for copy",0); 01346 return TCL_ERROR; 01347 } 01348 if(strcmp(zConflict, "rollback") != 0 && 01349 strcmp(zConflict, "abort" ) != 0 && 01350 strcmp(zConflict, "fail" ) != 0 && 01351 strcmp(zConflict, "ignore" ) != 0 && 01352 strcmp(zConflict, "replace" ) != 0 ) { 01353 Tcl_AppendResult(interp, "Error: \"", zConflict, 01354 "\", conflict-algorithm must be one of: rollback, " 01355 "abort, fail, ignore, or replace", 0); 01356 return TCL_ERROR; 01357 } 01358 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable); 01359 if( zSql==0 ){ 01360 Tcl_AppendResult(interp, "Error: no such table: ", zTable, 0); 01361 return TCL_ERROR; 01362 } 01363 nByte = strlen(zSql); 01364 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); 01365 sqlite3_free(zSql); 01366 if( rc ){ 01367 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0); 01368 nCol = 0; 01369 }else{ 01370 nCol = sqlite3_column_count(pStmt); 01371 } 01372 sqlite3_finalize(pStmt); 01373 if( nCol==0 ) { 01374 return TCL_ERROR; 01375 } 01376 zSql = malloc( nByte + 50 + nCol*2 ); 01377 if( zSql==0 ) { 01378 Tcl_AppendResult(interp, "Error: can't malloc()", 0); 01379 return TCL_ERROR; 01380 } 01381 sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?", 01382 zConflict, zTable); 01383 j = strlen(zSql); 01384 for(i=1; i<nCol; i++){ 01385 zSql[j++] = ','; 01386 zSql[j++] = '?'; 01387 } 01388 zSql[j++] = ')'; 01389 zSql[j] = 0; 01390 rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0); 01391 free(zSql); 01392 if( rc ){ 01393 Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0); 01394 sqlite3_finalize(pStmt); 01395 return TCL_ERROR; 01396 } 01397 in = fopen(zFile, "rb"); 01398 if( in==0 ){ 01399 Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, NULL); 01400 sqlite3_finalize(pStmt); 01401 return TCL_ERROR; 01402 } 01403 azCol = malloc( sizeof(azCol[0])*(nCol+1) ); 01404 if( azCol==0 ) { 01405 Tcl_AppendResult(interp, "Error: can't malloc()", 0); 01406 fclose(in); 01407 return TCL_ERROR; 01408 } 01409 (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0); 01410 zCommit = "COMMIT"; 01411 while( (zLine = local_getline(0, in))!=0 ){ 01412 char *z; 01413 i = 0; 01414 lineno++; 01415 azCol[0] = zLine; 01416 for(i=0, z=zLine; *z; z++){ 01417 if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){ 01418 *z = 0; 01419 i++; 01420 if( i<nCol ){ 01421 azCol[i] = &z[nSep]; 01422 z += nSep-1; 01423 } 01424 } 01425 } 01426 if( i+1!=nCol ){ 01427 char *zErr; 01428 int nErr = strlen(zFile) + 200; 01429 zErr = malloc(nErr); 01430 if( zErr ){ 01431 sqlite3_snprintf(nErr, zErr, 01432 "Error: %s line %d: expected %d columns of data but found %d", 01433 zFile, lineno, nCol, i+1); 01434 Tcl_AppendResult(interp, zErr, 0); 01435 free(zErr); 01436 } 01437 zCommit = "ROLLBACK"; 01438 break; 01439 } 01440 for(i=0; i<nCol; i++){ 01441 /* check for null data, if so, bind as null */ 01442 if ((nNull>0 && strcmp(azCol[i], zNull)==0) || strlen(azCol[i])==0) { 01443 sqlite3_bind_null(pStmt, i+1); 01444 }else{ 01445 sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC); 01446 } 01447 } 01448 sqlite3_step(pStmt); 01449 rc = sqlite3_reset(pStmt); 01450 free(zLine); 01451 if( rc!=SQLITE_OK ){ 01452 Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), 0); 01453 zCommit = "ROLLBACK"; 01454 break; 01455 } 01456 } 01457 free(azCol); 01458 fclose(in); 01459 sqlite3_finalize(pStmt); 01460 (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0); 01461 01462 if( zCommit[0] == 'C' ){ 01463 /* success, set result as number of lines processed */ 01464 pResult = Tcl_GetObjResult(interp); 01465 Tcl_SetIntObj(pResult, lineno); 01466 rc = TCL_OK; 01467 }else{ 01468 /* failure, append lineno where failed */ 01469 sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno); 01470 Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,0); 01471 rc = TCL_ERROR; 01472 } 01473 break; 01474 } 01475 01476 /* 01477 ** $db enable_load_extension BOOLEAN 01478 ** 01479 ** Turn the extension loading feature on or off. It if off by 01480 ** default. 01481 */ 01482 case DB_ENABLE_LOAD_EXTENSION: { 01483 #ifndef SQLITE_OMIT_LOAD_EXTENSION 01484 int onoff; 01485 if( objc!=3 ){ 01486 Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN"); 01487 return TCL_ERROR; 01488 } 01489 if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){ 01490 return TCL_ERROR; 01491 } 01492 sqlite3_enable_load_extension(pDb->db, onoff); 01493 break; 01494 #else 01495 Tcl_AppendResult(interp, "extension loading is turned off at compile-time", 01496 0); 01497 return TCL_ERROR; 01498 #endif 01499 } 01500 01501 /* 01502 ** $db errorcode 01503 ** 01504 ** Return the numeric error code that was returned by the most recent 01505 ** call to sqlite3_exec(). 01506 */ 01507 case DB_ERRORCODE: { 01508 Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db))); 01509 break; 01510 } 01511 01512 /* 01513 ** $db eval $sql ?array? ?{ ...code... }? 01514 ** $db onecolumn $sql 01515 ** 01516 ** The SQL statement in $sql is evaluated. For each row, the values are 01517 ** placed in elements of the array named "array" and ...code... is executed. 01518 ** If "array" and "code" are omitted, then no callback is every invoked. 01519 ** If "array" is an empty string, then the values are placed in variables 01520 ** that have the same name as the fields extracted by the query. 01521 ** 01522 ** The onecolumn method is the equivalent of: 01523 ** lindex [$db eval $sql] 0 01524 */ 01525 case DB_ONECOLUMN: 01526 case DB_EVAL: 01527 case DB_EXISTS: { 01528 char const *zSql; /* Next SQL statement to execute */ 01529 char const *zLeft; /* What is left after first stmt in zSql */ 01530 sqlite3_stmt *pStmt; /* Compiled SQL statment */ 01531 Tcl_Obj *pArray; /* Name of array into which results are written */ 01532 Tcl_Obj *pScript; /* Script to run for each result set */ 01533 Tcl_Obj **apParm; /* Parameters that need a Tcl_DecrRefCount() */ 01534 int nParm; /* Number of entries used in apParm[] */ 01535 Tcl_Obj *aParm[10]; /* Static space for apParm[] in the common case */ 01536 Tcl_Obj *pRet; /* Value to be returned */ 01537 SqlPreparedStmt *pPreStmt; /* Pointer to a prepared statement */ 01538 int rc2; 01539 01540 if( choice==DB_EVAL ){ 01541 if( objc<3 || objc>5 ){ 01542 Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?"); 01543 return TCL_ERROR; 01544 } 01545 pRet = Tcl_NewObj(); 01546 Tcl_IncrRefCount(pRet); 01547 }else{ 01548 if( objc!=3 ){ 01549 Tcl_WrongNumArgs(interp, 2, objv, "SQL"); 01550 return TCL_ERROR; 01551 } 01552 if( choice==DB_EXISTS ){ 01553 pRet = Tcl_NewBooleanObj(0); 01554 Tcl_IncrRefCount(pRet); 01555 }else{ 01556 pRet = 0; 01557 } 01558 } 01559 if( objc==3 ){ 01560 pArray = pScript = 0; 01561 }else if( objc==4 ){ 01562 pArray = 0; 01563 pScript = objv[3]; 01564 }else{ 01565 pArray = objv[3]; 01566 if( Tcl_GetString(pArray)[0]==0 ) pArray = 0; 01567 pScript = objv[4]; 01568 } 01569 01570 Tcl_IncrRefCount(objv[2]); 01571 zSql = Tcl_GetStringFromObj(objv[2], 0); 01572 while( rc==TCL_OK && zSql[0] ){ 01573 int i; /* Loop counter */ 01574 int nVar; /* Number of bind parameters in the pStmt */ 01575 int nCol = -1; /* Number of columns in the result set */ 01576 Tcl_Obj **apColName = 0; /* Array of column names */ 01577 int len; /* String length of zSql */ 01578 01579 /* Try to find a SQL statement that has already been compiled and 01580 ** which matches the next sequence of SQL. 01581 */ 01582 pStmt = 0; 01583 len = strlen(zSql); 01584 for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){ 01585 int n = pPreStmt->nSql; 01586 if( len>=n 01587 && memcmp(pPreStmt->zSql, zSql, n)==0 01588 && (zSql[n]==0 || zSql[n-1]==';') 01589 ){ 01590 pStmt = pPreStmt->pStmt; 01591 zLeft = &zSql[pPreStmt->nSql]; 01592 01593 /* When a prepared statement is found, unlink it from the 01594 ** cache list. It will later be added back to the beginning 01595 ** of the cache list in order to implement LRU replacement. 01596 */ 01597 if( pPreStmt->pPrev ){ 01598 pPreStmt->pPrev->pNext = pPreStmt->pNext; 01599 }else{ 01600 pDb->stmtList = pPreStmt->pNext; 01601 } 01602 if( pPreStmt->pNext ){ 01603 pPreStmt->pNext->pPrev = pPreStmt->pPrev; 01604 }else{ 01605 pDb->stmtLast = pPreStmt->pPrev; 01606 } 01607 pDb->nStmt--; 01608 break; 01609 } 01610 } 01611 01612 /* If no prepared statement was found. Compile the SQL text 01613 */ 01614 if( pStmt==0 ){ 01615 if( SQLITE_OK!=sqlite3_prepare_v2(pDb->db, zSql, -1, &pStmt, &zLeft) ){ 01616 Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db))); 01617 rc = TCL_ERROR; 01618 break; 01619 } 01620 if( pStmt==0 ){ 01621 if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){ 01622 /* A compile-time error in the statement 01623 */ 01624 Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db))); 01625 rc = TCL_ERROR; 01626 break; 01627 }else{ 01628 /* The statement was a no-op. Continue to the next statement 01629 ** in the SQL string. 01630 */ 01631 zSql = zLeft; 01632 continue; 01633 } 01634 } 01635 assert( pPreStmt==0 ); 01636 } 01637 01638 /* Bind values to parameters that begin with $ or : 01639 */ 01640 nVar = sqlite3_bind_parameter_count(pStmt); 01641 nParm = 0; 01642 if( nVar>sizeof(aParm)/sizeof(aParm[0]) ){ 01643 apParm = (Tcl_Obj**)Tcl_Alloc(nVar*sizeof(apParm[0])); 01644 }else{ 01645 apParm = aParm; 01646 } 01647 for(i=1; i<=nVar; i++){ 01648 const char *zVar = sqlite3_bind_parameter_name(pStmt, i); 01649 if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){ 01650 Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0); 01651 if( pVar ){ 01652 int n; 01653 u8 *data; 01654 char *zType = pVar->typePtr ? pVar->typePtr->name : ""; 01655 char c = zType[0]; 01656 if( zVar[0]=='@' || 01657 (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){ 01658 /* Load a BLOB type if the Tcl variable is a bytearray and 01659 ** it has no string representation or the host 01660 ** parameter name begins with "@". */ 01661 data = Tcl_GetByteArrayFromObj(pVar, &n); 01662 sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC); 01663 Tcl_IncrRefCount(pVar); 01664 apParm[nParm++] = pVar; 01665 }else if( c=='b' && strcmp(zType,"boolean")==0 ){ 01666 Tcl_GetIntFromObj(interp, pVar, &n); 01667 sqlite3_bind_int(pStmt, i, n); 01668 }else if( c=='d' && strcmp(zType,"double")==0 ){ 01669 double r; 01670 Tcl_GetDoubleFromObj(interp, pVar, &r); 01671 sqlite3_bind_double(pStmt, i, r); 01672 }else if( (c=='w' && strcmp(zType,"wideInt")==0) || 01673 (c=='i' && strcmp(zType,"int")==0) ){ 01674 Tcl_WideInt v; 01675 Tcl_GetWideIntFromObj(interp, pVar, &v); 01676 sqlite3_bind_int64(pStmt, i, v); 01677 }else{ 01678 data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n); 01679 sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC); 01680 Tcl_IncrRefCount(pVar); 01681 apParm[nParm++] = pVar; 01682 } 01683 }else{ 01684 sqlite3_bind_null( pStmt, i ); 01685 } 01686 } 01687 } 01688 01689 /* Execute the SQL 01690 */ 01691 while( rc==TCL_OK && pStmt && SQLITE_ROW==sqlite3_step(pStmt) ){ 01692 01693 /* Compute column names. This must be done after the first successful 01694 ** call to sqlite3_step(), in case the query is recompiled and the 01695 ** number or names of the returned columns changes. 01696 */ 01697 assert(!pArray||pScript); 01698 if (nCol < 0) { 01699 Tcl_Obj ***ap = (pScript?&apColName:0); 01700 nCol = computeColumnNames(interp, pStmt, ap, pArray); 01701 } 01702 01703 for(i=0; i<nCol; i++){ 01704 Tcl_Obj *pVal; 01705 01706 /* Set pVal to contain the i'th column of this row. */ 01707 switch( sqlite3_column_type(pStmt, i) ){ 01708 case SQLITE_BLOB: { 01709 int bytes = sqlite3_column_bytes(pStmt, i); 01710 const char *zBlob = sqlite3_column_blob(pStmt, i); 01711 if( !zBlob ) bytes = 0; 01712 pVal = Tcl_NewByteArrayObj((u8*)zBlob, bytes); 01713 break; 01714 } 01715 case SQLITE_INTEGER: { 01716 sqlite_int64 v = sqlite3_column_int64(pStmt, i); 01717 if( v>=-2147483647 && v<=2147483647 ){ 01718 pVal = Tcl_NewIntObj(v); 01719 }else{ 01720 pVal = Tcl_NewWideIntObj(v); 01721 } 01722 break; 01723 } 01724 case SQLITE_FLOAT: { 01725 double r = sqlite3_column_double(pStmt, i); 01726 pVal = Tcl_NewDoubleObj(r); 01727 break; 01728 } 01729 case SQLITE_NULL: { 01730 pVal = dbTextToObj(pDb->zNull); 01731 break; 01732 } 01733 default: { 01734 pVal = dbTextToObj((char *)sqlite3_column_text(pStmt, i)); 01735 break; 01736 } 01737 } 01738 01739 if( pScript ){ 01740 if( pArray==0 ){ 01741 Tcl_ObjSetVar2(interp, apColName[i], 0, pVal, 0); 01742 }else{ 01743 Tcl_ObjSetVar2(interp, pArray, apColName[i], pVal, 0); 01744 } 01745 }else if( choice==DB_ONECOLUMN ){ 01746 assert( pRet==0 ); 01747 if( pRet==0 ){ 01748 pRet = pVal; 01749 Tcl_IncrRefCount(pRet); 01750 } 01751 rc = TCL_BREAK; 01752 i = nCol; 01753 }else if( choice==DB_EXISTS ){ 01754 Tcl_DecrRefCount(pRet); 01755 pRet = Tcl_NewBooleanObj(1); 01756 Tcl_IncrRefCount(pRet); 01757 rc = TCL_BREAK; 01758 i = nCol; 01759 }else{ 01760 Tcl_ListObjAppendElement(interp, pRet, pVal); 01761 } 01762 } 01763 01764 if( pScript ){ 01765 pDb->nStep = sqlite3_stmt_status(pStmt, 01766 SQLITE_STMTSTATUS_FULLSCAN_STEP, 0); 01767 pDb->nSort = sqlite3_stmt_status(pStmt, 01768 SQLITE_STMTSTATUS_SORT, 0); 01769 rc = Tcl_EvalObjEx(interp, pScript, 0); 01770 if( rc==TCL_CONTINUE ){ 01771 rc = TCL_OK; 01772 } 01773 } 01774 } 01775 if( rc==TCL_BREAK ){ 01776 rc = TCL_OK; 01777 } 01778 01779 /* Free the column name objects */ 01780 if( pScript ){ 01781 /* If the query returned no rows, but an array variable was 01782 ** specified, call computeColumnNames() now to populate the 01783 ** arrayname(*) variable. 01784 */ 01785 if (pArray && nCol < 0) { 01786 Tcl_Obj ***ap = (pScript?&apColName:0); 01787 nCol = computeColumnNames(interp, pStmt, ap, pArray); 01788 } 01789 for(i=0; i<nCol; i++){ 01790 Tcl_DecrRefCount(apColName[i]); 01791 } 01792 Tcl_Free((char*)apColName); 01793 } 01794 01795 /* Free the bound string and blob parameters */ 01796 for(i=0; i<nParm; i++){ 01797 Tcl_DecrRefCount(apParm[i]); 01798 } 01799 if( apParm!=aParm ){ 01800 Tcl_Free((char*)apParm); 01801 } 01802 01803 /* Reset the statement. If the result code is SQLITE_SCHEMA, then 01804 ** flush the statement cache and try the statement again. 01805 */ 01806 rc2 = sqlite3_reset(pStmt); 01807 pDb->nStep = sqlite3_stmt_status(pStmt, 01808 SQLITE_STMTSTATUS_FULLSCAN_STEP, 1); 01809 pDb->nSort = sqlite3_stmt_status(pStmt, 01810 SQLITE_STMTSTATUS_SORT, 1); 01811 if( SQLITE_OK!=rc2 ){ 01812 /* If a run-time error occurs, report the error and stop reading 01813 ** the SQL 01814 */ 01815 Tcl_SetObjResult(interp, dbTextToObj(sqlite3_errmsg(pDb->db))); 01816 sqlite3_finalize(pStmt); 01817 rc = TCL_ERROR; 01818 if( pPreStmt ) Tcl_Free((char*)pPreStmt); 01819 break; 01820 }else if( pDb->maxStmt<=0 ){ 01821 /* If the cache is turned off, deallocated the statement */ 01822 if( pPreStmt ) Tcl_Free((char*)pPreStmt); 01823 sqlite3_finalize(pStmt); 01824 }else{ 01825 /* Everything worked and the cache is operational. 01826 ** Create a new SqlPreparedStmt structure if we need one. 01827 ** (If we already have one we can just reuse it.) 01828 */ 01829 if( pPreStmt==0 ){ 01830 len = zLeft - zSql; 01831 pPreStmt = (SqlPreparedStmt*)Tcl_Alloc( sizeof(*pPreStmt) ); 01832 if( pPreStmt==0 ) return TCL_ERROR; 01833 pPreStmt->pStmt = pStmt; 01834 pPreStmt->nSql = len; 01835 pPreStmt->zSql = sqlite3_sql(pStmt); 01836 assert( strlen(pPreStmt->zSql)==len ); 01837 assert( 0==memcmp(pPreStmt->zSql, zSql, len) ); 01838 } 01839 01840 /* Add the prepared statement to the beginning of the cache list 01841 */ 01842 pPreStmt->pNext = pDb->stmtList; 01843 pPreStmt->pPrev = 0; 01844 if( pDb->stmtList ){ 01845 pDb->stmtList->pPrev = pPreStmt; 01846 } 01847 pDb->stmtList = pPreStmt; 01848 if( pDb->stmtLast==0 ){ 01849 assert( pDb->nStmt==0 ); 01850 pDb->stmtLast = pPreStmt; 01851 }else{ 01852 assert( pDb->nStmt>0 ); 01853 } 01854 pDb->nStmt++; 01855 01856 /* If we have too many statement in cache, remove the surplus from the 01857 ** end of the cache list. 01858 */ 01859 while( pDb->nStmt>pDb->maxStmt ){ 01860 sqlite3_finalize(pDb->stmtLast->pStmt); 01861 pDb->stmtLast = pDb->stmtLast->pPrev; 01862 Tcl_Free((char*)pDb->stmtLast->pNext); 01863 pDb->stmtLast->pNext = 0; 01864 pDb->nStmt--; 01865 } 01866 } 01867 01868 /* Proceed to the next statement */ 01869 zSql = zLeft; 01870 } 01871 Tcl_DecrRefCount(objv[2]); 01872 01873 if( pRet ){ 01874 if( rc==TCL_OK ){ 01875 Tcl_SetObjResult(interp, pRet); 01876 } 01877 Tcl_DecrRefCount(pRet); 01878 }else if( rc==TCL_OK ){ 01879 Tcl_ResetResult(interp); 01880 } 01881 break; 01882 } 01883 01884 /* 01885 ** $db function NAME [-argcount N] SCRIPT 01886 ** 01887 ** Create a new SQL function called NAME. Whenever that function is 01888 ** called, invoke SCRIPT to evaluate the function. 01889 */ 01890 case DB_FUNCTION: { 01891 SqlFunc *pFunc; 01892 Tcl_Obj *pScript; 01893 char *zName; 01894 int nArg = -1; 01895 if( objc==6 ){ 01896 const char *z = Tcl_GetString(objv[3]); 01897 int n = strlen(z); 01898 if( n>2 && strncmp(z, "-argcount",n)==0 ){ 01899 if( Tcl_GetIntFromObj(interp, objv[4], &nArg) ) return TCL_ERROR; 01900 if( nArg<0 ){ 01901 Tcl_AppendResult(interp, "number of arguments must be non-negative", 01902 (char*)0); 01903 return TCL_ERROR; 01904 } 01905 } 01906 pScript = objv[5]; 01907 }else if( objc!=4 ){ 01908 Tcl_WrongNumArgs(interp, 2, objv, "NAME [-argcount N] SCRIPT"); 01909 return TCL_ERROR; 01910 }else{ 01911 pScript = objv[3]; 01912 } 01913 zName = Tcl_GetStringFromObj(objv[2], 0); 01914 pFunc = findSqlFunc(pDb, zName); 01915 if( pFunc==0 ) return TCL_ERROR; 01916 if( pFunc->pScript ){ 01917 Tcl_DecrRefCount(pFunc->pScript); 01918 } 01919 pFunc->pScript = pScript; 01920 Tcl_IncrRefCount(pScript); 01921 pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript); 01922 rc = sqlite3_create_function(pDb->db, zName, nArg, SQLITE_UTF8, 01923 pFunc, tclSqlFunc, 0, 0); 01924 if( rc!=SQLITE_OK ){ 01925 rc = TCL_ERROR; 01926 Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE); 01927 } 01928 break; 01929 } 01930 01931 /* 01932 ** $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID 01933 */ 01934 case DB_INCRBLOB: { 01935 #ifdef SQLITE_OMIT_INCRBLOB 01936 Tcl_AppendResult(interp, "incrblob not available in this build", 0); 01937 return TCL_ERROR; 01938 #else 01939 int isReadonly = 0; 01940 const char *zDb = "main"; 01941 const char *zTable; 01942 const char *zColumn; 01943 sqlite_int64 iRow; 01944 01945 /* Check for the -readonly option */ 01946 if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){ 01947 isReadonly = 1; 01948 } 01949 01950 if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){ 01951 Tcl_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID"); 01952 return TCL_ERROR; 01953 } 01954 01955 if( objc==(6+isReadonly) ){ 01956 zDb = Tcl_GetString(objv[2]); 01957 } 01958 zTable = Tcl_GetString(objv[objc-3]); 01959 zColumn = Tcl_GetString(objv[objc-2]); 01960 rc = Tcl_GetWideIntFromObj(interp, objv[objc-1], &iRow); 01961 01962 if( rc==TCL_OK ){ 01963 rc = createIncrblobChannel( 01964 interp, pDb, zDb, zTable, zColumn, iRow, isReadonly 01965 ); 01966 } 01967 #endif 01968 break; 01969 } 01970 01971 /* 01972 ** $db interrupt 01973 ** 01974 ** Interrupt the execution of the inner-most SQL interpreter. This 01975 ** causes the SQL statement to return an error of SQLITE_INTERRUPT. 01976 */ 01977 case DB_INTERRUPT: { 01978 sqlite3_interrupt(pDb->db); 01979 break; 01980 } 01981 01982 /* 01983 ** $db nullvalue ?STRING? 01984 ** 01985 ** Change text used when a NULL comes back from the database. If ?STRING? 01986 ** is not present, then the current string used for NULL is returned. 01987 ** If STRING is present, then STRING is returned. 01988 ** 01989 */ 01990 case DB_NULLVALUE: { 01991 if( objc!=2 && objc!=3 ){ 01992 Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE"); 01993 return TCL_ERROR; 01994 } 01995 if( objc==3 ){ 01996 int len; 01997 char *zNull = Tcl_GetStringFromObj(objv[2], &len); 01998 if( pDb->zNull ){ 01999 Tcl_Free(pDb->zNull); 02000 } 02001 if( zNull && len>0 ){ 02002 pDb->zNull = Tcl_Alloc( len + 1 ); 02003 strncpy(pDb->zNull, zNull, len); 02004 pDb->zNull[len] = '\0'; 02005 }else{ 02006 pDb->zNull = 0; 02007 } 02008 } 02009 Tcl_SetObjResult(interp, dbTextToObj(pDb->zNull)); 02010 break; 02011 } 02012 02013 /* 02014 ** $db last_insert_rowid 02015 ** 02016 ** Return an integer which is the ROWID for the most recent insert. 02017 */ 02018 case DB_LAST_INSERT_ROWID: { 02019 Tcl_Obj *pResult; 02020 Tcl_WideInt rowid; 02021 if( objc!=2 ){ 02022 Tcl_WrongNumArgs(interp, 2, objv, ""); 02023 return TCL_ERROR; 02024 } 02025 rowid = sqlite3_last_insert_rowid(pDb->db); 02026 pResult = Tcl_GetObjResult(interp); 02027 Tcl_SetWideIntObj(pResult, rowid); 02028 break; 02029 } 02030 02031 /* 02032 ** The DB_ONECOLUMN method is implemented together with DB_EVAL. 02033 */ 02034 02035 /* $db progress ?N CALLBACK? 02036 ** 02037 ** Invoke the given callback every N virtual machine opcodes while executing 02038 ** queries. 02039 */ 02040 case DB_PROGRESS: { 02041 if( objc==2 ){ 02042 if( pDb->zProgress ){ 02043 Tcl_AppendResult(interp, pDb->zProgress, 0); 02044 } 02045 }else if( objc==4 ){ 02046 char *zProgress; 02047 int len; 02048 int N; 02049 if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){ 02050 return TCL_ERROR; 02051 }; 02052 if( pDb->zProgress ){ 02053 Tcl_Free(pDb->zProgress); 02054 } 02055 zProgress = Tcl_GetStringFromObj(objv[3], &len); 02056 if( zProgress && len>0 ){ 02057 pDb->zProgress = Tcl_Alloc( len + 1 ); 02058 memcpy(pDb->zProgress, zProgress, len+1); 02059 }else{ 02060 pDb->zProgress = 0; 02061 } 02062 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK 02063 if( pDb->zProgress ){ 02064 pDb->interp = interp; 02065 sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb); 02066 }else{ 02067 sqlite3_progress_handler(pDb->db, 0, 0, 0); 02068 } 02069 #endif 02070 }else{ 02071 Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK"); 02072 return TCL_ERROR; 02073 } 02074 break; 02075 } 02076 02077 /* $db profile ?CALLBACK? 02078 ** 02079 ** Make arrangements to invoke the CALLBACK routine after each SQL statement 02080 ** that has run. The text of the SQL and the amount of elapse time are 02081 ** appended to CALLBACK before the script is run. 02082 */ 02083 case DB_PROFILE: { 02084 if( objc>3 ){ 02085 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 02086 return TCL_ERROR; 02087 }else if( objc==2 ){ 02088 if( pDb->zProfile ){ 02089 Tcl_AppendResult(interp, pDb->zProfile, 0); 02090 } 02091 }else{ 02092 char *zProfile; 02093 int len; 02094 if( pDb->zProfile ){ 02095 Tcl_Free(pDb->zProfile); 02096 } 02097 zProfile = Tcl_GetStringFromObj(objv[2], &len); 02098 if( zProfile && len>0 ){ 02099 pDb->zProfile = Tcl_Alloc( len + 1 ); 02100 memcpy(pDb->zProfile, zProfile, len+1); 02101 }else{ 02102 pDb->zProfile = 0; 02103 } 02104 #ifndef SQLITE_OMIT_TRACE 02105 if( pDb->zProfile ){ 02106 pDb->interp = interp; 02107 sqlite3_profile(pDb->db, DbProfileHandler, pDb); 02108 }else{ 02109 sqlite3_profile(pDb->db, 0, 0); 02110 } 02111 #endif 02112 } 02113 break; 02114 } 02115 02116 /* 02117 ** $db rekey KEY 02118 ** 02119 ** Change the encryption key on the currently open database. 02120 */ 02121 case DB_REKEY: { 02122 int nKey; 02123 void *pKey; 02124 if( objc!=3 ){ 02125 Tcl_WrongNumArgs(interp, 2, objv, "KEY"); 02126 return TCL_ERROR; 02127 } 02128 pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey); 02129 #ifdef SQLITE_HAS_CODEC 02130 rc = sqlite3_rekey(pDb->db, pKey, nKey); 02131 if( rc ){ 02132 Tcl_AppendResult(interp, sqlite3ErrStr(rc), 0); 02133 rc = TCL_ERROR; 02134 } 02135 #endif 02136 break; 02137 } 02138 02139 /* 02140 ** $db status (step|sort) 02141 ** 02142 ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or 02143 ** SQLITE_STMTSTATUS_SORT for the most recent eval. 02144 */ 02145 case DB_STATUS: { 02146 int v; 02147 const char *zOp; 02148 if( objc!=3 ){ 02149 Tcl_WrongNumArgs(interp, 2, objv, "(step|sort)"); 02150 return TCL_ERROR; 02151 } 02152 zOp = Tcl_GetString(objv[2]); 02153 if( strcmp(zOp, "step")==0 ){ 02154 v = pDb->nStep; 02155 }else if( strcmp(zOp, "sort")==0 ){ 02156 v = pDb->nSort; 02157 }else{ 02158 Tcl_AppendResult(interp, "bad argument: should be step or sort", 02159 (char*)0); 02160 return TCL_ERROR; 02161 } 02162 Tcl_SetObjResult(interp, Tcl_NewIntObj(v)); 02163 break; 02164 } 02165 02166 /* 02167 ** $db timeout MILLESECONDS 02168 ** 02169 ** Delay for the number of milliseconds specified when a file is locked. 02170 */ 02171 case DB_TIMEOUT: { 02172 int ms; 02173 if( objc!=3 ){ 02174 Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS"); 02175 return TCL_ERROR; 02176 } 02177 if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR; 02178 sqlite3_busy_timeout(pDb->db, ms); 02179 break; 02180 } 02181 02182 /* 02183 ** $db total_changes 02184 ** 02185 ** Return the number of rows that were modified, inserted, or deleted 02186 ** since the database handle was created. 02187 */ 02188 case DB_TOTAL_CHANGES: { 02189 Tcl_Obj *pResult; 02190 if( objc!=2 ){ 02191 Tcl_WrongNumArgs(interp, 2, objv, ""); 02192 return TCL_ERROR; 02193 } 02194 pResult = Tcl_GetObjResult(interp); 02195 Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db)); 02196 break; 02197 } 02198 02199 /* $db trace ?CALLBACK? 02200 ** 02201 ** Make arrangements to invoke the CALLBACK routine for each SQL statement 02202 ** that is executed. The text of the SQL is appended to CALLBACK before 02203 ** it is executed. 02204 */ 02205 case DB_TRACE: { 02206 if( objc>3 ){ 02207 Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?"); 02208 return TCL_ERROR; 02209 }else if( objc==2 ){ 02210 if( pDb->zTrace ){ 02211 Tcl_AppendResult(interp, pDb->zTrace, 0); 02212 } 02213 }else{ 02214 char *zTrace; 02215 int len; 02216 if( pDb->zTrace ){ 02217 Tcl_Free(pDb->zTrace); 02218 } 02219 zTrace = Tcl_GetStringFromObj(objv[2], &len); 02220 if( zTrace && len>0 ){ 02221 pDb->zTrace = Tcl_Alloc( len + 1 ); 02222 memcpy(pDb->zTrace, zTrace, len+1); 02223 }else{ 02224 pDb->zTrace = 0; 02225 } 02226 #ifndef SQLITE_OMIT_TRACE 02227 if( pDb->zTrace ){ 02228 pDb->interp = interp; 02229 sqlite3_trace(pDb->db, DbTraceHandler, pDb); 02230 }else{ 02231 sqlite3_trace(pDb->db, 0, 0); 02232 } 02233 #endif 02234 } 02235 break; 02236 } 02237 02238 /* $db transaction [-deferred|-immediate|-exclusive] SCRIPT 02239 ** 02240 ** Start a new transaction (if we are not already in the midst of a 02241 ** transaction) and execute the TCL script SCRIPT. After SCRIPT 02242 ** completes, either commit the transaction or roll it back if SCRIPT 02243 ** throws an exception. Or if no new transation was started, do nothing. 02244 ** pass the exception on up the stack. 02245 ** 02246 ** This command was inspired by Dave Thomas's talk on Ruby at the 02247 ** 2005 O'Reilly Open Source Convention (OSCON). 02248 */ 02249 case DB_TRANSACTION: { 02250 int inTrans; 02251 Tcl_Obj *pScript; 02252 const char *zBegin = "BEGIN"; 02253 if( objc!=3 && objc!=4 ){ 02254 Tcl_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT"); 02255 return TCL_ERROR; 02256 } 02257 if( objc==3 ){ 02258 pScript = objv[2]; 02259 } else { 02260 static const char *TTYPE_strs[] = { 02261 "deferred", "exclusive", "immediate", 0 02262 }; 02263 enum TTYPE_enum { 02264 TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE 02265 }; 02266 int ttype; 02267 if( Tcl_GetIndexFromObj(interp, objv[2], TTYPE_strs, "transaction type", 02268 0, &ttype) ){ 02269 return TCL_ERROR; 02270 } 02271 switch( (enum TTYPE_enum)ttype ){ 02272 case TTYPE_DEFERRED: /* no-op */; break; 02273 case TTYPE_EXCLUSIVE: zBegin = "BEGIN EXCLUSIVE"; break; 02274 case TTYPE_IMMEDIATE: zBegin = "BEGIN IMMEDIATE"; break; 02275 } 02276 pScript = objv[3]; 02277 } 02278 inTrans = !sqlite3_get_autocommit(pDb->db); 02279 if( !inTrans ){ 02280 pDb->disableAuth++; 02281 (void)sqlite3_exec(pDb->db, zBegin, 0, 0, 0); 02282 pDb->disableAuth--; 02283 } 02284 rc = Tcl_EvalObjEx(interp, pScript, 0); 02285 if( !inTrans ){ 02286 const char *zEnd; 02287 if( rc==TCL_ERROR ){ 02288 zEnd = "ROLLBACK"; 02289 } else { 02290 zEnd = "COMMIT"; 02291 } 02292 pDb->disableAuth++; 02293 if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){ 02294 sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0); 02295 } 02296 pDb->disableAuth--; 02297 } 02298 break; 02299 } 02300 02301 /* 02302 ** $db update_hook ?script? 02303 ** $db rollback_hook ?script? 02304 */ 02305 case DB_UPDATE_HOOK: 02306 case DB_ROLLBACK_HOOK: { 02307 02308 /* set ppHook to point at pUpdateHook or pRollbackHook, depending on 02309 ** whether [$db update_hook] or [$db rollback_hook] was invoked. 02310 */ 02311 Tcl_Obj **ppHook; 02312 if( choice==DB_UPDATE_HOOK ){ 02313 ppHook = &pDb->pUpdateHook; 02314 }else{ 02315 ppHook = &pDb->pRollbackHook; 02316 } 02317 02318 if( objc!=2 && objc!=3 ){ 02319 Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?"); 02320 return TCL_ERROR; 02321 } 02322 if( *ppHook ){ 02323 Tcl_SetObjResult(interp, *ppHook); 02324 if( objc==3 ){ 02325 Tcl_DecrRefCount(*ppHook); 02326 *ppHook = 0; 02327 } 02328 } 02329 if( objc==3 ){ 02330 assert( !(*ppHook) ); 02331 if( Tcl_GetCharLength(objv[2])>0 ){ 02332 *ppHook = objv[2]; 02333 Tcl_IncrRefCount(*ppHook); 02334 } 02335 } 02336 02337 sqlite3_update_hook(pDb->db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb); 02338 sqlite3_rollback_hook(pDb->db,(pDb->pRollbackHook?DbRollbackHandler:0),pDb); 02339 02340 break; 02341 } 02342 02343 /* $db version 02344 ** 02345 ** Return the version string for this database. 02346 */ 02347 case DB_VERSION: { 02348 Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC); 02349 break; 02350 } 02351 02352 02353 } /* End of the SWITCH statement */ 02354 return rc; 02355 } 02356 02357 /* 02358 ** sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN? 02359 ** ?-create BOOLEAN? ?-nomutex BOOLEAN? 02360 ** 02361 ** This is the main Tcl command. When the "sqlite" Tcl command is 02362 ** invoked, this routine runs to process that command. 02363 ** 02364 ** The first argument, DBNAME, is an arbitrary name for a new 02365 ** database connection. This command creates a new command named 02366 ** DBNAME that is used to control that connection. The database 02367 ** connection is deleted when the DBNAME command is deleted. 02368 ** 02369 ** The second argument is the name of the database file. 02370 ** 02371 */ 02372 static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){ 02373 SqliteDb *p; 02374 void *pKey = 0; 02375 int nKey = 0; 02376 const char *zArg; 02377 char *zErrMsg; 02378 int i; 02379 const char *zFile; 02380 const char *zVfs = 0; 02381 int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX; 02382 Tcl_DString translatedFilename; 02383 if( objc==2 ){ 02384 zArg = Tcl_GetStringFromObj(objv[1], 0); 02385 if( strcmp(zArg,"-version")==0 ){ 02386 Tcl_AppendResult(interp,sqlite3_version,0); 02387 return TCL_OK; 02388 } 02389 if( strcmp(zArg,"-has-codec")==0 ){ 02390 #ifdef SQLITE_HAS_CODEC 02391 Tcl_AppendResult(interp,"1",0); 02392 #else 02393 Tcl_AppendResult(interp,"0",0); 02394 #endif 02395 return TCL_OK; 02396 } 02397 } 02398 for(i=3; i+1<objc; i+=2){ 02399 zArg = Tcl_GetString(objv[i]); 02400 if( strcmp(zArg,"-key")==0 ){ 02401 pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey); 02402 }else if( strcmp(zArg, "-vfs")==0 ){ 02403 i++; 02404 zVfs = Tcl_GetString(objv[i]); 02405 }else if( strcmp(zArg, "-readonly")==0 ){ 02406 int b; 02407 if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; 02408 if( b ){ 02409 flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); 02410 flags |= SQLITE_OPEN_READONLY; 02411 }else{ 02412 flags &= ~SQLITE_OPEN_READONLY; 02413 flags |= SQLITE_OPEN_READWRITE; 02414 } 02415 }else if( strcmp(zArg, "-create")==0 ){ 02416 int b; 02417 if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; 02418 if( b && (flags & SQLITE_OPEN_READONLY)==0 ){ 02419 flags |= SQLITE_OPEN_CREATE; 02420 }else{ 02421 flags &= ~SQLITE_OPEN_CREATE; 02422 } 02423 }else if( strcmp(zArg, "-nomutex")==0 ){ 02424 int b; 02425 if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; 02426 if( b ){ 02427 flags |= SQLITE_OPEN_NOMUTEX; 02428 flags &= ~SQLITE_OPEN_FULLMUTEX; 02429 }else{ 02430 flags &= ~SQLITE_OPEN_NOMUTEX; 02431 } 02432 }else if( strcmp(zArg, "-fullmutex")==0 ){ 02433 int b; 02434 if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; 02435 if( b ){ 02436 flags |= SQLITE_OPEN_FULLMUTEX; 02437 flags &= ~SQLITE_OPEN_NOMUTEX; 02438 }else{ 02439 flags &= ~SQLITE_OPEN_FULLMUTEX; 02440 } 02441 }else{ 02442 Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); 02443 return TCL_ERROR; 02444 } 02445 } 02446 if( objc<3 || (objc&1)!=1 ){ 02447 Tcl_WrongNumArgs(interp, 1, objv, 02448 "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?" 02449 " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN?" 02450 #ifdef SQLITE_HAS_CODEC 02451 " ?-key CODECKEY?" 02452 #endif 02453 ); 02454 return TCL_ERROR; 02455 } 02456 zErrMsg = 0; 02457 p = (SqliteDb*)Tcl_Alloc( sizeof(*p) ); 02458 if( p==0 ){ 02459 Tcl_SetResult(interp, "malloc failed", TCL_STATIC); 02460 return TCL_ERROR; 02461 } 02462 memset(p, 0, sizeof(*p)); 02463 zFile = Tcl_GetStringFromObj(objv[2], 0); 02464 zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename); 02465 sqlite3_open_v2(zFile, &p->db, flags, zVfs); 02466 Tcl_DStringFree(&translatedFilename); 02467 if( SQLITE_OK!=sqlite3_errcode(p->db) ){ 02468 zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db)); 02469 sqlite3_close(p->db); 02470 p->db = 0; 02471 } 02472 #ifdef SQLITE_HAS_CODEC 02473 if( p->db ){ 02474 sqlite3_key(p->db, pKey, nKey); 02475 } 02476 #endif 02477 if( p->db==0 ){ 02478 Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE); 02479 Tcl_Free((char*)p); 02480 sqlite3_free(zErrMsg); 02481 return TCL_ERROR; 02482 } 02483 p->maxStmt = NUM_PREPARED_STMTS; 02484 p->interp = interp; 02485 zArg = Tcl_GetStringFromObj(objv[1], 0); 02486 Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd); 02487 return TCL_OK; 02488 } 02489 02490 /* 02491 ** Provide a dummy Tcl_InitStubs if we are using this as a static 02492 ** library. 02493 */ 02494 #ifndef USE_TCL_STUBS 02495 # undef Tcl_InitStubs 02496 # define Tcl_InitStubs(a,b,c) 02497 #endif 02498 02499 /* 02500 ** Make sure we have a PACKAGE_VERSION macro defined. This will be 02501 ** defined automatically by the TEA makefile. But other makefiles 02502 ** do not define it. 02503 */ 02504 #ifndef PACKAGE_VERSION 02505 # define PACKAGE_VERSION SQLITE_VERSION 02506 #endif 02507 02508 /* 02509 ** Initialize this module. 02510 ** 02511 ** This Tcl module contains only a single new Tcl command named "sqlite". 02512 ** (Hence there is no namespace. There is no point in using a namespace 02513 ** if the extension only supplies one new name!) The "sqlite" command is 02514 ** used to open a new SQLite database. See the DbMain() routine above 02515 ** for additional information. 02516 */ 02517 EXTERN int Sqlite3_Init(Tcl_Interp *interp){ 02518 Tcl_InitStubs(interp, "8.4", 0); 02519 Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0); 02520 Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION); 02521 Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0); 02522 Tcl_PkgProvide(interp, "sqlite", PACKAGE_VERSION); 02523 return TCL_OK; 02524 } 02525 EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } 02526 EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; } 02527 EXTERN int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; } 02528 EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } 02529 EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } 02530 EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; } 02531 EXTERN int Tclsqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;} 02532 02533 02534 #ifndef SQLITE_3_SUFFIX_ONLY 02535 EXTERN int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } 02536 EXTERN int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); } 02537 EXTERN int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; } 02538 EXTERN int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; } 02539 EXTERN int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } 02540 EXTERN int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; } 02541 EXTERN int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; } 02542 EXTERN int Tclsqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;} 02543 #endif 02544 02545 #ifdef TCLSH 02546 /***************************************************************************** 02547 ** The code that follows is used to build standalone TCL interpreters 02548 ** that are statically linked with SQLite. 02549 */ 02550 02551 /* 02552 ** If the macro TCLSH is one, then put in code this for the 02553 ** "main" routine that will initialize Tcl and take input from 02554 ** standard input, or if a file is named on the command line 02555 ** the TCL interpreter reads and evaluates that file. 02556 */ 02557 #if TCLSH==1 02558 static char zMainloop[] = 02559 "set line {}\n" 02560 "while {![eof stdin]} {\n" 02561 "if {$line!=\"\"} {\n" 02562 "puts -nonewline \"> \"\n" 02563 "} else {\n" 02564 "puts -nonewline \"% \"\n" 02565 "}\n" 02566 "flush stdout\n" 02567 "append line [gets stdin]\n" 02568 "if {[info complete $line]} {\n" 02569 "if {[catch {uplevel #0 $line} result]} {\n" 02570 "puts stderr \"Error: $result\"\n" 02571 "} elseif {$result!=\"\"} {\n" 02572 "puts $result\n" 02573 "}\n" 02574 "set line {}\n" 02575 "} else {\n" 02576 "append line \\n\n" 02577 "}\n" 02578 "}\n" 02579 ; 02580 #endif 02581 02582 /* 02583 ** If the macro TCLSH is two, then get the main loop code out of 02584 ** the separate file "spaceanal_tcl.h". 02585 */ 02586 #if TCLSH==2 02587 static char zMainloop[] = 02588 #include "spaceanal_tcl.h" 02589 ; 02590 #endif 02591 02592 #define TCLSH_MAIN main /* Needed to fake out mktclapp */ 02593 int TCLSH_MAIN(int argc, char **argv){ 02594 Tcl_Interp *interp; 02595 Tcl_FindExecutable(argv[0]); 02596 interp = Tcl_CreateInterp(); 02597 Sqlite3_Init(interp); 02598 #ifdef SQLITE_TEST 02599 { 02600 extern int Md5_Init(Tcl_Interp*); 02601 extern int Sqliteconfig_Init(Tcl_Interp*); 02602 extern int Sqlitetest1_Init(Tcl_Interp*); 02603 extern int Sqlitetest2_Init(Tcl_Interp*); 02604 extern int Sqlitetest3_Init(Tcl_Interp*); 02605 extern int Sqlitetest4_Init(Tcl_Interp*); 02606 extern int Sqlitetest5_Init(Tcl_Interp*); 02607 extern int Sqlitetest6_Init(Tcl_Interp*); 02608 extern int Sqlitetest7_Init(Tcl_Interp*); 02609 extern int Sqlitetest8_Init(Tcl_Interp*); 02610 extern int Sqlitetest9_Init(Tcl_Interp*); 02611 extern int Sqlitetestasync_Init(Tcl_Interp*); 02612 extern int Sqlitetest_autoext_Init(Tcl_Interp*); 02613 extern int Sqlitetest_func_Init(Tcl_Interp*); 02614 extern int Sqlitetest_hexio_Init(Tcl_Interp*); 02615 extern int Sqlitetest_malloc_Init(Tcl_Interp*); 02616 extern int Sqlitetest_mutex_Init(Tcl_Interp*); 02617 extern int Sqlitetestschema_Init(Tcl_Interp*); 02618 extern int Sqlitetestsse_Init(Tcl_Interp*); 02619 extern int Sqlitetesttclvar_Init(Tcl_Interp*); 02620 extern int SqlitetestThread_Init(Tcl_Interp*); 02621 extern int SqlitetestOnefile_Init(); 02622 extern int SqlitetestOsinst_Init(Tcl_Interp*); 02623 02624 Md5_Init(interp); 02625 Sqliteconfig_Init(interp); 02626 Sqlitetest1_Init(interp); 02627 Sqlitetest2_Init(interp); 02628 Sqlitetest3_Init(interp); 02629 Sqlitetest4_Init(interp); 02630 Sqlitetest5_Init(interp); 02631 Sqlitetest6_Init(interp); 02632 Sqlitetest7_Init(interp); 02633 Sqlitetest8_Init(interp); 02634 Sqlitetest9_Init(interp); 02635 Sqlitetestasync_Init(interp); 02636 Sqlitetest_autoext_Init(interp); 02637 Sqlitetest_func_Init(interp); 02638 Sqlitetest_hexio_Init(interp); 02639 Sqlitetest_malloc_Init(interp); 02640 Sqlitetest_mutex_Init(interp); 02641 Sqlitetestschema_Init(interp); 02642 Sqlitetesttclvar_Init(interp); 02643 SqlitetestThread_Init(interp); 02644 SqlitetestOnefile_Init(interp); 02645 SqlitetestOsinst_Init(interp); 02646 02647 #ifdef SQLITE_SSE 02648 Sqlitetestsse_Init(interp); 02649 #endif 02650 } 02651 #endif 02652 if( argc>=2 || TCLSH==2 ){ 02653 int i; 02654 char zArgc[32]; 02655 sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH)); 02656 Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY); 02657 Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY); 02658 Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY); 02659 for(i=3-TCLSH; i<argc; i++){ 02660 Tcl_SetVar(interp, "argv", argv[i], 02661 TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE); 02662 } 02663 if( TCLSH==1 && Tcl_EvalFile(interp, argv[1])!=TCL_OK ){ 02664 const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY); 02665 if( zInfo==0 ) zInfo = interp->result; 02666 fprintf(stderr,"%s: %s\n", *argv, zInfo); 02667 return 1; 02668 } 02669 } 02670 if( argc<=1 || TCLSH==2 ){ 02671 Tcl_GlobalEval(interp, zMainloop); 02672 } 02673 return 0; 02674 } 02675 #endif /* TCLSH */
ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:56 2011 by Doxygen 1.6.1