000001  /*
000002  ** 2001 September 15
000003  **
000004  ** The author disclaims copyright to this source code.  In place of
000005  ** a legal notice, here is a blessing:
000006  **
000007  **    May you do good and not evil.
000008  **    May you find forgiveness for yourself and forgive others.
000009  **    May you share freely, never taking more than you give.
000010  **
000011  *************************************************************************
000012  ** A TCL Interface to SQLite.  Append this file to sqlite3.c and
000013  ** compile the whole thing to build a TCL-enabled version of SQLite.
000014  **
000015  ** Compile-time options:
000016  **
000017  **  -DTCLSH         Add a "main()" routine that works as a tclsh.
000018  **
000019  **  -DTCLSH_INIT_PROC=name
000020  **
000021  **                  Invoke name(interp) to initialize the Tcl interpreter.
000022  **                  If name(interp) returns a non-NULL string, then run
000023  **                  that string as a Tcl script to launch the application.
000024  **                  If name(interp) returns NULL, then run the regular
000025  **                  tclsh-emulator code.
000026  */
000027  #ifdef TCLSH_INIT_PROC
000028  # define TCLSH 1
000029  #endif
000030  
000031  /*
000032  ** If requested, include the SQLite compiler options file for MSVC.
000033  */
000034  #if defined(INCLUDE_MSVC_H)
000035  # include "msvc.h"
000036  #endif
000037  
000038  #if defined(INCLUDE_SQLITE_TCL_H)
000039  # include "sqlite_tcl.h"
000040  #else
000041  # include "tcl.h"
000042  # ifndef SQLITE_TCLAPI
000043  #  define SQLITE_TCLAPI
000044  # endif
000045  #endif
000046  #include <errno.h>
000047  
000048  /*
000049  ** Some additional include files are needed if this file is not
000050  ** appended to the amalgamation.
000051  */
000052  #ifndef SQLITE_AMALGAMATION
000053  # include "sqlite3.h"
000054  # include <stdlib.h>
000055  # include <string.h>
000056  # include <assert.h>
000057    typedef unsigned char u8;
000058  #endif
000059  #include <ctype.h>
000060  
000061  /* Used to get the current process ID */
000062  #if !defined(_WIN32)
000063  # include <unistd.h>
000064  # define GETPID getpid
000065  #elif !defined(_WIN32_WCE)
000066  # ifndef SQLITE_AMALGAMATION
000067  #  define WIN32_LEAN_AND_MEAN
000068  #  include <windows.h>
000069  # endif
000070  # define GETPID (int)GetCurrentProcessId
000071  #endif
000072  
000073  /*
000074   * Windows needs to know which symbols to export.  Unix does not.
000075   * BUILD_sqlite should be undefined for Unix.
000076   */
000077  #ifdef BUILD_sqlite
000078  #undef TCL_STORAGE_CLASS
000079  #define TCL_STORAGE_CLASS DLLEXPORT
000080  #endif /* BUILD_sqlite */
000081  
000082  #define NUM_PREPARED_STMTS 10
000083  #define MAX_PREPARED_STMTS 100
000084  
000085  /* Forward declaration */
000086  typedef struct SqliteDb SqliteDb;
000087  
000088  /*
000089  ** New SQL functions can be created as TCL scripts.  Each such function
000090  ** is described by an instance of the following structure.
000091  */
000092  typedef struct SqlFunc SqlFunc;
000093  struct SqlFunc {
000094    Tcl_Interp *interp;   /* The TCL interpret to execute the function */
000095    Tcl_Obj *pScript;     /* The Tcl_Obj representation of the script */
000096    SqliteDb *pDb;        /* Database connection that owns this function */
000097    int useEvalObjv;      /* True if it is safe to use Tcl_EvalObjv */
000098    char *zName;          /* Name of this function */
000099    SqlFunc *pNext;       /* Next function on the list of them all */
000100  };
000101  
000102  /*
000103  ** New collation sequences function can be created as TCL scripts.  Each such
000104  ** function is described by an instance of the following structure.
000105  */
000106  typedef struct SqlCollate SqlCollate;
000107  struct SqlCollate {
000108    Tcl_Interp *interp;   /* The TCL interpret to execute the function */
000109    char *zScript;        /* The script to be run */
000110    SqlCollate *pNext;    /* Next function on the list of them all */
000111  };
000112  
000113  /*
000114  ** Prepared statements are cached for faster execution.  Each prepared
000115  ** statement is described by an instance of the following structure.
000116  */
000117  typedef struct SqlPreparedStmt SqlPreparedStmt;
000118  struct SqlPreparedStmt {
000119    SqlPreparedStmt *pNext;  /* Next in linked list */
000120    SqlPreparedStmt *pPrev;  /* Previous on the list */
000121    sqlite3_stmt *pStmt;     /* The prepared statement */
000122    int nSql;                /* chars in zSql[] */
000123    const char *zSql;        /* Text of the SQL statement */
000124    int nParm;               /* Size of apParm array */
000125    Tcl_Obj **apParm;        /* Array of referenced object pointers */
000126  };
000127  
000128  typedef struct IncrblobChannel IncrblobChannel;
000129  
000130  /*
000131  ** There is one instance of this structure for each SQLite database
000132  ** that has been opened by the SQLite TCL interface.
000133  **
000134  ** If this module is built with SQLITE_TEST defined (to create the SQLite
000135  ** testfixture executable), then it may be configured to use either
000136  ** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements.
000137  ** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used.
000138  */
000139  struct SqliteDb {
000140    sqlite3 *db;               /* The "real" database structure. MUST BE FIRST */
000141    Tcl_Interp *interp;        /* The interpreter used for this database */
000142    char *zBusy;               /* The busy callback routine */
000143    char *zCommit;             /* The commit hook callback routine */
000144    char *zTrace;              /* The trace callback routine */
000145    char *zTraceV2;            /* The trace_v2 callback routine */
000146    char *zProfile;            /* The profile callback routine */
000147    char *zProgress;           /* The progress callback routine */
000148    char *zAuth;               /* The authorization callback routine */
000149    int disableAuth;           /* Disable the authorizer if it exists */
000150    char *zNull;               /* Text to substitute for an SQL NULL value */
000151    SqlFunc *pFunc;            /* List of SQL functions */
000152    Tcl_Obj *pUpdateHook;      /* Update hook script (if any) */
000153    Tcl_Obj *pPreUpdateHook;   /* Pre-update hook script (if any) */
000154    Tcl_Obj *pRollbackHook;    /* Rollback hook script (if any) */
000155    Tcl_Obj *pWalHook;         /* WAL hook script (if any) */
000156    Tcl_Obj *pUnlockNotify;    /* Unlock notify script (if any) */
000157    SqlCollate *pCollate;      /* List of SQL collation functions */
000158    int rc;                    /* Return code of most recent sqlite3_exec() */
000159    Tcl_Obj *pCollateNeeded;   /* Collation needed script */
000160    SqlPreparedStmt *stmtList; /* List of prepared statements*/
000161    SqlPreparedStmt *stmtLast; /* Last statement in the list */
000162    int maxStmt;               /* The next maximum number of stmtList */
000163    int nStmt;                 /* Number of statements in stmtList */
000164    IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
000165    int nStep, nSort, nIndex;  /* Statistics for most recent operation */
000166    int nVMStep;               /* Another statistic for most recent operation */
000167    int nTransaction;          /* Number of nested [transaction] methods */
000168    int openFlags;             /* Flags used to open.  (SQLITE_OPEN_URI) */
000169  #ifdef SQLITE_TEST
000170    int bLegacyPrepare;        /* True to use sqlite3_prepare() */
000171  #endif
000172  };
000173  
000174  struct IncrblobChannel {
000175    sqlite3_blob *pBlob;      /* sqlite3 blob handle */
000176    SqliteDb *pDb;            /* Associated database connection */
000177    int iSeek;                /* Current seek offset */
000178    Tcl_Channel channel;      /* Channel identifier */
000179    IncrblobChannel *pNext;   /* Linked list of all open incrblob channels */
000180    IncrblobChannel *pPrev;   /* Linked list of all open incrblob channels */
000181  };
000182  
000183  /*
000184  ** Compute a string length that is limited to what can be stored in
000185  ** lower 30 bits of a 32-bit signed integer.
000186  */
000187  static int strlen30(const char *z){
000188    const char *z2 = z;
000189    while( *z2 ){ z2++; }
000190    return 0x3fffffff & (int)(z2 - z);
000191  }
000192  
000193  
000194  #ifndef SQLITE_OMIT_INCRBLOB
000195  /*
000196  ** Close all incrblob channels opened using database connection pDb.
000197  ** This is called when shutting down the database connection.
000198  */
000199  static void closeIncrblobChannels(SqliteDb *pDb){
000200    IncrblobChannel *p;
000201    IncrblobChannel *pNext;
000202  
000203    for(p=pDb->pIncrblob; p; p=pNext){
000204      pNext = p->pNext;
000205  
000206      /* Note: Calling unregister here call Tcl_Close on the incrblob channel,
000207      ** which deletes the IncrblobChannel structure at *p. So do not
000208      ** call Tcl_Free() here.
000209      */
000210      Tcl_UnregisterChannel(pDb->interp, p->channel);
000211    }
000212  }
000213  
000214  /*
000215  ** Close an incremental blob channel.
000216  */
000217  static int SQLITE_TCLAPI incrblobClose(
000218    ClientData instanceData,
000219    Tcl_Interp *interp
000220  ){
000221    IncrblobChannel *p = (IncrblobChannel *)instanceData;
000222    int rc = sqlite3_blob_close(p->pBlob);
000223    sqlite3 *db = p->pDb->db;
000224  
000225    /* Remove the channel from the SqliteDb.pIncrblob list. */
000226    if( p->pNext ){
000227      p->pNext->pPrev = p->pPrev;
000228    }
000229    if( p->pPrev ){
000230      p->pPrev->pNext = p->pNext;
000231    }
000232    if( p->pDb->pIncrblob==p ){
000233      p->pDb->pIncrblob = p->pNext;
000234    }
000235  
000236    /* Free the IncrblobChannel structure */
000237    Tcl_Free((char *)p);
000238  
000239    if( rc!=SQLITE_OK ){
000240      Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE);
000241      return TCL_ERROR;
000242    }
000243    return TCL_OK;
000244  }
000245  
000246  /*
000247  ** Read data from an incremental blob channel.
000248  */
000249  static int SQLITE_TCLAPI incrblobInput(
000250    ClientData instanceData,
000251    char *buf,
000252    int bufSize,
000253    int *errorCodePtr
000254  ){
000255    IncrblobChannel *p = (IncrblobChannel *)instanceData;
000256    int nRead = bufSize;         /* Number of bytes to read */
000257    int nBlob;                   /* Total size of the blob */
000258    int rc;                      /* sqlite error code */
000259  
000260    nBlob = sqlite3_blob_bytes(p->pBlob);
000261    if( (p->iSeek+nRead)>nBlob ){
000262      nRead = nBlob-p->iSeek;
000263    }
000264    if( nRead<=0 ){
000265      return 0;
000266    }
000267  
000268    rc = sqlite3_blob_read(p->pBlob, (void *)buf, nRead, p->iSeek);
000269    if( rc!=SQLITE_OK ){
000270      *errorCodePtr = rc;
000271      return -1;
000272    }
000273  
000274    p->iSeek += nRead;
000275    return nRead;
000276  }
000277  
000278  /*
000279  ** Write data to an incremental blob channel.
000280  */
000281  static int SQLITE_TCLAPI incrblobOutput(
000282    ClientData instanceData,
000283    CONST char *buf,
000284    int toWrite,
000285    int *errorCodePtr
000286  ){
000287    IncrblobChannel *p = (IncrblobChannel *)instanceData;
000288    int nWrite = toWrite;        /* Number of bytes to write */
000289    int nBlob;                   /* Total size of the blob */
000290    int rc;                      /* sqlite error code */
000291  
000292    nBlob = sqlite3_blob_bytes(p->pBlob);
000293    if( (p->iSeek+nWrite)>nBlob ){
000294      *errorCodePtr = EINVAL;
000295      return -1;
000296    }
000297    if( nWrite<=0 ){
000298      return 0;
000299    }
000300  
000301    rc = sqlite3_blob_write(p->pBlob, (void *)buf, nWrite, p->iSeek);
000302    if( rc!=SQLITE_OK ){
000303      *errorCodePtr = EIO;
000304      return -1;
000305    }
000306  
000307    p->iSeek += nWrite;
000308    return nWrite;
000309  }
000310  
000311  /*
000312  ** Seek an incremental blob channel.
000313  */
000314  static int SQLITE_TCLAPI incrblobSeek(
000315    ClientData instanceData,
000316    long offset,
000317    int seekMode,
000318    int *errorCodePtr
000319  ){
000320    IncrblobChannel *p = (IncrblobChannel *)instanceData;
000321  
000322    switch( seekMode ){
000323      case SEEK_SET:
000324        p->iSeek = offset;
000325        break;
000326      case SEEK_CUR:
000327        p->iSeek += offset;
000328        break;
000329      case SEEK_END:
000330        p->iSeek = sqlite3_blob_bytes(p->pBlob) + offset;
000331        break;
000332  
000333      default: assert(!"Bad seekMode");
000334    }
000335  
000336    return p->iSeek;
000337  }
000338  
000339  
000340  static void SQLITE_TCLAPI incrblobWatch(
000341    ClientData instanceData,
000342    int mode
000343  ){
000344    /* NO-OP */
000345  }
000346  static int SQLITE_TCLAPI incrblobHandle(
000347    ClientData instanceData,
000348    int dir,
000349    ClientData *hPtr
000350  ){
000351    return TCL_ERROR;
000352  }
000353  
000354  static Tcl_ChannelType IncrblobChannelType = {
000355    "incrblob",                        /* typeName                             */
000356    TCL_CHANNEL_VERSION_2,             /* version                              */
000357    incrblobClose,                     /* closeProc                            */
000358    incrblobInput,                     /* inputProc                            */
000359    incrblobOutput,                    /* outputProc                           */
000360    incrblobSeek,                      /* seekProc                             */
000361    0,                                 /* setOptionProc                        */
000362    0,                                 /* getOptionProc                        */
000363    incrblobWatch,                     /* watchProc (this is a no-op)          */
000364    incrblobHandle,                    /* getHandleProc (always returns error) */
000365    0,                                 /* close2Proc                           */
000366    0,                                 /* blockModeProc                        */
000367    0,                                 /* flushProc                            */
000368    0,                                 /* handlerProc                          */
000369    0,                                 /* wideSeekProc                         */
000370  };
000371  
000372  /*
000373  ** Create a new incrblob channel.
000374  */
000375  static int createIncrblobChannel(
000376    Tcl_Interp *interp,
000377    SqliteDb *pDb,
000378    const char *zDb,
000379    const char *zTable,
000380    const char *zColumn,
000381    sqlite_int64 iRow,
000382    int isReadonly
000383  ){
000384    IncrblobChannel *p;
000385    sqlite3 *db = pDb->db;
000386    sqlite3_blob *pBlob;
000387    int rc;
000388    int flags = TCL_READABLE|(isReadonly ? 0 : TCL_WRITABLE);
000389  
000390    /* This variable is used to name the channels: "incrblob_[incr count]" */
000391    static int count = 0;
000392    char zChannel[64];
000393  
000394    rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob);
000395    if( rc!=SQLITE_OK ){
000396      Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
000397      return TCL_ERROR;
000398    }
000399  
000400    p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel));
000401    p->iSeek = 0;
000402    p->pBlob = pBlob;
000403  
000404    sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count);
000405    p->channel = Tcl_CreateChannel(&IncrblobChannelType, zChannel, p, flags);
000406    Tcl_RegisterChannel(interp, p->channel);
000407  
000408    /* Link the new channel into the SqliteDb.pIncrblob list. */
000409    p->pNext = pDb->pIncrblob;
000410    p->pPrev = 0;
000411    if( p->pNext ){
000412      p->pNext->pPrev = p;
000413    }
000414    pDb->pIncrblob = p;
000415    p->pDb = pDb;
000416  
000417    Tcl_SetResult(interp, (char *)Tcl_GetChannelName(p->channel), TCL_VOLATILE);
000418    return TCL_OK;
000419  }
000420  #else  /* else clause for "#ifndef SQLITE_OMIT_INCRBLOB" */
000421    #define closeIncrblobChannels(pDb)
000422  #endif
000423  
000424  /*
000425  ** Look at the script prefix in pCmd.  We will be executing this script
000426  ** after first appending one or more arguments.  This routine analyzes
000427  ** the script to see if it is safe to use Tcl_EvalObjv() on the script
000428  ** rather than the more general Tcl_EvalEx().  Tcl_EvalObjv() is much
000429  ** faster.
000430  **
000431  ** Scripts that are safe to use with Tcl_EvalObjv() consists of a
000432  ** command name followed by zero or more arguments with no [...] or $
000433  ** or {...} or ; to be seen anywhere.  Most callback scripts consist
000434  ** of just a single procedure name and they meet this requirement.
000435  */
000436  static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){
000437    /* We could try to do something with Tcl_Parse().  But we will instead
000438    ** just do a search for forbidden characters.  If any of the forbidden
000439    ** characters appear in pCmd, we will report the string as unsafe.
000440    */
000441    const char *z;
000442    int n;
000443    z = Tcl_GetStringFromObj(pCmd, &n);
000444    while( n-- > 0 ){
000445      int c = *(z++);
000446      if( c=='$' || c=='[' || c==';' ) return 0;
000447    }
000448    return 1;
000449  }
000450  
000451  /*
000452  ** Find an SqlFunc structure with the given name.  Or create a new
000453  ** one if an existing one cannot be found.  Return a pointer to the
000454  ** structure.
000455  */
000456  static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
000457    SqlFunc *p, *pNew;
000458    int nName = strlen30(zName);
000459    pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + nName + 1 );
000460    pNew->zName = (char*)&pNew[1];
000461    memcpy(pNew->zName, zName, nName+1);
000462    for(p=pDb->pFunc; p; p=p->pNext){
000463      if( sqlite3_stricmp(p->zName, pNew->zName)==0 ){
000464        Tcl_Free((char*)pNew);
000465        return p;
000466      }
000467    }
000468    pNew->interp = pDb->interp;
000469    pNew->pDb = pDb;
000470    pNew->pScript = 0;
000471    pNew->pNext = pDb->pFunc;
000472    pDb->pFunc = pNew;
000473    return pNew;
000474  }
000475  
000476  /*
000477  ** Free a single SqlPreparedStmt object.
000478  */
000479  static void dbFreeStmt(SqlPreparedStmt *pStmt){
000480  #ifdef SQLITE_TEST
000481    if( sqlite3_sql(pStmt->pStmt)==0 ){
000482      Tcl_Free((char *)pStmt->zSql);
000483    }
000484  #endif
000485    sqlite3_finalize(pStmt->pStmt);
000486    Tcl_Free((char *)pStmt);
000487  }
000488  
000489  /*
000490  ** Finalize and free a list of prepared statements
000491  */
000492  static void flushStmtCache(SqliteDb *pDb){
000493    SqlPreparedStmt *pPreStmt;
000494    SqlPreparedStmt *pNext;
000495  
000496    for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pNext){
000497      pNext = pPreStmt->pNext;
000498      dbFreeStmt(pPreStmt);
000499    }
000500    pDb->nStmt = 0;
000501    pDb->stmtLast = 0;
000502    pDb->stmtList = 0;
000503  }
000504  
000505  /*
000506  ** TCL calls this procedure when an sqlite3 database command is
000507  ** deleted.
000508  */
000509  static void SQLITE_TCLAPI DbDeleteCmd(void *db){
000510    SqliteDb *pDb = (SqliteDb*)db;
000511    flushStmtCache(pDb);
000512    closeIncrblobChannels(pDb);
000513    sqlite3_close(pDb->db);
000514    while( pDb->pFunc ){
000515      SqlFunc *pFunc = pDb->pFunc;
000516      pDb->pFunc = pFunc->pNext;
000517      assert( pFunc->pDb==pDb );
000518      Tcl_DecrRefCount(pFunc->pScript);
000519      Tcl_Free((char*)pFunc);
000520    }
000521    while( pDb->pCollate ){
000522      SqlCollate *pCollate = pDb->pCollate;
000523      pDb->pCollate = pCollate->pNext;
000524      Tcl_Free((char*)pCollate);
000525    }
000526    if( pDb->zBusy ){
000527      Tcl_Free(pDb->zBusy);
000528    }
000529    if( pDb->zTrace ){
000530      Tcl_Free(pDb->zTrace);
000531    }
000532    if( pDb->zTraceV2 ){
000533      Tcl_Free(pDb->zTraceV2);
000534    }
000535    if( pDb->zProfile ){
000536      Tcl_Free(pDb->zProfile);
000537    }
000538    if( pDb->zAuth ){
000539      Tcl_Free(pDb->zAuth);
000540    }
000541    if( pDb->zNull ){
000542      Tcl_Free(pDb->zNull);
000543    }
000544    if( pDb->pUpdateHook ){
000545      Tcl_DecrRefCount(pDb->pUpdateHook);
000546    }
000547    if( pDb->pPreUpdateHook ){
000548      Tcl_DecrRefCount(pDb->pPreUpdateHook);
000549    }
000550    if( pDb->pRollbackHook ){
000551      Tcl_DecrRefCount(pDb->pRollbackHook);
000552    }
000553    if( pDb->pWalHook ){
000554      Tcl_DecrRefCount(pDb->pWalHook);
000555    }
000556    if( pDb->pCollateNeeded ){
000557      Tcl_DecrRefCount(pDb->pCollateNeeded);
000558    }
000559    Tcl_Free((char*)pDb);
000560  }
000561  
000562  /*
000563  ** This routine is called when a database file is locked while trying
000564  ** to execute SQL.
000565  */
000566  static int DbBusyHandler(void *cd, int nTries){
000567    SqliteDb *pDb = (SqliteDb*)cd;
000568    int rc;
000569    char zVal[30];
000570  
000571    sqlite3_snprintf(sizeof(zVal), zVal, "%d", nTries);
000572    rc = Tcl_VarEval(pDb->interp, pDb->zBusy, " ", zVal, (char*)0);
000573    if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
000574      return 0;
000575    }
000576    return 1;
000577  }
000578  
000579  #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
000580  /*
000581  ** This routine is invoked as the 'progress callback' for the database.
000582  */
000583  static int DbProgressHandler(void *cd){
000584    SqliteDb *pDb = (SqliteDb*)cd;
000585    int rc;
000586  
000587    assert( pDb->zProgress );
000588    rc = Tcl_Eval(pDb->interp, pDb->zProgress);
000589    if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
000590      return 1;
000591    }
000592    return 0;
000593  }
000594  #endif
000595  
000596  #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
000597      !defined(SQLITE_OMIT_DEPRECATED)
000598  /*
000599  ** This routine is called by the SQLite trace handler whenever a new
000600  ** block of SQL is executed.  The TCL script in pDb->zTrace is executed.
000601  */
000602  static void DbTraceHandler(void *cd, const char *zSql){
000603    SqliteDb *pDb = (SqliteDb*)cd;
000604    Tcl_DString str;
000605  
000606    Tcl_DStringInit(&str);
000607    Tcl_DStringAppend(&str, pDb->zTrace, -1);
000608    Tcl_DStringAppendElement(&str, zSql);
000609    Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
000610    Tcl_DStringFree(&str);
000611    Tcl_ResetResult(pDb->interp);
000612  }
000613  #endif
000614  
000615  #ifndef SQLITE_OMIT_TRACE
000616  /*
000617  ** This routine is called by the SQLite trace_v2 handler whenever a new
000618  ** supported event is generated.  Unsupported event types are ignored.
000619  ** The TCL script in pDb->zTraceV2 is executed, with the arguments for
000620  ** the event appended to it (as list elements).
000621  */
000622  static int DbTraceV2Handler(
000623    unsigned type, /* One of the SQLITE_TRACE_* event types. */
000624    void *cd,      /* The original context data pointer. */
000625    void *pd,      /* Primary event data, depends on event type. */
000626    void *xd       /* Extra event data, depends on event type. */
000627  ){
000628    SqliteDb *pDb = (SqliteDb*)cd;
000629    Tcl_Obj *pCmd;
000630  
000631    switch( type ){
000632      case SQLITE_TRACE_STMT: {
000633        sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
000634        char *zSql = (char *)xd;
000635  
000636        pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
000637        Tcl_IncrRefCount(pCmd);
000638        Tcl_ListObjAppendElement(pDb->interp, pCmd,
000639                                 Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
000640        Tcl_ListObjAppendElement(pDb->interp, pCmd,
000641                                 Tcl_NewStringObj(zSql, -1));
000642        Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
000643        Tcl_DecrRefCount(pCmd);
000644        Tcl_ResetResult(pDb->interp);
000645        break;
000646      }
000647      case SQLITE_TRACE_PROFILE: {
000648        sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
000649        sqlite3_int64 ns = (sqlite3_int64)xd;
000650  
000651        pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
000652        Tcl_IncrRefCount(pCmd);
000653        Tcl_ListObjAppendElement(pDb->interp, pCmd,
000654                                 Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
000655        Tcl_ListObjAppendElement(pDb->interp, pCmd,
000656                                 Tcl_NewWideIntObj((Tcl_WideInt)ns));
000657        Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
000658        Tcl_DecrRefCount(pCmd);
000659        Tcl_ResetResult(pDb->interp);
000660        break;
000661      }
000662      case SQLITE_TRACE_ROW: {
000663        sqlite3_stmt *pStmt = (sqlite3_stmt *)pd;
000664  
000665        pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
000666        Tcl_IncrRefCount(pCmd);
000667        Tcl_ListObjAppendElement(pDb->interp, pCmd,
000668                                 Tcl_NewWideIntObj((Tcl_WideInt)pStmt));
000669        Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
000670        Tcl_DecrRefCount(pCmd);
000671        Tcl_ResetResult(pDb->interp);
000672        break;
000673      }
000674      case SQLITE_TRACE_CLOSE: {
000675        sqlite3 *db = (sqlite3 *)pd;
000676  
000677        pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1);
000678        Tcl_IncrRefCount(pCmd);
000679        Tcl_ListObjAppendElement(pDb->interp, pCmd,
000680                                 Tcl_NewWideIntObj((Tcl_WideInt)db));
000681        Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
000682        Tcl_DecrRefCount(pCmd);
000683        Tcl_ResetResult(pDb->interp);
000684        break;
000685      }
000686    }
000687    return SQLITE_OK;
000688  }
000689  #endif
000690  
000691  #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
000692      !defined(SQLITE_OMIT_DEPRECATED)
000693  /*
000694  ** This routine is called by the SQLite profile handler after a statement
000695  ** SQL has executed.  The TCL script in pDb->zProfile is evaluated.
000696  */
000697  static void DbProfileHandler(void *cd, const char *zSql, sqlite_uint64 tm){
000698    SqliteDb *pDb = (SqliteDb*)cd;
000699    Tcl_DString str;
000700    char zTm[100];
000701  
000702    sqlite3_snprintf(sizeof(zTm)-1, zTm, "%lld", tm);
000703    Tcl_DStringInit(&str);
000704    Tcl_DStringAppend(&str, pDb->zProfile, -1);
000705    Tcl_DStringAppendElement(&str, zSql);
000706    Tcl_DStringAppendElement(&str, zTm);
000707    Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
000708    Tcl_DStringFree(&str);
000709    Tcl_ResetResult(pDb->interp);
000710  }
000711  #endif
000712  
000713  /*
000714  ** This routine is called when a transaction is committed.  The
000715  ** TCL script in pDb->zCommit is executed.  If it returns non-zero or
000716  ** if it throws an exception, the transaction is rolled back instead
000717  ** of being committed.
000718  */
000719  static int DbCommitHandler(void *cd){
000720    SqliteDb *pDb = (SqliteDb*)cd;
000721    int rc;
000722  
000723    rc = Tcl_Eval(pDb->interp, pDb->zCommit);
000724    if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
000725      return 1;
000726    }
000727    return 0;
000728  }
000729  
000730  static void DbRollbackHandler(void *clientData){
000731    SqliteDb *pDb = (SqliteDb*)clientData;
000732    assert(pDb->pRollbackHook);
000733    if( TCL_OK!=Tcl_EvalObjEx(pDb->interp, pDb->pRollbackHook, 0) ){
000734      Tcl_BackgroundError(pDb->interp);
000735    }
000736  }
000737  
000738  /*
000739  ** This procedure handles wal_hook callbacks.
000740  */
000741  static int DbWalHandler(
000742    void *clientData,
000743    sqlite3 *db,
000744    const char *zDb,
000745    int nEntry
000746  ){
000747    int ret = SQLITE_OK;
000748    Tcl_Obj *p;
000749    SqliteDb *pDb = (SqliteDb*)clientData;
000750    Tcl_Interp *interp = pDb->interp;
000751    assert(pDb->pWalHook);
000752  
000753    assert( db==pDb->db );
000754    p = Tcl_DuplicateObj(pDb->pWalHook);
000755    Tcl_IncrRefCount(p);
000756    Tcl_ListObjAppendElement(interp, p, Tcl_NewStringObj(zDb, -1));
000757    Tcl_ListObjAppendElement(interp, p, Tcl_NewIntObj(nEntry));
000758    if( TCL_OK!=Tcl_EvalObjEx(interp, p, 0)
000759     || TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &ret)
000760    ){
000761      Tcl_BackgroundError(interp);
000762    }
000763    Tcl_DecrRefCount(p);
000764  
000765    return ret;
000766  }
000767  
000768  #if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
000769  static void setTestUnlockNotifyVars(Tcl_Interp *interp, int iArg, int nArg){
000770    char zBuf[64];
000771    sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", iArg);
000772    Tcl_SetVar(interp, "sqlite_unlock_notify_arg", zBuf, TCL_GLOBAL_ONLY);
000773    sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nArg);
000774    Tcl_SetVar(interp, "sqlite_unlock_notify_argcount", zBuf, TCL_GLOBAL_ONLY);
000775  }
000776  #else
000777  # define setTestUnlockNotifyVars(x,y,z)
000778  #endif
000779  
000780  #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
000781  static void DbUnlockNotify(void **apArg, int nArg){
000782    int i;
000783    for(i=0; i<nArg; i++){
000784      const int flags = (TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
000785      SqliteDb *pDb = (SqliteDb *)apArg[i];
000786      setTestUnlockNotifyVars(pDb->interp, i, nArg);
000787      assert( pDb->pUnlockNotify);
000788      Tcl_EvalObjEx(pDb->interp, pDb->pUnlockNotify, flags);
000789      Tcl_DecrRefCount(pDb->pUnlockNotify);
000790      pDb->pUnlockNotify = 0;
000791    }
000792  }
000793  #endif
000794  
000795  #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
000796  /*
000797  ** Pre-update hook callback.
000798  */
000799  static void DbPreUpdateHandler(
000800    void *p,
000801    sqlite3 *db,
000802    int op,
000803    const char *zDb,
000804    const char *zTbl,
000805    sqlite_int64 iKey1,
000806    sqlite_int64 iKey2
000807  ){
000808    SqliteDb *pDb = (SqliteDb *)p;
000809    Tcl_Obj *pCmd;
000810    static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"};
000811  
000812    assert( (SQLITE_DELETE-1)/9 == 0 );
000813    assert( (SQLITE_INSERT-1)/9 == 1 );
000814    assert( (SQLITE_UPDATE-1)/9 == 2 );
000815    assert( pDb->pPreUpdateHook );
000816    assert( db==pDb->db );
000817    assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
000818  
000819    pCmd = Tcl_DuplicateObj(pDb->pPreUpdateHook);
000820    Tcl_IncrRefCount(pCmd);
000821    Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1));
000822    Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
000823    Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
000824    Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey1));
000825    Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(iKey2));
000826    Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
000827    Tcl_DecrRefCount(pCmd);
000828  }
000829  #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
000830  
000831  static void DbUpdateHandler(
000832    void *p,
000833    int op,
000834    const char *zDb,
000835    const char *zTbl,
000836    sqlite_int64 rowid
000837  ){
000838    SqliteDb *pDb = (SqliteDb *)p;
000839    Tcl_Obj *pCmd;
000840    static const char *azStr[] = {"DELETE", "INSERT", "UPDATE"};
000841  
000842    assert( (SQLITE_DELETE-1)/9 == 0 );
000843    assert( (SQLITE_INSERT-1)/9 == 1 );
000844    assert( (SQLITE_UPDATE-1)/9 == 2 );
000845  
000846    assert( pDb->pUpdateHook );
000847    assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
000848  
000849    pCmd = Tcl_DuplicateObj(pDb->pUpdateHook);
000850    Tcl_IncrRefCount(pCmd);
000851    Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(azStr[(op-1)/9], -1));
000852    Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
000853    Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
000854    Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(rowid));
000855    Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
000856    Tcl_DecrRefCount(pCmd);
000857  }
000858  
000859  static void tclCollateNeeded(
000860    void *pCtx,
000861    sqlite3 *db,
000862    int enc,
000863    const char *zName
000864  ){
000865    SqliteDb *pDb = (SqliteDb *)pCtx;
000866    Tcl_Obj *pScript = Tcl_DuplicateObj(pDb->pCollateNeeded);
000867    Tcl_IncrRefCount(pScript);
000868    Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zName, -1));
000869    Tcl_EvalObjEx(pDb->interp, pScript, 0);
000870    Tcl_DecrRefCount(pScript);
000871  }
000872  
000873  /*
000874  ** This routine is called to evaluate an SQL collation function implemented
000875  ** using TCL script.
000876  */
000877  static int tclSqlCollate(
000878    void *pCtx,
000879    int nA,
000880    const void *zA,
000881    int nB,
000882    const void *zB
000883  ){
000884    SqlCollate *p = (SqlCollate *)pCtx;
000885    Tcl_Obj *pCmd;
000886  
000887    pCmd = Tcl_NewStringObj(p->zScript, -1);
000888    Tcl_IncrRefCount(pCmd);
000889    Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA));
000890    Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB));
000891    Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
000892    Tcl_DecrRefCount(pCmd);
000893    return (atoi(Tcl_GetStringResult(p->interp)));
000894  }
000895  
000896  /*
000897  ** This routine is called to evaluate an SQL function implemented
000898  ** using TCL script.
000899  */
000900  static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
000901    SqlFunc *p = sqlite3_user_data(context);
000902    Tcl_Obj *pCmd;
000903    int i;
000904    int rc;
000905  
000906    if( argc==0 ){
000907      /* If there are no arguments to the function, call Tcl_EvalObjEx on the
000908      ** script object directly.  This allows the TCL compiler to generate
000909      ** bytecode for the command on the first invocation and thus make
000910      ** subsequent invocations much faster. */
000911      pCmd = p->pScript;
000912      Tcl_IncrRefCount(pCmd);
000913      rc = Tcl_EvalObjEx(p->interp, pCmd, 0);
000914      Tcl_DecrRefCount(pCmd);
000915    }else{
000916      /* If there are arguments to the function, make a shallow copy of the
000917      ** script object, lappend the arguments, then evaluate the copy.
000918      **
000919      ** By "shallow" copy, we mean only the outer list Tcl_Obj is duplicated.
000920      ** The new Tcl_Obj contains pointers to the original list elements.
000921      ** That way, when Tcl_EvalObjv() is run and shimmers the first element
000922      ** of the list to tclCmdNameType, that alternate representation will
000923      ** be preserved and reused on the next invocation.
000924      */
000925      Tcl_Obj **aArg;
000926      int nArg;
000927      if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){
000928        sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
000929        return;
000930      }
000931      pCmd = Tcl_NewListObj(nArg, aArg);
000932      Tcl_IncrRefCount(pCmd);
000933      for(i=0; i<argc; i++){
000934        sqlite3_value *pIn = argv[i];
000935        Tcl_Obj *pVal;
000936  
000937        /* Set pVal to contain the i'th column of this row. */
000938        switch( sqlite3_value_type(pIn) ){
000939          case SQLITE_BLOB: {
000940            int bytes = sqlite3_value_bytes(pIn);
000941            pVal = Tcl_NewByteArrayObj(sqlite3_value_blob(pIn), bytes);
000942            break;
000943          }
000944          case SQLITE_INTEGER: {
000945            sqlite_int64 v = sqlite3_value_int64(pIn);
000946            if( v>=-2147483647 && v<=2147483647 ){
000947              pVal = Tcl_NewIntObj((int)v);
000948            }else{
000949              pVal = Tcl_NewWideIntObj(v);
000950            }
000951            break;
000952          }
000953          case SQLITE_FLOAT: {
000954            double r = sqlite3_value_double(pIn);
000955            pVal = Tcl_NewDoubleObj(r);
000956            break;
000957          }
000958          case SQLITE_NULL: {
000959            pVal = Tcl_NewStringObj(p->pDb->zNull, -1);
000960            break;
000961          }
000962          default: {
000963            int bytes = sqlite3_value_bytes(pIn);
000964            pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes);
000965            break;
000966          }
000967        }
000968        rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal);
000969        if( rc ){
000970          Tcl_DecrRefCount(pCmd);
000971          sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
000972          return;
000973        }
000974      }
000975      if( !p->useEvalObjv ){
000976        /* Tcl_EvalObjEx() will automatically call Tcl_EvalObjv() if pCmd
000977        ** is a list without a string representation.  To prevent this from
000978        ** happening, make sure pCmd has a valid string representation */
000979        Tcl_GetString(pCmd);
000980      }
000981      rc = Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
000982      Tcl_DecrRefCount(pCmd);
000983    }
000984  
000985    if( rc && rc!=TCL_RETURN ){
000986      sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1);
000987    }else{
000988      Tcl_Obj *pVar = Tcl_GetObjResult(p->interp);
000989      int n;
000990      u8 *data;
000991      const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
000992      char c = zType[0];
000993      if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
000994        /* Only return a BLOB type if the Tcl variable is a bytearray and
000995        ** has no string representation. */
000996        data = Tcl_GetByteArrayFromObj(pVar, &n);
000997        sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
000998      }else if( c=='b' && strcmp(zType,"boolean")==0 ){
000999        Tcl_GetIntFromObj(0, pVar, &n);
001000        sqlite3_result_int(context, n);
001001      }else if( c=='d' && strcmp(zType,"double")==0 ){
001002        double r;
001003        Tcl_GetDoubleFromObj(0, pVar, &r);
001004        sqlite3_result_double(context, r);
001005      }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
001006            (c=='i' && strcmp(zType,"int")==0) ){
001007        Tcl_WideInt v;
001008        Tcl_GetWideIntFromObj(0, pVar, &v);
001009        sqlite3_result_int64(context, v);
001010      }else{
001011        data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
001012        sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT);
001013      }
001014    }
001015  }
001016  
001017  #ifndef SQLITE_OMIT_AUTHORIZATION
001018  /*
001019  ** This is the authentication function.  It appends the authentication
001020  ** type code and the two arguments to zCmd[] then invokes the result
001021  ** on the interpreter.  The reply is examined to determine if the
001022  ** authentication fails or succeeds.
001023  */
001024  static int auth_callback(
001025    void *pArg,
001026    int code,
001027    const char *zArg1,
001028    const char *zArg2,
001029    const char *zArg3,
001030    const char *zArg4
001031  #ifdef SQLITE_USER_AUTHENTICATION
001032    ,const char *zArg5
001033  #endif
001034  ){
001035    const char *zCode;
001036    Tcl_DString str;
001037    int rc;
001038    const char *zReply;
001039    /* EVIDENCE-OF: R-38590-62769 The first parameter to the authorizer
001040    ** callback is a copy of the third parameter to the
001041    ** sqlite3_set_authorizer() interface.
001042    */
001043    SqliteDb *pDb = (SqliteDb*)pArg;
001044    if( pDb->disableAuth ) return SQLITE_OK;
001045  
001046    /* EVIDENCE-OF: R-56518-44310 The second parameter to the callback is an
001047    ** integer action code that specifies the particular action to be
001048    ** authorized. */
001049    switch( code ){
001050      case SQLITE_COPY              : zCode="SQLITE_COPY"; break;
001051      case SQLITE_CREATE_INDEX      : zCode="SQLITE_CREATE_INDEX"; break;
001052      case SQLITE_CREATE_TABLE      : zCode="SQLITE_CREATE_TABLE"; break;
001053      case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
001054      case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
001055      case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;
001056      case SQLITE_CREATE_TEMP_VIEW  : zCode="SQLITE_CREATE_TEMP_VIEW"; break;
001057      case SQLITE_CREATE_TRIGGER    : zCode="SQLITE_CREATE_TRIGGER"; break;
001058      case SQLITE_CREATE_VIEW       : zCode="SQLITE_CREATE_VIEW"; break;
001059      case SQLITE_DELETE            : zCode="SQLITE_DELETE"; break;
001060      case SQLITE_DROP_INDEX        : zCode="SQLITE_DROP_INDEX"; break;
001061      case SQLITE_DROP_TABLE        : zCode="SQLITE_DROP_TABLE"; break;
001062      case SQLITE_DROP_TEMP_INDEX   : zCode="SQLITE_DROP_TEMP_INDEX"; break;
001063      case SQLITE_DROP_TEMP_TABLE   : zCode="SQLITE_DROP_TEMP_TABLE"; break;
001064      case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break;
001065      case SQLITE_DROP_TEMP_VIEW    : zCode="SQLITE_DROP_TEMP_VIEW"; break;
001066      case SQLITE_DROP_TRIGGER      : zCode="SQLITE_DROP_TRIGGER"; break;
001067      case SQLITE_DROP_VIEW         : zCode="SQLITE_DROP_VIEW"; break;
001068      case SQLITE_INSERT            : zCode="SQLITE_INSERT"; break;
001069      case SQLITE_PRAGMA            : zCode="SQLITE_PRAGMA"; break;
001070      case SQLITE_READ              : zCode="SQLITE_READ"; break;
001071      case SQLITE_SELECT            : zCode="SQLITE_SELECT"; break;
001072      case SQLITE_TRANSACTION       : zCode="SQLITE_TRANSACTION"; break;
001073      case SQLITE_UPDATE            : zCode="SQLITE_UPDATE"; break;
001074      case SQLITE_ATTACH            : zCode="SQLITE_ATTACH"; break;
001075      case SQLITE_DETACH            : zCode="SQLITE_DETACH"; break;
001076      case SQLITE_ALTER_TABLE       : zCode="SQLITE_ALTER_TABLE"; break;
001077      case SQLITE_REINDEX           : zCode="SQLITE_REINDEX"; break;
001078      case SQLITE_ANALYZE           : zCode="SQLITE_ANALYZE"; break;
001079      case SQLITE_CREATE_VTABLE     : zCode="SQLITE_CREATE_VTABLE"; break;
001080      case SQLITE_DROP_VTABLE       : zCode="SQLITE_DROP_VTABLE"; break;
001081      case SQLITE_FUNCTION          : zCode="SQLITE_FUNCTION"; break;
001082      case SQLITE_SAVEPOINT         : zCode="SQLITE_SAVEPOINT"; break;
001083      case SQLITE_RECURSIVE         : zCode="SQLITE_RECURSIVE"; break;
001084      default                       : zCode="????"; break;
001085    }
001086    Tcl_DStringInit(&str);
001087    Tcl_DStringAppend(&str, pDb->zAuth, -1);
001088    Tcl_DStringAppendElement(&str, zCode);
001089    Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
001090    Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
001091    Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : "");
001092    Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
001093  #ifdef SQLITE_USER_AUTHENTICATION
001094    Tcl_DStringAppendElement(&str, zArg5 ? zArg5 : "");
001095  #endif
001096    rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
001097    Tcl_DStringFree(&str);
001098    zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY";
001099    if( strcmp(zReply,"SQLITE_OK")==0 ){
001100      rc = SQLITE_OK;
001101    }else if( strcmp(zReply,"SQLITE_DENY")==0 ){
001102      rc = SQLITE_DENY;
001103    }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){
001104      rc = SQLITE_IGNORE;
001105    }else{
001106      rc = 999;
001107    }
001108    return rc;
001109  }
001110  #endif /* SQLITE_OMIT_AUTHORIZATION */
001111  
001112  /*
001113  ** This routine reads a line of text from FILE in, stores
001114  ** the text in memory obtained from malloc() and returns a pointer
001115  ** to the text.  NULL is returned at end of file, or if malloc()
001116  ** fails.
001117  **
001118  ** The interface is like "readline" but no command-line editing
001119  ** is done.
001120  **
001121  ** copied from shell.c from '.import' command
001122  */
001123  static char *local_getline(char *zPrompt, FILE *in){
001124    char *zLine;
001125    int nLine;
001126    int n;
001127  
001128    nLine = 100;
001129    zLine = malloc( nLine );
001130    if( zLine==0 ) return 0;
001131    n = 0;
001132    while( 1 ){
001133      if( n+100>nLine ){
001134        nLine = nLine*2 + 100;
001135        zLine = realloc(zLine, nLine);
001136        if( zLine==0 ) return 0;
001137      }
001138      if( fgets(&zLine[n], nLine - n, in)==0 ){
001139        if( n==0 ){
001140          free(zLine);
001141          return 0;
001142        }
001143        zLine[n] = 0;
001144        break;
001145      }
001146      while( zLine[n] ){ n++; }
001147      if( n>0 && zLine[n-1]=='\n' ){
001148        n--;
001149        zLine[n] = 0;
001150        break;
001151      }
001152    }
001153    zLine = realloc( zLine, n+1 );
001154    return zLine;
001155  }
001156  
001157  
001158  /*
001159  ** This function is part of the implementation of the command:
001160  **
001161  **   $db transaction [-deferred|-immediate|-exclusive] SCRIPT
001162  **
001163  ** It is invoked after evaluating the script SCRIPT to commit or rollback
001164  ** the transaction or savepoint opened by the [transaction] command.
001165  */
001166  static int SQLITE_TCLAPI DbTransPostCmd(
001167    ClientData data[],                   /* data[0] is the Sqlite3Db* for $db */
001168    Tcl_Interp *interp,                  /* Tcl interpreter */
001169    int result                           /* Result of evaluating SCRIPT */
001170  ){
001171    static const char *const azEnd[] = {
001172      "RELEASE _tcl_transaction",        /* rc==TCL_ERROR, nTransaction!=0 */
001173      "COMMIT",                          /* rc!=TCL_ERROR, nTransaction==0 */
001174      "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction",
001175      "ROLLBACK"                         /* rc==TCL_ERROR, nTransaction==0 */
001176    };
001177    SqliteDb *pDb = (SqliteDb*)data[0];
001178    int rc = result;
001179    const char *zEnd;
001180  
001181    pDb->nTransaction--;
001182    zEnd = azEnd[(rc==TCL_ERROR)*2 + (pDb->nTransaction==0)];
001183  
001184    pDb->disableAuth++;
001185    if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){
001186        /* This is a tricky scenario to handle. The most likely cause of an
001187        ** error is that the exec() above was an attempt to commit the
001188        ** top-level transaction that returned SQLITE_BUSY. Or, less likely,
001189        ** that an IO-error has occurred. In either case, throw a Tcl exception
001190        ** and try to rollback the transaction.
001191        **
001192        ** But it could also be that the user executed one or more BEGIN,
001193        ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing
001194        ** this method's logic. Not clear how this would be best handled.
001195        */
001196      if( rc!=TCL_ERROR ){
001197        Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
001198        rc = TCL_ERROR;
001199      }
001200      sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0);
001201    }
001202    pDb->disableAuth--;
001203  
001204    return rc;
001205  }
001206  
001207  /*
001208  ** Unless SQLITE_TEST is defined, this function is a simple wrapper around
001209  ** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either
001210  ** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending
001211  ** on whether or not the [db_use_legacy_prepare] command has been used to
001212  ** configure the connection.
001213  */
001214  static int dbPrepare(
001215    SqliteDb *pDb,                  /* Database object */
001216    const char *zSql,               /* SQL to compile */
001217    sqlite3_stmt **ppStmt,          /* OUT: Prepared statement */
001218    const char **pzOut              /* OUT: Pointer to next SQL statement */
001219  ){
001220    unsigned int prepFlags = 0;
001221  #ifdef SQLITE_TEST
001222    if( pDb->bLegacyPrepare ){
001223      return sqlite3_prepare(pDb->db, zSql, -1, ppStmt, pzOut);
001224    }
001225  #endif
001226    /* If the statement cache is large, use the SQLITE_PREPARE_PERSISTENT
001227    ** flags, which uses less lookaside memory.  But if the cache is small,
001228    ** omit that flag to make full use of lookaside */
001229    if( pDb->maxStmt>5 ) prepFlags = SQLITE_PREPARE_PERSISTENT;
001230  
001231    return sqlite3_prepare_v3(pDb->db, zSql, -1, prepFlags, ppStmt, pzOut);
001232  }
001233  
001234  /*
001235  ** Search the cache for a prepared-statement object that implements the
001236  ** first SQL statement in the buffer pointed to by parameter zIn. If
001237  ** no such prepared-statement can be found, allocate and prepare a new
001238  ** one. In either case, bind the current values of the relevant Tcl
001239  ** variables to any $var, :var or @var variables in the statement. Before
001240  ** returning, set *ppPreStmt to point to the prepared-statement object.
001241  **
001242  ** Output parameter *pzOut is set to point to the next SQL statement in
001243  ** buffer zIn, or to the '\0' byte at the end of zIn if there is no
001244  ** next statement.
001245  **
001246  ** If successful, TCL_OK is returned. Otherwise, TCL_ERROR is returned
001247  ** and an error message loaded into interpreter pDb->interp.
001248  */
001249  static int dbPrepareAndBind(
001250    SqliteDb *pDb,                  /* Database object */
001251    char const *zIn,                /* SQL to compile */
001252    char const **pzOut,             /* OUT: Pointer to next SQL statement */
001253    SqlPreparedStmt **ppPreStmt     /* OUT: Object used to cache statement */
001254  ){
001255    const char *zSql = zIn;         /* Pointer to first SQL statement in zIn */
001256    sqlite3_stmt *pStmt = 0;        /* Prepared statement object */
001257    SqlPreparedStmt *pPreStmt;      /* Pointer to cached statement */
001258    int nSql;                       /* Length of zSql in bytes */
001259    int nVar = 0;                   /* Number of variables in statement */
001260    int iParm = 0;                  /* Next free entry in apParm */
001261    char c;
001262    int i;
001263    Tcl_Interp *interp = pDb->interp;
001264  
001265    *ppPreStmt = 0;
001266  
001267    /* Trim spaces from the start of zSql and calculate the remaining length. */
001268    while( (c = zSql[0])==' ' || c=='\t' || c=='\r' || c=='\n' ){ zSql++; }
001269    nSql = strlen30(zSql);
001270  
001271    for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){
001272      int n = pPreStmt->nSql;
001273      if( nSql>=n
001274          && memcmp(pPreStmt->zSql, zSql, n)==0
001275          && (zSql[n]==0 || zSql[n-1]==';')
001276      ){
001277        pStmt = pPreStmt->pStmt;
001278        *pzOut = &zSql[pPreStmt->nSql];
001279  
001280        /* When a prepared statement is found, unlink it from the
001281        ** cache list.  It will later be added back to the beginning
001282        ** of the cache list in order to implement LRU replacement.
001283        */
001284        if( pPreStmt->pPrev ){
001285          pPreStmt->pPrev->pNext = pPreStmt->pNext;
001286        }else{
001287          pDb->stmtList = pPreStmt->pNext;
001288        }
001289        if( pPreStmt->pNext ){
001290          pPreStmt->pNext->pPrev = pPreStmt->pPrev;
001291        }else{
001292          pDb->stmtLast = pPreStmt->pPrev;
001293        }
001294        pDb->nStmt--;
001295        nVar = sqlite3_bind_parameter_count(pStmt);
001296        break;
001297      }
001298    }
001299  
001300    /* If no prepared statement was found. Compile the SQL text. Also allocate
001301    ** a new SqlPreparedStmt structure.  */
001302    if( pPreStmt==0 ){
001303      int nByte;
001304  
001305      if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){
001306        Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
001307        return TCL_ERROR;
001308      }
001309      if( pStmt==0 ){
001310        if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
001311          /* A compile-time error in the statement. */
001312          Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
001313          return TCL_ERROR;
001314        }else{
001315          /* The statement was a no-op.  Continue to the next statement
001316          ** in the SQL string.
001317          */
001318          return TCL_OK;
001319        }
001320      }
001321  
001322      assert( pPreStmt==0 );
001323      nVar = sqlite3_bind_parameter_count(pStmt);
001324      nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Tcl_Obj *);
001325      pPreStmt = (SqlPreparedStmt*)Tcl_Alloc(nByte);
001326      memset(pPreStmt, 0, nByte);
001327  
001328      pPreStmt->pStmt = pStmt;
001329      pPreStmt->nSql = (int)(*pzOut - zSql);
001330      pPreStmt->zSql = sqlite3_sql(pStmt);
001331      pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1];
001332  #ifdef SQLITE_TEST
001333      if( pPreStmt->zSql==0 ){
001334        char *zCopy = Tcl_Alloc(pPreStmt->nSql + 1);
001335        memcpy(zCopy, zSql, pPreStmt->nSql);
001336        zCopy[pPreStmt->nSql] = '\0';
001337        pPreStmt->zSql = zCopy;
001338      }
001339  #endif
001340    }
001341    assert( pPreStmt );
001342    assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql );
001343    assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) );
001344  
001345    /* Bind values to parameters that begin with $ or : */
001346    for(i=1; i<=nVar; i++){
001347      const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
001348      if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){
001349        Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
001350        if( pVar ){
001351          int n;
001352          u8 *data;
001353          const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
001354          c = zType[0];
001355          if( zVar[0]=='@' ||
001356             (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){
001357            /* Load a BLOB type if the Tcl variable is a bytearray and
001358            ** it has no string representation or the host
001359            ** parameter name begins with "@". */
001360            data = Tcl_GetByteArrayFromObj(pVar, &n);
001361            sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
001362            Tcl_IncrRefCount(pVar);
001363            pPreStmt->apParm[iParm++] = pVar;
001364          }else if( c=='b' && strcmp(zType,"boolean")==0 ){
001365            Tcl_GetIntFromObj(interp, pVar, &n);
001366            sqlite3_bind_int(pStmt, i, n);
001367          }else if( c=='d' && strcmp(zType,"double")==0 ){
001368            double r;
001369            Tcl_GetDoubleFromObj(interp, pVar, &r);
001370            sqlite3_bind_double(pStmt, i, r);
001371          }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
001372                (c=='i' && strcmp(zType,"int")==0) ){
001373            Tcl_WideInt v;
001374            Tcl_GetWideIntFromObj(interp, pVar, &v);
001375            sqlite3_bind_int64(pStmt, i, v);
001376          }else{
001377            data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
001378            sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC);
001379            Tcl_IncrRefCount(pVar);
001380            pPreStmt->apParm[iParm++] = pVar;
001381          }
001382        }else{
001383          sqlite3_bind_null(pStmt, i);
001384        }
001385      }
001386    }
001387    pPreStmt->nParm = iParm;
001388    *ppPreStmt = pPreStmt;
001389  
001390    return TCL_OK;
001391  }
001392  
001393  /*
001394  ** Release a statement reference obtained by calling dbPrepareAndBind().
001395  ** There should be exactly one call to this function for each call to
001396  ** dbPrepareAndBind().
001397  **
001398  ** If the discard parameter is non-zero, then the statement is deleted
001399  ** immediately. Otherwise it is added to the LRU list and may be returned
001400  ** by a subsequent call to dbPrepareAndBind().
001401  */
001402  static void dbReleaseStmt(
001403    SqliteDb *pDb,                  /* Database handle */
001404    SqlPreparedStmt *pPreStmt,      /* Prepared statement handle to release */
001405    int discard                     /* True to delete (not cache) the pPreStmt */
001406  ){
001407    int i;
001408  
001409    /* Free the bound string and blob parameters */
001410    for(i=0; i<pPreStmt->nParm; i++){
001411      Tcl_DecrRefCount(pPreStmt->apParm[i]);
001412    }
001413    pPreStmt->nParm = 0;
001414  
001415    if( pDb->maxStmt<=0 || discard ){
001416      /* If the cache is turned off, deallocated the statement */
001417      dbFreeStmt(pPreStmt);
001418    }else{
001419      /* Add the prepared statement to the beginning of the cache list. */
001420      pPreStmt->pNext = pDb->stmtList;
001421      pPreStmt->pPrev = 0;
001422      if( pDb->stmtList ){
001423       pDb->stmtList->pPrev = pPreStmt;
001424      }
001425      pDb->stmtList = pPreStmt;
001426      if( pDb->stmtLast==0 ){
001427        assert( pDb->nStmt==0 );
001428        pDb->stmtLast = pPreStmt;
001429      }else{
001430        assert( pDb->nStmt>0 );
001431      }
001432      pDb->nStmt++;
001433  
001434      /* If we have too many statement in cache, remove the surplus from
001435      ** the end of the cache list.  */
001436      while( pDb->nStmt>pDb->maxStmt ){
001437        SqlPreparedStmt *pLast = pDb->stmtLast;
001438        pDb->stmtLast = pLast->pPrev;
001439        pDb->stmtLast->pNext = 0;
001440        pDb->nStmt--;
001441        dbFreeStmt(pLast);
001442      }
001443    }
001444  }
001445  
001446  /*
001447  ** Structure used with dbEvalXXX() functions:
001448  **
001449  **   dbEvalInit()
001450  **   dbEvalStep()
001451  **   dbEvalFinalize()
001452  **   dbEvalRowInfo()
001453  **   dbEvalColumnValue()
001454  */
001455  typedef struct DbEvalContext DbEvalContext;
001456  struct DbEvalContext {
001457    SqliteDb *pDb;                  /* Database handle */
001458    Tcl_Obj *pSql;                  /* Object holding string zSql */
001459    const char *zSql;               /* Remaining SQL to execute */
001460    SqlPreparedStmt *pPreStmt;      /* Current statement */
001461    int nCol;                       /* Number of columns returned by pStmt */
001462    int evalFlags;                  /* Flags used */
001463    Tcl_Obj *pArray;                /* Name of array variable */
001464    Tcl_Obj **apColName;            /* Array of column names */
001465  };
001466  
001467  #define SQLITE_EVAL_WITHOUTNULLS  0x00001  /* Unset array(*) for NULL */
001468  
001469  /*
001470  ** Release any cache of column names currently held as part of
001471  ** the DbEvalContext structure passed as the first argument.
001472  */
001473  static void dbReleaseColumnNames(DbEvalContext *p){
001474    if( p->apColName ){
001475      int i;
001476      for(i=0; i<p->nCol; i++){
001477        Tcl_DecrRefCount(p->apColName[i]);
001478      }
001479      Tcl_Free((char *)p->apColName);
001480      p->apColName = 0;
001481    }
001482    p->nCol = 0;
001483  }
001484  
001485  /*
001486  ** Initialize a DbEvalContext structure.
001487  **
001488  ** If pArray is not NULL, then it contains the name of a Tcl array
001489  ** variable. The "*" member of this array is set to a list containing
001490  ** the names of the columns returned by the statement as part of each
001491  ** call to dbEvalStep(), in order from left to right. e.g. if the names
001492  ** of the returned columns are a, b and c, it does the equivalent of the
001493  ** tcl command:
001494  **
001495  **     set ${pArray}(*) {a b c}
001496  */
001497  static void dbEvalInit(
001498    DbEvalContext *p,               /* Pointer to structure to initialize */
001499    SqliteDb *pDb,                  /* Database handle */
001500    Tcl_Obj *pSql,                  /* Object containing SQL script */
001501    Tcl_Obj *pArray,                /* Name of Tcl array to set (*) element of */
001502    int evalFlags                   /* Flags controlling evaluation */
001503  ){
001504    memset(p, 0, sizeof(DbEvalContext));
001505    p->pDb = pDb;
001506    p->zSql = Tcl_GetString(pSql);
001507    p->pSql = pSql;
001508    Tcl_IncrRefCount(pSql);
001509    if( pArray ){
001510      p->pArray = pArray;
001511      Tcl_IncrRefCount(pArray);
001512    }
001513    p->evalFlags = evalFlags;
001514  }
001515  
001516  /*
001517  ** Obtain information about the row that the DbEvalContext passed as the
001518  ** first argument currently points to.
001519  */
001520  static void dbEvalRowInfo(
001521    DbEvalContext *p,               /* Evaluation context */
001522    int *pnCol,                     /* OUT: Number of column names */
001523    Tcl_Obj ***papColName           /* OUT: Array of column names */
001524  ){
001525    /* Compute column names */
001526    if( 0==p->apColName ){
001527      sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
001528      int i;                        /* Iterator variable */
001529      int nCol;                     /* Number of columns returned by pStmt */
001530      Tcl_Obj **apColName = 0;      /* Array of column names */
001531  
001532      p->nCol = nCol = sqlite3_column_count(pStmt);
001533      if( nCol>0 && (papColName || p->pArray) ){
001534        apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
001535        for(i=0; i<nCol; i++){
001536          apColName[i] = Tcl_NewStringObj(sqlite3_column_name(pStmt,i), -1);
001537          Tcl_IncrRefCount(apColName[i]);
001538        }
001539        p->apColName = apColName;
001540      }
001541  
001542      /* If results are being stored in an array variable, then create
001543      ** the array(*) entry for that array
001544      */
001545      if( p->pArray ){
001546        Tcl_Interp *interp = p->pDb->interp;
001547        Tcl_Obj *pColList = Tcl_NewObj();
001548        Tcl_Obj *pStar = Tcl_NewStringObj("*", -1);
001549  
001550        for(i=0; i<nCol; i++){
001551          Tcl_ListObjAppendElement(interp, pColList, apColName[i]);
001552        }
001553        Tcl_IncrRefCount(pStar);
001554        Tcl_ObjSetVar2(interp, p->pArray, pStar, pColList, 0);
001555        Tcl_DecrRefCount(pStar);
001556      }
001557    }
001558  
001559    if( papColName ){
001560      *papColName = p->apColName;
001561    }
001562    if( pnCol ){
001563      *pnCol = p->nCol;
001564    }
001565  }
001566  
001567  /*
001568  ** Return one of TCL_OK, TCL_BREAK or TCL_ERROR. If TCL_ERROR is
001569  ** returned, then an error message is stored in the interpreter before
001570  ** returning.
001571  **
001572  ** A return value of TCL_OK means there is a row of data available. The
001573  ** data may be accessed using dbEvalRowInfo() and dbEvalColumnValue(). This
001574  ** is analogous to a return of SQLITE_ROW from sqlite3_step(). If TCL_BREAK
001575  ** is returned, then the SQL script has finished executing and there are
001576  ** no further rows available. This is similar to SQLITE_DONE.
001577  */
001578  static int dbEvalStep(DbEvalContext *p){
001579    const char *zPrevSql = 0;       /* Previous value of p->zSql */
001580  
001581    while( p->zSql[0] || p->pPreStmt ){
001582      int rc;
001583      if( p->pPreStmt==0 ){
001584        zPrevSql = (p->zSql==zPrevSql ? 0 : p->zSql);
001585        rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt);
001586        if( rc!=TCL_OK ) return rc;
001587      }else{
001588        int rcs;
001589        SqliteDb *pDb = p->pDb;
001590        SqlPreparedStmt *pPreStmt = p->pPreStmt;
001591        sqlite3_stmt *pStmt = pPreStmt->pStmt;
001592  
001593        rcs = sqlite3_step(pStmt);
001594        if( rcs==SQLITE_ROW ){
001595          return TCL_OK;
001596        }
001597        if( p->pArray ){
001598          dbEvalRowInfo(p, 0, 0);
001599        }
001600        rcs = sqlite3_reset(pStmt);
001601  
001602        pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1);
001603        pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1);
001604        pDb->nIndex = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_AUTOINDEX,1);
001605        pDb->nVMStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_VM_STEP,1);
001606        dbReleaseColumnNames(p);
001607        p->pPreStmt = 0;
001608  
001609        if( rcs!=SQLITE_OK ){
001610          /* If a run-time error occurs, report the error and stop reading
001611          ** the SQL.  */
001612          dbReleaseStmt(pDb, pPreStmt, 1);
001613  #if SQLITE_TEST
001614          if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){
001615            /* If the runtime error was an SQLITE_SCHEMA, and the database
001616            ** handle is configured to use the legacy sqlite3_prepare()
001617            ** interface, retry prepare()/step() on the same SQL statement.
001618            ** This only happens once. If there is a second SQLITE_SCHEMA
001619            ** error, the error will be returned to the caller. */
001620            p->zSql = zPrevSql;
001621            continue;
001622          }
001623  #endif
001624          Tcl_SetObjResult(pDb->interp,
001625                           Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
001626          return TCL_ERROR;
001627        }else{
001628          dbReleaseStmt(pDb, pPreStmt, 0);
001629        }
001630      }
001631    }
001632  
001633    /* Finished */
001634    return TCL_BREAK;
001635  }
001636  
001637  /*
001638  ** Free all resources currently held by the DbEvalContext structure passed
001639  ** as the first argument. There should be exactly one call to this function
001640  ** for each call to dbEvalInit().
001641  */
001642  static void dbEvalFinalize(DbEvalContext *p){
001643    if( p->pPreStmt ){
001644      sqlite3_reset(p->pPreStmt->pStmt);
001645      dbReleaseStmt(p->pDb, p->pPreStmt, 0);
001646      p->pPreStmt = 0;
001647    }
001648    if( p->pArray ){
001649      Tcl_DecrRefCount(p->pArray);
001650      p->pArray = 0;
001651    }
001652    Tcl_DecrRefCount(p->pSql);
001653    dbReleaseColumnNames(p);
001654  }
001655  
001656  /*
001657  ** Return a pointer to a Tcl_Obj structure with ref-count 0 that contains
001658  ** the value for the iCol'th column of the row currently pointed to by
001659  ** the DbEvalContext structure passed as the first argument.
001660  */
001661  static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
001662    sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
001663    switch( sqlite3_column_type(pStmt, iCol) ){
001664      case SQLITE_BLOB: {
001665        int bytes = sqlite3_column_bytes(pStmt, iCol);
001666        const char *zBlob = sqlite3_column_blob(pStmt, iCol);
001667        if( !zBlob ) bytes = 0;
001668        return Tcl_NewByteArrayObj((u8*)zBlob, bytes);
001669      }
001670      case SQLITE_INTEGER: {
001671        sqlite_int64 v = sqlite3_column_int64(pStmt, iCol);
001672        if( v>=-2147483647 && v<=2147483647 ){
001673          return Tcl_NewIntObj((int)v);
001674        }else{
001675          return Tcl_NewWideIntObj(v);
001676        }
001677      }
001678      case SQLITE_FLOAT: {
001679        return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol));
001680      }
001681      case SQLITE_NULL: {
001682        return Tcl_NewStringObj(p->pDb->zNull, -1);
001683      }
001684    }
001685  
001686    return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1);
001687  }
001688  
001689  /*
001690  ** If using Tcl version 8.6 or greater, use the NR functions to avoid
001691  ** recursive evalution of scripts by the [db eval] and [db trans]
001692  ** commands. Even if the headers used while compiling the extension
001693  ** are 8.6 or newer, the code still tests the Tcl version at runtime.
001694  ** This allows stubs-enabled builds to be used with older Tcl libraries.
001695  */
001696  #if TCL_MAJOR_VERSION>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6)
001697  # define SQLITE_TCL_NRE 1
001698  static int DbUseNre(void){
001699    int major, minor;
001700    Tcl_GetVersion(&major, &minor, 0, 0);
001701    return( (major==8 && minor>=6) || major>8 );
001702  }
001703  #else
001704  /*
001705  ** Compiling using headers earlier than 8.6. In this case NR cannot be
001706  ** used, so DbUseNre() to always return zero. Add #defines for the other
001707  ** Tcl_NRxxx() functions to prevent them from causing compilation errors,
001708  ** even though the only invocations of them are within conditional blocks
001709  ** of the form:
001710  **
001711  **   if( DbUseNre() ) { ... }
001712  */
001713  # define SQLITE_TCL_NRE 0
001714  # define DbUseNre() 0
001715  # define Tcl_NRAddCallback(a,b,c,d,e,f) (void)0
001716  # define Tcl_NREvalObj(a,b,c) 0
001717  # define Tcl_NRCreateCommand(a,b,c,d,e,f) (void)0
001718  #endif
001719  
001720  /*
001721  ** This function is part of the implementation of the command:
001722  **
001723  **   $db eval SQL ?ARRAYNAME? SCRIPT
001724  */
001725  static int SQLITE_TCLAPI DbEvalNextCmd(
001726    ClientData data[],                   /* data[0] is the (DbEvalContext*) */
001727    Tcl_Interp *interp,                  /* Tcl interpreter */
001728    int result                           /* Result so far */
001729  ){
001730    int rc = result;                     /* Return code */
001731  
001732    /* The first element of the data[] array is a pointer to a DbEvalContext
001733    ** structure allocated using Tcl_Alloc(). The second element of data[]
001734    ** is a pointer to a Tcl_Obj containing the script to run for each row
001735    ** returned by the queries encapsulated in data[0]. */
001736    DbEvalContext *p = (DbEvalContext *)data[0];
001737    Tcl_Obj *pScript = (Tcl_Obj *)data[1];
001738    Tcl_Obj *pArray = p->pArray;
001739  
001740    while( (rc==TCL_OK || rc==TCL_CONTINUE) && TCL_OK==(rc = dbEvalStep(p)) ){
001741      int i;
001742      int nCol;
001743      Tcl_Obj **apColName;
001744      dbEvalRowInfo(p, &nCol, &apColName);
001745      for(i=0; i<nCol; i++){
001746        if( pArray==0 ){
001747          Tcl_ObjSetVar2(interp, apColName[i], 0, dbEvalColumnValue(p,i), 0);
001748        }else if( (p->evalFlags & SQLITE_EVAL_WITHOUTNULLS)!=0
001749               && sqlite3_column_type(p->pPreStmt->pStmt, i)==SQLITE_NULL 
001750        ){
001751          Tcl_UnsetVar2(interp, Tcl_GetString(pArray), 
001752                        Tcl_GetString(apColName[i]), 0);
001753        }else{
001754          Tcl_ObjSetVar2(interp, pArray, apColName[i], dbEvalColumnValue(p,i), 0);
001755        }
001756      }
001757  
001758      /* The required interpreter variables are now populated with the data
001759      ** from the current row. If using NRE, schedule callbacks to evaluate
001760      ** script pScript, then to invoke this function again to fetch the next
001761      ** row (or clean up if there is no next row or the script throws an
001762      ** exception). After scheduling the callbacks, return control to the
001763      ** caller.
001764      **
001765      ** If not using NRE, evaluate pScript directly and continue with the
001766      ** next iteration of this while(...) loop.  */
001767      if( DbUseNre() ){
001768        Tcl_NRAddCallback(interp, DbEvalNextCmd, (void*)p, (void*)pScript, 0, 0);
001769        return Tcl_NREvalObj(interp, pScript, 0);
001770      }else{
001771        rc = Tcl_EvalObjEx(interp, pScript, 0);
001772      }
001773    }
001774  
001775    Tcl_DecrRefCount(pScript);
001776    dbEvalFinalize(p);
001777    Tcl_Free((char *)p);
001778  
001779    if( rc==TCL_OK || rc==TCL_BREAK ){
001780      Tcl_ResetResult(interp);
001781      rc = TCL_OK;
001782    }
001783    return rc;
001784  }
001785  
001786  /*
001787  ** This function is used by the implementations of the following database
001788  ** handle sub-commands:
001789  **
001790  **   $db update_hook ?SCRIPT?
001791  **   $db wal_hook ?SCRIPT?
001792  **   $db commit_hook ?SCRIPT?
001793  **   $db preupdate hook ?SCRIPT?
001794  */
001795  static void DbHookCmd(
001796    Tcl_Interp *interp,             /* Tcl interpreter */
001797    SqliteDb *pDb,                  /* Database handle */
001798    Tcl_Obj *pArg,                  /* SCRIPT argument (or NULL) */
001799    Tcl_Obj **ppHook                /* Pointer to member of SqliteDb */
001800  ){
001801    sqlite3 *db = pDb->db;
001802  
001803    if( *ppHook ){
001804      Tcl_SetObjResult(interp, *ppHook);
001805      if( pArg ){
001806        Tcl_DecrRefCount(*ppHook);
001807        *ppHook = 0;
001808      }
001809    }
001810    if( pArg ){
001811      assert( !(*ppHook) );
001812      if( Tcl_GetCharLength(pArg)>0 ){
001813        *ppHook = pArg;
001814        Tcl_IncrRefCount(*ppHook);
001815      }
001816    }
001817  
001818  #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
001819    sqlite3_preupdate_hook(db, (pDb->pPreUpdateHook?DbPreUpdateHandler:0), pDb);
001820  #endif
001821    sqlite3_update_hook(db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb);
001822    sqlite3_rollback_hook(db, (pDb->pRollbackHook?DbRollbackHandler:0), pDb);
001823    sqlite3_wal_hook(db, (pDb->pWalHook?DbWalHandler:0), pDb);
001824  }
001825  
001826  /*
001827  ** The "sqlite" command below creates a new Tcl command for each
001828  ** connection it opens to an SQLite database.  This routine is invoked
001829  ** whenever one of those connection-specific commands is executed
001830  ** in Tcl.  For example, if you run Tcl code like this:
001831  **
001832  **       sqlite3 db1  "my_database"
001833  **       db1 close
001834  **
001835  ** The first command opens a connection to the "my_database" database
001836  ** and calls that connection "db1".  The second command causes this
001837  ** subroutine to be invoked.
001838  */
001839  static int SQLITE_TCLAPI DbObjCmd(
001840    void *cd,
001841    Tcl_Interp *interp,
001842    int objc,
001843    Tcl_Obj *const*objv
001844  ){
001845    SqliteDb *pDb = (SqliteDb*)cd;
001846    int choice;
001847    int rc = TCL_OK;
001848    static const char *DB_strs[] = {
001849      "authorizer",         "backup",            "busy",
001850      "cache",              "changes",           "close",
001851      "collate",            "collation_needed",  "commit_hook",
001852      "complete",           "copy",              "enable_load_extension",
001853      "errorcode",          "eval",              "exists",
001854      "function",           "incrblob",          "interrupt",
001855      "last_insert_rowid",  "nullvalue",         "onecolumn",
001856      "preupdate",          "profile",           "progress",
001857      "rekey",              "restore",           "rollback_hook",
001858      "status",             "timeout",           "total_changes",
001859      "trace",              "trace_v2",          "transaction",
001860      "unlock_notify",      "update_hook",       "version",
001861      "wal_hook",
001862      0
001863    };
001864    enum DB_enum {
001865      DB_AUTHORIZER,        DB_BACKUP,           DB_BUSY,
001866      DB_CACHE,             DB_CHANGES,          DB_CLOSE,
001867      DB_COLLATE,           DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
001868      DB_COMPLETE,          DB_COPY,             DB_ENABLE_LOAD_EXTENSION,
001869      DB_ERRORCODE,         DB_EVAL,             DB_EXISTS,
001870      DB_FUNCTION,          DB_INCRBLOB,         DB_INTERRUPT,
001871      DB_LAST_INSERT_ROWID, DB_NULLVALUE,        DB_ONECOLUMN,
001872      DB_PREUPDATE,         DB_PROFILE,          DB_PROGRESS,
001873      DB_REKEY,             DB_RESTORE,          DB_ROLLBACK_HOOK,
001874      DB_STATUS,            DB_TIMEOUT,          DB_TOTAL_CHANGES,
001875      DB_TRACE,             DB_TRACE_V2,         DB_TRANSACTION,
001876      DB_UNLOCK_NOTIFY,     DB_UPDATE_HOOK,      DB_VERSION,
001877      DB_WAL_HOOK,
001878    };
001879    /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
001880  
001881    if( objc<2 ){
001882      Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
001883      return TCL_ERROR;
001884    }
001885    if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){
001886      return TCL_ERROR;
001887    }
001888  
001889    switch( (enum DB_enum)choice ){
001890  
001891    /*    $db authorizer ?CALLBACK?
001892    **
001893    ** Invoke the given callback to authorize each SQL operation as it is
001894    ** compiled.  5 arguments are appended to the callback before it is
001895    ** invoked:
001896    **
001897    **   (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...)
001898    **   (2) First descriptive name (depends on authorization type)
001899    **   (3) Second descriptive name
001900    **   (4) Name of the database (ex: "main", "temp")
001901    **   (5) Name of trigger that is doing the access
001902    **
001903    ** The callback should return on of the following strings: SQLITE_OK,
001904    ** SQLITE_IGNORE, or SQLITE_DENY.  Any other return value is an error.
001905    **
001906    ** If this method is invoked with no arguments, the current authorization
001907    ** callback string is returned.
001908    */
001909    case DB_AUTHORIZER: {
001910  #ifdef SQLITE_OMIT_AUTHORIZATION
001911      Tcl_AppendResult(interp, "authorization not available in this build",
001912                       (char*)0);
001913      return TCL_ERROR;
001914  #else
001915      if( objc>3 ){
001916        Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
001917        return TCL_ERROR;
001918      }else if( objc==2 ){
001919        if( pDb->zAuth ){
001920          Tcl_AppendResult(interp, pDb->zAuth, (char*)0);
001921        }
001922      }else{
001923        char *zAuth;
001924        int len;
001925        if( pDb->zAuth ){
001926          Tcl_Free(pDb->zAuth);
001927        }
001928        zAuth = Tcl_GetStringFromObj(objv[2], &len);
001929        if( zAuth && len>0 ){
001930          pDb->zAuth = Tcl_Alloc( len + 1 );
001931          memcpy(pDb->zAuth, zAuth, len+1);
001932        }else{
001933          pDb->zAuth = 0;
001934        }
001935        if( pDb->zAuth ){
001936          typedef int (*sqlite3_auth_cb)(
001937             void*,int,const char*,const char*,
001938             const char*,const char*);
001939          pDb->interp = interp;
001940          sqlite3_set_authorizer(pDb->db,(sqlite3_auth_cb)auth_callback,pDb);
001941        }else{
001942          sqlite3_set_authorizer(pDb->db, 0, 0);
001943        }
001944      }
001945  #endif
001946      break;
001947    }
001948  
001949    /*    $db backup ?DATABASE? FILENAME
001950    **
001951    ** Open or create a database file named FILENAME.  Transfer the
001952    ** content of local database DATABASE (default: "main") into the
001953    ** FILENAME database.
001954    */
001955    case DB_BACKUP: {
001956      const char *zDestFile;
001957      const char *zSrcDb;
001958      sqlite3 *pDest;
001959      sqlite3_backup *pBackup;
001960  
001961      if( objc==3 ){
001962        zSrcDb = "main";
001963        zDestFile = Tcl_GetString(objv[2]);
001964      }else if( objc==4 ){
001965        zSrcDb = Tcl_GetString(objv[2]);
001966        zDestFile = Tcl_GetString(objv[3]);
001967      }else{
001968        Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
001969        return TCL_ERROR;
001970      }
001971      rc = sqlite3_open_v2(zDestFile, &pDest,
001972                 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE| pDb->openFlags, 0);
001973      if( rc!=SQLITE_OK ){
001974        Tcl_AppendResult(interp, "cannot open target database: ",
001975             sqlite3_errmsg(pDest), (char*)0);
001976        sqlite3_close(pDest);
001977        return TCL_ERROR;
001978      }
001979      pBackup = sqlite3_backup_init(pDest, "main", pDb->db, zSrcDb);
001980      if( pBackup==0 ){
001981        Tcl_AppendResult(interp, "backup failed: ",
001982             sqlite3_errmsg(pDest), (char*)0);
001983        sqlite3_close(pDest);
001984        return TCL_ERROR;
001985      }
001986      while(  (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
001987      sqlite3_backup_finish(pBackup);
001988      if( rc==SQLITE_DONE ){
001989        rc = TCL_OK;
001990      }else{
001991        Tcl_AppendResult(interp, "backup failed: ",
001992             sqlite3_errmsg(pDest), (char*)0);
001993        rc = TCL_ERROR;
001994      }
001995      sqlite3_close(pDest);
001996      break;
001997    }
001998  
001999    /*    $db busy ?CALLBACK?
002000    **
002001    ** Invoke the given callback if an SQL statement attempts to open
002002    ** a locked database file.
002003    */
002004    case DB_BUSY: {
002005      if( objc>3 ){
002006        Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK");
002007        return TCL_ERROR;
002008      }else if( objc==2 ){
002009        if( pDb->zBusy ){
002010          Tcl_AppendResult(interp, pDb->zBusy, (char*)0);
002011        }
002012      }else{
002013        char *zBusy;
002014        int len;
002015        if( pDb->zBusy ){
002016          Tcl_Free(pDb->zBusy);
002017        }
002018        zBusy = Tcl_GetStringFromObj(objv[2], &len);
002019        if( zBusy && len>0 ){
002020          pDb->zBusy = Tcl_Alloc( len + 1 );
002021          memcpy(pDb->zBusy, zBusy, len+1);
002022        }else{
002023          pDb->zBusy = 0;
002024        }
002025        if( pDb->zBusy ){
002026          pDb->interp = interp;
002027          sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb);
002028        }else{
002029          sqlite3_busy_handler(pDb->db, 0, 0);
002030        }
002031      }
002032      break;
002033    }
002034  
002035    /*     $db cache flush
002036    **     $db cache size n
002037    **
002038    ** Flush the prepared statement cache, or set the maximum number of
002039    ** cached statements.
002040    */
002041    case DB_CACHE: {
002042      char *subCmd;
002043      int n;
002044  
002045      if( objc<=2 ){
002046        Tcl_WrongNumArgs(interp, 1, objv, "cache option ?arg?");
002047        return TCL_ERROR;
002048      }
002049      subCmd = Tcl_GetStringFromObj( objv[2], 0 );
002050      if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){
002051        if( objc!=3 ){
002052          Tcl_WrongNumArgs(interp, 2, objv, "flush");
002053          return TCL_ERROR;
002054        }else{
002055          flushStmtCache( pDb );
002056        }
002057      }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){
002058        if( objc!=4 ){
002059          Tcl_WrongNumArgs(interp, 2, objv, "size n");
002060          return TCL_ERROR;
002061        }else{
002062          if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){
002063            Tcl_AppendResult( interp, "cannot convert \"",
002064                 Tcl_GetStringFromObj(objv[3],0), "\" to integer", (char*)0);
002065            return TCL_ERROR;
002066          }else{
002067            if( n<0 ){
002068              flushStmtCache( pDb );
002069              n = 0;
002070            }else if( n>MAX_PREPARED_STMTS ){
002071              n = MAX_PREPARED_STMTS;
002072            }
002073            pDb->maxStmt = n;
002074          }
002075        }
002076      }else{
002077        Tcl_AppendResult( interp, "bad option \"",
002078            Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size",
002079            (char*)0);
002080        return TCL_ERROR;
002081      }
002082      break;
002083    }
002084  
002085    /*     $db changes
002086    **
002087    ** Return the number of rows that were modified, inserted, or deleted by
002088    ** the most recent INSERT, UPDATE or DELETE statement, not including
002089    ** any changes made by trigger programs.
002090    */
002091    case DB_CHANGES: {
002092      Tcl_Obj *pResult;
002093      if( objc!=2 ){
002094        Tcl_WrongNumArgs(interp, 2, objv, "");
002095        return TCL_ERROR;
002096      }
002097      pResult = Tcl_GetObjResult(interp);
002098      Tcl_SetIntObj(pResult, sqlite3_changes(pDb->db));
002099      break;
002100    }
002101  
002102    /*    $db close
002103    **
002104    ** Shutdown the database
002105    */
002106    case DB_CLOSE: {
002107      Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0));
002108      break;
002109    }
002110  
002111    /*
002112    **     $db collate NAME SCRIPT
002113    **
002114    ** Create a new SQL collation function called NAME.  Whenever
002115    ** that function is called, invoke SCRIPT to evaluate the function.
002116    */
002117    case DB_COLLATE: {
002118      SqlCollate *pCollate;
002119      char *zName;
002120      char *zScript;
002121      int nScript;
002122      if( objc!=4 ){
002123        Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
002124        return TCL_ERROR;
002125      }
002126      zName = Tcl_GetStringFromObj(objv[2], 0);
002127      zScript = Tcl_GetStringFromObj(objv[3], &nScript);
002128      pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 );
002129      if( pCollate==0 ) return TCL_ERROR;
002130      pCollate->interp = interp;
002131      pCollate->pNext = pDb->pCollate;
002132      pCollate->zScript = (char*)&pCollate[1];
002133      pDb->pCollate = pCollate;
002134      memcpy(pCollate->zScript, zScript, nScript+1);
002135      if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8,
002136          pCollate, tclSqlCollate) ){
002137        Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
002138        return TCL_ERROR;
002139      }
002140      break;
002141    }
002142  
002143    /*
002144    **     $db collation_needed SCRIPT
002145    **
002146    ** Create a new SQL collation function called NAME.  Whenever
002147    ** that function is called, invoke SCRIPT to evaluate the function.
002148    */
002149    case DB_COLLATION_NEEDED: {
002150      if( objc!=3 ){
002151        Tcl_WrongNumArgs(interp, 2, objv, "SCRIPT");
002152        return TCL_ERROR;
002153      }
002154      if( pDb->pCollateNeeded ){
002155        Tcl_DecrRefCount(pDb->pCollateNeeded);
002156      }
002157      pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]);
002158      Tcl_IncrRefCount(pDb->pCollateNeeded);
002159      sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded);
002160      break;
002161    }
002162  
002163    /*    $db commit_hook ?CALLBACK?
002164    **
002165    ** Invoke the given callback just before committing every SQL transaction.
002166    ** If the callback throws an exception or returns non-zero, then the
002167    ** transaction is aborted.  If CALLBACK is an empty string, the callback
002168    ** is disabled.
002169    */
002170    case DB_COMMIT_HOOK: {
002171      if( objc>3 ){
002172        Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
002173        return TCL_ERROR;
002174      }else if( objc==2 ){
002175        if( pDb->zCommit ){
002176          Tcl_AppendResult(interp, pDb->zCommit, (char*)0);
002177        }
002178      }else{
002179        const char *zCommit;
002180        int len;
002181        if( pDb->zCommit ){
002182          Tcl_Free(pDb->zCommit);
002183        }
002184        zCommit = Tcl_GetStringFromObj(objv[2], &len);
002185        if( zCommit && len>0 ){
002186          pDb->zCommit = Tcl_Alloc( len + 1 );
002187          memcpy(pDb->zCommit, zCommit, len+1);
002188        }else{
002189          pDb->zCommit = 0;
002190        }
002191        if( pDb->zCommit ){
002192          pDb->interp = interp;
002193          sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb);
002194        }else{
002195          sqlite3_commit_hook(pDb->db, 0, 0);
002196        }
002197      }
002198      break;
002199    }
002200  
002201    /*    $db complete SQL
002202    **
002203    ** Return TRUE if SQL is a complete SQL statement.  Return FALSE if
002204    ** additional lines of input are needed.  This is similar to the
002205    ** built-in "info complete" command of Tcl.
002206    */
002207    case DB_COMPLETE: {
002208  #ifndef SQLITE_OMIT_COMPLETE
002209      Tcl_Obj *pResult;
002210      int isComplete;
002211      if( objc!=3 ){
002212        Tcl_WrongNumArgs(interp, 2, objv, "SQL");
002213        return TCL_ERROR;
002214      }
002215      isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
002216      pResult = Tcl_GetObjResult(interp);
002217      Tcl_SetBooleanObj(pResult, isComplete);
002218  #endif
002219      break;
002220    }
002221  
002222    /*    $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
002223    **
002224    ** Copy data into table from filename, optionally using SEPARATOR
002225    ** as column separators.  If a column contains a null string, or the
002226    ** value of NULLINDICATOR, a NULL is inserted for the column.
002227    ** conflict-algorithm is one of the sqlite conflict algorithms:
002228    **    rollback, abort, fail, ignore, replace
002229    ** On success, return the number of lines processed, not necessarily same
002230    ** as 'db changes' due to conflict-algorithm selected.
002231    **
002232    ** This code is basically an implementation/enhancement of
002233    ** the sqlite3 shell.c ".import" command.
002234    **
002235    ** This command usage is equivalent to the sqlite2.x COPY statement,
002236    ** which imports file data into a table using the PostgreSQL COPY file format:
002237    **   $db copy $conflit_algo $table_name $filename \t \\N
002238    */
002239    case DB_COPY: {
002240      char *zTable;               /* Insert data into this table */
002241      char *zFile;                /* The file from which to extract data */
002242      char *zConflict;            /* The conflict algorithm to use */
002243      sqlite3_stmt *pStmt;        /* A statement */
002244      int nCol;                   /* Number of columns in the table */
002245      int nByte;                  /* Number of bytes in an SQL string */
002246      int i, j;                   /* Loop counters */
002247      int nSep;                   /* Number of bytes in zSep[] */
002248      int nNull;                  /* Number of bytes in zNull[] */
002249      char *zSql;                 /* An SQL statement */
002250      char *zLine;                /* A single line of input from the file */
002251      char **azCol;               /* zLine[] broken up into columns */
002252      const char *zCommit;        /* How to commit changes */
002253      FILE *in;                   /* The input file */
002254      int lineno = 0;             /* Line number of input file */
002255      char zLineNum[80];          /* Line number print buffer */
002256      Tcl_Obj *pResult;           /* interp result */
002257  
002258      const char *zSep;
002259      const char *zNull;
002260      if( objc<5 || objc>7 ){
002261        Tcl_WrongNumArgs(interp, 2, objv,
002262           "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
002263        return TCL_ERROR;
002264      }
002265      if( objc>=6 ){
002266        zSep = Tcl_GetStringFromObj(objv[5], 0);
002267      }else{
002268        zSep = "\t";
002269      }
002270      if( objc>=7 ){
002271        zNull = Tcl_GetStringFromObj(objv[6], 0);
002272      }else{
002273        zNull = "";
002274      }
002275      zConflict = Tcl_GetStringFromObj(objv[2], 0);
002276      zTable = Tcl_GetStringFromObj(objv[3], 0);
002277      zFile = Tcl_GetStringFromObj(objv[4], 0);
002278      nSep = strlen30(zSep);
002279      nNull = strlen30(zNull);
002280      if( nSep==0 ){
002281        Tcl_AppendResult(interp,"Error: non-null separator required for copy",
002282                         (char*)0);
002283        return TCL_ERROR;
002284      }
002285      if(strcmp(zConflict, "rollback") != 0 &&
002286         strcmp(zConflict, "abort"   ) != 0 &&
002287         strcmp(zConflict, "fail"    ) != 0 &&
002288         strcmp(zConflict, "ignore"  ) != 0 &&
002289         strcmp(zConflict, "replace" ) != 0 ) {
002290        Tcl_AppendResult(interp, "Error: \"", zConflict,
002291              "\", conflict-algorithm must be one of: rollback, "
002292              "abort, fail, ignore, or replace", (char*)0);
002293        return TCL_ERROR;
002294      }
002295      zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
002296      if( zSql==0 ){
002297        Tcl_AppendResult(interp, "Error: no such table: ", zTable, (char*)0);
002298        return TCL_ERROR;
002299      }
002300      nByte = strlen30(zSql);
002301      rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
002302      sqlite3_free(zSql);
002303      if( rc ){
002304        Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0);
002305        nCol = 0;
002306      }else{
002307        nCol = sqlite3_column_count(pStmt);
002308      }
002309      sqlite3_finalize(pStmt);
002310      if( nCol==0 ) {
002311        return TCL_ERROR;
002312      }
002313      zSql = malloc( nByte + 50 + nCol*2 );
002314      if( zSql==0 ) {
002315        Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
002316        return TCL_ERROR;
002317      }
002318      sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?",
002319           zConflict, zTable);
002320      j = strlen30(zSql);
002321      for(i=1; i<nCol; i++){
002322        zSql[j++] = ',';
002323        zSql[j++] = '?';
002324      }
002325      zSql[j++] = ')';
002326      zSql[j] = 0;
002327      rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
002328      free(zSql);
002329      if( rc ){
002330        Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), (char*)0);
002331        sqlite3_finalize(pStmt);
002332        return TCL_ERROR;
002333      }
002334      in = fopen(zFile, "rb");
002335      if( in==0 ){
002336        Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, (char*)0);
002337        sqlite3_finalize(pStmt);
002338        return TCL_ERROR;
002339      }
002340      azCol = malloc( sizeof(azCol[0])*(nCol+1) );
002341      if( azCol==0 ) {
002342        Tcl_AppendResult(interp, "Error: can't malloc()", (char*)0);
002343        fclose(in);
002344        return TCL_ERROR;
002345      }
002346      (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0);
002347      zCommit = "COMMIT";
002348      while( (zLine = local_getline(0, in))!=0 ){
002349        char *z;
002350        lineno++;
002351        azCol[0] = zLine;
002352        for(i=0, z=zLine; *z; z++){
002353          if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){
002354            *z = 0;
002355            i++;
002356            if( i<nCol ){
002357              azCol[i] = &z[nSep];
002358              z += nSep-1;
002359            }
002360          }
002361        }
002362        if( i+1!=nCol ){
002363          char *zErr;
002364          int nErr = strlen30(zFile) + 200;
002365          zErr = malloc(nErr);
002366          if( zErr ){
002367            sqlite3_snprintf(nErr, zErr,
002368               "Error: %s line %d: expected %d columns of data but found %d",
002369               zFile, lineno, nCol, i+1);
002370            Tcl_AppendResult(interp, zErr, (char*)0);
002371            free(zErr);
002372          }
002373          zCommit = "ROLLBACK";
002374          break;
002375        }
002376        for(i=0; i<nCol; i++){
002377          /* check for null data, if so, bind as null */
002378          if( (nNull>0 && strcmp(azCol[i], zNull)==0)
002379            || strlen30(azCol[i])==0
002380          ){
002381            sqlite3_bind_null(pStmt, i+1);
002382          }else{
002383            sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
002384          }
002385        }
002386        sqlite3_step(pStmt);
002387        rc = sqlite3_reset(pStmt);
002388        free(zLine);
002389        if( rc!=SQLITE_OK ){
002390          Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), (char*)0);
002391          zCommit = "ROLLBACK";
002392          break;
002393        }
002394      }
002395      free(azCol);
002396      fclose(in);
002397      sqlite3_finalize(pStmt);
002398      (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0);
002399  
002400      if( zCommit[0] == 'C' ){
002401        /* success, set result as number of lines processed */
002402        pResult = Tcl_GetObjResult(interp);
002403        Tcl_SetIntObj(pResult, lineno);
002404        rc = TCL_OK;
002405      }else{
002406        /* failure, append lineno where failed */
002407        sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno);
002408        Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,
002409                         (char*)0);
002410        rc = TCL_ERROR;
002411      }
002412      break;
002413    }
002414  
002415    /*
002416    **    $db enable_load_extension BOOLEAN
002417    **
002418    ** Turn the extension loading feature on or off.  It if off by
002419    ** default.
002420    */
002421    case DB_ENABLE_LOAD_EXTENSION: {
002422  #ifndef SQLITE_OMIT_LOAD_EXTENSION
002423      int onoff;
002424      if( objc!=3 ){
002425        Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN");
002426        return TCL_ERROR;
002427      }
002428      if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){
002429        return TCL_ERROR;
002430      }
002431      sqlite3_enable_load_extension(pDb->db, onoff);
002432      break;
002433  #else
002434      Tcl_AppendResult(interp, "extension loading is turned off at compile-time",
002435                       (char*)0);
002436      return TCL_ERROR;
002437  #endif
002438    }
002439  
002440    /*
002441    **    $db errorcode
002442    **
002443    ** Return the numeric error code that was returned by the most recent
002444    ** call to sqlite3_exec().
002445    */
002446    case DB_ERRORCODE: {
002447      Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db)));
002448      break;
002449    }
002450  
002451    /*
002452    **    $db exists $sql
002453    **    $db onecolumn $sql
002454    **
002455    ** The onecolumn method is the equivalent of:
002456    **     lindex [$db eval $sql] 0
002457    */
002458    case DB_EXISTS:
002459    case DB_ONECOLUMN: {
002460      Tcl_Obj *pResult = 0;
002461      DbEvalContext sEval;
002462      if( objc!=3 ){
002463        Tcl_WrongNumArgs(interp, 2, objv, "SQL");
002464        return TCL_ERROR;
002465      }
002466  
002467      dbEvalInit(&sEval, pDb, objv[2], 0, 0);
002468      rc = dbEvalStep(&sEval);
002469      if( choice==DB_ONECOLUMN ){
002470        if( rc==TCL_OK ){
002471          pResult = dbEvalColumnValue(&sEval, 0);
002472        }else if( rc==TCL_BREAK ){
002473          Tcl_ResetResult(interp);
002474        }
002475      }else if( rc==TCL_BREAK || rc==TCL_OK ){
002476        pResult = Tcl_NewBooleanObj(rc==TCL_OK);
002477      }
002478      dbEvalFinalize(&sEval);
002479      if( pResult ) Tcl_SetObjResult(interp, pResult);
002480  
002481      if( rc==TCL_BREAK ){
002482        rc = TCL_OK;
002483      }
002484      break;
002485    }
002486  
002487    /*
002488    **    $db eval ?options? $sql ?array? ?{  ...code... }?
002489    **
002490    ** The SQL statement in $sql is evaluated.  For each row, the values are
002491    ** placed in elements of the array named "array" and ...code... is executed.
002492    ** If "array" and "code" are omitted, then no callback is every invoked.
002493    ** If "array" is an empty string, then the values are placed in variables
002494    ** that have the same name as the fields extracted by the query.
002495    */
002496    case DB_EVAL: {
002497      int evalFlags = 0;
002498      const char *zOpt;
002499      while( objc>3 && (zOpt = Tcl_GetString(objv[2]))!=0 && zOpt[0]=='-' ){
002500        if( strcmp(zOpt, "-withoutnulls")==0 ){
002501          evalFlags |= SQLITE_EVAL_WITHOUTNULLS;
002502        }
002503        else{
002504          Tcl_AppendResult(interp, "unknown option: \"", zOpt, "\"", (void*)0);
002505          return TCL_ERROR;
002506        }
002507        objc--;
002508        objv++;
002509      }
002510      if( objc<3 || objc>5 ){
002511        Tcl_WrongNumArgs(interp, 2, objv, 
002512            "?OPTIONS? SQL ?ARRAY-NAME? ?SCRIPT?");
002513        return TCL_ERROR;
002514      }
002515  
002516      if( objc==3 ){
002517        DbEvalContext sEval;
002518        Tcl_Obj *pRet = Tcl_NewObj();
002519        Tcl_IncrRefCount(pRet);
002520        dbEvalInit(&sEval, pDb, objv[2], 0, 0);
002521        while( TCL_OK==(rc = dbEvalStep(&sEval)) ){
002522          int i;
002523          int nCol;
002524          dbEvalRowInfo(&sEval, &nCol, 0);
002525          for(i=0; i<nCol; i++){
002526            Tcl_ListObjAppendElement(interp, pRet, dbEvalColumnValue(&sEval, i));
002527          }
002528        }
002529        dbEvalFinalize(&sEval);
002530        if( rc==TCL_BREAK ){
002531          Tcl_SetObjResult(interp, pRet);
002532          rc = TCL_OK;
002533        }
002534        Tcl_DecrRefCount(pRet);
002535      }else{
002536        ClientData cd2[2];
002537        DbEvalContext *p;
002538        Tcl_Obj *pArray = 0;
002539        Tcl_Obj *pScript;
002540  
002541        if( objc>=5 && *(char *)Tcl_GetString(objv[3]) ){
002542          pArray = objv[3];
002543        }
002544        pScript = objv[objc-1];
002545        Tcl_IncrRefCount(pScript);
002546  
002547        p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
002548        dbEvalInit(p, pDb, objv[2], pArray, evalFlags);
002549  
002550        cd2[0] = (void *)p;
002551        cd2[1] = (void *)pScript;
002552        rc = DbEvalNextCmd(cd2, interp, TCL_OK);
002553      }
002554      break;
002555    }
002556  
002557    /*
002558    **     $db function NAME [-argcount N] [-deterministic] SCRIPT
002559    **
002560    ** Create a new SQL function called NAME.  Whenever that function is
002561    ** called, invoke SCRIPT to evaluate the function.
002562    */
002563    case DB_FUNCTION: {
002564      int flags = SQLITE_UTF8;
002565      SqlFunc *pFunc;
002566      Tcl_Obj *pScript;
002567      char *zName;
002568      int nArg = -1;
002569      int i;
002570      if( objc<4 ){
002571        Tcl_WrongNumArgs(interp, 2, objv, "NAME ?SWITCHES? SCRIPT");
002572        return TCL_ERROR;
002573      }
002574      for(i=3; i<(objc-1); i++){
002575        const char *z = Tcl_GetString(objv[i]);
002576        int n = strlen30(z);
002577        if( n>2 && strncmp(z, "-argcount",n)==0 ){
002578          if( i==(objc-2) ){
002579            Tcl_AppendResult(interp, "option requires an argument: ", z,(char*)0);
002580            return TCL_ERROR;
002581          }
002582          if( Tcl_GetIntFromObj(interp, objv[i+1], &nArg) ) return TCL_ERROR;
002583          if( nArg<0 ){
002584            Tcl_AppendResult(interp, "number of arguments must be non-negative",
002585                             (char*)0);
002586            return TCL_ERROR;
002587          }
002588          i++;
002589        }else
002590        if( n>2 && strncmp(z, "-deterministic",n)==0 ){
002591          flags |= SQLITE_DETERMINISTIC;
002592        }else{
002593          Tcl_AppendResult(interp, "bad option \"", z,
002594              "\": must be -argcount or -deterministic", (char*)0
002595          );
002596          return TCL_ERROR;
002597        }
002598      }
002599  
002600      pScript = objv[objc-1];
002601      zName = Tcl_GetStringFromObj(objv[2], 0);
002602      pFunc = findSqlFunc(pDb, zName);
002603      if( pFunc==0 ) return TCL_ERROR;
002604      if( pFunc->pScript ){
002605        Tcl_DecrRefCount(pFunc->pScript);
002606      }
002607      pFunc->pScript = pScript;
002608      Tcl_IncrRefCount(pScript);
002609      pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript);
002610      rc = sqlite3_create_function(pDb->db, zName, nArg, flags,
002611          pFunc, tclSqlFunc, 0, 0);
002612      if( rc!=SQLITE_OK ){
002613        rc = TCL_ERROR;
002614        Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
002615      }
002616      break;
002617    }
002618  
002619    /*
002620    **     $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID
002621    */
002622    case DB_INCRBLOB: {
002623  #ifdef SQLITE_OMIT_INCRBLOB
002624      Tcl_AppendResult(interp, "incrblob not available in this build", (char*)0);
002625      return TCL_ERROR;
002626  #else
002627      int isReadonly = 0;
002628      const char *zDb = "main";
002629      const char *zTable;
002630      const char *zColumn;
002631      Tcl_WideInt iRow;
002632  
002633      /* Check for the -readonly option */
002634      if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){
002635        isReadonly = 1;
002636      }
002637  
002638      if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){
002639        Tcl_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID");
002640        return TCL_ERROR;
002641      }
002642  
002643      if( objc==(6+isReadonly) ){
002644        zDb = Tcl_GetString(objv[2]);
002645      }
002646      zTable = Tcl_GetString(objv[objc-3]);
002647      zColumn = Tcl_GetString(objv[objc-2]);
002648      rc = Tcl_GetWideIntFromObj(interp, objv[objc-1], &iRow);
002649  
002650      if( rc==TCL_OK ){
002651        rc = createIncrblobChannel(
002652            interp, pDb, zDb, zTable, zColumn, (sqlite3_int64)iRow, isReadonly
002653        );
002654      }
002655  #endif
002656      break;
002657    }
002658  
002659    /*
002660    **     $db interrupt
002661    **
002662    ** Interrupt the execution of the inner-most SQL interpreter.  This
002663    ** causes the SQL statement to return an error of SQLITE_INTERRUPT.
002664    */
002665    case DB_INTERRUPT: {
002666      sqlite3_interrupt(pDb->db);
002667      break;
002668    }
002669  
002670    /*
002671    **     $db nullvalue ?STRING?
002672    **
002673    ** Change text used when a NULL comes back from the database. If ?STRING?
002674    ** is not present, then the current string used for NULL is returned.
002675    ** If STRING is present, then STRING is returned.
002676    **
002677    */
002678    case DB_NULLVALUE: {
002679      if( objc!=2 && objc!=3 ){
002680        Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE");
002681        return TCL_ERROR;
002682      }
002683      if( objc==3 ){
002684        int len;
002685        char *zNull = Tcl_GetStringFromObj(objv[2], &len);
002686        if( pDb->zNull ){
002687          Tcl_Free(pDb->zNull);
002688        }
002689        if( zNull && len>0 ){
002690          pDb->zNull = Tcl_Alloc( len + 1 );
002691          memcpy(pDb->zNull, zNull, len);
002692          pDb->zNull[len] = '\0';
002693        }else{
002694          pDb->zNull = 0;
002695        }
002696      }
002697      Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1));
002698      break;
002699    }
002700  
002701    /*
002702    **     $db last_insert_rowid
002703    **
002704    ** Return an integer which is the ROWID for the most recent insert.
002705    */
002706    case DB_LAST_INSERT_ROWID: {
002707      Tcl_Obj *pResult;
002708      Tcl_WideInt rowid;
002709      if( objc!=2 ){
002710        Tcl_WrongNumArgs(interp, 2, objv, "");
002711        return TCL_ERROR;
002712      }
002713      rowid = sqlite3_last_insert_rowid(pDb->db);
002714      pResult = Tcl_GetObjResult(interp);
002715      Tcl_SetWideIntObj(pResult, rowid);
002716      break;
002717    }
002718  
002719    /*
002720    ** The DB_ONECOLUMN method is implemented together with DB_EXISTS.
002721    */
002722  
002723    /*    $db progress ?N CALLBACK?
002724    **
002725    ** Invoke the given callback every N virtual machine opcodes while executing
002726    ** queries.
002727    */
002728    case DB_PROGRESS: {
002729      if( objc==2 ){
002730        if( pDb->zProgress ){
002731          Tcl_AppendResult(interp, pDb->zProgress, (char*)0);
002732        }
002733      }else if( objc==4 ){
002734        char *zProgress;
002735        int len;
002736        int N;
002737        if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){
002738          return TCL_ERROR;
002739        };
002740        if( pDb->zProgress ){
002741          Tcl_Free(pDb->zProgress);
002742        }
002743        zProgress = Tcl_GetStringFromObj(objv[3], &len);
002744        if( zProgress && len>0 ){
002745          pDb->zProgress = Tcl_Alloc( len + 1 );
002746          memcpy(pDb->zProgress, zProgress, len+1);
002747        }else{
002748          pDb->zProgress = 0;
002749        }
002750  #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
002751        if( pDb->zProgress ){
002752          pDb->interp = interp;
002753          sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb);
002754        }else{
002755          sqlite3_progress_handler(pDb->db, 0, 0, 0);
002756        }
002757  #endif
002758      }else{
002759        Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK");
002760        return TCL_ERROR;
002761      }
002762      break;
002763    }
002764  
002765    /*    $db profile ?CALLBACK?
002766    **
002767    ** Make arrangements to invoke the CALLBACK routine after each SQL statement
002768    ** that has run.  The text of the SQL and the amount of elapse time are
002769    ** appended to CALLBACK before the script is run.
002770    */
002771    case DB_PROFILE: {
002772      if( objc>3 ){
002773        Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
002774        return TCL_ERROR;
002775      }else if( objc==2 ){
002776        if( pDb->zProfile ){
002777          Tcl_AppendResult(interp, pDb->zProfile, (char*)0);
002778        }
002779      }else{
002780        char *zProfile;
002781        int len;
002782        if( pDb->zProfile ){
002783          Tcl_Free(pDb->zProfile);
002784        }
002785        zProfile = Tcl_GetStringFromObj(objv[2], &len);
002786        if( zProfile && len>0 ){
002787          pDb->zProfile = Tcl_Alloc( len + 1 );
002788          memcpy(pDb->zProfile, zProfile, len+1);
002789        }else{
002790          pDb->zProfile = 0;
002791        }
002792  #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
002793      !defined(SQLITE_OMIT_DEPRECATED)
002794        if( pDb->zProfile ){
002795          pDb->interp = interp;
002796          sqlite3_profile(pDb->db, DbProfileHandler, pDb);
002797        }else{
002798          sqlite3_profile(pDb->db, 0, 0);
002799        }
002800  #endif
002801      }
002802      break;
002803    }
002804  
002805    /*
002806    **     $db rekey KEY
002807    **
002808    ** Change the encryption key on the currently open database.
002809    */
002810    case DB_REKEY: {
002811  #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
002812      int nKey;
002813      void *pKey;
002814  #endif
002815      if( objc!=3 ){
002816        Tcl_WrongNumArgs(interp, 2, objv, "KEY");
002817        return TCL_ERROR;
002818      }
002819  #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
002820      pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
002821      rc = sqlite3_rekey(pDb->db, pKey, nKey);
002822      if( rc ){
002823        Tcl_AppendResult(interp, sqlite3_errstr(rc), (char*)0);
002824        rc = TCL_ERROR;
002825      }
002826  #endif
002827      break;
002828    }
002829  
002830    /*    $db restore ?DATABASE? FILENAME
002831    **
002832    ** Open a database file named FILENAME.  Transfer the content
002833    ** of FILENAME into the local database DATABASE (default: "main").
002834    */
002835    case DB_RESTORE: {
002836      const char *zSrcFile;
002837      const char *zDestDb;
002838      sqlite3 *pSrc;
002839      sqlite3_backup *pBackup;
002840      int nTimeout = 0;
002841  
002842      if( objc==3 ){
002843        zDestDb = "main";
002844        zSrcFile = Tcl_GetString(objv[2]);
002845      }else if( objc==4 ){
002846        zDestDb = Tcl_GetString(objv[2]);
002847        zSrcFile = Tcl_GetString(objv[3]);
002848      }else{
002849        Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
002850        return TCL_ERROR;
002851      }
002852      rc = sqlite3_open_v2(zSrcFile, &pSrc,
002853                           SQLITE_OPEN_READONLY | pDb->openFlags, 0);
002854      if( rc!=SQLITE_OK ){
002855        Tcl_AppendResult(interp, "cannot open source database: ",
002856             sqlite3_errmsg(pSrc), (char*)0);
002857        sqlite3_close(pSrc);
002858        return TCL_ERROR;
002859      }
002860      pBackup = sqlite3_backup_init(pDb->db, zDestDb, pSrc, "main");
002861      if( pBackup==0 ){
002862        Tcl_AppendResult(interp, "restore failed: ",
002863             sqlite3_errmsg(pDb->db), (char*)0);
002864        sqlite3_close(pSrc);
002865        return TCL_ERROR;
002866      }
002867      while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
002868                || rc==SQLITE_BUSY ){
002869        if( rc==SQLITE_BUSY ){
002870          if( nTimeout++ >= 3 ) break;
002871          sqlite3_sleep(100);
002872        }
002873      }
002874      sqlite3_backup_finish(pBackup);
002875      if( rc==SQLITE_DONE ){
002876        rc = TCL_OK;
002877      }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
002878        Tcl_AppendResult(interp, "restore failed: source database busy",
002879                         (char*)0);
002880        rc = TCL_ERROR;
002881      }else{
002882        Tcl_AppendResult(interp, "restore failed: ",
002883             sqlite3_errmsg(pDb->db), (char*)0);
002884        rc = TCL_ERROR;
002885      }
002886      sqlite3_close(pSrc);
002887      break;
002888    }
002889  
002890    /*
002891    **     $db status (step|sort|autoindex|vmstep)
002892    **
002893    ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or
002894    ** SQLITE_STMTSTATUS_SORT for the most recent eval.
002895    */
002896    case DB_STATUS: {
002897      int v;
002898      const char *zOp;
002899      if( objc!=3 ){
002900        Tcl_WrongNumArgs(interp, 2, objv, "(step|sort|autoindex)");
002901        return TCL_ERROR;
002902      }
002903      zOp = Tcl_GetString(objv[2]);
002904      if( strcmp(zOp, "step")==0 ){
002905        v = pDb->nStep;
002906      }else if( strcmp(zOp, "sort")==0 ){
002907        v = pDb->nSort;
002908      }else if( strcmp(zOp, "autoindex")==0 ){
002909        v = pDb->nIndex;
002910      }else if( strcmp(zOp, "vmstep")==0 ){
002911        v = pDb->nVMStep;
002912      }else{
002913        Tcl_AppendResult(interp,
002914              "bad argument: should be autoindex, step, sort or vmstep",
002915              (char*)0);
002916        return TCL_ERROR;
002917      }
002918      Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
002919      break;
002920    }
002921  
002922    /*
002923    **     $db timeout MILLESECONDS
002924    **
002925    ** Delay for the number of milliseconds specified when a file is locked.
002926    */
002927    case DB_TIMEOUT: {
002928      int ms;
002929      if( objc!=3 ){
002930        Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS");
002931        return TCL_ERROR;
002932      }
002933      if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR;
002934      sqlite3_busy_timeout(pDb->db, ms);
002935      break;
002936    }
002937  
002938    /*
002939    **     $db total_changes
002940    **
002941    ** Return the number of rows that were modified, inserted, or deleted
002942    ** since the database handle was created.
002943    */
002944    case DB_TOTAL_CHANGES: {
002945      Tcl_Obj *pResult;
002946      if( objc!=2 ){
002947        Tcl_WrongNumArgs(interp, 2, objv, "");
002948        return TCL_ERROR;
002949      }
002950      pResult = Tcl_GetObjResult(interp);
002951      Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db));
002952      break;
002953    }
002954  
002955    /*    $db trace ?CALLBACK?
002956    **
002957    ** Make arrangements to invoke the CALLBACK routine for each SQL statement
002958    ** that is executed.  The text of the SQL is appended to CALLBACK before
002959    ** it is executed.
002960    */
002961    case DB_TRACE: {
002962      if( objc>3 ){
002963        Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
002964        return TCL_ERROR;
002965      }else if( objc==2 ){
002966        if( pDb->zTrace ){
002967          Tcl_AppendResult(interp, pDb->zTrace, (char*)0);
002968        }
002969      }else{
002970        char *zTrace;
002971        int len;
002972        if( pDb->zTrace ){
002973          Tcl_Free(pDb->zTrace);
002974        }
002975        zTrace = Tcl_GetStringFromObj(objv[2], &len);
002976        if( zTrace && len>0 ){
002977          pDb->zTrace = Tcl_Alloc( len + 1 );
002978          memcpy(pDb->zTrace, zTrace, len+1);
002979        }else{
002980          pDb->zTrace = 0;
002981        }
002982  #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT) && \
002983      !defined(SQLITE_OMIT_DEPRECATED)
002984        if( pDb->zTrace ){
002985          pDb->interp = interp;
002986          sqlite3_trace(pDb->db, DbTraceHandler, pDb);
002987        }else{
002988          sqlite3_trace(pDb->db, 0, 0);
002989        }
002990  #endif
002991      }
002992      break;
002993    }
002994  
002995    /*    $db trace_v2 ?CALLBACK? ?MASK?
002996    **
002997    ** Make arrangements to invoke the CALLBACK routine for each trace event
002998    ** matching the mask that is generated.  The parameters are appended to
002999    ** CALLBACK before it is executed.
003000    */
003001    case DB_TRACE_V2: {
003002      if( objc>4 ){
003003        Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK? ?MASK?");
003004        return TCL_ERROR;
003005      }else if( objc==2 ){
003006        if( pDb->zTraceV2 ){
003007          Tcl_AppendResult(interp, pDb->zTraceV2, (char*)0);
003008        }
003009      }else{
003010        char *zTraceV2;
003011        int len;
003012        Tcl_WideInt wMask = 0;
003013        if( objc==4 ){
003014          static const char *TTYPE_strs[] = {
003015            "statement", "profile", "row", "close", 0
003016          };
003017          enum TTYPE_enum {
003018            TTYPE_STMT, TTYPE_PROFILE, TTYPE_ROW, TTYPE_CLOSE
003019          };
003020          int i;
003021          if( TCL_OK!=Tcl_ListObjLength(interp, objv[3], &len) ){
003022            return TCL_ERROR;
003023          }
003024          for(i=0; i<len; i++){
003025            Tcl_Obj *pObj;
003026            int ttype;
003027            if( TCL_OK!=Tcl_ListObjIndex(interp, objv[3], i, &pObj) ){
003028              return TCL_ERROR;
003029            }
003030            if( Tcl_GetIndexFromObj(interp, pObj, TTYPE_strs, "trace type",
003031                                    0, &ttype)!=TCL_OK ){
003032              Tcl_WideInt wType;
003033              Tcl_Obj *pError = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
003034              Tcl_IncrRefCount(pError);
003035              if( TCL_OK==Tcl_GetWideIntFromObj(interp, pObj, &wType) ){
003036                Tcl_DecrRefCount(pError);
003037                wMask |= wType;
003038              }else{
003039                Tcl_SetObjResult(interp, pError);
003040                Tcl_DecrRefCount(pError);
003041                return TCL_ERROR;
003042              }
003043            }else{
003044              switch( (enum TTYPE_enum)ttype ){
003045                case TTYPE_STMT:    wMask |= SQLITE_TRACE_STMT;    break;
003046                case TTYPE_PROFILE: wMask |= SQLITE_TRACE_PROFILE; break;
003047                case TTYPE_ROW:     wMask |= SQLITE_TRACE_ROW;     break;
003048                case TTYPE_CLOSE:   wMask |= SQLITE_TRACE_CLOSE;   break;
003049              }
003050            }
003051          }
003052        }else{
003053          wMask = SQLITE_TRACE_STMT; /* use the "legacy" default */
003054        }
003055        if( pDb->zTraceV2 ){
003056          Tcl_Free(pDb->zTraceV2);
003057        }
003058        zTraceV2 = Tcl_GetStringFromObj(objv[2], &len);
003059        if( zTraceV2 && len>0 ){
003060          pDb->zTraceV2 = Tcl_Alloc( len + 1 );
003061          memcpy(pDb->zTraceV2, zTraceV2, len+1);
003062        }else{
003063          pDb->zTraceV2 = 0;
003064        }
003065  #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
003066        if( pDb->zTraceV2 ){
003067          pDb->interp = interp;
003068          sqlite3_trace_v2(pDb->db, (unsigned)wMask, DbTraceV2Handler, pDb);
003069        }else{
003070          sqlite3_trace_v2(pDb->db, 0, 0, 0);
003071        }
003072  #endif
003073      }
003074      break;
003075    }
003076  
003077    /*    $db transaction [-deferred|-immediate|-exclusive] SCRIPT
003078    **
003079    ** Start a new transaction (if we are not already in the midst of a
003080    ** transaction) and execute the TCL script SCRIPT.  After SCRIPT
003081    ** completes, either commit the transaction or roll it back if SCRIPT
003082    ** throws an exception.  Or if no new transation was started, do nothing.
003083    ** pass the exception on up the stack.
003084    **
003085    ** This command was inspired by Dave Thomas's talk on Ruby at the
003086    ** 2005 O'Reilly Open Source Convention (OSCON).
003087    */
003088    case DB_TRANSACTION: {
003089      Tcl_Obj *pScript;
003090      const char *zBegin = "SAVEPOINT _tcl_transaction";
003091      if( objc!=3 && objc!=4 ){
003092        Tcl_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT");
003093        return TCL_ERROR;
003094      }
003095  
003096      if( pDb->nTransaction==0 && objc==4 ){
003097        static const char *TTYPE_strs[] = {
003098          "deferred",   "exclusive",  "immediate", 0
003099        };
003100        enum TTYPE_enum {
003101          TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE
003102        };
003103        int ttype;
003104        if( Tcl_GetIndexFromObj(interp, objv[2], TTYPE_strs, "transaction type",
003105                                0, &ttype) ){
003106          return TCL_ERROR;
003107        }
003108        switch( (enum TTYPE_enum)ttype ){
003109          case TTYPE_DEFERRED:    /* no-op */;                 break;
003110          case TTYPE_EXCLUSIVE:   zBegin = "BEGIN EXCLUSIVE";  break;
003111          case TTYPE_IMMEDIATE:   zBegin = "BEGIN IMMEDIATE";  break;
003112        }
003113      }
003114      pScript = objv[objc-1];
003115  
003116      /* Run the SQLite BEGIN command to open a transaction or savepoint. */
003117      pDb->disableAuth++;
003118      rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0);
003119      pDb->disableAuth--;
003120      if( rc!=SQLITE_OK ){
003121        Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
003122        return TCL_ERROR;
003123      }
003124      pDb->nTransaction++;
003125  
003126      /* If using NRE, schedule a callback to invoke the script pScript, then
003127      ** a second callback to commit (or rollback) the transaction or savepoint
003128      ** opened above. If not using NRE, evaluate the script directly, then
003129      ** call function DbTransPostCmd() to commit (or rollback) the transaction
003130      ** or savepoint.  */
003131      if( DbUseNre() ){
003132        Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
003133        (void)Tcl_NREvalObj(interp, pScript, 0);
003134      }else{
003135        rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0));
003136      }
003137      break;
003138    }
003139  
003140    /*
003141    **    $db unlock_notify ?script?
003142    */
003143    case DB_UNLOCK_NOTIFY: {
003144  #ifndef SQLITE_ENABLE_UNLOCK_NOTIFY
003145      Tcl_AppendResult(interp, "unlock_notify not available in this build",
003146                       (char*)0);
003147      rc = TCL_ERROR;
003148  #else
003149      if( objc!=2 && objc!=3 ){
003150        Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
003151        rc = TCL_ERROR;
003152      }else{
003153        void (*xNotify)(void **, int) = 0;
003154        void *pNotifyArg = 0;
003155  
003156        if( pDb->pUnlockNotify ){
003157          Tcl_DecrRefCount(pDb->pUnlockNotify);
003158          pDb->pUnlockNotify = 0;
003159        }
003160  
003161        if( objc==3 ){
003162          xNotify = DbUnlockNotify;
003163          pNotifyArg = (void *)pDb;
003164          pDb->pUnlockNotify = objv[2];
003165          Tcl_IncrRefCount(pDb->pUnlockNotify);
003166        }
003167  
003168        if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){
003169          Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
003170          rc = TCL_ERROR;
003171        }
003172      }
003173  #endif
003174      break;
003175    }
003176  
003177    /*
003178    **    $db preupdate_hook count
003179    **    $db preupdate_hook hook ?SCRIPT?
003180    **    $db preupdate_hook new INDEX
003181    **    $db preupdate_hook old INDEX
003182    */
003183    case DB_PREUPDATE: {
003184  #ifndef SQLITE_ENABLE_PREUPDATE_HOOK
003185      Tcl_AppendResult(interp, "preupdate_hook was omitted at compile-time", 
003186                       (char*)0);
003187      rc = TCL_ERROR;
003188  #else
003189      static const char *azSub[] = {"count", "depth", "hook", "new", "old", 0};
003190      enum DbPreupdateSubCmd {
003191        PRE_COUNT, PRE_DEPTH, PRE_HOOK, PRE_NEW, PRE_OLD
003192      };
003193      int iSub;
003194  
003195      if( objc<3 ){
003196        Tcl_WrongNumArgs(interp, 2, objv, "SUB-COMMAND ?ARGS?");
003197      }
003198      if( Tcl_GetIndexFromObj(interp, objv[2], azSub, "sub-command", 0, &iSub) ){
003199        return TCL_ERROR;
003200      }
003201  
003202      switch( (enum DbPreupdateSubCmd)iSub ){
003203        case PRE_COUNT: {
003204          int nCol = sqlite3_preupdate_count(pDb->db);
003205          Tcl_SetObjResult(interp, Tcl_NewIntObj(nCol));
003206          break;
003207        }
003208  
003209        case PRE_HOOK: {
003210          if( objc>4 ){
003211            Tcl_WrongNumArgs(interp, 2, objv, "hook ?SCRIPT?");
003212            return TCL_ERROR;
003213          }
003214          DbHookCmd(interp, pDb, (objc==4 ? objv[3] : 0), &pDb->pPreUpdateHook);
003215          break;
003216        }
003217  
003218        case PRE_DEPTH: {
003219          Tcl_Obj *pRet;
003220          if( objc!=3 ){
003221            Tcl_WrongNumArgs(interp, 3, objv, "");
003222            return TCL_ERROR;
003223          }
003224          pRet = Tcl_NewIntObj(sqlite3_preupdate_depth(pDb->db));
003225          Tcl_SetObjResult(interp, pRet);
003226          break;
003227        }
003228  
003229        case PRE_NEW:
003230        case PRE_OLD: {
003231          int iIdx;
003232          sqlite3_value *pValue;
003233          if( objc!=4 ){
003234            Tcl_WrongNumArgs(interp, 3, objv, "INDEX");
003235            return TCL_ERROR;
003236          }
003237          if( Tcl_GetIntFromObj(interp, objv[3], &iIdx) ){
003238            return TCL_ERROR;
003239          }
003240  
003241          if( iSub==PRE_OLD ){
003242            rc = sqlite3_preupdate_old(pDb->db, iIdx, &pValue);
003243          }else{
003244            assert( iSub==PRE_NEW );
003245            rc = sqlite3_preupdate_new(pDb->db, iIdx, &pValue);
003246          }
003247  
003248          if( rc==SQLITE_OK ){
003249            Tcl_Obj *pObj;
003250            pObj = Tcl_NewStringObj((char*)sqlite3_value_text(pValue), -1);
003251            Tcl_SetObjResult(interp, pObj);
003252          }else{
003253            Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
003254            return TCL_ERROR;
003255          }
003256        }
003257      }
003258  #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
003259      break;
003260    }
003261  
003262    /*
003263    **    $db wal_hook ?script?
003264    **    $db update_hook ?script?
003265    **    $db rollback_hook ?script?
003266    */
003267    case DB_WAL_HOOK:
003268    case DB_UPDATE_HOOK:
003269    case DB_ROLLBACK_HOOK: {
003270      /* set ppHook to point at pUpdateHook or pRollbackHook, depending on
003271      ** whether [$db update_hook] or [$db rollback_hook] was invoked.
003272      */
003273      Tcl_Obj **ppHook = 0;
003274      if( choice==DB_WAL_HOOK ) ppHook = &pDb->pWalHook;
003275      if( choice==DB_UPDATE_HOOK ) ppHook = &pDb->pUpdateHook;
003276      if( choice==DB_ROLLBACK_HOOK ) ppHook = &pDb->pRollbackHook;
003277      if( objc>3 ){
003278         Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
003279         return TCL_ERROR;
003280      }
003281  
003282      DbHookCmd(interp, pDb, (objc==3 ? objv[2] : 0), ppHook);
003283      break;
003284    }
003285  
003286    /*    $db version
003287    **
003288    ** Return the version string for this database.
003289    */
003290    case DB_VERSION: {
003291      int i;
003292      for(i=2; i<objc; i++){
003293        const char *zArg = Tcl_GetString(objv[i]);
003294        /* Optional arguments to $db version are used for testing purpose */
003295  #ifdef SQLITE_TEST
003296        /* $db version -use-legacy-prepare BOOLEAN
003297        **
003298        ** Turn the use of legacy sqlite3_prepare() on or off.
003299        */
003300        if( strcmp(zArg, "-use-legacy-prepare")==0 && i+1<objc ){
003301          i++;
003302          if( Tcl_GetBooleanFromObj(interp, objv[i], &pDb->bLegacyPrepare) ){
003303            return TCL_ERROR;
003304          }
003305        }else
003306  
003307        /* $db version -last-stmt-ptr
003308        **
003309        ** Return a string which is a hex encoding of the pointer to the
003310        ** most recent sqlite3_stmt in the statement cache.
003311        */
003312        if( strcmp(zArg, "-last-stmt-ptr")==0 ){
003313          char zBuf[100];
003314          sqlite3_snprintf(sizeof(zBuf), zBuf, "%p",
003315                           pDb->stmtList ? pDb->stmtList->pStmt: 0);
003316          Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
003317        }else
003318  #endif /* SQLITE_TEST */
003319        {
003320          Tcl_AppendResult(interp, "unknown argument: ", zArg, (char*)0);
003321          return TCL_ERROR;
003322        }
003323      }
003324      if( i==2 ){   
003325        Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
003326      }
003327      break;
003328    }
003329  
003330  
003331    } /* End of the SWITCH statement */
003332    return rc;
003333  }
003334  
003335  #if SQLITE_TCL_NRE
003336  /*
003337  ** Adaptor that provides an objCmd interface to the NRE-enabled
003338  ** interface implementation.
003339  */
003340  static int SQLITE_TCLAPI DbObjCmdAdaptor(
003341    void *cd,
003342    Tcl_Interp *interp,
003343    int objc,
003344    Tcl_Obj *const*objv
003345  ){
003346    return Tcl_NRCallObjProc(interp, DbObjCmd, cd, objc, objv);
003347  }
003348  #endif /* SQLITE_TCL_NRE */
003349  
003350  /*
003351  **   sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
003352  **                           ?-create BOOLEAN? ?-nomutex BOOLEAN?
003353  **
003354  ** This is the main Tcl command.  When the "sqlite" Tcl command is
003355  ** invoked, this routine runs to process that command.
003356  **
003357  ** The first argument, DBNAME, is an arbitrary name for a new
003358  ** database connection.  This command creates a new command named
003359  ** DBNAME that is used to control that connection.  The database
003360  ** connection is deleted when the DBNAME command is deleted.
003361  **
003362  ** The second argument is the name of the database file.
003363  **
003364  */
003365  static int SQLITE_TCLAPI DbMain(
003366    void *cd,
003367    Tcl_Interp *interp,
003368    int objc,
003369    Tcl_Obj *const*objv
003370  ){
003371    SqliteDb *p;
003372    const char *zArg;
003373    char *zErrMsg;
003374    int i;
003375    const char *zFile;
003376    const char *zVfs = 0;
003377    int flags;
003378    Tcl_DString translatedFilename;
003379  #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
003380    void *pKey = 0;
003381    int nKey = 0;
003382  #endif
003383    int rc;
003384  
003385    /* In normal use, each TCL interpreter runs in a single thread.  So
003386    ** by default, we can turn of mutexing on SQLite database connections.
003387    ** However, for testing purposes it is useful to have mutexes turned
003388    ** on.  So, by default, mutexes default off.  But if compiled with
003389    ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on.
003390    */
003391  #ifdef SQLITE_TCL_DEFAULT_FULLMUTEX
003392    flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX;
003393  #else
003394    flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX;
003395  #endif
003396  
003397    if( objc==2 ){
003398      zArg = Tcl_GetStringFromObj(objv[1], 0);
003399      if( strcmp(zArg,"-version")==0 ){
003400        Tcl_AppendResult(interp,sqlite3_libversion(), (char*)0);
003401        return TCL_OK;
003402      }
003403      if( strcmp(zArg,"-sourceid")==0 ){
003404        Tcl_AppendResult(interp,sqlite3_sourceid(), (char*)0);
003405        return TCL_OK;
003406      }
003407      if( strcmp(zArg,"-has-codec")==0 ){
003408  #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
003409        Tcl_AppendResult(interp,"1",(char*)0);
003410  #else
003411        Tcl_AppendResult(interp,"0",(char*)0);
003412  #endif
003413        return TCL_OK;
003414      }
003415    }
003416    for(i=3; i+1<objc; i+=2){
003417      zArg = Tcl_GetString(objv[i]);
003418      if( strcmp(zArg,"-key")==0 ){
003419  #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
003420        pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey);
003421  #endif
003422      }else if( strcmp(zArg, "-vfs")==0 ){
003423        zVfs = Tcl_GetString(objv[i+1]);
003424      }else if( strcmp(zArg, "-readonly")==0 ){
003425        int b;
003426        if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
003427        if( b ){
003428          flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
003429          flags |= SQLITE_OPEN_READONLY;
003430        }else{
003431          flags &= ~SQLITE_OPEN_READONLY;
003432          flags |= SQLITE_OPEN_READWRITE;
003433        }
003434      }else if( strcmp(zArg, "-create")==0 ){
003435        int b;
003436        if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
003437        if( b && (flags & SQLITE_OPEN_READONLY)==0 ){
003438          flags |= SQLITE_OPEN_CREATE;
003439        }else{
003440          flags &= ~SQLITE_OPEN_CREATE;
003441        }
003442      }else if( strcmp(zArg, "-nomutex")==0 ){
003443        int b;
003444        if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
003445        if( b ){
003446          flags |= SQLITE_OPEN_NOMUTEX;
003447          flags &= ~SQLITE_OPEN_FULLMUTEX;
003448        }else{
003449          flags &= ~SQLITE_OPEN_NOMUTEX;
003450        }
003451      }else if( strcmp(zArg, "-fullmutex")==0 ){
003452        int b;
003453        if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
003454        if( b ){
003455          flags |= SQLITE_OPEN_FULLMUTEX;
003456          flags &= ~SQLITE_OPEN_NOMUTEX;
003457        }else{
003458          flags &= ~SQLITE_OPEN_FULLMUTEX;
003459        }
003460      }else if( strcmp(zArg, "-uri")==0 ){
003461        int b;
003462        if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
003463        if( b ){
003464          flags |= SQLITE_OPEN_URI;
003465        }else{
003466          flags &= ~SQLITE_OPEN_URI;
003467        }
003468      }else{
003469        Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0);
003470        return TCL_ERROR;
003471      }
003472    }
003473    if( objc<3 || (objc&1)!=1 ){
003474      Tcl_WrongNumArgs(interp, 1, objv,
003475        "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
003476        " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
003477  #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
003478        " ?-key CODECKEY?"
003479  #endif
003480      );
003481      return TCL_ERROR;
003482    }
003483    zErrMsg = 0;
003484    p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
003485    memset(p, 0, sizeof(*p));
003486    zFile = Tcl_GetStringFromObj(objv[2], 0);
003487    zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
003488    rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
003489    Tcl_DStringFree(&translatedFilename);
003490    if( p->db ){
003491      if( SQLITE_OK!=sqlite3_errcode(p->db) ){
003492        zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
003493        sqlite3_close(p->db);
003494        p->db = 0;
003495      }
003496    }else{
003497      zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc));
003498    }
003499  #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_CODEC_FROM_TCL)
003500    if( p->db ){
003501      sqlite3_key(p->db, pKey, nKey);
003502    }
003503  #endif
003504    if( p->db==0 ){
003505      Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
003506      Tcl_Free((char*)p);
003507      sqlite3_free(zErrMsg);
003508      return TCL_ERROR;
003509    }
003510    p->maxStmt = NUM_PREPARED_STMTS;
003511    p->openFlags = flags & SQLITE_OPEN_URI;
003512    p->interp = interp;
003513    zArg = Tcl_GetStringFromObj(objv[1], 0);
003514    if( DbUseNre() ){
003515      Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd,
003516                          (char*)p, DbDeleteCmd);
003517    }else{
003518      Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);
003519    }
003520    return TCL_OK;
003521  }
003522  
003523  /*
003524  ** Provide a dummy Tcl_InitStubs if we are using this as a static
003525  ** library.
003526  */
003527  #ifndef USE_TCL_STUBS
003528  # undef  Tcl_InitStubs
003529  # define Tcl_InitStubs(a,b,c) TCL_VERSION
003530  #endif
003531  
003532  /*
003533  ** Make sure we have a PACKAGE_VERSION macro defined.  This will be
003534  ** defined automatically by the TEA makefile.  But other makefiles
003535  ** do not define it.
003536  */
003537  #ifndef PACKAGE_VERSION
003538  # define PACKAGE_VERSION SQLITE_VERSION
003539  #endif
003540  
003541  /*
003542  ** Initialize this module.
003543  **
003544  ** This Tcl module contains only a single new Tcl command named "sqlite".
003545  ** (Hence there is no namespace.  There is no point in using a namespace
003546  ** if the extension only supplies one new name!)  The "sqlite" command is
003547  ** used to open a new SQLite database.  See the DbMain() routine above
003548  ** for additional information.
003549  **
003550  ** The EXTERN macros are required by TCL in order to work on windows.
003551  */
003552  EXTERN int Sqlite3_Init(Tcl_Interp *interp){
003553    int rc = Tcl_InitStubs(interp, "8.4", 0) ? TCL_OK : TCL_ERROR;
003554    if( rc==TCL_OK ){
003555      Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
003556  #ifndef SQLITE_3_SUFFIX_ONLY
003557      /* The "sqlite" alias is undocumented.  It is here only to support
003558      ** legacy scripts.  All new scripts should use only the "sqlite3"
003559      ** command. */
003560      Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
003561  #endif
003562      rc = Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION);
003563    }
003564    return rc;
003565  }
003566  EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
003567  EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
003568  EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
003569  
003570  /* Because it accesses the file-system and uses persistent state, SQLite
003571  ** is not considered appropriate for safe interpreters.  Hence, we cause
003572  ** the _SafeInit() interfaces return TCL_ERROR.
003573  */
003574  EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_ERROR; }
003575  EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){return TCL_ERROR;}
003576  
003577  
003578  
003579  #ifndef SQLITE_3_SUFFIX_ONLY
003580  int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
003581  int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
003582  int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
003583  int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
003584  #endif
003585  
003586  /*
003587  ** If the TCLSH macro is defined, add code to make a stand-alone program.
003588  */
003589  #if defined(TCLSH)
003590  
003591  /* This is the main routine for an ordinary TCL shell.  If there are
003592  ** are arguments, run the first argument as a script.  Otherwise,
003593  ** read TCL commands from standard input
003594  */
003595  static const char *tclsh_main_loop(void){
003596    static const char zMainloop[] =
003597      "if {[llength $argv]>=1} {\n"
003598        "set argv0 [lindex $argv 0]\n"
003599        "set argv [lrange $argv 1 end]\n"
003600        "source $argv0\n"
003601      "} else {\n"
003602        "set line {}\n"
003603        "while {![eof stdin]} {\n"
003604          "if {$line!=\"\"} {\n"
003605            "puts -nonewline \"> \"\n"
003606          "} else {\n"
003607            "puts -nonewline \"% \"\n"
003608          "}\n"
003609          "flush stdout\n"
003610          "append line [gets stdin]\n"
003611          "if {[info complete $line]} {\n"
003612            "if {[catch {uplevel #0 $line} result]} {\n"
003613              "puts stderr \"Error: $result\"\n"
003614            "} elseif {$result!=\"\"} {\n"
003615              "puts $result\n"
003616            "}\n"
003617            "set line {}\n"
003618          "} else {\n"
003619            "append line \\n\n"
003620          "}\n"
003621        "}\n"
003622      "}\n"
003623    ;
003624    return zMainloop;
003625  }
003626  
003627  #define TCLSH_MAIN main   /* Needed to fake out mktclapp */
003628  int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){
003629    Tcl_Interp *interp;
003630    int i;
003631    const char *zScript = 0;
003632    char zArgc[32];
003633  #if defined(TCLSH_INIT_PROC)
003634    extern const char *TCLSH_INIT_PROC(Tcl_Interp*);
003635  #endif
003636  
003637  #if !defined(_WIN32_WCE)
003638    if( getenv("BREAK") ){
003639      fprintf(stderr,
003640          "attach debugger to process %d and press any key to continue.\n",
003641          GETPID());
003642      fgetc(stdin);
003643    }
003644  #endif
003645  
003646    /* Call sqlite3_shutdown() once before doing anything else. This is to
003647    ** test that sqlite3_shutdown() can be safely called by a process before
003648    ** sqlite3_initialize() is. */
003649    sqlite3_shutdown();
003650  
003651    Tcl_FindExecutable(argv[0]);
003652    Tcl_SetSystemEncoding(NULL, "utf-8");
003653    interp = Tcl_CreateInterp();
003654    Sqlite3_Init(interp);
003655  
003656    sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-1);
003657    Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
003658    Tcl_SetVar(interp,"argv0",argv[0],TCL_GLOBAL_ONLY);
003659    Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
003660    for(i=1; i<argc; i++){
003661      Tcl_SetVar(interp, "argv", argv[i],
003662          TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
003663    }
003664  #if defined(TCLSH_INIT_PROC)
003665    zScript = TCLSH_INIT_PROC(interp);
003666  #endif
003667    if( zScript==0 ){
003668      zScript = tclsh_main_loop();
003669    }
003670    if( Tcl_GlobalEval(interp, zScript)!=TCL_OK ){
003671      const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
003672      if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp);
003673      fprintf(stderr,"%s: %s\n", *argv, zInfo);
003674      return 1;
003675    }
003676    return 0;
003677  }
003678  #endif /* TCLSH */