-C Enable\sconstant\sexpression\sfactoring\seven\sif\sno\stables\sare\sread\sand\sno\ntransaction\sis\sstarted.
-D 2014-02-08T04:24:37.181
+C Experimental\schange\sto\sos_unix.c\sto\sdelay\screating\sa\sdatabase\sfile\suntil\sit\sis\sfirst\swritten.
+D 2014-02-10T19:37:03.413
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
-F src/os_unix.c 18f7f95dc6bcb9cf4d4a238d8e2de96611bc2ae5
+F src/os_unix.c dcb7dd4fb2ef823b534383bb7e58efdf8cb7d582
F src/os_win.c d4284f003445054a26689f1264b1b9bf7261bd1b
F src/pager.c efa923693e958696eee69b205a20bfbc402c8480
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c 649d373f2a3cfbefe8e935a8dec83686616f9a85
F src/test1.c 2401eee14a4309a7cfe2aeb2f30ad517a1d9c299
-F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
+F src/test2.c 0f8bd858c127fd5236dd965d534622422fbe0b2f
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
F src/test5.c a6d1ac55ac054d0b2b8f37b5e655b6c92645a013
F test/pcache.test b09104b03160aca0d968d99e8cd2c5b1921a993d
F test/pcache2.test a83efe2dec0d392f814bfc998def1d1833942025
F test/percentile.test b98fc868d71eb5619d42a1702e9ab91718cbed54
-F test/permutations.test 40add071ba71aefe1c04f5845308cf46f7de8d04
+F test/permutations.test 64771d6c1cbe270acb788dfdc32ede157a627583
F test/pragma.test e882183ecd21d064cec5c7aaea174fbd36293429
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 192dea97316144f15f6dd0eabff08a0bf9ef203e
-R e90c019788474c8101c0d70d2228b12b
-U drh
-Z 46adb7aa7b0c0d2f1d0d873b94d6c7bb
+P a45b87713c0afca2be2ace9500513620a024c0a2
+R 116d1a6917169d2dbbd8194f87400b30
+T *branch * deferred-open
+T *sym-deferred-open *
+T -sym-trunk *
+U dan
+Z 79711705a6aa2396617bcc4018494171
int sectorSize; /* Device sector size */
int deviceCharacteristics; /* Precomputed device characteristics */
#endif
-#if SQLITE_ENABLE_LOCKING_STYLE
int openFlags; /* The flags specified at open() */
-#endif
#if SQLITE_ENABLE_LOCKING_STYLE || defined(__APPLE__)
unsigned fsFlags; /* cached details from statfs() */
#endif
#define UNIXFILE_DELETE 0x20 /* Delete on close */
#define UNIXFILE_URI 0x40 /* Filename might have query parameters */
#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */
-#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings have been issued */
+#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() has issued warnings */
+#define UNIXFILE_DEFERRED 0x0200 /* File has not yet been opened */
/*
** Include code that is common to all os_*.c files
int reserved = 0;
unixFile *pFile = (unixFile*)id;
+ assert( pFile );
SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
- assert( pFile );
+ if( pFile->ctrlFlags==UNIXFILE_DEFERRED ){
+ *pResOut = 0;
+ return SQLITE_OK;
+ }
+
unixEnterMutex(); /* Because pFile->pInode is shared across threads */
/* Check if a thread in this process holds such a lock */
return rc;
}
+static int unixOpen(sqlite3_vfs*, const char*, sqlite3_file*, int, int *);
+
/*
** Lock the file with the lock specified by parameter eFileLock - one
** of the following:
return SQLITE_OK;
}
+ if( pFile->ctrlFlags==UNIXFILE_DEFERRED ){
+ int eOrigLock = pFile->eFileLock;
+ if( eFileLock==SHARED_LOCK ){
+ int statrc;
+ struct stat sBuf;
+ memset(&sBuf, 0, sizeof(sBuf));
+ statrc = osStat(pFile->zPath, &sBuf);
+ if( statrc && errno==ENOENT ){
+ pFile->eFileLock = SHARED_LOCK;
+ return SQLITE_OK;
+ }
+ }
+
+ rc = unixOpen(pFile->pVfs, pFile->zPath, id, pFile->openFlags, 0);
+ if( rc==SQLITE_OK && eOrigLock ){
+ rc = unixLock(id, eOrigLock);
+ }
+ if( rc!=SQLITE_OK ) return rc;
+ }
+ assert( (pFile->ctrlFlags & UNIXFILE_DEFERRED)==0 );
+
/* Make sure the locking sequence is correct.
** (1) We never move from unlocked to anything higher than shared lock.
** (2) SQLite never explicitly requests a pendig lock.
return SQLITE_OK;
}
unixEnterMutex();
+ if( pFile->ctrlFlags==UNIXFILE_DEFERRED ) goto end_unlock;
pInode = pFile->pInode;
assert( pInode->nShared!=0 );
if( pFile->eFileLock>SHARED_LOCK ){
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);
+ ** routine (e.g. nolockClose()) would be called instead. */
+ assert( pFile->pInode==0
+ || pFile->pInode->nLock>0
+ || pFile->pInode->bProcessLock==0
+ );
+ if( pFile->pInode ){
+ if( 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);
}
- releaseInodeInfo(pFile);
rc = closeUnixFile(id);
unixLeaveMutex();
return rc;
);
#endif
+ if( pFile->ctrlFlags==UNIXFILE_DEFERRED ){
+ int rc;
+ struct stat sBuf;
+ memset(&sBuf, 0, sizeof(sBuf));
+ rc = osStat(pFile->zPath, &sBuf);
+ if( rc!=0 ){
+ memset(pBuf, 0, amt);
+ rc = (errno==ENOENT ? SQLITE_IOERR_SHORT_READ : SQLITE_IOERR_FSTAT);
+ }else{
+ rc = unixOpen(pFile->pVfs, pFile->zPath, id, pFile->openFlags, 0);
+ }
+ if( rc!=SQLITE_OK ){
+ return rc;
+ }
+ }
+ assert( (pFile->ctrlFlags & UNIXFILE_DEFERRED)==0 );
+
#if SQLITE_MAX_MMAP_SIZE>0
/* Deal with as much of this read request as possible by transfering
** data from the memory mapping using memcpy(). */
** Determine the current size of a file in bytes
*/
static int unixFileSize(sqlite3_file *id, i64 *pSize){
+ unixFile *pFile = (unixFile*)id;
int rc;
struct stat buf;
assert( id );
- rc = osFstat(((unixFile*)id)->h, &buf);
+ if( pFile->ctrlFlags==UNIXFILE_DEFERRED ){
+ rc = osStat(pFile->zPath, &buf);
+ if( rc && errno==ENOENT ){
+ rc = 0;
+ buf.st_size = 0;
+ }
+ }else{
+ rc = osFstat(pFile->h, &buf);
+ }
SimulateIOError( rc=1 );
if( rc!=0 ){
((unixFile*)id)->lastErrno = errno;
*/
if( *pSize==1 ) *pSize = 0;
-
return SQLITE_OK;
}
pNew->h = h;
pNew->pVfs = pVfs;
pNew->zPath = zFilename;
- pNew->ctrlFlags = (u8)ctrlFlags;
+ pNew->ctrlFlags = (unsigned short)ctrlFlags;
#if SQLITE_MAX_MMAP_SIZE>0
pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap;
#endif
return rc;
}
+static int unixOpenDeferred(
+ sqlite3_vfs *pVfs, /* The VFS for which this is the xOpen method */
+ const char *zPath, /* Pathname of file to be opened */
+ sqlite3_file *pFile, /* The file descriptor to be filled in */
+ int flags, /* Input flags to control the opening */
+ int *pOutFlags /* Output flags returned to SQLite core */
+){
+ const int mask1 = SQLITE_OPEN_MAIN_DB | SQLITE_OPEN_READWRITE
+ | SQLITE_OPEN_CREATE;
+ const int mask2 = SQLITE_OPEN_READONLY | SQLITE_OPEN_DELETEONCLOSE
+ | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_AUTOPROXY;
+ int rc = SQLITE_OK; /* Return code */
+
+ /* If all the flags in mask1 are set, and all the flags in mask2 are
+ ** clear, then this will be a deferred open. */
+ if( zPath && (flags & (mask1 | mask2))==mask1 ){
+ unixFile *p = (unixFile*)pFile;
+ memset(p, 0, sizeof(unixFile));
+
+ p->pMethod = (**(finder_type*)pVfs->pAppData)(0, 0);
+ p->pVfs = pVfs;
+ p->h = -1;
+ p->ctrlFlags = UNIXFILE_DEFERRED;
+ p->openFlags = flags;
+ p->zPath = zPath;
+ if( pOutFlags ) *pOutFlags = flags;
+ }else{
+ rc = unixOpen(pVfs, zPath, pFile, flags, pOutFlags);
+ }
+ return rc;
+}
/*
** Delete the file at zPath. If the dirSync argument is true, fsync()
0, /* pNext */ \
VFSNAME, /* zName */ \
(void*)&FINDER, /* pAppData */ \
- unixOpen, /* xOpen */ \
+ unixOpenDeferred, /* xOpen */ \
unixDelete, /* xDelete */ \
unixAccess, /* xAccess */ \
unixFullPathname, /* xFullPathname */ \