]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Added support for SQLITE_ENABLE_PERSIST_WAL compile time macro, retrieving lastErrno...
authoradam <adam@noemail.net>
Wed, 9 May 2012 22:36:25 +0000 (22:36 +0000)
committeradam <adam@noemail.net>
Wed, 9 May 2012 22:36:25 +0000 (22:36 +0000)
FossilOrigin-Name: 654792941011c96db879f6b779e99b1c65c587af

27 files changed:
Makefile.in
manifest
manifest.uuid
src/main.c
src/os_unix.c
src/pager.c
src/pager.h
src/sqlite3_private.h
src/test_config.c
src/wal.c
src/wal.h
test/cache.test
test/dbstatus2.test
test/fallocate.test
test/memsubsys1.test
test/pager1.test
test/pcache.test
test/shrink.test
test/wal.test
test/wal2.test
test/wal5.test
test/walbak.test
test/walhook.test
test/walmode.test
test/walnoshm.test
test/walpersist.test
test/walro.test

index 3b85bb1ff118a77d6723aafa64b2c94fa52d9984..60fe43d428138f45c3bed13f6044f8042e1fe9ba 100644 (file)
@@ -57,7 +57,7 @@ LIBREADLINE = @TARGET_READLINE_LIBS@
 
 # Should the database engine be compiled threadsafe
 #
-TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@
+#TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@
 
 # Any target libraries which libsqlite must be linked against
 # 
@@ -108,7 +108,7 @@ TCLSH_CMD = @TCLSH_CMD@
 
 # Where do we want to install the tcl plugin
 #
-TCLLIBDIR = @TCLLIBDIR@
+TCLLIBDIR = /System/Library/Tcl
 
 # The suffix used on shared libraries.  Ex:  ".dll", ".so", ".dylib"
 #
@@ -505,9 +505,8 @@ libsqlite3.la:      $(LIBOBJ)
 libtclsqlite3.la:      tclsqlite.lo libsqlite3.la
        $(LTLINK) -o $@ tclsqlite.lo \
                libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \
-               -rpath "$(TCLLIBDIR)" \
-               -version-info "8:6:8" \
-               -avoid-version
+                -rpath "$(TCLLIBDIR)/sqlite3" \
+               -version-info "8:6:8"
 
 sqlite3$(TEXE):        $(TOP)/src/shell.c libsqlite3.la sqlite3.h
        $(LTLINK) $(READLINE_FLAGS) \
@@ -933,12 +932,12 @@ install:  sqlite3$(BEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_instal
        $(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(pkgconfigdir)
 
 pkgIndex.tcl:
-       echo 'package ifneeded sqlite3 $(RELEASE) [list load $(TCLLIBDIR)/libtclsqlite3.so sqlite3]' > $@
+       echo 'package ifneeded sqlite3 $(RELEASE) [list load [file join \$dir libtclsqlite3.so] Tclsqlite3]' > $@
 tcl_install:   lib_install libtclsqlite3.la pkgIndex.tcl
-       $(INSTALL) -d $(DESTDIR)$(TCLLIBDIR)
-       $(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)
-       rm -f $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/libtclsqlite3.a
-       $(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR)
+       $(INSTALL) -d $(DESTDIR)$(TCLLIBDIR)/sqlite3
+       $(LTINSTALL) libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/sqlite3
+       rm -f $(DESTDIR)$(TCLLIBDIR)/sqlite3/libtclsqlite3.la $(DESTDIR)$(TCLLIBDIR)/sqlite3/libtclsqlite3.a
+       $(INSTALL) -m 0644 pkgIndex.tcl $(DESTDIR)$(TCLLIBDIR)/sqlite3
 
 clean: 
        rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la
index 37aacf15ede537db7300c9015106e0ad89b33581..e47f4f26f58cdefb97edaf5145e9a74561c14e94 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,7 +1,7 @@
-C Merge\sthe\slatest\strunk\schanges\sinto\sthe\sapple-osx\sbranch.
-D 2012-05-05T01:03:31.058
+C Added\ssupport\sfor\sSQLITE_ENABLE_PERSIST_WAL\scompile\stime\smacro,\sretrieving\slastErrno\sfrom\sWAL\sfile\sand\ssetting\slast\serrno\swhen\swrites\sfail\sdue\sto\sspace\sconstraints
+D 2012-05-09T22:36:25.742
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
-F Makefile.in 7bd2fa7753fc9de38994b8d4fa7f10deb19966a5
+F Makefile.in 957c9693400fca6cb8b533b589e69ddee7bcb27c
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
 F Makefile.msc 7849a871b6cdb20fd51baee6bbe5965a03326be4
 F Makefile.vxworks 3b7fe7a0571fdadc61363ebc1b23732d2d6363ca
@@ -143,7 +143,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
 F src/legacy.c 015826a958f690302d27e096a68d50b3657e4201
 F src/lempar.c 0ee69fca0be54cd93939df98d2aca4ca46f44416
 F src/loadext.c f20382fbaeec832438a1ba7797bee3d3c8a6d51d
-F src/main.c 2ba24071c42849fde838c32f1b508712c51dd758
+F src/main.c 75cdf5977022fe92a8fc2327934fd2ab4ccd29c0
 F src/malloc.c 15afac5e59b6584efe072e9933aefb4230e74f97
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c b3677415e69603d6a0e7c5410a1b3731d55beda1
@@ -162,10 +162,10 @@ F src/os.c 4c8c8d72a6c58ad2fde4865783e8ae26b494a85e
 F src/os.h 59beba555b65a450bd1d804220532971d4299f60
 F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
-F src/os_unix.c d1978ba892240d106f5c45a9ec588dfa54431df5
+F src/os_unix.c f8c943a0f9c4e2e7fae9facb3a243cb58cc8ceb5
 F src/os_win.c 12e76b4aa5426022939f92e894a5c20dd40be7f4
-F src/pager.c 69429aeb2452cf61c524466315b76e8bc8c71dbd
-F src/pager.h ef1eaf8593e78f73885c1dfac27ad83bee23bdc5
+F src/pager.c c296b3035a5a45d138e7370a3292ba07617adbf9
+F src/pager.h 42926ac0fe69e9d7e17a54e6b37417e581a429d7
 F src/parse.y eb054bb40a5bf90d3422a01ed0e5df229461727a
 F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
 F src/pcache.h 1b5dcc3dc8103d03e625b177023ee67764fa6b7c
@@ -179,7 +179,7 @@ F src/rowset.c f6a49f3e9579428024662f6e2931832511f831a1
 F src/select.c cf2f8f771bab6417e51a0f17b086a87bb74d624c
 F src/shell.c 04399b2f9942bd02ed5ffee3b84bcdb39c52a1e6
 F src/sqlite.h.in c8d096addc2814b900ee2e2b3b1f22ba56502d5f
-F src/sqlite3_private.h 77bebe843a3eabfb7994990aab780d34d25819c7
+F src/sqlite3_private.h 97a1e15b3a078bb583622da01a2e9bc96c6edf14
 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
 F src/sqliteInt.h ec90f0d797bbc93dd849629f18513b57bfd9a787
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
@@ -199,7 +199,7 @@ F src/test_async.c 0612a752896fad42d55c3999a5122af10dcf22ad
 F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e
 F src/test_backup.c 64fd6173ad99daade1227aa17c3ca0d18fa5e5fa
 F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2
-F src/test_config.c 5fb0e0d01b3219895e3475db9af27e701585ec77
+F src/test_config.c 805727b0fec25f9a77aec2ecd6c98f8f25e41748
 F src/test_demovfs.c 20a4975127993f4959890016ae9ce5535a880094
 F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
 F src/test_func.c 090f2c3339e85c2c964435f99aed6f3da9d59525
@@ -248,8 +248,8 @@ F src/vdbemem.c cb55e84b8e2c15704968ee05f0fae25883299b74
 F src/vdbesort.c b25814d385895544ebc8118245c8311ded7f81c9
 F src/vdbetrace.c 2405f68d14c49d2e0a798d71e35d62b8569bfb65
 F src/vtab.c ae657b1c22cff43863458e768a44f915c07bc0e4
-F src/wal.c b5ba968e7d5a17f745b78b3acde2214ec985d21e
-F src/wal.h a8ade3069ab75e3c79e9ca067a5ac7e1dbaf93a6
+F src/wal.c 1ff2ebb47ba29610abd768bf74cecd9c33049ebf
+F src/wal.h ce626f1f9000caf09a99a6634a8d794686f92e1b
 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
 F src/where.c 8e9f01cd1604aa21cfa8e0258b7101e05082fa98
 F test/8_3_names.test 0ed0f6711fefac33829ef9f1d6ca3c56c48ef1c7
@@ -311,7 +311,7 @@ F test/boundary3.test 56ef82096b4329aca2be74fa1e2b0f762ea0eb45
 F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983
 F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b
 F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
-F test/cache.test f64136b0893c293d0b910ed057b3b711249099a7
+F test/cache.test 3e50417948e06959aca785db81896b28a38c36dd
 F test/capi2.test 835d4cee9f542ea50fa8d01f3fe6de80b0627360
 F test/capi3.test 8dedb0050610e9ff95cd9d487beb0ce5f33a31ee
 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
@@ -364,7 +364,7 @@ F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
 F test/ctime.test 7bd009071e242aac4f18521581536b652b789a47
 F test/date.test a18a2ce81add84b17b06559e82ad7bb91bc6ddff
 F test/dbstatus.test 207e5b63fcb7b9c3bb8e1fdf38ebd4654ad0e54b
-F test/dbstatus2.test b1de8250fde1f3474d6b86f0e89de38d84794f56
+F test/dbstatus2.test 50ce645331b6fca84586bb0f03b274a4b4508ec3
 F test/default.test 6faf23ccb300114924353007795aa9a8ec0aa9dc
 F test/delete.test a065b05d2ebf60fd16639c579a4adfb7c381c701
 F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa
@@ -402,7 +402,7 @@ F test/exclusive2.test 372be98f6de44dd78734e364b7b626ea211761a6
 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
 F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
 F test/expr.test 67c9fd6f8f829e239dc8b0f4a08a73c08b09196d
-F test/fallocate.test 1abe364ff739f494523e88ba881c5eab72df9143
+F test/fallocate.test 9b74e7469ac8c1c19871a667dac1dd642d06a9ed
 F test/filectrl.test f0327bd804d9c7bd048fa7a151c5eab8e27df42b
 F test/filefmt.test ffa17b5aebc3eb4b1e3be1ccb5ee906ffbd97f6e
 F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
@@ -603,7 +603,7 @@ F test/manydb.test 3cd8e52ab3112cb8365afeedd6e8231977920577
 F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f
 F test/memdb.test 499d199e612bc229f52d1c46c6038deeef93d1f2
 F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
-F test/memsubsys1.test f431d42296dc502d4dbc19a6f89a76e46d74275f
+F test/memsubsys1.test c5fcd4bfda423c7cca6edbba96491af631758939
 F test/memsubsys2.test 3a1c1a9de48e5726faa85108b02459fae8cb9ee9
 F test/minmax.test 722d80816f7e096bf2c04f4111f1a6c1ba65453d
 F test/minmax2.test 33504c01a03bd99226144e4b03f7631a274d66e0
@@ -630,7 +630,7 @@ F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
 F test/null.test a8b09b8ed87852742343b33441a9240022108993
 F test/openv2.test 0d3040974bf402e19b7df4b783e447289d7ab394
 F test/oserror.test 50417780d0e0d7cd23cf12a8277bb44024765df3
-F test/pager1.test 4fbf634d26661578af38db830bd3442287aed91d
+F test/pager1.test 99cf69a829f1724e17b427592804c54b80b7de0c
 F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1
 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f
 F test/pagerfault.test a15ef77c8495882d7debb43794e87b6e46174c8a
@@ -638,7 +638,7 @@ F test/pagerfault2.test 1f79ea40d1133b2683a2f811b00f2399f7ec2401
 F test/pagerfault3.test f16e2efcb5fc9996d1356f7cbc44c998318ae1d7
 F test/pageropt.test 9191867ed19a2b3db6c42d1b36b6fbc657cd1ab0
 F test/pagesize.test 1dd51367e752e742f58e861e65ed7390603827a0
-F test/pcache.test 065aa286e722ab24f2e51792c1f093bf60656b16
+F test/pcache.test fa8a2b0677225765eced806d9d1676b78a9e2c40
 F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
 F test/permutations.test dbda172249564f43ec556108a704581044c57dbd
 F test/pragma.test e284a28b6e9debfb8b55d5413b7c27996e3ae2cd
@@ -694,13 +694,13 @@ F test/shared6.test 866bb4982c45ce216c61ded5e8fde4e7e2f3ffa9
 F test/shared7.test 960760bc8d03e1419e70dea69cf41db62853616e
 F test/shared_err.test 91e26ec4f3fbe07951967955585137e2f18993de
 F test/sharedlock.test ffa0a3c4ac192145b310f1254f8afca4d553eabf
-F test/shell1.test 7dcd612b0018ddad783647d984fffa76791ffd3d w tool/shell1.test
-F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a w tool/shell2.test
-F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59 w tool/shell3.test
-F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9 w tool/shell4.test
-F test/shell5.test fa2188bbb13fe2d183fd04a5f7b512650c35ef5d w tool/shell5.test
+F test/shell1.test 7dcd612b0018ddad783647d984fffa76791ffd3d
+F test/shell2.test 037d6ad16e873354195d30bb2dc4b5321788154a
+F test/shell3.test 9196c42772d575685e722c92b4b39053c6ebba59
+F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9
+F test/shell5.test fa2188bbb13fe2d183fd04a5f7b512650c35ef5d
 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
-F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
+F test/shrink.test 41ab166b276af4812bcaf6f1b99c53fab4e706d0
 F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
 F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
 F test/softheap1.test c16709a16ad79fa43b32929b2e623d1d117ccf53
@@ -920,27 +920,27 @@ F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
 F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
 F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
 F test/vtab_shared.test 82f463886e18d7f8395a4b6167c91815efe54839
-F test/wal.test 9c29891ca329de5bba41dfa26b855ca82950e01c
-F test/wal2.test ea811f7bc9abbc4282700c8969b175c31e884045
+F test/wal.test 3b7e0c1a2a9a8c39e4e00124f18f14a74f366060
+F test/wal2.test 3e151660c09d9a3c273c2862b6a392ae6138784b
 F test/wal3.test ae86a92d41d81730278fca0b71368f3e78e9c64a
 F test/wal4.test 5755887f321baa4c55de0b91066fa7d0cafcac9d
-F test/wal5.test 46a422956ec203bc5899dad5e70d9e655b1c91e4
+F test/wal5.test 187ae92cc9ba1ec6803681b9025cad89af1a8c69
 F test/wal6.test c561d1e44c89f9cb458a7b03003ed4baac08ba07
 F test/wal7.test 18cf68ab8010ae0a2baaa48e5b59567a9503e63e
 F test/wal8.test a0b7dee73fc3d3bbf167e04533d37df379a0b7d1
 F test/wal_common.tcl 15f152fd55703975878741beca6cfa4209d5b3b3
-F test/walbak.test 8edea4daad739587f049633071d0f063fa808049
+F test/walbak.test 67339b9e54db0cdaaf21287349bc8056e2919f96
 F test/walbig.test 3ca3d94751b80054eed5bda20a1339ae1f619483
 F test/walcksum.test 6510e82303f6fffc2c55bb77a7774cd0eed21a6e
 F test/walcrash.test a8fa8d8a9a50a49b7abaf8a4a7e2c7ea352c49be
 F test/walcrash2.test c032d0040374ae28b41f99fc0cc290b4e2e34f17
 F test/walcrash3.test 97e775404f4c76e5c46f71fbd09691c7e9c25c68
 F test/walfault.test e5309befcaf4ab08151c35dba20cc5b8a5846748
-F test/walhook.test 9716f865303130d7fcda61bcabb863090be9cca2
-F test/walmode.test 9308ffc25555a1c4eaa44a863792240406637496
-F test/walnoshm.test b1337ce99aabdf4da7a4a3f0c5ce1f05450bc3cc
-F test/walpersist.test 12d1a54a5d5e06af0ec4bbd5421608a957ed8630
-F test/walro.test 04d6382b2a87cfc82b87336eb8d8a8e9afd8bcf8
+F test/walhook.test 5d2bdb04fd3e220e2f96e6b566d57e00020bdaec
+F test/walmode.test aa45339b4afa435dde5d88e71a95459cc221a3f4
+F test/walnoshm.test 559b878f3aab838971d820329ca35f1caa7b038e
+F test/walpersist.test abd956d66e2f36d2d9d05d3a969f48be6d2ddbec
+F test/walro.test 180321fa4e7cf7e98b5df232763c3e0781673a41
 F test/walshared.test 04590b10c677f75318701818c50bc0dda5da64ab
 F test/walslow.test 658066419a92d3bd85be71a11ce477af4ffe9153
 F test/walthread.test c3aaf9ef7ad21ae79c2345425bfddb39cdac954f
@@ -1000,7 +1000,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings-clang.sh a8a0a3babda96dfb1ff51adda3cbbf3dfb7266c2
 F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P b72f07b4a2cf62ac1b52d432f13057d5d93a4ec4 bfa61e781cb442be641486e7e55a1518e888d830
-R dd82e74bcdab2fda6d096f215441e239
-U drh
-Z 7cba0cb59bdfe5fcf9605e6cbb5a3583
+P 2a99c0074aaabb4916d82464427be079d44d65e6
+R f9d69863cbb167dfcb5b19e9da7a6e71
+U adam
+Z 11d754e5694ab5d4ff0658638a828bc2
index 5bb93f73482b1424770a5df995c83baa9714098c..5d51223e6cc0d1f2b7b16dcb85086f126e2dcd98 100644 (file)
@@ -1 +1 @@
-2a99c0074aaabb4916d82464427be079d44d65e6
\ No newline at end of file
+654792941011c96db879f6b779e99b1c65c587af
\ No newline at end of file
index 1d56540db6c3e09eed1101e27425321db3f33ab3..0282e7443c109a19e189db043d4236f094270e78 100644 (file)
@@ -2843,6 +2843,14 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
       rc = SQLITE_OK;
     }else if( fd->pMethods ){
       rc = sqlite3OsFileControl(fd, op, pArg);
+#ifndef SQLITE_OMIT_WAL
+      if( (op==SQLITE_FCNTL_LAST_ERRNO)&&(*(int *)pArg==0) ){
+        sqlite3_file *pWalFd = sqlite3PagerWalFile(pPager);
+        if( pWalFd&&(pWalFd->pMethods) ){
+          rc = sqlite3OsFileControl(pWalFd, op, pArg);
+        }
+      }
+#endif
     }else{
       rc = SQLITE_NOTFOUND;
     }
index 960d1b1257d570bbde24945f03d5c1c7fa451abd..3f5c728a2e6934863cfc377f7fa380f3fd2f175d 100644 (file)
@@ -226,7 +226,7 @@ struct unixFile {
   const char *zPath;                  /* Name of the file */
   unixShm *pShm;                      /* Shared memory segment information */
   int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
-#if SQLITE_ENABLE_LOCKING_STYLE
+#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
   int openFlags;                      /* The flags specified at open() */
 #endif
 #if SQLITE_ENABLE_DATA_PROTECTION
@@ -554,7 +554,7 @@ static int sqlite3demo_superlock_corrupt(sqlite3_file *id, int eTargetFileLock,
   if( eFileLock<eTargetFileLock ){
     rc = pFile->pMethod->xLock(id, SQLITE_LOCK_SHARED);
   }
-  if( !rc && eFileLock<eTargetFileLock ){
+  if( !rc && SQLITE_LOCK_SHARED<eTargetFileLock ){
     rc = pFile->pMethod->xLock(id, SQLITE_LOCK_EXCLUSIVE);
   }
   if( rc ){
@@ -1411,6 +1411,10 @@ static void robust_close(unixFile *pFile, int h, int lineno){
   }
 }
 
+static void storeLastErrno(unixFile *pFile, int error){
+  pFile->lastErrno = error;
+}
+
 /*
 ** Close all file descriptors accumuated in the unixInodeInfo->pUnused list.
 */ 
@@ -1422,7 +1426,7 @@ static void closePendingFds(unixFile *pFile){
     pNext = p->pNext;
 #if OSCLOSE_CHECK_CLOSE_IOERR
     if( close(p->fd) ){
-      pFile->lastErrno = errno;
+      storeLastErrno(pFile, errno);
       rc = SQLITE_IOERR_CLOSE;
       p->pNext = pError;
       pError = p;
@@ -1495,7 +1499,7 @@ static int findInodeInfo(
   fd = pFile->h;
   rc = osFstat(fd, &statbuf);
   if( rc!=0 ){
-    pFile->lastErrno = errno;
+    storeLastErrno(pFile, errno);
 #ifdef EOVERFLOW
     if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
 #endif
@@ -1516,12 +1520,12 @@ static int findInodeInfo(
   if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){
     do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR );
     if( rc!=1 ){
-      pFile->lastErrno = errno;
+      storeLastErrno(pFile, errno);
       return SQLITE_IOERR;
     }
     rc = osFstat(fd, &statbuf);
     if( rc!=0 ){
-      pFile->lastErrno = errno;
+      storeLastErrno(pFile, errno);
       return SQLITE_IOERR;
     }
   }
@@ -1592,10 +1596,10 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
 #if OSLOCKING_CHECK_BUSY_IOERR
       int tErrno = errno;
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
-      pFile->lastErrno = tErrno;
+      storeLastErrno(pFile, tErrno);
 #else
       rc = SQLITE_IOERR_CHECKRESERVEDLOCK;
-      pFile->lastErrno = errno;
+      storeLastErrno(pFile, errno);
 #endif
     } else if( lock.l_type!=F_UNLCK ){
       reserved = 1;
@@ -1802,7 +1806,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
       tErrno = errno;
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
       if( IS_LOCK_ERROR(rc) ){
-        pFile->lastErrno = tErrno;
+        storeLastErrno(pFile, tErrno);
       }
       goto end_lock;
     }
@@ -1841,7 +1845,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
 
     if( rc ){
       if( IS_LOCK_ERROR(rc) ){
-        pFile->lastErrno = tErrno;
+        storeLastErrno(pFile, tErrno);
       }
       goto end_lock;
     }else{
@@ -1874,7 +1878,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
       tErrno = errno;
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
       if( rc!=SQLITE_BUSY ){
-        pFile->lastErrno = tErrno;
+        storeLastErrno(pFile, tErrno);
       }
     }
   }
@@ -2003,7 +2007,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
           rc = SQLITE_IOERR_UNLOCK;
 #endif
           if( IS_LOCK_ERROR(rc) ){
-            pFile->lastErrno = tErrno;
+            storeLastErrno(pFile, tErrno);
           }
           goto end_unlock;
         }
@@ -2019,7 +2023,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
           rc = SQLITE_IOERR_UNLOCK;
 #endif
           if( IS_LOCK_ERROR(rc) ){
-            pFile->lastErrno = tErrno;
+            storeLastErrno(pFile, tErrno);
           }
           goto end_unlock;
         }
@@ -2035,7 +2039,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
           rc = SQLITE_IOERR_UNLOCK;
 #endif
           if( IS_LOCK_ERROR(rc) ){
-            pFile->lastErrno = tErrno;
+            storeLastErrno(pFile, tErrno);
           }
           goto end_unlock;
         }
@@ -2058,10 +2062,10 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
           ** SQLITE_BUSY would confuse the upper layer (in practice it causes 
           ** an assert to fail). */ 
           rc = SQLITE_IOERR_RDLOCK;
-          pFile->lastErrno = tErrno;
+          storeLastErrno(pFile, tErrno);
 #endif
           if( IS_LOCK_ERROR(rc) ){
-            pFile->lastErrno = tErrno;
+            storeLastErrno(pFile, tErrno);
           }
           goto end_unlock;
         }
@@ -2078,11 +2082,11 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
       tErrno = errno;
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
       if( IS_LOCK_ERROR(rc) ){
-        pFile->lastErrno = tErrno;
+        storeLastErrno(pFile, tErrno);
       }
 #else
       rc = SQLITE_IOERR_UNLOCK;
-      pFile->lastErrno = errno;
+      storeLastErrno(pFile, errno);
 #endif
       goto end_unlock;
     }
@@ -2104,11 +2108,11 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
         tErrno = errno;
         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
         if( IS_LOCK_ERROR(rc) ){
-          pFile->lastErrno = tErrno;
+          storeLastErrno(pFile, tErrno);
         }
 #else
         rc = SQLITE_IOERR_UNLOCK;
-           pFile->lastErrno = errno;
+           storeLastErrno(pFile, errno);
 #endif
         pInode->eFileLock = NO_LOCK;
         pFile->eFileLock = NO_LOCK;
@@ -2159,7 +2163,7 @@ static int closeUnixFile(sqlite3_file *id){
   if( pFile->h>=0 ){
     int err = close(pFile->h);
     if( err ){
-      pFile->lastErrno = errno;
+      storeLastErrno(pFile, errno);
       return SQLITE_IOERR_CLOSE;
     }else{
       pFile->h=-1;
@@ -2396,7 +2400,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) {
     } else {
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
       if( IS_LOCK_ERROR(rc) ){
-        pFile->lastErrno = tErrno;
+        storeLastErrno(pFile, tErrno);
       }
     }
     return rc;
@@ -2454,7 +2458,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
 #endif
     }
     if( IS_LOCK_ERROR(rc) ){
-      pFile->lastErrno = tErrno;
+      storeLastErrno(pFile, tErrno);
     }
     return rc; 
   }
@@ -2545,7 +2549,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
         lrc = SQLITE_IOERR_UNLOCK; 
 #endif
         if( IS_LOCK_ERROR(lrc) ){
-          pFile->lastErrno = tErrno;
+          storeLastErrno(pFile, tErrno);
           rc = lrc;
         }
       }
@@ -2555,7 +2559,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
       /* someone else might have it reserved */
       lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); 
       if( IS_LOCK_ERROR(lrc) ){
-        pFile->lastErrno = tErrno;
+        storeLastErrno(pFile, tErrno);
         rc = lrc;
       }
     }
@@ -2621,7 +2625,7 @@ static int flockLock(sqlite3_file *id, int eFileLock) {
     /* didn't get, must be busy */
     rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
     if( IS_LOCK_ERROR(rc) ){
-      pFile->lastErrno = tErrno;
+      storeLastErrno(pFile, tErrno);
     }
   } else {
     /* got it, set the type and return ok */
@@ -2732,7 +2736,7 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
       int tErrno = errno;
       if( EAGAIN != tErrno ){
         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
-        pFile->lastErrno = tErrno;
+        storeLastErrno(pFile, tErrno);
       } else {
         /* someone else has the lock when we are in NO_LOCK */
         reserved = (pFile->eFileLock < SHARED_LOCK);
@@ -2837,7 +2841,7 @@ static int semUnlock(sqlite3_file *id, int eFileLock) {
     int rc, tErrno = errno;
     rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
     if( IS_LOCK_ERROR(rc) ){
-      pFile->lastErrno = tErrno;
+      storeLastErrno(pFile, tErrno);
     }
     return rc; 
   }
@@ -2939,7 +2943,7 @@ static int afpSetLock(
                     setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK);
 #endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */
     if( IS_LOCK_ERROR(rc) ){
-      pFile->lastErrno = tErrno;
+      storeLastErrno(pFile, tErrno);
     }
     return rc;
   } else {
@@ -3122,7 +3126,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){
     lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
     
     if( IS_LOCK_ERROR(lrc1) ) {
-      pFile->lastErrno = lrc1Errno;
+      storeLastErrno(pFile, lrc1Errno);
       rc = lrc1;
       goto afp_end_lock;
     } else if( IS_LOCK_ERROR(lrc2) ){
@@ -3406,9 +3410,9 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
     SimulateIOError( newOffset-- );
     if( newOffset!=offset ){
       if( newOffset == -1 ){
-        ((unixFile*)id)->lastErrno = errno;
+        storeLastErrno((unixFile*)id, errno);
       }else{
-        ((unixFile*)id)->lastErrno = 0;                        
+        storeLastErrno((unixFile*)id, 0);
       }
       return -1;
     }
@@ -3418,7 +3422,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
     if( got<0 ){
       if( errno==EINTR ){ got = 1; continue; }
       prior = 0;
-      ((unixFile*)id)->lastErrno = errno;
+      storeLastErrno((unixFile*)id, errno);
       break;
     }else if( got>0 ){
       cnt -= got;
@@ -3464,7 +3468,7 @@ static int unixRead(
     /* lastErrno set by seekAndRead */
     return SQLITE_IOERR_READ;
   }else{
-    pFile->lastErrno = 0; /* not a system error */
+    //storeLastErrno(pFile, 0); /* not a system error, but we want to preserve lastErrno */
     /* Unread parts of the buffer must be zero-filled */
     memset(&((char*)pBuf)[got], 0, amt-got);
     return SQLITE_IOERR_SHORT_READ;
@@ -3494,9 +3498,9 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
     SimulateIOError( newOffset-- );
     if( newOffset!=offset ){
       if( newOffset == -1 ){
-        ((unixFile*)id)->lastErrno = errno;
+        storeLastErrno((unixFile*)id, errno);
       }else{
-        ((unixFile*)id)->lastErrno = 0;                        
+        storeLastErrno((unixFile*)id, 0);
       }
       return -1;
     }
@@ -3505,7 +3509,7 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){
 #endif
   TIMER_END;
   if( got<0 ){
-    ((unixFile*)id)->lastErrno = errno;
+    storeLastErrno((unixFile*)id, errno);
   }
 
   OSTRACE(("WRITE   %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED));
@@ -3572,7 +3576,7 @@ static int unixWrite(
       /* lastErrno set by seekAndWrite */
       return SQLITE_IOERR_WRITE;
     }else{
-      pFile->lastErrno = 0; /* not a system error */
+      //storeLastErrno(pFile, 0); /* not a system error, but we want to preserve lastErrno */
       return SQLITE_FULL;
     }
   }
@@ -3796,7 +3800,7 @@ static int unixSync(sqlite3_file *id, int flags){
   rc = full_fsync(pFile->h, isFullsync, isDataOnly);
   SimulateIOError( rc=1 );
   if( rc ){
-    pFile->lastErrno = errno;
+    storeLastErrno(pFile, errno);
     return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
   }
 
@@ -3813,7 +3817,7 @@ static int unixSync(sqlite3_file *id, int flags){
       full_fsync(dirfd, 0, 0);
 #if OSCLOSE_CHECK_CLOSE_IOERR
       if( close(pFile->dirfd) ){
-        pFile->lastErrno = errno;
+        storeLastErrno(pFile, errno);
         rc = SQLITE_IOERR_DIR_CLOSE;
       }
 #else
@@ -3848,7 +3852,7 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
 
   rc = robust_ftruncate(pFile->h, (off_t)nByte);
   if( rc ){
-    pFile->lastErrno = errno;
+    storeLastErrno(pFile, errno);
     return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
   }else{
 #ifndef NDEBUG
@@ -3878,7 +3882,7 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){
   rc = osFstat(((unixFile*)id)->h, &buf);
   SimulateIOError( rc=1 );
   if( rc!=0 ){
-    ((unixFile*)id)->lastErrno = errno;
+    storeLastErrno((unixFile*)id, errno);
     return SQLITE_IOERR_FSTAT;
   }
   *pSize = buf.st_size;
@@ -3939,7 +3943,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
       i64 iWrite;                 /* Next offset to write to */
 
       if( robust_ftruncate(pFile->h, nSize) ){
-        pFile->lastErrno = errno;
+        storeLastErrno(pFile, errno);
         return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
       }
       iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
@@ -4025,12 +4029,15 @@ static int unixReplaceDatabase(unixFile *pFile, sqlite3 *srcdb) {
     if( src_file->pMethods ){
       int srcFlags = 0;
       pSrcFile = (unixFile *)src_file;
-      /* wal mode db cannot be opened readonly */
+#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
       if ((pSrcFile->openFlags & O_RDWR) == O_RDWR) {
         srcFlags = SQLITE_OPEN_READWRITE;
       } else {
         srcFlags = SQLITE_OPEN_READONLY;
       }
+#else
+      srcFlags = SQLITE_OPEN_READWRITE;
+#endif
 #if SQLITE_ENABLE_DATA_PROTECTION
       srcFlags |= pSrcFile->protFlags;
 #endif
@@ -4079,7 +4086,7 @@ static int unixReplaceDatabase(unixFile *pFile, sqlite3 *srcdb) {
             rc = SQLITE_NOMEM;
             break;
           default:
-            pFile->lastErrno = err;
+            storeLastErrno(pFile, err);
             rc = SQLITE_IOERR;
         }
       }
@@ -4106,7 +4113,7 @@ static int unixReplaceDatabase(unixFile *pFile, sqlite3 *srcdb) {
           rc = SQLITE_NOMEM;
           break;
         default:
-          pFile->lastErrno = err;
+          storeLastErrno(pFile, err);
           rc = SQLITE_IOERR;
       }
     }
@@ -4624,7 +4631,12 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
 
     if( pInode->bProcessLock==0 ){
       int openFlags = O_RDWR | O_CREAT;
-      if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
+      if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0)
+#if defined(SQLITE_ENABLE_PERSIST_WAL)&&(SQLITE_ENABLE_LOCKING_STYLE \
+    || defined(__APPLE__))
+         || (pDbFd->openFlags & O_RDWR) != O_RDWR
+#endif
+         ){
         openFlags = O_RDONLY;
         pShmNode->isReadonly = 1;
       }
@@ -5074,6 +5086,79 @@ static int unixInvalidateSupportFiles(unixFile *pFile, int skipWAL) {
   return SQLITE_OK;
 }
 
+static int unixUnsafeTruncateDatabase(unixFile *pFile){
+  // this is nasty & bad.  destruction with prejudice.  we'll lose all the file locks in this process, however.
+  // sqlite3_file_control works properly.  But if it fails, this works approximately
+  char journalPath[MAXPATHLEN];
+  char walPath[MAXPATHLEN];
+  int rc = SQLITE_OK;
+  
+  strlcpy(journalPath, pFile->zPath, MAXPATHLEN);
+  strlcat(journalPath, "-journal", MAXPATHLEN);
+  strlcpy(walPath, pFile->zPath, MAXPATHLEN);
+  strlcat(walPath, "-wal", MAXPATHLEN);
+  int fd1 = pFile->h;
+  int result = 0;
+  result = ftruncate(fd1, 0ll);
+  if (result) {
+    result = errno;
+  }
+  if (result) {
+    rc = SQLITE_IOERR;
+    storeLastErrno(pFile, result);
+  }
+  
+  int fd2 = open(journalPath, O_RDWR);
+  int result2 = 0;
+  if (fd2 < 0) {
+    if (errno != ENOENT) {
+      result2 = errno;
+    } else {
+      result2 = 0;
+    }
+  } else {
+    result2 = ftruncate(fd2, 0ll);
+    if (result2) {
+      result2 = errno;
+    }
+  }
+  if (result2 && !result) {
+    rc = SQLITE_IOERR;
+    storeLastErrno(pFile, result2);
+  }
+  
+  int fd3 = open(walPath, O_RDWR);
+  int result3 = 0;
+  if (fd3 < 0) {
+    if (errno != ENOENT) {
+      result3 = errno;
+    } else {
+      result3 = 0;
+    }
+  } else {
+    result3 = ftruncate(fd3, 0ll);
+    if (result3) {
+      result3 = errno;
+    }
+  }
+  if (result3 && !(result || result2)) {
+    rc = SQLITE_IOERR;
+    storeLastErrno(pFile, result2);
+  }
+  
+  if (fd3 >= 0) {
+    fsync(fd3);
+    close(fd3);
+  }
+  if (fd2 >= 0) {
+    fsync(fd2);
+    close(fd2);
+  }
+  fsync(fd1);
+       
+  return rc;
+}
+
 static int unixTruncateDatabase(unixFile *pFile, int bFlags) {
   sqlite3_file *id = (sqlite3_file *)pFile;
   int rc = SQLITE_OK;
@@ -5081,7 +5166,8 @@ static int unixTruncateDatabase(unixFile *pFile, int bFlags) {
   int flags = 0;
   int corruptFileLock = 0;
   int isCorrupt = 0;
-    
+  int force = (bFlags & SQLITE_TRUNCATE_FORCE);
+  
 #if SQLITE_ENABLE_DATA_PROTECTION
   flags |= pFile->protFlags;
 #endif
@@ -5097,11 +5183,11 @@ static int unixTruncateDatabase(unixFile *pFile, int bFlags) {
       isCorrupt = 1;
       rc = sqlite3demo_superlock_corrupt(id, SQLITE_LOCK_EXCLUSIVE, &corruptFileLock);
     }
-    if( rc ){
+    if( rc && !force ){
       return rc;
     }
   }
-  if( bFlags!=0 ){
+  if( (bFlags&SQLITE_TRUNCATE_INITIALIZE_HEADER_MASK)!=0 ){
     /* initialize a new database in TMPDIR and copy the contents over */
     const char *tDir = unixTempFileDir();
     int tLen = sizeof(char) * (strlen(tDir) + 11);
@@ -5112,8 +5198,12 @@ static int unixTruncateDatabase(unixFile *pFile, int bFlags) {
     strlcat(tDbPath, "tmpdbXXXXX", tLen);
     tFd = mkstemp(tDbPath);
     if( tFd==-1 ){
-      pFile->lastErrno=errno;
+      storeLastErrno(pFile, errno);
       rc = SQLITE_IOERR;
+      if( force ){
+        /* attempt the truncation, even if we can't seed the database in a temp directory */
+        rc = pFile->pMethod->xTruncate(id, ((pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS) != 0) ? 1L : 0L);
+      }
     }else{
       sqlite3 *tDb = NULL;
       copyfile_state_t s;
@@ -5149,6 +5239,9 @@ static int unixTruncateDatabase(unixFile *pFile, int bFlags) {
         }
       }
       if( tDb ){
+        int off = 0;
+        /* merge the wal into the db */
+        sqlite3_file_control(tDb, NULL, SQLITE_FCNTL_PERSIST_WAL, &off);
         sqlite3_close(tDb);
       }
       s = copyfile_state_alloc();
@@ -5161,7 +5254,7 @@ static int unixTruncateDatabase(unixFile *pFile, int bFlags) {
             rc = SQLITE_NOMEM;
             break;
           default:
-            pFile->lastErrno = err;
+            storeLastErrno(pFile, err);
             rc = SQLITE_IOERR;
         }
       }
@@ -5174,7 +5267,7 @@ static int unixTruncateDatabase(unixFile *pFile, int bFlags) {
   } else {
     rc = pFile->pMethod->xTruncate(id, ((pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS) != 0) ? 1L : 0L);
   }
-  if( rc==SQLITE_OK ){
+  if( rc==SQLITE_OK || force ){
     unixInvalidateSupportFiles(pFile, 0);
   }
   pFile->pMethod->xSync(id, SQLITE_SYNC_FULL);
@@ -5182,9 +5275,16 @@ static int unixTruncateDatabase(unixFile *pFile, int bFlags) {
 
   if( isCorrupt ){
     sqlite3demo_superunlock_corrupt(id, corruptFileLock);
-  }else{
+  }else if( pLock ){
     sqlite3demo_superunlock(pLock);
+  }else{
+    assert(force);
   }
+  
+  if( rc!=SQLITE_OK && force){
+    unixUnsafeTruncateDatabase(pFile);
+  }
+  
   return rc;
 }
 
@@ -5208,8 +5308,9 @@ static int unixLockstatePid(unixFile *pFile, pid_t pid, int *pLockstate){
   int hDb;        /* File descriptor for the open database file */
   int hShm = -1;  /* File descriptor for WAL shared-memory file */
   ssize_t got;    /* Bytes read from header */
-  int isWal;                 /* True if in WAL mode */
+  int isWal = 0;             /* True if in WAL mode */
   int nLock = 0;             /* Number of locks held */
+  int noHdr = 0;             /* Zero byte DB has no header */
   unsigned char aHdr[100];   /* Database header */
   
   assert(pLockstate);
@@ -5226,14 +5327,18 @@ static int unixLockstatePid(unixFile *pFile, pid_t pid, int *pLockstate){
     *pLockstate = SQLITE_LOCKSTATE_ERROR;
     return SQLITE_ERROR;
   }
-  if( got!=100 || memcmp(aHdr, SQLITE_FILE_HEADER, SQLITE_FILE_HEADER_LEN)!=0 ){
+  if( got==0 ){
+    noHdr = 1;
+  }else if( got!=100 || memcmp(aHdr, SQLITE_FILE_HEADER, SQLITE_FILE_HEADER_LEN)!=0 ){
     *pLockstate = SQLITE_LOCKSTATE_NOTADB;
     return SQLITE_NOTADB;
   }
   
   /* First check for an exclusive lock */
   nLock += unixIsLocked(pid, hDb, F_RDLCK, SHARED_FIRST, SHARED_SIZE, "EXCLUSIVE");
-  isWal = aHdr[18]==2;
+  if (!noHdr) {
+    isWal = aHdr[18]==2;
+  }
   if( nLock==0 && isWal==0 ){
     /* Rollback mode */
     nLock += unixIsLocked(pid, hDb, F_WRLCK, PENDING_BYTE, SHARED_SIZE+2, "PENDING|RESERVED|SHARED");
@@ -6186,7 +6291,7 @@ static int unixOpen(
     osUnlink(zName);
 #endif
   }
-#if SQLITE_ENABLE_LOCKING_STYLE
+#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
   else{
     p->openFlags = openFlags;
   }
@@ -6197,7 +6302,7 @@ static int unixOpen(
   
 #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
   if( fstatfs(fd, &fsInfo) == -1 ){
-    ((unixFile*)pFile)->lastErrno = errno;
+    storeLastErrno(p, errno);
     robust_close(p, fd, __LINE__);
     return SQLITE_IOERR_ACCESS;
   }
@@ -6215,6 +6320,11 @@ static int unixOpen(
   if( noLock )                  ctrlFlags |= UNIXFILE_NOLOCK;
   if( syncDir )                 ctrlFlags |= UNIXFILE_DIRSYNC;
   if( flags & SQLITE_OPEN_URI ) ctrlFlags |= UNIXFILE_URI;
+#if defined(SQLITE_ENABLE_PERSIST_WAL)
+  if( eType==SQLITE_OPEN_MAIN_DB ) {
+    ctrlFlags |= UNIXFILE_PERSIST_WAL;
+  }
+#endif
 
 #if SQLITE_ENABLE_LOCKING_STYLE
 #if SQLITE_PREFER_PROXY_LOCKING
@@ -7102,7 +7212,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
        */
       struct stat buf;
       if( osFstat(conchFile->h, &buf) ){
-        pFile->lastErrno = errno;
+        storeLastErrno(pFile, errno);
         return SQLITE_IOERR_LOCK;
       }
       
@@ -7122,7 +7232,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
         char tBuf[PROXY_MAXCONCHLEN];
         int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0);
         if( len<0 ){
-          pFile->lastErrno = errno;
+          storeLastErrno(pFile, errno);
           return SQLITE_IOERR_LOCK;
         }
         if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){
@@ -7199,7 +7309,7 @@ static int proxyTakeConch(unixFile *pFile){
 
     rc = proxyGetHostID(myHostID, &pError);
     if( (rc&0xff)==SQLITE_IOERR ){
-      pFile->lastErrno = pError;
+      storeLastErrno(pFile, pError);
       goto end_takeconch;
     }
     rc = proxyConchLock(pFile, myHostID, SHARED_LOCK);
@@ -7210,7 +7320,7 @@ static int proxyTakeConch(unixFile *pFile){
     readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN);
     if( readLen<0 ){
       /* I/O error: lastErrno set by seekAndRead */
-      pFile->lastErrno = conchFile->lastErrno;
+      storeLastErrno(pFile, conchFile->lastErrno);
       rc = SQLITE_IOERR_READ;
       goto end_takeconch;
     }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || 
@@ -7340,7 +7450,7 @@ static int proxyTakeConch(unixFile *pFile){
         if( pFile->h>=0 ){
 #if defined(STRICT_CLOSE_ERROR) && OSCLOSE_CHECK_CLOSE_IOERR
           if( close(pFile->h) ){
-            pFile->lastErrno = errno;
+            storeLastErrno(pFile, errno);
             return SQLITE_IOERR_CLOSE;
           }
 #else
index 2fb80c18db92bdf891debff9f82b926bde6d4bdd..bd46a6aa0d88f60affb4a64550e6b945b791edc2 100644 (file)
@@ -6343,6 +6343,15 @@ sqlite3_file *sqlite3PagerFile(Pager *pPager){
   return pPager->fd;
 }
 
+/*
+ ** Return the file handle for the WAL journal file associated
+ ** with the pager.  This might return NULL if the file has
+ ** not yet been opened.
+ */
+sqlite3_file *sqlite3PagerWalFile(Pager *pPager){
+  return ((pPager->pWal) ? sqlite3WalFile(pPager->pWal) : (NULL));
+}
+
 /*
 ** Return the full pathname of the journal file.
 */
index eca8a2f077e3504172e3c8f8b0612a3fc6a6451f..e90304cf1bedd3f7a9c5af39e2bfbbec7495d365 100644 (file)
@@ -154,6 +154,7 @@ int sqlite3PagerMemUsed(Pager*);
 const char *sqlite3PagerFilename(Pager*);
 const sqlite3_vfs *sqlite3PagerVfs(Pager*);
 sqlite3_file *sqlite3PagerFile(Pager*);
+sqlite3_file *sqlite3PagerWalFile(Pager *pPager);
 const char *sqlite3PagerJournalname(Pager*);
 int sqlite3PagerNosync(Pager*);
 void *sqlite3PagerTempSpace(Pager*);
index e7a4c1905d841bc68d73bda158efcddb21be0524..a81bc59b946cbdcadf0530f641e807653070e0b1 100644 (file)
@@ -49,6 +49,7 @@ extern int _sqlite3_lockstate(const char *path, pid_t pid);
 */
 #define SQLITE_FCNTL_TRUNCATE_DATABASE      101
 #define SQLITE_TRUNCATE_DATABASE            SQLITE_FCNTL_TRUNCATE_DATABASE
+#define SQLITE_TRUNCATE_INITIALIZE_HEADER_MASK    (0x63<<0)
 #define SQLITE_TRUNCATE_JOURNALMODE_WAL           (0x1<<0)
 #define SQLITE_TRUNCATE_AUTOVACUUM_MASK           (0x3<<2)
 #define SQLITE_TRUNCATE_AUTOVACUUM_OFF            (0x1<<2)
@@ -59,9 +60,10 @@ extern int _sqlite3_lockstate(const char *path, pid_t pid);
 #define SQLITE_TRUNCATE_PAGESIZE_2048             (0x2<<4)
 #define SQLITE_TRUNCATE_PAGESIZE_4096             (0x3<<4)
 #define SQLITE_TRUNCATE_PAGESIZE_8192             (0x4<<4)
+#define SQLITE_TRUNCATE_FORCE                     (0x1<<7)
 
 /*
-** Pass the SQLITE_REPLACE_DATABASE operation code to sqlite3_file_control() 
+** Pass the SQLITE_REPLACE_DATABASE operation code to sqlite3_file_control()
 ** and a sqlite3 pointer to another open database file to safely copy the 
 ** contents of that database file into the receiving database.
 */
index 1820d4887c41357ce61bb0ce01f8e0029cdefbcf..5f416bdf5333fc2c41b85b59d86198b0be0a1c4f 100644 (file)
@@ -461,6 +461,11 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
 #else
   Tcl_SetVar2(interp,"sqlite_options","prefer_proxy_locking","0",TCL_GLOBAL_ONLY);
 #endif
+#if defined(SQLITE_ENABLE_PURGEABLE_PCACHE) && defined(__APPLE__)
+  Tcl_SetVar2(interp,"sqlite_options","enable_purgeable_pcache","1",TCL_GLOBAL_ONLY);
+#else
+  Tcl_SetVar2(interp,"sqlite_options","enable_purgeable_pcache","0",TCL_GLOBAL_ONLY);
+#endif
 #if SQLITE_DEFAULT_CKPTFULLFSYNC
   Tcl_SetVar2(interp,"sqlite_options","default_ckptfullfsync","1",TCL_GLOBAL_ONLY);
 #else
@@ -472,6 +477,11 @@ Tcl_SetVar2(interp, "sqlite_options", "long_double",
 #else
   Tcl_SetVar2(interp,"sqlite_options","default_wal_safetylevel","0",TCL_GLOBAL_ONLY);
 #endif
+#if SQLITE_ENABLE_PERSIST_WAL
+  Tcl_SetVar2(interp,"sqlite_options","enable_persist_wal","1",TCL_GLOBAL_ONLY);
+#else
+  Tcl_SetVar2(interp,"sqlite_options","enable_persist_wal","0",TCL_GLOBAL_ONLY);
+#endif
     
 #ifdef SQLITE_OMIT_SHARED_CACHE
   Tcl_SetVar2(interp, "sqlite_options", "shared_cache", "0", TCL_GLOBAL_ONLY);
index 18903bf64373264486d89227baf51943e17b0be2..808075d3fc7fc7241efa3826e132d7d430aeda9a 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -2423,6 +2423,15 @@ Pgno sqlite3WalDbsize(Wal *pWal){
   return 0;
 }
 
+/* 
+ ** Return the file for this Wal journal (or zero, if unknown).
+ */
+sqlite3_file *sqlite3WalFile(Wal *pWal){
+  if( pWal ){
+    return pWal->pWalFd;
+  }
+  return 0;
+}
 
 /* 
 ** This function starts a write transaction on the WAL.
index 16f39315d0528b54f2b129fadb461d32c272e2b4..6dcc158f7e18046f94a0897e6db257e418b9e840 100644 (file)
--- a/src/wal.h
+++ b/src/wal.h
@@ -76,6 +76,9 @@ int sqlite3WalRead(Wal *pWal, Pgno pgno, int *pInWal, int nOut, u8 *pOut);
 /* If the WAL is not empty, return the size of the database. */
 Pgno sqlite3WalDbsize(Wal *pWal);
 
+/* If a WAL journal file has been created, return it */
+sqlite3_file *sqlite3WalFile(Wal *pWal);
+  
 /* Obtain or release the WRITER lock. */
 int sqlite3WalBeginWriteTransaction(Wal *pWal);
 int sqlite3WalEndWriteTransaction(Wal *pWal);
index f81948ba2c6e8cacc8db0fc7b071fe611e3c9a06..3211a258fde8ca5695f359b310cac5281008713a 100644 (file)
@@ -107,12 +107,17 @@ do_execsql_test cache-2.3.3 {
 } {main exclusive temp closed}
 do_test cache-2.3.4 { pager_cache_size db } 2
 do_execsql_test cache-2.3.5 COMMIT
-do_test cache-2.3.6 { pager_cache_size db } 1
-
+if !$::sqlite_options(enable_purgeable_pcache) {
+  # purgeable pcache doesn't share cache between connections
+  do_test cache-2.3.6 { pager_cache_size db } 1
+}
 do_execsql_test cache-2.3.7 {
   SELECT * FROM t1 UNION SELECT * FROM t2;
 } {1 2 i j x y}
-do_test cache-2.3.8 { pager_cache_size db } 1
+if !$::sqlite_options(enable_purgeable_pcache) {
+  # purgeable pcache doesn't share cache between connections
+  do_test cache-2.3.8 { pager_cache_size db } 1
+}
 
 # Tests for cache_size = 0.
 #
@@ -130,11 +135,17 @@ do_execsql_test cache-2.4.3 {
 do_test cache-2.4.4 { pager_cache_size db } 2
 do_execsql_test cache-2.4.5 COMMIT
 
-do_test cache-2.4.6 { pager_cache_size db } 0
+if !$::sqlite_options(enable_purgeable_pcache) {
+  # purgeable pcache doesn't share cache between connections
+  do_test cache-2.4.6 { pager_cache_size db } 0
+}
 do_execsql_test cache-2.4.7 {
   SELECT * FROM t1 UNION SELECT * FROM t2;
 } {1 2 i j x y}
-do_test cache-2.4.8 { pager_cache_size db } 0
+if !$::sqlite_options(enable_purgeable_pcache) {
+  # purgeable pcache doesn't share cache between connections
+  do_test cache-2.4.8 { pager_cache_size db } 0
+}
 
 sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)
 finish_test
index b2ec15665530975813a51788c6c8bbff5a0bd29a..d9416711dc2d87eb731e6a63110ea74380d298bd 100644 (file)
@@ -38,6 +38,9 @@ proc db_write {db {reset 0}} {
 }
 
 do_test 1.1 {
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db 0
+  }
   db close
   sqlite3 db test.db
   expr {[file size test.db] / 1024}
index 82379b397ad6f42aca13170417c3596a53a0b2ea..92f0d5e11860e792d963364b8511ac89a970877a 100644 (file)
@@ -81,10 +81,19 @@ if {![wal_is_ok]} { set skipwaltests 1 }
 if {!$skipwaltests} {
   db close
   forcedelete test.db
-  if {[forced_proxy_locking]} { file delete -force .test.db-conch }
+  ifcapable enable_persist_wal {
+    forcedelete test.db-journal
+    forcedelete test.db-wal
+    forcedelete test.db-shm
+  }
+  if {[forced_proxy_locking]} { 
+    forcedelete .test.db-conch
+  }
   sqlite3 db test.db
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db 0
+  }
   file_control_chunksize_test db main [expr 32*1024]
-  
   do_test fallocate-2.1 {
     execsql {
       PRAGMA page_size = 1024;
index ae9de19b11b78b9d9c83f697b9c208857620d981..463cc2ca9446a63bc143d00026fd6be499cf18d1 100644 (file)
@@ -98,9 +98,11 @@ build_test_db memsubsys1-2 {PRAGMA page_size=1024}
 #show_memstats
 set MEMORY_MANAGEMENT $sqlite_options(memorymanage)
 ifcapable !malloc_usable_size {
- do_test memsubsys1-2.3 {
-    set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
-  } [expr ($TEMP_STORE>1 || $MEMORY_MANAGEMENT==0)*1024]
+  if !$::sqlite_options(enable_purgeable_pcache) {
+    do_test memsubsys1-2.3 {
+      set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
+    } [expr ($TEMP_STORE>1 || $MEMORY_MANAGEMENT==0)*1024]
+  }
 }
 do_test memsubsys1-2.4 {
   set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
@@ -119,12 +121,14 @@ sqlite3_initialize
 reset_highwater_marks
 build_test_db memsubsys1-3.1 {PRAGMA page_size=1024}
 #show_memstats
-do_test memsubsys1-3.1.3 {
-  set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
-} 0
-do_test memsubsys1-3.1.4 {
-  set overflow [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
-} $max_pagecache
+if !$::sqlite_options(enable_purgeable_pcache) {
+  do_test memsubsys1-3.1.3 {
+    set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
+  } 0
+  do_test memsubsys1-3.1.4 {
+    set overflow [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
+  } $max_pagecache
+}
 do_test memsubsys1-3.1.5 {
   set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
 } 0
@@ -159,9 +163,11 @@ do_test memsubsys1-4.3 {
   set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
   expr {$pg_used>=45 && $pg_used<=50}
 } 1
-do_test memsubsys1-4.4 {
-  set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
-} 0
+if !$::sqlite_options(enable_purgeable_pcache) {
+  do_test memsubsys1-4.4 {
+    set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
+  } 0
+}
 do_test memsubsys1-4.5 {
   set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
   expr {$maxreq<7000}
@@ -244,13 +250,15 @@ do_test memsubsys1-7.3 {
   set pg_used [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_USED 0] 2]
   expr {$pg_used<24}
 } 1
-do_test memsubsys1-7.4 {
-  set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
-} 0
-do_test memsubsys1-7.5 {
-  set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
-  expr {$maxreq<4100}
-} 1
+if !$::sqlite_options(enable_purgeable_pcache) {
+  do_test memsubsys1-7.4 {
+    set pg_ovfl [lindex [sqlite3_status SQLITE_STATUS_PAGECACHE_OVERFLOW 0] 2]
+  } 0
+  do_test memsubsys1-7.5 {
+    set maxreq [lindex [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0] 2]
+    expr {$maxreq<4100}
+  } 1
+}
 do_test memsubsys1-7.6 {
   set s_used [lindex [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0] 2]
 } 1
index ac6a18c111b303951fc348c2cbd86c20f617d22a..cbf88c897993c6d80885b94977148d69af763937 100644 (file)
@@ -1162,6 +1162,9 @@ if {$::sqlite_options(wal) && [wal_is_ok]} {
     10 { SELECT * FROM t1 }               {1 2 3 4 5 6 7 8} 0 -1
   
   }] {
+    ifcapable enable_persist_wal {
+      file_control_persist_wal db 0
+    }
     do_execsql_test pager1-7.1.$tn.1 $sql $res
     catch { set J -1 ; set J [file size test.db-journal] }
     catch { set W -1 ; set W [file size test.db-wal] }
index 5dc3059c44834cfbe02049f5d51df1e18d9a39c8..082aa298337959599a04649e80446acc1bfa1ae2 100644 (file)
@@ -116,7 +116,9 @@ do_test pcache-1.7 {
 # page. Because the number of allocated pages is greater than the 
 # configured maximum, this page should be freed immediately instead of
 # recycled.
-#
+# Note- purgable_pcache doesn't share caches between connections and these tests
+# are only useful for testing that feature.  
+if !$::sqlite_options(enable_purgeable_pcache) {
 do_test pcache-1.8 {
   execsql {ROLLBACK} db2
   pcache_stats
@@ -177,5 +179,8 @@ do_test pcache-1.15 {
   }
   pcache_stats
 } {current 14 max 15 min 10 recyclable 14}
+} else {
+  db2 close
+}
 
 finish_test
index e03ebeeb6ecab22d1bb6444736b493f6a8bd8a98..6b9a78f4f9556428ecfd495eee5e8a7bcd6b25d7 100644 (file)
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
 
+# purgeable pcache tracks memory differently
+ifcapable {enable_purgeable_pcache} {
+  finish_test
+  return
+}
 unset -nocomplain baseline
 do_test shrink-1.1 {
   db eval {
index 51d8ab5c12ada9edcf3ca1408f58635c23622514..5a0bbf96e88e9fa2fffdc1f86d2c5204f940c2a4 100644 (file)
@@ -176,6 +176,9 @@ do_test wal-4.3 {
 } {a b}
 
 do_test wal-4.4.1 {
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db 0
+  }
   db close
   sqlite3 db test.db
   db func blob blob
@@ -227,6 +230,9 @@ db2 close
 
 do_test wal-4.5.1 {
   reopen_db
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db 0
+  }
   db func blob blob
   execsql {
     PRAGMA journal_mode = WAL;
@@ -341,6 +347,9 @@ foreach sector {512 4096} {
     forcedelete test.db test.db-wal
     do_test wal-6.$sector.$pgsz.1 {
       sqlite3 db test.db -vfs devsym
+      ifcapable enable_persist_wal {
+        file_control_persist_wal db 0
+      }
       execsql "
         PRAGMA page_size = $pgsz;
         PRAGMA auto_vacuum = 0;
@@ -727,10 +736,16 @@ do_test wal-11.8 {
   list [expr [file size test.db]/1024] [file size test.db-wal]
 } [list 37 [wal_file_size 41 1024]]
 do_test wal-11.9 {
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db 0
+  }
   db close
   list [expr [file size test.db]/1024] [log_deleted test.db-wal]
 } {37 1}
 sqlite3_wal db test.db
+ifcapable enable_persist_wal {
+  file_control_persist_wal db 0
+}
 do_test wal-11.10 {
   execsql {
     PRAGMA cache_size = 10;
@@ -778,6 +793,9 @@ do_test wal-12.1 {
   list [expr [file size test.db]/1024] [file size test.db-wal]
 } [list 1 [wal_file_size 5 1024]]
 do_test wal-12.2 {
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db 0
+  }
   db close
   sqlite3 db test.db
   execsql {
@@ -815,6 +833,9 @@ do_test wal-12.6 {
   execsql { SELECT * FROM t2 } db2
 } {B 2}
 db2 close
+ifcapable enable_persist_wal {
+  file_control_persist_wal db 0
+}
 db close
 
 #-------------------------------------------------------------------------
@@ -855,6 +876,9 @@ do_test wal-13.1.2 {
 } {B 2}
 breakpoint
 do_test wal-13.1.3 {
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db 0
+  }
   db close
   file exists test.db-wal
 } {0}
@@ -1349,6 +1373,9 @@ do_test wal-19.2 {
   }
 } {1 2 3 4 5 6}
 do_test wal-19.3 {
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db2 0
+  }
   db close
   db2 close
   file exists test.db-wal
@@ -1495,6 +1522,9 @@ do_test wal-23.1 {
     INSERT INTO t1 VALUES(1, 2);
     INSERT INTO t1 VALUES(3, 4);
   }
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db 0
+  }
   faultsim_save_and_close
 
   sqlite3_shutdown
@@ -1541,6 +1571,9 @@ ifcapable autovacuum {
     INSERT INTO t1 SELECT * FROM t1;
   } {wal}
   do_test 24.2 { 
+    ifcapable enable_persist_wal {
+      file_control_persist_wal db 0
+    }
     execsql {
       DELETE FROM t1;
       PRAGMA wal_checkpoint;
@@ -1569,6 +1602,9 @@ ifcapable autovacuum {
   } [wal_file_size 1 1024]
 }
 
+ifcapable enable_persist_wal {
+  file_control_persist_wal db 0
+}
 db close
 sqlite3_shutdown
 test_sqlite3_log
index 2076a24a8a7322b4b7351ab40aaa9c701a551565..21158feedb8506fabd50432acb8c42987570622a 100644 (file)
@@ -576,9 +576,15 @@ do_test wal2-6.3.1 {
   list [file exists test.db-wal] [file exists test.db-journal]
 } {1 0}
 do_test wal2-6.3.2 {
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db 0
+  }
   execsql { PRAGMA journal_mode = DELETE }
   file exists test.db-wal
 } {0}
+do_test wal2-6.3.2.1 {
+  execsql { PRAGMA journal_mode; }
+} {delete}
 do_test wal2-6.3.3 {
   execsql { PRAGMA lock_status }
 } {main exclusive temp closed}
@@ -725,7 +731,9 @@ foreach {tn sql res expected_locks} {
   do_test wal2-6.4.$tn.1 { execsql $S } $res
   do_test wal2-6.4.$tn.2 { set ::locks  } $L
 }
-
+ifcapable enable_persist_wal {
+  file_control_persist_wal db 0
+}
 db close
 tvfs delete
 
@@ -1096,6 +1104,9 @@ if {$::tcl_platform(platform) == "unix"} {
       list [file attr test.db-wal -perm] [file attr $shmpath -perm]
     } [list $effective $effective]
     do_test wal2-12.2.$tn.5 {
+      ifcapable enable_persist_wal {
+        file_control_persist_wal db 0
+      }
       db close
       list [file exists test.db-wal] [file exists $shmpath]
     } {0 0}
index bab6187be956e5ca2e9d3bb584dd6e106a26aa43..dc70d8ad4b09a7c6971942e9af328c3df3c3d67b 100644 (file)
@@ -79,6 +79,11 @@ foreach {testprefix do_wal_checkpoint} {
     }
 
     proc reopen_all {} {
+      ifcapable enable_persist_wal {
+        code1 { file_control_persist_wal db 0 }
+        code2 { file_control_persist_wal db2 0 }
+        code3 { file_control_persist_wal db3 0 }
+      }
       code1 {db close}
       code2 {db2 close}
       code3 {db3 close}
@@ -328,6 +333,11 @@ foreach {testprefix do_wal_checkpoint} {
 
     do_test 3.$tn.4 { code3 { do_wal_checkpoint db3 } } {0 2 2}
 
+    ifcapable enable_persist_wal {
+      code1 { file_control_persist_wal db 0 }
+      code2 { file_control_persist_wal db2 0 }
+      code3 { file_control_persist_wal db3 0 }
+    }
     code1 {db  close}
     code2 {db2 close}
     code3 {db3 close}
index ca5376eb6b866a075060fd8e80e468472dea198a..7d438ba9e87320387bdd907be46e30679eb71a4f 100644 (file)
@@ -323,6 +323,9 @@ foreach {tn src dest dest_final} {
   do_test walbak-4.$tn.1 {
     sqlite3 db test.db
     db eval "PRAGMA journal_mode = $src"
+    ifcapable enable_persist_wal {
+      file_control_persist_wal db 0
+    }
     db eval {
       CREATE TABLE t1(a, b);
       INSERT INTO t1 VALUES('I', 'II');
@@ -331,6 +334,9 @@ foreach {tn src dest dest_final} {
 
     sqlite3 db2 test.db2
     db2 eval "PRAGMA journal_mode = $dest"
+    ifcapable enable_persist_wal {
+      file_control_persist_wal db2 0
+    }
     db2 eval {
       CREATE TABLE t2(x, y);
       INSERT INTO t2 VALUES('1', '2');
index 4d8f833fc3f536472d230c1b04a2f684599f55de..ecedf9258f2bb4c3c28b7e26207c4c2e92ab05dd 100644 (file)
@@ -72,8 +72,14 @@ do_test walhook-1.5 {
 } [expr 6*1024]
 
 db2 close
+ifcapable enable_persist_wal {
+  file_control_persist_wal db 0
+}
 db close
 sqlite3 db test.db
+ifcapable enable_persist_wal {
+  file_control_persist_wal db 0
+}
 do_test walhook-2.1 {
   execsql { PRAGMA synchronous = NORMAL }
   execsql { PRAGMA wal_autocheckpoint }
index 728a1e110282a779e204ba6ed98a176575b994ca..38f2d36368db136b634deb8995d879a515484506 100644 (file)
@@ -88,6 +88,9 @@ do_test walmode-1.6 {
   file exists test.db-wal
 } {1}
 do_test walmode-1.7 {
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db 0
+  }
   db close
   file exists test.db-wal
 } {0}
@@ -104,6 +107,9 @@ do_test walmode-2.2 {
   file exists test.db-wal
 } {1}
 do_test walmode-2.3 {
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db 0
+  }
   db close
   file exists test.db-wal
 } {0}
@@ -126,6 +132,9 @@ do_test walmode-3.2 {
 #
 do_test walmode-4.1 {
   execsql { INSERT INTO t1 VALUES(1, 2) }
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db 0
+  }
   execsql { PRAGMA journal_mode = persist }
 } {persist}
 do_test walmode-4.2 {
@@ -149,6 +158,9 @@ do_test walmode-4.5 {
 #
 do_test walmode-4.6 {
   sqlite3 db2 test.db
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db2 0
+  }
   execsql { PRAGMA main.journal_mode } db2
 } {delete}
 do_test walmode-4.7 {
@@ -166,6 +178,9 @@ do_test walmode-4.10 {
 
 do_test walmode-4.11 {
   db2 close
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db 0
+  }
   execsql { PRAGMA journal_mode = delete } db
 } {delete}
 do_test walmode-4.12 {
@@ -319,6 +334,9 @@ db close
 do_test walmode-7.0 {
   forcedelete test.db
   sqlite3 db test.db
+  ifcapable enable_persist_wal {
+    file_control_persist_wal db 0
+  }
   execsql {
     PRAGMA journal_mode = WAL;
     CREATE TABLE t1(a, b);
index c14c110a5cd98342389a79ea80063e2c35e080c7..f5f20480a0b1e93bc93c4057d02fa1214b51319a 100644 (file)
@@ -54,6 +54,9 @@ do_execsql_test 1.6 { INSERT INTO t1 VALUES(3, 4) }
 do_execsql_test 1.7 {
   PRAGMA locking_mode = normal;
 } {exclusive}
+ifcapable enable_persist_wal {
+  file_control_persist_wal db 0
+}
 do_execsql_test 1.8 {
   PRAGMA journal_mode = delete;
   PRAGMA main.locking_mode;
index 125e43f7f3e44aa84e7ffca25954fe403c62840f..1b3e2c5407b5c5103b603183f2ebade4e5937465 100644 (file)
@@ -39,10 +39,17 @@ do_test walpersist-1.0 {
 do_test walpersist-1.1 {
   file exists $shmpath
 } {1}
-do_test walpersist-1.2 {
-  db close
-  list [file exists test.db] [file exists test.db-wal] [file exists $shmpath]
-} {1 0 0}
+ifcapable enable_persist_wal {
+  do_test walpersist-1.2-on {
+    db close
+    list [file exists test.db] [file exists test.db-wal] [file exists $shmpath]
+  } {1 1 1}
+} {
+  do_test walpersist-1.2-off {
+    db close
+    list [file exists test.db] [file exists test.db-wal] [file exists $shmpath]
+  } {1 0 0}
+}
 do_test walpersist-1.3 {
   sqlite3 db test.db
   db eval {SELECT length(a) FROM t1}
@@ -50,9 +57,15 @@ do_test walpersist-1.3 {
 do_test walpersist-1.4 {
   list [file exists test.db] [file exists test.db-wal] [file exists $shmpath]
 } {1 1 1}
-do_test walpersist-1.5 {
-  file_control_persist_wal db -1
-} {0 0}
+ifcapable enable_persist_wal {
+  do_test walpersist-1.5-on {
+    file_control_persist_wal db -1
+  } {0 1}
+} {
+  do_test walpersist-1.5-off {
+    file_control_persist_wal db -1
+  } {0 0}
+}
 do_test walpersist-1.6 {
   file_control_persist_wal db 1
 } {0 1}
index f1d09b46f60b6ddc0d8803a9c5d357732182c3a9..8362e0e4c447ed2e7ecfa8166480f7e3c6410cb2 100644 (file)
@@ -153,6 +153,10 @@ do_multiclient_test tn {
   # Also test that if the -shm file can be opened for read/write access,
   # it is not if readonly_shm=1 is present in the URI.
   do_test 1.3.2.1 {
+    ifcapable enable_persist_wal {
+      code1 { file_control_persist_wal db 0 }
+      code2 { file_control_persist_wal db2 0 }
+    }
     code1 { db close }
     code2 { db2 close }
     file exists $shmpath