diff --git a/manifest b/manifest index a067459e54..3496399bb7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\sold\sOsFile\sand\sIoMethod\srelated\scode.\sAdd\sthe\ssqlite3OsLockState\sfunction.\s(CVS\s4241) -D 2007-08-17T16:50:38 +C Further\sprogress\son\smigration\sto\ssqlite3_vfs.\s(CVS\s4242) +D 2007-08-18T10:59:20 F Makefile.in 0c0e53720f658c7a551046442dd7afba0b72bfbe F Makefile.linux-gcc 65241babba6faf1152bf86574477baab19190499 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -74,7 +74,7 @@ F src/btreeInt.h 6329e955a7dadd8628d5866e2465721b5fd25ef2 F src/build.c add67be992307b4b11849a6611bfd3352aacde92 F src/callback.c 143436453bb93e831c9574fea0b9b9eb90e40ff3 F src/complete.c ea63834e798a0ab14159bdc6e6cabc3df21aa346 -F src/date.c c44aa498ee9a289ba2b2c62e8269b74b1b81351f +F src/date.c 8c37dbbabc9fceec51e8adfcd771328345679b14 F src/delete.c 849846d06d29851dde0d9f424a5de5817eb140d1 F src/experimental.c 1b2d1a6cd62ecc39610e97670332ca073c50792b F src/expr.c 3ea108a9e409f58b8203e29c54442da5085be5bf @@ -85,24 +85,24 @@ F src/insert.c 633322aef1799f6604fa805e12488bc628570b0c F src/legacy.c 6013a7cb7da1b72550b3d35d4fc598b3c3e5b8c1 F src/limits.h 71ab25f17e35e0a9f3f6f234b8ed49cc56731d35 F src/loadext.c c0ccda3dbda109da087a8fd762deebe5fdf24a1d -F src/main.c cb6635a4d2fe2b140942338ff5ab605f4c08fa5d +F src/main.c e4bfea7b893688b034cb5fd43a8f9d19a0c72c34 F src/malloc.c 613c65f12ff0ee4edd017aa458209ab7a23cd7b1 F src/md5.c c5fdfa5c2593eaee2e32a5ce6c6927c986eaf217 F src/mem1.c 30bf8be3846f92fdf88c490c5e5378512383bcbe F src/mem2.c 661ca7ebf6e4b964fecc95d24e8c89dbcfc9dfea F src/mutex.c 67b2efd36a1e67a7dc7b7fa852fd69953462c943 -F src/os.c dce5a35b7ef4e8087b682376adf835d132ccf850 -F src/os.h d33920f6b3e0dc300a2de3d765820cb0e8176cbc +F src/os.c f08ddf81e0e66e4196a3e0b13d4330c1400783c1 +F src/os.h 447a22462d4cc5e570269451122767e8cd27097d F src/os_common.h a5c446d3b93f09f369d13bf217de4bed3437dd1c F src/os_os2.c cba4e96fadb949076c717108fe0599d1a3c2e446 F src/os_os2.h e5f17dd69333632bbc3112881ea407c37d245eb3 F src/os_test.c 49833426101f99aee4bb5f6a44b7c4b2029fda1c F src/os_test.h 903c93554c23d88f34f667f1979e4a1cee792af3 -F src/os_unix.c 4b27202b4bfc1548c2ff3ae9a40b2e4530e57c7b +F src/os_unix.c 07c91dfdf6ae20014d1e7172cd648d3ae1dcebdf F src/os_unix.h 5768d56d28240d3fe4537fac08cc85e4fb52279e F src/os_win.c d868d5f9e95ec9c1b9e2a30c54c996053db6dddd F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b -F src/pager.c ee60b932e7b4ba355f2606505415b4d5183b1de1 +F src/pager.c e7b94954a489485e9bc2954810f8708f27dae27d F src/pager.h 53087c6fb9db01aed17c7fd044662a27507e89b8 F src/parse.y c03529c3b82702ada98ce405b390e3a9409708cf F src/pragma.c 8f5e37c3cf6dbdeb3645bb80cc58cfc3324c0178 @@ -112,14 +112,14 @@ F src/random.c 00b30565f018f3a256c157432935de070231c73b F src/select.c 98c367bce3f38c5adfcc97de9ab5c79b0e5dc2b2 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c ac29402b538515fa4697282387be9c1205e6e9eb -F src/sqlite.h.in 366645a566cb674c1e26d10451e784cbe2a7b58c +F src/sqlite.h.in a0baef0f4c969a4eb9dfc9096bf527ca543485e5 F src/sqlite3ext.h 647a6b8a8f76ff6c9611e4a071531d8e63ff2d6b F src/sqliteInt.h 442a6861cf3f535f410acad19a55b2fbca2564a7 F src/sqliteLimit.h f14609c27636ebc217c9603ade26dbdd7d0f6afa F src/table.c c725e47f6f3092b9a7b569fc58e408e2173ee008 F src/tclsqlite.c 0606c4f31711492eb4d7480a981eebb80914f3d9 F src/test1.c a226ab03048491aa6c5d43d26097df96bdb162e7 -F src/test2.c 47bb59a0198651a9f0551ec956de151da7c24575 +F src/test2.c 8dc9775a8419cd2238bbfdea3023f7325e227f92 F src/test3.c b87e8fcce45e1d3153aae9f04236076b7707a714 F src/test4.c d22cb3ab4f9fdfd0a595b70d5328cee923b7322c F src/test5.c 7bc8a87c2b6fd076ec2ca9972946e71a367883ad @@ -148,7 +148,7 @@ F src/vdbe.c b5cd895a0516466daacc564da332589a903e2eb0 F src/vdbe.h 001c5b257567c1d3de7feb2203aac71d0d7b16a3 F src/vdbeInt.h 8e360d326328e7a66100f468697edf9cfb4567dc F src/vdbeapi.c ddfe341249929b89c47a0ff77f8043ef0987612b -F src/vdbeaux.c 6468d5665a3dd932c2e7e4f6b1c0319334b9887a +F src/vdbeaux.c c155bc8ef20772d481fbd6733ebdc5921fc725e0 F src/vdbeblob.c cf9ee3c7d9977cbd896f8b118da4fb4268637f4f F src/vdbefifo.c 334c838c8f42d61a94813d136019ee566b5dc2f6 F src/vdbemem.c 019952d44066a24aef70ca8c284cfd2d1073c398 @@ -178,7 +178,7 @@ F test/autovacuum_ioerr2.test dc189f323cf0546289b5a9bbda60bcb1fe52bd4b F test/avtrans.test 365beb46116ec0a1a5b0cab8ce0df63d62367208 F test/badutf.test e5cd3fd946b76fb0d05024156618ed905298f44a F test/between.test 16b1776c6323faadb097a52d673e8e3d8be7d070 -F test/bigfile.test ebc9ce9216e08bead63734ab816d0f27858f3b80 +F test/bigfile.test 9a6a8346e4042d9c781ed6cb6553ac871ae30618 F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747 F test/bind.test 261fd1603613e7f877a516d29f281c9d8c2ecf52 F test/bindxfer.test b9a57f66dbd317feeefa28bd65b6576f1592ee98 @@ -529,7 +529,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P af3e3c7acdc67013dd733effebe981620d922dd1 -R 0b450cd00a75691c9505bbff03bfb4a5 +P 08a0f48028794abbeae1b4852652062b38d37d88 +R d17ed65ec6cd4048d7ed68411869b446 U danielk1977 -Z 31339accc484dfc95959c68759a89caa +Z 457c2c17e418be6c89b765be93941d83 diff --git a/manifest.uuid b/manifest.uuid index d74ff6fc4f..b9398c1e59 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -08a0f48028794abbeae1b4852652062b38d37d88 \ No newline at end of file +a258c4ec240f96bccfe493e98d0827ec7dd12e67 \ No newline at end of file diff --git a/src/date.c b/src/date.c index ec2d34ab8f..4629ebac92 100644 --- a/src/date.c +++ b/src/date.c @@ -16,7 +16,7 @@ ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: date.c,v 1.68 2007/08/16 10:09:03 danielk1977 Exp $ +** $Id: date.c,v 1.69 2007/08/18 10:59:20 danielk1977 Exp $ ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon @@ -303,7 +303,11 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ ** as there is a time string. The time string can be omitted as long ** as there is a year and date. */ -static int parseDateOrTime(const char *zDate, DateTime *p){ +static int parseDateOrTime( + sqlite3_context *context, + const char *zDate, + DateTime *p +){ memset(p, 0, sizeof(*p)); if( parseYyyyMmDd(zDate,p)==0 ){ return 0; @@ -311,7 +315,7 @@ static int parseDateOrTime(const char *zDate, DateTime *p){ return 0; }else if( sqlite3StrICmp(zDate,"now")==0){ double r; - sqlite3OsCurrentTime(&r); + sqlite3OsCurrentTime((sqlite3_vfs *)sqlite3_user_data(context), &r); p->rJD = r; p->validJD = 1; return 0; @@ -423,7 +427,7 @@ static double localtimeOffset(DateTime *p){ #else { struct tm *pTm; - sqlite3OsEnterMutex(); + sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL)); pTm = localtime(&t); y.Y = pTm->tm_year + 1900; y.M = pTm->tm_mon + 1; @@ -431,7 +435,7 @@ static double localtimeOffset(DateTime *p){ y.h = pTm->tm_hour; y.m = pTm->tm_min; y.s = pTm->tm_sec; - sqlite3OsLeaveMutex(); + sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_GLOBAL)); } #endif y.validYMD = 1; @@ -651,11 +655,17 @@ static int parseModifier(const char *zMod, DateTime *p){ ** the resulting time into the DateTime structure p. Return 0 ** on success and 1 if there are any errors. */ -static int isDate(int argc, sqlite3_value **argv, DateTime *p){ +static int isDate( + sqlite3_context *context, + int argc, + sqlite3_value **argv, + DateTime *p +){ int i; const unsigned char *z; if( argc==0 ) return 1; - if( (z = sqlite3_value_text(argv[0]))==0 || parseDateOrTime((char*)z, p) ){ + z = sqlite3_value_text(argv[0]); + if( !z || parseDateOrTime(context, (char*)z, p) ){ return 1; } for(i=1; ipVfs), aFuncs[i].xFunc, 0, 0); } #else static const struct { diff --git a/src/main.c b/src/main.c index b3eab17579..9db08c4171 100644 --- a/src/main.c +++ b/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.384 2007/08/17 15:53:36 danielk1977 Exp $ +** $Id: main.c,v 1.385 2007/08/18 10:59:20 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -1378,7 +1378,11 @@ int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ int sqlite3_sleep(int ms){ sqlite3_vfs *pVfs; pVfs = sqlite3_find_vfs(0); - return sqlite3OsSleep(pVfs, 1000*ms); + + /* This function works in milliseconds, but the underlying OsSleep() + ** API uses microseconds. Hence the 1000's. + */ + return (sqlite3OsSleep(pVfs, 1000*ms)/1000); } /* diff --git a/src/os.c b/src/os.c index ed5c98e87b..f7aedd7361 100644 --- a/src/os.c +++ b/src/os.c @@ -83,8 +83,8 @@ int sqlite3OsOpen( ){ return pVfs->xOpen(pVfs->pAppData, zPath, pFile, flags, pFlagsOut); } -int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath){ - return pVfs->xDelete(pVfs->pAppData, zPath); +int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + return pVfs->xDelete(pVfs->pAppData, zPath, dirSync); } int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){ return pVfs->xAccess(pVfs->pAppData, zPath, flags); diff --git a/src/os.h b/src/os.h index e37ac40743..fadf1c821a 100644 --- a/src/os.h +++ b/src/os.h @@ -243,7 +243,7 @@ int sqlite3OsDeviceCharacteristics(sqlite3_file *id); ** Functions for accessing sqlite3_vfs methods */ int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); -int sqlite3OsDelete(sqlite3_vfs *, const char *); +int sqlite3OsDelete(sqlite3_vfs *, const char *, int); int sqlite3OsAccess(sqlite3_vfs *, const char *, int); int sqlite3OsGetTempName(sqlite3_vfs *, char *); int sqlite3OsFullPathname(sqlite3_vfs *, const char *, char *); diff --git a/src/os_unix.c b/src/os_unix.c index 00eb2f2499..6200ac1aef 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -2504,6 +2504,7 @@ static int allocateUnixFile( #else /* SQLITE_ENABLE_LOCKING_STYLE */ static int fillInUnixFile( int h, /* Open file descriptor on file being opened */ + int dirfd, sqlite3_file *pId, /* Write to the unixFile structure here */ const char *zFilename /* Name of the file being opened */ ){ @@ -2525,6 +2526,7 @@ static int fillInUnixFile( OSTRACE3("OPEN %-3d %s\n", h, zFilename); pNew->dirfd = -1; pNew->h = h; + pNew->dirfd = dirfd; SET_THREADID(pNew); pNew->pMethod = &sqlite3UnixIoMethod; @@ -2539,6 +2541,33 @@ static int fillInUnixFile( ** with other miscellanous aspects of the operating system interface ****************************************************************************/ +static int openDirectory(const char *zFilename, int *pFd){ + char *zDirname; + int ii; + int fd; + + zDirname = (char *)sqlite3_malloc(MAX_PATHNAME); + if( !zDirname ){ + return SQLITE_NOMEM; + } + strncpy(zDirname, zFilename, MAX_PATHNAME); + zDirname[MAX_PATHNAME-1] = '\0'; + for(ii=strlen(zDirname); ii>=0 && zDirname[ii]!='/'; ii--); + if( ii>0 ){ + zDirname[ii] = '\0'; + fd = open(zDirname, O_RDONLY|O_BINARY, 0); + if( fd>0 ){ +#ifdef FD_CLOEXEC + fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC); +#endif + OSTRACE3("OPENDIR %-3d %s\n", fd, zDirname); + } + } + sqlite3_free(zDirname); + *pFd = fd; + return (fd>0?SQLITE_OK:SQLITE_CANTOPEN); +} + /* ** Previously, the SQLite OS layer used three functions in place of this ** one: @@ -2566,8 +2595,10 @@ static int unixOpen( int flags, int *pOutFlags ){ - int fd = 0; - int oflags = 0; + int fd = 0; /* File descriptor returned by open() */ + int dirfd = -1; /* Directory file descriptor */ + int oflags = 0; /* Flags to pass to open() */ + int eType = flags&0xFFFFFF00; /* Type of file to open */ int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); @@ -2575,15 +2606,30 @@ static int unixOpen( int isReadonly = (flags & SQLITE_OPEN_READONLY); int isReadWrite = (flags & SQLITE_OPEN_READWRITE); - /* Exactly one of the READWRITE and READONLY flags must be set */ + /* If creating a master or main-file journal, this function will open + ** a file-descriptor on the directory too. The first time unixSync() + ** is called the directory file descriptor will be fsync()ed and close()d. + */ + int isOpenDirectory = (isCreate && + (eType==SQLITE_OPEN_MASTER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL) + ); + + /* Check the following statements are true: + ** + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (b) if CREATE is set, then READWRITE must also be set, and + ** (c) if EXCLUSIVE is set, then CREATE must also be set. + */ assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly)); - - /* If isCreate is true, then the file must be opened for read/write access. */ assert(isCreate==0 || isReadWrite); - - /* If isExclusive is true, then isCreate must also be true */ assert(isExclusive==0 || isCreate); + /* Assert that the upper layer has set one of the "file-type" flags. */ + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_MASTER_JOURNAL + ); + if( isReadonly ) oflags |= O_RDONLY; if( isReadWrite ) oflags |= O_RDWR; if( isCreate ) oflags |= O_CREAT; @@ -2609,16 +2655,35 @@ static int unixOpen( } assert(fd!=0); - return fillInUnixFile(fd, pFile, zPath); + if( isOpenDirectory ){ + int rc = openDirectory(zPath, &dirfd); + if( rc!=SQLITE_OK ){ + close(fd); + return rc; + } + } + return fillInUnixFile(fd, dirfd, pFile, zPath); } /* -** Delete the file at zPath. +** Delete the file at zPath. If the dirSync argument is true, fsync() +** the directory after deleting the file. */ -static int unixDelete(void *pNotUsed, const char *zPath){ +static int unixDelete(void *pNotUsed, const char *zPath, int dirSync){ + int rc = SQLITE_OK; SimulateIOError(return SQLITE_IOERR_DELETE); unlink(zPath); - return SQLITE_OK; + if( dirSync ){ + int fd; + rc = openDirectory(zPath, &fd); + if( rc==SQLITE_OK ){ + if( fsync(fd) ){ + rc = SQLITE_IOERR_DIR_FSYNC; + } + close(fd); + } + } + return rc; } /* diff --git a/src/pager.c b/src/pager.c index 5fbedba319..8100de2945 100644 --- a/src/pager.c +++ b/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.359 2007/08/17 15:53:37 danielk1977 Exp $ +** @(#) $Id: pager.c,v 1.360 2007/08/18 10:59:20 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" @@ -1024,7 +1024,7 @@ static int pager_end_transaction(Pager *pPager){ sqlite3OsClose(pPager->jfd); pPager->journalOpen = 0; if( rc==SQLITE_OK ){ - rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal); + rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); } } sqlite3_free( pPager->aInJournal ); @@ -1239,11 +1239,12 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ ** is running this routine also. Not that it makes too much difference. */ pMaster = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile * 2); + pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile); if( !pMaster ){ rc = SQLITE_NOMEM; }else{ - pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile); - rc = sqlite3OsOpen(pVfs, zMaster, pMaster, SQLITE_OPEN_READONLY, 0); + int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL); + rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0); } if( rc!=SQLITE_OK ) goto delmaster_out; master_open = 1; @@ -1274,8 +1275,8 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ ** so, return without deleting the master journal file. */ int c; - - rc = sqlite3OsOpen(pVfs, zJournal, pJournal, SQLITE_OPEN_READONLY, 0); + int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL); + rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0); if( rc!=SQLITE_OK ){ goto delmaster_out; } @@ -1297,7 +1298,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ } } - rc = sqlite3OsDelete(pVfs, zMaster); + rc = sqlite3OsDelete(pVfs, zMaster, 0); delmaster_out: if( zMasterJournal ){ @@ -1687,10 +1688,11 @@ int sqlite3_opentemp_count = 0; ** Open a temporary file. ** ** Write the file descriptor into *fd. Return SQLITE_OK on success or some -** other error code if we fail. +** other error code if we fail. The OS will automatically delete the temporary +** file when it is closed. ** -** The OS will automatically delete the temporary file when it is -** closed. +** If zNameOut is 0, then SQLITE_OPEN_SUBJOURNAL is passed to the OS layer. +** If zNameOut is not 0, SQLITE_OPEN_TEMP_DB is passed. */ static int sqlite3PagerOpentemp( sqlite3_vfs *pVfs, @@ -1708,6 +1710,9 @@ static int sqlite3PagerOpentemp( return SQLITE_NOMEM; } zNameOut = zFree; + flags |= SQLITE_OPEN_SUBJOURNAL; + }else{ + flags |= SQLITE_OPEN_TEMP_DB; } #ifdef SQLITE_TEST @@ -1811,9 +1816,10 @@ int sqlite3PagerOpen( if( strlen(pPager->zFilename)>(pVfs->mxPathname - strlen("-journal")) ){ rc = SQLITE_CANTOPEN; }else{ - int flag = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); + int oflag = + (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_DB); int fout = 0; - rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, flag, &fout); + rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, oflag, &fout); readOnly = (fout&SQLITE_OPEN_READONLY); } } @@ -2624,7 +2630,7 @@ static int hasHotJournal(Pager *pPager){ return 0; } if( sqlite3PagerPagecount(pPager)==0 ){ - sqlite3OsDelete(pVfs, pPager->zJournal); + sqlite3OsDelete(pVfs, pPager->zJournal, 0); return 0; }else{ return 1; @@ -2906,7 +2912,7 @@ static int pagerSharedLock(Pager *pPager){ rc = SQLITE_BUSY; if( sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS) ){ int fout = 0; - int flags = SQLITE_OPEN_READWRITE; + int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; assert( !pPager->tempFile ); rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, &fout); assert( rc!=SQLITE_OK || pPager->jfd->pMethods ); @@ -3352,7 +3358,9 @@ static int pager_open_journal(Pager *pPager){ } if( pPager->tempFile ){ - flags |= SQLITE_OPEN_DELETEONCLOSE; + flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL); + }else{ + flags |= (SQLITE_OPEN_MAIN_JOURNAL); } rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0); assert( rc!=SQLITE_OK || pPager->jfd->pMethods ); @@ -3361,14 +3369,13 @@ static int pager_open_journal(Pager *pPager){ pPager->journalHdr = 0; if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ){ - sqlite3OsDelete(pVfs, pPager->zJournal); + sqlite3OsDelete(pVfs, pPager->zJournal, 0); } goto failed_to_open_journal; } #if 0 sqlite3OsSetFullSync(pPager->jfd, pPager->full_fsync); sqlite3OsSetFullSync(pPager->fd, pPager->full_fsync); - sqlite3OsOpenDirectory(pPager->jfd, pPager->zDirectory); #endif pPager->journalOpen = 1; pPager->journalStarted = 0; diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 02d6cd498f..55f2a50e66 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -30,7 +30,7 @@ ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. ** -** @(#) $Id: sqlite.h.in,v 1.229 2007/08/17 16:50:38 danielk1977 Exp $ +** @(#) $Id: sqlite.h.in,v 1.230 2007/08/18 10:59:21 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -641,7 +641,7 @@ struct sqlite3_vfs { void *pAppData; /* Application context */ int (*xOpen)(void *pAppData, const char *zName, sqlite3_file*, int flags, int *pOutFlags); - int (*xDelete)(void *pAppData, const char *zName); + int (*xDelete)(void *pAppData, const char *zName, int syncDir); int (*xAccess)(void *pAppData, const char *zName, int flags); int (*xGetTempName)(void *pAppData, char *zOut); int (*xFullPathname)(void *pAppData, const char *zName, char *zOut); diff --git a/src/test2.c b/src/test2.c index a45d60c965..d6dfa75df5 100644 --- a/src/test2.c +++ b/src/test2.c @@ -13,7 +13,7 @@ ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** -** $Id: test2.c,v 1.46 2007/08/17 15:53:37 danielk1977 Exp $ +** $Id: test2.c,v 1.47 2007/08/18 10:59:21 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -530,7 +530,6 @@ static int fake_big_file( ){ sqlite3_vfs *pVfs; sqlite3_file *fd = 0; - int flags = SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE; int rc; int n; i64 offset; @@ -542,7 +541,9 @@ static int fake_big_file( if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR; pVfs = sqlite3_find_vfs(0); - rc = sqlite3OsOpenMalloc(pVfs, argv[2], &fd, flags); + rc = sqlite3OsOpenMalloc(pVfs, argv[2], &fd, + (SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB) + ); if( rc ){ Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0); return TCL_ERROR; diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 3771296d40..cfd234ad35 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1133,7 +1133,6 @@ static int vdbeCommit(sqlite3 *db){ #ifndef SQLITE_OMIT_DISKIO else{ sqlite3_vfs *pVfs = db->pVfs; - int flag = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_EXCLUSIVE); int needSync = 0; char *zMaster = 0; /* File-name for the master journal */ char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt); @@ -1152,11 +1151,12 @@ static int vdbeCommit(sqlite3 *db){ }while( sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS) ); /* Open the master journal. */ - pMaster = sqlite3_malloc(pVfs->szOsFile); - rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flag, 0); + rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, + SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| + SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL + ); if( rc!=SQLITE_OK ){ sqlite3_free(zMaster); - sqlite3_free(pMaster); return rc; } @@ -1178,10 +1178,9 @@ static int vdbeCommit(sqlite3 *db){ rc = sqlite3OsWrite(pMaster, zFile, strlen(zFile)+1, offset); offset += strlen(zFile)+1; if( rc!=SQLITE_OK ){ - sqlite3OsClose(pMaster); - sqlite3OsDelete(pVfs, zMaster); + sqlite3OsCloseFree(pMaster); + sqlite3OsDelete(pVfs, zMaster, 0); sqlite3_free(zMaster); - sqlite3_free(pMaster); return rc; } } @@ -1192,16 +1191,12 @@ static int vdbeCommit(sqlite3 *db){ ** the master journal file is store in so that it gets synced too. */ zMainFile = sqlite3BtreeGetDirname(db->aDb[0].pBt); -#if 0 - rc = sqlite3OsOpenDirectory(master, zMainFile); - if( rc!=SQLITE_OK || - (needSync && (rc=sqlite3OsSync(master,0))!=SQLITE_OK) ){ - sqlite3OsClose(&master); - sqlite3OsDelete(zMaster); + if( (needSync && (rc=sqlite3OsSync(pMaster,0))!=SQLITE_OK) ){ + sqlite3OsCloseFree(pMaster); + sqlite3OsDelete(pVfs, zMaster, 0); sqlite3_free(zMaster); return rc; } -#endif /* Sync all the db files involved in the transaction. The same call ** sets the master journal pointer in each individual journal. If @@ -1219,10 +1214,9 @@ static int vdbeCommit(sqlite3 *db){ rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster); } } - sqlite3OsClose(pMaster); + sqlite3OsCloseFree(pMaster); if( rc!=SQLITE_OK ){ sqlite3_free(zMaster); - sqlite3_free(pMaster); return rc; } @@ -1230,27 +1224,12 @@ static int vdbeCommit(sqlite3 *db){ ** doing this the directory is synced again before any individual ** transaction files are deleted. */ - rc = sqlite3OsDelete(pVfs, zMaster); + rc = sqlite3OsDelete(pVfs, zMaster, 1); sqlite3_free(zMaster); - sqlite3_free(pMaster); zMaster = 0; - pMaster = 0; if( rc ){ return rc; } -#if 0 - rc = sqlite3OsSyncDirectory(zMainFile); -#endif - if( rc!=SQLITE_OK ){ - /* This is not good. The master journal file has been deleted, but - ** the directory sync failed. There is no completely safe course of - ** action from here. The individual journals contain the name of the - ** master journal file, but there is no way of knowing if that - ** master journal exists now or if it will exist after the operating - ** system crash that may follow the fsync() failure. - */ - return rc; - } /* All files and directories have already been synced, so the following ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and diff --git a/test/bigfile.test b/test/bigfile.test index c3ea633f1b..20ace5c92a 100644 --- a/test/bigfile.test +++ b/test/bigfile.test @@ -12,7 +12,7 @@ # focus of this script testing the ability of SQLite to handle database # files larger than 4GB. # -# $Id: bigfile.test,v 1.9 2005/11/25 09:01:24 danielk1977 Exp $ +# $Id: bigfile.test,v 1.10 2007/08/18 10:59:21 danielk1977 Exp $ # set testdir [file dirname $argv0] @@ -64,8 +64,9 @@ do_test bigfile-1.1 { # large files. So skip all of the remaining tests in this file. # db close -if {[catch {fake_big_file 4096 test.db}]} { +if {[catch {fake_big_file 4096 test.db} msg]} { puts "**** Unable to create a file larger than 4096 MB. *****" + puts "$msg" finish_test return }