tclsqlite.c

Go to the documentation of this file.
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