------BEGIN PGP SIGNED MESSAGE-----
-Hash: SHA1
-
-C Merge\sin\sall\schanges\sup\sto\sthe\s3.7.0.1\srelease.
-D 2010-08-07T11:46:07
+C Updating\sapple-osx\swith\sminor\ssource\sfixes,\sdatabase\struncate\sand\sreplace\sprivate\scalls\sand\sa\sbunch\sof\sconditionalization\sfor\stests\srunning\sin\sdifferent\senvironments
+D 2010-08-18T00:09:48
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
F Makefile.in 9e1872338c526a5d6797f19dd04388f2a321e3d6
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e
-F src/os_unix.c 3109e0e5a0d5551bab2e8c7322b20a3b8b171248
-F src/os_win.c ed741817cfa97270e17f8f63c06f7e79e3b534d0
+F src/os_unix.c b7267d7fa3b77306bcebcd6bb2a322ebf06e4d21
+F src/os_win.c 1f8b0a1a5bcf6289e7754d0d3c16cec16d4c93ab
F src/pager.c c0f3c60b701a794344961700da7c4e2ae23d79a8
F src/pager.h 879fdde5a102d2f21a3135d6f647530b21c2796c
F src/parse.y 220a11ac72e2c9dffbf4cbe5fe462f328bd8d884
F src/pcache.c 1e9aa2dbc0845b52e1b51cc39753b6d1e041cb07
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
F src/pcache1.c 3a7c28f46a61b43ff0b5c087a7983c154f4b264c
-F src/pragma.c 6ee427538964886ce466a6ef8b0c2557a2b27d7e
+F src/pragma.c 055115ce2ba78af1aee2b973d947172a036f7a98
F src/prepare.c e81fd00d882e849498b0927a046cd06aab7bd502
F src/printf.c 5f5b65a83e63f2096a541a340722a509fa0240a7
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
F src/select.c 4903ff1bbd08b55cbce00ea43c645530de41b362
F src/shell.c fd4ccdb37c3b68de0623eb938a649e0990710714
F src/sqlite.h.in 8b05aef506d9bc7fc7da1572744e3174cb16ed59
+F src/sqlite3_private.h 2a814d17913732831acf13e7e87860105a3416e4
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
F src/sqliteInt.h d9e42f2029d4c526f9ba960bda1980ef17429c30
F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3
F src/status.c 4df6fe7dce2d256130b905847c6c60055882bdbe
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c ae1e4fb653c91ddad7e2534d209711a12604ccc4
-F src/test1.c 0dc3be6a14d6478ded56daca868cc989fd8f7f1c
+F src/test1.c 8d65857cd33db9baa6f276ce6fcd76c98c798261
F src/test2.c e3f564ab1e9fd0b47b0c9e23e7054e38bf0836cf
F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94
F src/test4.c ad03bb987ddedce928f4258c1e7fa4109a73497d
F src/test_autoext.c 30e7bd98ab6d70a62bb9ba572e4c7df347fe645e
F src/test_backup.c 64fd6173ad99daade1227aa17c3ca0d18fa5e5fa
F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2
-F src/test_config.c 5a11c51af2156e2d07186930b36f2b8239a4393f
+F src/test_config.c 91e758b037c7c58a6e3b3ce6babae883666174e9
F src/test_demovfs.c da81a5f7785bb352bda7911c332a983ec4f17f27
F src/test_devsym.c e7498904e72ba7491d142d5c83b476c4e76993bc
F src/test_func.c 13b582345fb1185a93e46c53310fae8547dcce20
F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685
F src/util.c 32aebf04c10e51ad3977a928b7416bed671b620b
F src/vacuum.c 241a8386727c1497eba4955933356dfba6ff8c9f
-F src/vdbe.c 6294de3327e09d14e9c06ecfd10e57c2d8e85307
+F src/vdbe.c a4c6eed89bb8332aa5ac4828e38e30e7c833477a
F src/vdbe.h 471f6a3dcec4817ca33596fe7f6654d56c0e75f3
F src/vdbeInt.h 19ebc8c2a2e938340051ee65af3f377fb99102d1
-F src/vdbeapi.c 95b451c6d991fddef6f9e4e68acfe573f597fb2f
+F src/vdbeapi.c a4e1b491545b8927d54c96b5ac8e44e460e2b7d5
F src/vdbeaux.c 7f99c1f00e4b31e8b28d8a87ecc2322bb46ae99c
F src/vdbeblob.c 258a6010ba7a82b72b327fb24c55790655689256
F src/vdbemem.c 5e579abf6532001dfbee0e640dc34eae897a9807
F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070
F test/bigfile.test a8ec8073a20207456dab01a29ad9cde42b0dd103
F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747
-F test/bind.test 3c7b320969000c441a70952b0b15938fbb66237c
+F test/bind.test 30af0fc61bc3836034215cdbdeca46113ca1b4a1
F test/bindxfer.test efecd12c580c14df5f4ad3b3e83c667744a4f7e0
F test/bitvec.test 75894a880520164d73b1305c1c3f96882615e142
F test/blob.test e7ac6c7d3a985cc4678c64f325292529a69ae252
F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398
F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041
F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
-F test/exclusive.test 5fe18e10a159342dd52ca14b1554e33f98734267
+F test/exclusive.test b8ac927ca1067abd0044703aca2d00cd56d518ab
F test/exclusive2.test fcbb1c9ca9739292a0a22a3763243ad6d868086b
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/expr.test 9f521ae22f00e074959f72ce2e55d46b9ed23f68
F test/join6.test bf82cf3f979e9eade83ad0d056a66c5ed71d1901
F test/journal1.test 36f2d1bb9bf03f790f43fbdb439e44c0657fab19
F test/journal2.test 50a3604768494d4a337f194f0a9480e7c57dcb72
-F test/journal3.test ff175219be1b02d2f7e54297ad7e491b7533edb6
+F test/journal3.test 7cfbd86429305c96c9d985665320db5364764d96
F test/jrnlmode.test 2d5a8b6d68de8512f522532731d90ca96912f3b7
F test/jrnlmode2.test a19e28de1a6ec898067e46a122f1b71c9323bf00
F test/jrnlmode3.test cfcdb12b90e640a23b92785a002d96c0624c8710
F test/lock2.test 5242d8ac4e2d59c403aebff606af449b455aceff
F test/lock3.test f271375930711ae044080f4fe6d6eda930870d00
F test/lock4.test c82268c031d39345d05efa672f80b025481b3ae5
-F test/lock5.test b2abb5e711bc59b0eae00f6c97a36ec9f458fada
+F test/lock5.test d0d313f059ae5661726d3f197ba6ed8f69257d8e
F test/lock6.test 8df56060f396151777390982422c800d026e1722
F test/lock7.test 64006c84c1c616657e237c7ad6532b765611cf64
F test/lock_common.tcl e7013c6208f5fa818735c324eb0249b4c0f317cf
-F test/lock_proxy.test 364b6c6220c023b57fc37eb52ec97c1f5c682c47
+F test/lock_proxy.test 9ea4307b186949fcfd012e4cd44149d2b6360da6
F test/lookaside.test 382e7bc2fab23d902c8eafb1b9ed7ababfff75a6
F test/main.test 753e2b772c041bd8dbd17c7e4132b3981378eaab
F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
F test/mallocJ.test b5d1839da331d96223e5f458856f8ffe1366f62e
F test/mallocK.test d79968641d1b70d88f6c01bdb9a7eb4a55582cc9
F test/malloc_common.tcl bd0b0916f03cb4f4c973bcb793f3057e84d5ecfb
-F test/manydb.test b3d3bc4c25657e7f68d157f031eb4db7b3df0d3c
+F test/manydb.test 7faa0df55bbab2b14c25f323801db336c4e7ce3a
F test/memdb.test f773146f66ee2c635854a8264317f39a6cc3e18c
F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2
F test/memsubsys1.test 98d5ff4c9f534cc863c07b74043bd44921893f29
F test/notnull.test cc7c78340328e6112a13c3e311a9ab3127114347
F test/null.test a8b09b8ed87852742343b33441a9240022108993
F test/openv2.test af02ed0a9cbc0d2a61b8f35171d4d117e588e4ec
-F test/pager1.test d8e4b2bc8164c920e6ea0572c9e13576d6e4f3fa
+F test/pager1.test 8343530e91cf617b3157dac05531fa4038e9a263
F test/pager2.test f5c757c271ce642d36a393ecbfb3aef1c240dcef
F test/pagerfault.test c1d176326ce244db157ce9c3ba128be2a9b172d6
F test/pagerfault2.test 1f79ea40d1133b2683a2f811b00f2399f7ec2401
F test/selectB.test f305cc6660804cb239aab4e2f26b0e288b59958b
F test/selectC.test 33bb5673a8141df193c6fd56e6de7fea38b8d2ee
F test/server1.test f5b790d4c0498179151ca8a7715a65a7802c859c
-F test/shared.test 3b448dc0f7a9356e641894ed81c27599f39d809d
+F test/shared.test a192585f23f5b9aab2e16fe6f11af79893353a62
F test/shared2.test d6ba4ca1827ea36a1ac23a99e3c36eeac9165450
F test/shared3.test d69bdd5f156580876c5345652d21dc2092e85962
F test/shared4.test d0fadacb50bb6981b2fb9dc6d1da30fa1edddf83
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/sqllimits1.test e90a0ed94452076f6a10209d378e06b5f75ef0a0
-F test/stat.test 70fe540ffb285947aead5533dfd0c8c12f17f14e
-F test/stmt.test 7915bd3e8380b956c095f40f41a775a30716e649
+F test/stat.test 8b7342007bdb49a9427d57a9bb94d02d6e54f2d0
+F test/stmt.test 8e39760750cdf8044d4ca441b2b95053817c9a5f
F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796
F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4
F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a
F test/table.test 04ba066432430657712d167ebf28080fe878d305
F test/tableapi.test 7262a8cbaa9965d429f1cbd2747edc185fa56516
F test/tclsqlite.test 8c154101e704170c2be10f137a5499ac2c6da8d3
-F test/tempdb.test 800c36623d67a2ad1f58784b9c5644e0405af6e6
+F test/tempdb.test 285dda9fdf10730702549e8aa19c9258bbf753b8
F test/temptable.test f42121a0d29a62f00f93274464164177ab1cc24a
F test/temptrigger.test b0273db072ce5f37cf19140ceb1f0d524bbe9f05
-F test/tester.tcl 7ea0c78442dccd4d7dde572c4a271dbc8b615e17
+F test/tester.tcl faae2f58058f129fa13992bdf728ee672d513588
F test/thread001.test a3e6a7254d1cb057836cb3145b60c10bf5b7e60f
F test/thread002.test afd20095e6e845b405df4f2c920cb93301ca69db
F test/thread003.test b824d4f52b870ae39fc5bae4d8070eca73085dca
F test/tkt3419.test 1bbf36d7ea03b638c15804251287c2391f5c1f6b
F test/tkt3424.test 61f831bd2b071bd128fa5d00fbda57e656ca5812
F test/tkt3442.test 89d7b41a4ec4d9d9b40ab8575d648579fb13cb4f
-F test/tkt3457.test edbf54b05cbe5165f00192becbd621038f1615e4
+F test/tkt3457.test 8a8f29536bf65b994bef5dde881404530b61a62a
F test/tkt3461.test 228ea328a5a21e8663f80ee3d212a6ad92549a19
F test/tkt3493.test 1686cbde85f8721fc1bdc0ee72f2ef2f63139218
F test/tkt3508.test d75704db9501625c7f7deec119fcaf1696aefb7d
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test 0eff9ce4f19facbe0a3e693f6c14b80711a4222d
-F test/wal.test 1891e6f72dd437a1c2a48091aa9182ba17a8f780
-F test/wal2.test fa6dc4457b46988f46cf6c68ea51ebe341765f4a
-F test/wal3.test d2ae7e66f973bd6b58ce49e546b2c00f44fe0485
-F test/wal4.test 3404b048fa5e10605facaf70384e6d2943412e30
+F test/wal.test 93cbc7a85563b2445940b77bf20d527755e6fc9d
+F test/wal2.test 86d38974445365f082fdc1c41cd8151f6d83685d
+F test/wal3.test c5d29ae29989b87dfe583b96c839a824d830e8e4
+F test/wal4.test 6a68c45bc1ca24a3592ec449ddcb92b29d0e0e87
F test/wal_common.tcl 895d76138043b86bdccf36494054bdabcf65837b
-F test/walbak.test 4df1c7369da0301caeb9a48fa45997fd592380e4
-F test/walbig.test e882bc1d014afffbfa2b6ba36e0f07d30a633ad0
-F test/walcksum.test a37b36375c595e61bdb7e1ec49b5f0979b6fc7ce
-F test/walcrash.test e763841551d6b23677ccb419797c1589dcbdbaf5
-F test/walcrash2.test 019d60b89d96c1937adb2b30b850ac7e86e5a142
-F test/walfault.test 05c470688d742688e455dd56816bd6bcffa298f8
-F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
-F test/walmode.test 5dc3008ef71988ecdd949ea16e5750e325b92b54
-F test/walslow.test d21625e2e99e11c032ce949e8a94661576548933
-F test/walthread.test a25a393c068a2b42b44333fa3fdaae9072f1617c
+F test/walbak.test 767e1c9e0ea0cfb907873b332883e66e187fa4bc
+F test/walbig.test 78ac493db2abdb65b9c6cace5b851cc32df1d449
+F test/walcksum.test cf6787f2ee1a6a3da6f0c2b20b9ede5153e4e03f
+F test/walcrash.test 80c1cc3173a0ef09d8303fa556cb0187a36d82ea
+F test/walcrash2.test 929c99d14ee2e3e3ef82585058968a8b12f72706
+F test/walfault.test 60527645638532a565a8e729db287ef0dba85ece
+F test/walhook.test c934ac5219fee2b4e7653d291db9107b8dc73bba
+F test/walmode.test 72517eb4f787c21b0478e608009642405885d613
+F test/walslow.test 989854bc5c214700a9f2d545bb158643813b8881
+F test/walthread.test e6e32e93ccebfa401dfc0dd930c79daa3472b0ae
F test/where.test de337a3fe0a459ec7c93db16a519657a90552330
F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554
F test/where3.test aa44a9b29e8c9f3d7bb94a3bb3a95b31627d520d
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 21ca87f69125a9e7124c6ddc566d17f64661b0d3 042a1abb030a0711386add7eb6e10832cc8b0f57
-R a0302c2cc0f7d48015e224bb2b269904
-U drh
-Z 2e5c390a58c654c840972d590ea9776b
------BEGIN PGP SIGNATURE-----
-Version: GnuPG v1.4.6 (GNU/Linux)
-
-iD8DBQFMXUeCoxKgR168RlERAh3wAJ9vkuYLkmYAethkfRnCyA85itOWmQCdHqi9
-Um3XnsUJPDOzuj+sNtgxEE0=
-=FT3/
------END PGP SIGNATURE-----
+P f88c6367d2f96cc93846ba38e6b963a1a3936e8d
+R 5e13346496ee8c75e29f49b7f6c975c4
+U adam
+Z 6d6d71585a30456468bba06c8dd3f59f
-f88c6367d2f96cc93846ba38e6b963a1a3936e8d
\ No newline at end of file
+5e2ee7db0f7a2a042b182336438107e2248d7b88
\ No newline at end of file
static int proxyFileControl(sqlite3_file*,int,void*);
#endif
+#if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__)
+#include "sqlite3_private.h"
+#include <copyfile.h>
+static int getDbPathForUnixFile(unixFile *pFile, char *dbPath);
+#endif
/*
** Information and control of an open file handle.
return proxyFileControl(id,op,pArg);
}
#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
+#if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__)
+ case SQLITE_TRUNCATE_DATABASE: {
+ unixFile *pFile = (unixFile*)id;
+ int trc = SQLITE_OK;
+ int eFileLock = pFile->eFileLock;
+ int rc = SQLITE_OK;
+ char jPath[MAXPATHLEN+9];
+ size_t jLen;
+
+ if( eFileLock<SQLITE_LOCK_SHARED ){
+ rc = pFile->pMethod->xLock(id, SQLITE_LOCK_SHARED);
+ }
+ if( !rc && eFileLock<SQLITE_LOCK_EXCLUSIVE ){
+ rc = pFile->pMethod->xLock(id, SQLITE_LOCK_EXCLUSIVE);
+ }
+ if( rc ){
+ if( pFile->eFileLock > eFileLock ){
+ pFile->pMethod->xUnlock(id, eFileLock);
+ }
+ return rc;
+ }
+ rc = pFile->pMethod->xTruncate(id, ((pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS) != 0) ? 1L : 0L);
+ if( !rc && (SQLITE_OK==getDbPathForUnixFile(pFile, jPath)) ){
+ jLen = strlcat(jPath, "-journal", MAXPATHLEN+9);
+ if( jLen < MAXPATHLEN+9 ){
+ int jfd = open(jPath, O_TRUNC);
+ if( (jfd == -1) ){
+ if ( errno!=ENOENT ){
+ perror(jPath);
+ }
+ } else {
+ fsync(jfd);
+ close(jfd);
+ }
+ }
+ }else{
+ trc=rc;
+ }
+ if( !trc ){
+ trc = pFile->pMethod->xSync(id, SQLITE_SYNC_FULL);
+ }
+ if( pFile->eFileLock > eFileLock ){
+ int unlockRC = pFile->pMethod->xUnlock(id, SQLITE_LOCK_SHARED);
+ if (!rc) rc = unlockRC;
+ }
+ if( pFile->eFileLock > eFileLock ){
+ int unlockRC = pFile->pMethod->xUnlock(id, SQLITE_LOCK_NONE);
+ if (!rc) rc = unlockRC;
+ }
+ if( trc ){
+ return trc;
+ }
+ return rc;
+ }
+
+ case SQLITE_REPLACE_DATABASE: {
+ unixFile *pFile = (unixFile*)id;
+ int trc = SQLITE_OK;
+ int eFileLock = pFile->eFileLock;
+ int rc = SQLITE_OK;
+ char jPath[MAXPATHLEN+9];
+ size_t jLen;
+ sqlite3 *srcdb = (sqlite3 *)pArg;
+ Btree *pSrcBtree = NULL;
+ int eSrcFileLock = SQLITE_LOCK_NONE;
+ int srcLockRC = -1;
+ sqlite3_file *src_file = NULL;
+ unixFile *pSrcFile = NULL;
+
+ if( !sqlite3SafetyCheckOk(srcdb) ){
+ return SQLITE_MISUSE;
+ }
+ if( eFileLock<SQLITE_LOCK_SHARED ){
+ rc = pFile->pMethod->xLock(id, SQLITE_LOCK_SHARED);
+ }
+ if( !rc && eFileLock<SQLITE_LOCK_EXCLUSIVE ){
+ rc = pFile->pMethod->xLock(id, SQLITE_LOCK_EXCLUSIVE);
+ }
+ if( !rc ){
+ /* get the src file descriptor adhering to the db struct access rules
+ ** this code is modeled after sqlite3_file_control() in main.c
+ */
+ sqlite3_mutex_enter(srcdb->mutex);
+ if( srcdb->nDb>0 ){
+ pSrcBtree = srcdb->aDb[0].pBt;
+ }
+ if( pSrcBtree ){
+ Pager *pSrcPager;
+ sqlite3BtreeEnter(pSrcBtree);
+ pSrcPager = sqlite3BtreePager(pSrcBtree);
+ assert( pSrcPager!=0 );
+ src_file = sqlite3PagerFile(pSrcPager);
+ assert( src_file!=0 );
+ if( src_file->pMethods ){
+ pSrcFile = (unixFile *)src_file;
+ eSrcFileLock = pSrcFile->eFileLock;
+ if( eSrcFileLock<SQLITE_LOCK_SHARED ){
+ rc = pSrcFile->pMethod->xLock(src_file, SQLITE_LOCK_SHARED);
+ srcLockRC = rc; /* SQLITE_OK means we need to unlock later */
+ } else if( eSrcFileLock==SQLITE_LOCK_EXCLUSIVE ){
+ /* if the src database has an exclusive lock, verify that the
+ ** it doesn't have a journal file with open transactions
+ */
+ if( getDbPathForUnixFile(pSrcFile, jPath) ){
+ rc = SQLITE_INTERNAL;
+ }else{
+ jLen = strlcat(jPath, "-journal", MAXPATHLEN+9);
+ if( jLen < MAXPATHLEN+9 ){
+ int jfd = open(jPath, O_RDONLY);
+ if( jfd==-1 ){
+ if( errno!=ENOENT ){
+ pFile->lastErrno = errno;
+ rc = SQLITE_IOERR;
+ }
+ }else{
+ /* if the journal exists ensure there's no pending
+ ** transaction by checking the journal header */
+ char magic[8];
+ ssize_t rlen = pread(jfd, magic, 8, 0);
+ if( rlen<0 ){
+ pFile->lastErrno = errno;
+ rc = SQLITE_IOERR;
+ }else if( rlen==8 ){
+ char test[8] = {'\0','\0','\0','\0','\0','\0','\0','\0'};
+ if( memcmp(magic,test,8) ){
+ rc = SQLITE_LOCKED;
+ }
+ }else if( rlen!=0 ){
+ rc = SQLITE_INTERNAL;
+ }
+ close(jfd);
+ }
+ }
+ }
+ }
+ }else{
+ rc = SQLITE_MISUSE;
+ }
+ if( rc ){
+ if( srcLockRC==SQLITE_OK ){
+ pSrcFile->pMethod->xUnlock(src_file, eSrcFileLock);
+ }
+ sqlite3BtreeLeave(pSrcBtree);
+ }
+ }
+ if( pSrcFile==NULL || (pSrcFile->h<0) ){
+ rc = SQLITE_INTERNAL;
+ sqlite3_mutex_leave(srcdb->mutex);
+ }
+ }
+ if( rc ){
+ /* unroll state changes and return error code */
+ if( pFile->eFileLock > eFileLock ){
+ pFile->pMethod->xUnlock(id, eFileLock);
+ }
+ return rc;
+ }else{
+ /* both databases are locked appropriately, copy file data
+ ** and then unroll the locks we added.
+ */
+ copyfile_state_t s;
+
+ s = copyfile_state_alloc();
+ if( fcopyfile(pSrcFile->h, pFile->h, s, COPYFILE_ALL) ){
+ switch(errno) {
+ case ENOMEM:
+ rc = SQLITE_NOMEM;
+ break;
+ default:
+ rc = SQLITE_INTERNAL;
+ }
+ }
+ copyfile_state_free(s);
+ if( srcLockRC==SQLITE_OK ){
+ pSrcFile->pMethod->xUnlock(src_file, eSrcFileLock);
+ }
+ sqlite3BtreeLeave(pSrcBtree);
+ sqlite3_mutex_leave(srcdb->mutex);
+ }
+
+ if( !rc && (SQLITE_OK==getDbPathForUnixFile(pFile, jPath)) ){
+ jLen = strlcat(jPath, "-journal", MAXPATHLEN+9);
+ if( jLen < MAXPATHLEN+9 ){
+ int jfd = open(jPath, O_TRUNC);
+ if( (jfd == -1) ){
+ if ( errno!=ENOENT ){
+ perror(jPath);
+ }
+ } else {
+ fsync(jfd);
+ close(jfd);
+ }
+ }
+ }else{
+ trc=rc;
+ }
+ if( !trc ){
+ trc = pFile->pMethod->xSync(id, SQLITE_SYNC_FULL);
+ }
+ if( pFile->eFileLock > eFileLock ){
+ int unlockRC = pFile->pMethod->xUnlock(id, SQLITE_LOCK_SHARED);
+ if (!rc) rc = unlockRC;
+ }
+ if( pFile->eFileLock > eFileLock ){
+ int unlockRC = pFile->pMethod->xUnlock(id, SQLITE_LOCK_NONE);
+ if (!rc) rc = unlockRC;
+ }
+ if( trc ){
+ return trc;
+ }
+ return rc;
+ }
+#endif /* (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) */
}
return SQLITE_ERROR;
}
if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) {
((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
}
+ if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) {
+ ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
+ }
#endif
#if SQLITE_ENABLE_LOCKING_STYLE
if( useProxy ){
rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete);
if( rc==SQLITE_OK ){
+ /* cache the pMethod in case the transform fails */
+ const struct sqlite3_io_methods *pMethod = pFile->pMethods;
rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
if( rc!=SQLITE_OK ){
/* Use unixClose to clean up the resources added in fillInUnixFile
** and clear all the structure's references. Specifically,
** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op
*/
- unixClose(pFile);
+ if( pMethod!=NULL ){
+ pMethod->xClose(pFile);
+ }else{
+ unixClose(pFile);
+ }
return rc;
}
}
** This routine find the filename associated with pFile and writes it
** int dbPath.
*/
-static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){
+static int getDbPathForUnixFile(unixFile *pFile, char *dbPath){
#if defined(__APPLE__)
if( pFile->pMethod == &afpIoMethods ){
/* afp style keeps a reference to the db path in the filePath field
if( pFile->eFileLock!=NO_LOCK ){
return SQLITE_BUSY;
}
- proxyGetDbPathForUnixFile(pFile, dbPath);
+ getDbPathForUnixFile(pFile, dbPath);
if( !path || path[0]=='\0' || !strcmp(path, ":auto:") ){
lockPath=NULL;
}else{
}
if( rc==SQLITE_OK && lockPath ){
pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath);
+ if( pCtx->lockProxyPath==NULL ){
+ rc = SQLITE_NOMEM;
+ }
}
if( rc==SQLITE_OK ){
*(int*)pArg = (int)((winFile*)id)->lastErrno;
return SQLITE_OK;
}
- case SQLITE_FCNTL_SIZE_HINT: {
- sqlite3_int64 sz = *(sqlite3_int64*)pArg;
- winTruncate(id, sz);
- return SQLITE_OK;
- }
case SQLITE_FCNTL_SIZE_HINT: {
sqlite3_int64 sz = *(sqlite3_int64*)pArg;
SimulateIOErrorBenign(1);
** of N.
*/
if( sqlite3StrICmp(zLeft, "wal_autocheckpoint")==0 ){
- sqlite3_int64 ret;
+ i64 walArg = 0;
if( zRight ){
int nAuto = atoi(zRight);
sqlite3_wal_autocheckpoint(db, nAuto);
}
if( db->xWalCallback==sqlite3WalDefaultHook ){
- ret = SQLITE_PTR_TO_INT(db->pWalArg);
- }else{
- ret = 0;
+ walArg = SQLITE_PTR_TO_INT(db->pWalArg);
}
- returnSingleInt(pParse, "wal_autocheckpoint", &ret);
+ returnSingleInt(pParse, "wal_autocheckpoint", &walArg);
}else
#endif
--- /dev/null
+/*
+ * sqlite3_private.h
+ */
+
+#ifndef _SQLITE3_PRIVATE_H
+#define _SQLITE3_PRIVATE_H
+
+/*
+** Pass the SQLITE_TRUNCATE_DATABASE operation code to sqlite3_file_control()
+** to truncate a database and its associated journal file to zero length.
+*/
+#define SQLITE_TRUNCATE_DATABASE 101
+
+/*
+** 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.
+*/
+#define SQLITE_REPLACE_DATABASE 102
+
+#endif
return TCL_ERROR;
}
if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
- sqlite3_clear_bindings(0); /* test for handling NULL <rdar://problem/6646331> */
Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(pStmt)));
return TCL_OK;
}
+/*
+ ** Usage: sqlite3_clear_bindings STMT
+ **
+ */
+static int test_clear_bindings_null(
+ void * clientData,
+ Tcl_Interp *interp,
+ int objc,
+ Tcl_Obj *CONST objv[]
+){
+ if( objc!=1 ){
+ return TCL_ERROR;
+ }
+ /* test for handling NULL <rdar://problem/6646331> */
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_clear_bindings(0)));
+ return TCL_OK;
+}
+
/*
** Usage: sqlite3_sleep MILLISECONDS
*/
return TCL_OK;
}
+#ifdef __APPLE__
+#include <sys/param.h>
+#include <sys/mount.h>
+#include <sys/errno.h>
+#endif
+
+/*
+ ** tclcmd: path_is_local PWD
+ */
+static int path_is_local(
+ ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ sqlite3 *db;
+ const char *zPath;
+ int nPath;
+
+ if( objc!=2 ){
+ Tcl_AppendResult(interp, "wrong # args: should be \"",
+ Tcl_GetStringFromObj(objv[0], 0), " PATH", 0);
+ return TCL_ERROR;
+ }
+ zPath = Tcl_GetStringFromObj(objv[1], &nPath);
+
+#ifdef __APPLE__
+ {
+ struct statfs fsInfo;
+ if( statfs(zPath, &fsInfo) == -1 ){
+ int err = errno;
+ Tcl_AppendResult(interp, "Error calling statfs on path",
+ Tcl_NewIntObj(err), 0);
+ return TCL_ERROR;
+ }
+ if( fsInfo.f_flags&MNT_LOCAL ){
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
+ }
+ }
+#else
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
+#endif
+
+ return TCL_OK;
+}
+
+/*
+ ** tclcmd: path_is_dos PWD
+ */
+static int path_is_dos(
+ ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
+ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
+ int objc, /* Number of arguments */
+ Tcl_Obj *CONST objv[] /* Command arguments */
+){
+ sqlite3 *db;
+ const char *zPath;
+ int nPath;
+
+ if( objc!=2 ){
+ Tcl_AppendResult(interp, "wrong # args: should be \"",
+ Tcl_GetStringFromObj(objv[0], 0), " PATH", 0);
+ return TCL_ERROR;
+ }
+ zPath = Tcl_GetStringFromObj(objv[1], &nPath);
+
+#ifdef __APPLE__
+ {
+ struct statfs fsInfo;
+ if( statfs(zPath, &fsInfo) == -1 ){
+ int err = errno;
+ Tcl_AppendResult(interp, "Error calling statfs on path",
+ Tcl_NewIntObj(err), 0);
+ return TCL_ERROR;
+ }
+ if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
+ } else if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
+ }
+ }
+#else
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
+#endif
+
+ return TCL_OK;
+}
/*
** tclcmd: sqlite3_vfs_list
{ "sqlite3_bind_parameter_name", test_bind_parameter_name, 0},
{ "sqlite3_bind_parameter_index", test_bind_parameter_index, 0},
{ "sqlite3_clear_bindings", test_clear_bindings, 0},
+ { "sqlite3_clear_bindings_null", test_clear_bindings_null, 0},
{ "sqlite3_sleep", test_sleep, 0},
{ "sqlite3_errcode", test_errcode ,0 },
{ "sqlite3_extended_errcode", test_ex_errcode ,0 },
{ "file_control_test", file_control_test, 0 },
{ "file_control_lasterrno_test", file_control_lasterrno_test, 0 },
{ "file_control_lockproxy_test", file_control_lockproxy_test, 0 },
+ { "path_is_local", path_is_local, 0 },
+ { "path_is_dos", path_is_dos, 0 },
{ "sqlite3_vfs_list", vfs_list, 0 },
/* Functions from os.h */
#else
Tcl_SetVar2(interp, "sqlite_options", "yytrackmaxstackdepth", "0", TCL_GLOBAL_ONLY);
#endif
-
+
+#ifdef __APPLE__
+# if defined(__ppc__)
+ Tcl_SetVar2(interp, "os_options", "arch", "ppc", TCL_GLOBAL_ONLY);
+# elif defined(__i386__)
+ Tcl_SetVar2(interp, "os_options", "arch", "i386", TCL_GLOBAL_ONLY);
+# elif defined(__x86_64__)
+ Tcl_SetVar2(interp, "os_options", "arch", "x86_64", TCL_GLOBAL_ONLY);
+# elif defined(__arm__)
+ Tcl_SetVar2(interp, "os_options", "arch", "arm", TCL_GLOBAL_ONLY);
+# else
+# error Unrecognized architecture for exec_options
+# endif
+#else
+ Tcl_SetVar2(interp, "os_options", "arch", "unknown", TCL_GLOBAL_ONLY);
+#endif
+
#define LINKVAR(x) { \
static const int cv_ ## x = SQLITE_ ## x; \
Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \
** sqlite3_column_text16() failed. */
goto no_mem;
}
- assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY );
+ assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || ((p->rc&0xFF) == SQLITE_LOCKED));
p->rc = SQLITE_OK;
assert( p->explain==0 );
p->pResultSet = 0;
** invalid). Return false if it is ok.
*/
static int vdbeSafety(Vdbe *p){
- if( p->db==0 ){
+ sqlite3* db = p->db;
+ if((db==0) || (db->magic != SQLITE_MAGIC_OPEN) || ((p->magic != VDBE_MAGIC_RUN) && (p->magic != VDBE_MAGIC_HALT))){
sqlite3_log(SQLITE_MISUSE, "API called with finalized prepared statement");
return 1;
}else{
[sqlite3_column_type $VM 2]
} {NULL NULL NULL}
sqlite3_finalize $VM
+do_test bind-13.5 {
+ sqlite3_clear_bindings_null
+} {0}
#--------------------------------------------------------------------
# These tests attempt to reproduce bug #3463.
# if we're using proxy locks, we use 3 filedescriptors for a db
# that is open but NOT writing changes, normally
# sqlite uses 1 (proxy locking adds the conch and the local lock)
-set using_proxy 0
-foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
- set using_proxy $value
-}
set extrafds 0
-if {$using_proxy!=0} {
+if {[forced_proxy_locking]} {
set extrafds 2
}
# If a connection is required to create a journal file, it creates it with
# the same file-system permissions as the database file itself. Test this.
#
-if {$::tcl_platform(platform) == "unix"} {
+if {$::tcl_platform(platform) == "unix" && ![path_is_dos "."]} {
set umask [exec /bin/sh -c umask]
faultsim_delete_and_reopen
return
}
-do_test lock5-flock.1 {
- sqlite3 db test.db -vfs unix-flock
- execsql {
- CREATE TABLE t1(a, b);
- BEGIN;
- INSERT INTO t1 VALUES(1, 2);
- }
-} {}
-
-# Make sure we are not accidentally using the dotfile locking scheme.
-do_test lock5-flock.2 {
- file exists test.db.lock
-} {0}
-
-do_test lock5-flock.3 {
- catch { sqlite3 db2 test.db -vfs unix-flock }
- catchsql { SELECT * FROM t1 } db2
-} {1 {database is locked}}
-
-do_test lock5-flock.4 {
- execsql COMMIT
- catchsql { SELECT * FROM t1 } db2
-} {0 {1 2}}
-
-do_test lock5-flock.5 {
- execsql BEGIN
- catchsql { SELECT * FROM t1 } db2
-} {0 {1 2}}
-
-do_test lock5-flock.6 {
- execsql {SELECT * FROM t1}
- catchsql { SELECT * FROM t1 } db2
-} {1 {database is locked}}
-
-do_test lock5-flock.7 {
- db close
- catchsql { SELECT * FROM t1 } db2
-} {0 {1 2}}
-
-do_test lock5-flock.8 {
- db2 close
-} {}
-
-#####################################################################
+# Only run the flock tests on a local file system
+if { [path_is_local "."] } {
+
+ do_test lock5-flock.1 {
+ sqlite3 db test.db -vfs unix-flock
+ execsql {
+ CREATE TABLE t1(a, b);
+ BEGIN;
+ INSERT INTO t1 VALUES(1, 2);
+ }
+ } {}
+
+ # Make sure we are not accidentally using the dotfile locking scheme.
+ do_test lock5-flock.2 {
+ file exists test.db.lock
+ } {0}
+
+ do_test lock5-flock.3 {
+ catch { sqlite3 db2 test.db -vfs unix-flock }
+ catchsql { SELECT * FROM t1 } db2
+ } {1 {database is locked}}
+
+ do_test lock5-flock.4 {
+ execsql COMMIT
+ catchsql { SELECT * FROM t1 } db2
+ } {0 {1 2}}
+
+ do_test lock5-flock.5 {
+ execsql BEGIN
+ catchsql { SELECT * FROM t1 } db2
+ } {0 {1 2}}
+
+ do_test lock5-flock.6 {
+ execsql {SELECT * FROM t1}
+ catchsql { SELECT * FROM t1 } db2
+ } {1 {database is locked}}
+
+ do_test lock5-flock.7 {
+ db close
+ catchsql { SELECT * FROM t1 } db2
+ } {0 {1 2}}
+
+ do_test lock5-flock.8 {
+ db2 close
+ } {}
+
+ #####################################################################
+
+ do_test lock5-none.1 {
+ sqlite3 db test.db -vfs unix-none
+ sqlite3 db2 test.db -vfs unix-none
+ execsql {
+ BEGIN;
+ INSERT INTO t1 VALUES(3, 4);
+ }
+ } {}
+ do_test lock5-none.2 {
+ execsql { SELECT * FROM t1 }
+ } {1 2 3 4}
+ do_test lock5-flock.3 {
+ execsql { SELECT * FROM t1 } db2
+ } {1 2}
+ do_test lock5-none.4 {
+ execsql {
+ BEGIN;
+ SELECT * FROM t1;
+ } db2
+ } {1 2}
+ do_test lock5-none.5 {
+ execsql COMMIT
+ execsql {SELECT * FROM t1} db2
+ } {1 2}
-do_test lock5-none.1 {
- sqlite3 db test.db -vfs unix-none
- sqlite3 db2 test.db -vfs unix-none
- execsql {
- BEGIN;
- INSERT INTO t1 VALUES(3, 4);
+ ifcapable memorymanage {
+ do_test lock5-none.6 {
+ sqlite3_release_memory 1000000
+ execsql {SELECT * FROM t1} db2
+ } {1 2 3 4}
}
-} {}
-do_test lock5-none.2 {
- execsql { SELECT * FROM t1 }
-} {1 2 3 4}
-do_test lock5-flock.3 {
- execsql { SELECT * FROM t1 } db2
-} {1 2}
-do_test lock5-none.4 {
- execsql {
- BEGIN;
- SELECT * FROM t1;
- } db2
-} {1 2}
-do_test lock5-none.5 {
- execsql COMMIT
- execsql {SELECT * FROM t1} db2
-} {1 2}
-ifcapable memorymanage {
- do_test lock5-none.6 {
- sqlite3_release_memory 1000000
- execsql {SELECT * FROM t1} db2
- } {1 2 3 4}
+ do_test lock5-flock.X {
+ db close
+ db2 close
+ } {}
}
-do_test lock5-flock.X {
- db close
- db2 close
-} {}
-
ifcapable lock_proxy_pragmas {
set env(SQLITE_FORCE_PROXY_LOCKING) $::using_proxy
}
db close
file delete -force test.db.lock
+#####################################################################
ifcapable lock_proxy_pragmas {
set ::using_proxy 0
foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
set ::using_proxy $value
}
- # Disable the proxy locking for these tests
- set env(SQLITE_FORCE_PROXY_LOCKING) "0"
-}
+ # enable the proxy locking for these tests
+ set env(SQLITE_FORCE_PROXY_LOCKING) "1"
-#####################################################################
+ # test conch file creation
+ #
+
+ catch { file delete lock_proxy_test.db }
+ catch { file delete .lock_proxy_test.db-conch }
+ # test that proxy locking mode creates conch files
+ do_test lock_proxy1.0 {
+ sqlite3 db2 lock_proxy_test.db
+ catchsql {
+ create table x(y);
+ } db2
+ file exists .lock_proxy_test.db-conch
+ } {1}
+ catch { db2 close }
+
+
+ # test proxy locking readonly file system handling
+ #
-# test proxy locking readonly file system handling
-#
-ifcapable lock_proxy_pragmas {
if {[file exists /usr/bin/hdiutil]} {
puts "Creating readonly file system for proxy locking tests..."
}
exec hdiutil create -megabytes 1 -fs HFS+ readonly.dmg -volname readonly
exec hdiutil attach readonly.dmg
- set sqlite_hostid_num 4
- set env(SQLITE_FORCE_PROXY_LOCKING) "1"
+ # create test1.db and a .test1.db-conch for host4
+ set sqlite_hostid_num 4
sqlite3 db2 /Volumes/readonly/test1.db
execsql {
create table x(y);
} db2
db2 close
+ # create test2.db and a .test2.db-conch for host5
set sqlite_hostid_num 5
sqlite3 db2 /Volumes/readonly/test2.db
execsql {
} db2
db2 close
+ # create test3.db without a conch file
set env(SQLITE_FORCE_PROXY_LOCKING) "0"
sqlite3 db2 /Volumes/readonly/test3.db
execsql {
create table x(y);
} db2
db2 close
- set env(SQLITE_FORCE_PROXY_LOCKING) "1"
exec hdiutil detach /Volumes/readonly
exec hdiutil attach -readonly readonly.dmg
+ # test that an unwritable, host-mismatched conch file prevents
+ # read only proxy-locking mode database access
+ set env(SQLITE_FORCE_PROXY_LOCKING) "1"
do_test lock_proxy2.0 {
sqlite3 db2 /Volumes/readonly/test1.db
catchsql {
} {1 {database is locked}}
catch { db2 close }
+ # test that an unwritable, host-matching conch file allows
+ # read only proxy-locking mode database access
do_test lock_proxy2.1 {
sqlite3 db2 /Volumes/readonly/test2.db
catchsql {
} {0 {table x x 2 {CREATE TABLE x(y)}}}
catch { db2 close }
+ # test that an unwritable, nonexistant conch file allows
+ # read only proxy-locking mode database access
do_test lock_proxy2.2 {
sqlite3 db2 /Volumes/readonly/test3.db
catchsql {
# if we're using proxy locks, we use 5 filedescriptors for a db
# that is open and in the middle of writing changes, normally
# sqlite uses 3 (proxy locking adds the conch and the local lock)
-set using_proxy 0
-foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
- set using_proxy value
-}
set num_fd_per_openwrite_db 3
-if {$using_proxy>0} {
+if {[forced_proxy_locking]} {
set num_fd_per_openwrite_db 5
}
# a valid page record (if the file page-size is 512 bytes). So as to
# make sure SQLite doesn't get confused by this.
#
- set nPadding [expr 511 - $::mj_filename_length]
+ set target_length 511
+ if { [forced_proxy_locking] } {
+ set target_length 255
+ }
+ set nPadding [expr $target_length - $::mj_filename_length]
if {$tcl_platform(platform)=="windows"} {
# TBD need to figure out how to do this correctly for Windows!!!
set nPadding [expr 255 - $::mj_filename_length]
set padding [string repeat x [expr $nPadding %32]]
set prefix "test.db${padding}"
+ set prefix
}
} {
eval $tcl
# $ws: The expected size of the WAL file, in bytes, after executing
# the SQL script. Or -1 if the WAL is not expected to exist.
#
-ifcapable wal {
- faultsim_delete_and_reopen
- foreach {tn sql res js ws} [subst {
-
- 1 {
- CREATE TABLE t1(a, b);
- PRAGMA auto_vacuum=OFF;
- PRAGMA synchronous=NORMAL;
- PRAGMA page_size=1024;
- PRAGMA locking_mode=EXCLUSIVE;
- PRAGMA journal_mode=TRUNCATE;
- INSERT INTO t1 VALUES(1, 2);
- } {exclusive truncate} 0 -1
-
- 2 {
- BEGIN IMMEDIATE;
- SELECT * FROM t1;
- COMMIT;
- } {1 2} 0 -1
-
- 3 {
- BEGIN;
- SELECT * FROM t1;
- COMMIT;
- } {1 2} 0 -1
-
- 4 { PRAGMA journal_mode = WAL } wal -1 -1
- 5 { INSERT INTO t1 VALUES(3, 4) } {} -1 [wal_file_size 1 1024]
- 6 { PRAGMA locking_mode = NORMAL } normal -1 [wal_file_size 1 1024]
- 7 { INSERT INTO t1 VALUES(5, 6); } {} -1 [wal_file_size 2 1024]
-
- 8 { PRAGMA journal_mode = TRUNCATE } truncate 0 -1
- 9 { INSERT INTO t1 VALUES(7, 8) } {} 0 -1
- 10 { SELECT * FROM t1 } {1 2 3 4 5 6 7 8} 0 -1
-
- }] {
- 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] }
- do_test pager1-7.1.$tn.2 { list $J $W } [list $js $ws]
+set do_wal_tests [wal_is_ok]
+if { $do_wal_tests } {
+ ifcapable wal {
+ faultsim_delete_and_reopen
+ foreach {tn sql res js ws} [subst {
+
+ 1 {
+ CREATE TABLE t1(a, b);
+ PRAGMA auto_vacuum=OFF;
+ PRAGMA synchronous=NORMAL;
+ PRAGMA page_size=1024;
+ PRAGMA locking_mode=EXCLUSIVE;
+ PRAGMA journal_mode=TRUNCATE;
+ INSERT INTO t1 VALUES(1, 2);
+ } {exclusive truncate} 0 -1
+
+ 2 {
+ BEGIN IMMEDIATE;
+ SELECT * FROM t1;
+ COMMIT;
+ } {1 2} 0 -1
+
+ 3 {
+ BEGIN;
+ SELECT * FROM t1;
+ COMMIT;
+ } {1 2} 0 -1
+
+ 4 { PRAGMA journal_mode = WAL } wal -1 -1
+ 5 { INSERT INTO t1 VALUES(3, 4) } {} -1 [wal_file_size 1 1024]
+ 6 { PRAGMA locking_mode = NORMAL } normal -1 [wal_file_size 1 1024]
+ 7 { INSERT INTO t1 VALUES(5, 6); } {} -1 [wal_file_size 2 1024]
+
+ 8 { PRAGMA journal_mode = TRUNCATE } truncate 0 -1
+ 9 { INSERT INTO t1 VALUES(7, 8) } {} 0 -1
+ 10 { SELECT * FROM t1 } {1 2 3 4 5 6 7 8} 0 -1
+
+ }] {
+ 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] }
+ do_test pager1-7.1.$tn.2 { list $J $W } [list $js $ws]
+ }
}
+} else {
+ do_test pager1-7.1.wal_is_not_ok {
+ execsql { PRAGMA journal_mode = WAL }
+ } {delete}
}
do_test pager1-7.2.1 {
sqlite3_backup B db2 main db main
list [B step 10000] [B finish]
} {SQLITE_DONE SQLITE_OK}
-do_test pager1-9.4.2 {
- list [file size test.db2] [file size test.db]
-} {0 0}
+if { [path_is_dos "."] } {
+ do_test pager1-9.4.2_dos {
+ list [file size test.db2] [file size test.db]
+ } {0 1}
+} else {
+ do_test pager1-9.4.2 {
+ list [file size test.db2] [file size test.db]
+ } {0 0}
+}
db2 close
#-------------------------------------------------------------------------
}
} {}
-do_test pager1-20.3.1 {
- faultsim_delete_and_reopen
- db func a_string a_string
- execsql {
- PRAGMA cache_size = 10;
- PRAGMA journal_mode = wal;
- BEGIN;
- CREATE TABLE t1(x);
- CREATE TABLE t2(y);
- INSERT INTO t1 VALUES(a_string(800));
- INSERT INTO t1 SELECT a_string(800) FROM t1; /* 2 */
- INSERT INTO t1 SELECT a_string(800) FROM t1; /* 4 */
- INSERT INTO t1 SELECT a_string(800) FROM t1; /* 8 */
- INSERT INTO t1 SELECT a_string(800) FROM t1; /* 16 */
- INSERT INTO t1 SELECT a_string(800) FROM t1; /* 32 */
- COMMIT;
- }
-} {wal}
-do_test pager1-20.3.2 {
- execsql {
- BEGIN;
- INSERT INTO t2 VALUES('xxxx');
- }
- recursive_select 32 t1
- execsql COMMIT
-} {}
+if { $do_wal_tests } {
+ do_test pager1-20.3.1 {
+ faultsim_delete_and_reopen
+ db func a_string a_string
+ execsql {
+ PRAGMA cache_size = 10;
+ PRAGMA journal_mode = wal;
+ BEGIN;
+ CREATE TABLE t1(x);
+ CREATE TABLE t2(y);
+ INSERT INTO t1 VALUES(a_string(800));
+ INSERT INTO t1 SELECT a_string(800) FROM t1; /* 2 */
+ INSERT INTO t1 SELECT a_string(800) FROM t1; /* 4 */
+ INSERT INTO t1 SELECT a_string(800) FROM t1; /* 8 */
+ INSERT INTO t1 SELECT a_string(800) FROM t1; /* 16 */
+ INSERT INTO t1 SELECT a_string(800) FROM t1; /* 32 */
+ COMMIT;
+ }
+ } {wal}
+ do_test pager1-20.3.2 {
+ execsql {
+ BEGIN;
+ INSERT INTO t2 VALUES('xxxx');
+ }
+ recursive_select 32 t1
+ execsql COMMIT
+ } {}
+}
#-------------------------------------------------------------------------
# Test that a WAL database may not be opened if:
# pager1-21.1.*: The VFS has an iVersion less than 2, or
# pager1-21.2.*: The VFS does not provide xShmXXX() methods.
#
-do_test pager1-21.0 {
- faultsim_delete_and_reopen
- execsql {
- PRAGMA journal_mode = WAL;
- CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def');
- INSERT INTO ko DEFAULT VALUES;
- }
-} {wal}
-do_test pager1-21.1 {
- testvfs tv -noshm 1
- sqlite3 db2 test.db -vfs tv
- catchsql { SELECT * FROM ko } db2
-} {1 {unable to open database file}}
-db2 close
-tv delete
-do_test pager1-21.2 {
- testvfs tv -iversion 1
- sqlite3 db2 test.db -vfs tv
- catchsql { SELECT * FROM ko } db2
-} {1 {unable to open database file}}
-db2 close
-tv delete
+if { $do_wal_tests } {
+ do_test pager1-21.0 {
+ faultsim_delete_and_reopen
+ execsql {
+ PRAGMA journal_mode = WAL;
+ CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def');
+ INSERT INTO ko DEFAULT VALUES;
+ }
+ } {wal}
+ do_test pager1-21.1 {
+ testvfs tv -noshm 1
+ sqlite3 db2 test.db -vfs tv
+ catchsql { SELECT * FROM ko } db2
+ } {1 {unable to open database file}}
+ db2 close
+ tv delete
+ do_test pager1-21.2 {
+ testvfs tv -iversion 1
+ sqlite3 db2 test.db -vfs tv
+ catchsql { SELECT * FROM ko } db2
+ } {1 {unable to open database file}}
+ db2 close
+ tv delete
+}
#-------------------------------------------------------------------------
# Test that a "PRAGMA wal_checkpoint":
# if we're using proxy locks, we use 2 filedescriptors for a db
# that is open but NOT yet locked, after a lock is taken we'll have 3,
# normally sqlite uses 1 (proxy locking adds the conch and the local lock)
-set using_proxy 0
-foreach {name value} [array get env SQLITE_FORCE_PROXY_LOCKING] {
- set using_proxy $value
-}
set extrafds_prelock 0
set extrafds_postlock 0
-if {$using_proxy>0} {
+if {[forced_proxy_locking]} {
set extrafds_prelock 1
set extrafds_postlock 2
}
CREATE VIRTUAL TABLE temp.stat USING dbstat;
SELECT * FROM stat;
} {}
-do_execsql_test stat-0.1 {
- PRAGMA journal_mode = WAL;
- PRAGMA journal_mode = delete;
- SELECT * FROM stat;
-} {wal delete sqlite_master / 1 leaf 0 0 916 0}
-
+if {[wal_is_ok]} {
+ do_execsql_test stat-0.1 {
+ PRAGMA journal_mode = WAL;
+ PRAGMA journal_mode = delete;
+ SELECT * FROM stat;
+ } {wal delete sqlite_master / 1 leaf 0 0 916 0}
+}
do_test stat-1.0 {
execsql {
CREATE TABLE t1(a, b);
finish_test
return
}
+
+# if we're using proxy locks, we use 3 filedescriptors for a db
+# that is open but NOT writing changes, normally
+# sqlite uses 1 (proxy locking adds the conch and the local lock)
+set extrafds 0
+if {[forced_proxy_locking]} {
+ set extrafds 2
+}
+
+
do_test stmt-1.2 {
set sqlite_open_file_count
+ expr $sqlite_open_file_count-$extrafds
} {1}
do_test stmt-1.3 {
execsql {
INSERT INTO t1 VALUES(1, 1);
}
set sqlite_open_file_count
+ expr $sqlite_open_file_count-$extrafds
} {2}
do_test stmt-1.4 {
execsql {
INSERT INTO t1 SELECT a+1, b+1 FROM t1;
}
set sqlite_open_file_count
+ expr $sqlite_open_file_count-$extrafds
} {3}
do_test stmt-1.5 {
execsql COMMIT
set sqlite_open_file_count
+ expr $sqlite_open_file_count-$extrafds
} {1}
do_test stmt-1.6.1 {
execsql {
INSERT INTO t1 SELECT a+2, b+2 FROM t1;
}
set sqlite_open_file_count
+ expr $sqlite_open_file_count-$extrafds
} {2}
do_test stmt-1.6.2 {
execsql { INSERT INTO t1 SELECT a+4, b+4 FROM t1 }
set sqlite_open_file_count
+ expr $sqlite_open_file_count-$extrafds
} {3}
do_test stmt-1.7 {
execsql COMMIT
set sqlite_open_file_count
+ expr $sqlite_open_file_count-$extrafds
} {1}
-proc filecount {testname sql expected} {
+proc filecount {testname sql expected extrafds} {
uplevel [list do_test $testname [subst -nocommand {
execsql BEGIN
execsql { $sql }
set ret [set sqlite_open_file_count]
execsql ROLLBACK
set ret
- }] $expected]
+ }] [ expr $expected+$extrafds ] ]
}
-filecount stmt-2.1 { INSERT INTO t1 VALUES(9, 9) } 2
-filecount stmt-2.2 { REPLACE INTO t1 VALUES(9, 9) } 2
-filecount stmt-2.3 { INSERT INTO t1 SELECT 9, 9 } 2
+filecount stmt-2.1 { INSERT INTO t1 VALUES(9, 9) } 2 $extrafds
+filecount stmt-2.2 { REPLACE INTO t1 VALUES(9, 9) } 2 $extrafds
+filecount stmt-2.3 { INSERT INTO t1 SELECT 9, 9 } 2 $extrafds
filecount stmt-2.4 {
INSERT INTO t1 SELECT 9, 9;
INSERT INTO t1 SELECT 10, 10;
-} 3
+} 3 $extrafds
do_test stmt-2.5 {
execsql { CREATE INDEX i1 ON t1(b) }
filecount stmt-2.6 {
REPLACE INTO t1 VALUES(5, 5);
REPLACE INTO t1 VALUES(5, 5);
-} 3
+} 3 $extrafds
finish_test
}
} {}
+set extrafds 0
+if {[forced_proxy_locking]} {
+ set extrafds 2
+}
+
do_test tempdb-2.1 {
# Set $::jrnl_in_memory if the journal file is expected to be in-memory.
# Similarly, set $::subj_in_memory if the sub-journal file is expected
}
catchsql { INSERT INTO t1 SELECT * FROM t2 }
set sqlite_open_file_count
-} [expr 1 + (0==$jrnl_in_memory) + (0==$subj_in_memory)]
+} [expr 1 + $extrafds + (0==$jrnl_in_memory) + (0==$subj_in_memory)]
do_test tempdb-2.3 {
execsql {
PRAGMA temp_store = 'memory';
}
catchsql { INSERT INTO t1 SELECT * FROM t2 }
set sqlite_open_file_count
-} [expr 1 + (0==$jrnl_in_memory)]
+} [expr 1 + $extrafds + (0==$jrnl_in_memory)]
finish_test
set perm
}
+proc forced_proxy_locking {} {
+ ifcapable lock_proxy_pragmas&&prefer_proxy_locking {
+ set force_proxy_value 0
+ set force_key "SQLITE_FORCE_PROXY_LOCKING="
+ foreach {env_pair} [exec env] {
+ if { [string first $force_key $env_pair] == 0} {
+ set force_proxy_value [string range $env_pair [string length $force_key] end]
+ }
+ }
+ if { "$force_proxy_value " == "1 " } {
+ return 1
+ }
+ }
+ return 0
+}
+
+proc wal_is_ok {} {
+ if { [forced_proxy_locking] } {
+ return 0
+ }
+ if { ![path_is_local "."] } {
+ return 0
+ }
+ if { [path_is_dos "."] } {
+ return 0
+ }
+ return 1
+}
+
#-------------------------------------------------------------------------
#
proc slave_test_script {script} {
execsql COMMIT
} {}
-do_test tkt3457-1.2 {
- file copy -force bak.db-journal test.db-journal
- file attributes test.db-journal -permissions ---------
- catchsql { SELECT * FROM t1 }
-} {1 {unable to open database file}}
-do_test tkt3457-1.3 {
- file copy -force bak.db-journal test.db-journal
- file attributes test.db-journal -permissions -w--w--w-
- catchsql { SELECT * FROM t1 }
-} {1 {unable to open database file}}
-do_test tkt3457-1.4 {
- file copy -force bak.db-journal test.db-journal
- file attributes test.db-journal -permissions r--r--r--
- catchsql { SELECT * FROM t1 }
-} {1 {unable to open database file}}
+if { ![path_is_dos "."] } {
+ do_test tkt3457-1.2 {
+ file copy -force bak.db-journal test.db-journal
+ file attributes test.db-journal -permissions ---------
+ catchsql { SELECT * FROM t1 }
+ } {1 {unable to open database file}}
+ do_test tkt3457-1.3 {
+ file copy -force bak.db-journal test.db-journal
+ file attributes test.db-journal -permissions -w--w--w-
+ catchsql { SELECT * FROM t1 }
+ } {1 {unable to open database file}}
+ do_test tkt3457-1.4 {
+ file copy -force bak.db-journal test.db-journal
+ file attributes test.db-journal -permissions r--r--r--
+ catchsql { SELECT * FROM t1 }
+ } {1 {unable to open database file}}
-do_test tkt3457-1.5 {
- file copy -force bak.db-journal test.db-journal
- file attributes test.db-journal -permissions rw-rw-rw-
- catchsql { SELECT * FROM t1 }
-} {0 {1 2 3 4 5 6}}
+ do_test tkt3457-1.5 {
+ file copy -force bak.db-journal test.db-journal
+ file attributes test.db-journal -permissions rw-rw-rw-
+ catchsql { SELECT * FROM t1 }
+ } {0 {1 2 3 4 5 6}}
+}
finish_test
source $testdir/wal_common.tcl
ifcapable !wal {finish_test ; return }
+if { ![wal_is_ok] } {
+ finish_test
+ return
+}
proc reopen_db {} {
catch { db close }
source $testdir/wal_common.tcl
ifcapable !wal {finish_test ; return }
+if { ![wal_is_ok] || [path_is_dos "."]} {
+ finish_test
+ return
+}
proc set_tvfs_hdr {file args} {
source $testdir/wal_common.tcl
source $testdir/malloc_common.tcl
ifcapable !wal {finish_test ; return }
+if { ![wal_is_ok] } {
+ finish_test
+ return
+}
set a_string_counter 1
proc a_string {n} {
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
ifcapable !wal {finish_test ; return }
+if { ![wal_is_ok] || [path_is_dos "."]} {
+ finish_test
+ return
+}
do_test wal4-1.1 {
execsql {
do_not_use_codec
ifcapable !wal {finish_test ; return }
+if { ![wal_is_ok] } {
+ finish_test
+ return
+}
# Test organization:
finish_test
return
}
+if { ![wal_is_ok] } {
+ finish_test
+ return
+}
set a_string_counter 1
proc a_string {n} {
source $testdir/wal_common.tcl
ifcapable !wal {finish_test ; return }
+if { ![wal_is_ok] } {
+ finish_test
+ return
+}
# Read and return the contents of file $filename. Treat the content as
# binary data.
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !wal {finish_test ; return }
+if { ![wal_is_ok] } {
+ finish_test
+ return
+}
db close
source $testdir/lock_common.tcl
source $testdir/wal_common.tcl
ifcapable !wal {finish_test ; return }
+if { ![wal_is_ok] } {
+ finish_test
+ return
+}
#-------------------------------------------------------------------------
source $testdir/lock_common.tcl
ifcapable !wal {finish_test ; return }
+if { ![wal_is_ok] } {
+ finish_test
+ return
+}
#-------------------------------------------------------------------------
# This test case, walfault-1-*, simulates faults while executing a
source $testdir/wal_common.tcl
ifcapable !wal {finish_test ; return }
+if { ![wal_is_ok] } {
+ finish_test
+ return
+}
set ::wal_hook [list]
proc wal_hook {zDb nEntry} {
finish_test
return
}
+if { ![wal_is_ok] } {
+ do_test walmode-0.1 {
+ execsql { PRAGMA journal_mode = wal }
+ } {delete}
+ do_test walmode-0.2 {
+ execsql { PRAGMA main.journal_mode = wal }
+ } {delete}
+ do_test walmode-0.3 {
+ execsql { PRAGMA main.journal_mode }
+ } {delete}
+
+ finish_test
+ return
+}
do_test walmode-1.1 {
set sqlite_sync_count 0
source $testdir/tester.tcl
ifcapable !wal {finish_test ; return }
+if { ![wal_is_ok] } {
+ finish_test
+ return
+}
proc reopen_db {} {
catch { db close }
source $testdir/lock_common.tcl
if {[run_thread_tests]==0} { finish_test ; return }
ifcapable !wal { finish_test ; return }
+if { ![wal_is_ok] } {
+ finish_test
+ return
+}
set sqlite_walsummary_mmap_incr 64