Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge in latest changes, autologging options, read only file system wal support, test config conditionalization, WAL frame write prebuffering |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | apple-osx |
Files: | files | file ages | folders |
SHA1: |
d51c086e5c006821e2ab932f229649a7 |
User & Date: | adam 2012-04-02 23:35:45.151 |
Context
2012-04-02
| ||
23:42 | bad assert (check-in: 0c0150f2a3 user: adam tags: apple-osx) | |
23:35 | Merge in latest changes, autologging options, read only file system wal support, test config conditionalization, WAL frame write prebuffering (check-in: d51c086e5c user: adam tags: apple-osx) | |
2012-03-31
| ||
02:46 | Merge all the latest trunk changes into the apple-osx branch. (check-in: 18ec60cacd user: drh tags: apple-osx) | |
Changes
Changes to src/main.c.
︙ | ︙ | |||
1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 | newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ } db->aLimit[limitId] = newLimit; } return oldLimit; /* IMP: R-53341-35419 */ } #if defined(SQLITE_ENABLE_AUTO_PROFILE) 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) { #pragma unused(aux) fprintf(stderr, "Query: %s\n Execution Time: %llu ms\n", sql, ns / 1000000); } void _sqlite_auto_trace(void *aux, const char *sql) { fprintf(stderr, "TraceSQL(%p): %s\n", aux, sql); } #endif /* ** This function is used to parse both URIs and non-URI filenames passed by the ** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database ** URIs specified as part of ATTACH statements. ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 | newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ } db->aLimit[limitId] = 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) { #pragma unused(aux) fprintf(stderr, "Query: %s\n Execution Time: %llu ms\n", sql, ns / 1000000); } void _sqlite_auto_trace(void *aux, const char *sql) { fprintf(stderr, "TraceSQL(%p): %s\n", aux, sql); } /* syslog logging */ #include <asl.h> 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 /* ** This function is used to parse both URIs and non-URI filenames passed by the ** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database ** URIs specified as part of ATTACH statements. ** |
︙ | ︙ | |||
2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 | zFile = 0; } *pFlags = flags; *pzFile = zFile; return rc; } /* ** This routine does the work of opening a database on behalf of ** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" ** is UTF-8 encoded. */ static int openDatabase( | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 | zFile = 0; } *pFlags = flags; *pzFile = zFile; 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 ** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" ** is UTF-8 encoded. */ static int openDatabase( |
︙ | ︙ | |||
2347 2348 2349 2350 2351 2352 2353 | assert( db!=0 || rc==SQLITE_NOMEM ); if( rc==SQLITE_NOMEM ){ sqlite3_close(db); db = 0; }else if( rc!=SQLITE_OK ){ db->magic = SQLITE_MAGIC_SICK; } | | | | > > | < | > > > > < < | > > > > | 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 | assert( db!=0 || rc==SQLITE_NOMEM ); if( rc==SQLITE_NOMEM ){ sqlite3_close(db); db = 0; }else if( rc!=SQLITE_OK ){ db->magic = SQLITE_MAGIC_SICK; } #if defined(__APPLE__) && ENABLE_FORCE_WAL if( db && !rc ){ 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 SRRecOpen(db, zFilename, flags); #endif return sqlite3ApiExit(0, rc); |
︙ | ︙ | |||
3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 | if( sqlite3_open_v2(path, &db, SQLITE_OPEN_READONLY, NULL) == SQLITE_OK ){ LockstatePID lockstate = {pid, -1}; sqlite3_file_control(db, NULL, SQLITE_FCNTL_LOCKSTATE_PID, &lockstate); sqlite3_close(db); int state = lockstate.state; return state; } return SQLITE_LOCKSTATE_ERROR; } #endif /* SQLITE_ENABLE_APPLE_SPI */ | > > > | 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 | if( sqlite3_open_v2(path, &db, SQLITE_OPEN_READONLY, NULL) == SQLITE_OK ){ LockstatePID lockstate = {pid, -1}; sqlite3_file_control(db, NULL, SQLITE_FCNTL_LOCKSTATE_PID, &lockstate); sqlite3_close(db); 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; } #endif /* SQLITE_ENABLE_APPLE_SPI */ |
Changes to src/os_unix.c.
︙ | ︙ | |||
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 | } lock.l_type = F_RDLCK; lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = divSize; if( unixFileLock(pFile, &lock, 10)==(-1) ){ tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; } goto end_unlock; } lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; | > > > > | 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 | } lock.l_type = F_RDLCK; lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; 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; } goto end_unlock; } lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; |
︙ | ︙ | |||
2235 2236 2237 2238 2239 2240 2241 | return SQLITE_OK; } /* ** Close the file. */ static int nolockClose(sqlite3_file *id) { | > > > > > > > > > > > > > > > > > | > > | 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 | return SQLITE_OK; } /* ** Close the file. */ static int nolockClose(sqlite3_file *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 ********************* ******************************************************************************/ /****************************************************************************** ************************* Begin dot-file Locking ****************************** |
︙ | ︙ | |||
3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 | } #endif } } return SQLITE_OK; } #if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) #include "sqlite3_private.h" #include <copyfile.h> static int getDbPathForUnixFile(unixFile *pFile, char *dbPath); #endif static int isProxyLockingMode(unixFile *); #if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) | > | < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 | } #endif } } return SQLITE_OK; } #if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) #include "sqlite3_private.h" #include <copyfile.h> static int getDbPathForUnixFile(unixFile *pFile, char *dbPath); #endif static int isProxyLockingMode(unixFile *); #if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) static int unixTruncateDatabase(unixFile *, int); static int unixInvalidateSupportFiles(unixFile *, int); static int unixReplaceDatabase(unixFile *pFile, sqlite3 *srcdb) { sqlite3_file *id = (sqlite3_file *)pFile; Btree *pSrcBtree = NULL; sqlite3_file *src_file = NULL; unixFile *pSrcFile = NULL; char srcWalPath[MAXPATHLEN+5]; |
︙ | ︙ | |||
4253 4254 4255 4256 4257 4258 4259 | fprintf(stderr, "%s lock held by %d\n", zType, (int)lk.l_pid); #endif return 1; } return 0; } | < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 | fprintf(stderr, "%s lock held by %d\n", zType, (int)lk.l_pid); #endif return 1; } return 0; } static int unixLockstatePid(unixFile *, pid_t, int *); #endif /* (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) */ /* ** If *pArg is inititially negative then this is a query. Set *pArg to ** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set. |
︙ | ︙ | |||
4367 4368 4369 4370 4371 4372 4373 | static int unixFileControl(sqlite3_file *id, int op, void *pArg){ unixFile *pFile = (unixFile*)id; switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = pFile->eFileLock; return SQLITE_OK; } | | | 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 | static int unixFileControl(sqlite3_file *id, int op, void *pArg){ unixFile *pFile = (unixFile*)id; switch( op ){ case SQLITE_FCNTL_LOCKSTATE: { *(int*)pArg = pFile->eFileLock; return SQLITE_OK; } case SQLITE_FCNTL_LAST_ERRNO: { *(int*)pArg = pFile->lastErrno; return SQLITE_OK; } case SQLITE_FCNTL_CHUNK_SIZE: { pFile->szChunk = *(int *)pArg; return SQLITE_OK; } |
︙ | ︙ | |||
4406 4407 4408 4409 4410 4411 4412 | */ case SQLITE_FCNTL_DB_UNCHANGED: { ((unixFile*)id)->dbUpdate = 0; return SQLITE_OK; } #endif #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) | | | | 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 | */ case SQLITE_FCNTL_DB_UNCHANGED: { ((unixFile*)id)->dbUpdate = 0; return SQLITE_OK; } #endif #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) case SQLITE_FCNTL_SET_LOCKPROXYFILE: case SQLITE_FCNTL_GET_LOCKPROXYFILE: { return proxyFileControl(id,op,pArg); } #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ #if (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) case SQLITE_FCNTL_TRUNCATE_DATABASE: { return unixTruncateDatabase(pFile, (pArg ? (*(int *)pArg) : 0)); } |
︙ | ︙ | |||
5135 5136 5137 5138 5139 5140 5141 | /* If pShmNode->nRef has reached 0, then close the underlying ** shared-memory file, too */ unixEnterMutex(); assert( pShmNode->nRef>0 ); pShmNode->nRef--; if( pShmNode->nRef==0 ){ | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 | /* If pShmNode->nRef has reached 0, then close the underlying ** shared-memory file, too */ unixEnterMutex(); assert( pShmNode->nRef>0 ); pShmNode->nRef--; if( pShmNode->nRef==0 ){ if( deleteFlag && pShmNode->h>=0 ) { if (deleteFlag == 1) { unlink(pShmNode->zFilename); } else if (deleteFlag == 2) { //ftruncate(pShmNode->h, 32 * 1024); } } unixShmPurge(pDbFd); } unixLeaveMutex(); return SQLITE_OK; } #else # define unixShmMap 0 # define unixShmLock 0 # define unixShmBarrier 0 # 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( zLen<MAXPATHLEN ){ size_t jLen; const char extensions[3][9] = { "-wal", "-journal", "-shm" }; int j = (skipWAL ? 1 : 0); for( ; j<3; j++ ){ /* Check to see if the shm file is already opened for this pFile */ if( j==2 ){ unixEnterMutex(); /* Because pFile->pInode 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. ** ********************** End sqlite3_file Methods ******************************* ******************************************************************************/ |
︙ | ︙ | |||
5235 5236 5237 5238 5239 5240 5241 | unixLock, /* xLock method */ unixUnlock, /* xUnlock method */ unixCheckReservedLock /* xCheckReservedLock method */ ) IOMETHODS( nolockIoFinder, /* Finder function name */ nolockIoMethods, /* sqlite3_io_methods object name */ | | | 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 | unixLock, /* xLock method */ unixUnlock, /* xUnlock method */ unixCheckReservedLock /* xCheckReservedLock method */ ) IOMETHODS( nolockIoFinder, /* Finder function name */ nolockIoMethods, /* sqlite3_io_methods object name */ 2, /* shared memory is enabled */ nolockClose, /* xClose method */ nolockLock, /* xLock method */ nolockUnlock, /* xUnlock method */ nolockCheckReservedLock /* xCheckReservedLock method */ ) IOMETHODS( dotlockIoFinder, /* Finder function name */ |
︙ | ︙ | |||
5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 | #endif } if( pLockingStyle == &posixIoMethods #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE || pLockingStyle == &nfsIoMethods #endif ){ unixEnterMutex(); rc = findInodeInfo(pNew, &pNew->pInode); if( rc!=SQLITE_OK ){ /* If an error occured in findInodeInfo(), close the file descriptor ** immediately, before releasing the mutex. findInodeInfo() may fail ** in two scenarios: | > > | 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 | #endif } if( pLockingStyle == &posixIoMethods #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); if( rc!=SQLITE_OK ){ /* If an error occured in findInodeInfo(), close the file descriptor ** immediately, before releasing the mutex. findInodeInfo() may fail ** in two scenarios: |
︙ | ︙ | |||
6093 6094 6095 6096 6097 6098 6099 | int useProxy = 0; /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means ** never use proxy, NULL means use proxy for non-local files only. */ if( envforce!=NULL ){ useProxy = atoi(envforce)>0; }else{ | < < < < < < < < < < < < < | 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 | int useProxy = 0; /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means ** never use proxy, NULL means use proxy for non-local files only. */ if( envforce!=NULL ){ useProxy = atoi(envforce)>0; }else{ useProxy = !(fsInfo.f_flags&MNT_LOCAL); } if( useProxy ){ rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); if( rc==SQLITE_OK ){ /* cache the pMethod in case the transform fails */ const struct sqlite3_io_methods *pMethod = pFile->pMethods; |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
829 830 831 832 833 834 835 | ** that the VFS encountered an error while handling the [PRAGMA] and the ** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] ** file control occurs at the beginning of pragma statement analysis and so ** it is able to override built-in [PRAGMA] statements. ** </ul> */ #define SQLITE_FCNTL_LOCKSTATE 1 | | | | > > > > | 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 | ** that the VFS encountered an error while handling the [PRAGMA] and the ** compilation of the PRAGMA fails with an error. ^The [SQLITE_FCNTL_PRAGMA] ** file control occurs at the beginning of pragma statement analysis and so ** it is able to override built-in [PRAGMA] statements. ** </ul> */ #define SQLITE_FCNTL_LOCKSTATE 1 #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 #define SQLITE_FCNTL_SYNC_OMITTED 8 #define SQLITE_FCNTL_WIN32_AV_RETRY 9 #define SQLITE_FCNTL_PERSIST_WAL 10 #define SQLITE_FCNTL_OVERWRITE 11 #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 ** ** The mutex module within SQLite defines [sqlite3_mutex] to be an ** abstract type for a mutex object. The SQLite core never looks ** at the internal representation of an [sqlite3_mutex]. It only |
︙ | ︙ |
Changes to src/sqlite3_private.h.
︙ | ︙ | |||
33 34 35 36 37 38 39 | ** locks by re-using open file descriptors for the database file and support ** files (-shm) */ #define SQLITE_FCNTL_LOCKSTATE_PID 103 /* ** Pass the SQLITE_TRUNCATE_DATABASE operation code to sqlite3_file_control() | | > > > > > > > > > > > > > > > > > > | 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | ** locks by re-using open file descriptors for the database file and support ** files (-shm) */ #define SQLITE_FCNTL_LOCKSTATE_PID 103 /* ** Pass the SQLITE_TRUNCATE_DATABASE operation code to sqlite3_file_control() ** 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() ** and a sqlite3 pointer to another open database file to safely copy the ** contents of that database file into the receiving database. */ #define SQLITE_FCNTL_REPLACE_DATABASE 102 |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 | return TCL_OK; } #ifdef __APPLE__ /* From sqlite3_priavet.h */ # ifndef SQLITE_TRUNCATE_DATABASE # define SQLITE_TRUNCATE_DATABASE 101 # endif # ifndef SQLITE_REPLACE_DATABASE # define SQLITE_REPLACE_DATABASE 102 # endif /* ** tclcmd: file_control_truncate_test DB | > > > > > > > > > > | 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 | return TCL_OK; } #ifdef __APPLE__ /* 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 # endif /* ** tclcmd: file_control_truncate_test DB |
︙ | ︙ |
Changes to src/wal.c.
︙ | ︙ | |||
2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 | */ typedef struct WalWriter { Wal *pWal; /* The complete WAL information */ sqlite3_file *pFd; /* The WAL file to which we write */ sqlite3_int64 iSyncPoint; /* Fsync at this offset */ int syncFlags; /* Flags for the fsync */ int szPage; /* Size of one page */ } WalWriter; /* ** Write iAmt bytes of content into the WAL file beginning at iOffset. ** Do a sync when crossing the p->iSyncPoint boundary. ** ** In other words, if iSyncPoint is in between iOffset and iOffset+iAmt, | > > > > | 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 | */ typedef struct WalWriter { Wal *pWal; /* The complete WAL information */ sqlite3_file *pFd; /* The WAL file to which we write */ 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; /* ** Write iAmt bytes of content into the WAL file beginning at iOffset. ** Do a sync when crossing the p->iSyncPoint boundary. ** ** In other words, if iSyncPoint is in between iOffset and iOffset+iAmt, |
︙ | ︙ | |||
2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 | WalWriter *p, /* Where to write the frame */ PgHdr *pPage, /* The page of the frame to be written */ int nTruncate, /* The commit flag. Usually 0. >0 for commit */ sqlite3_int64 iOffset /* Byte offset at which to write */ ){ int rc; /* Result code from subfunctions */ void *pData; /* Data actually written */ u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ #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); rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset); if( rc ) return rc; /* Write the page data */ rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame)); return rc; } /* ** Write a set of frames to the log. The caller must hold the write-lock ** on the log file (obtained using sqlite3WalBeginWriteTransaction()). */ | > > > > > > > > > > > > > > > | 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 | WalWriter *p, /* Where to write the frame */ PgHdr *pPage, /* The page of the frame to be written */ int nTruncate, /* The commit flag. Usually 0. >0 for commit */ sqlite3_int64 iOffset /* Byte offset at which to write */ ){ 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; } /* ** Write a set of frames to the log. The caller must hold the write-lock ** on the log file (obtained using sqlite3WalBeginWriteTransaction()). */ |
︙ | ︙ | |||
2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 | w.pWal = pWal; w.pFd = pWal->pWalFd; w.iSyncPoint = 0; w.syncFlags = sync_flags; w.szPage = szPage; iOffset = walFrameOffset(iFrame+1, szPage); szFrame = szPage + WAL_FRAME_HDRSIZE; /* Write all frames into the log file exactly once */ for(p=pList; p; p=p->pDirty){ int nDbSize; /* 0 normally. Positive == commit flag */ iFrame++; assert( iOffset==walFrameOffset(iFrame, szPage) ); nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0; | > > > > > > > | 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 | w.pWal = pWal; w.pFd = pWal->pWalFd; w.iSyncPoint = 0; w.syncFlags = sync_flags; 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){ int nDbSize; /* 0 normally. Positive == commit flag */ iFrame++; assert( iOffset==walFrameOffset(iFrame, szPage) ); nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0; |
︙ | ︙ | |||
2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 | nExtra++; } }else{ rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK); } } /* 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. */ if( isCommit && pWal->truncateOnCommit && pWal->mxWalSize>=0 ){ i64 sz = pWal->mxWalSize; if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){ | > > > | 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 | nExtra++; } }else{ rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK); } } #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. */ if( isCommit && pWal->truncateOnCommit && pWal->mxWalSize>=0 ){ i64 sz = pWal->mxWalSize; if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){ |
︙ | ︙ |
Changes to test/8_3_names.test.
︙ | ︙ | |||
142 143 144 145 146 147 148 149 150 151 152 153 154 155 | ########################################################################## # WAL mode. # ifcapable !wal { finish_test return } db close forcedelete test.db do_test 8_3_names-5.0 { sqlite3 db file:./test.db?8_3_names=1 register_wholenumber_module db db eval { PRAGMA journal_mode=WAL; | > > | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | ########################################################################## # WAL mode. # ifcapable !wal { finish_test return } if ![wal_is_ok] { finish_test; return } db close forcedelete test.db do_test 8_3_names-5.0 { sqlite3 db file:./test.db?8_3_names=1 register_wholenumber_module db db eval { PRAGMA journal_mode=WAL; |
︙ | ︙ |
Changes to test/attach4.test.
︙ | ︙ | |||
76 77 78 79 80 81 82 83 84 85 86 87 88 89 | foreach {name f} $files { if {[permutation] == "journaltest"} { set mode delete } else { set mode wal } ifcapable !wal { set mode delete } lappend L $mode append S " PRAGMA $name.journal_mode = WAL; UPDATE $name.tbl SET x = '$name'; " } do_execsql_test 1.5 $S $L | > | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | foreach {name f} $files { if {[permutation] == "journaltest"} { set mode delete } else { 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; UPDATE $name.tbl SET x = '$name'; " } do_execsql_test 1.5 $S $L |
︙ | ︙ |
Changes to test/capi3.test.
︙ | ︙ | |||
897 898 899 900 901 902 903 | } {0 {}} do_test capi3-11.9.3 { sqlite3_get_autocommit $DB } 1 do_test capi3-11.10 { sqlite3_step $STMT } {SQLITE_ERROR} | > | | | | | | | | | | > | 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 | } {0 {}} do_test capi3-11.9.3 { sqlite3_get_autocommit $DB } 1 do_test capi3-11.10 { sqlite3_step $STMT } {SQLITE_ERROR} 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; } } {1 2} do_test capi3-11.14.1 { sqlite3_get_autocommit $DB |
︙ | ︙ |
Changes to test/capi3c.test.
︙ | ︙ | |||
852 853 854 855 856 857 858 | } {0 {}} do_test capi3c-11.9.3 { sqlite3_get_autocommit $DB } 1 do_test capi3c-11.10 { sqlite3_step $STMT } {SQLITE_ABORT} | > | | | | | | | | | | > | 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 | } {0 {}} do_test capi3c-11.9.3 { sqlite3_get_autocommit $DB } 1 do_test capi3c-11.10 { sqlite3_step $STMT } {SQLITE_ABORT} 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; } } {1 2} do_test capi3c-11.14.1 { sqlite3_get_autocommit $DB |
︙ | ︙ |
Changes to test/incrvacuum2.test.
︙ | ︙ | |||
130 131 132 133 134 135 136 137 138 139 140 141 142 143 | DELETE FROM abc; PRAGMA incremental_vacuum; COMMIT; } } {} integrity_check incrvacuum2-3.3 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 # occurred before the specific page in the free-list trunk were being # written to the journal or wal file. This is not necessary. Only the # extracted page and the page that contains the pointer to it need to | > > | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | DELETE FROM abc; PRAGMA incremental_vacuum; COMMIT; } } {} 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 # occurred before the specific page in the free-list trunk were being # written to the journal or wal file. This is not necessary. Only the # extracted page and the page that contains the pointer to it need to |
︙ | ︙ |
Changes to test/pager1.test.
︙ | ︙ | |||
1122 1123 1124 1125 1126 1127 1128 | # $sql: SQL to execute. # $res: Expected result of executing $sql. # $js: The expected size of the journal file, in bytes, after executing # the SQL script. Or -1 if the journal is not expected to exist. # $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. # | | | 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 | # $sql: SQL to execute. # $res: Expected result of executing $sql. # $js: The expected size of the journal file, in bytes, after executing # the SQL script. Or -1 if the journal is not expected to exist. # $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. # if {$::sqlite_options(wal) && [wal_is_ok]} { faultsim_delete_and_reopen foreach {tn sql res js ws} [subst { 1 { CREATE TABLE t1(a, b); PRAGMA auto_vacuum=OFF; PRAGMA synchronous=NORMAL; |
︙ | ︙ | |||
1926 1927 1928 1929 1930 1931 1932 | do_test pager1-20.2.2 { execsql { BEGIN EXCLUSIVE; COMMIT; } } {} | | | 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 | do_test pager1-20.2.2 { execsql { BEGIN EXCLUSIVE; COMMIT; } } {} if {$::sqlite_options(wal) && [wal_is_ok]} { 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; |
︙ | ︙ | |||
1961 1962 1963 1964 1965 1966 1967 | #------------------------------------------------------------------------- # 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. # | | | 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 | #------------------------------------------------------------------------- # 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. # if {$::sqlite_options(wal) && [wal_is_ok]} { 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; } |
︙ | ︙ | |||
2270 2271 2272 2273 2274 2275 2276 | #------------------------------------------------------------------------- # Test that attempting to open a write-transaction with # locking_mode=exclusive in WAL mode fails if there are other clients on # the same database. # catch { db close } | | | 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 | #------------------------------------------------------------------------- # Test that attempting to open a write-transaction with # locking_mode=exclusive in WAL mode fails if there are other clients on # the same database. # catch { db close } if {$::sqlite_options(wal) && [wal_is_ok]} { do_multiclient_test tn { do_test pager1-28.$tn.1 { sql1 { PRAGMA journal_mode = WAL; CREATE TABLE t1(a, b); INSERT INTO t1 VALUES('a', 'b'); } |
︙ | ︙ |
Changes to test/stat.test.
︙ | ︙ | |||
28 29 30 31 32 33 34 | register_dbstat_vtab db do_execsql_test stat-0.0 { PRAGMA auto_vacuum = OFF; CREATE VIRTUAL TABLE temp.stat USING dbstat; SELECT * FROM stat; } {} | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | register_dbstat_vtab db do_execsql_test stat-0.0 { PRAGMA auto_vacuum = OFF; CREATE VIRTUAL TABLE temp.stat USING dbstat; SELECT * FROM stat; } {} if {$::sqlite_options(wal) && [wal_is_ok]} { do_execsql_test stat-0.1 { PRAGMA journal_mode = WAL; PRAGMA journal_mode = delete; SELECT name, path, pageno, pagetype, ncell, payload, unused, mx_payload FROM stat; } {wal delete sqlite_master / 1 leaf 0 0 916 0} } |
︙ | ︙ |
Changes to test/superlock.test.
︙ | ︙ | |||
38 39 40 41 42 43 44 45 46 47 48 49 50 51 | # handler returns 0 before said clients relinquish their locks. # # 6.*: Test that if a superlocked WAL database is overwritten, existing # clients run the recovery to build the new wal-index after the # superlock is released. # # do_execsql_test 1.1 { CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); PRAGMA journal_mode = DELETE; } {delete} | > > > > > | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | # handler returns 0 before said clients relinquish their locks. # # 6.*: Test that if a superlocked WAL database is overwritten, existing # clients run the recovery to build the new wal-index after the # superlock is released. # # if {[forced_proxy_locking]} { finish_test return } do_execsql_test 1.1 { CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); PRAGMA journal_mode = DELETE; } {delete} |
︙ | ︙ |
Changes to test/tkt-2d1a5c67d.test.
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix tkt-2d1a5c67d ifcapable {!wal || !vtab} {finish_test; return} for {set ii 1} {$ii<=10} {incr ii} { do_test tkt-2d1a5c67d.1.$ii { db close forcedelete test.db test.db-wal sqlite3 db test.db db eval "PRAGMA cache_size=$::ii" | > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # set testdir [file dirname $argv0] 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 { db close forcedelete test.db test.db-wal sqlite3 db test.db db eval "PRAGMA cache_size=$::ii" |
︙ | ︙ |
Changes to test/tkt-313723c356.test.
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl ifcapable !wal { finish_test ; return } do_execsql_test tkt-313723c356.1 { PRAGMA page_size = 1024; PRAGMA journal_mode = WAL; CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(a, b); INSERT INTO t1 VALUES(randomblob(400), randomblob(400)); | > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # set testdir [file dirname $argv0] 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; PRAGMA journal_mode = WAL; CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(a, b); INSERT INTO t1 VALUES(randomblob(400), randomblob(400)); |
︙ | ︙ |
Changes to test/tkt-5d863f876e.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # This file implements tests to verify that ticket [5d863f876e] has been # fixed. # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl do_multiclient_test tn { do_test $tn.1 { sql1 { CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(a, b); INSERT INTO t1 VALUES(1, 2); | > > > > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # This file implements tests to verify that ticket [5d863f876e] has been # fixed. # 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 { CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(a, b); INSERT INTO t1 VALUES(1, 2); |
︙ | ︙ |
Changes to test/wal2.test.
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 | source $testdir/lock_common.tcl source $testdir/malloc_common.tcl source $testdir/wal_common.tcl set testprefix wal2 ifcapable !wal {finish_test ; return } set sqlite_sync_count 0 proc cond_incr_sync_count {adj} { global sqlite_sync_count if {$::tcl_platform(platform) == "windows"} { incr sqlite_sync_count $adj } { | > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | source $testdir/lock_common.tcl source $testdir/malloc_common.tcl 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} { global sqlite_sync_count if {$::tcl_platform(platform) == "windows"} { incr sqlite_sync_count $adj } { |
︙ | ︙ | |||
65 66 67 68 69 70 71 72 73 74 75 76 77 78 | proc incr_tvfs_hdr {file idx incrval} { set ints [set_tvfs_hdr $file] set v [lindex $ints $idx] incr v $incrval lset ints $idx $v set_tvfs_hdr $file $ints } #------------------------------------------------------------------------- # Test case wal2-1.*: # # Set up a small database containing a single table. The database is not # checkpointed during the test - all content resides in the log file. | > > > > > > > | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | proc incr_tvfs_hdr {file idx incrval} { set ints [set_tvfs_hdr $file] set v [lindex $ints $idx] incr v $incrval lset ints $idx $v 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.*: # # Set up a small database containing a single table. The database is not # checkpointed during the test - all content resides in the log file. |
︙ | ︙ | |||
938 939 940 941 942 943 944 945 946 947 948 949 950 951 | execsql { PRAGMA journal_mode = WAL; CREATE TABLE t1(a, b); PRAGMA wal_checkpoint; INSERT INTO t1 VALUES(1, 2); INSERT INTO t1 VALUES(3, 4); } faultsim_save_and_close } {} do_test wal2-10.1.2 { faultsim_restore_and_reopen execsql { SELECT * FROM t1 } } {1 2 3 4} do_test wal2-10.1.3 { | > > > | 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 | execsql { PRAGMA journal_mode = WAL; CREATE TABLE t1(a, b); PRAGMA wal_checkpoint; 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 { faultsim_restore_and_reopen execsql { SELECT * FROM t1 } } {1 2 3 4} do_test wal2-10.1.3 { |
︙ | ︙ | |||
1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 | #------------------------------------------------------------------------- # If a connection is required to create a WAL or SHM file, it creates # the new files with the same file-system permissions as the database # file itself. Test this. # if {$::tcl_platform(platform) == "unix"} { faultsim_delete_and_reopen # Changed on 2012-02-13: umask is deliberately ignored for -wal files. #set umask [exec /bin/sh -c umask] set umask 0 do_test wal2-12.1 { sqlite3 db test.db execsql { CREATE TABLE tx(y, z); PRAGMA journal_mode = WAL; } db close | > > > > > | | | | | | > > > > | > > > > > > | | | 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 | #------------------------------------------------------------------------- # If a connection is required to create a WAL or SHM file, it creates # the new files with the same file-system permissions as the database # 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] set umask 0 do_test wal2-12.1 { sqlite3 db test.db execsql { CREATE TABLE tx(y, z); PRAGMA journal_mode = WAL; } db close list [file exists test.db-wal] [file exists $shmpath] } {0 0} foreach {tn permissions} { 1 00644 2 00666 3 00600 4 00755 } { set effective [format %.5o [expr $permissions & ~$umask]] do_test wal2-12.2.$tn.1 { file attributes test.db -permissions $permissions file attributes test.db -permissions } $permissions do_test wal2-12.2.$tn.2 { 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 $shmpath] } {1 1} do_test wal2-12.2.$tn.4 { 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 $shmpath] } {0 0} } } #------------------------------------------------------------------------- # Test the libraries response to discovering that one or more of the # database, wal or shm files cannot be opened, or can only be opened # read-only. # if {$::tcl_platform(platform) == "unix"} { proc perm {} { set L [list] foreach f {test.db test.db-wal $shmpath} { if {[file exists $f]} { lappend L [file attr $f -perm] } else { lappend L {} } } 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; CREATE TABLE t1(a, b); PRAGMA wal_checkpoint; INSERT INTO t1 VALUES('3.14', '2.72'); } do_test wal2-13.1.1 { 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} { 2 00644 00644 00644 1 1 1 3 00644 00400 00644 1 1 0 4 00644 00644 00400 1 0 0 5 00400 00644 00644 1 1 0 7 00644 00000 00644 1 0 0 8 00644 00644 00000 1 0 0 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 $shmpath -perm $shm_perm set L [file attr test.db -perm] lappend L [file attr test.db-wal -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 # handle. Otherwise, if $can_open is 0, attempting to open the db # handle throws an "unable to open database file" exception. # set r(1) {0 ok} |
︙ | ︙ | |||
1176 1177 1178 1179 1180 1181 1182 | catch { db close } } } #------------------------------------------------------------------------- # Test that "PRAGMA checkpoint_fullsync" appears to be working. # | | | | | > > > > > | | | | 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 | catch { db close } } } #------------------------------------------------------------------------- # Test that "PRAGMA checkpoint_fullsync" appears to be working. # 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 execsql {PRAGMA auto_vacuum = 0} execsql $sql do_execsql_test wal2-14.$tn.0 { PRAGMA page_size = 4096 } {} do_execsql_test wal2-14.$tn.1 { PRAGMA journal_mode = WAL } {wal} 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 INSERT INTO t1 VALUES(1, 2); -- 2 wal sync PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync BEGIN; INSERT INTO t1 VALUES(3, 4); INSERT INTO t1 VALUES(5, 6); COMMIT; -- 2 wal sync PRAGMA wal_checkpoint; -- 1 wal sync, 1 db sync } {10 0 3 3 0 1 1} do_test wal2-14.$tn.3 { cond_incr_sync_count 1 list $sqlite_sync_count $sqlite_fullsync_count } [lrange $useres 0 1] set sqlite_sync_count 0 set sqlite_fullsync_count 0 do_test wal2-14.$tn.4 { execsql { INSERT INTO t1 VALUES(7, zeroblob(12*4096)) } list $sqlite_sync_count $sqlite_fullsync_count } [lrange $useres 2 3] set sqlite_sync_count 0 set sqlite_fullsync_count 0 do_test wal2-14.$tn.5 { execsql { PRAGMA wal_autocheckpoint = 1000 } execsql { INSERT INTO t1 VALUES(9, 10) } execsql { INSERT INTO t1 VALUES(11, 12) } execsql { INSERT INTO t1 VALUES(13, 14) } db close list $sqlite_sync_count $sqlite_fullsync_count } [lrange $useres 4 5] } catch { db close } # PRAGMA checkpoint_fullsync # PRAGMA fullfsync # PRAGMA synchronous |
︙ | ︙ |
Changes to test/wal3.test.
︙ | ︙ | |||
15 16 17 18 19 20 21 22 23 24 25 26 27 28 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/wal_common.tcl source $testdir/malloc_common.tcl ifcapable !wal {finish_test ; return } set a_string_counter 1 proc a_string {n} { global a_string_counter incr a_string_counter string range [string repeat "${a_string_counter}." $n] 1 $n } | > | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | set testdir [file dirname $argv0] source $testdir/tester.tcl 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} { global a_string_counter incr a_string_counter string range [string repeat "${a_string_counter}." $n] 1 $n } |
︙ | ︙ | |||
190 191 192 193 194 195 196 | # CREATE TABLE x(y); # INSERT INTO x VALUES('z'); # PRAGMA wal_checkpoint; # # in WAL mode the xSync method is invoked as expected for each of # synchronous=off, synchronous=normal and synchronous=full. # | | > > > > > > > > | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | # CREATE TABLE x(y); # INSERT INTO x VALUES('z'); # PRAGMA wal_checkpoint; # # in WAL mode the xSync method is invoked as expected for each of # synchronous=off, synchronous=normal and synchronous=full. # 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 testvfs T T filter {} T script sync_counter sqlite3 db test.db -vfs T |
︙ | ︙ | |||
224 225 226 227 228 229 230 | execsql { CREATE TABLE x(y); INSERT INTO x VALUES('z'); PRAGMA wal_checkpoint; } T filter {} set ::syncs | | | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | execsql { CREATE TABLE x(y); INSERT INTO x VALUES('z'); PRAGMA wal_checkpoint; } T filter {} set ::syncs } $usecount db close T delete } #------------------------------------------------------------------------- # When recovering the contents of a WAL file, a process obtains the WRITER |
︙ | ︙ |
Changes to test/wal5.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/wal_common.tcl ifcapable !wal {finish_test ; return } set testprefix wal5 proc db_page_count {{file test.db}} { expr [file size $file] / 1024 } proc wal_page_count {{file test.db}} { wal_frame_count ${file}-wal 1024 } | > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # set testdir [file dirname $argv0] 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 proc db_page_count {{file test.db}} { expr [file size $file] / 1024 } proc wal_page_count {{file test.db}} { wal_frame_count ${file}-wal 1024 } |
︙ | ︙ |
Changes to test/wal7.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # focus of this file is testing the PRAGMA journal_size_limit when # in WAL mode. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !wal {finish_test ; return } # Case 1: No size limit. Journal can get large. # do_test wal7-1.0 { db close forcedelete test.db sqlite3 db test.db | > | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # focus of this file is testing the PRAGMA journal_size_limit when # in WAL mode. # 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. # do_test wal7-1.0 { db close forcedelete test.db sqlite3 db test.db |
︙ | ︙ |
Changes to test/wal8.test.
︙ | ︙ | |||
22 23 24 25 26 27 28 29 30 31 32 33 34 35 | # size from the database file as soon as it is opened (even before the # first read transaction is executed), and the "PRAGMA page_size = XXX" # is a no-op. # set testdir [file dirname $argv0] source $testdir/tester.tcl set ::testprefix wal8 db close forcedelete test.db test.db-wal sqlite3 db test.db sqlite3 db2 test.db | > > | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | # size from the database file as soon as it is opened (even before the # first read transaction is executed), and the "PRAGMA page_size = XXX" # is a no-op. # 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 sqlite3 db test.db sqlite3 db2 test.db |
︙ | ︙ |
Changes to test/walbak.test.
︙ | ︙ | |||
17 18 19 20 21 22 23 | source $testdir/tester.tcl source $testdir/wal_common.tcl source $testdir/malloc_common.tcl do_not_use_codec ifcapable !wal {finish_test ; return } | | < < < | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | source $testdir/tester.tcl source $testdir/wal_common.tcl source $testdir/malloc_common.tcl do_not_use_codec ifcapable !wal {finish_test ; return } if { ![wal_is_ok] } { finish_test ; return } # Test organization: # # walback-1.*: Simple tests. # # walback-2.*: Test backups when the source db is modified mid-backup. |
︙ | ︙ |
Changes to test/walbig.test.
︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 27 28 29 30 | set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !wal { 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). # do_not_use_codec # If SQLITE_DISABLE_LFS is defined, omit this file. | > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | set testdir [file dirname $argv0] source $testdir/tester.tcl 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). # do_not_use_codec # If SQLITE_DISABLE_LFS is defined, omit this file. |
︙ | ︙ |
Changes to test/walcksum.test.
︙ | ︙ | |||
12 13 14 15 16 17 18 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/wal_common.tcl ifcapable !wal {finish_test ; return } | | < < < | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | set testdir [file dirname $argv0] 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 } # Read and return the contents of file $filename. Treat the content as # binary data. # proc readfile {filename} { set fd [open $filename] fconfigure $fd -encoding binary |
︙ | ︙ |
Changes to test/walcrash.test.
︙ | ︙ | |||
24 25 26 27 28 29 30 | # walcrash-3.*: Recover multiple databases where the failed transaction # was a multi-file transaction. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !wal {finish_test ; return } | | < < < | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | # walcrash-3.*: Recover multiple databases where the failed transaction # was a multi-file transaction. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !wal {finish_test ; return } if ![wal_is_ok] { finish_test; return } db close set seed 0 set REPEATS 100 # walcrash-1.* |
︙ | ︙ |
Changes to test/walcrash3.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # truncates the WAL file if "PRAGMA journal_size_limit" is configured. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !wal {finish_test ; return } set testprefix walcrash3 db close testvfs tvfs tvfs filter {xTruncate xWrite} tvfs script tvfs_callback proc tvfs_callback {args} {} | > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # truncates the WAL file if "PRAGMA journal_size_limit" is configured. # 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 testvfs tvfs tvfs filter {xTruncate xWrite} tvfs script tvfs_callback proc tvfs_callback {args} {} |
︙ | ︙ |
Changes to test/walfault.test.
︙ | ︙ | |||
15 16 17 18 19 20 21 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl source $testdir/lock_common.tcl ifcapable !wal {finish_test ; return } | | < < < | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl 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 # # PRAGMA journal_mode = WAL; # # statement immediately after creating a new database. |
︙ | ︙ |
Changes to test/walhook.test.
︙ | ︙ | |||
18 19 20 21 22 23 24 | # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/wal_common.tcl ifcapable !wal {finish_test ; return } | | < < < | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # set testdir [file dirname $argv0] source $testdir/tester.tcl 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} { lappend ::wal_hook $zDb $nEntry return 0 } db wal_hook wal_hook |
︙ | ︙ |
Changes to test/walnoshm.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # using the xShm primitives if the connection is in exclusive-mode. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix walnoshm ifcapable !wal {finish_test ; return } db close testvfs tvfsshm testvfs tvfs -default 1 -iversion 1 sqlite3 db test.db #-------------------------------------------------------------------------- | > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # using the xShm primitives if the connection is in exclusive-mode. # 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 testvfs tvfs -default 1 -iversion 1 sqlite3 db test.db #-------------------------------------------------------------------------- |
︙ | ︙ |
Changes to test/walpersist.test.
︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | source $testdir/lock_common.tcl set ::testprefix walpersist ifcapable !wal { finish_test return } do_test walpersist-1.0 { db eval { PRAGMA journal_mode=WAL; CREATE TABLE t1(a); INSERT INTO t1 VALUES(randomblob(5000)); } file exists test.db-wal } {1} do_test walpersist-1.1 { | > > > > > > | | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | source $testdir/lock_common.tcl set ::testprefix walpersist 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 { PRAGMA journal_mode=WAL; CREATE TABLE t1(a); INSERT INTO t1 VALUES(randomblob(5000)); } file exists test.db-wal } {1} do_test walpersist-1.1 { file exists $shmpath } {1} do_test walpersist-1.2 { db close list [file exists test.db] [file exists test.db-wal] [file exists $shmpath] } {1 0 0} 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 $shmpath] } {1 1 1} do_test walpersist-1.5 { file_control_persist_wal db -1 } {0 0} do_test walpersist-1.6 { file_control_persist_wal db 1 } {0 1} |
︙ | ︙ | |||
60 61 62 63 64 65 66 | file_control_persist_wal db -1 } {0 0} do_test walpersist-1.10 { file_control_persist_wal db 1 } {0 1} do_test walpersist-1.11 { db close | | | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | file_control_persist_wal db -1 } {0 0} do_test walpersist-1.10 { file_control_persist_wal db 1 } {0 1} do_test walpersist-1.11 { db close 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 # persisted wal file. In persistent-wal mode, any non-negative # journal_size_limit causes the WAL file to be truncated to zero bytes # when closing. # forcedelete test.db $shmpath test.db-wal do_test walpersist-2.1 { sqlite3 db test.db db eval { PRAGMA journal_mode=WAL; PRAGMA wal_autocheckpoint=OFF; PRAGMA journal_size_limit=12000; CREATE TABLE t1(x); |
︙ | ︙ | |||
93 94 95 96 97 98 99 | do_test walpersist-2.3 { sqlite3 db test.db execsql { PRAGMA integrity_check } } {ok} do_test 3.1 { catch {db close} | | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | do_test walpersist-2.3 { sqlite3 db test.db execsql { PRAGMA integrity_check } } {ok} do_test 3.1 { catch {db close} forcedelete test.db $shmpath test.db-wal sqlite3 db test.db execsql { PRAGMA page_size = 1024; PRAGMA journal_mode = WAL; PRAGMA wal_autocheckpoint=128; PRAGMA journal_size_limit=16384; CREATE TABLE t1(a, b, PRIMARY KEY(a, b)); |
︙ | ︙ |
Changes to test/walro.test.
︙ | ︙ | |||
26 27 28 29 30 31 32 33 34 35 36 37 38 39 | # And only if the build is WAL-capable. # ifcapable !wal { finish_test return } do_multiclient_test tn { # Do not run tests with the connections in the same process. # if {$tn==2} continue # Close all connections and delete the database. | > > > > > > > > | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | # And only if the build is WAL-capable. # 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. # if {$tn==2} continue # Close all connections and delete the database. |
︙ | ︙ | |||
56 57 58 59 60 61 62 | do_test 1.1.1 { code2 { sqlite3 db2 test.db } sql2 { PRAGMA journal_mode = WAL; CREATE TABLE t1(x, y); INSERT INTO t1 VALUES('a', 'b'); } | | | | 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | do_test 1.1.1 { code2 { sqlite3 db2 test.db } sql2 { PRAGMA journal_mode = WAL; CREATE TABLE t1(x, y); INSERT INTO t1 VALUES('a', 'b'); } file exists $shmpath } {1} do_test 1.1.2 { file attributes $shmpath -permissions r--r--r-- code1 { sqlite3 db file:test.db?readonly_shm=1 } } {} do_test 1.1.3 { sql1 "SELECT * FROM t1" } {a b} do_test 1.1.4 { sql2 "INSERT INTO t1 VALUES('c', 'd')" } {} do_test 1.1.5 { sql1 "SELECT * FROM t1" } {a b c d} |
︙ | ︙ | |||
93 94 95 96 97 98 99 | } {} do_test 1.1.12 { sql1 "SELECT * FROM t1" } {a b c d e f g h} do_test 1.1.13 { sql2 "INSERT INTO t1 VALUES('i', 'j')" } {} do_test 1.2.1 { code2 { db2 close } code1 { db close } | | | | | | | | 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | } {} do_test 1.1.12 { sql1 "SELECT * FROM t1" } {a b c d e f g h} do_test 1.1.13 { sql2 "INSERT INTO t1 VALUES('i', 'j')" } {} do_test 1.2.1 { code2 { db2 close } code1 { db close } 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 } sql1 { SELECT * FROM t1 } } {a b c d e f g h i j} do_test 1.2.3 { code1 { db close } 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}} do_test 1.2.4 { code1 { sqlite3_extended_errcode db } } {SQLITE_READONLY_RECOVERY} do_test 1.2.5 { 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 $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 { sql2 { PRAGMA wal_checkpoint; INSERT INTO t1 VALUES('k', 'l'); } |
︙ | ︙ | |||
143 144 145 146 147 148 149 | } {1 {unable to open database file}} # Also test that if the -shm file can be opened for read/write access, # it is not if readonly_shm=1 is present in the URI. do_test 1.3.2.1 { code1 { db close } code2 { db2 close } | | | | > > | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | } {1 {unable to open database file}} # Also test that if the -shm file can be opened for read/write access, # it is not if readonly_shm=1 is present in the URI. do_test 1.3.2.1 { code1 { db close } code2 { db2 close } file exists $shmpath } {0} do_test 1.3.2.2 { code1 { sqlite3 db file:test.db?readonly_shm=1 } csql1 { SELECT * FROM sqlite_master } } {1 {unable to open database file}} do_test 1.3.2.3 { code1 { db close } 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}} do_test 1.3.2.4 { code1 { sqlite3_extended_errcode db } } {SQLITE_READONLY_RECOVERY} } forcedelete $shmpath finish_test |
Changes to test/walshared.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 20 21 22 23 24 25 26 | # "PRAGMA journal_mode=WAL" mode with shared-cache turned on. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !wal {finish_test ; return } db close set ::enable_shared_cache [sqlite3_enable_shared_cache 1] sqlite3 db test.db sqlite3 db2 test.db | > | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # "PRAGMA journal_mode=WAL" mode with shared-cache turned on. # 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] sqlite3 db test.db sqlite3 db2 test.db |
︙ | ︙ |
Changes to test/walslow.test.
︙ | ︙ | |||
14 15 16 17 18 19 20 | # brute force methods, so may take a while to run. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !wal {finish_test ; return } | | < < < | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | # brute force methods, so may take a while to run. # set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !wal {finish_test ; return } if ![wal_is_ok] { finish_test; return } proc reopen_db {} { catch { db close } forcedelete test.db test.db-wal sqlite3 db test.db execsql { PRAGMA journal_mode = wal } } |
︙ | ︙ |
Changes to test/walthread.test.
︙ | ︙ | |||
15 16 17 18 19 20 21 | set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl if {[run_thread_tests]==0} { finish_test ; return } ifcapable !wal { finish_test ; return } | | < < < | 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | set testdir [file dirname $argv0] 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 } set sqlite_walsummary_mmap_incr 64 # How long, in seconds, to run each test for. If a test is set to run for # 0 seconds, it is omitted entirely. # unset -nocomplain seconds |
︙ | ︙ |