From: adam Date: Mon, 2 Apr 2012 23:35:45 +0000 (+0000) Subject: Merge in latest changes, autologging options, read only file system wal support,... X-Git-Tag: mountain-lion~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0cb33b650cf7ed93ac514fa325ef3a1c9c49e983;p=thirdparty%2Fsqlite.git Merge in latest changes, autologging options, read only file system wal support, test config conditionalization, WAL frame write prebuffering FossilOrigin-Name: d51c086e5c006821e2ab932f229649a729d914b2 --- diff --git a/manifest b/manifest index 53f5c8bfbf..4d56e8f74c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sall\sthe\slatest\strunk\schanges\sinto\sthe\sapple-osx\sbranch. -D 2012-03-31T02:46:20.444 +C Merge\sin\slatest\schanges,\sautologging\soptions,\sread\sonly\sfile\ssystem\swal\ssupport,\stest\sconfig\sconditionalization,\sWAL\sframe\swrite\sprebuffering +D 2012-04-02T23:35:45.151 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7bd2fa7753fc9de38994b8d4fa7f10deb19966a5 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -151,7 +151,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 d61d7eacf656b19b353e2cab34daf4eba4ba8c8f +F src/main.c 2ba24071c42849fde838c32f1b508712c51dd758 F src/malloc.c 15afac5e59b6584efe072e9933aefb4230e74f97 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c b3677415e69603d6a0e7c5410a1b3731d55beda1 @@ -170,7 +170,7 @@ 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 c008584c899e9c6b702078fbb9cb59839a0a66d3 +F src/os_unix.c 5e6ead4f8f4236f0ed016ca4518300985daddf7e F src/os_win.c 12e76b4aa5426022939f92e894a5c20dd40be7f4 F src/pager.c ce4fde5951bf71b4f5316ff5afd0219ff7e99b3f F src/pager.h ef1eaf8593e78f73885c1dfac27ad83bee23bdc5 @@ -186,15 +186,15 @@ F src/resolve.c 3d3e80a98f203ac6b9329e9621e29eda85ddfd40 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697 F src/select.c 36d5ed5c4504fd37c024141ce2b699148b231a8d F src/shell.c abf18d6ee54f2631860a98fdd7ab1327f470db67 -F src/sqlite.h.in 5538b920986b8c1f8385b97b7ae31b74a39a9ca5 -F src/sqlite3_private.h e3b586e0aa329075d99be7198df9bc80c5b19e2d +F src/sqlite.h.in 8714ac9f594717d667fb0c1149f97332bebce8e0 +F src/sqlite3_private.h 77bebe843a3eabfb7994990aab780d34d25819c7 F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477 F src/sqliteInt.h efee04f7c9e000b77d89f87baf77397b4025246c F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 35939e7e03abf1b7577ce311f48f682c40de3208 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/tclsqlite.c 086dfdd72e5892de223968a258e1ccbd9693e717 -F src/test1.c fa09748bbcd6c3efa076e45648857e922ce97224 +F src/test1.c a23a59fb8aaa49f94fe5d214907618264f05b923 F src/test2.c 711555927f1f7e8db9aab86b512bc6934a774abe F src/test3.c f82399ec50d9cd7378bf9d6db6c1409d5e77b042 F src/test4.c d1e5a5e904d4b444cf572391fdcb017638e36ff7 @@ -255,11 +255,11 @@ F src/vdbemem.c fb0ac964ccbcd94f595eb993c05bfd9c52468a4a F src/vdbesort.c b25814d385895544ebc8118245c8311ded7f81c9 F src/vdbetrace.c 2405f68d14c49d2e0a798d71e35d62b8569bfb65 F src/vtab.c ab90fb600a3f5e4b7c48d22a4cdb2d6b23239847 -F src/wal.c 8a89f4f60097c88e3b5c3baeb5f4942035411a29 +F src/wal.c c13ee6f76871d33a2c33be3959d2281a77233a53 F src/wal.h a8ade3069ab75e3c79e9ca067a5ac7e1dbaf93a6 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f F src/where.c 2112422a404dcca5d47f6630bdf180bccd36c62b -F test/8_3_names.test 631ea964a3edb091cf73c3b540f6bcfdb36ce823 +F test/8_3_names.test 0ed0f6711fefac33829ef9f1d6ca3c56c48ef1c7 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 52fc8dee494092031a556911d404ca30a749a30b @@ -283,7 +283,7 @@ F test/async5.test 0dd8701bd588bf6e70c2557a22ae3f22b2567b4c F test/attach.test 63033baa59be42c811ef0d4e73ebd2d6dba4805c F test/attach2.test e54436ed956d3d88bdee61221da59bf3935a0966 F test/attach3.test d89ccfe4fe6e2b5e368d480fcdfe4b496c54cf4e -F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c +F test/attach4.test faaaf33fa51f986b414520cb03cecdc7999df108 F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0 F test/auth.test 304e82f31592820d3bde26ab6b75deaa123e1a6f F test/auth2.test 270baddc8b9c273682760cffba6739d907bd2882 @@ -320,9 +320,9 @@ F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0 F test/cache.test f64136b0893c293d0b910ed057b3b711249099a7 F test/capi2.test 835d4cee9f542ea50fa8d01f3fe6de80b0627360 -F test/capi3.test 9c8b58b6a6aeb14e69bd8c8c7721b47d640464d1 +F test/capi3.test 468b750927dd6b8ed487232bb8ea93ce03edd605 F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4 -F test/capi3c.test 1b5424d2ac57b7b443b5de5b9a287642c02279b6 +F test/capi3c.test 7f45970fb0ae10d04cb957030fef725758a48898 F test/capi3d.test 17b57ca28be3e37e14c2ba8f787d292d84b724a1 F test/capi3e.test f7408dda65c92b9056199fdc180f893015f83dde F test/cast.test 4c275cbdc8202d6f9c54a3596701719868ac7dc3 @@ -530,7 +530,7 @@ F test/incrblob4.test 09be37d3dd996a31ea6993bba7837ece549414a8 F test/incrblob_err.test d2562d2771ebffd4b3af89ef64c140dd44371597 F test/incrblobfault.test 917c0292224c64a56ef7215fd633a3a82f805be0 F test/incrvacuum.test d2a6ddf5e429720b5fe502766af747915ccf6c32 -F test/incrvacuum2.test c776f80c2b20d4088f9ff3fd0177ff76af9f51b7 +F test/incrvacuum2.test a1828b6165af6c248c4eb80aeaee2bcbb45768c1 F test/incrvacuum_ioerr.test 22f208d01c528403240e05beecc41dc98ed01637 F test/index.test b5429732b3b983fa810e3ac867d7ca85dae35097 F test/index2.test ee83c6b5e3173a3d7137140d945d9a5d4fdfb9d6 @@ -637,7 +637,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 34fb695debe94ba64d9b949cc6da11dbcc786e3d +F test/pager1.test 4fbf634d26661578af38db830bd3442287aed91d F test/pager2.test 745b911dde3d1f24ae0870bd433dfa83d7c658c1 F test/pager3.test 3856d9c80839be0668efee1b74811b1b7f7fc95f F test/pagerfault.test a15ef77c8495882d7debb43794e87b6e46174c8a @@ -715,13 +715,13 @@ F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298 -F test/stat.test 08e8185b3fd5b010c90d7ad82b9dd4ea1cbf14b0 +F test/stat.test 4ce96d67f6a0bc9647a042c7140cf1c56e049a69 F test/stmt.test 78a6764439cfa5abdcbf98d4d084739e81eeec4f F test/subquery.test b524f57c9574b2c0347045b4510ef795d4686796 F test/subquery2.test edcad5c118f0531c2e21bf16a09bbb105252d4cd F test/subselect.test d24fd8757daf97dafd2e889c73ea4c4272dcf4e4 F test/substr.test 18f57c4ca8a598805c4d64e304c418734d843c1a -F test/superlock.test d69dcf1cd52c52c38dbb2df432233e1ecb62fd09 +F test/superlock.test 2b27b4ae7c6b9d534b0412e0d99f989aa1f3b9cf F test/sync.test a34cd43e98b7fb84eabbf38f7ed8f7349b3f3d85 F test/syscall.test bea9bf329bff733c791310244617c2a76974e64a F test/sysfault.test c79441d88d23696fbec7b147dba98d42a04f523f @@ -745,17 +745,17 @@ F test/threadtest2.c ace893054fa134af3fc8d6e7cfecddb8e3acefb9 F test/threadtest3.c 0ed13e09690f6204d7455fac3b0e8ece490f6eef F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c F test/tkt-26ff0c2d1e.test 888324e751512972c6e0d1a09df740d8f5aaf660 -F test/tkt-2d1a5c67d.test b028a811049eb472cb2d3a43fc8ce4f6894eebda +F test/tkt-2d1a5c67d.test 0e23cbbbecda6ce453ffb560fdac28489d491d36 F test/tkt-2ea2425d34.test 1cf13e6f75d149b3209a0cb32927a82d3d79fb28 F test/tkt-31338dca7e.test 1f714c14b6682c5db715e0bda347926a3456f7a9 -F test/tkt-313723c356.test c47f8a9330523e6f35698bf4489bcb29609b53ac +F test/tkt-313723c356.test 54a1558d2719e171bd88967d66c73be4c617ec55 F test/tkt-38cb5df375.test f3cc8671f1eb604d4ae9cf886ed4366bec656678 F test/tkt-3998683a16.test 6d1d04d551ed1704eb3396ca87bb9ccc8c5c1eb7 F test/tkt-3a77c9714e.test 32bb28afa8c63fc76e972e996193139b63551ed9 F test/tkt-3fe897352e.test 10de1a67bd5c66b238a4c96abe55531b37bb4f00 F test/tkt-4a03edc4c8.test 2865e4edbc075b954daa82f8da7cc973033ec76e F test/tkt-54844eea3f.test a12b851128f46a695e4e378cca67409b9b8f5894 -F test/tkt-5d863f876e.test 884072c2de496ddbb90c387c9ebc0d4f44a91b8e +F test/tkt-5d863f876e.test b4b58f9e14ddd29f6e7577aad16b2d43b1237429 F test/tkt-5e10420e8d.test 904d1687b3c06d43e5b3555bbcf6802e7c0ffd84 F test/tkt-5ee23731f.test 9db6e1d7209dc0794948b260d6f82b2b1de83a9f F test/tkt-752e1646fc.test ea78d88d14fe9866bdd991c634483334639e13bf @@ -920,29 +920,29 @@ 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 8871e7fd2c86711ff415a5817d68ea3101a15312 -F test/wal3.test 6504bbf348b2d6dfade64a064f1050fd617e8706 +F test/wal2.test ea811f7bc9abbc4282700c8969b175c31e884045 +F test/wal3.test ae86a92d41d81730278fca0b71368f3e78e9c64a F test/wal4.test 5755887f321baa4c55de0b91066fa7d0cafcac9d -F test/wal5.test f58ed4b8b542f71c7441da12fbd769d99b362437 +F test/wal5.test 46a422956ec203bc5899dad5e70d9e655b1c91e4 F test/wal6.test c561d1e44c89f9cb458a7b03003ed4baac08ba07 -F test/wal7.test 2ae8f427d240099cc4b2dfef63cff44e2a68a1bd -F test/wal8.test 5ab217d21f7e5e86af2933a4ffd0d8357cc2c0bd +F test/wal7.test 18cf68ab8010ae0a2baaa48e5b59567a9503e63e +F test/wal8.test a0b7dee73fc3d3bbf167e04533d37df379a0b7d1 F test/wal_common.tcl 15f152fd55703975878741beca6cfa4209d5b3b3 -F test/walbak.test b30cbbb2996947c96a2e562020dff61013a17a96 -F test/walbig.test 65699b66911a681e194eec280d45c6ee715e48b4 -F test/walcksum.test 3dff8817d31a4207d1ad31e7da06073a34e7fe1c -F test/walcrash.test 5f749f38e4a5ee1f862c88a73286b35cf05031a0 +F test/walbak.test 8edea4daad739587f049633071d0f063fa808049 +F test/walbig.test 3ca3d94751b80054eed5bda20a1339ae1f619483 +F test/walcksum.test 6510e82303f6fffc2c55bb77a7774cd0eed21a6e +F test/walcrash.test a8fa8d8a9a50a49b7abaf8a4a7e2c7ea352c49be F test/walcrash2.test c032d0040374ae28b41f99fc0cc290b4e2e34f17 -F test/walcrash3.test 595e44c6197f0d0aa509fc135be2fd0209d11a2c -F test/walfault.test a16ad4987e6ff433e9dc760fec91f95c174c8e51 -F test/walhook.test c934ac5219fee2b4e7653d291db9107b8dc73bba +F test/walcrash3.test 97e775404f4c76e5c46f71fbd09691c7e9c25c68 +F test/walfault.test e5309befcaf4ab08151c35dba20cc5b8a5846748 +F test/walhook.test 9716f865303130d7fcda61bcabb863090be9cca2 F test/walmode.test 9308ffc25555a1c4eaa44a863792240406637496 -F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496 -F test/walpersist.test 8c6b7e3ec1ba91b5e4dc4e0921d6d3f87cd356a6 -F test/walro.test e6bb27762c9f22601cbb8bff6e0acfd124e74b63 -F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417 -F test/walslow.test 3c2475d7672511380d33cef1924a065d2ad62ff0 -F test/walthread.test 3decc7e72594e0270dc1a1cc0984d6db7165b4cc +F test/walnoshm.test b1337ce99aabdf4da7a4a3f0c5ce1f05450bc3cc +F test/walpersist.test 12d1a54a5d5e06af0ec4bbd5421608a957ed8630 +F test/walro.test 04d6382b2a87cfc82b87336eb8d8a8e9afd8bcf8 +F test/walshared.test 04590b10c677f75318701818c50bc0dda5da64ab +F test/walslow.test 658066419a92d3bd85be71a11ce477af4ffe9153 +F test/walthread.test c3aaf9ef7ad21ae79c2345425bfddb39cdac954f F test/where.test de337a3fe0a459ec7c93db16a519657a90552330 F test/where2.test 43d4becaf5a5df854e6c21d624a1cb84c6904554 F test/where3.test 667e75642102c97a00bf9b23d3cb267db321d006 @@ -1004,7 +1004,7 @@ F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381 -P f999197b75465a1f71ac1dab8f22ba2167fc0c67 f9a7e179cbbeeab5e57bbf392bef89750215546b -R 82541a9eaf4a147ff8f864155ac5fc2d -U drh -Z ccad7cece0bf00c1026435d33943b52d +P 18ec60cacd37a70d598ac1af5e50faffa73bb134 +R 73390db6e66a079b7d6e56cc27ecf8d0 +U adam +Z d6996fec7b0aa226442af546de346566 diff --git a/manifest.uuid b/manifest.uuid index a7a37f9c0b..3f2eba4ec3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -18ec60cacd37a70d598ac1af5e50faffa73bb134 \ No newline at end of file +d51c086e5c006821e2ab932f229649a729d914b2 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 84ea47b4d2..1d56540db6 100644 --- a/src/main.c +++ b/src/main.c @@ -1850,6 +1850,7 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ return oldLimit; /* IMP: R-53341-35419 */ } #if defined(SQLITE_ENABLE_AUTO_PROFILE) +/* stderr logging */ void _sqlite_auto_profile(void *aux, const char *sql, u64 ns); void _sqlite_auto_trace(void *aux, const char *sql); void _sqlite_auto_profile(void *aux, const char *sql, u64 ns) { @@ -1859,6 +1860,32 @@ void _sqlite_auto_profile(void *aux, const char *sql, u64 ns) { void _sqlite_auto_trace(void *aux, const char *sql) { fprintf(stderr, "TraceSQL(%p): %s\n", aux, sql); } + +/* syslog logging */ +#include +static aslclient autolog_client = NULL; +static void _close_asl_log() { + if( NULL!=autolog_client ){ + asl_close(autolog_client); + autolog_client = NULL; + } +} +static void _open_asl_log() { + if( NULL==autolog_client ){ + autolog_client = asl_open("SQLite", NULL, 0); + atexit(_close_asl_log); + } +} + +void _sqlite_auto_profile_syslog(void *aux, const char *sql, u64 ns); +void _sqlite_auto_trace_syslog(void *aux, const char *sql); +void _sqlite_auto_profile_syslog(void *aux, const char *sql, u64 ns) { +#pragma unused(aux) + asl_log(autolog_client, NULL, ASL_LEVEL_NOTICE, "Query: %s\n Execution Time: %llu ms\n", sql, ns / 1000000); +} +void _sqlite_auto_trace_syslog(void *aux, const char *sql) { + asl_log(autolog_client, NULL, ASL_LEVEL_NOTICE, "TraceSQL(%p): %s\n", aux, sql); +} #endif /* @@ -2090,6 +2117,57 @@ int sqlite3ParseUri( return rc; } +#if defined(SQLITE_ENABLE_AUTO_PROFILE) +#define SQLITE_AUTOLOGGING_STDERR 1 +#define SQLITE_AUTOLOGGING_SYSLOG 2 +static void enableAutoLogging( + sqlite3 *db +){ + char *envprofile = getenv("SQLITE_AUTO_PROFILE"); + + if( envprofile!=NULL ){ + int where = 0; + if( !strncasecmp("1", envprofile, 1) ){ + if( isatty(STDERR_FILENO) ){ + where = SQLITE_AUTOLOGGING_STDERR; + }else{ + where = SQLITE_AUTOLOGGING_SYSLOG; + } + } else if( !strncasecmp("stderr", envprofile, 6) ){ + where = SQLITE_AUTOLOGGING_STDERR; + } else if( !strncasecmp("syslog", envprofile, 6) ){ + where = SQLITE_AUTOLOGGING_SYSLOG; + } + if( where==SQLITE_AUTOLOGGING_STDERR ){ + sqlite3_profile(db, _sqlite_auto_profile, db); + }else if( where==SQLITE_AUTOLOGGING_SYSLOG ){ + _open_asl_log(); + sqlite3_profile(db, _sqlite_auto_profile_syslog, db); + } + } + char *envtrace = getenv("SQLITE_AUTO_TRACE"); + if( envtrace!=NULL ){ + int where = 0; + if( !strncasecmp("1", envtrace, 1) ){ + if( isatty(STDERR_FILENO) ){ + where = SQLITE_AUTOLOGGING_STDERR; + }else{ + where = SQLITE_AUTOLOGGING_SYSLOG; + } + } else if( !strncasecmp("stderr", envtrace, 6) ){ + where = SQLITE_AUTOLOGGING_STDERR; + } else if( !strncasecmp("syslog", envtrace, 6) ){ + where = SQLITE_AUTOLOGGING_SYSLOG; + } + if( where==SQLITE_AUTOLOGGING_STDERR ){ + sqlite3_trace(db, _sqlite_auto_trace, db); + }else if( where==SQLITE_AUTOLOGGING_SYSLOG ){ + _open_asl_log(); + sqlite3_trace(db, _sqlite_auto_trace_syslog, db); + } + } +} +#endif /* ** This routine does the work of opening a database on behalf of @@ -2351,18 +2429,25 @@ opendb_out: }else if( rc!=SQLITE_OK ){ db->magic = SQLITE_MAGIC_SICK; } -#if defined(SQLITE_ENABLE_AUTO_PROFILE) +#if defined(__APPLE__) && ENABLE_FORCE_WAL if( db && !rc ){ - char *envprofile = getenv("SQLITE_AUTO_PROFILE"); - char *envtrace = getenv("SQLITE_AUTO_TRACE"); - - if( envprofile!=NULL ){ - sqlite3_profile(db, _sqlite_auto_profile, db); - } - if( envtrace!=NULL ){ - sqlite3_trace(db, _sqlite_auto_trace, db); + if ((0 == access("/var/db/enableForceWAL", R_OK))) { +#ifdef SQLITE_DEBUG + fprintf(stderr, "SQLite WAL journal_mode ENABLED by default.\n"); +#endif + + sqlite3_exec(db, "pragma journal_mode=wal", NULL, NULL, NULL); +#ifdef SQLITE_DEBUG +// } else { +// fprintf(stderr, "SQLite WAL journal_mode NOT ENABLED by default.\n"); +#endif } } +#endif +#if defined(SQLITE_ENABLE_AUTO_PROFILE) + if( db && !rc ){ + enableAutoLogging(db); + } #endif *ppDb = db; #ifdef SQLITE_ENABLE_SQLRR @@ -3108,6 +3193,9 @@ int _sqlite3_lockstate(const char *path, pid_t pid){ int state = lockstate.state; return state; } + if( NULL!=db ){ + sqlite3_close(db); /* need to close even if open returns an error */ + } return SQLITE_LOCKSTATE_ERROR; } diff --git a/src/os_unix.c b/src/os_unix.c index be50b43719..2a6fba2a90 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -2004,7 +2004,11 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ lock.l_len = divSize; if( unixFileLock(pFile, &lock, 10)==(-1) ){ tErrno = errno; +#if OSLOCKING_CHECK_BUSY_IOERR rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); +#else + rc = SQLITE_IOERR_UNLOCK; +#endif if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } @@ -2239,7 +2243,26 @@ static int nolockUnlock(sqlite3_file *NotUsed, int NotUsed2){ ** Close the file. */ static int nolockClose(sqlite3_file *id) { - return closeUnixFile(id); + int rc = SQLITE_OK; + unixFile *pFile = (unixFile *)id; + unixEnterMutex(); + + /* unixFile.pInode is always valid here. Otherwise, a different close + ** routine (e.g. nolockClose()) would be called instead. + */ + assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 ); + if( ALWAYS(pFile->pInode) && pFile->pInode->nLock ){ + /* If there are outstanding locks, do not actually close the file just + ** yet because that would clear those locks. Instead, add the file + ** descriptor to pInode->pUnused list. It will be automatically closed + ** when the last lock is cleared. + */ + setPendingFd(pFile); + } + releaseInodeInfo(pFile); + rc = closeUnixFile(id); + unixLeaveMutex(); + return rc; } /******************* End of the no-op lock implementation ********************* @@ -3926,6 +3949,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){ return SQLITE_OK; } + #if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) #include "sqlite3_private.h" #include @@ -3934,105 +3958,9 @@ static int getDbPathForUnixFile(unixFile *pFile, char *dbPath); static int isProxyLockingMode(unixFile *); #if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) -static int unixTruncateDatabase(unixFile *pFile, int bFlags) { - sqlite3_file *id = (sqlite3_file *)pFile; - int rc = SQLITE_OK; - void *pLock = NULL; - int flags = 0; - int corruptFileLock = 0; - int isCorrupt = 0; - -#if SQLITE_ENABLE_DATA_PROTECTION - flags |= pFile->protFlags; -#endif -#if SQLITE_ENABLE_LOCKING_STYLE - if( isProxyLockingMode(pFile) ){ - flags |= SQLITE_OPEN_AUTOPROXY; - } -#endif - - rc = sqlite3demo_superlock(pFile->zPath, 0, flags, 0, 0, &pLock); - if( rc ){ - if( rc==SQLITE_CORRUPT || rc==SQLITE_NOTADB ){ - isCorrupt = 1; - rc = sqlite3demo_superlock_corrupt(id, SQLITE_LOCK_EXCLUSIVE, &corruptFileLock); - } - if( rc ){ - return rc; - } - } - rc = pFile->pMethod->xTruncate(id, ((pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS) != 0) ? 1L : 0L); - if( rc==SQLITE_OK ){ - unixInvalidateSupportFiles(pFile, 0); - } - pFile->pMethod->xSync(id, SQLITE_SYNC_FULL); - +static int unixTruncateDatabase(unixFile *, int); - if( isCorrupt ){ - sqlite3demo_superunlock_corrupt(id, corruptFileLock); - }else{ - sqlite3demo_superunlock(pLock); - } - return rc; -} - -static int unixInvalidateSupportFiles(unixFile *pFile, int skipWAL) { - char jPath[MAXPATHLEN+9]; - int zLen = strlcpy(jPath, pFile->zPath, MAXPATHLEN+9); - if( zLenpInode is shared across threads */ - unixShmNode *pShmNode = pFile->pInode->pShmNode; - if( pShmNode && !pShmNode->isReadonly ){ - struct stat sStat; - sqlite3_mutex_enter(pShmNode->mutex); - - if( pShmNode->h>=0 && !osFstat(pShmNode->h, &sStat) ){ - unsigned long size = (sStat.st_size<4) ? sStat.st_size : 4; - if( size>0 ){ - bzero(pShmNode->apRegion[0], size); - sqlite3_mutex_leave(pShmNode->mutex); - unixLeaveMutex(); - continue; - } - } - sqlite3_mutex_leave(pShmNode->mutex); - } - unixLeaveMutex(); - } - jLen = strlcpy(&jPath[zLen], extensions[j], 9); - if( jLen < 9 ){ - int jflags = (j<2) ? O_TRUNC : O_RDWR; - int jfd = open(jPath, jflags); - if( jfd==(-1) ){ - if( errno!=ENOENT ){ - perror(jPath); - } - } else { - if( j==2 ){ - struct stat sStat; - if( !osFstat(jfd, &sStat) ){ - unsigned long size = (sStat.st_size<4) ? sStat.st_size : 4; - if( size>0 ){ - uint32_t zero = 0; - pwrite(jfd, &zero, (size_t)size, 0); - } - } - } - fsync(jfd); - close(jfd); - } - } - } - } - return SQLITE_OK; -} +static int unixInvalidateSupportFiles(unixFile *, int); static int unixReplaceDatabase(unixFile *pFile, sqlite3 *srcdb) { sqlite3_file *id = (sqlite3_file *)pFile; @@ -4257,90 +4185,7 @@ static int unixIsLocked( return 0; } -/* -** This test only works for lock testing on unix/posix VFS. -** Adapted from tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce -*/ -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 nLock = 0; /* Number of locks held */ - unsigned char aHdr[100]; /* Database header */ - - assert(pLockstate); - - /* make sure we are dealing with a database file */ - hDb = pFile->h; - if( hDb<0 ){ - *pLockstate = SQLITE_LOCKSTATE_ERROR; - return SQLITE_ERROR; - } - assert( (strlen(SQLITE_FILE_HEADER)+1)==SQLITE_FILE_HEADER_LEN ); - got = pread(hDb, aHdr, 100, 0); - if( got<0 ){ - *pLockstate = SQLITE_LOCKSTATE_ERROR; - return SQLITE_ERROR; - } - 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( nLock==0 && isWal==0 ){ - /* Rollback mode */ - nLock += unixIsLocked(pid, hDb, F_WRLCK, PENDING_BYTE, SHARED_SIZE+2, "PENDING|RESERVED|SHARED"); - } - if( nLock==0 && isWal!=0 ){ - /* lookup the file descriptor for the shared memory file if we have it open in this process */ - unixEnterMutex(); /* Because pFile->pInode is shared across threads */ - unixShmNode *pShmNode = pFile->pInode->pShmNode; - if( pShmNode ){ - sqlite3_mutex_enter(pShmNode->mutex); - - hShm = pShmNode->h; - if( hShm >= 0){ - if( unixIsLocked(pid, hShm, F_RDLCK, SHM_RECOVER, 1, "WAL-RECOVERY") || - unixIsLocked(pid, hShm, F_RDLCK, SHM_WRITE, 1, "WAL-WRITE") ){ - nLock = 1; - } - } - - sqlite3_mutex_leave(pShmNode->mutex); - } - - if( hShm<0 ){ - /* the shared memory file isn't open in this process space, open our own FD */ - char zShm[MAXPATHLEN]; - - /* WAL mode */ - strlcpy(zShm, pFile->zPath, MAXPATHLEN); - strlcat(zShm, "-shm", MAXPATHLEN); - hShm = open(zShm, O_RDONLY, 0); - if( hShm<0 ){ - *pLockstate = SQLITE_LOCKSTATE_OFF; - unixLeaveMutex(); - return SQLITE_OK; - } - if( unixIsLocked(pid, hShm, F_RDLCK, SHM_RECOVER, 1, "WAL-RECOVERY") || - unixIsLocked(pid, hShm, F_RDLCK, SHM_WRITE, 1, "WAL-WRITE") ){ - nLock = 1; - } - close(hShm); - } - unixLeaveMutex(); - } - if( nLock>0 ){ - *pLockstate = SQLITE_LOCKSTATE_ON; - } else { - *pLockstate = SQLITE_LOCKSTATE_OFF; - } - return SQLITE_OK; -} +static int unixLockstatePid(unixFile *, pid_t, int *); #endif /* (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) */ @@ -4371,7 +4216,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ *(int*)pArg = pFile->eFileLock; return SQLITE_OK; } - case SQLITE_LAST_ERRNO: { + case SQLITE_FCNTL_LAST_ERRNO: { *(int*)pArg = pFile->lastErrno; return SQLITE_OK; } @@ -4410,8 +4255,8 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ } #endif #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) - case SQLITE_SET_LOCKPROXYFILE: - case SQLITE_GET_LOCKPROXYFILE: { + case SQLITE_FCNTL_SET_LOCKPROXYFILE: + case SQLITE_FCNTL_GET_LOCKPROXYFILE: { return proxyFileControl(id,op,pArg); } #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ @@ -5139,7 +4984,14 @@ static int unixShmUnmap( assert( pShmNode->nRef>0 ); pShmNode->nRef--; if( pShmNode->nRef==0 ){ - if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename); + if( deleteFlag && pShmNode->h>=0 ) { + if (deleteFlag == 1) { + unlink(pShmNode->zFilename); + } else if (deleteFlag == 2) { + //ftruncate(pShmNode->h, 32 * 1024); + } + } + unixShmPurge(pDbFd); } unixLeaveMutex(); @@ -5155,6 +5007,282 @@ static int unixShmUnmap( # define unixShmUnmap 0 #endif /* #ifndef SQLITE_OMIT_WAL */ +#if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) +static const char *unixTempFileDir(void); + +static int unixInvalidateSupportFiles(unixFile *pFile, int skipWAL) { + char jPath[MAXPATHLEN+9]; + int zLen = strlcpy(jPath, pFile->zPath, MAXPATHLEN+9); + if( zLenpInode is shared across threads */ + unixShmNode *pShmNode = pFile->pInode->pShmNode; + if( pShmNode && !pShmNode->isReadonly ){ + struct stat sStat; + sqlite3_mutex_enter(pShmNode->mutex); + + if( pShmNode->h>=0 && !osFstat(pShmNode->h, &sStat) ){ + unsigned long size = (sStat.st_size<4) ? sStat.st_size : 4; + if( size>0 ){ + bzero(pShmNode->apRegion[0], size); + sqlite3_mutex_leave(pShmNode->mutex); + unixLeaveMutex(); + continue; + } + } + sqlite3_mutex_leave(pShmNode->mutex); + } + unixLeaveMutex(); + } + jLen = strlcpy(&jPath[zLen], extensions[j], 9); + if( jLen < 9 ){ + int jflags = (j<2) ? O_TRUNC : O_RDWR; + int jfd = open(jPath, jflags); + if( jfd==(-1) ){ + if( errno!=ENOENT ){ + perror(jPath); + } + } else { + if( j==2 ){ + struct stat sStat; + if( !osFstat(jfd, &sStat) ){ + unsigned long size = (sStat.st_size<4) ? sStat.st_size : 4; + if( size>0 ){ + uint32_t zero = 0; + pwrite(jfd, &zero, (size_t)size, 0); + } + } + } + fsync(jfd); + close(jfd); + } + } + } + } + return SQLITE_OK; +} + +static int unixTruncateDatabase(unixFile *pFile, int bFlags) { + sqlite3_file *id = (sqlite3_file *)pFile; + int rc = SQLITE_OK; + void *pLock = NULL; + int flags = 0; + int corruptFileLock = 0; + int isCorrupt = 0; + +#if SQLITE_ENABLE_DATA_PROTECTION + flags |= pFile->protFlags; +#endif +#if SQLITE_ENABLE_LOCKING_STYLE + if( isProxyLockingMode(pFile) ){ + flags |= SQLITE_OPEN_AUTOPROXY; + } +#endif + + rc = sqlite3demo_superlock(pFile->zPath, 0, flags, 0, 0, &pLock); + if( rc ){ + if( rc==SQLITE_CORRUPT || rc==SQLITE_NOTADB ){ + isCorrupt = 1; + rc = sqlite3demo_superlock_corrupt(id, SQLITE_LOCK_EXCLUSIVE, &corruptFileLock); + } + if( rc ){ + return rc; + } + } + if( bFlags!=0 ){ + /* initialize a new database in TMPDIR and copy the contents over */ + const char *tDir = unixTempFileDir(); + int tLen = sizeof(char) * (strlen(tDir) + 11); + char *tDbPath = (char *)malloc(tLen); + int tFd = -1; + + strlcpy(tDbPath, tDir, tLen); + strlcat(tDbPath, "tmpdbXXXXX", tLen); + tFd = mkstemp(tDbPath); + if( tFd==-1 ){ + pFile->lastErrno=errno; + rc = SQLITE_IOERR; + }else{ + sqlite3 *tDb = NULL; + copyfile_state_t s; + int trc = sqlite3_open_v2(tDbPath, &tDb, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_AUTOPROXY, NULL); + char *errmsg = NULL; + const char *sql = ""; + if( !trc && (bFlags&SQLITE_TRUNCATE_PAGESIZE_MASK) ){ + const char pagesize_sql[4][22] = { "pragma page_size=1024", "pragma page_size=2048", "pragma page_size=4096", "pragma page_size=8192" }; + int iPagesize = (((bFlags&SQLITE_TRUNCATE_PAGESIZE_MASK) >> 4) - 1); + assert( iPagesize>=0 && iPagesize<=4 ); + sql = pagesize_sql[iPagesize]; + trc = sqlite3_exec(tDb, sql, 0, 0, &errmsg); + } + if( !trc ){ + const char autovacuum_sql[3][21] = { "pragma auto_vacuum=0", "pragma auto_vacuum=1", "pragma auto_vacuum=2" }; + int iAutovacuum = 2; /* default to incremental */ + if( (bFlags&SQLITE_TRUNCATE_AUTOVACUUM_MASK) ){ + iAutovacuum = (((bFlags&SQLITE_TRUNCATE_AUTOVACUUM_MASK) >> 2) - 1); + } + assert( iAutovacuum>=0 && iAutovacuum<=2 ); + sql = autovacuum_sql[iAutovacuum]; + trc = sqlite3_exec(tDb, sql, 0, 0, &errmsg); + } + if( !trc && (bFlags&SQLITE_TRUNCATE_JOURNALMODE_WAL) ){ + sql = "pragma journal_mode=wal"; + trc = sqlite3_exec(tDb, sql, 0, 0, &errmsg); + } + if( trc ){ + if( !tDb ){ + fprintf(stderr, "failed to open temp database '%s' to reset truncated database %s with flags %x: %d\n", tDbPath, pFile->zPath, bFlags, trc); + }else{ + fprintf(stderr, "failed to set '%s' on truncated database %s, %d: %s\n", sql, pFile->zPath, trc, errmsg); + } + } + if( tDb ){ + sqlite3_close(tDb); + } + s = copyfile_state_alloc(); + lseek(tFd, 0, SEEK_SET); + lseek(pFile->h, 0, SEEK_SET); + if( fcopyfile(tFd, pFile->h, s, COPYFILE_ALL) ){ + int err=errno; + switch(err) { + case ENOMEM: + rc = SQLITE_NOMEM; + break; + default: + pFile->lastErrno = err; + rc = SQLITE_IOERR; + } + } + copyfile_state_free(s); + fsync(pFile->h); + close(tFd); + unlink(tDbPath); + } + free(tDbPath); + } else { + rc = pFile->pMethod->xTruncate(id, ((pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS) != 0) ? 1L : 0L); + } + if( rc==SQLITE_OK ){ + unixInvalidateSupportFiles(pFile, 0); + } + pFile->pMethod->xSync(id, SQLITE_SYNC_FULL); + + + if( isCorrupt ){ + sqlite3demo_superunlock_corrupt(id, corruptFileLock); + }else{ + sqlite3demo_superunlock(pLock); + } + return rc; +} + +/* + ** Lock locations for shared-memory locks used by WAL mode. + */ +#ifndef SHM_BASE +# define SHM_BASE 120 +# define SHM_WRITE SHM_BASE +# define SHM_CHECKPOINT (SHM_BASE+1) +# define SHM_RECOVER (SHM_BASE+2) +# define SHM_READ_FIRST (SHM_BASE+3) +# define SHM_READ_SIZE 5 +#endif /* SHM_BASE */ + +/* +** This test only works for lock testing on unix/posix VFS. +** Adapted from tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce +*/ +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 nLock = 0; /* Number of locks held */ + unsigned char aHdr[100]; /* Database header */ + + assert(pLockstate); + + /* make sure we are dealing with a database file */ + hDb = pFile->h; + if( hDb<0 ){ + *pLockstate = SQLITE_LOCKSTATE_ERROR; + return SQLITE_ERROR; + } + assert( (strlen(SQLITE_FILE_HEADER)+1)==SQLITE_FILE_HEADER_LEN ); + got = pread(hDb, aHdr, 100, 0); + if( got<0 ){ + *pLockstate = SQLITE_LOCKSTATE_ERROR; + return SQLITE_ERROR; + } + 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( nLock==0 && isWal==0 ){ + /* Rollback mode */ + nLock += unixIsLocked(pid, hDb, F_WRLCK, PENDING_BYTE, SHARED_SIZE+2, "PENDING|RESERVED|SHARED"); + } + if( nLock==0 && isWal!=0 ){ + /* lookup the file descriptor for the shared memory file if we have it open in this process */ + unixEnterMutex(); /* Because pFile->pInode is shared across threads */ + unixShmNode *pShmNode = pFile->pInode->pShmNode; + if( pShmNode ){ + sqlite3_mutex_enter(pShmNode->mutex); + + hShm = pShmNode->h; + if( hShm >= 0){ + if( unixIsLocked(pid, hShm, F_RDLCK, SHM_RECOVER, 1, "WAL-RECOVERY") || + unixIsLocked(pid, hShm, F_RDLCK, SHM_WRITE, 1, "WAL-WRITE") ){ + nLock = 1; + } + } + + sqlite3_mutex_leave(pShmNode->mutex); + } + + if( hShm<0 ){ + /* the shared memory file isn't open in this process space, open our own FD */ + char zShm[MAXPATHLEN]; + + /* WAL mode */ + strlcpy(zShm, pFile->zPath, MAXPATHLEN); + strlcat(zShm, "-shm", MAXPATHLEN); + hShm = open(zShm, O_RDONLY, 0); + if( hShm<0 ){ + *pLockstate = SQLITE_LOCKSTATE_OFF; + unixLeaveMutex(); + return SQLITE_OK; + } + if( unixIsLocked(pid, hShm, F_RDLCK, SHM_RECOVER, 1, "WAL-RECOVERY") || + unixIsLocked(pid, hShm, F_RDLCK, SHM_WRITE, 1, "WAL-WRITE") ){ + nLock = 1; + } + close(hShm); + } + unixLeaveMutex(); + } + if( nLock>0 ){ + *pLockstate = SQLITE_LOCKSTATE_ON; + } else { + *pLockstate = SQLITE_LOCKSTATE_OFF; + } + return SQLITE_OK; +} + +#endif /* (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) */ + + + /* ** Here ends the implementation of all sqlite3_file methods. ** @@ -5239,7 +5367,7 @@ IOMETHODS( IOMETHODS( nolockIoFinder, /* Finder function name */ nolockIoMethods, /* sqlite3_io_methods object name */ - 1, /* shared memory is disabled */ + 2, /* shared memory is enabled */ nolockClose, /* xClose method */ nolockLock, /* xLock method */ nolockUnlock, /* xUnlock method */ @@ -5513,6 +5641,8 @@ static int fillInUnixFile( #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE || pLockingStyle == &nfsIoMethods #endif + /* support WAL mode on read only mounted filesystem */ + || pLockingStyle == &nolockIoMethods ){ unixEnterMutex(); rc = findInodeInfo(pNew, &pNew->pInode); @@ -6097,19 +6227,6 @@ static int unixOpen( if( envforce!=NULL ){ useProxy = atoi(envforce)>0; }else{ - if( statfs(zPath, &fsInfo) == -1 ){ - /* In theory, the close(fd) call is sub-optimal. If the file opened - ** with fd is a database file, and there are other connections open - ** on that file that are currently holding advisory locks on it, - ** then the call to close() will cancel those locks. In practice, - ** we're assuming that statfs() doesn't fail very often. At least - ** not while other file descriptors opened by the same process on - ** the same file are working. */ - p->lastErrno = errno; - robust_close(p, fd, __LINE__); - rc = SQLITE_IOERR_ACCESS; - goto open_finished; - } useProxy = !(fsInfo.f_flags&MNT_LOCAL); } if( useProxy ){ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 3c9ee1b48f..c557a63e15 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -833,9 +833,9 @@ struct sqlite3_io_methods { ** */ #define SQLITE_FCNTL_LOCKSTATE 1 -#define SQLITE_GET_LOCKPROXYFILE 2 -#define SQLITE_SET_LOCKPROXYFILE 3 -#define SQLITE_LAST_ERRNO 4 +#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 +#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 +#define SQLITE_FCNTL_LAST_ERRNO 4 #define SQLITE_FCNTL_SIZE_HINT 5 #define SQLITE_FCNTL_CHUNK_SIZE 6 #define SQLITE_FCNTL_FILE_POINTER 7 @@ -846,6 +846,10 @@ struct sqlite3_io_methods { #define SQLITE_FCNTL_VFSNAME 12 #define SQLITE_FCNTL_POWERSAFE_OVERWRITE 13 #define SQLITE_FCNTL_PRAGMA 14 +/* deprecated names */ +#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE +#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE +#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO /* ** CAPI3REF: Mutex Handle diff --git a/src/sqlite3_private.h b/src/sqlite3_private.h index dfc3a0e48a..e7a4c1905d 100644 --- a/src/sqlite3_private.h +++ b/src/sqlite3_private.h @@ -37,10 +37,28 @@ extern int _sqlite3_lockstate(const char *path, pid_t pid); /* ** Pass the SQLITE_TRUNCATE_DATABASE operation code to sqlite3_file_control() -** to truncate a database and its associated journal file to zero length. +** to truncate a database and its associated journal file to zero length. The +** SQLITE_TRUNCATE_* flags represent optional flags to safely initialize an +** empty database in the place of the truncated database, the flags are passed +** into sqlite3_file_control via the fourth argument using a pointer to an integer +** configured with the ORed flags. If the fourth argument is NULL, the default +** behavior is applied and the database file is truncated to zero bytes, a rollback +** journal (if present) is unlinked, a WAL journal (if present) is truncated to zero +** bytes and the first few bytes of the -shm file is scrambled to trigger existing +** connections to rebuild the index from the database file contents. */ #define SQLITE_FCNTL_TRUNCATE_DATABASE 101 #define SQLITE_TRUNCATE_DATABASE SQLITE_FCNTL_TRUNCATE_DATABASE +#define SQLITE_TRUNCATE_JOURNALMODE_WAL (0x1<<0) +#define SQLITE_TRUNCATE_AUTOVACUUM_MASK (0x3<<2) +#define SQLITE_TRUNCATE_AUTOVACUUM_OFF (0x1<<2) +#define SQLITE_TRUNCATE_AUTOVACUUM_FULL (0x2<<2) +#define SQLITE_TRUNCATE_AUTOVACUUM_INCREMENTAL (0x3<<2) +#define SQLITE_TRUNCATE_PAGESIZE_MASK (0x7<<4) +#define SQLITE_TRUNCATE_PAGESIZE_1024 (0x1<<4) +#define SQLITE_TRUNCATE_PAGESIZE_2048 (0x2<<4) +#define SQLITE_TRUNCATE_PAGESIZE_4096 (0x3<<4) +#define SQLITE_TRUNCATE_PAGESIZE_8192 (0x4<<4) /* ** Pass the SQLITE_REPLACE_DATABASE operation code to sqlite3_file_control() diff --git a/src/test1.c b/src/test1.c index 9b72956172..52aa7a07a6 100644 --- a/src/test1.c +++ b/src/test1.c @@ -5068,6 +5068,16 @@ static int file_control_lasterrno_test( /* From sqlite3_priavet.h */ # ifndef SQLITE_TRUNCATE_DATABASE # define SQLITE_TRUNCATE_DATABASE 101 +# define SQLITE_TRUNCATE_JOURNALMODE_WAL (0x1<<0) +# define SQLITE_TRUNCATE_AUTOVACUUM_MASK (0x3<<2) +# define SQLITE_TRUNCATE_AUTOVACUUM_OFF (0x1<<2) +# define SQLITE_TRUNCATE_AUTOVACUUM_FULL (0x2<<2) +# define SQLITE_TRUNCATE_AUTOVACUUM_INCREMENTAL (0x3<<2) +# define SQLITE_TRUNCATE_PAGESIZE_MASK (0x7<<4) +# define SQLITE_TRUNCATE_PAGESIZE_1024 (0x1<<4) +# define SQLITE_TRUNCATE_PAGESIZE_2048 (0x2<<4) +# define SQLITE_TRUNCATE_PAGESIZE_4096 (0x3<<4) +# define SQLITE_TRUNCATE_PAGESIZE_8192 (0x4<<4) # endif # ifndef SQLITE_REPLACE_DATABASE # define SQLITE_REPLACE_DATABASE 102 diff --git a/src/wal.c b/src/wal.c index d38d27b52f..d2addb7575 100644 --- a/src/wal.c +++ b/src/wal.c @@ -2652,6 +2652,10 @@ typedef struct WalWriter { sqlite3_int64 iSyncPoint; /* Fsync at this offset */ int syncFlags; /* Flags for the fsync */ int szPage; /* Size of one page */ +#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED) + void *aFrameBuf; /* Frame buffer */ + size_t szFrameBuf; /* Size of frame buffer */ +#endif } WalWriter; /* @@ -2695,17 +2699,32 @@ static int walWriteOneFrame( ){ int rc; /* Result code from subfunctions */ void *pData; /* Data actually written */ +#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED) + void *aFrame; + + assert(sizeof(p->aFrameBuf) == (p->szPage + WAL_FRAME_HDRSIZE)); + aFrame = p->aFrameBuf; +#else u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ +#endif + #if defined(SQLITE_HAS_CODEC) if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM; #else pData = pPage->pData; #endif + walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame); + +#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED) + memcpy(&aFrame[WAL_FRAME_HDRSIZE], pData, p->szPage); + rc = walWriteToLog(p, aFrame, (p->szPage + WAL_FRAME_HDRSIZE), iOffset); +#else rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset); if( rc ) return rc; /* Write the page data */ rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame)); +#endif return rc; } @@ -2804,6 +2823,13 @@ int sqlite3WalFrames( w.szPage = szPage; iOffset = walFrameOffset(iFrame+1, szPage); szFrame = szPage + WAL_FRAME_HDRSIZE; +#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED) + w.aFrameBuf = (void *)malloc(szFrame); + if( NULL==w.aFrameBuf ){ + return SQLITE_NOMEM; + } +#endif + /* Write all frames into the log file exactly once */ for(p=pList; p; p=p->pDirty){ @@ -2846,6 +2872,9 @@ int sqlite3WalFrames( } } +#if defined(SQLITE_WRITE_WALFRAME_PREBUFFERED) + free(w.aFrameBuf); +#endif /* If this frame set completes the first transaction in the WAL and ** if PRAGMA journal_size_limit is set, then truncate the WAL to the ** journal size limit, if possible. diff --git a/test/8_3_names.test b/test/8_3_names.test index b53e28a92a..906e655184 100644 --- a/test/8_3_names.test +++ b/test/8_3_names.test @@ -146,6 +146,8 @@ ifcapable !wal { finish_test return } +if ![wal_is_ok] { finish_test; return } + db close forcedelete test.db do_test 8_3_names-5.0 { diff --git a/test/attach4.test b/test/attach4.test index 77dd7e4115..08f5ab1657 100644 --- a/test/attach4.test +++ b/test/attach4.test @@ -80,6 +80,7 @@ foreach {name f} $files { set mode wal } ifcapable !wal { set mode delete } + if ![wal_is_ok] { set mode delete } lappend L $mode append S " PRAGMA $name.journal_mode = WAL; diff --git a/test/capi3.test b/test/capi3.test index a9aab1e615..5b2fb390cd 100644 --- a/test/capi3.test +++ b/test/capi3.test @@ -901,16 +901,18 @@ do_test capi3-11.9.3 { do_test capi3-11.10 { sqlite3_step $STMT } {SQLITE_ERROR} -do_test capi3-11.11 { - sqlite3_step $STMT -} {SQLITE_ROW} -do_test capi3-11.12 { - sqlite3_step $STMT - sqlite3_step $STMT -} {SQLITE_DONE} -do_test capi3-11.13 { - sqlite3_finalize $STMT -} {SQLITE_OK} +ifcapable {autoreset} { + do_test capi3-11.11 { + sqlite3_step $STMT + } {SQLITE_ROW} + do_test capi3-11.12 { + sqlite3_step $STMT + sqlite3_step $STMT + } {SQLITE_DONE} + do_test capi3-11.13 { + sqlite3_finalize $STMT + } {SQLITE_OK} +} do_test capi3-11.14 { execsql { SELECT a FROM t2; diff --git a/test/capi3c.test b/test/capi3c.test index adef7f9189..b26ca205f0 100644 --- a/test/capi3c.test +++ b/test/capi3c.test @@ -856,16 +856,18 @@ do_test capi3c-11.9.3 { do_test capi3c-11.10 { sqlite3_step $STMT } {SQLITE_ABORT} -do_test capi3c-11.11 { - sqlite3_step $STMT -} {SQLITE_ROW} -do_test capi3c-11.12 { - sqlite3_step $STMT - sqlite3_step $STMT -} {SQLITE_DONE} -do_test capi3c-11.13 { - sqlite3_finalize $STMT -} {SQLITE_OK} +ifcapable {autoreset} { + do_test capi3c-11.11 { + sqlite3_step $STMT + } {SQLITE_ROW} + do_test capi3c-11.12 { + sqlite3_step $STMT + sqlite3_step $STMT + } {SQLITE_DONE} + do_test capi3c-11.13 { + sqlite3_finalize $STMT + } {SQLITE_OK} +} do_test capi3c-11.14 { execsql { SELECT a FROM t2; diff --git a/test/incrvacuum2.test b/test/incrvacuum2.test index 5d3787374b..6f1fb1e871 100644 --- a/test/incrvacuum2.test +++ b/test/incrvacuum2.test @@ -135,6 +135,8 @@ do_test incrvacuum2-3.2 { integrity_check incrvacuum2-3.3 +if ![wal_is_ok] { finish_test; return } + ifcapable wal { # At one point, when a specific page was being extracted from the b-tree # free-list (e.g. during an incremental-vacuum), all trunk pages that diff --git a/test/pager1.test b/test/pager1.test index 5ea3db80a9..ac6a18c111 100644 --- a/test/pager1.test +++ b/test/pager1.test @@ -1126,7 +1126,7 @@ do_execsql_test pager1-6.12 { PRAGMA max_page_count } {11} # $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 { +if {$::sqlite_options(wal) && [wal_is_ok]} { faultsim_delete_and_reopen foreach {tn sql res js ws} [subst { @@ -1930,7 +1930,7 @@ do_test pager1-20.2.2 { } } {} -ifcapable wal { +if {$::sqlite_options(wal) && [wal_is_ok]} { do_test pager1-20.3.1 { faultsim_delete_and_reopen db func a_string a_string @@ -1965,7 +1965,7 @@ ifcapable wal { # pager1-21.1.*: The VFS has an iVersion less than 2, or # pager1-21.2.*: The VFS does not provide xShmXXX() methods. # -ifcapable wal { +if {$::sqlite_options(wal) && [wal_is_ok]} { do_test pager1-21.0 { faultsim_delete_and_reopen execsql { @@ -2274,7 +2274,7 @@ do_test pager1.27.1 { # the same database. # catch { db close } -ifcapable wal { +if {$::sqlite_options(wal) && [wal_is_ok]} { do_multiclient_test tn { do_test pager1-28.$tn.1 { sql1 { diff --git a/test/stat.test b/test/stat.test index 926d9b7406..e9b563737c 100644 --- a/test/stat.test +++ b/test/stat.test @@ -32,7 +32,7 @@ do_execsql_test stat-0.0 { SELECT * FROM stat; } {} -ifcapable wal { +if {$::sqlite_options(wal) && [wal_is_ok]} { do_execsql_test stat-0.1 { PRAGMA journal_mode = WAL; PRAGMA journal_mode = delete; diff --git a/test/superlock.test b/test/superlock.test index bd3dbc00d3..50b09946ae 100644 --- a/test/superlock.test +++ b/test/superlock.test @@ -43,6 +43,11 @@ set testprefix superlock # # +if {[forced_proxy_locking]} { + finish_test + return +} + do_execsql_test 1.1 { CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); diff --git a/test/tkt-2d1a5c67d.test b/test/tkt-2d1a5c67d.test index bf9595f015..dca9919442 100644 --- a/test/tkt-2d1a5c67d.test +++ b/test/tkt-2d1a5c67d.test @@ -20,6 +20,7 @@ source $testdir/tester.tcl set testprefix tkt-2d1a5c67d ifcapable {!wal || !vtab} {finish_test; return} +if {![wal_is_ok]} {finish_test; return} for {set ii 1} {$ii<=10} {incr ii} { do_test tkt-2d1a5c67d.1.$ii { diff --git a/test/tkt-313723c356.test b/test/tkt-313723c356.test index 8c08c34976..2f3de34abd 100644 --- a/test/tkt-313723c356.test +++ b/test/tkt-313723c356.test @@ -19,6 +19,7 @@ source $testdir/tester.tcl source $testdir/malloc_common.tcl ifcapable !wal { finish_test ; return } +if ![wal_is_ok] { finish_test; return } do_execsql_test tkt-313723c356.1 { PRAGMA page_size = 1024; diff --git a/test/tkt-5d863f876e.test b/test/tkt-5d863f876e.test index 0a9017de11..176a636225 100644 --- a/test/tkt-5d863f876e.test +++ b/test/tkt-5d863f876e.test @@ -18,6 +18,10 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl +ifcapable !wal { finish_test; return } +if ![wal_is_ok] { finish_test; return } + + do_multiclient_test tn { do_test $tn.1 { sql1 { diff --git a/test/wal2.test b/test/wal2.test index cbefb7ab1e..2076a24a8a 100644 --- a/test/wal2.test +++ b/test/wal2.test @@ -22,6 +22,7 @@ source $testdir/wal_common.tcl set testprefix wal2 ifcapable !wal {finish_test ; return } +if ![wal_is_ok] {finish_test ; return } set sqlite_sync_count 0 proc cond_incr_sync_count {adj} { @@ -70,6 +71,13 @@ proc incr_tvfs_hdr {file idx incrval} { set_tvfs_hdr $file $ints } +set shmpath test.db-shm +if {[forced_proxy_locking]} { + sqlite3 db test.db + set shmpath [execsql { pragma lock_proxy_file }]-shm + db close +} + #------------------------------------------------------------------------- # Test case wal2-1.*: @@ -942,6 +950,9 @@ do_test wal2-10.1.1 { INSERT INTO t1 VALUES(1, 2); INSERT INTO t1 VALUES(3, 4); } + if {[forced_proxy_locking]} { + forcecopy $shmpath sv_test.db-shm + } faultsim_save_and_close } {} do_test wal2-10.1.2 { @@ -1041,6 +1052,11 @@ tvfs delete # file itself. Test this. # if {$::tcl_platform(platform) == "unix"} { + if {[forced_proxy_locking]} { + # faultsim_delete_and_reopen doesn't know about the shm file redirect... + forcedelete $shmpath + } + faultsim_delete_and_reopen # Changed on 2012-02-13: umask is deliberately ignored for -wal files. #set umask [exec /bin/sh -c umask] @@ -1054,7 +1070,7 @@ if {$::tcl_platform(platform) == "unix"} { PRAGMA journal_mode = WAL; } db close - list [file exists test.db-wal] [file exists test.db-shm] + list [file exists test.db-wal] [file exists $shmpath] } {0 0} foreach {tn permissions} { @@ -1069,19 +1085,19 @@ if {$::tcl_platform(platform) == "unix"} { file attributes test.db -permissions } $permissions do_test wal2-12.2.$tn.2 { - list [file exists test.db-wal] [file exists test.db-shm] + list [file exists test.db-wal] [file exists $shmpath] } {0 0} do_test wal2-12.2.$tn.3 { sqlite3 db test.db execsql { INSERT INTO tx DEFAULT VALUES } - list [file exists test.db-wal] [file exists test.db-shm] + list [file exists test.db-wal] [file exists $shmpath] } {1 1} do_test wal2-12.2.$tn.4 { - list [file attr test.db-wal -perm] [file attr test.db-shm -perm] + list [file attr test.db-wal -perm] [file attr $shmpath -perm] } [list $effective $effective] do_test wal2-12.2.$tn.5 { db close - list [file exists test.db-wal] [file exists test.db-shm] + list [file exists test.db-wal] [file exists $shmpath] } {0 0} } } @@ -1094,7 +1110,7 @@ if {$::tcl_platform(platform) == "unix"} { if {$::tcl_platform(platform) == "unix"} { proc perm {} { set L [list] - foreach f {test.db test.db-wal test.db-shm} { + foreach f {test.db test.db-wal $shmpath} { if {[file exists $f]} { lappend L [file attr $f -perm] } else { @@ -1104,6 +1120,10 @@ if {$::tcl_platform(platform) == "unix"} { set L } + if {[forced_proxy_locking]} { + # faultsim_delete_and_reopen doesn't know about the shm file redirect... + forcedelete $shmpath + } faultsim_delete_and_reopen execsql { PRAGMA journal_mode = WAL; @@ -1112,8 +1132,11 @@ if {$::tcl_platform(platform) == "unix"} { INSERT INTO t1 VALUES('3.14', '2.72'); } do_test wal2-13.1.1 { - list [file exists test.db-shm] [file exists test.db-wal] + list [file exists $shmpath] [file exists test.db-wal] } {1 1} + if {[forced_proxy_locking]} { + forcecopy $shmpath proxysv_test.db-shm + } faultsim_save_and_close foreach {tn db_perm wal_perm shm_perm can_open can_read can_write} { @@ -1127,14 +1150,17 @@ if {$::tcl_platform(platform) == "unix"} { 9 00000 00644 00644 0 0 0 } { faultsim_restore + if {[forced_proxy_locking]} { + forcecopy proxysv_test.db-shm $shmpath + } do_test wal2-13.$tn.1 { file attr test.db -perm $db_perm file attr test.db-wal -perm $wal_perm - file attr test.db-shm -perm $shm_perm + file attr $shmpath -perm $shm_perm set L [file attr test.db -perm] lappend L [file attr test.db-wal -perm] - lappend L [file attr test.db-shm -perm] + lappend L [file attr $shmpath -perm] } [list $db_perm $wal_perm $shm_perm] # If $can_open is true, then it should be possible to open a database @@ -1180,10 +1206,10 @@ if {$::tcl_platform(platform) == "unix"} { #------------------------------------------------------------------------- # Test that "PRAGMA checkpoint_fullsync" appears to be working. # -foreach {tn sql reslist} { - 1 { } {10 0 4 0 6 0} - 2 { PRAGMA checkpoint_fullfsync = 1 } {10 4 4 2 6 2} - 3 { PRAGMA checkpoint_fullfsync = 0 } {10 0 4 0 6 0} +foreach {tn sql reslist altreslist} { + 1 { } {10 0 4 0 6 0} {7 4 3 2 3 2} + 2 { PRAGMA checkpoint_fullfsync = 1 } {10 4 4 2 6 2} {7 4 3 2 3 2} + 3 { PRAGMA checkpoint_fullfsync = 0 } {10 0 4 0 6 0} {7 0 3 0 3 0} } { faultsim_delete_and_reopen @@ -1195,6 +1221,11 @@ foreach {tn sql reslist} { set sqlite_sync_count 0 set sqlite_fullsync_count 0 + set useres $reslist + if $::sqlite_options(default_wal_safetylevel) { + set useres $altreslist + } + do_execsql_test wal2-14.$tn.2 { PRAGMA wal_autocheckpoint = 10; CREATE TABLE t1(a, b); -- 2 wal syncs @@ -1210,7 +1241,7 @@ foreach {tn sql reslist} { do_test wal2-14.$tn.3 { cond_incr_sync_count 1 list $sqlite_sync_count $sqlite_fullsync_count - } [lrange $reslist 0 1] + } [lrange $useres 0 1] set sqlite_sync_count 0 set sqlite_fullsync_count 0 @@ -1218,7 +1249,7 @@ foreach {tn sql reslist} { do_test wal2-14.$tn.4 { execsql { INSERT INTO t1 VALUES(7, zeroblob(12*4096)) } list $sqlite_sync_count $sqlite_fullsync_count - } [lrange $reslist 2 3] + } [lrange $useres 2 3] set sqlite_sync_count 0 set sqlite_fullsync_count 0 @@ -1230,7 +1261,7 @@ foreach {tn sql reslist} { execsql { INSERT INTO t1 VALUES(13, 14) } db close list $sqlite_sync_count $sqlite_fullsync_count - } [lrange $reslist 4 5] + } [lrange $useres 4 5] } catch { db close } diff --git a/test/wal3.test b/test/wal3.test index ccab93e5da..229be5f7e9 100644 --- a/test/wal3.test +++ b/test/wal3.test @@ -19,6 +19,7 @@ source $testdir/lock_common.tcl 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} { @@ -194,19 +195,27 @@ catch {db close} # in WAL mode the xSync method is invoked as expected for each of # synchronous=off, synchronous=normal and synchronous=full. # -foreach {tn syncmode synccount} { +foreach {tn syncmode synccount altsynccount} { 1 off {} + {} 2 normal {test.db-wal normal test.db normal} + {test.db-wal full test.db full} 3 full {test.db-wal normal test.db-wal normal test.db-wal normal test.db normal} + {test.db-wal normal test.db-wal normal test.db-wal full test.db full} } { proc sync_counter {args} { foreach {method filename id flags} $args break lappend ::syncs [file tail $filename] $flags } + set usecount $synccount + if $::sqlite_options(default_wal_safetylevel) { + set usecount $altsynccount + } + do_test wal3-3.$tn { forcedelete test.db test.db-wal test.db-journal @@ -228,7 +237,7 @@ foreach {tn syncmode synccount} { } T filter {} set ::syncs - } $synccount + } $usecount db close T delete diff --git a/test/wal5.test b/test/wal5.test index 6eceed5e59..bab6187be9 100644 --- a/test/wal5.test +++ b/test/wal5.test @@ -18,6 +18,7 @@ source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/wal_common.tcl ifcapable !wal {finish_test ; return } +if ![wal_is_ok] { finish_test; return } set testprefix wal5 diff --git a/test/wal7.test b/test/wal7.test index cacfaedacb..749cf842a2 100644 --- a/test/wal7.test +++ b/test/wal7.test @@ -16,6 +16,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !wal {finish_test ; return } +if ![wal_is_ok] { finish_test; return } # Case 1: No size limit. Journal can get large. # diff --git a/test/wal8.test b/test/wal8.test index 4b97de7ae7..eb735fe83d 100644 --- a/test/wal8.test +++ b/test/wal8.test @@ -26,6 +26,8 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set ::testprefix wal8 +ifcapable !wal {finish_test ; return } +if ![wal_is_ok] { finish_test; return } db close forcedelete test.db test.db-wal diff --git a/test/walbak.test b/test/walbak.test index de8249ca8e..ca5376eb6b 100644 --- a/test/walbak.test +++ b/test/walbak.test @@ -21,10 +21,7 @@ source $testdir/malloc_common.tcl do_not_use_codec ifcapable !wal {finish_test ; return } -if { ![wal_is_ok] } { - finish_test - return -} +if { ![wal_is_ok] } { finish_test ; return } # Test organization: diff --git a/test/walbig.test b/test/walbig.test index 7523b0c7df..96031da500 100644 --- a/test/walbig.test +++ b/test/walbig.test @@ -21,6 +21,7 @@ ifcapable !wal { finish_test return } +if ![wal_is_ok] { finish_test; return } # Do not use a codec for this file, as the database is manipulated using # external methods (the [fake_big_file] and [hexio_write] commands). diff --git a/test/walcksum.test b/test/walcksum.test index 6425dba131..d1204da51b 100644 --- a/test/walcksum.test +++ b/test/walcksum.test @@ -16,10 +16,7 @@ source $testdir/lock_common.tcl source $testdir/wal_common.tcl ifcapable !wal {finish_test ; return } -if { ![wal_is_ok] } { - finish_test - return -} +if ![wal_is_ok] { finish_test; return } # Read and return the contents of file $filename. Treat the content as # binary data. diff --git a/test/walcrash.test b/test/walcrash.test index 8b10c6b88b..fdb2542ce2 100644 --- a/test/walcrash.test +++ b/test/walcrash.test @@ -28,10 +28,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !wal {finish_test ; return } -if { ![wal_is_ok] } { - finish_test - return -} +if ![wal_is_ok] { finish_test; return } db close diff --git a/test/walcrash3.test b/test/walcrash3.test index c2c9a6d518..b251578f5e 100644 --- a/test/walcrash3.test +++ b/test/walcrash3.test @@ -18,6 +18,8 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !wal {finish_test ; return } +if ![wal_is_ok] { finish_test; return } + set testprefix walcrash3 db close diff --git a/test/walfault.test b/test/walfault.test index b96b1651a4..7df6959587 100644 --- a/test/walfault.test +++ b/test/walfault.test @@ -19,10 +19,7 @@ source $testdir/malloc_common.tcl source $testdir/lock_common.tcl ifcapable !wal {finish_test ; return } -if { ![wal_is_ok] } { - finish_test - return -} +if ![wal_is_ok] { finish_test; return } #------------------------------------------------------------------------- # This test case, walfault-1-*, simulates faults while executing a diff --git a/test/walhook.test b/test/walhook.test index 23c27f729a..4d8f833fc3 100644 --- a/test/walhook.test +++ b/test/walhook.test @@ -22,10 +22,7 @@ source $testdir/tester.tcl source $testdir/wal_common.tcl ifcapable !wal {finish_test ; return } -if { ![wal_is_ok] } { - finish_test - return -} +if ![wal_is_ok] { finish_test; return } set ::wal_hook [list] proc wal_hook {zDb nEntry} { diff --git a/test/walnoshm.test b/test/walnoshm.test index d4082178dd..c14c110a5c 100644 --- a/test/walnoshm.test +++ b/test/walnoshm.test @@ -17,6 +17,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix walnoshm ifcapable !wal {finish_test ; return } +if ![wal_is_ok] { finish_test; return } db close testvfs tvfsshm diff --git a/test/walpersist.test b/test/walpersist.test index 692728dda4..125e43f7f3 100644 --- a/test/walpersist.test +++ b/test/walpersist.test @@ -21,6 +21,12 @@ ifcapable !wal { finish_test return } +if ![wal_is_ok] { finish_test; return } + +set shmpath test.db-shm +if {[forced_proxy_locking]} { + set shmpath [execsql { pragma lock_proxy_file }]-shm +} do_test walpersist-1.0 { db eval { @@ -31,18 +37,18 @@ do_test walpersist-1.0 { file exists test.db-wal } {1} do_test walpersist-1.1 { - file exists test.db-shm + file exists $shmpath } {1} do_test walpersist-1.2 { db close - list [file exists test.db] [file exists test.db-wal] [file exists test.db-shm] + 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} } {5000} do_test walpersist-1.4 { - list [file exists test.db] [file exists test.db-wal] [file exists test.db-shm] + 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 @@ -64,7 +70,7 @@ do_test walpersist-1.10 { } {0 1} do_test walpersist-1.11 { db close - list [file exists test.db] [file exists test.db-wal] [file exists test.db-shm] + list [file exists test.db] [file exists test.db-wal] [file exists $shmpath] } {1 1 1} # Make sure the journal_size_limit works to limit the size of the @@ -72,7 +78,7 @@ do_test walpersist-1.11 { # journal_size_limit causes the WAL file to be truncated to zero bytes # when closing. # -forcedelete test.db test.db-shm test.db-wal +forcedelete test.db $shmpath test.db-wal do_test walpersist-2.1 { sqlite3 db test.db db eval { @@ -97,7 +103,7 @@ do_test walpersist-2.3 { do_test 3.1 { catch {db close} - forcedelete test.db test.db-shm test.db-wal + forcedelete test.db $shmpath test.db-wal sqlite3 db test.db execsql { PRAGMA page_size = 1024; diff --git a/test/walro.test b/test/walro.test index 3ae7d53cd9..f1d09b46f6 100644 --- a/test/walro.test +++ b/test/walro.test @@ -30,6 +30,14 @@ ifcapable !wal { finish_test return } +if ![wal_is_ok] { finish_test; return } + +set shmpath test.db-shm +if {[forced_proxy_locking]} { + sqlite3 db test.db + set shmpath [execsql { pragma lock_proxy_file }]-shm + db close +} do_multiclient_test tn { # Do not run tests with the connections in the same process. @@ -60,11 +68,11 @@ do_multiclient_test tn { CREATE TABLE t1(x, y); INSERT INTO t1 VALUES('a', 'b'); } - file exists test.db-shm + file exists $shmpath } {1} do_test 1.1.2 { - file attributes test.db-shm -permissions r--r--r-- + file attributes $shmpath -permissions r--r--r-- code1 { sqlite3 db file:test.db?readonly_shm=1 } } {} @@ -97,7 +105,7 @@ do_multiclient_test tn { do_test 1.2.1 { code2 { db2 close } code1 { db close } - list [file exists test.db-wal] [file exists test.db-shm] + list [file exists test.db-wal] [file exists $shmpath] } {1 1} do_test 1.2.2 { code1 { sqlite3 db file:test.db?readonly_shm=1 } @@ -106,9 +114,9 @@ do_multiclient_test tn { do_test 1.2.3 { code1 { db close } - file attributes test.db-shm -permissions rw-r--r-- - hexio_write test.db-shm 0 01020304 - file attributes test.db-shm -permissions r--r--r-- + file attributes $shmpath -permissions rw-r--r-- + hexio_write $shmpath 0 01020304 + file attributes $shmpath -permissions r--r--r-- code1 { sqlite3 db file:test.db?readonly_shm=1 } csql1 { SELECT * FROM t1 } } {1 {attempt to write a readonly database}} @@ -117,11 +125,11 @@ do_multiclient_test tn { } {SQLITE_READONLY_RECOVERY} do_test 1.2.5 { - file attributes test.db-shm -permissions rw-r--r-- + file attributes $shmpath -permissions rw-r--r-- code2 { sqlite3 db2 test.db } sql2 "SELECT * FROM t1" } {a b c d e f g h i j} - file attributes test.db-shm -permissions r--r--r-- + file attributes $shmpath -permissions r--r--r-- do_test 1.2.6 { sql1 "SELECT * FROM t1" } {a b c d e f g h i j} do_test 1.2.7 { @@ -147,7 +155,7 @@ do_multiclient_test tn { do_test 1.3.2.1 { code1 { db close } code2 { db2 close } - file exists test.db-shm + file exists $shmpath } {0} do_test 1.3.2.2 { code1 { sqlite3 db file:test.db?readonly_shm=1 } @@ -155,8 +163,8 @@ do_multiclient_test tn { } {1 {unable to open database file}} do_test 1.3.2.3 { code1 { db close } - close [open test.db-shm w] - file attributes test.db-shm -permissions r--r--r-- + close [open $shmpath w] + file attributes $shmpath -permissions r--r--r-- code1 { sqlite3 db file:test.db?readonly_shm=1 } csql1 { SELECT * FROM t1 } } {1 {attempt to write a readonly database}} @@ -165,4 +173,6 @@ do_multiclient_test tn { } {SQLITE_READONLY_RECOVERY} } +forcedelete $shmpath + finish_test diff --git a/test/walshared.test b/test/walshared.test index fbbdeb4de3..97a64be7f5 100644 --- a/test/walshared.test +++ b/test/walshared.test @@ -17,6 +17,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !wal {finish_test ; return } +if ![wal_is_ok] { finish_test; return } db close set ::enable_shared_cache [sqlite3_enable_shared_cache 1] diff --git a/test/walslow.test b/test/walslow.test index abcc765df2..2594144625 100644 --- a/test/walslow.test +++ b/test/walslow.test @@ -18,10 +18,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !wal {finish_test ; return } -if { ![wal_is_ok] } { - finish_test - return -} +if ![wal_is_ok] { finish_test; return } proc reopen_db {} { catch { db close } diff --git a/test/walthread.test b/test/walthread.test index 8a41118fdc..8c40cdaceb 100644 --- a/test/walthread.test +++ b/test/walthread.test @@ -19,10 +19,7 @@ source $testdir/tester.tcl 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 -} +if ![wal_is_ok] { finish_test; return } set sqlite_walsummary_mmap_incr 64