/ Check-in [9ac8f1e7]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Merge the latest trunk changes into the threads branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | threads
Files: files | file ages | folders
SHA1: 9ac8f1e7115bc50663235adedeb0d3e1234c5740
User & Date: dan 2014-05-09 15:00:32
Context
2014-05-12
15:30
In the sorter, only use large memory allocations if scratch memory has not been configured. Add #ifdefs to disable unused code when SQLITE_MAX_WORKER_THREADS is zero. Other sorter changes in support of testability. check-in: d7e2b0d9 user: drh tags: threads
2014-05-09
15:00
Merge the latest trunk changes into the threads branch. check-in: 9ac8f1e7 user: dan tags: threads
11:15
Add new static mutex SQLITE_MUTEX_STATIC_APP3. check-in: ee0ab09c user: dan tags: threads
2014-05-07
21:16
Include sqlite3rtree.h in the tsrc/ pile of source files during target_source in the main.mk makefile. check-in: 116bed5a user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to Makefile.in.

   235    235     $(TOP)/src/mutex_noop.c \
   236    236     $(TOP)/src/mutex_unix.c \
   237    237     $(TOP)/src/mutex_w32.c \
   238    238     $(TOP)/src/notify.c \
   239    239     $(TOP)/src/os.c \
   240    240     $(TOP)/src/os.h \
   241    241     $(TOP)/src/os_common.h \
          242  +  $(TOP)/src/os_setup.h \
   242    243     $(TOP)/src/os_unix.c \
   243    244     $(TOP)/src/os_win.c \
          245  +  $(TOP)/src/os_win.h \
   244    246     $(TOP)/src/pager.c \
   245    247     $(TOP)/src/pager.h \
   246    248     $(TOP)/src/parse.y \
   247    249     $(TOP)/src/pcache.c \
   248    250     $(TOP)/src/pcache.h \
   249    251     $(TOP)/src/pcache1.c \
   250    252     $(TOP)/src/pragma.c \
................................................................................
   454    456      $(TOP)/src/hash.h \
   455    457      $(TOP)/src/hwtime.h \
   456    458      keywordhash.h \
   457    459      $(TOP)/src/mutex.h \
   458    460      opcodes.h \
   459    461      $(TOP)/src/os.h \
   460    462      $(TOP)/src/os_common.h \
          463  +   $(TOP)/src/os_setup.h \
          464  +   $(TOP)/src/os_win.h \
   461    465      $(TOP)/src/pager.h \
   462    466      $(TOP)/src/pcache.h \
   463    467      parse.h  \
   464    468      sqlite3.h  \
   465    469      $(TOP)/src/sqlite3ext.h \
   466    470      $(TOP)/src/sqliteInt.h  \
   467    471      $(TOP)/src/sqliteLimit.h \

Changes to Makefile.msc.

   506    506   # When compiling for use in the WinRT environment, the following
   507    507   # linker option must be used to mark the executable as runnable
   508    508   # only in the context of an application container.
   509    509   #
   510    510   !IF $(FOR_WINRT)!=0
   511    511   LTLINKOPTS = $(LTLINKOPTS) /APPCONTAINER
   512    512   !IF "$(VISUALSTUDIOVERSION)"=="12.0"
          513  +!IFNDEF STORELIBPATH
   513    514   !IF "$(PLATFORM)"=="x86"
   514         -LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(VCINSTALLDIR)\lib\store"
          515  +STORELIBPATH = $(NCRTLIBPATH)\store
   515    516   !ELSEIF "$(PLATFORM)"=="x64"
   516         -LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(VCINSTALLDIR)\lib\store\amd64"
          517  +STORELIBPATH = $(NCRTLIBPATH)\store\amd64
   517    518   !ELSEIF "$(PLATFORM)"=="ARM"
   518         -LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(VCINSTALLDIR)\lib\store\arm"
          519  +STORELIBPATH = $(NCRTLIBPATH)\store\arm
   519    520   !ELSE
   520         -LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(VCINSTALLDIR)\lib\store"
          521  +STORELIBPATH = $(NCRTLIBPATH)\store
   521    522   !ENDIF
   522    523   !ENDIF
          524  +STORELIBPATH = $(STORELIBPATH:\\=\)
          525  +LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(STORELIBPATH)"
          526  +!ENDIF
   523    527   !ENDIF
   524    528   
   525    529   # If either debugging or symbols are enabled, enable PDBs.
   526    530   !IF $(DEBUG)>0 || $(SYMBOLS)!=0
   527    531   LDFLAGS = /DEBUG
   528    532   !ENDIF
   529    533   
................................................................................
   633    637     $(TOP)\src\mutex_noop.c \
   634    638     $(TOP)\src\mutex_unix.c \
   635    639     $(TOP)\src\mutex_w32.c \
   636    640     $(TOP)\src\notify.c \
   637    641     $(TOP)\src\os.c \
   638    642     $(TOP)\src\os.h \
   639    643     $(TOP)\src\os_common.h \
          644  +  $(TOP)\src\os_setup.h \
   640    645     $(TOP)\src\os_unix.c \
   641    646     $(TOP)\src\os_win.c \
          647  +  $(TOP)\src\os_win.h \
   642    648     $(TOP)\src\pager.c \
   643    649     $(TOP)\src\pager.h \
   644    650     $(TOP)\src\parse.y \
   645    651     $(TOP)\src\pcache.c \
   646    652     $(TOP)\src\pcache.h \
   647    653     $(TOP)\src\pcache1.c \
   648    654     $(TOP)\src\pragma.c \
................................................................................
   855    861      $(TOP)\src\hash.h \
   856    862      $(TOP)\src\hwtime.h \
   857    863      keywordhash.h \
   858    864      $(TOP)\src\mutex.h \
   859    865      opcodes.h \
   860    866      $(TOP)\src\os.h \
   861    867      $(TOP)\src\os_common.h \
          868  +   $(TOP)\src\os_setup.h \
          869  +   $(TOP)\src\os_win.h \
   862    870      $(TOP)\src\pager.h \
   863    871      $(TOP)\src\pcache.h \
   864    872      parse.h \
   865    873      sqlite3.h \
   866    874      $(TOP)\src\sqlite3ext.h \
   867    875      $(TOP)\src\sqliteInt.h \
   868    876      $(TOP)\src\sqliteLimit.h \
................................................................................
   951    959   
   952    960   # Rules to build the LEMON compiler generator
   953    961   #
   954    962   lempar.c:	$(TOP)\src\lempar.c
   955    963   	copy $(TOP)\src\lempar.c .
   956    964   
   957    965   lemon.exe:	$(TOP)\tool\lemon.c lempar.c
   958         -	$(BCC) -Daccess=_access -Fe$@ $(TOP)\tool\lemon.c /link $(NLTLIBPATHS)
          966  +	$(BCC) -Daccess=_access -Fe$@ $(TOP)\tool\lemon.c /link $(NLTLINKOPTS) $(NLTLIBPATHS)
   959    967   
   960    968   # Rules to build individual *.lo files from generated *.c files. This
   961    969   # applies to:
   962    970   #
   963    971   #     parse.lo
   964    972   #     opcodes.lo
   965    973   #
................................................................................
  1222   1230   	move parse.h parse.h.temp
  1223   1231   	$(NAWK) -f $(TOP)\addopcodes.awk parse.h.temp > parse.h
  1224   1232   
  1225   1233   sqlite3.h:	$(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
  1226   1234   	$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > sqlite3.h
  1227   1235   
  1228   1236   mkkeywordhash.exe:	$(TOP)\tool\mkkeywordhash.c
  1229         -	$(BCC) -Fe$@ $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)\tool\mkkeywordhash.c /link $(NLTLIBPATHS)
         1237  +	$(BCC) -Fe$@ $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)\tool\mkkeywordhash.c /link $(NLTLINKOPTS) $(NLTLIBPATHS)
  1230   1238   
  1231   1239   keywordhash.h:	$(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
  1232   1240   	.\mkkeywordhash.exe > keywordhash.h
  1233   1241   
  1234   1242   
  1235   1243   
  1236   1244   # Rules to build the extension objects.
................................................................................
  1370   1378   	$(LTLINK) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1371   1379   		$(TOP)\test\speedtest1.c $(SQLITE3C)
  1372   1380   
  1373   1381   clean:
  1374   1382   	del /Q *.lo *.ilk *.lib *.obj *.pdb sqlite3.exe libsqlite3.lib
  1375   1383   	del /Q *.cod *.da *.bb *.bbg gmon.out
  1376   1384   	del /Q sqlite3.h opcodes.c opcodes.h
  1377         -	del /Q lemon.exe lempar.c parse.*
  1378         -	del /Q mkkeywordhash.exe keywordhash.h
         1385  +	del /Q lemon.* lempar.c parse.*
         1386  +	del /Q mkkeywordhash.* keywordhash.h
  1379   1387   	del /Q notasharedlib.*
  1380   1388   	-rmdir /Q/S .deps
  1381   1389   	-rmdir /Q/S .libs
  1382   1390   	-rmdir /Q/S quota2a
  1383   1391   	-rmdir /Q/S quota2b
  1384   1392   	-rmdir /Q/S quota2c
  1385   1393   	-rmdir /Q/S tsrc

Changes to Makefile.vxworks.

   258    258     $(TOP)/src/mutex_noop.c \
   259    259     $(TOP)/src/mutex_unix.c \
   260    260     $(TOP)/src/mutex_w32.c \
   261    261     $(TOP)/src/notify.c \
   262    262     $(TOP)/src/os.c \
   263    263     $(TOP)/src/os.h \
   264    264     $(TOP)/src/os_common.h \
          265  +  $(TOP)/src/os_setup.h \
   265    266     $(TOP)/src/os_unix.c \
   266    267     $(TOP)/src/os_win.c \
          268  +  $(TOP)/src/os_win.h \
   267    269     $(TOP)/src/pager.c \
   268    270     $(TOP)/src/pager.h \
   269    271     $(TOP)/src/parse.y \
   270    272     $(TOP)/src/pcache.c \
   271    273     $(TOP)/src/pcache.h \
   272    274     $(TOP)/src/pcache1.c \
   273    275     $(TOP)/src/pragma.c \
................................................................................
   412    414      $(TOP)/src/hash.h \
   413    415      $(TOP)/src/hwtime.h \
   414    416      keywordhash.h \
   415    417      $(TOP)/src/mutex.h \
   416    418      opcodes.h \
   417    419      $(TOP)/src/os.h \
   418    420      $(TOP)/src/os_common.h \
          421  +   $(TOP)/src/os_setup.h \
          422  +   $(TOP)/src/os_win.h \
   419    423      $(TOP)/src/pager.h \
   420    424      $(TOP)/src/pcache.h \
   421    425      parse.h  \
   422    426      sqlite3.h  \
   423    427      $(TOP)/src/sqlite3ext.h \
   424    428      $(TOP)/src/sqliteInt.h  \
   425    429      $(TOP)/src/sqliteLimit.h \

Changes to ext/fts3/fts3_expr.c.

   181    181     int *pnConsumed                         /* OUT: Number of bytes consumed */
   182    182   ){
   183    183     sqlite3_tokenizer *pTokenizer = pParse->pTokenizer;
   184    184     sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
   185    185     int rc;
   186    186     sqlite3_tokenizer_cursor *pCursor;
   187    187     Fts3Expr *pRet = 0;
   188         -  int nConsumed = 0;
          188  +  int i = 0;
   189    189   
   190         -  rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor);
          190  +  /* Set variable i to the maximum number of bytes of input to tokenize. */
          191  +  for(i=0; i<n; i++){
          192  +    if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
          193  +    if( z[i]=='*' || z[i]=='"' ) break;
          194  +  }
          195  +
          196  +  *pnConsumed = i;
          197  +  rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor);
   191    198     if( rc==SQLITE_OK ){
   192    199       const char *zToken;
   193    200       int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
   194    201       int nByte;                               /* total space to allocate */
   195    202   
   196    203       rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
   197         -
   198         -    if( (rc==SQLITE_OK || rc==SQLITE_DONE) && sqlite3_fts3_enable_parentheses ){
   199         -      int i;
   200         -      if( rc==SQLITE_DONE ) iStart = n;
   201         -      for(i=0; i<iStart; i++){
   202         -        if( z[i]=='(' ){
   203         -          pParse->nNest++;
   204         -          rc = fts3ExprParse(pParse, &z[i+1], n-i-1, &pRet, &nConsumed);
   205         -          if( rc==SQLITE_OK && !pRet ){
   206         -            rc = SQLITE_DONE;
   207         -          }
   208         -          nConsumed = (int)(i + 1 + nConsumed);
   209         -          break;
   210         -        }
   211         -
   212         -        if( z[i]==')' ){
   213         -          rc = SQLITE_DONE;
   214         -          pParse->nNest--;
   215         -          nConsumed = i+1;
   216         -          break;
   217         -        }
   218         -      }
   219         -    }
   220         -
   221         -    if( nConsumed==0 && rc==SQLITE_OK ){
          204  +    if( rc==SQLITE_OK ){
   222    205         nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
   223    206         pRet = (Fts3Expr *)fts3MallocZero(nByte);
   224    207         if( !pRet ){
   225    208           rc = SQLITE_NOMEM;
   226    209         }else{
   227    210           pRet->eType = FTSQUERY_PHRASE;
   228    211           pRet->pPhrase = (Fts3Phrase *)&pRet[1];
................................................................................
   248    231               iStart--;
   249    232             }else{
   250    233               break;
   251    234             }
   252    235           }
   253    236   
   254    237         }
   255         -      nConsumed = iEnd;
          238  +      *pnConsumed = iEnd;
          239  +    }else if( i && rc==SQLITE_DONE ){
          240  +      rc = SQLITE_OK;
   256    241       }
   257    242   
   258    243       pModule->xClose(pCursor);
   259    244     }
   260    245     
   261         -  *pnConsumed = nConsumed;
   262    246     *ppExpr = pRet;
   263    247     return rc;
   264    248   }
   265    249   
   266    250   
   267    251   /*
   268    252   ** Enlarge a memory allocation.  If an out-of-memory allocation occurs,
................................................................................
   504    488       *pnConsumed = (int)((zInput - z) + ii + 1);
   505    489       if( ii==nInput ){
   506    490         return SQLITE_ERROR;
   507    491       }
   508    492       return getNextString(pParse, &zInput[1], ii-1, ppExpr);
   509    493     }
   510    494   
          495  +  if( sqlite3_fts3_enable_parentheses ){
          496  +    if( *zInput=='(' ){
          497  +      int nConsumed = 0;
          498  +      pParse->nNest++;
          499  +      rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed);
          500  +      if( rc==SQLITE_OK && !*ppExpr ){ rc = SQLITE_DONE; }
          501  +      *pnConsumed = (int)(zInput - z) + 1 + nConsumed;
          502  +      return rc;
          503  +    }else if( *zInput==')' ){
          504  +      pParse->nNest--;
          505  +      *pnConsumed = (zInput - z) + 1;
          506  +      *ppExpr = 0;
          507  +      return SQLITE_DONE;
          508  +    }
          509  +  }
   511    510   
   512    511     /* If control flows to this point, this must be a regular token, or 
   513    512     ** the end of the input. Read a regular token using the sqlite3_tokenizer
   514    513     ** interface. Before doing so, figure out if there is an explicit
   515    514     ** column specifier for the token. 
   516    515     **
   517    516     ** TODO: Strangely, it is not possible to associate a column specifier
................................................................................
   622    621     const char *zIn = z;
   623    622     int rc = SQLITE_OK;
   624    623     int isRequirePhrase = 1;
   625    624   
   626    625     while( rc==SQLITE_OK ){
   627    626       Fts3Expr *p = 0;
   628    627       int nByte = 0;
          628  +
   629    629       rc = getNextNode(pParse, zIn, nIn, &p, &nByte);
          630  +    assert( nByte>0 || (rc!=SQLITE_OK && p==0) );
   630    631       if( rc==SQLITE_OK ){
          632  +      if( p ){
   631    633         int isPhrase;
   632    634   
   633    635         if( !sqlite3_fts3_enable_parentheses 
   634    636          && p->eType==FTSQUERY_PHRASE && pParse->isNot 
   635    637         ){
   636    638           /* Create an implicit NOT operator. */
   637    639           Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr));
................................................................................
   706    708               pRet = p;
   707    709             }
   708    710           }else{
   709    711             insertBinaryOperator(&pRet, pPrev, p);
   710    712           }
   711    713           isRequirePhrase = !isPhrase;
   712    714         }
          715  +        pPrev = p;
          716  +      }
   713    717         assert( nByte>0 );
   714    718       }
   715    719       assert( rc!=SQLITE_OK || (nByte>0 && nByte<=nIn) );
   716    720       nIn -= nByte;
   717    721       zIn += nByte;
   718         -    pPrev = p;
   719    722     }
   720    723   
   721    724     if( rc==SQLITE_DONE && pRet && isRequirePhrase ){
   722    725       rc = SQLITE_ERROR;
   723    726     }
   724    727   
   725    728     if( rc==SQLITE_DONE ){

Changes to main.mk.

   117    117     $(TOP)/src/mutex_noop.c \
   118    118     $(TOP)/src/mutex_unix.c \
   119    119     $(TOP)/src/mutex_w32.c \
   120    120     $(TOP)/src/notify.c \
   121    121     $(TOP)/src/os.c \
   122    122     $(TOP)/src/os.h \
   123    123     $(TOP)/src/os_common.h \
          124  +  $(TOP)/src/os_setup.h \
   124    125     $(TOP)/src/os_unix.c \
   125    126     $(TOP)/src/os_win.c \
          127  +  $(TOP)/src/os_win.h \
   126    128     $(TOP)/src/pager.c \
   127    129     $(TOP)/src/pager.h \
   128    130     $(TOP)/src/parse.y \
   129    131     $(TOP)/src/pcache.c \
   130    132     $(TOP)/src/pcache.h \
   131    133     $(TOP)/src/pcache1.c \
   132    134     $(TOP)/src/pragma.c \
................................................................................
   205    207     $(TOP)/ext/fts3/fts3_unicode.c \
   206    208     $(TOP)/ext/fts3/fts3_unicode2.c \
   207    209     $(TOP)/ext/fts3/fts3_write.c
   208    210   SRC += \
   209    211     $(TOP)/ext/icu/sqliteicu.h \
   210    212     $(TOP)/ext/icu/icu.c
   211    213   SRC += \
          214  +  $(TOP)/ext/rtree/sqlite3rtree.h \
   212    215     $(TOP)/ext/rtree/rtree.h \
   213    216     $(TOP)/ext/rtree/rtree.c
   214    217   
   215    218   
   216    219   # Generated source code files
   217    220   #
   218    221   SRC += \
................................................................................
   337    340      $(TOP)/src/hash.h \
   338    341      $(TOP)/src/hwtime.h \
   339    342      keywordhash.h \
   340    343      $(TOP)/src/mutex.h \
   341    344      opcodes.h \
   342    345      $(TOP)/src/os.h \
   343    346      $(TOP)/src/os_common.h \
          347  +   $(TOP)/src/os_setup.h \
          348  +   $(TOP)/src/os_win.h \
   344    349      $(TOP)/src/pager.h \
   345    350      $(TOP)/src/pcache.h \
   346    351      parse.h  \
   347    352      sqlite3.h  \
   348    353      $(TOP)/src/sqlite3ext.h \
   349    354      $(TOP)/src/sqliteInt.h  \
   350    355      $(TOP)/src/sqliteLimit.h \

Changes to src/func.c.

  1537   1537           zSep = ",";
  1538   1538           nSep = 1;
  1539   1539         }
  1540   1540         if( nSep ) sqlite3StrAccumAppend(pAccum, zSep, nSep);
  1541   1541       }
  1542   1542       zVal = (char*)sqlite3_value_text(argv[0]);
  1543   1543       nVal = sqlite3_value_bytes(argv[0]);
  1544         -    if( nVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal);
         1544  +    if( zVal ) sqlite3StrAccumAppend(pAccum, zVal, nVal);
  1545   1545     }
  1546   1546   }
  1547   1547   static void groupConcatFinalize(sqlite3_context *context){
  1548   1548     StrAccum *pAccum;
  1549   1549     pAccum = sqlite3_aggregate_context(context, 0);
  1550   1550     if( pAccum ){
  1551   1551       if( pAccum->accError==STRACCUM_TOOBIG ){

Changes to src/mutex_w32.c.

    15     15   
    16     16   /*
    17     17   ** The code in this file is only used if we are compiling multithreaded
    18     18   ** on a win32 system.
    19     19   */
    20     20   #ifdef SQLITE_MUTEX_W32
    21     21   
           22  +/*
           23  +** Include the header file for the Windows VFS.
           24  +*/
           25  +#include "os_win.h"
           26  +
    22     27   /*
    23     28   ** Each recursive mutex is an instance of the following structure.
    24     29   */
    25     30   struct sqlite3_mutex {
    26     31     CRITICAL_SECTION mutex;    /* Mutex controlling the lock */
    27     32     int id;                    /* Mutex type */
    28     33   #ifdef SQLITE_DEBUG

Changes to src/os.h.

    17     17   ** This header file is #include-ed by sqliteInt.h and thus ends up
    18     18   ** being included by every source file.
    19     19   */
    20     20   #ifndef _SQLITE_OS_H_
    21     21   #define _SQLITE_OS_H_
    22     22   
    23     23   /*
    24         -** Figure out if we are dealing with Unix, Windows, or some other
    25         -** operating system.  After the following block of preprocess macros,
    26         -** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER 
    27         -** will defined to either 1 or 0.  One of the four will be 1.  The other 
    28         -** three will be 0.
           24  +** Attempt to automatically detect the operating system and setup the
           25  +** necessary pre-processor macros for it.
    29     26   */
    30         -#if defined(SQLITE_OS_OTHER)
    31         -# if SQLITE_OS_OTHER==1
    32         -#   undef SQLITE_OS_UNIX
    33         -#   define SQLITE_OS_UNIX 0
    34         -#   undef SQLITE_OS_WIN
    35         -#   define SQLITE_OS_WIN 0
    36         -# else
    37         -#   undef SQLITE_OS_OTHER
    38         -# endif
    39         -#endif
    40         -#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER)
    41         -# define SQLITE_OS_OTHER 0
    42         -# ifndef SQLITE_OS_WIN
    43         -#   if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
    44         -#     define SQLITE_OS_WIN 1
    45         -#     define SQLITE_OS_UNIX 0
    46         -#   else
    47         -#     define SQLITE_OS_WIN 0
    48         -#     define SQLITE_OS_UNIX 1
    49         -#  endif
    50         -# else
    51         -#  define SQLITE_OS_UNIX 0
    52         -# endif
    53         -#else
    54         -# ifndef SQLITE_OS_WIN
    55         -#  define SQLITE_OS_WIN 0
    56         -# endif
    57         -#endif
    58         -
    59         -#if SQLITE_OS_WIN
    60         -# include <windows.h>
    61         -#endif
    62         -
    63         -/*
    64         -** Determine if we are dealing with Windows NT.
    65         -**
    66         -** We ought to be able to determine if we are compiling for win98 or winNT
    67         -** using the _WIN32_WINNT macro as follows:
    68         -**
    69         -** #if defined(_WIN32_WINNT)
    70         -** # define SQLITE_OS_WINNT 1
    71         -** #else
    72         -** # define SQLITE_OS_WINNT 0
    73         -** #endif
    74         -**
    75         -** However, vs2005 does not set _WIN32_WINNT by default, as it ought to,
    76         -** so the above test does not work.  We'll just assume that everything is
    77         -** winNT unless the programmer explicitly says otherwise by setting
    78         -** SQLITE_OS_WINNT to 0.
    79         -*/
    80         -#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT)
    81         -# define SQLITE_OS_WINNT 1
    82         -#endif
    83         -
    84         -/*
    85         -** Determine if we are dealing with WindowsCE - which has a much
    86         -** reduced API.
    87         -*/
    88         -#if defined(_WIN32_WCE)
    89         -# define SQLITE_OS_WINCE 1
    90         -#else
    91         -# define SQLITE_OS_WINCE 0
    92         -#endif
    93         -
    94         -/*
    95         -** Determine if we are dealing with WinRT, which provides only a subset of
    96         -** the full Win32 API.
    97         -*/
    98         -#if !defined(SQLITE_OS_WINRT)
    99         -# define SQLITE_OS_WINRT 0
   100         -#endif
           27  +#include "os_setup.h"
   101     28   
   102     29   /* If the SET_FULLSYNC macro is not defined above, then make it
   103     30   ** a no-op
   104     31   */
   105     32   #ifndef SET_FULLSYNC
   106     33   # define SET_FULLSYNC(x,y)
   107     34   #endif

Added src/os_setup.h.

            1  +/*
            2  +** 2013 November 25
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +******************************************************************************
           12  +**
           13  +** This file contains pre-processor directives related to operating system
           14  +** detection and/or setup.
           15  +*/
           16  +#ifndef _OS_SETUP_H_
           17  +#define _OS_SETUP_H_
           18  +
           19  +/*
           20  +** Figure out if we are dealing with Unix, Windows, or some other operating
           21  +** system.
           22  +**
           23  +** After the following block of preprocess macros, all of SQLITE_OS_UNIX,
           24  +** SQLITE_OS_WIN, and SQLITE_OS_OTHER will defined to either 1 or 0.  One of
           25  +** the three will be 1.  The other two will be 0.
           26  +*/
           27  +#if defined(SQLITE_OS_OTHER)
           28  +#  if SQLITE_OS_OTHER==1
           29  +#    undef SQLITE_OS_UNIX
           30  +#    define SQLITE_OS_UNIX 0
           31  +#    undef SQLITE_OS_WIN
           32  +#    define SQLITE_OS_WIN 0
           33  +#  else
           34  +#    undef SQLITE_OS_OTHER
           35  +#  endif
           36  +#endif
           37  +#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER)
           38  +#  define SQLITE_OS_OTHER 0
           39  +#  ifndef SQLITE_OS_WIN
           40  +#    if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \
           41  +        defined(__MINGW32__) || defined(__BORLANDC__)
           42  +#      define SQLITE_OS_WIN 1
           43  +#      define SQLITE_OS_UNIX 0
           44  +#    else
           45  +#      define SQLITE_OS_WIN 0
           46  +#      define SQLITE_OS_UNIX 1
           47  +#    endif
           48  +#  else
           49  +#    define SQLITE_OS_UNIX 0
           50  +#  endif
           51  +#else
           52  +#  ifndef SQLITE_OS_WIN
           53  +#    define SQLITE_OS_WIN 0
           54  +#  endif
           55  +#endif
           56  +
           57  +#endif /* _OS_SETUP_H_ */

Changes to src/os_win.c.

    11     11   ******************************************************************************
    12     12   **
    13     13   ** This file contains code that is specific to Windows.
    14     14   */
    15     15   #include "sqliteInt.h"
    16     16   #if SQLITE_OS_WIN               /* This file is used for Windows only */
    17     17   
    18         -#ifdef __CYGWIN__
    19         -# include <sys/cygwin.h>
    20         -# include <errno.h> /* amalgamator: keep */
    21         -#endif
    22         -
    23     18   /*
    24     19   ** Include code that is common to all os_*.c files
    25     20   */
    26     21   #include "os_common.h"
    27     22   
           23  +/*
           24  +** Include the header file for the Windows VFS.
           25  +*/
           26  +#include "os_win.h"
           27  +
    28     28   /*
    29     29   ** Compiling and using WAL mode requires several APIs that are only
    30     30   ** available in Windows platforms based on the NT kernel.
    31     31   */
    32     32   #if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL)
    33     33   #  error "WAL mode requires support from the Windows NT kernel, compile\
    34     34    with SQLITE_OMIT_WAL."
................................................................................
  1835   1835   #endif
  1836   1836   #ifndef SQLITE_WIN32_IOERR_RETRY_DELAY
  1837   1837   # define SQLITE_WIN32_IOERR_RETRY_DELAY 25
  1838   1838   #endif
  1839   1839   static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY;
  1840   1840   static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
  1841   1841   
         1842  +/*
         1843  +** The "winIoerrCanRetry1" macro is used to determine if a particular I/O
         1844  +** error code obtained via GetLastError() is eligible to be retried.  It
         1845  +** must accept the error code DWORD as its only argument and should return
         1846  +** non-zero if the error code is transient in nature and the operation
         1847  +** responsible for generating the original error might succeed upon being
         1848  +** retried.  The argument to this macro should be a variable.
         1849  +**
         1850  +** Additionally, a macro named "winIoerrCanRetry2" may be defined.  If it
         1851  +** is defined, it will be consulted only when the macro "winIoerrCanRetry1"
         1852  +** returns zero.  The "winIoerrCanRetry2" macro is completely optional and
         1853  +** may be used to include additional error codes in the set that should
         1854  +** result in the failing I/O operation being retried by the caller.  If
         1855  +** defined, the "winIoerrCanRetry2" macro must exhibit external semantics
         1856  +** identical to those of the "winIoerrCanRetry1" macro.
         1857  +*/
         1858  +#if !defined(winIoerrCanRetry1)
         1859  +#define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED)        || \
         1860  +                              ((a)==ERROR_SHARING_VIOLATION)    || \
         1861  +                              ((a)==ERROR_LOCK_VIOLATION)       || \
         1862  +                              ((a)==ERROR_DEV_NOT_EXIST)        || \
         1863  +                              ((a)==ERROR_NETNAME_DELETED)      || \
         1864  +                              ((a)==ERROR_SEM_TIMEOUT)          || \
         1865  +                              ((a)==ERROR_NETWORK_UNREACHABLE))
         1866  +#endif
         1867  +
  1842   1868   /*
  1843   1869   ** If a ReadFile() or WriteFile() error occurs, invoke this routine
  1844   1870   ** to see if it should be retried.  Return TRUE to retry.  Return FALSE
  1845   1871   ** to give up with an error.
  1846   1872   */
  1847   1873   static int winRetryIoerr(int *pnRetry, DWORD *pError){
  1848   1874     DWORD e = osGetLastError();
  1849   1875     if( *pnRetry>=winIoerrRetry ){
  1850   1876       if( pError ){
  1851   1877         *pError = e;
  1852   1878       }
  1853   1879       return 0;
  1854   1880     }
  1855         -  if( e==ERROR_ACCESS_DENIED ||
  1856         -      e==ERROR_LOCK_VIOLATION ||
  1857         -      e==ERROR_SHARING_VIOLATION ){
         1881  +  if( winIoerrCanRetry1(e) ){
         1882  +    sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
         1883  +    ++*pnRetry;
         1884  +    return 1;
         1885  +  }
         1886  +#if defined(winIoerrCanRetry2)
         1887  +  else if( winIoerrCanRetry2(e) ){
  1858   1888       sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
  1859   1889       ++*pnRetry;
  1860   1890       return 1;
  1861   1891     }
         1892  +#endif
  1862   1893     if( pError ){
  1863   1894       *pError = e;
  1864   1895     }
  1865   1896     return 0;
  1866   1897   }
  1867   1898   
  1868   1899   /*

Added src/os_win.h.

            1  +/*
            2  +** 2013 November 25
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +******************************************************************************
           12  +**
           13  +** This file contains code that is specific to Windows.
           14  +*/
           15  +#ifndef _OS_WIN_H_
           16  +#define _OS_WIN_H_
           17  +
           18  +/*
           19  +** Include the primary Windows SDK header file.
           20  +*/
           21  +#include "windows.h"
           22  +
           23  +#ifdef __CYGWIN__
           24  +# include <sys/cygwin.h>
           25  +# include <errno.h> /* amalgamator: dontcache */
           26  +#endif
           27  +
           28  +/*
           29  +** Determine if we are dealing with Windows NT.
           30  +**
           31  +** We ought to be able to determine if we are compiling for Windows 9x or
           32  +** Windows NT using the _WIN32_WINNT macro as follows:
           33  +**
           34  +** #if defined(_WIN32_WINNT)
           35  +** # define SQLITE_OS_WINNT 1
           36  +** #else
           37  +** # define SQLITE_OS_WINNT 0
           38  +** #endif
           39  +**
           40  +** However, Visual Studio 2005 does not set _WIN32_WINNT by default, as
           41  +** it ought to, so the above test does not work.  We'll just assume that
           42  +** everything is Windows NT unless the programmer explicitly says otherwise
           43  +** by setting SQLITE_OS_WINNT to 0.
           44  +*/
           45  +#if SQLITE_OS_WIN && !defined(SQLITE_OS_WINNT)
           46  +# define SQLITE_OS_WINNT 1
           47  +#endif
           48  +
           49  +/*
           50  +** Determine if we are dealing with Windows CE - which has a much reduced
           51  +** API.
           52  +*/
           53  +#if defined(_WIN32_WCE)
           54  +# define SQLITE_OS_WINCE 1
           55  +#else
           56  +# define SQLITE_OS_WINCE 0
           57  +#endif
           58  +
           59  +/*
           60  +** Determine if we are dealing with WinRT, which provides only a subset of
           61  +** the full Win32 API.
           62  +*/
           63  +#if !defined(SQLITE_OS_WINRT)
           64  +# define SQLITE_OS_WINRT 0
           65  +#endif
           66  +
           67  +#endif /* _OS_WIN_H_ */

Changes to src/pager.c.

   622    622     u8 journalMode;             /* One of the PAGER_JOURNALMODE_* values */
   623    623     u8 useJournal;              /* Use a rollback journal on this file */
   624    624     u8 noSync;                  /* Do not sync the journal if true */
   625    625     u8 fullSync;                /* Do extra syncs of the journal for robustness */
   626    626     u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
   627    627     u8 walSyncFlags;            /* SYNC_NORMAL or SYNC_FULL for wal writes */
   628    628     u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
   629         -  u8 tempFile;                /* zFilename is a temporary file */
          629  +  u8 tempFile;                /* zFilename is a temporary or immutable file */
          630  +  u8 noLock;                  /* Do not lock (except in WAL mode) */
   630    631     u8 readOnly;                /* True for a read-only database */
   631    632     u8 memDb;                   /* True to inhibit all file I/O */
   632    633   
   633    634     /**************************************************************************
   634    635     ** The following block contains those class members that change during
   635    636     ** routine opertion.  Class members not in this block are either fixed
   636    637     ** when the pager is first created or else only change when there is a
................................................................................
  1087   1088     int rc = SQLITE_OK;
  1088   1089   
  1089   1090     assert( !pPager->exclusiveMode || pPager->eLock==eLock );
  1090   1091     assert( eLock==NO_LOCK || eLock==SHARED_LOCK );
  1091   1092     assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 );
  1092   1093     if( isOpen(pPager->fd) ){
  1093   1094       assert( pPager->eLock>=eLock );
  1094         -    rc = sqlite3OsUnlock(pPager->fd, eLock);
         1095  +    rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock);
  1095   1096       if( pPager->eLock!=UNKNOWN_LOCK ){
  1096   1097         pPager->eLock = (u8)eLock;
  1097   1098       }
  1098   1099       IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
  1099   1100     }
  1100   1101     return rc;
  1101   1102   }
................................................................................
  1111   1112   ** of this.
  1112   1113   */
  1113   1114   static int pagerLockDb(Pager *pPager, int eLock){
  1114   1115     int rc = SQLITE_OK;
  1115   1116   
  1116   1117     assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK );
  1117   1118     if( pPager->eLock<eLock || pPager->eLock==UNKNOWN_LOCK ){
  1118         -    rc = sqlite3OsLock(pPager->fd, eLock);
         1119  +    rc = pPager->noLock ? SQLITE_OK : sqlite3OsLock(pPager->fd, eLock);
  1119   1120       if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){
  1120   1121         pPager->eLock = (u8)eLock;
  1121   1122         IOTRACE(("LOCK %p %d\n", pPager, eLock))
  1122   1123       }
  1123   1124     }
  1124   1125     return rc;
  1125   1126   }
................................................................................
  4670   4671       ** choose a default page size in case we have to create the
  4671   4672       ** database file. The default page size is the maximum of:
  4672   4673       **
  4673   4674       **    + SQLITE_DEFAULT_PAGE_SIZE,
  4674   4675       **    + The value returned by sqlite3OsSectorSize()
  4675   4676       **    + The largest page size that can be written atomically.
  4676   4677       */
  4677         -    if( rc==SQLITE_OK && !readOnly ){
         4678  +    if( rc==SQLITE_OK ){
         4679  +      int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
         4680  +      if( !readOnly ){
  4678   4681         setSectorSize(pPager);
  4679   4682         assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE);
  4680   4683         if( szPageDflt<pPager->sectorSize ){
  4681   4684           if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
  4682   4685             szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE;
  4683   4686           }else{
  4684   4687             szPageDflt = (u32)pPager->sectorSize;
  4685   4688           }
  4686   4689         }
  4687   4690   #ifdef SQLITE_ENABLE_ATOMIC_WRITE
  4688   4691         {
  4689         -        int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
  4690   4692           int ii;
  4691   4693           assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
  4692   4694           assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
  4693   4695           assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536);
  4694   4696           for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){
  4695   4697             if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){
  4696   4698               szPageDflt = ii;
  4697   4699             }
  4698   4700           }
  4699   4701         }
  4700   4702   #endif
         4703  +      }
         4704  +      pPager->noLock = sqlite3_uri_boolean(zFilename, "nolock", 0);
         4705  +      if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0
         4706  +       || sqlite3_uri_boolean(zFilename, "immutable", 0) ){
         4707  +          vfsFlags |= SQLITE_OPEN_READONLY;
         4708  +          goto act_like_temp_file;
         4709  +      }
  4701   4710       }
  4702   4711     }else{
  4703   4712       /* If a temporary file is requested, it is not opened immediately.
  4704   4713       ** In this case we accept the default page size and delay actually
  4705   4714       ** opening the file until the first call to OsWrite().
  4706   4715       **
  4707   4716       ** This branch is also run for an in-memory database. An in-memory
  4708   4717       ** database is the same as a temp-file that is never written out to
  4709   4718       ** disk and uses an in-memory rollback journal.
         4719  +    **
         4720  +    ** This branch also runs for files marked as immutable.
  4710   4721       */ 
         4722  +act_like_temp_file:
  4711   4723       tempFile = 1;
  4712         -    pPager->eState = PAGER_READER;
  4713         -    pPager->eLock = EXCLUSIVE_LOCK;
         4724  +    pPager->eState = PAGER_READER;     /* Pretend we already have a lock */
         4725  +    pPager->eLock = EXCLUSIVE_LOCK;    /* Pretend we are in EXCLUSIVE locking mode */
         4726  +    pPager->noLock = 1;                /* Do no locking */
  4714   4727       readOnly = (vfsFlags&SQLITE_OPEN_READONLY);
  4715   4728     }
  4716   4729   
  4717   4730     /* The following call to PagerSetPagesize() serves to set the value of 
  4718   4731     ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer.
  4719   4732     */
  4720   4733     if( rc==SQLITE_OK ){
................................................................................
  4747   4760     /* pPager->stmtInUse = 0; */
  4748   4761     /* pPager->nRef = 0; */
  4749   4762     /* pPager->stmtSize = 0; */
  4750   4763     /* pPager->stmtJSize = 0; */
  4751   4764     /* pPager->nPage = 0; */
  4752   4765     pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
  4753   4766     /* pPager->state = PAGER_UNLOCK; */
  4754         -#if 0
  4755         -  assert( pPager->state == (tempFile ? PAGER_EXCLUSIVE : PAGER_UNLOCK) );
  4756         -#endif
  4757   4767     /* pPager->errMask = 0; */
  4758   4768     pPager->tempFile = (u8)tempFile;
  4759   4769     assert( tempFile==PAGER_LOCKINGMODE_NORMAL 
  4760   4770             || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
  4761   4771     assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
  4762   4772     pPager->exclusiveMode = (u8)tempFile; 
  4763   4773     pPager->changeCountDone = pPager->tempFile;

Changes to src/sqlite.h.in.

   551    551   ** way around.  The SQLITE_IOCAP_SEQUENTIAL property means that
   552    552   ** information is written to disk in the same order as calls
   553    553   ** to xWrite().  The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that
   554    554   ** after reboot following a crash or power loss, the only bytes in a
   555    555   ** file that were written at the application level might have changed
   556    556   ** and that adjacent bytes, even bytes within the same sector are
   557    557   ** guaranteed to be unchanged.  The SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
   558         -** flag indicate that a file cannot be deleted when open.
          558  +** flag indicate that a file cannot be deleted when open.  The
          559  +** SQLITE_IOCAP_IMMUTABLE flag indicates that the file is on
          560  +** read-only media and cannot be changed even by processes with
          561  +** elevated privileges.
   559    562   */
   560    563   #define SQLITE_IOCAP_ATOMIC                 0x00000001
   561    564   #define SQLITE_IOCAP_ATOMIC512              0x00000002
   562    565   #define SQLITE_IOCAP_ATOMIC1K               0x00000004
   563    566   #define SQLITE_IOCAP_ATOMIC2K               0x00000008
   564    567   #define SQLITE_IOCAP_ATOMIC4K               0x00000010
   565    568   #define SQLITE_IOCAP_ATOMIC8K               0x00000020
................................................................................
   566    569   #define SQLITE_IOCAP_ATOMIC16K              0x00000040
   567    570   #define SQLITE_IOCAP_ATOMIC32K              0x00000080
   568    571   #define SQLITE_IOCAP_ATOMIC64K              0x00000100
   569    572   #define SQLITE_IOCAP_SAFE_APPEND            0x00000200
   570    573   #define SQLITE_IOCAP_SEQUENTIAL             0x00000400
   571    574   #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN  0x00000800
   572    575   #define SQLITE_IOCAP_POWERSAFE_OVERWRITE    0x00001000
          576  +#define SQLITE_IOCAP_IMMUTABLE              0x00002000
   573    577   
   574    578   /*
   575    579   ** CAPI3REF: File Locking Levels
   576    580   **
   577    581   ** SQLite uses one of these integer values as the second
   578    582   ** argument to calls it makes to the xLock() and xUnlock() methods
   579    583   ** of an [sqlite3_io_methods] object.
................................................................................
  2781   2785   **     "private". ^Setting it to "shared" is equivalent to setting the
  2782   2786   **     SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to
  2783   2787   **     sqlite3_open_v2(). ^Setting the cache parameter to "private" is 
  2784   2788   **     equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit.
  2785   2789   **     ^If sqlite3_open_v2() is used and the "cache" parameter is present in
  2786   2790   **     a URI filename, its value overrides any behavior requested by setting
  2787   2791   **     SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
         2792  +**
         2793  +**  <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or
         2794  +**     "1") or "false" (or "off" or "no" or "0") to indicate that the
         2795  +**     [powersafe overwrite] property does or does not apply to the
         2796  +**     storage media on which the database file resides.  ^The psow query
         2797  +**     parameter only works for the built-in unix and Windows VFSes.
         2798  +**
         2799  +**  <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
         2800  +**     which if set disables file locking in rollback journal modes.  This
         2801  +**     is useful for accessing a database on a filesystem that does not
         2802  +**     support locking.  Caution:  Database corruption might result if two
         2803  +**     or more processes write to the same database and any one of those
         2804  +**     processes uses nolock=1.
         2805  +**
         2806  +**  <li> <b>immutable</b>: ^The immutable parameter is a boolean query
         2807  +**     parameter that indicates that the database file is stored on
         2808  +**     read-only media.  ^When immutable is set, SQLite assumes that the
         2809  +**     database file cannot be changed, even by a process with higher
         2810  +**     privilege, and so the database is opened read-only and all locking
         2811  +**     and change detection is disabled.  Caution: Setting the immutable
         2812  +**     property on a database file that does in fact change can result
         2813  +**     in incorrect query results and/or [SQLITE_CORRUPT] errors.
         2814  +**     See also: [SQLITE_IOCAP_IMMUTABLE].
         2815  +**       
  2788   2816   ** </ul>
  2789   2817   **
  2790   2818   ** ^Specifying an unknown parameter in the query component of a URI is not an
  2791   2819   ** error.  Future versions of SQLite might understand additional query
  2792   2820   ** parameters.  See "[query parameters with special meaning to SQLite]" for
  2793   2821   ** additional information.
  2794   2822   **
................................................................................
  2810   2838   **          C:. Note that the %20 escaping in this example is not strictly 
  2811   2839   **          necessary - space characters can be used literally
  2812   2840   **          in URI filenames.
  2813   2841   ** <tr><td> file:data.db?mode=ro&cache=private <td> 
  2814   2842   **          Open file "data.db" in the current directory for read-only access.
  2815   2843   **          Regardless of whether or not shared-cache mode is enabled by
  2816   2844   **          default, use a private cache.
  2817         -** <tr><td> file:/home/fred/data.db?vfs=unix-nolock <td>
  2818         -**          Open file "/home/fred/data.db". Use the special VFS "unix-nolock".
         2845  +** <tr><td> file:/home/fred/data.db?vfs=unix-dotfile <td>
         2846  +**          Open file "/home/fred/data.db". Use the special VFS "unix-dotfile"
         2847  +**          that uses dot-files in place of posix advisory locking.
  2819   2848   ** <tr><td> file:data.db?mode=readonly <td> 
  2820   2849   **          An error. "readonly" is not a valid option for the "mode" parameter.
  2821   2850   ** </table>
  2822   2851   **
  2823   2852   ** ^URI hexadecimal escape sequences (%HH) are supported within the path and
  2824   2853   ** query components of a URI. A hexadecimal escape sequence consists of a
  2825   2854   ** percent sign - "%" - followed by exactly two hexadecimal digits 

Changes to src/test1.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing all sorts of SQLite interfaces.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   */
    16     16   #include "sqliteInt.h"
           17  +#if SQLITE_OS_WIN
           18  +#  include "os_win.h"
           19  +#endif
           20  +
    17     21   #include "vdbeInt.h"
    18     22   #include "tcl.h"
    19     23   #include <stdlib.h>
    20     24   #include <string.h>
    21     25   
    22     26   /*
    23     27   ** This is a copy of the first part of the SqliteDb structure in 

Changes to src/test_config.c.

    16     16   ** The focus of this file is providing the TCL testing layer
    17     17   ** access to compile-time constants.
    18     18   */
    19     19   
    20     20   #include "sqliteLimit.h"
    21     21   
    22     22   #include "sqliteInt.h"
           23  +#if SQLITE_OS_WIN
           24  +#  include "os_win.h"
           25  +#endif
           26  +
    23     27   #include "tcl.h"
    24     28   #include <stdlib.h>
    25     29   #include <string.h>
    26     30   
    27     31   /*
    28     32   ** Macro to stringify the results of the evaluation a pre-processor
    29     33   ** macro. i.e. so that STRINGVALUE(SQLITE_NOMEM) -> "7".

Changes to src/test_osinst.c.

    66     66   **         rc       INTEGER,          // Return value
    67     67   **         size     INTEGER,          // Bytes read or written
    68     68   **         offset   INTEGER           // File offset read or written
    69     69   **       );
    70     70   */
    71     71   
    72     72   #include "sqlite3.h"
           73  +
           74  +#include "os_setup.h"
           75  +#if SQLITE_OS_WIN
           76  +#  include "os_win.h"
           77  +#endif
           78  +
    73     79   #include <string.h>
    74     80   #include <assert.h>
    75     81   
    76     82   
    77     83   /*
    78     84   ** Maximum pathname length supported by the vfslog backend.
    79     85   */
................................................................................
   217    223   #include <sys/time.h>
   218    224   static sqlite3_uint64 vfslog_time(){
   219    225     struct timeval sTime;
   220    226     gettimeofday(&sTime, 0);
   221    227     return sTime.tv_usec + (sqlite3_uint64)sTime.tv_sec * 1000000;
   222    228   }
   223    229   #elif SQLITE_OS_WIN
   224         -#include <windows.h>
   225    230   #include <time.h>
   226    231   static sqlite3_uint64 vfslog_time(){
   227    232     FILETIME ft;
   228    233     sqlite3_uint64 u64time = 0;
   229    234    
   230    235     GetSystemTimeAsFileTime(&ft);
   231    236   

Changes to src/test_quota.c.

    40     40   #define sqlite3_mutex_enter(X)
    41     41   #define sqlite3_mutex_try(X)      SQLITE_OK
    42     42   #define sqlite3_mutex_leave(X)
    43     43   #define sqlite3_mutex_held(X)     ((void)(X),1)
    44     44   #define sqlite3_mutex_notheld(X)  ((void)(X),1)
    45     45   #endif /* SQLITE_THREADSAFE==0 */
    46     46   
    47         -
    48         -/*
    49         -** Figure out if we are dealing with Unix, Windows, or some other
    50         -** operating system.  After the following block of preprocess macros,
    51         -** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, and SQLITE_OS_OTHER 
    52         -** will defined to either 1 or 0.  One of the four will be 1.  The other 
    53         -** three will be 0.
    54         -*/
    55         -#if defined(SQLITE_OS_OTHER)
    56         -# if SQLITE_OS_OTHER==1
    57         -#   undef SQLITE_OS_UNIX
    58         -#   define SQLITE_OS_UNIX 0
    59         -#   undef SQLITE_OS_WIN
    60         -#   define SQLITE_OS_WIN 0
    61         -# else
    62         -#   undef SQLITE_OS_OTHER
    63         -# endif
    64         -#endif
    65         -#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER)
    66         -# define SQLITE_OS_OTHER 0
    67         -# ifndef SQLITE_OS_WIN
    68         -#   if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) \
    69         -                       || defined(__MINGW32__) || defined(__BORLANDC__)
    70         -#     define SQLITE_OS_WIN 1
    71         -#     define SQLITE_OS_UNIX 0
    72         -#   else
    73         -#     define SQLITE_OS_WIN 0
    74         -#     define SQLITE_OS_UNIX 1
    75         -#  endif
    76         -# else
    77         -#  define SQLITE_OS_UNIX 0
    78         -# endif
    79         -#else
    80         -# ifndef SQLITE_OS_WIN
    81         -#  define SQLITE_OS_WIN 0
    82         -# endif
    83         -#endif
           47  +#include "os_setup.h"
    84     48   
    85     49   #if SQLITE_OS_UNIX
    86     50   # include <unistd.h>
    87     51   #endif
    88     52   #if SQLITE_OS_WIN
    89         -# include <windows.h>
           53  +# include "os_win.h"
    90     54   # include <io.h>
    91     55   #endif
    92     56   
    93     57   
    94     58   /************************ Object Definitions ******************************/
    95     59   
    96     60   /* Forward declaration of all object types */

Changes to src/test_quota.h.

    27     27   ** continues as if nothing had happened.
    28     28   */
    29     29   #ifndef _QUOTA_H_
    30     30   #include "sqlite3.h"
    31     31   #include <stdio.h>
    32     32   #include <sys/types.h>
    33     33   #include <sys/stat.h>
    34         -#if SQLITE_OS_UNIX
    35         -# include <unistd.h>
    36         -#endif
    37         -#if SQLITE_OS_WIN
    38         -# include <windows.h>
    39         -#endif
    40     34   
    41     35   /* Make this callable from C++ */
    42     36   #ifdef __cplusplus
    43     37   extern "C" {
    44     38   #endif
    45     39   
    46     40   /*

Changes to src/test_vfs.c.

   123    123   #define TESTVFS_CLOSE_MASK        0x00000800
   124    124   #define TESTVFS_WRITE_MASK        0x00001000
   125    125   #define TESTVFS_TRUNCATE_MASK     0x00002000
   126    126   #define TESTVFS_ACCESS_MASK       0x00004000
   127    127   #define TESTVFS_FULLPATHNAME_MASK 0x00008000
   128    128   #define TESTVFS_READ_MASK         0x00010000
   129    129   #define TESTVFS_UNLOCK_MASK       0x00020000
          130  +#define TESTVFS_LOCK_MASK         0x00040000
          131  +#define TESTVFS_CKLOCK_MASK       0x00080000
   130    132   
   131         -#define TESTVFS_ALL_MASK          0x0003FFFF
          133  +#define TESTVFS_ALL_MASK          0x000FFFFF
   132    134   
   133    135   
   134    136   #define TESTVFS_MAX_PAGES 1024
   135    137   
   136    138   /*
   137    139   ** A shared-memory buffer. There is one of these objects for each shared
   138    140   ** memory region opened by clients. If two clients open the same file,
................................................................................
   462    464     return sqlite3OsFileSize(p->pReal, pSize);
   463    465   }
   464    466   
   465    467   /*
   466    468   ** Lock an tvfs-file.
   467    469   */
   468    470   static int tvfsLock(sqlite3_file *pFile, int eLock){
   469         -  TestvfsFd *p = tvfsGetFd(pFile);
   470         -  return sqlite3OsLock(p->pReal, eLock);
          471  +  TestvfsFd *pFd = tvfsGetFd(pFile);
          472  +  Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
          473  +  if( p->pScript && p->mask&TESTVFS_LOCK_MASK ){
          474  +    char zLock[30];
          475  +    sqlite3_snprintf(sizeof(zLock),zLock,"%d",eLock);
          476  +    tvfsExecTcl(p, "xLock", Tcl_NewStringObj(pFd->zFilename, -1), 
          477  +                   Tcl_NewStringObj(zLock, -1), 0, 0);
          478  +  }
          479  +  return sqlite3OsLock(pFd->pReal, eLock);
   471    480   }
   472    481   
   473    482   /*
   474    483   ** Unlock an tvfs-file.
   475    484   */
   476    485   static int tvfsUnlock(sqlite3_file *pFile, int eLock){
   477    486     TestvfsFd *pFd = tvfsGetFd(pFile);
   478    487     Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
          488  +  if( p->pScript && p->mask&TESTVFS_UNLOCK_MASK ){
          489  +    char zLock[30];
          490  +    sqlite3_snprintf(sizeof(zLock),zLock,"%d",eLock);
          491  +    tvfsExecTcl(p, "xUnlock", Tcl_NewStringObj(pFd->zFilename, -1), 
          492  +                   Tcl_NewStringObj(zLock, -1), 0, 0);
          493  +  }
   479    494     if( p->mask&TESTVFS_WRITE_MASK && tvfsInjectIoerr(p) ){
   480    495       return SQLITE_IOERR_UNLOCK;
   481    496     }
   482    497     return sqlite3OsUnlock(pFd->pReal, eLock);
   483    498   }
   484    499   
   485    500   /*
   486    501   ** Check if another file-handle holds a RESERVED lock on an tvfs-file.
   487    502   */
   488    503   static int tvfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
   489         -  TestvfsFd *p = tvfsGetFd(pFile);
   490         -  return sqlite3OsCheckReservedLock(p->pReal, pResOut);
          504  +  TestvfsFd *pFd = tvfsGetFd(pFile);
          505  +  Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
          506  +  if( p->pScript && p->mask&TESTVFS_CKLOCK_MASK ){
          507  +    tvfsExecTcl(p, "xCheckReservedLock", Tcl_NewStringObj(pFd->zFilename, -1),
          508  +                   0, 0, 0);
          509  +  }
          510  +  return sqlite3OsCheckReservedLock(pFd->pReal, pResOut);
   491    511   }
   492    512   
   493    513   /*
   494    514   ** File control method. For custom operations on an tvfs-file.
   495    515   */
   496    516   static int tvfsFileControl(sqlite3_file *pFile, int op, void *pArg){
   497    517     TestvfsFd *p = tvfsGetFd(pFile);
................................................................................
  1107   1127           if( pgsz==0 ) pgsz = 65536;
  1108   1128           Tcl_AppendObjToObj(pObj, Tcl_NewByteArrayObj(pBuffer->aPage[i], pgsz));
  1109   1129         }
  1110   1130         Tcl_SetObjResult(interp, pObj);
  1111   1131         break;
  1112   1132       }
  1113   1133   
         1134  +    /*  TESTVFS filter METHOD-LIST
         1135  +    **
         1136  +    **     Activate special processing for those methods contained in the list
         1137  +    */
  1114   1138       case CMD_FILTER: {
  1115   1139         static struct VfsMethod {
  1116   1140           char *zName;
  1117   1141           int mask;
  1118   1142         } vfsmethod [] = {
  1119   1143           { "xShmOpen",      TESTVFS_SHMOPEN_MASK },
  1120   1144           { "xShmLock",      TESTVFS_SHMLOCK_MASK },
................................................................................
  1127   1151           { "xRead",         TESTVFS_READ_MASK },
  1128   1152           { "xTruncate",     TESTVFS_TRUNCATE_MASK },
  1129   1153           { "xOpen",         TESTVFS_OPEN_MASK },
  1130   1154           { "xClose",        TESTVFS_CLOSE_MASK },
  1131   1155           { "xAccess",       TESTVFS_ACCESS_MASK },
  1132   1156           { "xFullPathname", TESTVFS_FULLPATHNAME_MASK },
  1133   1157           { "xUnlock",       TESTVFS_UNLOCK_MASK },
         1158  +        { "xLock",              TESTVFS_LOCK_MASK },
         1159  +        { "xCheckReservedLock", TESTVFS_CKLOCK_MASK },
  1134   1160         };
  1135   1161         Tcl_Obj **apElem = 0;
  1136   1162         int nElem = 0;
  1137   1163         int i;
  1138   1164         int mask = 0;
  1139   1165         if( objc!=3 ){
  1140   1166           Tcl_WrongNumArgs(interp, 2, objv, "LIST");
................................................................................
  1158   1184             return TCL_ERROR;
  1159   1185           }
  1160   1186         }
  1161   1187         p->mask = mask;
  1162   1188         break;
  1163   1189       }
  1164   1190   
         1191  +    /*
         1192  +    **  TESTVFS script ?SCRIPT?
         1193  +    **
         1194  +    **  Query or set the script to be run when filtered VFS events
         1195  +    **  occur.
         1196  +    */
  1165   1197       case CMD_SCRIPT: {
  1166   1198         if( objc==3 ){
  1167   1199           int nByte;
  1168   1200           if( p->pScript ){
  1169   1201             Tcl_DecrRefCount(p->pScript);
  1170   1202             p->pScript = 0;
  1171   1203           }
................................................................................
  1244   1276           { "atomic16k",             SQLITE_IOCAP_ATOMIC16K             },
  1245   1277           { "atomic32k",             SQLITE_IOCAP_ATOMIC32K             },
  1246   1278           { "atomic64k",             SQLITE_IOCAP_ATOMIC64K             },
  1247   1279           { "sequential",            SQLITE_IOCAP_SEQUENTIAL            },
  1248   1280           { "safe_append",           SQLITE_IOCAP_SAFE_APPEND           },
  1249   1281           { "undeletable_when_open", SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN },
  1250   1282           { "powersafe_overwrite",   SQLITE_IOCAP_POWERSAFE_OVERWRITE   },
         1283  +        { "immutable",             SQLITE_IOCAP_IMMUTABLE             },
  1251   1284           { 0, 0 }
  1252   1285         };
  1253   1286         Tcl_Obj *pRet;
  1254   1287         int iFlag;
  1255   1288   
  1256   1289         if( objc>3 ){
  1257   1290           Tcl_WrongNumArgs(interp, 2, objv, "?ATTR-LIST?");

Changes to src/where.c.

  3757   3757   ){
  3758   3758     int i, j;
  3759   3759     if( pX->nLTerm >= pY->nLTerm ) return 0; /* X is not a subset of Y */
  3760   3760     if( pX->rRun >= pY->rRun ){
  3761   3761       if( pX->rRun > pY->rRun ) return 0;    /* X costs more than Y */
  3762   3762       if( pX->nOut > pY->nOut ) return 0;    /* X costs more than Y */
  3763   3763     }
  3764         -  for(j=0, i=pX->nLTerm-1; i>=0; i--){
         3764  +  for(i=pX->nLTerm-1; i>=0; i--){
  3765   3765       for(j=pY->nLTerm-1; j>=0; j--){
  3766   3766         if( pY->aLTerm[j]==pX->aLTerm[i] ) break;
  3767   3767       }
  3768   3768       if( j<0 ) return 0;  /* X not a subset of Y since term X[i] not used by Y */
  3769   3769     }
  3770   3770     return 1;  /* All conditions meet */
  3771   3771   }

Changes to test/fts3defer2.test.

    54     54   do_execsql_test 1.2.0 {
    55     55     SELECT content FROM t1 WHERE t1 MATCH 'f (e a)';
    56     56   } {{a b c d e f a x y}}
    57     57   
    58     58   do_execsql_test 1.2.1 {
    59     59     SELECT content FROM t1 WHERE t1 MATCH 'f (e NEAR/2 a)';
    60     60   } {{a b c d e f a x y}}
           61  +
    61     62   
    62     63   do_execsql_test 1.2.2 {
    63     64     SELECT snippet(t1, '[', ']'), offsets(t1), mit(matchinfo(t1, 'pcxnal'))
    64     65     FROM t1 WHERE t1 MATCH 'f (e NEAR/2 a)';
    65     66   } [list                              \
    66     67      {a b c d [e] [f] [a] x y}         \
    67     68      {0 1 8 1 0 0 10 1 0 2 12 1}       \

Changes to test/fts3expr.test.

   505    505   do_test fts3expr-8.5 { test_fts3expr "((blah.))" } {PHRASE 3 0 blah}
   506    506   do_test fts3expr-8.6 { test_fts3expr "(((blah,)))" } {PHRASE 3 0 blah}
   507    507   do_test fts3expr-8.7 { test_fts3expr "((((blah!))))" } {PHRASE 3 0 blah}
   508    508   
   509    509   do_test fts3expr-8.8 { test_fts3expr "(,(blah-),)" } {PHRASE 3 0 blah}
   510    510   
   511    511   set sqlite_fts3_enable_parentheses 0
          512  +
          513  +do_test fts3expr-9.1 {
          514  +  test_fts3expr "f (e NEAR/2 a)"
          515  +} {AND {PHRASE 3 0 f} {NEAR/2 {PHRASE 3 0 e} {PHRASE 3 0 a}}}
          516  +
   512    517   finish_test

Added test/fts3expr4.test.

            1  +# 2014 May 7
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#*************************************************************************
           11  +# This file implements regression tests for SQLite library.  The
           12  +# focus of this script is testing the FTS3 module.
           13  +#
           14  +
           15  +set testdir [file dirname $argv0]
           16  +source $testdir/tester.tcl
           17  +set testprefix fts3expr4
           18  +
           19  +# If SQLITE_ENABLE_FTS3 is defined, omit this file.
           20  +ifcapable !fts3||!icu {
           21  +  finish_test
           22  +  return
           23  +}
           24  +
           25  +set sqlite_fts3_enable_parentheses 1
           26  +
           27  +proc test_icu_fts3expr {expr} {
           28  +  db one {SELECT fts3_exprtest('icu', $expr, 'a', 'b', 'c')}
           29  +}
           30  +
           31  +proc do_icu_expr_test {tn expr res} {
           32  +  uplevel [list do_test $tn [list test_icu_fts3expr $expr] $res]
           33  +}
           34  +
           35  +#-------------------------------------------------------------------------
           36  +#
           37  +do_icu_expr_test 1.1 "abcd"    {PHRASE 3 0 abcd}
           38  +do_icu_expr_test 1.2 " tag "   {PHRASE 3 0 tag}
           39  +do_icu_expr_test 1.3 {"x y z"} {PHRASE 3 0 x y z}
           40  +do_icu_expr_test 1.4 {x OR y}       {OR {PHRASE 3 0 x} {PHRASE 3 0 y}}
           41  +do_icu_expr_test 1.5 {(x OR y)}     {OR {PHRASE 3 0 x} {PHRASE 3 0 y}}
           42  +do_icu_expr_test 1.6 { "(x OR y)" } {PHRASE 3 0 ( x or y )}
           43  +
           44  +# In "col:word", if "col" is not the name of a column, the entire thing
           45  +# is passed to the tokenizer.
           46  +#
           47  +do_icu_expr_test 1.7 {a:word} {PHRASE 0 0 word}
           48  +do_icu_expr_test 1.8 {d:word} {PHRASE 3 0 d:word}
           49  +
           50  +set sqlite_fts3_enable_parentheses 0
           51  +
           52  +do_icu_expr_test 2.1 {
           53  +  f (e NEAR/2 a)
           54  +} {AND {AND {AND {PHRASE 3 0 f} {PHRASE 3 0 (}} {NEAR/2 {PHRASE 3 0 e} {PHRASE 3 0 a}}} {PHRASE 3 0 )}}
           55  +
           56  +finish_test
           57  +

Changes to test/func.test.

  1190   1190   } {software}
  1191   1191   do_test func-24.12 {
  1192   1192     execsql {
  1193   1193       SELECT group_concat(CASE t1 WHEN 'this' THEN ''
  1194   1194                             WHEN 'program' THEN null ELSE t1 END) FROM tbl1
  1195   1195     }
  1196   1196   } {,is,free,software}
         1197  +# Tests to verify ticket http://www.sqlite.org/src/tktview/55746f9e65f8587c0
         1198  +do_test func-24.13 {
         1199  +  execsql {
         1200  +    SELECT typeof(group_concat(x)) FROM (SELECT '' AS x);
         1201  +  }
         1202  +} {text}
         1203  +do_test func-24.14 {
         1204  +  execsql {
         1205  +    SELECT typeof(group_concat(x,''))
         1206  +      FROM (SELECT '' AS x UNION ALL SELECT '');
         1207  +  }
         1208  +} {text}
  1197   1209   
  1198   1210   
  1199   1211   # Use the test_isolation function to make sure that type conversions
  1200   1212   # on function arguments do not effect subsequent arguments.
  1201   1213   #
  1202   1214   do_test func-25.1 {
  1203   1215     execsql {SELECT test_isolation(t1,t1) FROM tbl1}

Changes to test/fuzz.test.

   281    281                        SELECT ALL 123456789.1234567899
   282    282                     ) IN (SELECT 2147483649) 
   283    283                 FROM sqlite_master
   284    284              ) NOT IN (SELECT ALL 'The')
   285    285           )
   286    286        ))
   287    287     }
   288         -} {0 -4294967298}
          288  +} {0 {{}}}
   289    289   
   290    290   # At one point the following INSERT statement caused an assert() to fail.
   291    291   # 
   292    292   do_test fuzz-1.19 {
   293    293     execsql { CREATE TABLE t1(a) }
   294    294     catchsql {
   295    295       INSERT INTO t1 VALUES( 

Added test/nolock.test.

            1  +# 2014-05-07
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# This file implements regression tests for SQLite library.  The
           13  +# focus of this file is testing the nolock=1 and immutable=1 query
           14  +# parameters and the SQLITE_IOCAP_IMMUTABLE device characteristic.
           15  +#
           16  +
           17  +set testdir [file dirname $argv0]
           18  +source $testdir/tester.tcl
           19  +
           20  +unset -nocomplain tvfs_calls
           21  +proc tvfs_reset {} {
           22  +  global tvfs_calls
           23  +  array set tvfs_calls {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0}
           24  +}
           25  +proc tvfs_callback {op args} {
           26  +  global tvfs_calls
           27  +  incr tvfs_calls($op)
           28  +  return SQLITE_OK
           29  +}
           30  +tvfs_reset
           31  +
           32  +testvfs tvfs
           33  +tvfs script tvfs_callback
           34  +tvfs filter {xLock xUnlock xCheckReservedLock xAccess}
           35  +
           36  +############################################################################
           37  +# Verify that the nolock=1 query parameter for URI filenames disables all
           38  +# calls to xLock and xUnlock for rollback databases.
           39  +#
           40  +do_test nolock-1.0 {
           41  +  db close
           42  +  forcedelete test.db
           43  +  tvfs_reset
           44  +  sqlite db test.db -vfs tvfs
           45  +  db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);}
           46  +  list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
           47  +       xCheckReservedLock $::tvfs_calls(xCheckReservedLock)
           48  +} {xLock 7 xUnlock 5 xCheckReservedLock 0}
           49  +
           50  +do_test nolock-1.1 {
           51  +  db close
           52  +  forcedelete test.db
           53  +  tvfs_reset
           54  +  sqlite db file:test.db?nolock=0 -vfs tvfs -uri 1
           55  +  db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);}
           56  +  list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
           57  +       xCheckReservedLock $::tvfs_calls(xCheckReservedLock)
           58  +} {xLock 7 xUnlock 5 xCheckReservedLock 0}
           59  +
           60  +do_test nolock-1.2 {
           61  +  db close
           62  +  forcedelete test.db
           63  +  tvfs_reset
           64  +  sqlite db file:test.db?nolock=1 -vfs tvfs -uri 1
           65  +  db eval {CREATE TABLE t1(a,b,c); INSERT INTO t1 VALUES(1,2,3);}
           66  +  list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
           67  +       xCheckReservedLock $::tvfs_calls(xCheckReservedLock)
           68  +} {xLock 0 xUnlock 0 xCheckReservedLock 0}
           69  +
           70  +do_test nolock-1.3 {
           71  +  db close
           72  +  tvfs_reset
           73  +  sqlite db file:test.db?nolock=0 -vfs tvfs -uri 1 -readonly 1
           74  +  db eval {SELECT * FROM t1}
           75  +  list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
           76  +       xCheckReservedLock $::tvfs_calls(xCheckReservedLock)
           77  +} {xLock 2 xUnlock 2 xCheckReservedLock 0}
           78  +
           79  +do_test nolock-1.4 {
           80  +  db close
           81  +  tvfs_reset
           82  +  sqlite db file:test.db?nolock=1 -vfs tvfs -uri 1 -readonly 1
           83  +  db eval {SELECT * FROM t1}
           84  +  list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
           85  +       xCheckReservedLock $::tvfs_calls(xCheckReservedLock)
           86  +} {xLock 0 xUnlock 0 xCheckReservedLock 0}
           87  +
           88  +#############################################################################
           89  +# Verify that immutable=1 disables both locking and xAccess calls to the
           90  +# journal files.
           91  +#
           92  +do_test nolock-2.0 {
           93  +  db close
           94  +  forcedelete test.db
           95  +  # begin by creating a test database
           96  +  sqlite3 db test.db
           97  +  db eval {
           98  +     CREATE TABLE t1(a,b);
           99  +     INSERT INTO t1 VALUES('hello','world');
          100  +     CREATE TABLE t2(x,y);
          101  +     INSERT INTO t2 VALUES(12345,67890);
          102  +     SELECT * FROM t1, t2;
          103  +  }
          104  +} {hello world 12345 67890}
          105  +do_test nolock-2.1 {
          106  +  tvfs_reset
          107  +  sqlite3 db2 test.db -vfs tvfs
          108  +  db2 eval {SELECT * FROM t1, t2}
          109  +} {hello world 12345 67890}
          110  +do_test nolock-2.2 {
          111  +  list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
          112  +       xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
          113  +       xAccess $::tvfs_calls(xAccess)
          114  +} {xLock 2 xUnlock 2 xCheckReservedLock 0 xAccess 4}
          115  +
          116  +
          117  +do_test nolock-2.11 {
          118  +  db2 close
          119  +  tvfs_reset
          120  +  sqlite3 db2 file:test.db?immutable=0 -vfs tvfs -uri 1
          121  +  db2 eval {SELECT * FROM t1, t2}
          122  +} {hello world 12345 67890}
          123  +do_test nolock-2.12 {
          124  +  list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
          125  +       xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
          126  +       xAccess $::tvfs_calls(xAccess)
          127  +} {xLock 2 xUnlock 2 xCheckReservedLock 0 xAccess 4}
          128  +
          129  +
          130  +do_test nolock-2.21 {
          131  +  db2 close
          132  +  tvfs_reset
          133  +  sqlite3 db2 file:test.db?immutable=1 -vfs tvfs -uri 1
          134  +  db2 eval {SELECT * FROM t1, t2}
          135  +} {hello world 12345 67890}
          136  +do_test nolock-2.22 {
          137  +  list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
          138  +       xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
          139  +       xAccess $::tvfs_calls(xAccess)
          140  +} {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0}
          141  +
          142  +do_test nolock-2.31 {
          143  +  db2 close
          144  +  tvfs_reset
          145  +  sqlite3 db2 file:test.db?immutable=1 -vfs tvfs -uri 1 -readonly 1
          146  +  db2 eval {SELECT * FROM t1, t2}
          147  +} {hello world 12345 67890}
          148  +do_test nolock-2.32 {
          149  +  list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
          150  +       xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
          151  +       xAccess $::tvfs_calls(xAccess)
          152  +} {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0}
          153  +
          154  +############################################################################
          155  +# Verify that the SQLITE_IOCAP_IMMUTABLE flag works
          156  +#
          157  +do_test nolock-3.1 {
          158  +  db2 close
          159  +  tvfs devchar immutable
          160  +  tvfs_reset
          161  +  sqlite3 db2 test.db -vfs tvfs
          162  +  db2 eval {SELECT * FROM t1, t2}
          163  +} {hello world 12345 67890}
          164  +do_test nolock-3.2 {
          165  +  list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
          166  +       xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
          167  +       xAccess $::tvfs_calls(xAccess)
          168  +} {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0}
          169  +
          170  +do_test nolock-3.11 {
          171  +  db2 close
          172  +  tvfs_reset
          173  +  sqlite3 db2 test.db -vfs tvfs -readonly 1
          174  +  db2 eval {SELECT * FROM t1, t2}
          175  +} {hello world 12345 67890}
          176  +do_test nolock-3.12 {
          177  +  list xLock $::tvfs_calls(xLock) xUnlock $::tvfs_calls(xUnlock) \
          178  +       xCheckReservedLock $::tvfs_calls(xCheckReservedLock) \
          179  +       xAccess $::tvfs_calls(xAccess)
          180  +} {xLock 0 xUnlock 0 xCheckReservedLock 0 xAccess 0}
          181  +
          182  +db2 close
          183  +db close
          184  +tvfs delete
          185  +finish_test

Changes to tool/build-all-msvc.bat.

   142    142   REM
   143    143   IF NOT DEFINED CONFIGURATIONS (
   144    144     SET CONFIGURATIONS=Debug Retail
   145    145   )
   146    146   
   147    147   %_VECHO% Configurations = '%CONFIGURATIONS%'
   148    148   
          149  +REM
          150  +REM NOTE: If the command used to invoke NMAKE is not already set, use the
          151  +REM       default.
          152  +REM
          153  +IF NOT DEFINED NMAKE_CMD (
          154  +  SET NMAKE_CMD=nmake -B -f Makefile.msc
          155  +)
          156  +
          157  +%_VECHO% NmakeCmd = '%NMAKE_CMD%'
          158  +%_VECHO% NmakeArgs = '%NMAKE_ARGS%'
          159  +
   149    160   REM
   150    161   REM NOTE: Setup environment variables to translate between the MSVC platform
   151    162   REM       names and the names to be used for the platform-specific binary
   152    163   REM       directories.
   153    164   REM
   154    165   SET amd64_NAME=x64
   155    166   SET arm_NAME=ARM
................................................................................
   234    245   REM
   235    246   IF DEFINED WindowsPhoneKitDir GOTO set_vcvarsall_phone
   236    247   SET VCVARSALL=%VCINSTALLDIR%\vcvarsall.bat
   237    248   GOTO set_vcvarsall_done
   238    249   :set_vcvarsall_phone
   239    250   SET VCVARSALL=%VCINSTALLDIR%\WPSDK\WP80\vcvarsphoneall.bat
   240    251   :set_vcvarsall_done
          252  +SET VCVARSALL=%VCVARSALL:\\=\%
   241    253   
   242    254   REM
   243    255   REM NOTE: This is the outer loop.  There should be exactly one iteration per
   244    256   REM       platform.
   245    257   REM
   246    258   FOR %%P IN (%PLATFORMS%) DO (
   247    259     REM
................................................................................
   261    273     REM
   262    274     FOR /F "tokens=2* delims==" %%D IN ('SET PLATFORMNAME') DO (
   263    275       REM
   264    276       REM NOTE: Attempt to clean the environment of all variables used by MSVC
   265    277       REM       and/or Visual Studio.  This block may need to be updated in the
   266    278       REM       future to account for additional environment variables.
   267    279       REM
          280  +    CALL :fn_UnsetVariable CommandPromptType
   268    281       CALL :fn_UnsetVariable DevEnvDir
   269    282       CALL :fn_UnsetVariable ExtensionSdkDir
   270    283       CALL :fn_UnsetVariable Framework35Version
          284  +    CALL :fn_UnsetVariable Framework40Version
   271    285       CALL :fn_UnsetVariable FrameworkDir
   272    286       CALL :fn_UnsetVariable FrameworkDir32
   273    287       CALL :fn_UnsetVariable FrameworkVersion
   274    288       CALL :fn_UnsetVariable FrameworkVersion32
   275    289       CALL :fn_UnsetVariable FSHARPINSTALLDIR
   276    290       CALL :fn_UnsetVariable INCLUDE
   277    291       CALL :fn_UnsetVariable LIB
................................................................................
   279    293       CALL :fn_UnsetVariable Platform
   280    294       REM CALL :fn_UnsetVariable VCINSTALLDIR
   281    295       CALL :fn_UnsetVariable VSINSTALLDIR
   282    296       CALL :fn_UnsetVariable WindowsPhoneKitDir
   283    297       CALL :fn_UnsetVariable WindowsSdkDir
   284    298       CALL :fn_UnsetVariable WindowsSdkDir_35
   285    299       CALL :fn_UnsetVariable WindowsSdkDir_old
          300  +    CALL :fn_UnsetVariable WindowsSDK_ExecutablePath_x86
          301  +    CALL :fn_UnsetVariable WindowsSDK_ExecutablePath_x64
   286    302   
   287    303       REM
   288    304       REM NOTE: Reset the PATH here to the absolute bare minimum required.
   289    305       REM
   290    306       SET PATH=%TOOLPATH%;%SystemRoot%\System32;%SystemRoot%
   291    307   
   292    308       REM
................................................................................
   295    311       REM
   296    312       FOR %%B IN (%CONFIGURATIONS%) DO (
   297    313         REM
   298    314         REM NOTE: When preparing the debug build, set the DEBUG and MEMDEBUG
   299    315         REM       environment variables to be picked up by the MSVC makefile
   300    316         REM       itself.
   301    317         REM
          318  +      %_AECHO% Building the %%B configuration for platform %%P with name %%D...
          319  +
   302    320         IF /I "%%B" == "Debug" (
   303    321           SET DEBUG=2
   304    322           SET MEMDEBUG=1
   305    323         ) ELSE (
   306    324           CALL :fn_UnsetVariable DEBUG
   307    325           CALL :fn_UnsetVariable MEMDEBUG
   308    326         )
................................................................................
   370    388               CALL :fn_CopyVariable WindowsPhoneKitDir NSDKLIBPATH
   371    389               CALL :fn_AppendVariable NSDKLIBPATH \lib\x86
   372    390             ) ELSE IF DEFINED WindowsSdkDir (
   373    391               CALL :fn_CopyVariable WindowsSdkDir NSDKLIBPATH
   374    392   
   375    393               REM
   376    394               REM NOTE: The Windows 8.1 SDK has a slightly different directory
   377         -            REM       naming convention.  Currently, this tool assumes that
   378         -            REM       the Windows 8.1 SDK should only be used with MSVC 2013.
          395  +            REM       naming convention.
   379    396               REM
   380         -            IF "%VisualStudioVersion%" == "12.0" (
          397  +            IF DEFINED USE_WINV63_NSDKLIBPATH (
   381    398                 CALL :fn_AppendVariable NSDKLIBPATH \lib\winv6.3\um\x86
          399  +            ) ELSE IF "%VisualStudioVersion%" == "12.0" (
          400  +              CALL :fn_AppendVariable NSDKLIBPATH \..\8.0\lib\win8\um\x86
   382    401               ) ELSE (
   383    402                 CALL :fn_AppendVariable NSDKLIBPATH \lib\win8\um\x86
   384    403               )
   385    404             )
   386    405           )
   387    406   
   388    407           REM
   389    408           REM NOTE: Unless prevented from doing so, invoke NMAKE with the MSVC
   390    409           REM       makefile to clean any stale build output from previous
   391    410           REM       iterations of this loop and/or previous runs of this batch
   392    411           REM       file, etc.
   393    412           REM
   394    413           IF NOT DEFINED NOCLEAN (
   395         -          %__ECHO% nmake -f Makefile.msc clean
          414  +          %__ECHO% %NMAKE_CMD% clean
   396    415   
   397    416             IF ERRORLEVEL 1 (
   398    417               ECHO Failed to clean for platform %%P.
   399    418               GOTO errors
   400    419             )
   401    420           ) ELSE (
   402    421             REM
   403    422             REM NOTE: Even when the cleaning step has been disabled, we still
   404    423             REM       need to remove the build output for the files we are
   405    424             REM       specifically wanting to build for each platform.
   406    425             REM
          426  +          %_AECHO% Cleaning final output files only...
   407    427             %__ECHO% DEL /Q *.lo sqlite3.dll sqlite3.lib sqlite3.pdb
   408    428           )
   409    429   
   410    430           REM
   411    431           REM NOTE: Call NMAKE with the MSVC makefile to build the "sqlite3.dll"
   412    432           REM       binary.  The x86 compiler will be used to compile the native
   413    433           REM       command line tools needed during the build process itself.
   414    434           REM       Also, disable looking for and/or linking to the native Tcl
   415    435           REM       runtime library.
   416    436           REM
   417         -        %__ECHO% nmake -f Makefile.msc sqlite3.dll XCOMPILE=1 USE_NATIVE_LIBPATHS=1 NO_TCL=1 %NMAKE_ARGS%
          437  +        %__ECHO% %NMAKE_CMD% sqlite3.dll XCOMPILE=1 USE_NATIVE_LIBPATHS=1 NO_TCL=1 %NMAKE_ARGS%
   418    438   
   419    439           IF ERRORLEVEL 1 (
   420    440             ECHO Failed to build %%B "sqlite3.dll" for platform %%P.
   421    441             GOTO errors
   422    442           )
   423    443   
   424    444           REM

Changes to tool/mksqlite3c-noext.tcl.

    95     95      btreeInt.h
    96     96      hash.h
    97     97      hwtime.h
    98     98      keywordhash.h
    99     99      mutex.h
   100    100      opcodes.h
   101    101      os_common.h
          102  +   os_setup.h
          103  +   os_win.h
   102    104      os.h
   103    105      pager.h
   104    106      parse.h
   105    107      pcache.h
   106    108      sqlite3ext.h
   107    109      sqlite3.h
   108    110      sqliteicu.h

Changes to tool/mksqlite3c.tcl.

    99     99      fts3_tokenizer.h
   100    100      hash.h
   101    101      hwtime.h
   102    102      keywordhash.h
   103    103      mutex.h
   104    104      opcodes.h
   105    105      os_common.h
          106  +   os_setup.h
          107  +   os_win.h
   106    108      os.h
   107    109      pager.h
   108    110      parse.h
   109    111      pcache.h
   110    112      rtree.h
   111    113      sqlite3ext.h
   112    114      sqlite3.h
................................................................................
   164    166             }
   165    167             section_comment "Include $hdr in the middle of $tail"
   166    168             copy_file tsrc/$hdr
   167    169             section_comment "Continuing where we left off in $tail"
   168    170             if {$linemacros} {puts $out "#line [expr {$ln+1}] \"$filename\""}
   169    171           }
   170    172         } elseif {![info exists seen_hdr($hdr)]} {
          173  +        if {![regexp {/\*\s+amalgamator:\s+dontcache\s+\*/} $line]} {
   171    174           set seen_hdr($hdr) 1
          175  +        }
   172    176           puts $out $line
   173    177         } elseif {[regexp {/\*\s+amalgamator:\s+keep\s+\*/} $line]} {
   174    178           # This include file must be kept because there was a "keep"
   175    179           # directive inside of a line comment.
   176    180           puts $out $line
   177    181         } else {
   178    182           # Comment out the entire line, replacing any nested comment

Changes to tool/mksqlite3internalh.tcl.

    56     56      btree.h
    57     57      btreeInt.h
    58     58      hash.h
    59     59      hwtime.h
    60     60      keywordhash.h
    61     61      opcodes.h
    62     62      os_common.h
           63  +   os_setup.h
           64  +   os_win.h
    63     65      os.h
    64     66      pager.h
    65     67      parse.h
    66     68      sqlite3ext.h
    67     69      sqlite3.h
    68     70      sqliteInt.h
    69     71      sqliteLimit.h

Changes to tool/mkvsix.tcl.

    61     61   #
    62     62   # The first argument to this script is required and must be the name of the
    63     63   # top-level directory containing the directories and files organized into a
    64     64   # tree as described in item 6 of the PREREQUISITES section, above.  The second
    65     65   # argument is optional and if present must contain the name of the directory
    66     66   # containing the root of the source tree for SQLite.  The third argument is
    67     67   # optional and if present must contain the flavor the VSIX package to build.
    68         -# Currently, the only supported package flavors are "WinRT", "WinRT81", and
    69         -# "WP80".  The fourth argument is optional and if present must be a string
    70         -# containing a list of platforms to include in the VSIX package.  The format
    71         -# of the platform list string is "platform1,platform2,platform3".  Typically,
    72         -# when on Windows, this script is executed using commands similar to the
    73         -# following from a normal Windows command prompt:
           68  +# Currently, the only supported package flavors are "WinRT", "WinRT81", "WP80",
           69  +# and "Win32".  The fourth argument is optional and if present must be a string
           70  +# containing a list of platforms to include in the VSIX package.  The platform
           71  +# list is "platform1,platform2,platform3".  The fifth argument is optional and
           72  +# if present must contain the version of Visual Studio required by the package.
           73  +# Currently, the only supported versions are "2012" and "2013".  The package
           74  +# flavor "WinRT81" is only supported when the Visual Studio version is "2013".
           75  +# Typically, when on Windows, this script is executed using commands similar to
           76  +# the following from a normal Windows command prompt:
    74     77   #
    75     78   #                         CD /D C:\dev\sqlite\core
    76     79   #                         tclsh85 tool\mkvsix.tcl C:\Temp
    77     80   #
    78     81   # In the example above, "C:\dev\sqlite\core" represents the root of the source
    79     82   # tree for SQLite and "C:\Temp" represents the top-level directory containing
    80     83   # the executable and other compiled binary files, organized into a directory
................................................................................
    96     99       puts stdout $error
    97    100       if {!$usage} then {exit 1}
    98    101     }
    99    102   
   100    103     puts stdout "usage:\
   101    104   [file tail [info nameofexecutable]]\
   102    105   [file tail [info script]] <binaryDirectory> \[sourceDirectory\]\
   103         -\[packageFlavor\] \[platformNames\]"
          106  +\[packageFlavor\] \[platformNames\] \[vsVersion\]"
   104    107   
   105    108     exit 1
   106    109   }
   107    110   
   108    111   proc getEnvironmentVariable { name } {
   109    112     #
   110    113     # NOTE: Returns the value of the specified environment variable or an empty
................................................................................
   166    169     set file_id [open $fileName {WRONLY CREAT TRUNC}]
   167    170     fconfigure $file_id -encoding binary -translation binary
   168    171     puts -nonewline $file_id $data
   169    172     close $file_id
   170    173     return ""
   171    174   }
   172    175   
   173         -proc substFile { fileName } {
          176  +proc getMinVsVersionXmlChunk { vsVersion } {
          177  +  switch -exact $vsVersion {
          178  +    2012 {
          179  +      return [appendArgs \
          180  +          "\r\n    " {MinVSVersion="11.0"}]
          181  +    }
          182  +    2013 {
          183  +      return [appendArgs \
          184  +          "\r\n    " {MinVSVersion="12.0"}]
          185  +    }
          186  +    default {
          187  +      return ""
          188  +    }
          189  +  }
          190  +}
          191  +
          192  +proc getExtraFileListXmlChunk { packageFlavor vsVersion } {
   174    193     #
   175         -  # NOTE: Performs all Tcl command, variable, and backslash substitutions in
   176         -  #       the specified file and then rewrites the contents of that same file
   177         -  #       with the substituted data.
          194  +  # NOTE: Windows Phone 8.0 does not require any extra attributes in its VSIX
          195  +  #       package SDK manifests.
   178    196     #
   179         -  return [writeFile $fileName [uplevel 1 [list subst [readFile $fileName]]]]
          197  +  if {[string equal $packageFlavor WP80]} then {
          198  +    return ""
          199  +  }
          200  +
          201  +  set appliesTo [expr {[string equal $packageFlavor Win32] ? \
          202  +      "VisualC" : "WindowsAppContainer"}]
          203  +
          204  +  switch -exact $vsVersion {
          205  +    2012 {
          206  +      return [appendArgs \
          207  +          "\r\n    " AppliesTo=\" $appliesTo \" \
          208  +          "\r\n    " {DependsOn="Microsoft.VCLibs, version=11.0"}]
          209  +    }
          210  +    2013 {
          211  +      return [appendArgs \
          212  +          "\r\n    " AppliesTo=\" $appliesTo \" \
          213  +          "\r\n    " {DependsOn="Microsoft.VCLibs, version=12.0"}]
          214  +    }
          215  +    default {
          216  +      return ""
          217  +    }
          218  +  }
   180    219   }
   181    220   
   182    221   proc replaceFileNameTokens { fileName name buildName platformName } {
   183    222     #
   184    223     # NOTE: Returns the specified file name containing the platform name instead
   185    224     #       of platform placeholder tokens.
   186    225     #
   187    226     return [string map [list <build> $buildName <platform> $platformName \
   188    227         <name> $name] $fileName]
   189    228   }
          229  +
          230  +proc substFile { fileName } {
          231  +  #
          232  +  # NOTE: Performs all Tcl command, variable, and backslash substitutions in
          233  +  #       the specified file and then rewrites the contents of that same file
          234  +  #       with the substituted data.
          235  +  #
          236  +  return [writeFile $fileName [uplevel 1 [list subst [readFile $fileName]]]]
          237  +}
   190    238   
   191    239   #
   192    240   # NOTE: This is the entry point for this script.
   193    241   #
   194    242   set script [file normalize [info script]]
   195    243   
   196    244   if {[string length $script] == 0} then {
................................................................................
   202    250   
   203    251   ###############################################################################
   204    252   
   205    253   #
   206    254   # NOTE: Process and verify all the command line arguments.
   207    255   #
   208    256   set argc [llength $argv]
   209         -if {$argc < 1 || $argc > 4} then {fail}
          257  +if {$argc < 1 || $argc > 5} then {fail}
   210    258   
   211    259   set binaryDirectory [lindex $argv 0]
   212    260   
   213    261   if {[string length $binaryDirectory] == 0} then {
   214    262     fail "invalid binary directory"
   215    263   }
   216    264   
................................................................................
   247    295     set packageFlavor WinRT
   248    296   }
   249    297   
   250    298   if {[string length $packageFlavor] == 0} then {
   251    299     fail "invalid package flavor"
   252    300   }
   253    301   
   254         -if {[string equal -nocase $packageFlavor WinRT]} then {
   255         -  set shortName SQLite.WinRT
   256         -  set displayName "SQLite for Windows Runtime"
   257         -  set targetPlatformIdentifier Windows
   258         -  set targetPlatformVersion v8.0
   259         -  set minVsVersion 11.0
   260         -  set extraSdkPath ""
   261         -  set extraFileListAttributes [appendArgs \
   262         -      "\r\n    " {AppliesTo="WindowsAppContainer"} \
   263         -      "\r\n    " {DependsOn="Microsoft.VCLibs, version=11.0"}]
   264         -} elseif {[string equal -nocase $packageFlavor WinRT81]} then {
   265         -  set shortName SQLite.WinRT81
   266         -  set displayName "SQLite for Windows Runtime (Windows 8.1)"
   267         -  set targetPlatformIdentifier Windows
   268         -  set targetPlatformVersion v8.1
   269         -  set minVsVersion 12.0
   270         -  set extraSdkPath ""
   271         -  set extraFileListAttributes [appendArgs \
   272         -      "\r\n    " {AppliesTo="WindowsAppContainer"} \
   273         -      "\r\n    " {DependsOn="Microsoft.VCLibs, version=12.0"}]
   274         -} elseif {[string equal -nocase $packageFlavor WP80]} then {
   275         -  set shortName SQLite.WP80
   276         -  set displayName "SQLite for Windows Phone"
   277         -  set targetPlatformIdentifier "Windows Phone"
   278         -  set targetPlatformVersion v8.0
   279         -  set minVsVersion 11.0
   280         -  set extraSdkPath "\\..\\$targetPlatformIdentifier"
   281         -  set extraFileListAttributes ""
   282         -} elseif {[string equal -nocase $packageFlavor Win32]} then {
   283         -  set shortName SQLite.Win32
   284         -  set displayName "SQLite for Windows"
   285         -  set targetPlatformIdentifier Windows
   286         -  set targetPlatformVersion v8.0
   287         -  set minVsVersion 11.0
   288         -  set extraSdkPath ""
   289         -  set extraFileListAttributes [appendArgs \
   290         -      "\r\n    " {AppliesTo="VisualC"} \
   291         -      "\r\n    " {DependsOn="Microsoft.VCLibs, version=11.0"}]
   292         -} else {
   293         -  fail "unsupported package flavor, must be one of: WinRT WinRT81 WP80 Win32"
   294         -}
   295         -
   296    302   if {$argc >= 4} then {
   297    303     set platformNames [list]
   298    304   
   299    305     foreach platformName [split [lindex $argv 3] ", "] {
          306  +    set platformName [string trim $platformName]
          307  +
   300    308       if {[string length $platformName] > 0} then {
   301    309         lappend platformNames $platformName
   302    310       }
   303    311     }
   304    312   }
          313  +
          314  +if {$argc >= 5} then {
          315  +  set vsVersion [lindex $argv 4]
          316  +} else {
          317  +  set vsVersion 2012
          318  +}
          319  +
          320  +if {[string length $vsVersion] == 0} then {
          321  +  fail "invalid Visual Studio version"
          322  +}
          323  +
          324  +if {$vsVersion ne "2012" && $vsVersion ne "2013"} then {
          325  +  fail [appendArgs \
          326  +      "unsupported Visual Studio version, must be one of: " \
          327  +      [list 2012 2013]]
          328  +}
          329  +
          330  +set shortNames(WinRT,2012) SQLite.WinRT
          331  +set shortNames(WinRT,2013) SQLite.WinRT.2013
          332  +set shortNames(WinRT81,2013) SQLite.WinRT81
          333  +set shortNames(WP80,2012) SQLite.WP80
          334  +set shortNames(WP80,2013) SQLite.WP80.2013
          335  +set shortNames(Win32,2012) SQLite.Win32
          336  +set shortNames(Win32,2013) SQLite.Win32.2013
          337  +
          338  +set displayNames(WinRT,2012) "SQLite for Windows Runtime"
          339  +set displayNames(WinRT,2013) "SQLite for Windows Runtime"
          340  +set displayNames(WinRT81,2013) "SQLite for Windows Runtime (Windows 8.1)"
          341  +set displayNames(WP80,2012) "SQLite for Windows Phone"
          342  +set displayNames(WP80,2013) "SQLite for Windows Phone"
          343  +set displayNames(Win32,2012) "SQLite for Windows"
          344  +set displayNames(Win32,2013) "SQLite for Windows"
          345  +
          346  +if {[string equal $packageFlavor WinRT]} then {
          347  +  set shortName $shortNames($packageFlavor,$vsVersion)
          348  +  set displayName $displayNames($packageFlavor,$vsVersion)
          349  +  set targetPlatformIdentifier Windows
          350  +  set targetPlatformVersion v8.0
          351  +  set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
          352  +  set extraSdkPath ""
          353  +  set extraFileListAttributes \
          354  +      [getExtraFileListXmlChunk $packageFlavor $vsVersion]
          355  +} elseif {[string equal $packageFlavor WinRT81]} then {
          356  +  if {$vsVersion ne "2013"} then {
          357  +    fail [appendArgs \
          358  +        "unsupported combination, package flavor " $packageFlavor \
          359  +        " is only supported with Visual Studio 2013"]
          360  +  }
          361  +  set shortName $shortNames($packageFlavor,$vsVersion)
          362  +  set displayName $displayNames($packageFlavor,$vsVersion)
          363  +  set targetPlatformIdentifier Windows
          364  +  set targetPlatformVersion v8.1
          365  +  set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
          366  +  set extraSdkPath ""
          367  +  set extraFileListAttributes \
          368  +      [getExtraFileListXmlChunk $packageFlavor $vsVersion]
          369  +} elseif {[string equal $packageFlavor WP80]} then {
          370  +  set shortName $shortNames($packageFlavor,$vsVersion)
          371  +  set displayName $displayNames($packageFlavor,$vsVersion)
          372  +  set targetPlatformIdentifier "Windows Phone"
          373  +  set targetPlatformVersion v8.0
          374  +  set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
          375  +  set extraSdkPath "\\..\\$targetPlatformIdentifier"
          376  +  set extraFileListAttributes \
          377  +      [getExtraFileListXmlChunk $packageFlavor $vsVersion]
          378  +} elseif {[string equal $packageFlavor Win32]} then {
          379  +  set shortName $shortNames($packageFlavor,$vsVersion)
          380  +  set displayName $displayNames($packageFlavor,$vsVersion)
          381  +  set targetPlatformIdentifier Windows
          382  +  set targetPlatformVersion v8.0
          383  +  set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
          384  +  set extraSdkPath ""
          385  +  set extraFileListAttributes \
          386  +      [getExtraFileListXmlChunk $packageFlavor $vsVersion]
          387  +} else {
          388  +  fail [appendArgs \
          389  +      "unsupported package flavor, must be one of: " \
          390  +      [list WinRT WinRT81 WP80 Win32]]
          391  +}
   305    392   
   306    393   ###############################################################################
   307    394   
   308    395   #
   309    396   # NOTE: Evaluate the user-specific customizations file, if it exists.
   310    397   #
   311    398   set userFile [file join $path [appendArgs \
................................................................................
   486    573   ###############################################################################
   487    574   
   488    575   #
   489    576   # NOTE: Setup the list of platforms supported by this script.  These may be
   490    577   #       overridden via the command line or the user-specific customizations
   491    578   #       file.
   492    579   #
   493         -if {![info exists platformNames]} then {
          580  +if {![info exists platformNames] || [llength $platformNames] == 0} then {
   494    581     set platformNames [list x86 x64 ARM]
   495    582   }
   496    583   
   497    584   ###############################################################################
   498    585   
   499    586   #
   500    587   # NOTE: Make sure the staging directory exists, creating it if necessary.

Changes to tool/win/sqlite.vsix.

cannot compute difference between binary files