Changes On Branch tclRdOnly
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch tclRdOnly Excluding Merge-Ins

This is equivalent to a diff from 1fdeece215 to a6647539f6

2013-01-07
18:58
Improved error message handling. Fix the "fossil server" command so that it works when run as root on a repository in the root directory. check-in: baa1ebb7d9 user: drh tags: trunk
17:33
Merge updates from trunk. Leaf check-in: a6647539f6 user: mistachkin tags: tclRdOnly
17:21
Merge updates from trunk. Leaf check-in: 4f365f7b77 user: mistachkin tags: th1Hooks
17:18
Re-sync custom MinGW makefile. check-in: 1fdeece215 user: mistachkin tags: trunk
15:03
Fix "fossil revert" so that it works on files that have been renamed. check-in: 48798b2719 user: drh tags: trunk
2012-12-08
06:46
Merge updates from trunk. check-in: fc7e8d01d4 user: mistachkin tags: tclRdOnly

Changes to Makefile.in.

    40     40   
    41     41   LIB =	@LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@
    42     42   TCC +=	@EXTRA_CFLAGS@ @CPPFLAGS@ @CFLAGS@ -DHAVE_AUTOCONFIG_H
    43     43   INSTALLDIR = $(DESTDIR)@prefix@/bin
    44     44   USE_SYSTEM_SQLITE = @USE_SYSTEM_SQLITE@
    45     45   FOSSIL_ENABLE_TCL = @FOSSIL_ENABLE_TCL@
    46     46   FOSSIL_ENABLE_TCL_STUBS = @FOSSIL_ENABLE_TCL_STUBS@
           47  +FOSSIL_ENABLE_TCL_SQLITE = @FOSSIL_ENABLE_TCL_SQLITE@
    47     48   
    48     49   include $(SRCDIR)/main.mk
    49     50   
    50     51   distclean: clean
    51     52   	rm -f autoconfig.h config.log Makefile

Changes to auto.def.

     4      4   
     5      5   options {
     6      6       with-openssl:path|auto|none
     7      7                            => {Look for openssl in the given path, or auto or none}
     8      8       with-zlib:path       => {Look for zlib in the given path}
     9      9       with-tcl:path        => {Enable Tcl integration, with Tcl in the specified path}
    10     10       with-tcl-stubs=0     => {Enable Tcl integration via stubs mechanism}
           11  +    with-tcl-sqlite=0    => {Provide the SQLite package to Tcl}
    11     12       internal-sqlite=1    => {Don't use the internal sqlite, use the system one}
    12     13       static=0             => {Link a static executable}
    13     14       lineedit=1           => {Disable line editing}
    14     15       fossil-debug=0       => {Build with fossil debugging enabled}
    15     16       json=0               => {Build with fossil JSON API enabled}
    16     17       markdown=0           => {Build with markdown engine enabled}
    17     18   }
................................................................................
   128    129                   user-error "Cannot find a usable Tcl stubs library $msg"
   129    130               }
   130    131           } else {
   131    132               if {![cc-check-functions Tcl_CreateInterp]} {
   132    133                   user-error "Cannot find a usable Tcl library $msg"
   133    134               }
   134    135           }
          136  +    }
          137  +    if {[opt-bool with-tcl-sqlite]} {
          138  +      define FOSSIL_ENABLE_TCL_SQLITE
   135    139       }
   136    140       set version $tclconfig(TCL_VERSION)$tclconfig(TCL_PATCH_LEVEL)
   137    141       msg-result "Found Tcl $version at $tclconfig(TCL_PREFIX)"
   138    142       define-append LIBS $libs
   139    143       define-append EXTRA_CFLAGS $cflags
   140    144       define-append EXTRA_LDFLAGS $tclconfig(TCL_LD_FLAGS)
   141    145       define FOSSIL_ENABLE_TCL

Changes to src/configure.c.

    92     92     { "adunit",                 CONFIGSET_SKIN },
    93     93     { "adunit-omit-if-admin",   CONFIGSET_SKIN },
    94     94     { "adunit-omit-if-user",    CONFIGSET_SKIN },
    95     95     { "th1-setup",              CONFIGSET_ALL },
    96     96   
    97     97   #ifdef FOSSIL_ENABLE_TCL
    98     98     { "tcl",                    CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
           99  +  { "tcl-rdonly",             CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
    99    100     { "tcl-setup",              CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },
   100    101   #endif
   101    102   
   102    103     { "project-name",           CONFIGSET_PROJ },
   103    104     { "project-description",    CONFIGSET_PROJ },
   104    105     { "manifest",               CONFIGSET_PROJ },
   105    106     { "binary-glob",            CONFIGSET_PROJ },

Changes to src/db.c.

  2089   2089     { "self-register", 0,                0, 0, "off"                 },
  2090   2090     { "ssl-ca-location",0,              40, 0, ""                    },
  2091   2091     { "ssl-identity",  0,               40, 0, ""                    },
  2092   2092     { "ssh-command",   0,               40, 0, ""                    },
  2093   2093     { "th1-setup",     0,               40, 0, ""                    },
  2094   2094   #ifdef FOSSIL_ENABLE_TCL
  2095   2095     { "tcl",           0,                0, 0, "off"                 },
         2096  +  { "tcl-rdonly",    0,                0, 0, "on"                  },
  2096   2097     { "tcl-setup",     0,               40, 0, ""                    },
  2097   2098   #endif
  2098   2099     { "unicode-glob",  0,               40, 1, ""                    },
  2099   2100     { "web-browser",   0,               32, 0, ""                    },
  2100   2101     { "white-foreground", 0,             0, 0, "off"                 },
  2101   2102     { 0,0,0,0,0 }
  2102   2103   };
................................................................................
  2269   2270   **
  2270   2271   **    tcl              If enabled (and Fossil was compiled with Tcl support),
  2271   2272   **                     Tcl integration commands will be added to the TH1
  2272   2273   **                     interpreter, allowing arbitrary Tcl expressions and
  2273   2274   **                     scripts to be evaluated from TH1.  Additionally, the Tcl
  2274   2275   **                     interpreter will be able to evaluate arbitrary TH1
  2275   2276   **                     expressions and scripts. Default: off.
         2277  +**
         2278  +**    tcl-rdonly       If enabled (and Fossil was compiled with support for the
         2279  +**                     SQLite package for Tcl), Tcl scripts using the SQLite
         2280  +**                     package in the Fossil process will not be able to write
         2281  +**                     to any of the databases used by the repository.  This
         2282  +**                     feature is designed to provide some protection against
         2283  +**                     accidentally writing to a repository database; however,
         2284  +**                     it is not a security feature and does not guarantee that
         2285  +**                     writing to a repository database will be impossible if
         2286  +**                     somebody is determined to do so.
         2287  +**                     Default: on.
  2276   2288   **
  2277   2289   **    tcl-setup        This is the setup script to be evaluated after creating
  2278   2290   **                     and initializing the Tcl interpreter.  By default, this
  2279   2291   **                     is empty and no extra setup is performed.
  2280   2292   **
  2281   2293   **    th1-setup        This is the setup script to be evaluated after creating
  2282   2294   **                     and initializing the TH1 interpreter.  By default, this

Changes to src/makemake.tcl.

   391    391   #### Enable scripting support via Tcl/Tk
   392    392   #
   393    393   # FOSSIL_ENABLE_TCL = 1
   394    394   
   395    395   #### Load Tcl using the stubs mechanism
   396    396   #
   397    397   # FOSSIL_ENABLE_TCL_STUBS = 1
          398  +
          399  +#### Provide the SQLite package to Tcl
          400  +#
          401  +# FOSSIL_ENABLE_TCL_SQLITE = 1
   398    402   
   399    403   #### Use the Tcl source directory instead of the install directory?
   400    404   #    This is useful when Tcl has been compiled statically with MinGW.
   401    405   #
   402    406   FOSSIL_TCL_SOURCE = 1
   403    407   
   404    408   #### Check if the workaround for the MinGW command line handling needs to
................................................................................
   513    517   ifdef FOSSIL_ENABLE_TCL_STUBS
   514    518   TCC += -DFOSSIL_ENABLE_TCL_STUBS=1 -DUSE_TCL_STUBS
   515    519   RCC += -DFOSSIL_ENABLE_TCL_STUBS=1 -DUSE_TCL_STUBS
   516    520   else
   517    521   TCC += -DSTATIC_BUILD
   518    522   RCC += -DSTATIC_BUILD
   519    523   endif
          524  +# Provide the SQLite package to Tcl
          525  +ifdef FOSSIL_ENABLE_TCL_SQLITE
          526  +TCC += -DFOSSIL_ENABLE_TCL_SQLITE=1 -DBUILD_sqlite=1
          527  +RCC += -DFOSSIL_ENABLE_TCL_SQLITE=1 -DBUILD_sqlite=1
          528  +endif
   520    529   endif
   521    530   
   522    531   # With JSON support
   523    532   ifdef FOSSIL_ENABLE_JSON
   524    533   TCC += -DFOSSIL_ENABLE_JSON=1
   525    534   RCC += -DFOSSIL_ENABLE_JSON=1
   526    535   endif

Changes to src/sqlite3.c.

   671    671   **
   672    672   ** See also: [sqlite3_libversion()],
   673    673   ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
   674    674   ** [sqlite_version()] and [sqlite_source_id()].
   675    675   */
   676    676   #define SQLITE_VERSION        "3.7.16"
   677    677   #define SQLITE_VERSION_NUMBER 3007016
   678         -#define SQLITE_SOURCE_ID      "2013-01-07 13:26:23 0a1207c895d9f77586a3a2a4965175909be90503"
          678  +#define SQLITE_SOURCE_ID      "2012-12-08 06:46:05 e65db42c9fdc1d6f257c8db54a46ee4fc0d7aaf0"
   679    679   
   680    680   /*
   681    681   ** CAPI3REF: Run-Time Library Version Numbers
   682    682   ** KEYWORDS: sqlite3_version, sqlite3_sourceid
   683    683   **
   684    684   ** These interfaces provide the same information as the [SQLITE_VERSION],
   685    685   ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
................................................................................
  1813   1813   SQLITE_API int sqlite3_shutdown(void);
  1814   1814   SQLITE_API int sqlite3_os_init(void);
  1815   1815   SQLITE_API int sqlite3_os_end(void);
  1816   1816   
  1817   1817   /*
  1818   1818   ** CAPI3REF: Configuring The SQLite Library
  1819   1819   **
  1820         -** The sqlite3_config() interface is used to make global configuration
  1821         -** changes to SQLite in order to tune SQLite to the specific needs of
  1822         -** the application.  The default configuration is recommended for most
  1823         -** applications and so this routine is usually not necessary.  It is
  1824         -** provided to support rare applications with unusual needs.
         1820  +** The sqlite3_config() and sqlite3_reconfig() interfaces are used to make
         1821  +** global configuration changes to SQLite in order to tune SQLite to the
         1822  +** specific needs of the application.  The default configuration is recommended
         1823  +** for most applications and so this routine is usually not necessary.  They
         1824  +** are provided to support rare applications with unusual needs.
  1825   1825   **
  1826   1826   ** The sqlite3_config() interface is not threadsafe.  The application
  1827   1827   ** must insure that no other SQLite interfaces are invoked by other
  1828   1828   ** threads while sqlite3_config() is running.  Furthermore, sqlite3_config()
  1829   1829   ** may only be invoked prior to library initialization using
  1830   1830   ** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
  1831   1831   ** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
  1832   1832   ** [sqlite3_shutdown()] then it will return SQLITE_MISUSE.
  1833   1833   ** Note, however, that ^sqlite3_config() can be called as part of the
  1834   1834   ** implementation of an application-defined [sqlite3_os_init()].
  1835   1835   **
  1836         -** The first argument to sqlite3_config() is an integer
  1837         -** [configuration option] that determines
         1836  +** The sqlite3_reconfig() interface is threadsafe and may be called at any
         1837  +** time.  However, it supports only a small subset of the configuration
         1838  +** options available for use with sqlite3_config().
         1839  +**
         1840  +** The first argument to both sqlite3_config() and sqlite3_reconfig() is an
         1841  +** integer [configuration option] that determines
  1838   1842   ** what property of SQLite is to be configured.  Subsequent arguments
  1839   1843   ** vary depending on the [configuration option]
  1840   1844   ** in the first argument.
  1841   1845   **
  1842         -** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
         1846  +** ^When a configuration option is set, both sqlite3_config() and
         1847  +** sqlite3_reconfig() return [SQLITE_OK].
  1843   1848   ** ^If the option is unknown or SQLite is unable to set the option
  1844         -** then this routine returns a non-zero [error code].
         1849  +** then these routines returns a non-zero [error code].
  1845   1850   */
  1846   1851   SQLITE_API int sqlite3_config(int, ...);
         1852  +SQLITE_API int sqlite3_reconfig(int, ...);
  1847   1853   
  1848   1854   /*
  1849   1855   ** CAPI3REF: Configure database connections
  1850   1856   **
  1851   1857   ** The sqlite3_db_config() interface is used to make configuration
  1852   1858   ** changes to a [database connection].  The interface is similar to
  1853   1859   ** [sqlite3_config()] except that the changes apply to a single
................................................................................
  2164   2170   ** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
  2165   2171   ** if that compile-time option is omitted.
  2166   2172   ** The ability to disable the use of covering indices for full table scans
  2167   2173   ** is because some incorrectly coded legacy applications might malfunction
  2168   2174   ** malfunction when the optimization is enabled.  Providing the ability to
  2169   2175   ** disable the optimization allows the older, buggy application code to work
  2170   2176   ** without change even with newer versions of SQLite.
         2177  +**
         2178  +** [[SQLITE_CONFIG_READONLY]] <dt>SQLITE_CONFIG_READONLY
         2179  +** <dd> This option takes a single argument of type int. If non-zero, then
         2180  +** read-only mode for opening databases is globally enabled. If the parameter
         2181  +** is zero, then read-only mode for opening databases is globally disabled. If
         2182  +** read-only mode for opening databases is globally enabled, all databases
         2183  +** opened by [sqlite3_open()], [sqlite3_open16()], or specified as part of
         2184  +** [ATTACH] commands will be opened in read-only mode. Additionally, all calls
         2185  +** to [sqlite3_open_v2()] must have the [SQLITE_OPEN_READONLY] flag set in the
         2186  +** third argument; otherwise, a [SQLITE_READONLY] error will be returned. If it
         2187  +** is globally disabled, [sqlite3_open()], [sqlite3_open16()],
         2188  +** [sqlite3_open_v2()], and [ATTACH] commands will function normally. By
         2189  +** default, read-only mode is globally disabled.
  2171   2190   **
  2172   2191   ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
  2173   2192   ** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
  2174   2193   ** <dd> These options are obsolete and should not be used by new code.
  2175   2194   ** They are retained for backwards compatibility but are now no-ops.
  2176   2195   ** </dl>
  2177   2196   **
................................................................................
  2208   2227   #define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
  2209   2228   #define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
  2210   2229   #define SQLITE_CONFIG_URI          17  /* int */
  2211   2230   #define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
  2212   2231   #define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
  2213   2232   #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
  2214   2233   #define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
         2234  +#define SQLITE_CONFIG_READONLY     22  /* int */
  2215   2235   
  2216   2236   /*
  2217   2237   ** CAPI3REF: Database Connection Configuration Options
  2218   2238   **
  2219   2239   ** These constants are the available integer configuration options that
  2220   2240   ** can be passed as the second argument to the [sqlite3_db_config()] interface.
  2221   2241   **
................................................................................
 11551  11571   */
 11552  11572   struct Sqlite3Config {
 11553  11573     int bMemstat;                     /* True to enable memory status */
 11554  11574     int bCoreMutex;                   /* True to enable core mutexing */
 11555  11575     int bFullMutex;                   /* True to enable full mutexing */
 11556  11576     int bOpenUri;                     /* True to interpret filenames as URIs */
 11557  11577     int bUseCis;                      /* Use covering indices for full-scans */
        11578  +  int bReadOnly;                    /* True to force read-only mode */
 11558  11579     int mxStrlen;                     /* Maximum string length */
 11559  11580     int szLookaside;                  /* Default lookaside buffer size */
 11560  11581     int nLookaside;                   /* Default lookaside buffer count */
 11561  11582     sqlite3_mem_methods m;            /* Low-level memory allocation interface */
 11562  11583     sqlite3_mutex_methods mutex;      /* Low-level mutex interface */
 11563  11584     sqlite3_pcache_methods2 pcache2;  /* Low-level page-cache interface */
 11564  11585     void *pHeap;                      /* Heap storage space */
................................................................................
 12568  12589   */
 12569  12590   SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
 12570  12591      SQLITE_DEFAULT_MEMSTATUS,  /* bMemstat */
 12571  12592      1,                         /* bCoreMutex */
 12572  12593      SQLITE_THREADSAFE==1,      /* bFullMutex */
 12573  12594      SQLITE_USE_URI,            /* bOpenUri */
 12574  12595      SQLITE_ALLOW_COVERING_INDEX_SCAN,   /* bUseCis */
        12596  +   0,                         /* bReadOnly */
 12575  12597      0x7ffffffe,                /* mxStrlen */
 12576  12598      128,                       /* szLookaside */
 12577  12599      500,                       /* nLookaside */
 12578  12600      {0,0,0,0,0,0,0,0},         /* m */
 12579  12601      {0,0,0,0,0,0,0,0,0},       /* mutex */
 12580  12602      {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */
 12581  12603      (void*)0,                  /* pHeap */
................................................................................
113426 113448       case SQLITE_CONFIG_SQLLOG: {
113427 113449         typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int);
113428 113450         sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t);
113429 113451         sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *);
113430 113452         break;
113431 113453       }
113432 113454   #endif
       113455  +
       113456  +    case SQLITE_CONFIG_READONLY: {
       113457  +      sqlite3GlobalConfig.bReadOnly = va_arg(ap, int);
       113458  +      break;
       113459  +    }
       113460  +
       113461  +    default: {
       113462  +      rc = SQLITE_ERROR;
       113463  +      break;
       113464  +    }
       113465  +  }
       113466  +  va_end(ap);
       113467  +  return rc;
       113468  +}
       113469  +
       113470  +/*
       113471  +** This API allows applications to modify the global configuration of
       113472  +** the SQLite library at run-time.
       113473  +**
       113474  +** This routine differs from sqlite3_config() in that it may be called when
       113475  +** there are outstanding database connections and/or memory allocations.
       113476  +** This routine is threadsafe.
       113477  +*/
       113478  +SQLITE_API int sqlite3_reconfig(int op, ...){
       113479  +  va_list ap;
       113480  +  int rc = SQLITE_OK;
       113481  +
       113482  +  va_start(ap, op);
       113483  +  switch( op ){
       113484  +    case SQLITE_CONFIG_READONLY: {
       113485  +      /*
       113486  +      ** On platforms where assignment of an integer value is atomic, there
       113487  +      ** is no need for a mutex here.  On other platforms, there could be a
       113488  +      ** subtle race condition here; however, the effect would simply be that
       113489  +      ** a call to open a database would fail with SQLITE_READONLY.
       113490  +      */
       113491  +      sqlite3GlobalConfig.bReadOnly = va_arg(ap, int);
       113492  +      break;
       113493  +    }
113433 113494   
113434 113495       default: {
113435 113496         rc = SQLITE_ERROR;
113436 113497         break;
113437 113498       }
113438 113499     }
113439 113500     va_end(ap);
................................................................................
115156 115217   ** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"  
115157 115218   ** is UTF-8 encoded.
115158 115219   */
115159 115220   static int openDatabase(
115160 115221     const char *zFilename, /* Database filename UTF-8 encoded */
115161 115222     sqlite3 **ppDb,        /* OUT: Returned database handle */
115162 115223     unsigned int flags,    /* Operational flags */
115163         -  const char *zVfs       /* Name of the VFS to use */
       115224  +  const char *zVfs,      /* Name of the VFS to use */
       115225  +  int defaultFlags       /* Zero if opening via sqlite3_open_v2 */
115164 115226   ){
115165 115227     sqlite3 *db;                    /* Store allocated handle here */
115166 115228     int rc;                         /* Return code */
115167 115229     int isThreadsafe;               /* True for threadsafe connections */
115168 115230     char *zOpen = 0;                /* Filename argument to pass to BtreeOpen() */
115169 115231     char *zErrMsg = 0;              /* Error message from sqlite3ParseUri() */
115170 115232   
................................................................................
115225 115287                  SQLITE_OPEN_TEMP_JOURNAL | 
115226 115288                  SQLITE_OPEN_SUBJOURNAL | 
115227 115289                  SQLITE_OPEN_MASTER_JOURNAL |
115228 115290                  SQLITE_OPEN_NOMUTEX |
115229 115291                  SQLITE_OPEN_FULLMUTEX |
115230 115292                  SQLITE_OPEN_WAL
115231 115293                );
       115294  +
       115295  +  /* Check for global read-only mode */
       115296  +  if( sqlite3GlobalConfig.bReadOnly ){
       115297  +    if( defaultFlags ){
       115298  +      flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
       115299  +      flags |= SQLITE_OPEN_READONLY;
       115300  +    }else if( flags & SQLITE_OPEN_READWRITE ){
       115301  +      return SQLITE_READONLY;
       115302  +    }
       115303  +  }
115232 115304   
115233 115305     /* Allocate the sqlite data structure */
115234 115306     db = sqlite3MallocZero( sizeof(sqlite3) );
115235 115307     if( db==0 ) goto opendb_out;
115236 115308     if( isThreadsafe ){
115237 115309       db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
115238 115310       if( db->mutex==0 ){
................................................................................
115423 115495   ** Open a new database handle.
115424 115496   */
115425 115497   SQLITE_API int sqlite3_open(
115426 115498     const char *zFilename, 
115427 115499     sqlite3 **ppDb 
115428 115500   ){
115429 115501     return openDatabase(zFilename, ppDb,
115430         -                      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
       115502  +                      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0, 1);
115431 115503   }
115432 115504   SQLITE_API int sqlite3_open_v2(
115433 115505     const char *filename,   /* Database filename (UTF-8) */
115434 115506     sqlite3 **ppDb,         /* OUT: SQLite db handle */
115435 115507     int flags,              /* Flags */
115436 115508     const char *zVfs        /* Name of VFS module to use */
115437 115509   ){
115438         -  return openDatabase(filename, ppDb, (unsigned int)flags, zVfs);
       115510  +  return openDatabase(filename, ppDb, (unsigned int)flags, zVfs, 0);
115439 115511   }
115440 115512   
115441 115513   #ifndef SQLITE_OMIT_UTF16
115442 115514   /*
115443 115515   ** Open a new database handle.
115444 115516   */
115445 115517   SQLITE_API int sqlite3_open16(
................................................................................
115458 115530     if( rc ) return rc;
115459 115531   #endif
115460 115532     pVal = sqlite3ValueNew(0);
115461 115533     sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
115462 115534     zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
115463 115535     if( zFilename8 ){
115464 115536       rc = openDatabase(zFilename8, ppDb,
115465         -                      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
       115537  +                      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0, 1);
115466 115538       assert( *ppDb || rc==SQLITE_NOMEM );
115467 115539       if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){
115468 115540         ENC(*ppDb) = SQLITE_UTF16NATIVE;
115469 115541       }
115470 115542     }else{
115471 115543       rc = SQLITE_NOMEM;
115472 115544     }
................................................................................
137717 137789     *ppModule = &icuTokenizerModule;
137718 137790   }
137719 137791   
137720 137792   #endif /* defined(SQLITE_ENABLE_ICU) */
137721 137793   #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
137722 137794   
137723 137795   /************** End of fts3_icu.c ********************************************/
       137796  +/*
       137797  +** 2001 September 15
       137798  +**
       137799  +** The author disclaims copyright to this source code.  In place of
       137800  +** a legal notice, here is a blessing:
       137801  +**
       137802  +**    May you do good and not evil.
       137803  +**    May you find forgiveness for yourself and forgive others.
       137804  +**    May you share freely, never taking more than you give.
       137805  +**
       137806  +*************************************************************************
       137807  +** A TCL Interface to SQLite.  Append this file to sqlite3.c and
       137808  +** compile the whole thing to build a TCL-enabled version of SQLite.
       137809  +**
       137810  +** Compile-time options:
       137811  +**
       137812  +**  -DTCLSH=1             Add a "main()" routine that works as a tclsh.
       137813  +**
       137814  +**  -DSQLITE_TCLMD5       When used in conjuction with -DTCLSH=1, add
       137815  +**                        four new commands to the TCL interpreter for
       137816  +**                        generating MD5 checksums:  md5, md5file,
       137817  +**                        md5-10x8, and md5file-10x8.
       137818  +**
       137819  +**  -DSQLITE_TEST         When used in conjuction with -DTCLSH=1, add
       137820  +**                        hundreds of new commands used for testing
       137821  +**                        SQLite.  This option implies -DSQLITE_TCLMD5.
       137822  +*/
       137823  +#include "tcl.h"
       137824  +#include <errno.h>
       137825  +
       137826  +/*
       137827  +** Some additional include files are needed if this file is not
       137828  +** appended to the amalgamation.
       137829  +*/
       137830  +#ifndef SQLITE_AMALGAMATION
       137831  +# include "sqlite3.h"
       137832  +# include <stdlib.h>
       137833  +# include <string.h>
       137834  +# include <assert.h>
       137835  +  typedef unsigned char u8;
       137836  +#endif
       137837  +#include <ctype.h>
       137838  +
       137839  +/*
       137840  + * Windows needs to know which symbols to export.  Unix does not.
       137841  + * BUILD_sqlite should be undefined for Unix.
       137842  + */
       137843  +#ifdef BUILD_sqlite
       137844  +#undef TCL_STORAGE_CLASS
       137845  +#define TCL_STORAGE_CLASS DLLEXPORT
       137846  +#endif /* BUILD_sqlite */
       137847  +
       137848  +#define NUM_PREPARED_STMTS 10
       137849  +#define MAX_PREPARED_STMTS 100
       137850  +
       137851  +/* Forward declaration */
       137852  +typedef struct SqliteDb SqliteDb;
       137853  +
       137854  +/*
       137855  +** New SQL functions can be created as TCL scripts.  Each such function
       137856  +** is described by an instance of the following structure.
       137857  +*/
       137858  +typedef struct SqlFunc SqlFunc;
       137859  +struct SqlFunc {
       137860  +  Tcl_Interp *interp;   /* The TCL interpret to execute the function */
       137861  +  Tcl_Obj *pScript;     /* The Tcl_Obj representation of the script */
       137862  +  SqliteDb *pDb;        /* Database connection that owns this function */
       137863  +  int useEvalObjv;      /* True if it is safe to use Tcl_EvalObjv */
       137864  +  char *zName;          /* Name of this function */
       137865  +  SqlFunc *pNext;       /* Next function on the list of them all */
       137866  +};
       137867  +
       137868  +/*
       137869  +** New collation sequences function can be created as TCL scripts.  Each such
       137870  +** function is described by an instance of the following structure.
       137871  +*/
       137872  +typedef struct SqlCollate SqlCollate;
       137873  +struct SqlCollate {
       137874  +  Tcl_Interp *interp;   /* The TCL interpret to execute the function */
       137875  +  char *zScript;        /* The script to be run */
       137876  +  SqlCollate *pNext;    /* Next function on the list of them all */
       137877  +};
       137878  +
       137879  +/*
       137880  +** Prepared statements are cached for faster execution.  Each prepared
       137881  +** statement is described by an instance of the following structure.
       137882  +*/
       137883  +typedef struct SqlPreparedStmt SqlPreparedStmt;
       137884  +struct SqlPreparedStmt {
       137885  +  SqlPreparedStmt *pNext;  /* Next in linked list */
       137886  +  SqlPreparedStmt *pPrev;  /* Previous on the list */
       137887  +  sqlite3_stmt *pStmt;     /* The prepared statement */
       137888  +  int nSql;                /* chars in zSql[] */
       137889  +  const char *zSql;        /* Text of the SQL statement */
       137890  +  int nParm;               /* Size of apParm array */
       137891  +  Tcl_Obj **apParm;        /* Array of referenced object pointers */
       137892  +};
       137893  +
       137894  +typedef struct IncrblobChannel IncrblobChannel;
       137895  +
       137896  +/*
       137897  +** There is one instance of this structure for each SQLite database
       137898  +** that has been opened by the SQLite TCL interface.
       137899  +**
       137900  +** If this module is built with SQLITE_TEST defined (to create the SQLite
       137901  +** testfixture executable), then it may be configured to use either
       137902  +** sqlite3_prepare_v2() or sqlite3_prepare() to prepare SQL statements.
       137903  +** If SqliteDb.bLegacyPrepare is true, sqlite3_prepare() is used.
       137904  +*/
       137905  +struct SqliteDb {
       137906  +  sqlite3 *db;               /* The "real" database structure. MUST BE FIRST */
       137907  +  Tcl_Interp *interp;        /* The interpreter used for this database */
       137908  +  char *zBusy;               /* The busy callback routine */
       137909  +  char *zCommit;             /* The commit hook callback routine */
       137910  +  char *zTrace;              /* The trace callback routine */
       137911  +  char *zProfile;            /* The profile callback routine */
       137912  +  char *zProgress;           /* The progress callback routine */
       137913  +  char *zAuth;               /* The authorization callback routine */
       137914  +  int disableAuth;           /* Disable the authorizer if it exists */
       137915  +  char *zNull;               /* Text to substitute for an SQL NULL value */
       137916  +  SqlFunc *pFunc;            /* List of SQL functions */
       137917  +  Tcl_Obj *pUpdateHook;      /* Update hook script (if any) */
       137918  +  Tcl_Obj *pRollbackHook;    /* Rollback hook script (if any) */
       137919  +  Tcl_Obj *pWalHook;         /* WAL hook script (if any) */
       137920  +  Tcl_Obj *pUnlockNotify;    /* Unlock notify script (if any) */
       137921  +  SqlCollate *pCollate;      /* List of SQL collation functions */
       137922  +  int rc;                    /* Return code of most recent sqlite3_exec() */
       137923  +  Tcl_Obj *pCollateNeeded;   /* Collation needed script */
       137924  +  SqlPreparedStmt *stmtList; /* List of prepared statements*/
       137925  +  SqlPreparedStmt *stmtLast; /* Last statement in the list */
       137926  +  int maxStmt;               /* The next maximum number of stmtList */
       137927  +  int nStmt;                 /* Number of statements in stmtList */
       137928  +  IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
       137929  +  int nStep, nSort, nIndex;  /* Statistics for most recent operation */
       137930  +  int nTransaction;          /* Number of nested [transaction] methods */
       137931  +#ifdef SQLITE_TEST
       137932  +  int bLegacyPrepare;        /* True to use sqlite3_prepare() */
       137933  +#endif
       137934  +};
       137935  +
       137936  +struct IncrblobChannel {
       137937  +  sqlite3_blob *pBlob;      /* sqlite3 blob handle */
       137938  +  SqliteDb *pDb;            /* Associated database connection */
       137939  +  int iSeek;                /* Current seek offset */
       137940  +  Tcl_Channel channel;      /* Channel identifier */
       137941  +  IncrblobChannel *pNext;   /* Linked list of all open incrblob channels */
       137942  +  IncrblobChannel *pPrev;   /* Linked list of all open incrblob channels */
       137943  +};
       137944  +
       137945  +/*
       137946  +** Compute a string length that is limited to what can be stored in
       137947  +** lower 30 bits of a 32-bit signed integer.
       137948  +*/
       137949  +static int strlen30(const char *z){
       137950  +  const char *z2 = z;
       137951  +  while( *z2 ){ z2++; }
       137952  +  return 0x3fffffff & (int)(z2 - z);
       137953  +}
       137954  +
       137955  +
       137956  +#ifndef SQLITE_OMIT_INCRBLOB
       137957  +/*
       137958  +** Close all incrblob channels opened using database connection pDb.
       137959  +** This is called when shutting down the database connection.
       137960  +*/
       137961  +static void closeIncrblobChannels(SqliteDb *pDb){
       137962  +  IncrblobChannel *p;
       137963  +  IncrblobChannel *pNext;
       137964  +
       137965  +  for(p=pDb->pIncrblob; p; p=pNext){
       137966  +    pNext = p->pNext;
       137967  +
       137968  +    /* Note: Calling unregister here call Tcl_Close on the incrblob channel, 
       137969  +    ** which deletes the IncrblobChannel structure at *p. So do not
       137970  +    ** call Tcl_Free() here.
       137971  +    */
       137972  +    Tcl_UnregisterChannel(pDb->interp, p->channel);
       137973  +  }
       137974  +}
       137975  +
       137976  +/*
       137977  +** Close an incremental blob channel.
       137978  +*/
       137979  +static int incrblobClose(ClientData instanceData, Tcl_Interp *interp){
       137980  +  IncrblobChannel *p = (IncrblobChannel *)instanceData;
       137981  +  int rc = sqlite3_blob_close(p->pBlob);
       137982  +  sqlite3 *db = p->pDb->db;
       137983  +
       137984  +  /* Remove the channel from the SqliteDb.pIncrblob list. */
       137985  +  if( p->pNext ){
       137986  +    p->pNext->pPrev = p->pPrev;
       137987  +  }
       137988  +  if( p->pPrev ){
       137989  +    p->pPrev->pNext = p->pNext;
       137990  +  }
       137991  +  if( p->pDb->pIncrblob==p ){
       137992  +    p->pDb->pIncrblob = p->pNext;
       137993  +  }
       137994  +
       137995  +  /* Free the IncrblobChannel structure */
       137996  +  Tcl_Free((char *)p);
       137997  +
       137998  +  if( rc!=SQLITE_OK ){
       137999  +    Tcl_SetResult(interp, (char *)sqlite3_errmsg(db), TCL_VOLATILE);
       138000  +    return TCL_ERROR;
       138001  +  }
       138002  +  return TCL_OK;
       138003  +}
       138004  +
       138005  +/*
       138006  +** Read data from an incremental blob channel.
       138007  +*/
       138008  +static int incrblobInput(
       138009  +  ClientData instanceData, 
       138010  +  char *buf, 
       138011  +  int bufSize,
       138012  +  int *errorCodePtr
       138013  +){
       138014  +  IncrblobChannel *p = (IncrblobChannel *)instanceData;
       138015  +  int nRead = bufSize;         /* Number of bytes to read */
       138016  +  int nBlob;                   /* Total size of the blob */
       138017  +  int rc;                      /* sqlite error code */
       138018  +
       138019  +  nBlob = sqlite3_blob_bytes(p->pBlob);
       138020  +  if( (p->iSeek+nRead)>nBlob ){
       138021  +    nRead = nBlob-p->iSeek;
       138022  +  }
       138023  +  if( nRead<=0 ){
       138024  +    return 0;
       138025  +  }
       138026  +
       138027  +  rc = sqlite3_blob_read(p->pBlob, (void *)buf, nRead, p->iSeek);
       138028  +  if( rc!=SQLITE_OK ){
       138029  +    *errorCodePtr = rc;
       138030  +    return -1;
       138031  +  }
       138032  +
       138033  +  p->iSeek += nRead;
       138034  +  return nRead;
       138035  +}
       138036  +
       138037  +/*
       138038  +** Write data to an incremental blob channel.
       138039  +*/
       138040  +static int incrblobOutput(
       138041  +  ClientData instanceData, 
       138042  +  CONST char *buf, 
       138043  +  int toWrite,
       138044  +  int *errorCodePtr
       138045  +){
       138046  +  IncrblobChannel *p = (IncrblobChannel *)instanceData;
       138047  +  int nWrite = toWrite;        /* Number of bytes to write */
       138048  +  int nBlob;                   /* Total size of the blob */
       138049  +  int rc;                      /* sqlite error code */
       138050  +
       138051  +  nBlob = sqlite3_blob_bytes(p->pBlob);
       138052  +  if( (p->iSeek+nWrite)>nBlob ){
       138053  +    *errorCodePtr = EINVAL;
       138054  +    return -1;
       138055  +  }
       138056  +  if( nWrite<=0 ){
       138057  +    return 0;
       138058  +  }
       138059  +
       138060  +  rc = sqlite3_blob_write(p->pBlob, (void *)buf, nWrite, p->iSeek);
       138061  +  if( rc!=SQLITE_OK ){
       138062  +    *errorCodePtr = EIO;
       138063  +    return -1;
       138064  +  }
       138065  +
       138066  +  p->iSeek += nWrite;
       138067  +  return nWrite;
       138068  +}
       138069  +
       138070  +/*
       138071  +** Seek an incremental blob channel.
       138072  +*/
       138073  +static int incrblobSeek(
       138074  +  ClientData instanceData, 
       138075  +  long offset,
       138076  +  int seekMode,
       138077  +  int *errorCodePtr
       138078  +){
       138079  +  IncrblobChannel *p = (IncrblobChannel *)instanceData;
       138080  +
       138081  +  switch( seekMode ){
       138082  +    case SEEK_SET:
       138083  +      p->iSeek = offset;
       138084  +      break;
       138085  +    case SEEK_CUR:
       138086  +      p->iSeek += offset;
       138087  +      break;
       138088  +    case SEEK_END:
       138089  +      p->iSeek = sqlite3_blob_bytes(p->pBlob) + offset;
       138090  +      break;
       138091  +
       138092  +    default: assert(!"Bad seekMode");
       138093  +  }
       138094  +
       138095  +  return p->iSeek;
       138096  +}
       138097  +
       138098  +
       138099  +static void incrblobWatch(ClientData instanceData, int mode){ 
       138100  +  /* NO-OP */ 
       138101  +}
       138102  +static int incrblobHandle(ClientData instanceData, int dir, ClientData *hPtr){
       138103  +  return TCL_ERROR;
       138104  +}
       138105  +
       138106  +static Tcl_ChannelType IncrblobChannelType = {
       138107  +  "incrblob",                        /* typeName                             */
       138108  +  TCL_CHANNEL_VERSION_2,             /* version                              */
       138109  +  incrblobClose,                     /* closeProc                            */
       138110  +  incrblobInput,                     /* inputProc                            */
       138111  +  incrblobOutput,                    /* outputProc                           */
       138112  +  incrblobSeek,                      /* seekProc                             */
       138113  +  0,                                 /* setOptionProc                        */
       138114  +  0,                                 /* getOptionProc                        */
       138115  +  incrblobWatch,                     /* watchProc (this is a no-op)          */
       138116  +  incrblobHandle,                    /* getHandleProc (always returns error) */
       138117  +  0,                                 /* close2Proc                           */
       138118  +  0,                                 /* blockModeProc                        */
       138119  +  0,                                 /* flushProc                            */
       138120  +  0,                                 /* handlerProc                          */
       138121  +  0,                                 /* wideSeekProc                         */
       138122  +};
       138123  +
       138124  +/*
       138125  +** Create a new incrblob channel.
       138126  +*/
       138127  +static int createIncrblobChannel(
       138128  +  Tcl_Interp *interp, 
       138129  +  SqliteDb *pDb, 
       138130  +  const char *zDb,
       138131  +  const char *zTable, 
       138132  +  const char *zColumn, 
       138133  +  sqlite_int64 iRow,
       138134  +  int isReadonly
       138135  +){
       138136  +  IncrblobChannel *p;
       138137  +  sqlite3 *db = pDb->db;
       138138  +  sqlite3_blob *pBlob;
       138139  +  int rc;
       138140  +  int flags = TCL_READABLE|(isReadonly ? 0 : TCL_WRITABLE);
       138141  +
       138142  +  /* This variable is used to name the channels: "incrblob_[incr count]" */
       138143  +  static int count = 0;
       138144  +  char zChannel[64];
       138145  +
       138146  +  rc = sqlite3_blob_open(db, zDb, zTable, zColumn, iRow, !isReadonly, &pBlob);
       138147  +  if( rc!=SQLITE_OK ){
       138148  +    Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
       138149  +    return TCL_ERROR;
       138150  +  }
       138151  +
       138152  +  p = (IncrblobChannel *)Tcl_Alloc(sizeof(IncrblobChannel));
       138153  +  p->iSeek = 0;
       138154  +  p->pBlob = pBlob;
       138155  +
       138156  +  sqlite3_snprintf(sizeof(zChannel), zChannel, "incrblob_%d", ++count);
       138157  +  p->channel = Tcl_CreateChannel(&IncrblobChannelType, zChannel, p, flags);
       138158  +  Tcl_RegisterChannel(interp, p->channel);
       138159  +
       138160  +  /* Link the new channel into the SqliteDb.pIncrblob list. */
       138161  +  p->pNext = pDb->pIncrblob;
       138162  +  p->pPrev = 0;
       138163  +  if( p->pNext ){
       138164  +    p->pNext->pPrev = p;
       138165  +  }
       138166  +  pDb->pIncrblob = p;
       138167  +  p->pDb = pDb;
       138168  +
       138169  +  Tcl_SetResult(interp, (char *)Tcl_GetChannelName(p->channel), TCL_VOLATILE);
       138170  +  return TCL_OK;
       138171  +}
       138172  +#else  /* else clause for "#ifndef SQLITE_OMIT_INCRBLOB" */
       138173  +  #define closeIncrblobChannels(pDb)
       138174  +#endif
       138175  +
       138176  +/*
       138177  +** Look at the script prefix in pCmd.  We will be executing this script
       138178  +** after first appending one or more arguments.  This routine analyzes
       138179  +** the script to see if it is safe to use Tcl_EvalObjv() on the script
       138180  +** rather than the more general Tcl_EvalEx().  Tcl_EvalObjv() is much
       138181  +** faster.
       138182  +**
       138183  +** Scripts that are safe to use with Tcl_EvalObjv() consists of a
       138184  +** command name followed by zero or more arguments with no [...] or $
       138185  +** or {...} or ; to be seen anywhere.  Most callback scripts consist
       138186  +** of just a single procedure name and they meet this requirement.
       138187  +*/
       138188  +static int safeToUseEvalObjv(Tcl_Interp *interp, Tcl_Obj *pCmd){
       138189  +  /* We could try to do something with Tcl_Parse().  But we will instead
       138190  +  ** just do a search for forbidden characters.  If any of the forbidden
       138191  +  ** characters appear in pCmd, we will report the string as unsafe.
       138192  +  */
       138193  +  const char *z;
       138194  +  int n;
       138195  +  z = Tcl_GetStringFromObj(pCmd, &n);
       138196  +  while( n-- > 0 ){
       138197  +    int c = *(z++);
       138198  +    if( c=='$' || c=='[' || c==';' ) return 0;
       138199  +  }
       138200  +  return 1;
       138201  +}
       138202  +
       138203  +/*
       138204  +** Find an SqlFunc structure with the given name.  Or create a new
       138205  +** one if an existing one cannot be found.  Return a pointer to the
       138206  +** structure.
       138207  +*/
       138208  +static SqlFunc *findSqlFunc(SqliteDb *pDb, const char *zName){
       138209  +  SqlFunc *p, *pNew;
       138210  +  int i;
       138211  +  pNew = (SqlFunc*)Tcl_Alloc( sizeof(*pNew) + strlen30(zName) + 1 );
       138212  +  pNew->zName = (char*)&pNew[1];
       138213  +  for(i=0; zName[i]; i++){ pNew->zName[i] = tolower(zName[i]); }
       138214  +  pNew->zName[i] = 0;
       138215  +  for(p=pDb->pFunc; p; p=p->pNext){ 
       138216  +    if( strcmp(p->zName, pNew->zName)==0 ){
       138217  +      Tcl_Free((char*)pNew);
       138218  +      return p;
       138219  +    }
       138220  +  }
       138221  +  pNew->interp = pDb->interp;
       138222  +  pNew->pDb = pDb;
       138223  +  pNew->pScript = 0;
       138224  +  pNew->pNext = pDb->pFunc;
       138225  +  pDb->pFunc = pNew;
       138226  +  return pNew;
       138227  +}
       138228  +
       138229  +/*
       138230  +** Free a single SqlPreparedStmt object.
       138231  +*/
       138232  +static void dbFreeStmt(SqlPreparedStmt *pStmt){
       138233  +#ifdef SQLITE_TEST
       138234  +  if( sqlite3_sql(pStmt->pStmt)==0 ){
       138235  +    Tcl_Free((char *)pStmt->zSql);
       138236  +  }
       138237  +#endif
       138238  +  sqlite3_finalize(pStmt->pStmt);
       138239  +  Tcl_Free((char *)pStmt);
       138240  +}
       138241  +
       138242  +/*
       138243  +** Finalize and free a list of prepared statements
       138244  +*/
       138245  +static void flushStmtCache(SqliteDb *pDb){
       138246  +  SqlPreparedStmt *pPreStmt;
       138247  +  SqlPreparedStmt *pNext;
       138248  +
       138249  +  for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pNext){
       138250  +    pNext = pPreStmt->pNext;
       138251  +    dbFreeStmt(pPreStmt);
       138252  +  }
       138253  +  pDb->nStmt = 0;
       138254  +  pDb->stmtLast = 0;
       138255  +  pDb->stmtList = 0;
       138256  +}
       138257  +
       138258  +/*
       138259  +** TCL calls this procedure when an sqlite3 database command is
       138260  +** deleted.
       138261  +*/
       138262  +static void DbDeleteCmd(void *db){
       138263  +  SqliteDb *pDb = (SqliteDb*)db;
       138264  +  flushStmtCache(pDb);
       138265  +  closeIncrblobChannels(pDb);
       138266  +  sqlite3_close(pDb->db);
       138267  +  while( pDb->pFunc ){
       138268  +    SqlFunc *pFunc = pDb->pFunc;
       138269  +    pDb->pFunc = pFunc->pNext;
       138270  +    assert( pFunc->pDb==pDb );
       138271  +    Tcl_DecrRefCount(pFunc->pScript);
       138272  +    Tcl_Free((char*)pFunc);
       138273  +  }
       138274  +  while( pDb->pCollate ){
       138275  +    SqlCollate *pCollate = pDb->pCollate;
       138276  +    pDb->pCollate = pCollate->pNext;
       138277  +    Tcl_Free((char*)pCollate);
       138278  +  }
       138279  +  if( pDb->zBusy ){
       138280  +    Tcl_Free(pDb->zBusy);
       138281  +  }
       138282  +  if( pDb->zTrace ){
       138283  +    Tcl_Free(pDb->zTrace);
       138284  +  }
       138285  +  if( pDb->zProfile ){
       138286  +    Tcl_Free(pDb->zProfile);
       138287  +  }
       138288  +  if( pDb->zAuth ){
       138289  +    Tcl_Free(pDb->zAuth);
       138290  +  }
       138291  +  if( pDb->zNull ){
       138292  +    Tcl_Free(pDb->zNull);
       138293  +  }
       138294  +  if( pDb->pUpdateHook ){
       138295  +    Tcl_DecrRefCount(pDb->pUpdateHook);
       138296  +  }
       138297  +  if( pDb->pRollbackHook ){
       138298  +    Tcl_DecrRefCount(pDb->pRollbackHook);
       138299  +  }
       138300  +  if( pDb->pWalHook ){
       138301  +    Tcl_DecrRefCount(pDb->pWalHook);
       138302  +  }
       138303  +  if( pDb->pCollateNeeded ){
       138304  +    Tcl_DecrRefCount(pDb->pCollateNeeded);
       138305  +  }
       138306  +  Tcl_Free((char*)pDb);
       138307  +}
       138308  +
       138309  +/*
       138310  +** This routine is called when a database file is locked while trying
       138311  +** to execute SQL.
       138312  +*/
       138313  +static int DbBusyHandler(void *cd, int nTries){
       138314  +  SqliteDb *pDb = (SqliteDb*)cd;
       138315  +  int rc;
       138316  +  char zVal[30];
       138317  +
       138318  +  sqlite3_snprintf(sizeof(zVal), zVal, "%d", nTries);
       138319  +  rc = Tcl_VarEval(pDb->interp, pDb->zBusy, " ", zVal, (char*)0);
       138320  +  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
       138321  +    return 0;
       138322  +  }
       138323  +  return 1;
       138324  +}
       138325  +
       138326  +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
       138327  +/*
       138328  +** This routine is invoked as the 'progress callback' for the database.
       138329  +*/
       138330  +static int DbProgressHandler(void *cd){
       138331  +  SqliteDb *pDb = (SqliteDb*)cd;
       138332  +  int rc;
       138333  +
       138334  +  assert( pDb->zProgress );
       138335  +  rc = Tcl_Eval(pDb->interp, pDb->zProgress);
       138336  +  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
       138337  +    return 1;
       138338  +  }
       138339  +  return 0;
       138340  +}
       138341  +#endif
       138342  +
       138343  +#ifndef SQLITE_OMIT_TRACE
       138344  +/*
       138345  +** This routine is called by the SQLite trace handler whenever a new
       138346  +** block of SQL is executed.  The TCL script in pDb->zTrace is executed.
       138347  +*/
       138348  +static void DbTraceHandler(void *cd, const char *zSql){
       138349  +  SqliteDb *pDb = (SqliteDb*)cd;
       138350  +  Tcl_DString str;
       138351  +
       138352  +  Tcl_DStringInit(&str);
       138353  +  Tcl_DStringAppend(&str, pDb->zTrace, -1);
       138354  +  Tcl_DStringAppendElement(&str, zSql);
       138355  +  Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
       138356  +  Tcl_DStringFree(&str);
       138357  +  Tcl_ResetResult(pDb->interp);
       138358  +}
       138359  +#endif
       138360  +
       138361  +#ifndef SQLITE_OMIT_TRACE
       138362  +/*
       138363  +** This routine is called by the SQLite profile handler after a statement
       138364  +** SQL has executed.  The TCL script in pDb->zProfile is evaluated.
       138365  +*/
       138366  +static void DbProfileHandler(void *cd, const char *zSql, sqlite_uint64 tm){
       138367  +  SqliteDb *pDb = (SqliteDb*)cd;
       138368  +  Tcl_DString str;
       138369  +  char zTm[100];
       138370  +
       138371  +  sqlite3_snprintf(sizeof(zTm)-1, zTm, "%lld", tm);
       138372  +  Tcl_DStringInit(&str);
       138373  +  Tcl_DStringAppend(&str, pDb->zProfile, -1);
       138374  +  Tcl_DStringAppendElement(&str, zSql);
       138375  +  Tcl_DStringAppendElement(&str, zTm);
       138376  +  Tcl_Eval(pDb->interp, Tcl_DStringValue(&str));
       138377  +  Tcl_DStringFree(&str);
       138378  +  Tcl_ResetResult(pDb->interp);
       138379  +}
       138380  +#endif
       138381  +
       138382  +/*
       138383  +** This routine is called when a transaction is committed.  The
       138384  +** TCL script in pDb->zCommit is executed.  If it returns non-zero or
       138385  +** if it throws an exception, the transaction is rolled back instead
       138386  +** of being committed.
       138387  +*/
       138388  +static int DbCommitHandler(void *cd){
       138389  +  SqliteDb *pDb = (SqliteDb*)cd;
       138390  +  int rc;
       138391  +
       138392  +  rc = Tcl_Eval(pDb->interp, pDb->zCommit);
       138393  +  if( rc!=TCL_OK || atoi(Tcl_GetStringResult(pDb->interp)) ){
       138394  +    return 1;
       138395  +  }
       138396  +  return 0;
       138397  +}
       138398  +
       138399  +static void DbRollbackHandler(void *clientData){
       138400  +  SqliteDb *pDb = (SqliteDb*)clientData;
       138401  +  assert(pDb->pRollbackHook);
       138402  +  if( TCL_OK!=Tcl_EvalObjEx(pDb->interp, pDb->pRollbackHook, 0) ){
       138403  +    Tcl_BackgroundError(pDb->interp);
       138404  +  }
       138405  +}
       138406  +
       138407  +/*
       138408  +** This procedure handles wal_hook callbacks.
       138409  +*/
       138410  +static int DbWalHandler(
       138411  +  void *clientData, 
       138412  +  sqlite3 *db, 
       138413  +  const char *zDb, 
       138414  +  int nEntry
       138415  +){
       138416  +  int ret = SQLITE_OK;
       138417  +  Tcl_Obj *p;
       138418  +  SqliteDb *pDb = (SqliteDb*)clientData;
       138419  +  Tcl_Interp *interp = pDb->interp;
       138420  +  assert(pDb->pWalHook);
       138421  +
       138422  +  p = Tcl_DuplicateObj(pDb->pWalHook);
       138423  +  Tcl_IncrRefCount(p);
       138424  +  Tcl_ListObjAppendElement(interp, p, Tcl_NewStringObj(zDb, -1));
       138425  +  Tcl_ListObjAppendElement(interp, p, Tcl_NewIntObj(nEntry));
       138426  +  if( TCL_OK!=Tcl_EvalObjEx(interp, p, 0) 
       138427  +   || TCL_OK!=Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &ret)
       138428  +  ){
       138429  +    Tcl_BackgroundError(interp);
       138430  +  }
       138431  +  Tcl_DecrRefCount(p);
       138432  +
       138433  +  return ret;
       138434  +}
       138435  +
       138436  +#if defined(SQLITE_TEST) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
       138437  +static void setTestUnlockNotifyVars(Tcl_Interp *interp, int iArg, int nArg){
       138438  +  char zBuf[64];
       138439  +  sprintf(zBuf, "%d", iArg);
       138440  +  Tcl_SetVar(interp, "sqlite_unlock_notify_arg", zBuf, TCL_GLOBAL_ONLY);
       138441  +  sprintf(zBuf, "%d", nArg);
       138442  +  Tcl_SetVar(interp, "sqlite_unlock_notify_argcount", zBuf, TCL_GLOBAL_ONLY);
       138443  +}
       138444  +#else
       138445  +# define setTestUnlockNotifyVars(x,y,z)
       138446  +#endif
       138447  +
       138448  +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
       138449  +static void DbUnlockNotify(void **apArg, int nArg){
       138450  +  int i;
       138451  +  for(i=0; i<nArg; i++){
       138452  +    const int flags = (TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT);
       138453  +    SqliteDb *pDb = (SqliteDb *)apArg[i];
       138454  +    setTestUnlockNotifyVars(pDb->interp, i, nArg);
       138455  +    assert( pDb->pUnlockNotify);
       138456  +    Tcl_EvalObjEx(pDb->interp, pDb->pUnlockNotify, flags);
       138457  +    Tcl_DecrRefCount(pDb->pUnlockNotify);
       138458  +    pDb->pUnlockNotify = 0;
       138459  +  }
       138460  +}
       138461  +#endif
       138462  +
       138463  +static void DbUpdateHandler(
       138464  +  void *p, 
       138465  +  int op,
       138466  +  const char *zDb, 
       138467  +  const char *zTbl, 
       138468  +  sqlite_int64 rowid
       138469  +){
       138470  +  SqliteDb *pDb = (SqliteDb *)p;
       138471  +  Tcl_Obj *pCmd;
       138472  +
       138473  +  assert( pDb->pUpdateHook );
       138474  +  assert( op==SQLITE_INSERT || op==SQLITE_UPDATE || op==SQLITE_DELETE );
       138475  +
       138476  +  pCmd = Tcl_DuplicateObj(pDb->pUpdateHook);
       138477  +  Tcl_IncrRefCount(pCmd);
       138478  +  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(
       138479  +    ( (op==SQLITE_INSERT)?"INSERT":(op==SQLITE_UPDATE)?"UPDATE":"DELETE"), -1));
       138480  +  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zDb, -1));
       138481  +  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewStringObj(zTbl, -1));
       138482  +  Tcl_ListObjAppendElement(0, pCmd, Tcl_NewWideIntObj(rowid));
       138483  +  Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT);
       138484  +  Tcl_DecrRefCount(pCmd);
       138485  +}
       138486  +
       138487  +static void tclCollateNeeded(
       138488  +  void *pCtx,
       138489  +  sqlite3 *db,
       138490  +  int enc,
       138491  +  const char *zName
       138492  +){
       138493  +  SqliteDb *pDb = (SqliteDb *)pCtx;
       138494  +  Tcl_Obj *pScript = Tcl_DuplicateObj(pDb->pCollateNeeded);
       138495  +  Tcl_IncrRefCount(pScript);
       138496  +  Tcl_ListObjAppendElement(0, pScript, Tcl_NewStringObj(zName, -1));
       138497  +  Tcl_EvalObjEx(pDb->interp, pScript, 0);
       138498  +  Tcl_DecrRefCount(pScript);
       138499  +}
       138500  +
       138501  +/*
       138502  +** This routine is called to evaluate an SQL collation function implemented
       138503  +** using TCL script.
       138504  +*/
       138505  +static int tclSqlCollate(
       138506  +  void *pCtx,
       138507  +  int nA,
       138508  +  const void *zA,
       138509  +  int nB,
       138510  +  const void *zB
       138511  +){
       138512  +  SqlCollate *p = (SqlCollate *)pCtx;
       138513  +  Tcl_Obj *pCmd;
       138514  +
       138515  +  pCmd = Tcl_NewStringObj(p->zScript, -1);
       138516  +  Tcl_IncrRefCount(pCmd);
       138517  +  Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zA, nA));
       138518  +  Tcl_ListObjAppendElement(p->interp, pCmd, Tcl_NewStringObj(zB, nB));
       138519  +  Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
       138520  +  Tcl_DecrRefCount(pCmd);
       138521  +  return (atoi(Tcl_GetStringResult(p->interp)));
       138522  +}
       138523  +
       138524  +/*
       138525  +** This routine is called to evaluate an SQL function implemented
       138526  +** using TCL script.
       138527  +*/
       138528  +static void tclSqlFunc(sqlite3_context *context, int argc, sqlite3_value**argv){
       138529  +  SqlFunc *p = sqlite3_user_data(context);
       138530  +  Tcl_Obj *pCmd;
       138531  +  int i;
       138532  +  int rc;
       138533  +
       138534  +  if( argc==0 ){
       138535  +    /* If there are no arguments to the function, call Tcl_EvalObjEx on the
       138536  +    ** script object directly.  This allows the TCL compiler to generate
       138537  +    ** bytecode for the command on the first invocation and thus make
       138538  +    ** subsequent invocations much faster. */
       138539  +    pCmd = p->pScript;
       138540  +    Tcl_IncrRefCount(pCmd);
       138541  +    rc = Tcl_EvalObjEx(p->interp, pCmd, 0);
       138542  +    Tcl_DecrRefCount(pCmd);
       138543  +  }else{
       138544  +    /* If there are arguments to the function, make a shallow copy of the
       138545  +    ** script object, lappend the arguments, then evaluate the copy.
       138546  +    **
       138547  +    ** By "shallow" copy, we mean a only the outer list Tcl_Obj is duplicated.
       138548  +    ** The new Tcl_Obj contains pointers to the original list elements. 
       138549  +    ** That way, when Tcl_EvalObjv() is run and shimmers the first element
       138550  +    ** of the list to tclCmdNameType, that alternate representation will
       138551  +    ** be preserved and reused on the next invocation.
       138552  +    */
       138553  +    Tcl_Obj **aArg;
       138554  +    int nArg;
       138555  +    if( Tcl_ListObjGetElements(p->interp, p->pScript, &nArg, &aArg) ){
       138556  +      sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 
       138557  +      return;
       138558  +    }     
       138559  +    pCmd = Tcl_NewListObj(nArg, aArg);
       138560  +    Tcl_IncrRefCount(pCmd);
       138561  +    for(i=0; i<argc; i++){
       138562  +      sqlite3_value *pIn = argv[i];
       138563  +      Tcl_Obj *pVal;
       138564  +            
       138565  +      /* Set pVal to contain the i'th column of this row. */
       138566  +      switch( sqlite3_value_type(pIn) ){
       138567  +        case SQLITE_BLOB: {
       138568  +          int bytes = sqlite3_value_bytes(pIn);
       138569  +          pVal = Tcl_NewByteArrayObj(sqlite3_value_blob(pIn), bytes);
       138570  +          break;
       138571  +        }
       138572  +        case SQLITE_INTEGER: {
       138573  +          sqlite_int64 v = sqlite3_value_int64(pIn);
       138574  +          if( v>=-2147483647 && v<=2147483647 ){
       138575  +            pVal = Tcl_NewIntObj((int)v);
       138576  +          }else{
       138577  +            pVal = Tcl_NewWideIntObj(v);
       138578  +          }
       138579  +          break;
       138580  +        }
       138581  +        case SQLITE_FLOAT: {
       138582  +          double r = sqlite3_value_double(pIn);
       138583  +          pVal = Tcl_NewDoubleObj(r);
       138584  +          break;
       138585  +        }
       138586  +        case SQLITE_NULL: {
       138587  +          pVal = Tcl_NewStringObj(p->pDb->zNull, -1);
       138588  +          break;
       138589  +        }
       138590  +        default: {
       138591  +          int bytes = sqlite3_value_bytes(pIn);
       138592  +          pVal = Tcl_NewStringObj((char *)sqlite3_value_text(pIn), bytes);
       138593  +          break;
       138594  +        }
       138595  +      }
       138596  +      rc = Tcl_ListObjAppendElement(p->interp, pCmd, pVal);
       138597  +      if( rc ){
       138598  +        Tcl_DecrRefCount(pCmd);
       138599  +        sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 
       138600  +        return;
       138601  +      }
       138602  +    }
       138603  +    if( !p->useEvalObjv ){
       138604  +      /* Tcl_EvalObjEx() will automatically call Tcl_EvalObjv() if pCmd
       138605  +      ** is a list without a string representation.  To prevent this from
       138606  +      ** happening, make sure pCmd has a valid string representation */
       138607  +      Tcl_GetString(pCmd);
       138608  +    }
       138609  +    rc = Tcl_EvalObjEx(p->interp, pCmd, TCL_EVAL_DIRECT);
       138610  +    Tcl_DecrRefCount(pCmd);
       138611  +  }
       138612  +
       138613  +  if( rc && rc!=TCL_RETURN ){
       138614  +    sqlite3_result_error(context, Tcl_GetStringResult(p->interp), -1); 
       138615  +  }else{
       138616  +    Tcl_Obj *pVar = Tcl_GetObjResult(p->interp);
       138617  +    int n;
       138618  +    u8 *data;
       138619  +    const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
       138620  +    char c = zType[0];
       138621  +    if( c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0 ){
       138622  +      /* Only return a BLOB type if the Tcl variable is a bytearray and
       138623  +      ** has no string representation. */
       138624  +      data = Tcl_GetByteArrayFromObj(pVar, &n);
       138625  +      sqlite3_result_blob(context, data, n, SQLITE_TRANSIENT);
       138626  +    }else if( c=='b' && strcmp(zType,"boolean")==0 ){
       138627  +      Tcl_GetIntFromObj(0, pVar, &n);
       138628  +      sqlite3_result_int(context, n);
       138629  +    }else if( c=='d' && strcmp(zType,"double")==0 ){
       138630  +      double r;
       138631  +      Tcl_GetDoubleFromObj(0, pVar, &r);
       138632  +      sqlite3_result_double(context, r);
       138633  +    }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
       138634  +          (c=='i' && strcmp(zType,"int")==0) ){
       138635  +      Tcl_WideInt v;
       138636  +      Tcl_GetWideIntFromObj(0, pVar, &v);
       138637  +      sqlite3_result_int64(context, v);
       138638  +    }else{
       138639  +      data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
       138640  +      sqlite3_result_text(context, (char *)data, n, SQLITE_TRANSIENT);
       138641  +    }
       138642  +  }
       138643  +}
       138644  +
       138645  +#ifndef SQLITE_OMIT_AUTHORIZATION
       138646  +/*
       138647  +** This is the authentication function.  It appends the authentication
       138648  +** type code and the two arguments to zCmd[] then invokes the result
       138649  +** on the interpreter.  The reply is examined to determine if the
       138650  +** authentication fails or succeeds.
       138651  +*/
       138652  +static int auth_callback(
       138653  +  void *pArg,
       138654  +  int code,
       138655  +  const char *zArg1,
       138656  +  const char *zArg2,
       138657  +  const char *zArg3,
       138658  +  const char *zArg4
       138659  +){
       138660  +  char *zCode;
       138661  +  Tcl_DString str;
       138662  +  int rc;
       138663  +  const char *zReply;
       138664  +  SqliteDb *pDb = (SqliteDb*)pArg;
       138665  +  if( pDb->disableAuth ) return SQLITE_OK;
       138666  +
       138667  +  switch( code ){
       138668  +    case SQLITE_COPY              : zCode="SQLITE_COPY"; break;
       138669  +    case SQLITE_CREATE_INDEX      : zCode="SQLITE_CREATE_INDEX"; break;
       138670  +    case SQLITE_CREATE_TABLE      : zCode="SQLITE_CREATE_TABLE"; break;
       138671  +    case SQLITE_CREATE_TEMP_INDEX : zCode="SQLITE_CREATE_TEMP_INDEX"; break;
       138672  +    case SQLITE_CREATE_TEMP_TABLE : zCode="SQLITE_CREATE_TEMP_TABLE"; break;
       138673  +    case SQLITE_CREATE_TEMP_TRIGGER: zCode="SQLITE_CREATE_TEMP_TRIGGER"; break;
       138674  +    case SQLITE_CREATE_TEMP_VIEW  : zCode="SQLITE_CREATE_TEMP_VIEW"; break;
       138675  +    case SQLITE_CREATE_TRIGGER    : zCode="SQLITE_CREATE_TRIGGER"; break;
       138676  +    case SQLITE_CREATE_VIEW       : zCode="SQLITE_CREATE_VIEW"; break;
       138677  +    case SQLITE_DELETE            : zCode="SQLITE_DELETE"; break;
       138678  +    case SQLITE_DROP_INDEX        : zCode="SQLITE_DROP_INDEX"; break;
       138679  +    case SQLITE_DROP_TABLE        : zCode="SQLITE_DROP_TABLE"; break;
       138680  +    case SQLITE_DROP_TEMP_INDEX   : zCode="SQLITE_DROP_TEMP_INDEX"; break;
       138681  +    case SQLITE_DROP_TEMP_TABLE   : zCode="SQLITE_DROP_TEMP_TABLE"; break;
       138682  +    case SQLITE_DROP_TEMP_TRIGGER : zCode="SQLITE_DROP_TEMP_TRIGGER"; break;
       138683  +    case SQLITE_DROP_TEMP_VIEW    : zCode="SQLITE_DROP_TEMP_VIEW"; break;
       138684  +    case SQLITE_DROP_TRIGGER      : zCode="SQLITE_DROP_TRIGGER"; break;
       138685  +    case SQLITE_DROP_VIEW         : zCode="SQLITE_DROP_VIEW"; break;
       138686  +    case SQLITE_INSERT            : zCode="SQLITE_INSERT"; break;
       138687  +    case SQLITE_PRAGMA            : zCode="SQLITE_PRAGMA"; break;
       138688  +    case SQLITE_READ              : zCode="SQLITE_READ"; break;
       138689  +    case SQLITE_SELECT            : zCode="SQLITE_SELECT"; break;
       138690  +    case SQLITE_TRANSACTION       : zCode="SQLITE_TRANSACTION"; break;
       138691  +    case SQLITE_UPDATE            : zCode="SQLITE_UPDATE"; break;
       138692  +    case SQLITE_ATTACH            : zCode="SQLITE_ATTACH"; break;
       138693  +    case SQLITE_DETACH            : zCode="SQLITE_DETACH"; break;
       138694  +    case SQLITE_ALTER_TABLE       : zCode="SQLITE_ALTER_TABLE"; break;
       138695  +    case SQLITE_REINDEX           : zCode="SQLITE_REINDEX"; break;
       138696  +    case SQLITE_ANALYZE           : zCode="SQLITE_ANALYZE"; break;
       138697  +    case SQLITE_CREATE_VTABLE     : zCode="SQLITE_CREATE_VTABLE"; break;
       138698  +    case SQLITE_DROP_VTABLE       : zCode="SQLITE_DROP_VTABLE"; break;
       138699  +    case SQLITE_FUNCTION          : zCode="SQLITE_FUNCTION"; break;
       138700  +    case SQLITE_SAVEPOINT         : zCode="SQLITE_SAVEPOINT"; break;
       138701  +    default                       : zCode="????"; break;
       138702  +  }
       138703  +  Tcl_DStringInit(&str);
       138704  +  Tcl_DStringAppend(&str, pDb->zAuth, -1);
       138705  +  Tcl_DStringAppendElement(&str, zCode);
       138706  +  Tcl_DStringAppendElement(&str, zArg1 ? zArg1 : "");
       138707  +  Tcl_DStringAppendElement(&str, zArg2 ? zArg2 : "");
       138708  +  Tcl_DStringAppendElement(&str, zArg3 ? zArg3 : "");
       138709  +  Tcl_DStringAppendElement(&str, zArg4 ? zArg4 : "");
       138710  +  rc = Tcl_GlobalEval(pDb->interp, Tcl_DStringValue(&str));
       138711  +  Tcl_DStringFree(&str);
       138712  +  zReply = rc==TCL_OK ? Tcl_GetStringResult(pDb->interp) : "SQLITE_DENY";
       138713  +  if( strcmp(zReply,"SQLITE_OK")==0 ){
       138714  +    rc = SQLITE_OK;
       138715  +  }else if( strcmp(zReply,"SQLITE_DENY")==0 ){
       138716  +    rc = SQLITE_DENY;
       138717  +  }else if( strcmp(zReply,"SQLITE_IGNORE")==0 ){
       138718  +    rc = SQLITE_IGNORE;
       138719  +  }else{
       138720  +    rc = 999;
       138721  +  }
       138722  +  return rc;
       138723  +}
       138724  +#endif /* SQLITE_OMIT_AUTHORIZATION */
       138725  +
       138726  +/*
       138727  +** This routine reads a line of text from FILE in, stores
       138728  +** the text in memory obtained from malloc() and returns a pointer
       138729  +** to the text.  NULL is returned at end of file, or if malloc()
       138730  +** fails.
       138731  +**
       138732  +** The interface is like "readline" but no command-line editing
       138733  +** is done.
       138734  +**
       138735  +** copied from shell.c from '.import' command
       138736  +*/
       138737  +static char *local_getline(char *zPrompt, FILE *in){
       138738  +  char *zLine;
       138739  +  int nLine;
       138740  +  int n;
       138741  +
       138742  +  nLine = 100;
       138743  +  zLine = malloc( nLine );
       138744  +  if( zLine==0 ) return 0;
       138745  +  n = 0;
       138746  +  while( 1 ){
       138747  +    if( n+100>nLine ){
       138748  +      nLine = nLine*2 + 100;
       138749  +      zLine = realloc(zLine, nLine);
       138750  +      if( zLine==0 ) return 0;
       138751  +    }
       138752  +    if( fgets(&zLine[n], nLine - n, in)==0 ){
       138753  +      if( n==0 ){
       138754  +        free(zLine);
       138755  +        return 0;
       138756  +      }
       138757  +      zLine[n] = 0;
       138758  +      break;
       138759  +    }
       138760  +    while( zLine[n] ){ n++; }
       138761  +    if( n>0 && zLine[n-1]=='\n' ){
       138762  +      n--;
       138763  +      zLine[n] = 0;
       138764  +      break;
       138765  +    }
       138766  +  }
       138767  +  zLine = realloc( zLine, n+1 );
       138768  +  return zLine;
       138769  +}
       138770  +
       138771  +
       138772  +/*
       138773  +** This function is part of the implementation of the command:
       138774  +**
       138775  +**   $db transaction [-deferred|-immediate|-exclusive] SCRIPT
       138776  +**
       138777  +** It is invoked after evaluating the script SCRIPT to commit or rollback
       138778  +** the transaction or savepoint opened by the [transaction] command.
       138779  +*/
       138780  +static int DbTransPostCmd(
       138781  +  ClientData data[],                   /* data[0] is the Sqlite3Db* for $db */
       138782  +  Tcl_Interp *interp,                  /* Tcl interpreter */
       138783  +  int result                           /* Result of evaluating SCRIPT */
       138784  +){
       138785  +  static const char *azEnd[] = {
       138786  +    "RELEASE _tcl_transaction",        /* rc==TCL_ERROR, nTransaction!=0 */
       138787  +    "COMMIT",                          /* rc!=TCL_ERROR, nTransaction==0 */
       138788  +    "ROLLBACK TO _tcl_transaction ; RELEASE _tcl_transaction",
       138789  +    "ROLLBACK"                         /* rc==TCL_ERROR, nTransaction==0 */
       138790  +  };
       138791  +  SqliteDb *pDb = (SqliteDb*)data[0];
       138792  +  int rc = result;
       138793  +  const char *zEnd;
       138794  +
       138795  +  pDb->nTransaction--;
       138796  +  zEnd = azEnd[(rc==TCL_ERROR)*2 + (pDb->nTransaction==0)];
       138797  +
       138798  +  pDb->disableAuth++;
       138799  +  if( sqlite3_exec(pDb->db, zEnd, 0, 0, 0) ){
       138800  +      /* This is a tricky scenario to handle. The most likely cause of an
       138801  +      ** error is that the exec() above was an attempt to commit the 
       138802  +      ** top-level transaction that returned SQLITE_BUSY. Or, less likely,
       138803  +      ** that an IO-error has occured. In either case, throw a Tcl exception
       138804  +      ** and try to rollback the transaction.
       138805  +      **
       138806  +      ** But it could also be that the user executed one or more BEGIN, 
       138807  +      ** COMMIT, SAVEPOINT, RELEASE or ROLLBACK commands that are confusing
       138808  +      ** this method's logic. Not clear how this would be best handled.
       138809  +      */
       138810  +    if( rc!=TCL_ERROR ){
       138811  +      Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
       138812  +      rc = TCL_ERROR;
       138813  +    }
       138814  +    sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0);
       138815  +  }
       138816  +  pDb->disableAuth--;
       138817  +
       138818  +  return rc;
       138819  +}
       138820  +
       138821  +/*
       138822  +** Unless SQLITE_TEST is defined, this function is a simple wrapper around
       138823  +** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either
       138824  +** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending
       138825  +** on whether or not the [db_use_legacy_prepare] command has been used to 
       138826  +** configure the connection.
       138827  +*/
       138828  +static int dbPrepare(
       138829  +  SqliteDb *pDb,                  /* Database object */
       138830  +  const char *zSql,               /* SQL to compile */
       138831  +  sqlite3_stmt **ppStmt,          /* OUT: Prepared statement */
       138832  +  const char **pzOut              /* OUT: Pointer to next SQL statement */
       138833  +){
       138834  +#ifdef SQLITE_TEST
       138835  +  if( pDb->bLegacyPrepare ){
       138836  +    return sqlite3_prepare(pDb->db, zSql, -1, ppStmt, pzOut);
       138837  +  }
       138838  +#endif
       138839  +  return sqlite3_prepare_v2(pDb->db, zSql, -1, ppStmt, pzOut);
       138840  +}
       138841  +
       138842  +/*
       138843  +** Search the cache for a prepared-statement object that implements the
       138844  +** first SQL statement in the buffer pointed to by parameter zIn. If
       138845  +** no such prepared-statement can be found, allocate and prepare a new
       138846  +** one. In either case, bind the current values of the relevant Tcl
       138847  +** variables to any $var, :var or @var variables in the statement. Before
       138848  +** returning, set *ppPreStmt to point to the prepared-statement object.
       138849  +**
       138850  +** Output parameter *pzOut is set to point to the next SQL statement in
       138851  +** buffer zIn, or to the '\0' byte at the end of zIn if there is no
       138852  +** next statement.
       138853  +**
       138854  +** If successful, TCL_OK is returned. Otherwise, TCL_ERROR is returned
       138855  +** and an error message loaded into interpreter pDb->interp.
       138856  +*/
       138857  +static int dbPrepareAndBind(
       138858  +  SqliteDb *pDb,                  /* Database object */
       138859  +  char const *zIn,                /* SQL to compile */
       138860  +  char const **pzOut,             /* OUT: Pointer to next SQL statement */
       138861  +  SqlPreparedStmt **ppPreStmt     /* OUT: Object used to cache statement */
       138862  +){
       138863  +  const char *zSql = zIn;         /* Pointer to first SQL statement in zIn */
       138864  +  sqlite3_stmt *pStmt;            /* Prepared statement object */
       138865  +  SqlPreparedStmt *pPreStmt;      /* Pointer to cached statement */
       138866  +  int nSql;                       /* Length of zSql in bytes */
       138867  +  int nVar;                       /* Number of variables in statement */
       138868  +  int iParm = 0;                  /* Next free entry in apParm */
       138869  +  int i;
       138870  +  Tcl_Interp *interp = pDb->interp;
       138871  +
       138872  +  *ppPreStmt = 0;
       138873  +
       138874  +  /* Trim spaces from the start of zSql and calculate the remaining length. */
       138875  +  while( isspace(zSql[0]) ){ zSql++; }
       138876  +  nSql = strlen30(zSql);
       138877  +
       138878  +  for(pPreStmt = pDb->stmtList; pPreStmt; pPreStmt=pPreStmt->pNext){
       138879  +    int n = pPreStmt->nSql;
       138880  +    if( nSql>=n 
       138881  +        && memcmp(pPreStmt->zSql, zSql, n)==0
       138882  +        && (zSql[n]==0 || zSql[n-1]==';')
       138883  +    ){
       138884  +      pStmt = pPreStmt->pStmt;
       138885  +      *pzOut = &zSql[pPreStmt->nSql];
       138886  +
       138887  +      /* When a prepared statement is found, unlink it from the
       138888  +      ** cache list.  It will later be added back to the beginning
       138889  +      ** of the cache list in order to implement LRU replacement.
       138890  +      */
       138891  +      if( pPreStmt->pPrev ){
       138892  +        pPreStmt->pPrev->pNext = pPreStmt->pNext;
       138893  +      }else{
       138894  +        pDb->stmtList = pPreStmt->pNext;
       138895  +      }
       138896  +      if( pPreStmt->pNext ){
       138897  +        pPreStmt->pNext->pPrev = pPreStmt->pPrev;
       138898  +      }else{
       138899  +        pDb->stmtLast = pPreStmt->pPrev;
       138900  +      }
       138901  +      pDb->nStmt--;
       138902  +      nVar = sqlite3_bind_parameter_count(pStmt);
       138903  +      break;
       138904  +    }
       138905  +  }
       138906  +  
       138907  +  /* If no prepared statement was found. Compile the SQL text. Also allocate
       138908  +  ** a new SqlPreparedStmt structure.  */
       138909  +  if( pPreStmt==0 ){
       138910  +    int nByte;
       138911  +
       138912  +    if( SQLITE_OK!=dbPrepare(pDb, zSql, &pStmt, pzOut) ){
       138913  +      Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
       138914  +      return TCL_ERROR;
       138915  +    }
       138916  +    if( pStmt==0 ){
       138917  +      if( SQLITE_OK!=sqlite3_errcode(pDb->db) ){
       138918  +        /* A compile-time error in the statement. */
       138919  +        Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
       138920  +        return TCL_ERROR;
       138921  +      }else{
       138922  +        /* The statement was a no-op.  Continue to the next statement
       138923  +        ** in the SQL string.
       138924  +        */
       138925  +        return TCL_OK;
       138926  +      }
       138927  +    }
       138928  +
       138929  +    assert( pPreStmt==0 );
       138930  +    nVar = sqlite3_bind_parameter_count(pStmt);
       138931  +    nByte = sizeof(SqlPreparedStmt) + nVar*sizeof(Tcl_Obj *);
       138932  +    pPreStmt = (SqlPreparedStmt*)Tcl_Alloc(nByte);
       138933  +    memset(pPreStmt, 0, nByte);
       138934  +
       138935  +    pPreStmt->pStmt = pStmt;
       138936  +    pPreStmt->nSql = (int)(*pzOut - zSql);
       138937  +    pPreStmt->zSql = sqlite3_sql(pStmt);
       138938  +    pPreStmt->apParm = (Tcl_Obj **)&pPreStmt[1];
       138939  +#ifdef SQLITE_TEST
       138940  +    if( pPreStmt->zSql==0 ){
       138941  +      char *zCopy = Tcl_Alloc(pPreStmt->nSql + 1);
       138942  +      memcpy(zCopy, zSql, pPreStmt->nSql);
       138943  +      zCopy[pPreStmt->nSql] = '\0';
       138944  +      pPreStmt->zSql = zCopy;
       138945  +    }
       138946  +#endif
       138947  +  }
       138948  +  assert( pPreStmt );
       138949  +  assert( strlen30(pPreStmt->zSql)==pPreStmt->nSql );
       138950  +  assert( 0==memcmp(pPreStmt->zSql, zSql, pPreStmt->nSql) );
       138951  +
       138952  +  /* Bind values to parameters that begin with $ or : */  
       138953  +  for(i=1; i<=nVar; i++){
       138954  +    const char *zVar = sqlite3_bind_parameter_name(pStmt, i);
       138955  +    if( zVar!=0 && (zVar[0]=='$' || zVar[0]==':' || zVar[0]=='@') ){
       138956  +      Tcl_Obj *pVar = Tcl_GetVar2Ex(interp, &zVar[1], 0, 0);
       138957  +      if( pVar ){
       138958  +        int n;
       138959  +        u8 *data;
       138960  +        const char *zType = (pVar->typePtr ? pVar->typePtr->name : "");
       138961  +        char c = zType[0];
       138962  +        if( zVar[0]=='@' ||
       138963  +           (c=='b' && strcmp(zType,"bytearray")==0 && pVar->bytes==0) ){
       138964  +          /* Load a BLOB type if the Tcl variable is a bytearray and
       138965  +          ** it has no string representation or the host
       138966  +          ** parameter name begins with "@". */
       138967  +          data = Tcl_GetByteArrayFromObj(pVar, &n);
       138968  +          sqlite3_bind_blob(pStmt, i, data, n, SQLITE_STATIC);
       138969  +          Tcl_IncrRefCount(pVar);
       138970  +          pPreStmt->apParm[iParm++] = pVar;
       138971  +        }else if( c=='b' && strcmp(zType,"boolean")==0 ){
       138972  +          Tcl_GetIntFromObj(interp, pVar, &n);
       138973  +          sqlite3_bind_int(pStmt, i, n);
       138974  +        }else if( c=='d' && strcmp(zType,"double")==0 ){
       138975  +          double r;
       138976  +          Tcl_GetDoubleFromObj(interp, pVar, &r);
       138977  +          sqlite3_bind_double(pStmt, i, r);
       138978  +        }else if( (c=='w' && strcmp(zType,"wideInt")==0) ||
       138979  +              (c=='i' && strcmp(zType,"int")==0) ){
       138980  +          Tcl_WideInt v;
       138981  +          Tcl_GetWideIntFromObj(interp, pVar, &v);
       138982  +          sqlite3_bind_int64(pStmt, i, v);
       138983  +        }else{
       138984  +          data = (unsigned char *)Tcl_GetStringFromObj(pVar, &n);
       138985  +          sqlite3_bind_text(pStmt, i, (char *)data, n, SQLITE_STATIC);
       138986  +          Tcl_IncrRefCount(pVar);
       138987  +          pPreStmt->apParm[iParm++] = pVar;
       138988  +        }
       138989  +      }else{
       138990  +        sqlite3_bind_null(pStmt, i);
       138991  +      }
       138992  +    }
       138993  +  }
       138994  +  pPreStmt->nParm = iParm;
       138995  +  *ppPreStmt = pPreStmt;
       138996  +
       138997  +  return TCL_OK;
       138998  +}
       138999  +
       139000  +/*
       139001  +** Release a statement reference obtained by calling dbPrepareAndBind().
       139002  +** There should be exactly one call to this function for each call to
       139003  +** dbPrepareAndBind().
       139004  +**
       139005  +** If the discard parameter is non-zero, then the statement is deleted
       139006  +** immediately. Otherwise it is added to the LRU list and may be returned
       139007  +** by a subsequent call to dbPrepareAndBind().
       139008  +*/
       139009  +static void dbReleaseStmt(
       139010  +  SqliteDb *pDb,                  /* Database handle */
       139011  +  SqlPreparedStmt *pPreStmt,      /* Prepared statement handle to release */
       139012  +  int discard                     /* True to delete (not cache) the pPreStmt */
       139013  +){
       139014  +  int i;
       139015  +
       139016  +  /* Free the bound string and blob parameters */
       139017  +  for(i=0; i<pPreStmt->nParm; i++){
       139018  +    Tcl_DecrRefCount(pPreStmt->apParm[i]);
       139019  +  }
       139020  +  pPreStmt->nParm = 0;
       139021  +
       139022  +  if( pDb->maxStmt<=0 || discard ){
       139023  +    /* If the cache is turned off, deallocated the statement */
       139024  +    dbFreeStmt(pPreStmt);
       139025  +  }else{
       139026  +    /* Add the prepared statement to the beginning of the cache list. */
       139027  +    pPreStmt->pNext = pDb->stmtList;
       139028  +    pPreStmt->pPrev = 0;
       139029  +    if( pDb->stmtList ){
       139030  +     pDb->stmtList->pPrev = pPreStmt;
       139031  +    }
       139032  +    pDb->stmtList = pPreStmt;
       139033  +    if( pDb->stmtLast==0 ){
       139034  +      assert( pDb->nStmt==0 );
       139035  +      pDb->stmtLast = pPreStmt;
       139036  +    }else{
       139037  +      assert( pDb->nStmt>0 );
       139038  +    }
       139039  +    pDb->nStmt++;
       139040  +   
       139041  +    /* If we have too many statement in cache, remove the surplus from 
       139042  +    ** the end of the cache list.  */
       139043  +    while( pDb->nStmt>pDb->maxStmt ){
       139044  +      SqlPreparedStmt *pLast = pDb->stmtLast;
       139045  +      pDb->stmtLast = pLast->pPrev;
       139046  +      pDb->stmtLast->pNext = 0;
       139047  +      pDb->nStmt--;
       139048  +      dbFreeStmt(pLast);
       139049  +    }
       139050  +  }
       139051  +}
       139052  +
       139053  +/*
       139054  +** Structure used with dbEvalXXX() functions:
       139055  +**
       139056  +**   dbEvalInit()
       139057  +**   dbEvalStep()
       139058  +**   dbEvalFinalize()
       139059  +**   dbEvalRowInfo()
       139060  +**   dbEvalColumnValue()
       139061  +*/
       139062  +typedef struct DbEvalContext DbEvalContext;
       139063  +struct DbEvalContext {
       139064  +  SqliteDb *pDb;                  /* Database handle */
       139065  +  Tcl_Obj *pSql;                  /* Object holding string zSql */
       139066  +  const char *zSql;               /* Remaining SQL to execute */
       139067  +  SqlPreparedStmt *pPreStmt;      /* Current statement */
       139068  +  int nCol;                       /* Number of columns returned by pStmt */
       139069  +  Tcl_Obj *pArray;                /* Name of array variable */
       139070  +  Tcl_Obj **apColName;            /* Array of column names */
       139071  +};
       139072  +
       139073  +/*
       139074  +** Release any cache of column names currently held as part of
       139075  +** the DbEvalContext structure passed as the first argument.
       139076  +*/
       139077  +static void dbReleaseColumnNames(DbEvalContext *p){
       139078  +  if( p->apColName ){
       139079  +    int i;
       139080  +    for(i=0; i<p->nCol; i++){
       139081  +      Tcl_DecrRefCount(p->apColName[i]);
       139082  +    }
       139083  +    Tcl_Free((char *)p->apColName);
       139084  +    p->apColName = 0;
       139085  +  }
       139086  +  p->nCol = 0;
       139087  +}
       139088  +
       139089  +/*
       139090  +** Initialize a DbEvalContext structure.
       139091  +**
       139092  +** If pArray is not NULL, then it contains the name of a Tcl array
       139093  +** variable. The "*" member of this array is set to a list containing
       139094  +** the names of the columns returned by the statement as part of each
       139095  +** call to dbEvalStep(), in order from left to right. e.g. if the names 
       139096  +** of the returned columns are a, b and c, it does the equivalent of the 
       139097  +** tcl command:
       139098  +**
       139099  +**     set ${pArray}(*) {a b c}
       139100  +*/
       139101  +static void dbEvalInit(
       139102  +  DbEvalContext *p,               /* Pointer to structure to initialize */
       139103  +  SqliteDb *pDb,                  /* Database handle */
       139104  +  Tcl_Obj *pSql,                  /* Object containing SQL script */
       139105  +  Tcl_Obj *pArray                 /* Name of Tcl array to set (*) element of */
       139106  +){
       139107  +  memset(p, 0, sizeof(DbEvalContext));
       139108  +  p->pDb = pDb;
       139109  +  p->zSql = Tcl_GetString(pSql);
       139110  +  p->pSql = pSql;
       139111  +  Tcl_IncrRefCount(pSql);
       139112  +  if( pArray ){
       139113  +    p->pArray = pArray;
       139114  +    Tcl_IncrRefCount(pArray);
       139115  +  }
       139116  +}
       139117  +
       139118  +/*
       139119  +** Obtain information about the row that the DbEvalContext passed as the
       139120  +** first argument currently points to.
       139121  +*/
       139122  +static void dbEvalRowInfo(
       139123  +  DbEvalContext *p,               /* Evaluation context */
       139124  +  int *pnCol,                     /* OUT: Number of column names */
       139125  +  Tcl_Obj ***papColName           /* OUT: Array of column names */
       139126  +){
       139127  +  /* Compute column names */
       139128  +  if( 0==p->apColName ){
       139129  +    sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
       139130  +    int i;                        /* Iterator variable */
       139131  +    int nCol;                     /* Number of columns returned by pStmt */
       139132  +    Tcl_Obj **apColName = 0;      /* Array of column names */
       139133  +
       139134  +    p->nCol = nCol = sqlite3_column_count(pStmt);
       139135  +    if( nCol>0 && (papColName || p->pArray) ){
       139136  +      apColName = (Tcl_Obj**)Tcl_Alloc( sizeof(Tcl_Obj*)*nCol );
       139137  +      for(i=0; i<nCol; i++){
       139138  +        apColName[i] = Tcl_NewStringObj(sqlite3_column_name(pStmt,i), -1);
       139139  +        Tcl_IncrRefCount(apColName[i]);
       139140  +      }
       139141  +      p->apColName = apColName;
       139142  +    }
       139143  +
       139144  +    /* If results are being stored in an array variable, then create
       139145  +    ** the array(*) entry for that array
       139146  +    */
       139147  +    if( p->pArray ){
       139148  +      Tcl_Interp *interp = p->pDb->interp;
       139149  +      Tcl_Obj *pColList = Tcl_NewObj();
       139150  +      Tcl_Obj *pStar = Tcl_NewStringObj("*", -1);
       139151  +
       139152  +      for(i=0; i<nCol; i++){
       139153  +        Tcl_ListObjAppendElement(interp, pColList, apColName[i]);
       139154  +      }
       139155  +      Tcl_IncrRefCount(pStar);
       139156  +      Tcl_ObjSetVar2(interp, p->pArray, pStar, pColList, 0);
       139157  +      Tcl_DecrRefCount(pStar);
       139158  +    }
       139159  +  }
       139160  +
       139161  +  if( papColName ){
       139162  +    *papColName = p->apColName;
       139163  +  }
       139164  +  if( pnCol ){
       139165  +    *pnCol = p->nCol;
       139166  +  }
       139167  +}
       139168  +
       139169  +/*
       139170  +** Return one of TCL_OK, TCL_BREAK or TCL_ERROR. If TCL_ERROR is
       139171  +** returned, then an error message is stored in the interpreter before
       139172  +** returning.
       139173  +**
       139174  +** A return value of TCL_OK means there is a row of data available. The
       139175  +** data may be accessed using dbEvalRowInfo() and dbEvalColumnValue(). This
       139176  +** is analogous to a return of SQLITE_ROW from sqlite3_step(). If TCL_BREAK
       139177  +** is returned, then the SQL script has finished executing and there are
       139178  +** no further rows available. This is similar to SQLITE_DONE.
       139179  +*/
       139180  +static int dbEvalStep(DbEvalContext *p){
       139181  +  const char *zPrevSql = 0;       /* Previous value of p->zSql */
       139182  +
       139183  +  while( p->zSql[0] || p->pPreStmt ){
       139184  +    int rc;
       139185  +    if( p->pPreStmt==0 ){
       139186  +      zPrevSql = (p->zSql==zPrevSql ? 0 : p->zSql);
       139187  +      rc = dbPrepareAndBind(p->pDb, p->zSql, &p->zSql, &p->pPreStmt);
       139188  +      if( rc!=TCL_OK ) return rc;
       139189  +    }else{
       139190  +      int rcs;
       139191  +      SqliteDb *pDb = p->pDb;
       139192  +      SqlPreparedStmt *pPreStmt = p->pPreStmt;
       139193  +      sqlite3_stmt *pStmt = pPreStmt->pStmt;
       139194  +
       139195  +      rcs = sqlite3_step(pStmt);
       139196  +      if( rcs==SQLITE_ROW ){
       139197  +        return TCL_OK;
       139198  +      }
       139199  +      if( p->pArray ){
       139200  +        dbEvalRowInfo(p, 0, 0);
       139201  +      }
       139202  +      rcs = sqlite3_reset(pStmt);
       139203  +
       139204  +      pDb->nStep = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_FULLSCAN_STEP,1);
       139205  +      pDb->nSort = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_SORT,1);
       139206  +      pDb->nIndex = sqlite3_stmt_status(pStmt,SQLITE_STMTSTATUS_AUTOINDEX,1);
       139207  +      dbReleaseColumnNames(p);
       139208  +      p->pPreStmt = 0;
       139209  +
       139210  +      if( rcs!=SQLITE_OK ){
       139211  +        /* If a run-time error occurs, report the error and stop reading
       139212  +        ** the SQL.  */
       139213  +        dbReleaseStmt(pDb, pPreStmt, 1);
       139214  +#if SQLITE_TEST
       139215  +        if( p->pDb->bLegacyPrepare && rcs==SQLITE_SCHEMA && zPrevSql ){
       139216  +          /* If the runtime error was an SQLITE_SCHEMA, and the database
       139217  +          ** handle is configured to use the legacy sqlite3_prepare() 
       139218  +          ** interface, retry prepare()/step() on the same SQL statement.
       139219  +          ** This only happens once. If there is a second SQLITE_SCHEMA
       139220  +          ** error, the error will be returned to the caller. */
       139221  +          p->zSql = zPrevSql;
       139222  +          continue;
       139223  +        }
       139224  +#endif
       139225  +        Tcl_SetObjResult(pDb->interp,
       139226  +                         Tcl_NewStringObj(sqlite3_errmsg(pDb->db), -1));
       139227  +        return TCL_ERROR;
       139228  +      }else{
       139229  +        dbReleaseStmt(pDb, pPreStmt, 0);
       139230  +      }
       139231  +    }
       139232  +  }
       139233  +
       139234  +  /* Finished */
       139235  +  return TCL_BREAK;
       139236  +}
       139237  +
       139238  +/*
       139239  +** Free all resources currently held by the DbEvalContext structure passed
       139240  +** as the first argument. There should be exactly one call to this function
       139241  +** for each call to dbEvalInit().
       139242  +*/
       139243  +static void dbEvalFinalize(DbEvalContext *p){
       139244  +  if( p->pPreStmt ){
       139245  +    sqlite3_reset(p->pPreStmt->pStmt);
       139246  +    dbReleaseStmt(p->pDb, p->pPreStmt, 0);
       139247  +    p->pPreStmt = 0;
       139248  +  }
       139249  +  if( p->pArray ){
       139250  +    Tcl_DecrRefCount(p->pArray);
       139251  +    p->pArray = 0;
       139252  +  }
       139253  +  Tcl_DecrRefCount(p->pSql);
       139254  +  dbReleaseColumnNames(p);
       139255  +}
       139256  +
       139257  +/*
       139258  +** Return a pointer to a Tcl_Obj structure with ref-count 0 that contains
       139259  +** the value for the iCol'th column of the row currently pointed to by
       139260  +** the DbEvalContext structure passed as the first argument.
       139261  +*/
       139262  +static Tcl_Obj *dbEvalColumnValue(DbEvalContext *p, int iCol){
       139263  +  sqlite3_stmt *pStmt = p->pPreStmt->pStmt;
       139264  +  switch( sqlite3_column_type(pStmt, iCol) ){
       139265  +    case SQLITE_BLOB: {
       139266  +      int bytes = sqlite3_column_bytes(pStmt, iCol);
       139267  +      const char *zBlob = sqlite3_column_blob(pStmt, iCol);
       139268  +      if( !zBlob ) bytes = 0;
       139269  +      return Tcl_NewByteArrayObj((u8*)zBlob, bytes);
       139270  +    }
       139271  +    case SQLITE_INTEGER: {
       139272  +      sqlite_int64 v = sqlite3_column_int64(pStmt, iCol);
       139273  +      if( v>=-2147483647 && v<=2147483647 ){
       139274  +        return Tcl_NewIntObj((int)v);
       139275  +      }else{
       139276  +        return Tcl_NewWideIntObj(v);
       139277  +      }
       139278  +    }
       139279  +    case SQLITE_FLOAT: {
       139280  +      return Tcl_NewDoubleObj(sqlite3_column_double(pStmt, iCol));
       139281  +    }
       139282  +    case SQLITE_NULL: {
       139283  +      return Tcl_NewStringObj(p->pDb->zNull, -1);
       139284  +    }
       139285  +  }
       139286  +
       139287  +  return Tcl_NewStringObj((char*)sqlite3_column_text(pStmt, iCol), -1);
       139288  +}
       139289  +
       139290  +/*
       139291  +** If using Tcl version 8.6 or greater, use the NR functions to avoid
       139292  +** recursive evalution of scripts by the [db eval] and [db trans]
       139293  +** commands. Even if the headers used while compiling the extension
       139294  +** are 8.6 or newer, the code still tests the Tcl version at runtime.
       139295  +** This allows stubs-enabled builds to be used with older Tcl libraries.
       139296  +*/
       139297  +#if TCL_MAJOR_VERSION>8 || (TCL_MAJOR_VERSION==8 && TCL_MINOR_VERSION>=6)
       139298  +# define SQLITE_TCL_NRE 1
       139299  +static int DbUseNre(void){
       139300  +  int major, minor;
       139301  +  Tcl_GetVersion(&major, &minor, 0, 0);
       139302  +  return( (major==8 && minor>=6) || major>8 );
       139303  +}
       139304  +#else
       139305  +/* 
       139306  +** Compiling using headers earlier than 8.6. In this case NR cannot be
       139307  +** used, so DbUseNre() to always return zero. Add #defines for the other
       139308  +** Tcl_NRxxx() functions to prevent them from causing compilation errors,
       139309  +** even though the only invocations of them are within conditional blocks 
       139310  +** of the form:
       139311  +**
       139312  +**   if( DbUseNre() ) { ... }
       139313  +*/
       139314  +# define SQLITE_TCL_NRE 0
       139315  +# define DbUseNre() 0
       139316  +# define Tcl_NRAddCallback(a,b,c,d,e,f) 0
       139317  +# define Tcl_NREvalObj(a,b,c) 0
       139318  +# define Tcl_NRCreateCommand(a,b,c,d,e,f) 0
       139319  +#endif
       139320  +
       139321  +/*
       139322  +** This function is part of the implementation of the command:
       139323  +**
       139324  +**   $db eval SQL ?ARRAYNAME? SCRIPT
       139325  +*/
       139326  +static int DbEvalNextCmd(
       139327  +  ClientData data[],                   /* data[0] is the (DbEvalContext*) */
       139328  +  Tcl_Interp *interp,                  /* Tcl interpreter */
       139329  +  int result                           /* Result so far */
       139330  +){
       139331  +  int rc = result;                     /* Return code */
       139332  +
       139333  +  /* The first element of the data[] array is a pointer to a DbEvalContext
       139334  +  ** structure allocated using Tcl_Alloc(). The second element of data[]
       139335  +  ** is a pointer to a Tcl_Obj containing the script to run for each row
       139336  +  ** returned by the queries encapsulated in data[0]. */
       139337  +  DbEvalContext *p = (DbEvalContext *)data[0];
       139338  +  Tcl_Obj *pScript = (Tcl_Obj *)data[1];
       139339  +  Tcl_Obj *pArray = p->pArray;
       139340  +
       139341  +  while( (rc==TCL_OK || rc==TCL_CONTINUE) && TCL_OK==(rc = dbEvalStep(p)) ){
       139342  +    int i;
       139343  +    int nCol;
       139344  +    Tcl_Obj **apColName;
       139345  +    dbEvalRowInfo(p, &nCol, &apColName);
       139346  +    for(i=0; i<nCol; i++){
       139347  +      Tcl_Obj *pVal = dbEvalColumnValue(p, i);
       139348  +      if( pArray==0 ){
       139349  +        Tcl_ObjSetVar2(interp, apColName[i], 0, pVal, 0);
       139350  +      }else{
       139351  +        Tcl_ObjSetVar2(interp, pArray, apColName[i], pVal, 0);
       139352  +      }
       139353  +    }
       139354  +
       139355  +    /* The required interpreter variables are now populated with the data 
       139356  +    ** from the current row. If using NRE, schedule callbacks to evaluate
       139357  +    ** script pScript, then to invoke this function again to fetch the next
       139358  +    ** row (or clean up if there is no next row or the script throws an
       139359  +    ** exception). After scheduling the callbacks, return control to the 
       139360  +    ** caller.
       139361  +    **
       139362  +    ** If not using NRE, evaluate pScript directly and continue with the
       139363  +    ** next iteration of this while(...) loop.  */
       139364  +    if( DbUseNre() ){
       139365  +      Tcl_NRAddCallback(interp, DbEvalNextCmd, (void*)p, (void*)pScript, 0, 0);
       139366  +      return Tcl_NREvalObj(interp, pScript, 0);
       139367  +    }else{
       139368  +      rc = Tcl_EvalObjEx(interp, pScript, 0);
       139369  +    }
       139370  +  }
       139371  +
       139372  +  Tcl_DecrRefCount(pScript);
       139373  +  dbEvalFinalize(p);
       139374  +  Tcl_Free((char *)p);
       139375  +
       139376  +  if( rc==TCL_OK || rc==TCL_BREAK ){
       139377  +    Tcl_ResetResult(interp);
       139378  +    rc = TCL_OK;
       139379  +  }
       139380  +  return rc;
       139381  +}
       139382  +
       139383  +/*
       139384  +** The "sqlite" command below creates a new Tcl command for each
       139385  +** connection it opens to an SQLite database.  This routine is invoked
       139386  +** whenever one of those connection-specific commands is executed
       139387  +** in Tcl.  For example, if you run Tcl code like this:
       139388  +**
       139389  +**       sqlite3 db1  "my_database"
       139390  +**       db1 close
       139391  +**
       139392  +** The first command opens a connection to the "my_database" database
       139393  +** and calls that connection "db1".  The second command causes this
       139394  +** subroutine to be invoked.
       139395  +*/
       139396  +static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
       139397  +  SqliteDb *pDb = (SqliteDb*)cd;
       139398  +  int choice;
       139399  +  int rc = TCL_OK;
       139400  +  static const char *DB_strs[] = {
       139401  +    "authorizer",         "backup",            "busy",
       139402  +    "cache",              "changes",           "close",
       139403  +    "collate",            "collation_needed",  "commit_hook",
       139404  +    "complete",           "copy",              "enable_load_extension",
       139405  +    "errorcode",          "eval",              "exists",
       139406  +    "function",           "incrblob",          "interrupt",
       139407  +    "last_insert_rowid",  "nullvalue",         "onecolumn",
       139408  +    "profile",            "progress",          "rekey",
       139409  +    "restore",            "rollback_hook",     "status",
       139410  +    "timeout",            "total_changes",     "trace",
       139411  +    "transaction",        "unlock_notify",     "update_hook",
       139412  +    "version",            "wal_hook",          0
       139413  +  };
       139414  +  enum DB_enum {
       139415  +    DB_AUTHORIZER,        DB_BACKUP,           DB_BUSY,
       139416  +    DB_CACHE,             DB_CHANGES,          DB_CLOSE,
       139417  +    DB_COLLATE,           DB_COLLATION_NEEDED, DB_COMMIT_HOOK,
       139418  +    DB_COMPLETE,          DB_COPY,             DB_ENABLE_LOAD_EXTENSION,
       139419  +    DB_ERRORCODE,         DB_EVAL,             DB_EXISTS,
       139420  +    DB_FUNCTION,          DB_INCRBLOB,         DB_INTERRUPT,
       139421  +    DB_LAST_INSERT_ROWID, DB_NULLVALUE,        DB_ONECOLUMN,
       139422  +    DB_PROFILE,           DB_PROGRESS,         DB_REKEY,
       139423  +    DB_RESTORE,           DB_ROLLBACK_HOOK,    DB_STATUS,
       139424  +    DB_TIMEOUT,           DB_TOTAL_CHANGES,    DB_TRACE,
       139425  +    DB_TRANSACTION,       DB_UNLOCK_NOTIFY,    DB_UPDATE_HOOK,
       139426  +    DB_VERSION,           DB_WAL_HOOK
       139427  +  };
       139428  +  /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */
       139429  +
       139430  +  if( objc<2 ){
       139431  +    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
       139432  +    return TCL_ERROR;
       139433  +  }
       139434  +  if( Tcl_GetIndexFromObj(interp, objv[1], DB_strs, "option", 0, &choice) ){
       139435  +    return TCL_ERROR;
       139436  +  }
       139437  +
       139438  +  switch( (enum DB_enum)choice ){
       139439  +
       139440  +  /*    $db authorizer ?CALLBACK?
       139441  +  **
       139442  +  ** Invoke the given callback to authorize each SQL operation as it is
       139443  +  ** compiled.  5 arguments are appended to the callback before it is
       139444  +  ** invoked:
       139445  +  **
       139446  +  **   (1) The authorization type (ex: SQLITE_CREATE_TABLE, SQLITE_INSERT, ...)
       139447  +  **   (2) First descriptive name (depends on authorization type)
       139448  +  **   (3) Second descriptive name
       139449  +  **   (4) Name of the database (ex: "main", "temp")
       139450  +  **   (5) Name of trigger that is doing the access
       139451  +  **
       139452  +  ** The callback should return on of the following strings: SQLITE_OK,
       139453  +  ** SQLITE_IGNORE, or SQLITE_DENY.  Any other return value is an error.
       139454  +  **
       139455  +  ** If this method is invoked with no arguments, the current authorization
       139456  +  ** callback string is returned.
       139457  +  */
       139458  +  case DB_AUTHORIZER: {
       139459  +#ifdef SQLITE_OMIT_AUTHORIZATION
       139460  +    Tcl_AppendResult(interp, "authorization not available in this build", 0);
       139461  +    return TCL_ERROR;
       139462  +#else
       139463  +    if( objc>3 ){
       139464  +      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
       139465  +      return TCL_ERROR;
       139466  +    }else if( objc==2 ){
       139467  +      if( pDb->zAuth ){
       139468  +        Tcl_AppendResult(interp, pDb->zAuth, 0);
       139469  +      }
       139470  +    }else{
       139471  +      char *zAuth;
       139472  +      int len;
       139473  +      if( pDb->zAuth ){
       139474  +        Tcl_Free(pDb->zAuth);
       139475  +      }
       139476  +      zAuth = Tcl_GetStringFromObj(objv[2], &len);
       139477  +      if( zAuth && len>0 ){
       139478  +        pDb->zAuth = Tcl_Alloc( len + 1 );
       139479  +        memcpy(pDb->zAuth, zAuth, len+1);
       139480  +      }else{
       139481  +        pDb->zAuth = 0;
       139482  +      }
       139483  +      if( pDb->zAuth ){
       139484  +        pDb->interp = interp;
       139485  +        sqlite3_set_authorizer(pDb->db, auth_callback, pDb);
       139486  +      }else{
       139487  +        sqlite3_set_authorizer(pDb->db, 0, 0);
       139488  +      }
       139489  +    }
       139490  +#endif
       139491  +    break;
       139492  +  }
       139493  +
       139494  +  /*    $db backup ?DATABASE? FILENAME
       139495  +  **
       139496  +  ** Open or create a database file named FILENAME.  Transfer the
       139497  +  ** content of local database DATABASE (default: "main") into the
       139498  +  ** FILENAME database.
       139499  +  */
       139500  +  case DB_BACKUP: {
       139501  +    const char *zDestFile;
       139502  +    const char *zSrcDb;
       139503  +    sqlite3 *pDest;
       139504  +    sqlite3_backup *pBackup;
       139505  +
       139506  +    if( objc==3 ){
       139507  +      zSrcDb = "main";
       139508  +      zDestFile = Tcl_GetString(objv[2]);
       139509  +    }else if( objc==4 ){
       139510  +      zSrcDb = Tcl_GetString(objv[2]);
       139511  +      zDestFile = Tcl_GetString(objv[3]);
       139512  +    }else{
       139513  +      Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
       139514  +      return TCL_ERROR;
       139515  +    }
       139516  +    rc = sqlite3_open(zDestFile, &pDest);
       139517  +    if( rc!=SQLITE_OK ){
       139518  +      Tcl_AppendResult(interp, "cannot open target database: ",
       139519  +           sqlite3_errmsg(pDest), (char*)0);
       139520  +      sqlite3_close(pDest);
       139521  +      return TCL_ERROR;
       139522  +    }
       139523  +    pBackup = sqlite3_backup_init(pDest, "main", pDb->db, zSrcDb);
       139524  +    if( pBackup==0 ){
       139525  +      Tcl_AppendResult(interp, "backup failed: ",
       139526  +           sqlite3_errmsg(pDest), (char*)0);
       139527  +      sqlite3_close(pDest);
       139528  +      return TCL_ERROR;
       139529  +    }
       139530  +    while(  (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK ){}
       139531  +    sqlite3_backup_finish(pBackup);
       139532  +    if( rc==SQLITE_DONE ){
       139533  +      rc = TCL_OK;
       139534  +    }else{
       139535  +      Tcl_AppendResult(interp, "backup failed: ",
       139536  +           sqlite3_errmsg(pDest), (char*)0);
       139537  +      rc = TCL_ERROR;
       139538  +    }
       139539  +    sqlite3_close(pDest);
       139540  +    break;
       139541  +  }
       139542  +
       139543  +  /*    $db busy ?CALLBACK?
       139544  +  **
       139545  +  ** Invoke the given callback if an SQL statement attempts to open
       139546  +  ** a locked database file.
       139547  +  */
       139548  +  case DB_BUSY: {
       139549  +    if( objc>3 ){
       139550  +      Tcl_WrongNumArgs(interp, 2, objv, "CALLBACK");
       139551  +      return TCL_ERROR;
       139552  +    }else if( objc==2 ){
       139553  +      if( pDb->zBusy ){
       139554  +        Tcl_AppendResult(interp, pDb->zBusy, 0);
       139555  +      }
       139556  +    }else{
       139557  +      char *zBusy;
       139558  +      int len;
       139559  +      if( pDb->zBusy ){
       139560  +        Tcl_Free(pDb->zBusy);
       139561  +      }
       139562  +      zBusy = Tcl_GetStringFromObj(objv[2], &len);
       139563  +      if( zBusy && len>0 ){
       139564  +        pDb->zBusy = Tcl_Alloc( len + 1 );
       139565  +        memcpy(pDb->zBusy, zBusy, len+1);
       139566  +      }else{
       139567  +        pDb->zBusy = 0;
       139568  +      }
       139569  +      if( pDb->zBusy ){
       139570  +        pDb->interp = interp;
       139571  +        sqlite3_busy_handler(pDb->db, DbBusyHandler, pDb);
       139572  +      }else{
       139573  +        sqlite3_busy_handler(pDb->db, 0, 0);
       139574  +      }
       139575  +    }
       139576  +    break;
       139577  +  }
       139578  +
       139579  +  /*     $db cache flush
       139580  +  **     $db cache size n
       139581  +  **
       139582  +  ** Flush the prepared statement cache, or set the maximum number of
       139583  +  ** cached statements.
       139584  +  */
       139585  +  case DB_CACHE: {
       139586  +    char *subCmd;
       139587  +    int n;
       139588  +
       139589  +    if( objc<=2 ){
       139590  +      Tcl_WrongNumArgs(interp, 1, objv, "cache option ?arg?");
       139591  +      return TCL_ERROR;
       139592  +    }
       139593  +    subCmd = Tcl_GetStringFromObj( objv[2], 0 );
       139594  +    if( *subCmd=='f' && strcmp(subCmd,"flush")==0 ){
       139595  +      if( objc!=3 ){
       139596  +        Tcl_WrongNumArgs(interp, 2, objv, "flush");
       139597  +        return TCL_ERROR;
       139598  +      }else{
       139599  +        flushStmtCache( pDb );
       139600  +      }
       139601  +    }else if( *subCmd=='s' && strcmp(subCmd,"size")==0 ){
       139602  +      if( objc!=4 ){
       139603  +        Tcl_WrongNumArgs(interp, 2, objv, "size n");
       139604  +        return TCL_ERROR;
       139605  +      }else{
       139606  +        if( TCL_ERROR==Tcl_GetIntFromObj(interp, objv[3], &n) ){
       139607  +          Tcl_AppendResult( interp, "cannot convert \"", 
       139608  +               Tcl_GetStringFromObj(objv[3],0), "\" to integer", 0);
       139609  +          return TCL_ERROR;
       139610  +        }else{
       139611  +          if( n<0 ){
       139612  +            flushStmtCache( pDb );
       139613  +            n = 0;
       139614  +          }else if( n>MAX_PREPARED_STMTS ){
       139615  +            n = MAX_PREPARED_STMTS;
       139616  +          }
       139617  +          pDb->maxStmt = n;
       139618  +        }
       139619  +      }
       139620  +    }else{
       139621  +      Tcl_AppendResult( interp, "bad option \"", 
       139622  +          Tcl_GetStringFromObj(objv[2],0), "\": must be flush or size", 0);
       139623  +      return TCL_ERROR;
       139624  +    }
       139625  +    break;
       139626  +  }
       139627  +
       139628  +  /*     $db changes
       139629  +  **
       139630  +  ** Return the number of rows that were modified, inserted, or deleted by
       139631  +  ** the most recent INSERT, UPDATE or DELETE statement, not including 
       139632  +  ** any changes made by trigger programs.
       139633  +  */
       139634  +  case DB_CHANGES: {
       139635  +    Tcl_Obj *pResult;
       139636  +    if( objc!=2 ){
       139637  +      Tcl_WrongNumArgs(interp, 2, objv, "");
       139638  +      return TCL_ERROR;
       139639  +    }
       139640  +    pResult = Tcl_GetObjResult(interp);
       139641  +    Tcl_SetIntObj(pResult, sqlite3_changes(pDb->db));
       139642  +    break;
       139643  +  }
       139644  +
       139645  +  /*    $db close
       139646  +  **
       139647  +  ** Shutdown the database
       139648  +  */
       139649  +  case DB_CLOSE: {
       139650  +    Tcl_DeleteCommand(interp, Tcl_GetStringFromObj(objv[0], 0));
       139651  +    break;
       139652  +  }
       139653  +
       139654  +  /*
       139655  +  **     $db collate NAME SCRIPT
       139656  +  **
       139657  +  ** Create a new SQL collation function called NAME.  Whenever
       139658  +  ** that function is called, invoke SCRIPT to evaluate the function.
       139659  +  */
       139660  +  case DB_COLLATE: {
       139661  +    SqlCollate *pCollate;
       139662  +    char *zName;
       139663  +    char *zScript;
       139664  +    int nScript;
       139665  +    if( objc!=4 ){
       139666  +      Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT");
       139667  +      return TCL_ERROR;
       139668  +    }
       139669  +    zName = Tcl_GetStringFromObj(objv[2], 0);
       139670  +    zScript = Tcl_GetStringFromObj(objv[3], &nScript);
       139671  +    pCollate = (SqlCollate*)Tcl_Alloc( sizeof(*pCollate) + nScript + 1 );
       139672  +    if( pCollate==0 ) return TCL_ERROR;
       139673  +    pCollate->interp = interp;
       139674  +    pCollate->pNext = pDb->pCollate;
       139675  +    pCollate->zScript = (char*)&pCollate[1];
       139676  +    pDb->pCollate = pCollate;
       139677  +    memcpy(pCollate->zScript, zScript, nScript+1);
       139678  +    if( sqlite3_create_collation(pDb->db, zName, SQLITE_UTF8, 
       139679  +        pCollate, tclSqlCollate) ){
       139680  +      Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
       139681  +      return TCL_ERROR;
       139682  +    }
       139683  +    break;
       139684  +  }
       139685  +
       139686  +  /*
       139687  +  **     $db collation_needed SCRIPT
       139688  +  **
       139689  +  ** Create a new SQL collation function called NAME.  Whenever
       139690  +  ** that function is called, invoke SCRIPT to evaluate the function.
       139691  +  */
       139692  +  case DB_COLLATION_NEEDED: {
       139693  +    if( objc!=3 ){
       139694  +      Tcl_WrongNumArgs(interp, 2, objv, "SCRIPT");
       139695  +      return TCL_ERROR;
       139696  +    }
       139697  +    if( pDb->pCollateNeeded ){
       139698  +      Tcl_DecrRefCount(pDb->pCollateNeeded);
       139699  +    }
       139700  +    pDb->pCollateNeeded = Tcl_DuplicateObj(objv[2]);
       139701  +    Tcl_IncrRefCount(pDb->pCollateNeeded);
       139702  +    sqlite3_collation_needed(pDb->db, pDb, tclCollateNeeded);
       139703  +    break;
       139704  +  }
       139705  +
       139706  +  /*    $db commit_hook ?CALLBACK?
       139707  +  **
       139708  +  ** Invoke the given callback just before committing every SQL transaction.
       139709  +  ** If the callback throws an exception or returns non-zero, then the
       139710  +  ** transaction is aborted.  If CALLBACK is an empty string, the callback
       139711  +  ** is disabled.
       139712  +  */
       139713  +  case DB_COMMIT_HOOK: {
       139714  +    if( objc>3 ){
       139715  +      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
       139716  +      return TCL_ERROR;
       139717  +    }else if( objc==2 ){
       139718  +      if( pDb->zCommit ){
       139719  +        Tcl_AppendResult(interp, pDb->zCommit, 0);
       139720  +      }
       139721  +    }else{
       139722  +      char *zCommit;
       139723  +      int len;
       139724  +      if( pDb->zCommit ){
       139725  +        Tcl_Free(pDb->zCommit);
       139726  +      }
       139727  +      zCommit = Tcl_GetStringFromObj(objv[2], &len);
       139728  +      if( zCommit && len>0 ){
       139729  +        pDb->zCommit = Tcl_Alloc( len + 1 );
       139730  +        memcpy(pDb->zCommit, zCommit, len+1);
       139731  +      }else{
       139732  +        pDb->zCommit = 0;
       139733  +      }
       139734  +      if( pDb->zCommit ){
       139735  +        pDb->interp = interp;
       139736  +        sqlite3_commit_hook(pDb->db, DbCommitHandler, pDb);
       139737  +      }else{
       139738  +        sqlite3_commit_hook(pDb->db, 0, 0);
       139739  +      }
       139740  +    }
       139741  +    break;
       139742  +  }
       139743  +
       139744  +  /*    $db complete SQL
       139745  +  **
       139746  +  ** Return TRUE if SQL is a complete SQL statement.  Return FALSE if
       139747  +  ** additional lines of input are needed.  This is similar to the
       139748  +  ** built-in "info complete" command of Tcl.
       139749  +  */
       139750  +  case DB_COMPLETE: {
       139751  +#ifndef SQLITE_OMIT_COMPLETE
       139752  +    Tcl_Obj *pResult;
       139753  +    int isComplete;
       139754  +    if( objc!=3 ){
       139755  +      Tcl_WrongNumArgs(interp, 2, objv, "SQL");
       139756  +      return TCL_ERROR;
       139757  +    }
       139758  +    isComplete = sqlite3_complete( Tcl_GetStringFromObj(objv[2], 0) );
       139759  +    pResult = Tcl_GetObjResult(interp);
       139760  +    Tcl_SetBooleanObj(pResult, isComplete);
       139761  +#endif
       139762  +    break;
       139763  +  }
       139764  +
       139765  +  /*    $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR?
       139766  +  **
       139767  +  ** Copy data into table from filename, optionally using SEPARATOR
       139768  +  ** as column separators.  If a column contains a null string, or the
       139769  +  ** value of NULLINDICATOR, a NULL is inserted for the column.
       139770  +  ** conflict-algorithm is one of the sqlite conflict algorithms:
       139771  +  **    rollback, abort, fail, ignore, replace
       139772  +  ** On success, return the number of lines processed, not necessarily same
       139773  +  ** as 'db changes' due to conflict-algorithm selected.
       139774  +  **
       139775  +  ** This code is basically an implementation/enhancement of
       139776  +  ** the sqlite3 shell.c ".import" command.
       139777  +  **
       139778  +  ** This command usage is equivalent to the sqlite2.x COPY statement,
       139779  +  ** which imports file data into a table using the PostgreSQL COPY file format:
       139780  +  **   $db copy $conflit_algo $table_name $filename \t \\N
       139781  +  */
       139782  +  case DB_COPY: {
       139783  +    char *zTable;               /* Insert data into this table */
       139784  +    char *zFile;                /* The file from which to extract data */
       139785  +    char *zConflict;            /* The conflict algorithm to use */
       139786  +    sqlite3_stmt *pStmt;        /* A statement */
       139787  +    int nCol;                   /* Number of columns in the table */
       139788  +    int nByte;                  /* Number of bytes in an SQL string */
       139789  +    int i, j;                   /* Loop counters */
       139790  +    int nSep;                   /* Number of bytes in zSep[] */
       139791  +    int nNull;                  /* Number of bytes in zNull[] */
       139792  +    char *zSql;                 /* An SQL statement */
       139793  +    char *zLine;                /* A single line of input from the file */
       139794  +    char **azCol;               /* zLine[] broken up into columns */
       139795  +    char *zCommit;              /* How to commit changes */
       139796  +    FILE *in;                   /* The input file */
       139797  +    int lineno = 0;             /* Line number of input file */
       139798  +    char zLineNum[80];          /* Line number print buffer */
       139799  +    Tcl_Obj *pResult;           /* interp result */
       139800  +
       139801  +    char *zSep;
       139802  +    char *zNull;
       139803  +    if( objc<5 || objc>7 ){
       139804  +      Tcl_WrongNumArgs(interp, 2, objv, 
       139805  +         "CONFLICT-ALGORITHM TABLE FILENAME ?SEPARATOR? ?NULLINDICATOR?");
       139806  +      return TCL_ERROR;
       139807  +    }
       139808  +    if( objc>=6 ){
       139809  +      zSep = Tcl_GetStringFromObj(objv[5], 0);
       139810  +    }else{
       139811  +      zSep = "\t";
       139812  +    }
       139813  +    if( objc>=7 ){
       139814  +      zNull = Tcl_GetStringFromObj(objv[6], 0);
       139815  +    }else{
       139816  +      zNull = "";
       139817  +    }
       139818  +    zConflict = Tcl_GetStringFromObj(objv[2], 0);
       139819  +    zTable = Tcl_GetStringFromObj(objv[3], 0);
       139820  +    zFile = Tcl_GetStringFromObj(objv[4], 0);
       139821  +    nSep = strlen30(zSep);
       139822  +    nNull = strlen30(zNull);
       139823  +    if( nSep==0 ){
       139824  +      Tcl_AppendResult(interp,"Error: non-null separator required for copy",0);
       139825  +      return TCL_ERROR;
       139826  +    }
       139827  +    if(strcmp(zConflict, "rollback") != 0 &&
       139828  +       strcmp(zConflict, "abort"   ) != 0 &&
       139829  +       strcmp(zConflict, "fail"    ) != 0 &&
       139830  +       strcmp(zConflict, "ignore"  ) != 0 &&
       139831  +       strcmp(zConflict, "replace" ) != 0 ) {
       139832  +      Tcl_AppendResult(interp, "Error: \"", zConflict, 
       139833  +            "\", conflict-algorithm must be one of: rollback, "
       139834  +            "abort, fail, ignore, or replace", 0);
       139835  +      return TCL_ERROR;
       139836  +    }
       139837  +    zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
       139838  +    if( zSql==0 ){
       139839  +      Tcl_AppendResult(interp, "Error: no such table: ", zTable, 0);
       139840  +      return TCL_ERROR;
       139841  +    }
       139842  +    nByte = strlen30(zSql);
       139843  +    rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
       139844  +    sqlite3_free(zSql);
       139845  +    if( rc ){
       139846  +      Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0);
       139847  +      nCol = 0;
       139848  +    }else{
       139849  +      nCol = sqlite3_column_count(pStmt);
       139850  +    }
       139851  +    sqlite3_finalize(pStmt);
       139852  +    if( nCol==0 ) {
       139853  +      return TCL_ERROR;
       139854  +    }
       139855  +    zSql = malloc( nByte + 50 + nCol*2 );
       139856  +    if( zSql==0 ) {
       139857  +      Tcl_AppendResult(interp, "Error: can't malloc()", 0);
       139858  +      return TCL_ERROR;
       139859  +    }
       139860  +    sqlite3_snprintf(nByte+50, zSql, "INSERT OR %q INTO '%q' VALUES(?",
       139861  +         zConflict, zTable);
       139862  +    j = strlen30(zSql);
       139863  +    for(i=1; i<nCol; i++){
       139864  +      zSql[j++] = ',';
       139865  +      zSql[j++] = '?';
       139866  +    }
       139867  +    zSql[j++] = ')';
       139868  +    zSql[j] = 0;
       139869  +    rc = sqlite3_prepare(pDb->db, zSql, -1, &pStmt, 0);
       139870  +    free(zSql);
       139871  +    if( rc ){
       139872  +      Tcl_AppendResult(interp, "Error: ", sqlite3_errmsg(pDb->db), 0);
       139873  +      sqlite3_finalize(pStmt);
       139874  +      return TCL_ERROR;
       139875  +    }
       139876  +    in = fopen(zFile, "rb");
       139877  +    if( in==0 ){
       139878  +      Tcl_AppendResult(interp, "Error: cannot open file: ", zFile, NULL);
       139879  +      sqlite3_finalize(pStmt);
       139880  +      return TCL_ERROR;
       139881  +    }
       139882  +    azCol = malloc( sizeof(azCol[0])*(nCol+1) );
       139883  +    if( azCol==0 ) {
       139884  +      Tcl_AppendResult(interp, "Error: can't malloc()", 0);
       139885  +      fclose(in);
       139886  +      return TCL_ERROR;
       139887  +    }
       139888  +    (void)sqlite3_exec(pDb->db, "BEGIN", 0, 0, 0);
       139889  +    zCommit = "COMMIT";
       139890  +    while( (zLine = local_getline(0, in))!=0 ){
       139891  +      char *z;
       139892  +      lineno++;
       139893  +      azCol[0] = zLine;
       139894  +      for(i=0, z=zLine; *z; z++){
       139895  +        if( *z==zSep[0] && strncmp(z, zSep, nSep)==0 ){
       139896  +          *z = 0;
       139897  +          i++;
       139898  +          if( i<nCol ){
       139899  +            azCol[i] = &z[nSep];
       139900  +            z += nSep-1;
       139901  +          }
       139902  +        }
       139903  +      }
       139904  +      if( i+1!=nCol ){
       139905  +        char *zErr;
       139906  +        int nErr = strlen30(zFile) + 200;
       139907  +        zErr = malloc(nErr);
       139908  +        if( zErr ){
       139909  +          sqlite3_snprintf(nErr, zErr,
       139910  +             "Error: %s line %d: expected %d columns of data but found %d",
       139911  +             zFile, lineno, nCol, i+1);
       139912  +          Tcl_AppendResult(interp, zErr, 0);
       139913  +          free(zErr);
       139914  +        }
       139915  +        zCommit = "ROLLBACK";
       139916  +        break;
       139917  +      }
       139918  +      for(i=0; i<nCol; i++){
       139919  +        /* check for null data, if so, bind as null */
       139920  +        if( (nNull>0 && strcmp(azCol[i], zNull)==0)
       139921  +          || strlen30(azCol[i])==0 
       139922  +        ){
       139923  +          sqlite3_bind_null(pStmt, i+1);
       139924  +        }else{
       139925  +          sqlite3_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
       139926  +        }
       139927  +      }
       139928  +      sqlite3_step(pStmt);
       139929  +      rc = sqlite3_reset(pStmt);
       139930  +      free(zLine);
       139931  +      if( rc!=SQLITE_OK ){
       139932  +        Tcl_AppendResult(interp,"Error: ", sqlite3_errmsg(pDb->db), 0);
       139933  +        zCommit = "ROLLBACK";
       139934  +        break;
       139935  +      }
       139936  +    }
       139937  +    free(azCol);
       139938  +    fclose(in);
       139939  +    sqlite3_finalize(pStmt);
       139940  +    (void)sqlite3_exec(pDb->db, zCommit, 0, 0, 0);
       139941  +
       139942  +    if( zCommit[0] == 'C' ){
       139943  +      /* success, set result as number of lines processed */
       139944  +      pResult = Tcl_GetObjResult(interp);
       139945  +      Tcl_SetIntObj(pResult, lineno);
       139946  +      rc = TCL_OK;
       139947  +    }else{
       139948  +      /* failure, append lineno where failed */
       139949  +      sqlite3_snprintf(sizeof(zLineNum), zLineNum,"%d",lineno);
       139950  +      Tcl_AppendResult(interp,", failed while processing line: ",zLineNum,0);
       139951  +      rc = TCL_ERROR;
       139952  +    }
       139953  +    break;
       139954  +  }
       139955  +
       139956  +  /*
       139957  +  **    $db enable_load_extension BOOLEAN
       139958  +  **
       139959  +  ** Turn the extension loading feature on or off.  It if off by
       139960  +  ** default.
       139961  +  */
       139962  +  case DB_ENABLE_LOAD_EXTENSION: {
       139963  +#ifndef SQLITE_OMIT_LOAD_EXTENSION
       139964  +    int onoff;
       139965  +    if( objc!=3 ){
       139966  +      Tcl_WrongNumArgs(interp, 2, objv, "BOOLEAN");
       139967  +      return TCL_ERROR;
       139968  +    }
       139969  +    if( Tcl_GetBooleanFromObj(interp, objv[2], &onoff) ){
       139970  +      return TCL_ERROR;
       139971  +    }
       139972  +    sqlite3_enable_load_extension(pDb->db, onoff);
       139973  +    break;
       139974  +#else
       139975  +    Tcl_AppendResult(interp, "extension loading is turned off at compile-time",
       139976  +                     0);
       139977  +    return TCL_ERROR;
       139978  +#endif
       139979  +  }
       139980  +
       139981  +  /*
       139982  +  **    $db errorcode
       139983  +  **
       139984  +  ** Return the numeric error code that was returned by the most recent
       139985  +  ** call to sqlite3_exec().
       139986  +  */
       139987  +  case DB_ERRORCODE: {
       139988  +    Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_errcode(pDb->db)));
       139989  +    break;
       139990  +  }
       139991  +
       139992  +  /*
       139993  +  **    $db exists $sql
       139994  +  **    $db onecolumn $sql
       139995  +  **
       139996  +  ** The onecolumn method is the equivalent of:
       139997  +  **     lindex [$db eval $sql] 0
       139998  +  */
       139999  +  case DB_EXISTS: 
       140000  +  case DB_ONECOLUMN: {
       140001  +    DbEvalContext sEval;
       140002  +    if( objc!=3 ){
       140003  +      Tcl_WrongNumArgs(interp, 2, objv, "SQL");
       140004  +      return TCL_ERROR;
       140005  +    }
       140006  +
       140007  +    dbEvalInit(&sEval, pDb, objv[2], 0);
       140008  +    rc = dbEvalStep(&sEval);
       140009  +    if( choice==DB_ONECOLUMN ){
       140010  +      if( rc==TCL_OK ){
       140011  +        Tcl_SetObjResult(interp, dbEvalColumnValue(&sEval, 0));
       140012  +      }else if( rc==TCL_BREAK ){
       140013  +        Tcl_ResetResult(interp);
       140014  +      }
       140015  +    }else if( rc==TCL_BREAK || rc==TCL_OK ){
       140016  +      Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc==TCL_OK));
       140017  +    }
       140018  +    dbEvalFinalize(&sEval);
       140019  +
       140020  +    if( rc==TCL_BREAK ){
       140021  +      rc = TCL_OK;
       140022  +    }
       140023  +    break;
       140024  +  }
       140025  +   
       140026  +  /*
       140027  +  **    $db eval $sql ?array? ?{  ...code... }?
       140028  +  **
       140029  +  ** The SQL statement in $sql is evaluated.  For each row, the values are
       140030  +  ** placed in elements of the array named "array" and ...code... is executed.
       140031  +  ** If "array" and "code" are omitted, then no callback is every invoked.
       140032  +  ** If "array" is an empty string, then the values are placed in variables
       140033  +  ** that have the same name as the fields extracted by the query.
       140034  +  */
       140035  +  case DB_EVAL: {
       140036  +    if( objc<3 || objc>5 ){
       140037  +      Tcl_WrongNumArgs(interp, 2, objv, "SQL ?ARRAY-NAME? ?SCRIPT?");
       140038  +      return TCL_ERROR;
       140039  +    }
       140040  +
       140041  +    if( objc==3 ){
       140042  +      DbEvalContext sEval;
       140043  +      Tcl_Obj *pRet = Tcl_NewObj();
       140044  +      Tcl_IncrRefCount(pRet);
       140045  +      dbEvalInit(&sEval, pDb, objv[2], 0);
       140046  +      while( TCL_OK==(rc = dbEvalStep(&sEval)) ){
       140047  +        int i;
       140048  +        int nCol;
       140049  +        dbEvalRowInfo(&sEval, &nCol, 0);
       140050  +        for(i=0; i<nCol; i++){
       140051  +          Tcl_ListObjAppendElement(interp, pRet, dbEvalColumnValue(&sEval, i));
       140052  +        }
       140053  +      }
       140054  +      dbEvalFinalize(&sEval);
       140055  +      if( rc==TCL_BREAK ){
       140056  +        Tcl_SetObjResult(interp, pRet);
       140057  +        rc = TCL_OK;
       140058  +      }
       140059  +      Tcl_DecrRefCount(pRet);
       140060  +    }else{
       140061  +      ClientData cd[2];
       140062  +      DbEvalContext *p;
       140063  +      Tcl_Obj *pArray = 0;
       140064  +      Tcl_Obj *pScript;
       140065  +
       140066  +      if( objc==5 && *(char *)Tcl_GetString(objv[3]) ){
       140067  +        pArray = objv[3];
       140068  +      }
       140069  +      pScript = objv[objc-1];
       140070  +      Tcl_IncrRefCount(pScript);
       140071  +      
       140072  +      p = (DbEvalContext *)Tcl_Alloc(sizeof(DbEvalContext));
       140073  +      dbEvalInit(p, pDb, objv[2], pArray);
       140074  +
       140075  +      cd[0] = (void *)p;
       140076  +      cd[1] = (void *)pScript;
       140077  +      rc = DbEvalNextCmd(cd, interp, TCL_OK);
       140078  +    }
       140079  +    break;
       140080  +  }
       140081  +
       140082  +  /*
       140083  +  **     $db function NAME [-argcount N] SCRIPT
       140084  +  **
       140085  +  ** Create a new SQL function called NAME.  Whenever that function is
       140086  +  ** called, invoke SCRIPT to evaluate the function.
       140087  +  */
       140088  +  case DB_FUNCTION: {
       140089  +    SqlFunc *pFunc;
       140090  +    Tcl_Obj *pScript;
       140091  +    char *zName;
       140092  +    int nArg = -1;
       140093  +    if( objc==6 ){
       140094  +      const char *z = Tcl_GetString(objv[3]);
       140095  +      int n = strlen30(z);
       140096  +      if( n>2 && strncmp(z, "-argcount",n)==0 ){
       140097  +        if( Tcl_GetIntFromObj(interp, objv[4], &nArg) ) return TCL_ERROR;
       140098  +        if( nArg<0 ){
       140099  +          Tcl_AppendResult(interp, "number of arguments must be non-negative",
       140100  +                           (char*)0);
       140101  +          return TCL_ERROR;
       140102  +        }
       140103  +      }
       140104  +      pScript = objv[5];
       140105  +    }else if( objc!=4 ){
       140106  +      Tcl_WrongNumArgs(interp, 2, objv, "NAME [-argcount N] SCRIPT");
       140107  +      return TCL_ERROR;
       140108  +    }else{
       140109  +      pScript = objv[3];
       140110  +    }
       140111  +    zName = Tcl_GetStringFromObj(objv[2], 0);
       140112  +    pFunc = findSqlFunc(pDb, zName);
       140113  +    if( pFunc==0 ) return TCL_ERROR;
       140114  +    if( pFunc->pScript ){
       140115  +      Tcl_DecrRefCount(pFunc->pScript);
       140116  +    }
       140117  +    pFunc->pScript = pScript;
       140118  +    Tcl_IncrRefCount(pScript);
       140119  +    pFunc->useEvalObjv = safeToUseEvalObjv(interp, pScript);
       140120  +    rc = sqlite3_create_function(pDb->db, zName, nArg, SQLITE_UTF8,
       140121  +        pFunc, tclSqlFunc, 0, 0);
       140122  +    if( rc!=SQLITE_OK ){
       140123  +      rc = TCL_ERROR;
       140124  +      Tcl_SetResult(interp, (char *)sqlite3_errmsg(pDb->db), TCL_VOLATILE);
       140125  +    }
       140126  +    break;
       140127  +  }
       140128  +
       140129  +  /*
       140130  +  **     $db incrblob ?-readonly? ?DB? TABLE COLUMN ROWID
       140131  +  */
       140132  +  case DB_INCRBLOB: {
       140133  +#ifdef SQLITE_OMIT_INCRBLOB
       140134  +    Tcl_AppendResult(interp, "incrblob not available in this build", 0);
       140135  +    return TCL_ERROR;
       140136  +#else
       140137  +    int isReadonly = 0;
       140138  +    const char *zDb = "main";
       140139  +    const char *zTable;
       140140  +    const char *zColumn;
       140141  +    Tcl_WideInt iRow;
       140142  +
       140143  +    /* Check for the -readonly option */
       140144  +    if( objc>3 && strcmp(Tcl_GetString(objv[2]), "-readonly")==0 ){
       140145  +      isReadonly = 1;
       140146  +    }
       140147  +
       140148  +    if( objc!=(5+isReadonly) && objc!=(6+isReadonly) ){
       140149  +      Tcl_WrongNumArgs(interp, 2, objv, "?-readonly? ?DB? TABLE COLUMN ROWID");
       140150  +      return TCL_ERROR;
       140151  +    }
       140152  +
       140153  +    if( objc==(6+isReadonly) ){
       140154  +      zDb = Tcl_GetString(objv[2]);
       140155  +    }
       140156  +    zTable = Tcl_GetString(objv[objc-3]);
       140157  +    zColumn = Tcl_GetString(objv[objc-2]);
       140158  +    rc = Tcl_GetWideIntFromObj(interp, objv[objc-1], &iRow);
       140159  +
       140160  +    if( rc==TCL_OK ){
       140161  +      rc = createIncrblobChannel(
       140162  +          interp, pDb, zDb, zTable, zColumn, iRow, isReadonly
       140163  +      );
       140164  +    }
       140165  +#endif
       140166  +    break;
       140167  +  }
       140168  +
       140169  +  /*
       140170  +  **     $db interrupt
       140171  +  **
       140172  +  ** Interrupt the execution of the inner-most SQL interpreter.  This
       140173  +  ** causes the SQL statement to return an error of SQLITE_INTERRUPT.
       140174  +  */
       140175  +  case DB_INTERRUPT: {
       140176  +    sqlite3_interrupt(pDb->db);
       140177  +    break;
       140178  +  }
       140179  +
       140180  +  /*
       140181  +  **     $db nullvalue ?STRING?
       140182  +  **
       140183  +  ** Change text used when a NULL comes back from the database. If ?STRING?
       140184  +  ** is not present, then the current string used for NULL is returned.
       140185  +  ** If STRING is present, then STRING is returned.
       140186  +  **
       140187  +  */
       140188  +  case DB_NULLVALUE: {
       140189  +    if( objc!=2 && objc!=3 ){
       140190  +      Tcl_WrongNumArgs(interp, 2, objv, "NULLVALUE");
       140191  +      return TCL_ERROR;
       140192  +    }
       140193  +    if( objc==3 ){
       140194  +      int len;
       140195  +      char *zNull = Tcl_GetStringFromObj(objv[2], &len);
       140196  +      if( pDb->zNull ){
       140197  +        Tcl_Free(pDb->zNull);
       140198  +      }
       140199  +      if( zNull && len>0 ){
       140200  +        pDb->zNull = Tcl_Alloc( len + 1 );
       140201  +        memcpy(pDb->zNull, zNull, len);
       140202  +        pDb->zNull[len] = '\0';
       140203  +      }else{
       140204  +        pDb->zNull = 0;
       140205  +      }
       140206  +    }
       140207  +    Tcl_SetObjResult(interp, Tcl_NewStringObj(pDb->zNull, -1));
       140208  +    break;
       140209  +  }
       140210  +
       140211  +  /*
       140212  +  **     $db last_insert_rowid 
       140213  +  **
       140214  +  ** Return an integer which is the ROWID for the most recent insert.
       140215  +  */
       140216  +  case DB_LAST_INSERT_ROWID: {
       140217  +    Tcl_Obj *pResult;
       140218  +    Tcl_WideInt rowid;
       140219  +    if( objc!=2 ){
       140220  +      Tcl_WrongNumArgs(interp, 2, objv, "");
       140221  +      return TCL_ERROR;
       140222  +    }
       140223  +    rowid = sqlite3_last_insert_rowid(pDb->db);
       140224  +    pResult = Tcl_GetObjResult(interp);
       140225  +    Tcl_SetWideIntObj(pResult, rowid);
       140226  +    break;
       140227  +  }
       140228  +
       140229  +  /*
       140230  +  ** The DB_ONECOLUMN method is implemented together with DB_EXISTS.
       140231  +  */
       140232  +
       140233  +  /*    $db progress ?N CALLBACK?
       140234  +  ** 
       140235  +  ** Invoke the given callback every N virtual machine opcodes while executing
       140236  +  ** queries.
       140237  +  */
       140238  +  case DB_PROGRESS: {
       140239  +    if( objc==2 ){
       140240  +      if( pDb->zProgress ){
       140241  +        Tcl_AppendResult(interp, pDb->zProgress, 0);
       140242  +      }
       140243  +    }else if( objc==4 ){
       140244  +      char *zProgress;
       140245  +      int len;
       140246  +      int N;
       140247  +      if( TCL_OK!=Tcl_GetIntFromObj(interp, objv[2], &N) ){
       140248  +        return TCL_ERROR;
       140249  +      };
       140250  +      if( pDb->zProgress ){
       140251  +        Tcl_Free(pDb->zProgress);
       140252  +      }
       140253  +      zProgress = Tcl_GetStringFromObj(objv[3], &len);
       140254  +      if( zProgress && len>0 ){
       140255  +        pDb->zProgress = Tcl_Alloc( len + 1 );
       140256  +        memcpy(pDb->zProgress, zProgress, len+1);
       140257  +      }else{
       140258  +        pDb->zProgress = 0;
       140259  +      }
       140260  +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
       140261  +      if( pDb->zProgress ){
       140262  +        pDb->interp = interp;
       140263  +        sqlite3_progress_handler(pDb->db, N, DbProgressHandler, pDb);
       140264  +      }else{
       140265  +        sqlite3_progress_handler(pDb->db, 0, 0, 0);
       140266  +      }
       140267  +#endif
       140268  +    }else{
       140269  +      Tcl_WrongNumArgs(interp, 2, objv, "N CALLBACK");
       140270  +      return TCL_ERROR;
       140271  +    }
       140272  +    break;
       140273  +  }
       140274  +
       140275  +  /*    $db profile ?CALLBACK?
       140276  +  **
       140277  +  ** Make arrangements to invoke the CALLBACK routine after each SQL statement
       140278  +  ** that has run.  The text of the SQL and the amount of elapse time are
       140279  +  ** appended to CALLBACK before the script is run.
       140280  +  */
       140281  +  case DB_PROFILE: {
       140282  +    if( objc>3 ){
       140283  +      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
       140284  +      return TCL_ERROR;
       140285  +    }else if( objc==2 ){
       140286  +      if( pDb->zProfile ){
       140287  +        Tcl_AppendResult(interp, pDb->zProfile, 0);
       140288  +      }
       140289  +    }else{
       140290  +      char *zProfile;
       140291  +      int len;
       140292  +      if( pDb->zProfile ){
       140293  +        Tcl_Free(pDb->zProfile);
       140294  +      }
       140295  +      zProfile = Tcl_GetStringFromObj(objv[2], &len);
       140296  +      if( zProfile && len>0 ){
       140297  +        pDb->zProfile = Tcl_Alloc( len + 1 );
       140298  +        memcpy(pDb->zProfile, zProfile, len+1);
       140299  +      }else{
       140300  +        pDb->zProfile = 0;
       140301  +      }
       140302  +#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
       140303  +      if( pDb->zProfile ){
       140304  +        pDb->interp = interp;
       140305  +        sqlite3_profile(pDb->db, DbProfileHandler, pDb);
       140306  +      }else{
       140307  +        sqlite3_profile(pDb->db, 0, 0);
       140308  +      }
       140309  +#endif
       140310  +    }
       140311  +    break;
       140312  +  }
       140313  +
       140314  +  /*
       140315  +  **     $db rekey KEY
       140316  +  **
       140317  +  ** Change the encryption key on the currently open database.
       140318  +  */
       140319  +  case DB_REKEY: {
       140320  +#ifdef SQLITE_HAS_CODEC
       140321  +    int nKey;
       140322  +    void *pKey;
       140323  +#endif
       140324  +    if( objc!=3 ){
       140325  +      Tcl_WrongNumArgs(interp, 2, objv, "KEY");
       140326  +      return TCL_ERROR;
       140327  +    }
       140328  +#ifdef SQLITE_HAS_CODEC
       140329  +    pKey = Tcl_GetByteArrayFromObj(objv[2], &nKey);
       140330  +    rc = sqlite3_rekey(pDb->db, pKey, nKey);
       140331  +    if( rc ){
       140332  +      Tcl_AppendResult(interp, sqlite3_errstr(rc), 0);
       140333  +      rc = TCL_ERROR;
       140334  +    }
       140335  +#endif
       140336  +    break;
       140337  +  }
       140338  +
       140339  +  /*    $db restore ?DATABASE? FILENAME
       140340  +  **
       140341  +  ** Open a database file named FILENAME.  Transfer the content 
       140342  +  ** of FILENAME into the local database DATABASE (default: "main").
       140343  +  */
       140344  +  case DB_RESTORE: {
       140345  +    const char *zSrcFile;
       140346  +    const char *zDestDb;
       140347  +    sqlite3 *pSrc;
       140348  +    sqlite3_backup *pBackup;
       140349  +    int nTimeout = 0;
       140350  +
       140351  +    if( objc==3 ){
       140352  +      zDestDb = "main";
       140353  +      zSrcFile = Tcl_GetString(objv[2]);
       140354  +    }else if( objc==4 ){
       140355  +      zDestDb = Tcl_GetString(objv[2]);
       140356  +      zSrcFile = Tcl_GetString(objv[3]);
       140357  +    }else{
       140358  +      Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
       140359  +      return TCL_ERROR;
       140360  +    }
       140361  +    rc = sqlite3_open_v2(zSrcFile, &pSrc, SQLITE_OPEN_READONLY, 0);
       140362  +    if( rc!=SQLITE_OK ){
       140363  +      Tcl_AppendResult(interp, "cannot open source database: ",
       140364  +           sqlite3_errmsg(pSrc), (char*)0);
       140365  +      sqlite3_close(pSrc);
       140366  +      return TCL_ERROR;
       140367  +    }
       140368  +    pBackup = sqlite3_backup_init(pDb->db, zDestDb, pSrc, "main");
       140369  +    if( pBackup==0 ){
       140370  +      Tcl_AppendResult(interp, "restore failed: ",
       140371  +           sqlite3_errmsg(pDb->db), (char*)0);
       140372  +      sqlite3_close(pSrc);
       140373  +      return TCL_ERROR;
       140374  +    }
       140375  +    while( (rc = sqlite3_backup_step(pBackup,100))==SQLITE_OK
       140376  +              || rc==SQLITE_BUSY ){
       140377  +      if( rc==SQLITE_BUSY ){
       140378  +        if( nTimeout++ >= 3 ) break;
       140379  +        sqlite3_sleep(100);
       140380  +      }
       140381  +    }
       140382  +    sqlite3_backup_finish(pBackup);
       140383  +    if( rc==SQLITE_DONE ){
       140384  +      rc = TCL_OK;
       140385  +    }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
       140386  +      Tcl_AppendResult(interp, "restore failed: source database busy",
       140387  +                       (char*)0);
       140388  +      rc = TCL_ERROR;
       140389  +    }else{
       140390  +      Tcl_AppendResult(interp, "restore failed: ",
       140391  +           sqlite3_errmsg(pDb->db), (char*)0);
       140392  +      rc = TCL_ERROR;
       140393  +    }
       140394  +    sqlite3_close(pSrc);
       140395  +    break;
       140396  +  }
       140397  +
       140398  +  /*
       140399  +  **     $db status (step|sort|autoindex)
       140400  +  **
       140401  +  ** Display SQLITE_STMTSTATUS_FULLSCAN_STEP or 
       140402  +  ** SQLITE_STMTSTATUS_SORT for the most recent eval.
       140403  +  */
       140404  +  case DB_STATUS: {
       140405  +    int v;
       140406  +    const char *zOp;
       140407  +    if( objc!=3 ){
       140408  +      Tcl_WrongNumArgs(interp, 2, objv, "(step|sort|autoindex)");
       140409  +      return TCL_ERROR;
       140410  +    }
       140411  +    zOp = Tcl_GetString(objv[2]);
       140412  +    if( strcmp(zOp, "step")==0 ){
       140413  +      v = pDb->nStep;
       140414  +    }else if( strcmp(zOp, "sort")==0 ){
       140415  +      v = pDb->nSort;
       140416  +    }else if( strcmp(zOp, "autoindex")==0 ){
       140417  +      v = pDb->nIndex;
       140418  +    }else{
       140419  +      Tcl_AppendResult(interp, 
       140420  +            "bad argument: should be autoindex, step, or sort", 
       140421  +            (char*)0);
       140422  +      return TCL_ERROR;
       140423  +    }
       140424  +    Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
       140425  +    break;
       140426  +  }
       140427  +  
       140428  +  /*
       140429  +  **     $db timeout MILLESECONDS
       140430  +  **
       140431  +  ** Delay for the number of milliseconds specified when a file is locked.
       140432  +  */
       140433  +  case DB_TIMEOUT: {
       140434  +    int ms;
       140435  +    if( objc!=3 ){
       140436  +      Tcl_WrongNumArgs(interp, 2, objv, "MILLISECONDS");
       140437  +      return TCL_ERROR;
       140438  +    }
       140439  +    if( Tcl_GetIntFromObj(interp, objv[2], &ms) ) return TCL_ERROR;
       140440  +    sqlite3_busy_timeout(pDb->db, ms);
       140441  +    break;
       140442  +  }
       140443  +  
       140444  +  /*
       140445  +  **     $db total_changes
       140446  +  **
       140447  +  ** Return the number of rows that were modified, inserted, or deleted 
       140448  +  ** since the database handle was created.
       140449  +  */
       140450  +  case DB_TOTAL_CHANGES: {
       140451  +    Tcl_Obj *pResult;
       140452  +    if( objc!=2 ){
       140453  +      Tcl_WrongNumArgs(interp, 2, objv, "");
       140454  +      return TCL_ERROR;
       140455  +    }
       140456  +    pResult = Tcl_GetObjResult(interp);
       140457  +    Tcl_SetIntObj(pResult, sqlite3_total_changes(pDb->db));
       140458  +    break;
       140459  +  }
       140460  +
       140461  +  /*    $db trace ?CALLBACK?
       140462  +  **
       140463  +  ** Make arrangements to invoke the CALLBACK routine for each SQL statement
       140464  +  ** that is executed.  The text of the SQL is appended to CALLBACK before
       140465  +  ** it is executed.
       140466  +  */
       140467  +  case DB_TRACE: {
       140468  +    if( objc>3 ){
       140469  +      Tcl_WrongNumArgs(interp, 2, objv, "?CALLBACK?");
       140470  +      return TCL_ERROR;
       140471  +    }else if( objc==2 ){
       140472  +      if( pDb->zTrace ){
       140473  +        Tcl_AppendResult(interp, pDb->zTrace, 0);
       140474  +      }
       140475  +    }else{
       140476  +      char *zTrace;
       140477  +      int len;
       140478  +      if( pDb->zTrace ){
       140479  +        Tcl_Free(pDb->zTrace);
       140480  +      }
       140481  +      zTrace = Tcl_GetStringFromObj(objv[2], &len);
       140482  +      if( zTrace && len>0 ){
       140483  +        pDb->zTrace = Tcl_Alloc( len + 1 );
       140484  +        memcpy(pDb->zTrace, zTrace, len+1);
       140485  +      }else{
       140486  +        pDb->zTrace = 0;
       140487  +      }
       140488  +#if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
       140489  +      if( pDb->zTrace ){
       140490  +        pDb->interp = interp;
       140491  +        sqlite3_trace(pDb->db, DbTraceHandler, pDb);
       140492  +      }else{
       140493  +        sqlite3_trace(pDb->db, 0, 0);
       140494  +      }
       140495  +#endif
       140496  +    }
       140497  +    break;
       140498  +  }
       140499  +
       140500  +  /*    $db transaction [-deferred|-immediate|-exclusive] SCRIPT
       140501  +  **
       140502  +  ** Start a new transaction (if we are not already in the midst of a
       140503  +  ** transaction) and execute the TCL script SCRIPT.  After SCRIPT
       140504  +  ** completes, either commit the transaction or roll it back if SCRIPT
       140505  +  ** throws an exception.  Or if no new transation was started, do nothing.
       140506  +  ** pass the exception on up the stack.
       140507  +  **
       140508  +  ** This command was inspired by Dave Thomas's talk on Ruby at the
       140509  +  ** 2005 O'Reilly Open Source Convention (OSCON).
       140510  +  */
       140511  +  case DB_TRANSACTION: {
       140512  +    Tcl_Obj *pScript;
       140513  +    const char *zBegin = "SAVEPOINT _tcl_transaction";
       140514  +    if( objc!=3 && objc!=4 ){
       140515  +      Tcl_WrongNumArgs(interp, 2, objv, "[TYPE] SCRIPT");
       140516  +      return TCL_ERROR;
       140517  +    }
       140518  +
       140519  +    if( pDb->nTransaction==0 && objc==4 ){
       140520  +      static const char *TTYPE_strs[] = {
       140521  +        "deferred",   "exclusive",  "immediate", 0
       140522  +      };
       140523  +      enum TTYPE_enum {
       140524  +        TTYPE_DEFERRED, TTYPE_EXCLUSIVE, TTYPE_IMMEDIATE
       140525  +      };
       140526  +      int ttype;
       140527  +      if( Tcl_GetIndexFromObj(interp, objv[2], TTYPE_strs, "transaction type",
       140528  +                              0, &ttype) ){
       140529  +        return TCL_ERROR;
       140530  +      }
       140531  +      switch( (enum TTYPE_enum)ttype ){
       140532  +        case TTYPE_DEFERRED:    /* no-op */;                 break;
       140533  +        case TTYPE_EXCLUSIVE:   zBegin = "BEGIN EXCLUSIVE";  break;
       140534  +        case TTYPE_IMMEDIATE:   zBegin = "BEGIN IMMEDIATE";  break;
       140535  +      }
       140536  +    }
       140537  +    pScript = objv[objc-1];
       140538  +
       140539  +    /* Run the SQLite BEGIN command to open a transaction or savepoint. */
       140540  +    pDb->disableAuth++;
       140541  +    rc = sqlite3_exec(pDb->db, zBegin, 0, 0, 0);
       140542  +    pDb->disableAuth--;
       140543  +    if( rc!=SQLITE_OK ){
       140544  +      Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
       140545  +      return TCL_ERROR;
       140546  +    }
       140547  +    pDb->nTransaction++;
       140548  +
       140549  +    /* If using NRE, schedule a callback to invoke the script pScript, then
       140550  +    ** a second callback to commit (or rollback) the transaction or savepoint
       140551  +    ** opened above. If not using NRE, evaluate the script directly, then
       140552  +    ** call function DbTransPostCmd() to commit (or rollback) the transaction 
       140553  +    ** or savepoint.  */
       140554  +    if( DbUseNre() ){
       140555  +      Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
       140556  +      Tcl_NREvalObj(interp, pScript, 0);
       140557  +    }else{
       140558  +      rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0));
       140559  +    }
       140560  +    break;
       140561  +  }
       140562  +
       140563  +  /*
       140564  +  **    $db unlock_notify ?script?
       140565  +  */
       140566  +  case DB_UNLOCK_NOTIFY: {
       140567  +#ifndef SQLITE_ENABLE_UNLOCK_NOTIFY
       140568  +    Tcl_AppendResult(interp, "unlock_notify not available in this build", 0);
       140569  +    rc = TCL_ERROR;
       140570  +#else
       140571  +    if( objc!=2 && objc!=3 ){
       140572  +      Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
       140573  +      rc = TCL_ERROR;
       140574  +    }else{
       140575  +      void (*xNotify)(void **, int) = 0;
       140576  +      void *pNotifyArg = 0;
       140577  +
       140578  +      if( pDb->pUnlockNotify ){
       140579  +        Tcl_DecrRefCount(pDb->pUnlockNotify);
       140580  +        pDb->pUnlockNotify = 0;
       140581  +      }
       140582  +  
       140583  +      if( objc==3 ){
       140584  +        xNotify = DbUnlockNotify;
       140585  +        pNotifyArg = (void *)pDb;
       140586  +        pDb->pUnlockNotify = objv[2];
       140587  +        Tcl_IncrRefCount(pDb->pUnlockNotify);
       140588  +      }
       140589  +  
       140590  +      if( sqlite3_unlock_notify(pDb->db, xNotify, pNotifyArg) ){
       140591  +        Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), 0);
       140592  +        rc = TCL_ERROR;
       140593  +      }
       140594  +    }
       140595  +#endif
       140596  +    break;
       140597  +  }
       140598  +
       140599  +  /*
       140600  +  **    $db wal_hook ?script?
       140601  +  **    $db update_hook ?script?
       140602  +  **    $db rollback_hook ?script?
       140603  +  */
       140604  +  case DB_WAL_HOOK: 
       140605  +  case DB_UPDATE_HOOK: 
       140606  +  case DB_ROLLBACK_HOOK: {
       140607  +
       140608  +    /* set ppHook to point at pUpdateHook or pRollbackHook, depending on 
       140609  +    ** whether [$db update_hook] or [$db rollback_hook] was invoked.
       140610  +    */
       140611  +    Tcl_Obj **ppHook; 
       140612  +    if( choice==DB_UPDATE_HOOK ){
       140613  +      ppHook = &pDb->pUpdateHook;
       140614  +    }else if( choice==DB_WAL_HOOK ){
       140615  +      ppHook = &pDb->pWalHook;
       140616  +    }else{
       140617  +      ppHook = &pDb->pRollbackHook;
       140618  +    }
       140619  +
       140620  +    if( objc!=2 && objc!=3 ){
       140621  +       Tcl_WrongNumArgs(interp, 2, objv, "?SCRIPT?");
       140622  +       return TCL_ERROR;
       140623  +    }
       140624  +    if( *ppHook ){
       140625  +      Tcl_SetObjResult(interp, *ppHook);
       140626  +      if( objc==3 ){
       140627  +        Tcl_DecrRefCount(*ppHook);
       140628  +        *ppHook = 0;
       140629  +      }
       140630  +    }
       140631  +    if( objc==3 ){
       140632  +      assert( !(*ppHook) );
       140633  +      if( Tcl_GetCharLength(objv[2])>0 ){
       140634  +        *ppHook = objv[2];
       140635  +        Tcl_IncrRefCount(*ppHook);
       140636  +      }
       140637  +    }
       140638  +
       140639  +    sqlite3_update_hook(pDb->db, (pDb->pUpdateHook?DbUpdateHandler:0), pDb);
       140640  +    sqlite3_rollback_hook(pDb->db,(pDb->pRollbackHook?DbRollbackHandler:0),pDb);
       140641  +    sqlite3_wal_hook(pDb->db,(pDb->pWalHook?DbWalHandler:0),pDb);
       140642  +
       140643  +    break;
       140644  +  }
       140645  +
       140646  +  /*    $db version
       140647  +  **
       140648  +  ** Return the version string for this database.
       140649  +  */
       140650  +  case DB_VERSION: {
       140651  +    Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
       140652  +    break;
       140653  +  }
       140654  +
       140655  +
       140656  +  } /* End of the SWITCH statement */
       140657  +  return rc;
       140658  +}
       140659  +
       140660  +#if SQLITE_TCL_NRE
       140661  +/*
       140662  +** Adaptor that provides an objCmd interface to the NRE-enabled
       140663  +** interface implementation.
       140664  +*/
       140665  +static int DbObjCmdAdaptor(
       140666  +  void *cd,
       140667  +  Tcl_Interp *interp,
       140668  +  int objc,
       140669  +  Tcl_Obj *const*objv
       140670  +){
       140671  +  return Tcl_NRCallObjProc(interp, DbObjCmd, cd, objc, objv);
       140672  +}
       140673  +#endif /* SQLITE_TCL_NRE */
       140674  +
       140675  +/*
       140676  +**   sqlite3 DBNAME FILENAME ?-vfs VFSNAME? ?-key KEY? ?-readonly BOOLEAN?
       140677  +**                           ?-create BOOLEAN? ?-nomutex BOOLEAN?
       140678  +**
       140679  +** This is the main Tcl command.  When the "sqlite" Tcl command is
       140680  +** invoked, this routine runs to process that command.
       140681  +**
       140682  +** The first argument, DBNAME, is an arbitrary name for a new
       140683  +** database connection.  This command creates a new command named
       140684  +** DBNAME that is used to control that connection.  The database
       140685  +** connection is deleted when the DBNAME command is deleted.
       140686  +**
       140687  +** The second argument is the name of the database file.
       140688  +**
       140689  +*/
       140690  +static int DbMain(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
       140691  +  SqliteDb *p;
       140692  +  const char *zArg;
       140693  +  char *zErrMsg;
       140694  +  int i;
       140695  +  const char *zFile;
       140696  +  const char *zVfs = 0;
       140697  +  int flags;
       140698  +  Tcl_DString translatedFilename;
       140699  +#ifdef SQLITE_HAS_CODEC
       140700  +  void *pKey = 0;
       140701  +  int nKey = 0;
       140702  +#endif
       140703  +  int rc;
       140704  +
       140705  +  /* In normal use, each TCL interpreter runs in a single thread.  So
       140706  +  ** by default, we can turn of mutexing on SQLite database connections.
       140707  +  ** However, for testing purposes it is useful to have mutexes turned
       140708  +  ** on.  So, by default, mutexes default off.  But if compiled with
       140709  +  ** SQLITE_TCL_DEFAULT_FULLMUTEX then mutexes default on.
       140710  +  */
       140711  +#ifdef SQLITE_TCL_DEFAULT_FULLMUTEX
       140712  +  flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX;
       140713  +#else
       140714  +  flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX;
       140715  +#endif
       140716  +
       140717  +  if( objc==2 ){
       140718  +    zArg = Tcl_GetStringFromObj(objv[1], 0);
       140719  +    if( strcmp(zArg,"-version")==0 ){
       140720  +      Tcl_AppendResult(interp,sqlite3_version,0);
       140721  +      return TCL_OK;
       140722  +    }
       140723  +    if( strcmp(zArg,"-has-codec")==0 ){
       140724  +#ifdef SQLITE_HAS_CODEC
       140725  +      Tcl_AppendResult(interp,"1",0);
       140726  +#else
       140727  +      Tcl_AppendResult(interp,"0",0);
       140728  +#endif
       140729  +      return TCL_OK;
       140730  +    }
       140731  +  }
       140732  +  for(i=3; i+1<objc; i+=2){
       140733  +    zArg = Tcl_GetString(objv[i]);
       140734  +    if( strcmp(zArg,"-key")==0 ){
       140735  +#ifdef SQLITE_HAS_CODEC
       140736  +      pKey = Tcl_GetByteArrayFromObj(objv[i+1], &nKey);
       140737  +#endif
       140738  +    }else if( strcmp(zArg, "-vfs")==0 ){
       140739  +      zVfs = Tcl_GetString(objv[i+1]);
       140740  +    }else if( strcmp(zArg, "-readonly")==0 ){
       140741  +      int b;
       140742  +      if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
       140743  +      if( b ){
       140744  +        flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
       140745  +        flags |= SQLITE_OPEN_READONLY;
       140746  +      }else{
       140747  +        flags &= ~SQLITE_OPEN_READONLY;
       140748  +        flags |= SQLITE_OPEN_READWRITE;
       140749  +      }
       140750  +    }else if( strcmp(zArg, "-create")==0 ){
       140751  +      int b;
       140752  +      if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
       140753  +      if( b && (flags & SQLITE_OPEN_READONLY)==0 ){
       140754  +        flags |= SQLITE_OPEN_CREATE;
       140755  +      }else{
       140756  +        flags &= ~SQLITE_OPEN_CREATE;
       140757  +      }
       140758  +    }else if( strcmp(zArg, "-nomutex")==0 ){
       140759  +      int b;
       140760  +      if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
       140761  +      if( b ){
       140762  +        flags |= SQLITE_OPEN_NOMUTEX;
       140763  +        flags &= ~SQLITE_OPEN_FULLMUTEX;
       140764  +      }else{
       140765  +        flags &= ~SQLITE_OPEN_NOMUTEX;
       140766  +      }
       140767  +    }else if( strcmp(zArg, "-fullmutex")==0 ){
       140768  +      int b;
       140769  +      if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
       140770  +      if( b ){
       140771  +        flags |= SQLITE_OPEN_FULLMUTEX;
       140772  +        flags &= ~SQLITE_OPEN_NOMUTEX;
       140773  +      }else{
       140774  +        flags &= ~SQLITE_OPEN_FULLMUTEX;
       140775  +      }
       140776  +    }else if( strcmp(zArg, "-uri")==0 ){
       140777  +      int b;
       140778  +      if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
       140779  +      if( b ){
       140780  +        flags |= SQLITE_OPEN_URI;
       140781  +      }else{
       140782  +        flags &= ~SQLITE_OPEN_URI;
       140783  +      }
       140784  +    }else{
       140785  +      Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0);
       140786  +      return TCL_ERROR;
       140787  +    }
       140788  +  }
       140789  +  if( objc<3 || (objc&1)!=1 ){
       140790  +    Tcl_WrongNumArgs(interp, 1, objv, 
       140791  +      "HANDLE FILENAME ?-vfs VFSNAME? ?-readonly BOOLEAN? ?-create BOOLEAN?"
       140792  +      " ?-nomutex BOOLEAN? ?-fullmutex BOOLEAN? ?-uri BOOLEAN?"
       140793  +#ifdef SQLITE_HAS_CODEC
       140794  +      " ?-key CODECKEY?"
       140795  +#endif
       140796  +    );
       140797  +    return TCL_ERROR;
       140798  +  }
       140799  +  zErrMsg = 0;
       140800  +  p = (SqliteDb*)Tcl_Alloc( sizeof(*p) );
       140801  +  if( p==0 ){
       140802  +    Tcl_SetResult(interp, "malloc failed", TCL_STATIC);
       140803  +    return TCL_ERROR;
       140804  +  }
       140805  +  memset(p, 0, sizeof(*p));
       140806  +  zFile = Tcl_GetStringFromObj(objv[2], 0);
       140807  +  zFile = Tcl_TranslateFileName(interp, zFile, &translatedFilename);
       140808  +  rc = sqlite3_open_v2(zFile, &p->db, flags, zVfs);
       140809  +  Tcl_DStringFree(&translatedFilename);
       140810  +  if( p->db ){
       140811  +    if( SQLITE_OK!=sqlite3_errcode(p->db) ){
       140812  +      zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(p->db));
       140813  +      sqlite3_close(p->db);
       140814  +      p->db = 0;
       140815  +    }
       140816  +  }else{
       140817  +    zErrMsg = sqlite3_mprintf("%s", sqlite3_errstr(rc));
       140818  +  }
       140819  +#ifdef SQLITE_HAS_CODEC
       140820  +  if( p->db ){
       140821  +    sqlite3_key(p->db, pKey, nKey);
       140822  +  }
       140823  +#endif
       140824  +  if( p->db==0 ){
       140825  +    Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
       140826  +    Tcl_Free((char*)p);
       140827  +    sqlite3_free(zErrMsg);
       140828  +    return TCL_ERROR;
       140829  +  }
       140830  +  p->maxStmt = NUM_PREPARED_STMTS;
       140831  +  p->interp = interp;
       140832  +  zArg = Tcl_GetStringFromObj(objv[1], 0);
       140833  +  if( DbUseNre() ){
       140834  +    Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd,
       140835  +                        (char*)p, DbDeleteCmd);
       140836  +  }else{
       140837  +    Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);
       140838  +  }
       140839  +  return TCL_OK;
       140840  +}
       140841  +
       140842  +/*
       140843  +** Provide a dummy Tcl_InitStubs if we are using this as a static
       140844  +** library.
       140845  +*/
       140846  +#ifndef USE_TCL_STUBS
       140847  +# undef  Tcl_InitStubs
       140848  +# define Tcl_InitStubs(a,b,c)
       140849  +#endif
       140850  +
       140851  +/*
       140852  +** Make sure we have a PACKAGE_VERSION macro defined.  This will be
       140853  +** defined automatically by the TEA makefile.  But other makefiles
       140854  +** do not define it.
       140855  +*/
       140856  +#ifndef PACKAGE_VERSION
       140857  +# define PACKAGE_VERSION SQLITE_VERSION
       140858  +#endif
       140859  +
       140860  +/*
       140861  +** Initialize this module.
       140862  +**
       140863  +** This Tcl module contains only a single new Tcl command named "sqlite".
       140864  +** (Hence there is no namespace.  There is no point in using a namespace
       140865  +** if the extension only supplies one new name!)  The "sqlite" command is
       140866  +** used to open a new SQLite database.  See the DbMain() routine above
       140867  +** for additional information.
       140868  +**
       140869  +** The EXTERN macros are required by TCL in order to work on windows.
       140870  +*/
       140871  +EXTERN int Sqlite3_Init(Tcl_Interp *interp){
       140872  +  Tcl_InitStubs(interp, "8.4", 0);
       140873  +  Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
       140874  +  Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION);
       140875  +
       140876  +#ifndef SQLITE_3_SUFFIX_ONLY
       140877  +  /* The "sqlite" alias is undocumented.  It is here only to support
       140878  +  ** legacy scripts.  All new scripts should use only the "sqlite3"
       140879  +  ** command.
       140880  +  */
       140881  +  Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
       140882  +#endif
       140883  +
       140884  +  return TCL_OK;
       140885  +}
       140886  +EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
       140887  +EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
       140888  +EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
       140889  +
       140890  +/* Because it accesses the file-system and uses persistent state, SQLite
       140891  +** is not considered appropriate for safe interpreters.  Hence, we deliberately
       140892  +** omit the _SafeInit() interfaces.
       140893  +*/
       140894  +
       140895  +#ifndef SQLITE_3_SUFFIX_ONLY
       140896  +int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
       140897  +int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
       140898  +int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
       140899  +int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
       140900  +#endif
       140901  +
       140902  +#ifdef TCLSH
       140903  +/*****************************************************************************
       140904  +** All of the code that follows is used to build standalone TCL interpreters
       140905  +** that are statically linked with SQLite.  Enable these by compiling
       140906  +** with -DTCLSH=n where n can be 1 or 2.  An n of 1 generates a standard
       140907  +** tclsh but with SQLite built in.  An n of 2 generates the SQLite space
       140908  +** analysis program.
       140909  +*/
       140910  +
       140911  +#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5)
       140912  +/*
       140913  + * This code implements the MD5 message-digest algorithm.
       140914  + * The algorithm is due to Ron Rivest.  This code was
       140915  + * written by Colin Plumb in 1993, no copyright is claimed.
       140916  + * This code is in the public domain; do with it what you wish.
       140917  + *
       140918  + * Equivalent code is available from RSA Data Security, Inc.
       140919  + * This code has been tested against that, and is equivalent,
       140920  + * except that you don't need to include two pages of legalese
       140921  + * with every copy.
       140922  + *
       140923  + * To compute the message digest of a chunk of bytes, declare an
       140924  + * MD5Context structure, pass it to MD5Init, call MD5Update as
       140925  + * needed on buffers full of bytes, and then call MD5Final, which
       140926  + * will fill a supplied 16-byte array with the digest.
       140927  + */
       140928  +
       140929  +/*
       140930  + * If compiled on a machine that doesn't have a 32-bit integer,
       140931  + * you just set "uint32" to the appropriate datatype for an
       140932  + * unsigned 32-bit integer.  For example:
       140933  + *
       140934  + *       cc -Duint32='unsigned long' md5.c
       140935  + *
       140936  + */
       140937  +#ifndef uint32
       140938  +#  define uint32 unsigned int
       140939  +#endif
       140940  +
       140941  +struct MD5Context {
       140942  +  int isInit;
       140943  +  uint32 buf[4];
       140944  +  uint32 bits[2];
       140945  +  unsigned char in[64];
       140946  +};
       140947  +typedef struct MD5Context MD5Context;
       140948  +
       140949  +/*
       140950  + * Note: this code is harmless on little-endian machines.
       140951  + */
       140952  +static void byteReverse (unsigned char *buf, unsigned longs){
       140953  +        uint32 t;
       140954  +        do {
       140955  +                t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
       140956  +                            ((unsigned)buf[1]<<8 | buf[0]);
       140957  +                *(uint32 *)buf = t;
       140958  +                buf += 4;
       140959  +        } while (--longs);
       140960  +}
       140961  +/* The four core functions - F1 is optimized somewhat */
       140962  +
       140963  +/* #define F1(x, y, z) (x & y | ~x & z) */
       140964  +#define F1(x, y, z) (z ^ (x & (y ^ z)))
       140965  +#define F2(x, y, z) F1(z, x, y)
       140966  +#define F3(x, y, z) (x ^ y ^ z)
       140967  +#define F4(x, y, z) (y ^ (x | ~z))
       140968  +
       140969  +/* This is the central step in the MD5 algorithm. */
       140970  +#define MD5STEP(f, w, x, y, z, data, s) \
       140971  +        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
       140972  +
       140973  +/*
       140974  + * The core of the MD5 algorithm, this alters an existing MD5 hash to
       140975  + * reflect the addition of 16 longwords of new data.  MD5Update blocks
       140976  + * the data and converts bytes into longwords for this routine.
       140977  + */
       140978  +static void MD5Transform(uint32 buf[4], const uint32 in[16]){
       140979  +        register uint32 a, b, c, d;
       140980  +
       140981  +        a = buf[0];
       140982  +        b = buf[1];
       140983  +        c = buf[2];
       140984  +        d = buf[3];
       140985  +
       140986  +        MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
       140987  +        MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
       140988  +        MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
       140989  +        MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
       140990  +        MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
       140991  +        MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
       140992  +        MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
       140993  +        MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
       140994  +        MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
       140995  +        MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
       140996  +        MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
       140997  +        MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
       140998  +        MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
       140999  +        MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
       141000  +        MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
       141001  +        MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
       141002  +
       141003  +        MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
       141004  +        MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
       141005  +        MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
       141006  +        MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
       141007  +        MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
       141008  +        MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
       141009  +        MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
       141010  +        MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
       141011  +        MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
       141012  +        MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
       141013  +        MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
       141014  +        MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
       141015  +        MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
       141016  +        MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
       141017  +        MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
       141018  +        MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
       141019  +
       141020  +        MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
       141021  +        MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
       141022  +        MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
       141023  +        MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
       141024  +        MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
       141025  +        MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
       141026  +        MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
       141027  +        MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
       141028  +        MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
       141029  +        MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
       141030  +        MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
       141031  +        MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
       141032  +        MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
       141033  +        MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
       141034  +        MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
       141035  +        MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
       141036  +
       141037  +        MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
       141038  +        MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
       141039  +        MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
       141040  +        MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
       141041  +        MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
       141042  +        MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
       141043  +        MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
       141044  +        MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
       141045  +        MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
       141046  +        MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
       141047  +        MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
       141048  +        MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
       141049  +        MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
       141050  +        MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
       141051  +        MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
       141052  +        MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
       141053  +
       141054  +        buf[0] += a;
       141055  +        buf[1] += b;
       141056  +        buf[2] += c;
       141057  +        buf[3] += d;
       141058  +}
       141059  +
       141060  +/*
       141061  + * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
       141062  + * initialization constants.
       141063  + */
       141064  +static void MD5Init(MD5Context *ctx){
       141065  +        ctx->isInit = 1;
       141066  +        ctx->buf[0] = 0x67452301;
       141067  +        ctx->buf[1] = 0xefcdab89;
       141068  +        ctx->buf[2] = 0x98badcfe;
       141069  +        ctx->buf[3] = 0x10325476;
       141070  +        ctx->bits[0] = 0;
       141071  +        ctx->bits[1] = 0;
       141072  +}
       141073  +
       141074  +/*
       141075  + * Update context to reflect the concatenation of another buffer full
       141076  + * of bytes.
       141077  + */
       141078  +static 
       141079  +void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
       141080  +        uint32 t;
       141081  +
       141082  +        /* Update bitcount */
       141083  +
       141084  +        t = ctx->bits[0];
       141085  +        if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
       141086  +                ctx->bits[1]++; /* Carry from low to high */
       141087  +        ctx->bits[1] += len >> 29;
       141088  +
       141089  +        t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
       141090  +
       141091  +        /* Handle any leading odd-sized chunks */
       141092  +
       141093  +        if ( t ) {
       141094  +                unsigned char *p = (unsigned char *)ctx->in + t;
       141095  +
       141096  +                t = 64-t;
       141097  +                if (len < t) {
       141098  +                        memcpy(p, buf, len);
       141099  +                        return;
       141100  +                }
       141101  +                memcpy(p, buf, t);
       141102  +                byteReverse(ctx->in, 16);
       141103  +                MD5Transform(ctx->buf, (uint32 *)ctx->in);
       141104  +                buf += t;
       141105  +                len -= t;
       141106  +        }
       141107  +
       141108  +        /* Process data in 64-byte chunks */
       141109  +
       141110  +        while (len >= 64) {
       141111  +                memcpy(ctx->in, buf, 64);
       141112  +                byteReverse(ctx->in, 16);
       141113  +                MD5Transform(ctx->buf, (uint32 *)ctx->in);
       141114  +                buf += 64;
       141115  +                len -= 64;
       141116  +        }
       141117  +
       141118  +        /* Handle any remaining bytes of data. */
       141119  +
       141120  +        memcpy(ctx->in, buf, len);
       141121  +}
       141122  +
       141123  +/*
       141124  + * Final wrapup - pad to 64-byte boundary with the bit pattern 
       141125  + * 1 0* (64-bit count of bits processed, MSB-first)
       141126  + */
       141127  +static void MD5Final(unsigned char digest[16], MD5Context *ctx){
       141128  +        unsigned count;
       141129  +        unsigned char *p;
       141130  +
       141131  +        /* Compute number of bytes mod 64 */
       141132  +        count = (ctx->bits[0] >> 3) & 0x3F;
       141133  +
       141134  +        /* Set the first char of padding to 0x80.  This is safe since there is
       141135  +           always at least one byte free */
       141136  +        p = ctx->in + count;
       141137  +        *p++ = 0x80;
       141138  +
       141139  +        /* Bytes of padding needed to make 64 bytes */
       141140  +        count = 64 - 1 - count;
       141141  +
       141142  +        /* Pad out to 56 mod 64 */
       141143  +        if (count < 8) {
       141144  +                /* Two lots of padding:  Pad the first block to 64 bytes */
       141145  +                memset(p, 0, count);
       141146  +                byteReverse(ctx->in, 16);
       141147  +                MD5Transform(ctx->buf, (uint32 *)ctx->in);
       141148  +
       141149  +                /* Now fill the next block with 56 bytes */
       141150  +                memset(ctx->in, 0, 56);
       141151  +        } else {
       141152  +                /* Pad block to 56 bytes */
       141153  +                memset(p, 0, count-8);
       141154  +        }
       141155  +        byteReverse(ctx->in, 14);
       141156  +
       141157  +        /* Append length in bits and transform */
       141158  +        ((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
       141159  +        ((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
       141160  +
       141161  +        MD5Transform(ctx->buf, (uint32 *)ctx->in);
       141162  +        byteReverse((unsigned char *)ctx->buf, 4);
       141163  +        memcpy(digest, ctx->buf, 16);
       141164  +        memset(ctx, 0, sizeof(ctx));    /* In case it is sensitive */
       141165  +}
       141166  +
       141167  +/*
       141168  +** Convert a 128-bit MD5 digest into a 32-digit base-16 number.
       141169  +*/
       141170  +static void MD5DigestToBase16(unsigned char *digest, char *zBuf){
       141171  +  static char const zEncode[] = "0123456789abcdef";
       141172  +  int i, j;
       141173  +
       141174  +  for(j=i=0; i<16; i++){
       141175  +    int a = digest[i];
       141176  +    zBuf[j++] = zEncode[(a>>4)&0xf];
       141177  +    zBuf[j++] = zEncode[a & 0xf];
       141178  +  }
       141179  +  zBuf[j] = 0;
       141180  +}
       141181  +
       141182  +
       141183  +/*
       141184  +** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers
       141185  +** each representing 16 bits of the digest and separated from each
       141186  +** other by a "-" character.
       141187  +*/
       141188  +static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){
       141189  +  int i, j;
       141190  +  unsigned int x;
       141191  +  for(i=j=0; i<16; i+=2){
       141192  +    x = digest[i]*256 + digest[i+1];
       141193  +    if( i>0 ) zDigest[j++] = '-';
       141194  +    sprintf(&zDigest[j], "%05u", x);
       141195  +    j += 5;
       141196  +  }
       141197  +  zDigest[j] = 0;
       141198  +}
       141199  +
       141200  +/*
       141201  +** A TCL command for md5.  The argument is the text to be hashed.  The
       141202  +** Result is the hash in base64.  
       141203  +*/
       141204  +static int md5_cmd(void*cd, Tcl_Interp *interp, int argc, const char **argv){
       141205  +  MD5Context ctx;
       141206  +  unsigned char digest[16];
       141207  +  char zBuf[50];
       141208  +  void (*converter)(unsigned char*, char*);
       141209  +
       141210  +  if( argc!=2 ){
       141211  +    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], 
       141212  +        " TEXT\"", 0);
       141213  +    return TCL_ERROR;
       141214  +  }
       141215  +  MD5Init(&ctx);
       141216  +  MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1]));
       141217  +  MD5Final(digest, &ctx);
       141218  +  converter = (void(*)(unsigned char*,char*))cd;
       141219  +  converter(digest, zBuf);
       141220  +  Tcl_AppendResult(interp, zBuf, (char*)0);
       141221  +  return TCL_OK;
       141222  +}
       141223  +
       141224  +/*
       141225  +** A TCL command to take the md5 hash of a file.  The argument is the
       141226  +** name of the file.
       141227  +*/
       141228  +static int md5file_cmd(void*cd, Tcl_Interp*interp, int argc, const char **argv){
       141229  +  FILE *in;
       141230  +  MD5Context ctx;
       141231  +  void (*converter)(unsigned char*, char*);
       141232  +  unsigned char digest[16];
       141233  +  char zBuf[10240];
       141234  +
       141235  +  if( argc!=2 ){
       141236  +    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0], 
       141237  +        " FILENAME\"", 0);
       141238  +    return TCL_ERROR;
       141239  +  }
       141240  +  in = fopen(argv[1],"rb");
       141241  +  if( in==0 ){
       141242  +    Tcl_AppendResult(interp,"unable to open file \"", argv[1], 
       141243  +         "\" for reading", 0);
       141244  +    return TCL_ERROR;
       141245  +  }
       141246  +  MD5Init(&ctx);
       141247  +  for(;;){
       141248  +    int n;
       141249  +    n = (int)fread(zBuf, 1, sizeof(zBuf), in);
       141250  +    if( n<=0 ) break;
       141251  +    MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
       141252  +  }
       141253  +  fclose(in);
       141254  +  MD5Final(digest, &ctx);
       141255  +  converter = (void(*)(unsigned char*,char*))cd;
       141256  +  converter(digest, zBuf);
       141257  +  Tcl_AppendResult(interp, zBuf, (char*)0);
       141258  +  return TCL_OK;
       141259  +}
       141260  +
       141261  +/*
       141262  +** Register the four new TCL commands for generating MD5 checksums
       141263  +** with the TCL interpreter.
       141264  +*/
       141265  +int Md5_Init(Tcl_Interp *interp){
       141266  +  Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd,
       141267  +                    MD5DigestToBase16, 0);
       141268  +  Tcl_CreateCommand(interp, "md5-10x8", (Tcl_CmdProc*)md5_cmd,
       141269  +                    MD5DigestToBase10x8, 0);
       141270  +  Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd,
       141271  +                    MD5DigestToBase16, 0);
       141272  +  Tcl_CreateCommand(interp, "md5file-10x8", (Tcl_CmdProc*)md5file_cmd,
       141273  +                    MD5DigestToBase10x8, 0);
       141274  +  return TCL_OK;
       141275  +}
       141276  +#endif /* defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) */
       141277  +
       141278  +#if defined(SQLITE_TEST)
       141279  +/*
       141280  +** During testing, the special md5sum() aggregate function is available.
       141281  +** inside SQLite.  The following routines implement that function.
       141282  +*/
       141283  +static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
       141284  +  MD5Context *p;
       141285  +  int i;
       141286  +  if( argc<1 ) return;
       141287  +  p = sqlite3_aggregate_context(context, sizeof(*p));
       141288  +  if( p==0 ) return;
       141289  +  if( !p->isInit ){
       141290  +    MD5Init(p);
       141291  +  }
       141292  +  for(i=0; i<argc; i++){
       141293  +    const char *zData = (char*)sqlite3_value_text(argv[i]);
       141294  +    if( zData ){
       141295  +      MD5Update(p, (unsigned char*)zData, (int)strlen(zData));
       141296  +    }
       141297  +  }
       141298  +}
       141299  +static void md5finalize(sqlite3_context *context){
       141300  +  MD5Context *p;
       141301  +  unsigned char digest[16];
       141302  +  char zBuf[33];
       141303  +  p = sqlite3_aggregate_context(context, sizeof(*p));
       141304  +  MD5Final(digest,p);
       141305  +  MD5DigestToBase16(digest, zBuf);
       141306  +  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
       141307  +}
       141308  +int Md5_Register(sqlite3 *db){
       141309  +  int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0, 
       141310  +                                 md5step, md5finalize);
       141311  +  sqlite3_overload_function(db, "md5sum", -1);  /* To exercise this API */
       141312  +  return rc;
       141313  +}
       141314  +#endif /* defined(SQLITE_TEST) */
       141315  +
       141316  +
       141317  +/*
       141318  +** If the macro TCLSH is one, then put in code this for the
       141319  +** "main" routine that will initialize Tcl and take input from
       141320  +** standard input, or if a file is named on the command line
       141321  +** the TCL interpreter reads and evaluates that file.
       141322  +*/
       141323  +#if TCLSH==1
       141324  +static const char *tclsh_main_loop(void){
       141325  +  static const char zMainloop[] =
       141326  +    "set line {}\n"
       141327  +    "while {![eof stdin]} {\n"
       141328  +      "if {$line!=\"\"} {\n"
       141329  +        "puts -nonewline \"> \"\n"
       141330  +      "} else {\n"
       141331  +        "puts -nonewline \"% \"\n"
       141332  +      "}\n"
       141333  +      "flush stdout\n"
       141334  +      "append line [gets stdin]\n"
       141335  +      "if {[info complete $line]} {\n"
       141336  +        "if {[catch {uplevel #0 $line} result]} {\n"
       141337  +          "puts stderr \"Error: $result\"\n"
       141338  +        "} elseif {$result!=\"\"} {\n"
       141339  +          "puts $result\n"
       141340  +        "}\n"
       141341  +        "set line {}\n"
       141342  +      "} else {\n"
       141343  +        "append line \\n\n"
       141344  +      "}\n"
       141345  +    "}\n"
       141346  +  ;
       141347  +  return zMainloop;
       141348  +}
       141349  +#endif
       141350  +#if TCLSH==2
       141351  +static const char *tclsh_main_loop(void);
       141352  +#endif
       141353  +
       141354  +#ifdef SQLITE_TEST
       141355  +static void init_all(Tcl_Interp *);
       141356  +static int init_all_cmd(
       141357  +  ClientData cd,
       141358  +  Tcl_Interp *interp,
       141359  +  int objc,
       141360  +  Tcl_Obj *CONST objv[]
       141361  +){
       141362  +
       141363  +  Tcl_Interp *slave;
       141364  +  if( objc!=2 ){
       141365  +    Tcl_WrongNumArgs(interp, 1, objv, "SLAVE");
       141366  +    return TCL_ERROR;
       141367  +  }
       141368  +
       141369  +  slave = Tcl_GetSlave(interp, Tcl_GetString(objv[1]));
       141370  +  if( !slave ){
       141371  +    return TCL_ERROR;
       141372  +  }
       141373  +
       141374  +  init_all(slave);
       141375  +  return TCL_OK;
       141376  +}
       141377  +
       141378  +/*
       141379  +** Tclcmd: db_use_legacy_prepare DB BOOLEAN
       141380  +**
       141381  +**   The first argument to this command must be a database command created by
       141382  +**   [sqlite3]. If the second argument is true, then the handle is configured
       141383  +**   to use the sqlite3_prepare_v2() function to prepare statements. If it
       141384  +**   is false, sqlite3_prepare().
       141385  +*/
       141386  +static int db_use_legacy_prepare_cmd(
       141387  +  ClientData cd,
       141388  +  Tcl_Interp *interp,
       141389  +  int objc,
       141390  +  Tcl_Obj *CONST objv[]
       141391  +){
       141392  +  Tcl_CmdInfo cmdInfo;
       141393  +  SqliteDb *pDb;
       141394  +  int bPrepare;
       141395  +
       141396  +  if( objc!=3 ){
       141397  +    Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN");
       141398  +    return TCL_ERROR;
       141399  +  }
       141400  +
       141401  +  if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
       141402  +    Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0);
       141403  +    return TCL_ERROR;
       141404  +  }
       141405  +  pDb = (SqliteDb*)cmdInfo.objClientData;
       141406  +  if( Tcl_GetBooleanFromObj(interp, objv[2], &bPrepare) ){
       141407  +    return TCL_ERROR;
       141408  +  }
       141409  +
       141410  +  pDb->bLegacyPrepare = bPrepare;
       141411  +
       141412  +  Tcl_ResetResult(interp);
       141413  +  return TCL_OK;
       141414  +}
       141415  +#endif
       141416  +
       141417  +/*
       141418  +** Configure the interpreter passed as the first argument to have access
       141419  +** to the commands and linked variables that make up:
       141420  +**
       141421  +**   * the [sqlite3] extension itself, 
       141422  +**
       141423  +**   * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and
       141424  +**
       141425  +**   * If SQLITE_TEST is set, the various test interfaces used by the Tcl
       141426  +**     test suite.
       141427  +*/
       141428  +static void init_all(Tcl_Interp *interp){
       141429  +  Sqlite3_Init(interp);
       141430  +
       141431  +#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5)
       141432  +  Md5_Init(interp);
       141433  +#endif
       141434  +
       141435  +  /* Install the [register_dbstat_vtab] command to access the implementation
       141436  +  ** of virtual table dbstat (source file test_stat.c). This command is
       141437  +  ** required for testfixture and sqlite3_analyzer, but not by the production
       141438  +  ** Tcl extension.  */
       141439  +#if defined(SQLITE_TEST) || TCLSH==2
       141440  +  {
       141441  +    extern int SqlitetestStat_Init(Tcl_Interp*);
       141442  +    SqlitetestStat_Init(interp);
       141443  +  }
       141444  +#endif
       141445  +
       141446  +#ifdef SQLITE_TEST
       141447  +  {
       141448  +    extern int Sqliteconfig_Init(Tcl_Interp*);
       141449  +    extern int Sqlitetest1_Init(Tcl_Interp*);
       141450  +    extern int Sqlitetest2_Init(Tcl_Interp*);
       141451  +    extern int Sqlitetest3_Init(Tcl_Interp*);
       141452  +    extern int Sqlitetest4_Init(Tcl_Interp*);
       141453  +    extern int Sqlitetest5_Init(Tcl_Interp*);
       141454  +    extern int Sqlitetest6_Init(Tcl_Interp*);
       141455  +    extern int Sqlitetest7_Init(Tcl_Interp*);
       141456  +    extern int Sqlitetest8_Init(Tcl_Interp*);
       141457  +    extern int Sqlitetest9_Init(Tcl_Interp*);
       141458  +    extern int Sqlitetestasync_Init(Tcl_Interp*);
       141459  +    extern int Sqlitetest_autoext_Init(Tcl_Interp*);
       141460  +    extern int Sqlitetest_demovfs_Init(Tcl_Interp *);
       141461  +    extern int Sqlitetest_func_Init(Tcl_Interp*);
       141462  +    extern int Sqlitetest_hexio_Init(Tcl_Interp*);
       141463  +    extern int Sqlitetest_init_Init(Tcl_Interp*);
       141464  +    extern int Sqlitetest_malloc_Init(Tcl_Interp*);
       141465  +    extern int Sqlitetest_mutex_Init(Tcl_Interp*);
       141466  +    extern int Sqlitetestschema_Init(Tcl_Interp*);
       141467  +    extern int Sqlitetestsse_Init(Tcl_Interp*);
       141468  +    extern int Sqlitetesttclvar_Init(Tcl_Interp*);
       141469  +    extern int SqlitetestThread_Init(Tcl_Interp*);
       141470  +    extern int SqlitetestOnefile_Init();
       141471  +    extern int SqlitetestOsinst_Init(Tcl_Interp*);
       141472  +    extern int Sqlitetestbackup_Init(Tcl_Interp*);
       141473  +    extern int Sqlitetestintarray_Init(Tcl_Interp*);
       141474  +    extern int Sqlitetestvfs_Init(Tcl_Interp *);
       141475  +    extern int Sqlitetestrtree_Init(Tcl_Interp*);
       141476  +    extern int Sqlitequota_Init(Tcl_Interp*);
       141477  +    extern int Sqlitemultiplex_Init(Tcl_Interp*);
       141478  +    extern int SqliteSuperlock_Init(Tcl_Interp*);
       141479  +    extern int SqlitetestSyscall_Init(Tcl_Interp*);
       141480  +    extern int Sqlitetestfuzzer_Init(Tcl_Interp*);
       141481  +    extern int Sqlitetestwholenumber_Init(Tcl_Interp*);
       141482  +    extern int Sqlitetestregexp_Init(Tcl_Interp*);
       141483  +
       141484  +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
       141485  +    extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
       141486  +#endif
       141487  +
       141488  +#ifdef SQLITE_ENABLE_ZIPVFS
       141489  +    extern int Zipvfs_Init(Tcl_Interp*);
       141490  +    Zipvfs_Init(interp);
       141491  +#endif
       141492  +
       141493  +    Sqliteconfig_Init(interp);
       141494  +    Sqlitetest1_Init(interp);
       141495  +    Sqlitetest2_Init(interp);
       141496  +    Sqlitetest3_Init(interp);
       141497  +    Sqlitetest4_Init(interp);
       141498  +    Sqlitetest5_Init(interp);
       141499  +    Sqlitetest6_Init(interp);
       141500  +    Sqlitetest7_Init(interp);
       141501  +    Sqlitetest8_Init(interp);
       141502  +    Sqlitetest9_Init(interp);
       141503  +    Sqlitetestasync_Init(interp);
       141504  +    Sqlitetest_autoext_Init(interp);
       141505  +    Sqlitetest_demovfs_Init(interp);
       141506  +    Sqlitetest_func_Init(interp);
       141507  +    Sqlitetest_hexio_Init(interp);
       141508  +    Sqlitetest_init_Init(interp);
       141509  +    Sqlitetest_malloc_Init(interp);
       141510  +    Sqlitetest_mutex_Init(interp);
       141511  +    Sqlitetestschema_Init(interp);
       141512  +    Sqlitetesttclvar_Init(interp);
       141513  +    SqlitetestThread_Init(interp);
       141514  +    SqlitetestOnefile_Init(interp);
       141515  +    SqlitetestOsinst_Init(interp);
       141516  +    Sqlitetestbackup_Init(interp);
       141517  +    Sqlitetestintarray_Init(interp);
       141518  +    Sqlitetestvfs_Init(interp);
       141519  +    Sqlitetestrtree_Init(interp);
       141520  +    Sqlitequota_Init(interp);
       141521  +    Sqlitemultiplex_Init(interp);
       141522  +    SqliteSuperlock_Init(interp);
       141523  +    SqlitetestSyscall_Init(interp);
       141524  +    Sqlitetestfuzzer_Init(interp);
       141525  +    Sqlitetestwholenumber_Init(interp);
       141526  +    Sqlitetestregexp_Init(interp);
       141527  +
       141528  +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
       141529  +    Sqlitetestfts3_Init(interp);
       141530  +#endif
       141531  +
       141532  +    Tcl_CreateObjCommand(
       141533  +        interp, "load_testfixture_extensions", init_all_cmd, 0, 0
       141534  +    );
       141535  +    Tcl_CreateObjCommand(
       141536  +        interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0
       141537  +    );
       141538  +
       141539  +#ifdef SQLITE_SSE
       141540  +    Sqlitetestsse_Init(interp);
       141541  +#endif
       141542  +  }
       141543  +#endif
       141544  +}
       141545  +
       141546  +#define TCLSH_MAIN main   /* Needed to fake out mktclapp */
       141547  +int TCLSH_MAIN(int argc, char **argv){
       141548  +  Tcl_Interp *interp;
       141549  +  
       141550  +  /* Call sqlite3_shutdown() once before doing anything else. This is to
       141551  +  ** test that sqlite3_shutdown() can be safely called by a process before
       141552  +  ** sqlite3_initialize() is. */
       141553  +  sqlite3_shutdown();
       141554  +
       141555  +  Tcl_FindExecutable(argv[0]);
       141556  +  interp = Tcl_CreateInterp();
       141557  +
       141558  +#if TCLSH==2
       141559  +  sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
       141560  +#endif
       141561  +
       141562  +  init_all(interp);
       141563  +  if( argc>=2 ){
       141564  +    int i;
       141565  +    char zArgc[32];
       141566  +    sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH));
       141567  +    Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
       141568  +    Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY);
       141569  +    Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
       141570  +    for(i=3-TCLSH; i<argc; i++){
       141571  +      Tcl_SetVar(interp, "argv", argv[i],
       141572  +          TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
       141573  +    }
       141574  +    if( TCLSH==1 && Tcl_EvalFile(interp, argv[1])!=TCL_OK ){
       141575  +      const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
       141576  +      if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp);
       141577  +      fprintf(stderr,"%s: %s\n", *argv, zInfo);
       141578  +      return 1;
       141579  +    }
       141580  +  }
       141581  +  if( TCLSH==2 || argc<=1 ){
       141582  +    Tcl_GlobalEval(interp, tclsh_main_loop());
       141583  +  }
       141584  +  return 0;
       141585  +}
       141586  +#endif /* TCLSH */

Changes to src/sqlite3.h.

   105    105   **
   106    106   ** See also: [sqlite3_libversion()],
   107    107   ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
   108    108   ** [sqlite_version()] and [sqlite_source_id()].
   109    109   */
   110    110   #define SQLITE_VERSION        "3.7.16"
   111    111   #define SQLITE_VERSION_NUMBER 3007016
   112         -#define SQLITE_SOURCE_ID      "2013-01-07 13:26:23 0a1207c895d9f77586a3a2a4965175909be90503"
          112  +#define SQLITE_SOURCE_ID      "2012-12-08 06:46:05 e65db42c9fdc1d6f257c8db54a46ee4fc0d7aaf0"
   113    113   
   114    114   /*
   115    115   ** CAPI3REF: Run-Time Library Version Numbers
   116    116   ** KEYWORDS: sqlite3_version, sqlite3_sourceid
   117    117   **
   118    118   ** These interfaces provide the same information as the [SQLITE_VERSION],
   119    119   ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
................................................................................
  1247   1247   SQLITE_API int sqlite3_shutdown(void);
  1248   1248   SQLITE_API int sqlite3_os_init(void);
  1249   1249   SQLITE_API int sqlite3_os_end(void);
  1250   1250   
  1251   1251   /*
  1252   1252   ** CAPI3REF: Configuring The SQLite Library
  1253   1253   **
  1254         -** The sqlite3_config() interface is used to make global configuration
  1255         -** changes to SQLite in order to tune SQLite to the specific needs of
  1256         -** the application.  The default configuration is recommended for most
  1257         -** applications and so this routine is usually not necessary.  It is
  1258         -** provided to support rare applications with unusual needs.
         1254  +** The sqlite3_config() and sqlite3_reconfig() interfaces are used to make
         1255  +** global configuration changes to SQLite in order to tune SQLite to the
         1256  +** specific needs of the application.  The default configuration is recommended
         1257  +** for most applications and so this routine is usually not necessary.  They
         1258  +** are provided to support rare applications with unusual needs.
  1259   1259   **
  1260   1260   ** The sqlite3_config() interface is not threadsafe.  The application
  1261   1261   ** must insure that no other SQLite interfaces are invoked by other
  1262   1262   ** threads while sqlite3_config() is running.  Furthermore, sqlite3_config()
  1263   1263   ** may only be invoked prior to library initialization using
  1264   1264   ** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
  1265   1265   ** ^If sqlite3_config() is called after [sqlite3_initialize()] and before
  1266   1266   ** [sqlite3_shutdown()] then it will return SQLITE_MISUSE.
  1267   1267   ** Note, however, that ^sqlite3_config() can be called as part of the
  1268   1268   ** implementation of an application-defined [sqlite3_os_init()].
  1269   1269   **
  1270         -** The first argument to sqlite3_config() is an integer
  1271         -** [configuration option] that determines
         1270  +** The sqlite3_reconfig() interface is threadsafe and may be called at any
         1271  +** time.  However, it supports only a small subset of the configuration
         1272  +** options available for use with sqlite3_config().
         1273  +**
         1274  +** The first argument to both sqlite3_config() and sqlite3_reconfig() is an
         1275  +** integer [configuration option] that determines
  1272   1276   ** what property of SQLite is to be configured.  Subsequent arguments
  1273   1277   ** vary depending on the [configuration option]
  1274   1278   ** in the first argument.
  1275   1279   **
  1276         -** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK].
         1280  +** ^When a configuration option is set, both sqlite3_config() and
         1281  +** sqlite3_reconfig() return [SQLITE_OK].
  1277   1282   ** ^If the option is unknown or SQLite is unable to set the option
  1278         -** then this routine returns a non-zero [error code].
         1283  +** then these routines returns a non-zero [error code].
  1279   1284   */
  1280   1285   SQLITE_API int sqlite3_config(int, ...);
         1286  +SQLITE_API int sqlite3_reconfig(int, ...);
  1281   1287   
  1282   1288   /*
  1283   1289   ** CAPI3REF: Configure database connections
  1284   1290   **
  1285   1291   ** The sqlite3_db_config() interface is used to make configuration
  1286   1292   ** changes to a [database connection].  The interface is similar to
  1287   1293   ** [sqlite3_config()] except that the changes apply to a single
................................................................................
  1598   1604   ** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
  1599   1605   ** if that compile-time option is omitted.
  1600   1606   ** The ability to disable the use of covering indices for full table scans
  1601   1607   ** is because some incorrectly coded legacy applications might malfunction
  1602   1608   ** malfunction when the optimization is enabled.  Providing the ability to
  1603   1609   ** disable the optimization allows the older, buggy application code to work
  1604   1610   ** without change even with newer versions of SQLite.
         1611  +**
         1612  +** [[SQLITE_CONFIG_READONLY]] <dt>SQLITE_CONFIG_READONLY
         1613  +** <dd> This option takes a single argument of type int. If non-zero, then
         1614  +** read-only mode for opening databases is globally enabled. If the parameter
         1615  +** is zero, then read-only mode for opening databases is globally disabled. If
         1616  +** read-only mode for opening databases is globally enabled, all databases
         1617  +** opened by [sqlite3_open()], [sqlite3_open16()], or specified as part of
         1618  +** [ATTACH] commands will be opened in read-only mode. Additionally, all calls
         1619  +** to [sqlite3_open_v2()] must have the [SQLITE_OPEN_READONLY] flag set in the
         1620  +** third argument; otherwise, a [SQLITE_READONLY] error will be returned. If it
         1621  +** is globally disabled, [sqlite3_open()], [sqlite3_open16()],
         1622  +** [sqlite3_open_v2()], and [ATTACH] commands will function normally. By
         1623  +** default, read-only mode is globally disabled.
  1605   1624   **
  1606   1625   ** [[SQLITE_CONFIG_PCACHE]] [[SQLITE_CONFIG_GETPCACHE]]
  1607   1626   ** <dt>SQLITE_CONFIG_PCACHE and SQLITE_CONFIG_GETPCACHE
  1608   1627   ** <dd> These options are obsolete and should not be used by new code.
  1609   1628   ** They are retained for backwards compatibility but are now no-ops.
  1610   1629   ** </dl>
  1611   1630   **
................................................................................
  1642   1661   #define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
  1643   1662   #define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
  1644   1663   #define SQLITE_CONFIG_URI          17  /* int */
  1645   1664   #define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
  1646   1665   #define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
  1647   1666   #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
  1648   1667   #define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
         1668  +#define SQLITE_CONFIG_READONLY     22  /* int */
  1649   1669   
  1650   1670   /*
  1651   1671   ** CAPI3REF: Database Connection Configuration Options
  1652   1672   **
  1653   1673   ** These constants are the available integer configuration options that
  1654   1674   ** can be passed as the second argument to the [sqlite3_db_config()] interface.
  1655   1675   **

Changes to src/th_main.c.

    18     18   ** This file contains an interface between the TH scripting language
    19     19   ** (an independent project) and fossil.
    20     20   */
    21     21   #include "config.h"
    22     22   #include "th_main.h"
    23     23   #include "sqlite3.h"
    24     24   
           25  +#ifdef FOSSIL_ENABLE_TCL
           26  +#  include <sqlite3.h>
           27  +#endif
           28  +
    25     29   /*
    26     30   ** Global variable counting the number of outstanding calls to malloc()
    27     31   ** made by the th1 implementation. This is used to catch memory leaks
    28     32   ** in the interpreter. Obviously, it also means th1 is not threadsafe.
    29     33   */
    30     34   static int nOutstandingMalloc = 0;
    31     35   
................................................................................
   662    666         Th_ErrorMessage(interp, "SQL error: ", sqlite3_errmsg(g.db), -1);
   663    667         return TH_ERROR;
   664    668       }
   665    669     } 
   666    670     return res;
   667    671   }
   668    672   
          673  +#ifdef FOSSIL_ENABLE_TCL
          674  +static int wasReconfigured = 0;
          675  +
          676  +static int Th_PreTclEval(
          677  +  void *pContext,
          678  +  Th_Interp *interp, /* NOT USED */
          679  +  void *ctx,         /* NOT USED */
          680  +  int argc,          /* NOT USED */
          681  +  const char **argv, /* NOT USED */
          682  +  int *argl,         /* NOT USED */
          683  +  int rc
          684  +){
          685  +#if SQLITE_VERSION_NUMBER >= 3007015
          686  +  int *pbReconfigured = pContext;
          687  +  if( pbReconfigured ) *pbReconfigured = 0;
          688  +  if( db_get_boolean("tcl-rdonly", 1) ){
          689  +    int rc2;
          690  +    if ( (rc2=sqlite3_reconfig(SQLITE_CONFIG_READONLY, 1))==SQLITE_OK ){
          691  +      if( pbReconfigured ) *pbReconfigured = 1;
          692  +    }else{
          693  +      Th_ErrorMessage(interp,
          694  +          "failed to reconfigure SQLite:", sqlite3_errstr(rc2), -1);
          695  +      return TH_ERROR;
          696  +    }
          697  +  }
          698  +#endif
          699  +  return rc;
          700  +}
          701  +
          702  +static int Th_PostTclEval(
          703  +  void *pContext,
          704  +  Th_Interp *interp,  /* NOT USED */
          705  +  void *ctx,          /* NOT USED */
          706  +  int argc,           /* NOT USED */
          707  +  const char **argv,  /* NOT USED */
          708  +  int *argl,          /* NOT USED */
          709  +  int rc
          710  +){
          711  +#if SQLITE_VERSION_NUMBER >= 3007015
          712  +  int *pbReconfigured = pContext;
          713  +  if( pbReconfigured && *pbReconfigured ){
          714  +    int rc2;
          715  +    if ( (rc2=sqlite3_reconfig(SQLITE_CONFIG_READONLY, 0))==SQLITE_OK ){
          716  +      if( pbReconfigured ) *pbReconfigured = 0;
          717  +    }else{
          718  +      Th_ErrorMessage(interp,
          719  +          "failed to reconfigure SQLite:", sqlite3_errstr(rc2), -1);
          720  +      return TH_ERROR;
          721  +    }
          722  +  }
          723  +#endif
          724  +  return rc;
          725  +}
          726  +#endif
          727  +
   669    728   /*
   670    729   ** Make sure the interpreter has been initialized.  Initialize it if
   671    730   ** it has not been already.
   672    731   **
   673    732   ** The interpreter is stored in the g.interp global variable.
   674    733   */
   675    734   void Th_FossilInit(int needConfig, int forceSetup){
................................................................................
   714    773       g.interp = Th_CreateInterp(&vtab);
   715    774       th_register_language(g.interp);       /* Basic scripting commands. */
   716    775   #ifdef FOSSIL_ENABLE_TCL
   717    776       if( getenv("TH1_ENABLE_TCL")!=0 || db_get_boolean("tcl", 0) ){
   718    777         if( !g.tcl.setup ){
   719    778           g.tcl.setup = db_get("tcl-setup", 0); /* Grab Tcl setup script. */
   720    779         }
          780  +      g.tcl.xPreEval = Th_PreTclEval;
          781  +      g.tcl.pPreContext = &wasReconfigured;
          782  +      g.tcl.xPostEval = Th_PostTclEval;
          783  +      g.tcl.pPostContext = &wasReconfigured;
   721    784         th_register_tcl(g.interp, &g.tcl);  /* Tcl integration commands. */
   722    785       }
   723    786   #endif
   724    787       for(i=0; i<sizeof(aCommand)/sizeof(aCommand[0]); i++){
   725    788         if ( !aCommand[i].zName || !aCommand[i].xProc ) continue;
   726    789         Th_CreateCommand(g.interp, aCommand[i].zName, aCommand[i].xProc,
   727    790                          aCommand[i].pContext, 0);

Changes to src/th_tcl.c.

   688    688     if( Tcl_Init(tclInterp)!=TCL_OK ){
   689    689       Th_ErrorMessage(interp,
   690    690           "Tcl initialization error:", Tcl_GetStringResult(tclInterp), -1);
   691    691       Tcl_DeleteInterp(tclInterp);
   692    692       tclContext->interp = tclInterp = 0;
   693    693       return TH_ERROR;
   694    694     }
          695  +#ifdef FOSSIL_ENABLE_TCL_SQLITE
          696  +  /*
          697  +  ** Make sure the Tcl interpreter uses the SQLite package for Tcl that we
          698  +  ** are statically linked with rather than another one that may be present
          699  +  ** on the system.
          700  +  */
          701  +  extern int Sqlite3_Init(Tcl_Interp *interp);
          702  +  if( Sqlite3_Init(tclInterp)!=TCL_OK ){
          703  +    Th_ErrorMessage(interp,
          704  +        "SQLite package for Tcl error:", Tcl_GetStringResult(tclInterp), -1);
          705  +    Tcl_DeleteInterp(tclInterp);
          706  +    tclContext->interp = tclInterp = 0;
          707  +    return TH_ERROR;
          708  +  }
          709  +#endif
   695    710     if( setTclArguments(tclInterp, argc, argv)!=TCL_OK ){
   696    711       Th_ErrorMessage(interp,
   697    712           "Tcl error setting arguments:", Tcl_GetStringResult(tclInterp), -1);
   698    713       Tcl_DeleteInterp(tclInterp);
   699    714       tclContext->interp = tclInterp = 0;
   700    715       return TH_ERROR;
   701    716     }

Changes to test/th1-tcl.test.

   102    102   
   103    103   ###############################################################################
   104    104   
   105    105   fossil test-th-render [file nativename [file join $dir th1-tcl9.txt]]
   106    106   
   107    107   test th1-tcl-9 {[string trim $RESULT] eq [list [file tail $fossilexe] 2 \
   108    108   [list test-th-render [file nativename [file join $dir th1-tcl9.txt]]]]}
          109  +
          110  +###############################################################################
          111  +
          112  +fossil test-th-render [file nativename [file join $dir th1-tclA.txt]]
          113  +
          114  +test th1-tcl-A {[string trim $RESULT] eq \
          115  +"1 {attempt to write a readonly database}"}

Added test/th1-tclA.txt.

            1  +<th1>
            2  +  #
            3  +  # This is a "TH1 fragment" used to test the Tcl integration features of TH1.
            4  +  # The corresponding test file executes this file using the test-th-render
            5  +  # Fossil command.
            6  +  #
            7  +  # NOTE: This test requires that the SQLite package be available for the Tcl
            8  +  #       interpreter that is linked to the Fossil executable.
            9  +  #
           10  +  tclInvoke set repository_name [repository 1]
           11  +  proc doOut {msg} {puts $msg; puts \n}
           12  +  doOut [tclEval {
           13  +    package require sqlite3
           14  +    set c [catch {
           15  +      sqlite3 db $repository_name
           16  +      set m [clock seconds]
           17  +      db eval {
           18  +        INSERT INTO config (name, value, mtime)
           19  +        VALUES('test-rdonly', 'no', $m);
           20  +      }
           21  +      db close
           22  +    } x]
           23  +    return [list $c $x]
           24  +  }]
           25  +</th1>

Changes to win/Makefile.mingw.

    57     57   #### Enable scripting support via Tcl/Tk
    58     58   #
    59     59   # FOSSIL_ENABLE_TCL = 1
    60     60   
    61     61   #### Load Tcl using the stubs mechanism
    62     62   #
    63     63   # FOSSIL_ENABLE_TCL_STUBS = 1
           64  +
           65  +#### Provide the SQLite package to Tcl
           66  +#
           67  +# FOSSIL_ENABLE_TCL_SQLITE = 1
    64     68   
    65     69   #### Use the Tcl source directory instead of the install directory?
    66     70   #    This is useful when Tcl has been compiled statically with MinGW.
    67     71   #
    68     72   FOSSIL_TCL_SOURCE = 1
    69     73   
    70     74   #### Check if the workaround for the MinGW command line handling needs to
................................................................................
   179    183   ifdef FOSSIL_ENABLE_TCL_STUBS
   180    184   TCC += -DFOSSIL_ENABLE_TCL_STUBS=1 -DUSE_TCL_STUBS
   181    185   RCC += -DFOSSIL_ENABLE_TCL_STUBS=1 -DUSE_TCL_STUBS
   182    186   else
   183    187   TCC += -DSTATIC_BUILD
   184    188   RCC += -DSTATIC_BUILD
   185    189   endif
          190  +# Provide the SQLite package to Tcl
          191  +ifdef FOSSIL_ENABLE_TCL_SQLITE
          192  +TCC += -DFOSSIL_ENABLE_TCL_SQLITE=1 -DBUILD_sqlite=1
          193  +RCC += -DFOSSIL_ENABLE_TCL_SQLITE=1 -DBUILD_sqlite=1
          194  +endif
   186    195   endif
   187    196   
   188    197   # With JSON support
   189    198   ifdef FOSSIL_ENABLE_JSON
   190    199   TCC += -DFOSSIL_ENABLE_JSON=1
   191    200   RCC += -DFOSSIL_ENABLE_JSON=1
   192    201   endif

Changes to win/Makefile.mingw.mistachkin.

    57     57   #### Enable scripting support via Tcl/Tk
    58     58   #
    59     59   FOSSIL_ENABLE_TCL = 1
    60     60   
    61     61   #### Load Tcl using the stubs mechanism
    62     62   #
    63     63   FOSSIL_ENABLE_TCL_STUBS = 1
           64  +
           65  +#### Provide the SQLite package to Tcl
           66  +#
           67  +FOSSIL_ENABLE_TCL_SQLITE = 1
    64     68   
    65     69   #### Use the Tcl source directory instead of the install directory?
    66     70   #    This is useful when Tcl has been compiled statically with MinGW.
    67     71   #
    68     72   FOSSIL_TCL_SOURCE = 1
    69     73   
    70     74   #### Check if the workaround for the MinGW command line handling needs to
................................................................................
   179    183   ifdef FOSSIL_ENABLE_TCL_STUBS
   180    184   TCC += -DFOSSIL_ENABLE_TCL_STUBS=1 -DUSE_TCL_STUBS
   181    185   RCC += -DFOSSIL_ENABLE_TCL_STUBS=1 -DUSE_TCL_STUBS
   182    186   else
   183    187   TCC += -DSTATIC_BUILD
   184    188   RCC += -DSTATIC_BUILD
   185    189   endif
          190  +# Provide the SQLite package to Tcl
          191  +ifdef FOSSIL_ENABLE_TCL_SQLITE
          192  +TCC += -DFOSSIL_ENABLE_TCL_SQLITE=1 -DBUILD_sqlite=1
          193  +RCC += -DFOSSIL_ENABLE_TCL_SQLITE=1 -DBUILD_sqlite=1
          194  +endif
   186    195   endif
   187    196   
   188    197   # With JSON support
   189    198   ifdef FOSSIL_ENABLE_JSON
   190    199   TCC += -DFOSSIL_ENABLE_JSON=1
   191    200   RCC += -DFOSSIL_ENABLE_JSON=1
   192    201   endif

Changes to win/fossil.rc.

    98     98   #ifdef FOSSIL_ENABLE_TCL
    99     99         VALUE "TclEnabled", "Yes, Tcl " TCL_PATCH_LEVEL "\0"
   100    100   #ifdef FOSSIL_ENABLE_TCL_STUBS
   101    101         VALUE "TclStubsEnabled", "Yes\0"
   102    102   #else
   103    103         VALUE "TclStubsEnabled", "No\0"
   104    104   #endif
          105  +#ifdef FOSSIL_ENABLE_TCL_SQLITE
          106  +      VALUE "TclSqlitePackage", "Yes\0"
          107  +#else
          108  +      VALUE "TclSqlitePackage", "No\0"
          109  +#endif
   105    110   #endif
   106    111   #ifdef FOSSIL_ENABLE_JSON
   107    112         VALUE "JsonEnabled", "Yes, cson\0"
   108    113   #endif
   109    114   #ifdef FOSSIL_ENABLE_MARKDOWN
   110    115         VALUE "MarkdownEnabled", "Yes\0"
   111    116   #endif