Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add the ability to enable or disable SQLITE_IOCAP_ZERO_DAMAGE using a URI parameter for both unix and windows. Add a file-control to query or disable the ZERO_DAMAGE setting. Add the -uri option to the "sqlite3" TCL command in tclsqlite3.c. Allow the sqlite3_uri_parameter() interface to accept a NULL pointer for its first parameter. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | statvfs |
Files: | files | file ages | folders |
SHA1: |
c83627b73285f883719845c1b9fe85f3 |
User & Date: | drh 2011-12-21 14:42:29.520 |
Context
2011-12-22
| ||
01:46 | Remove a redundant assignment operator. (check-in: 19a6852a1e user: drh tags: statvfs) | |
2011-12-21
| ||
14:42 | Add the ability to enable or disable SQLITE_IOCAP_ZERO_DAMAGE using a URI parameter for both unix and windows. Add a file-control to query or disable the ZERO_DAMAGE setting. Add the -uri option to the "sqlite3" TCL command in tclsqlite3.c. Allow the sqlite3_uri_parameter() interface to accept a NULL pointer for its first parameter. (check-in: c83627b732 user: drh tags: statvfs) | |
2011-12-20
| ||
22:18 | Remove the code that tries to detect OOO header writes on a WAL recovery. The code is made obsolete by syncing the WAL header. (check-in: 7ac713a14e user: drh tags: statvfs) | |
Changes
Changes to src/main.c.
︙ | ︙ | |||
2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 | ** The zFilename argument is the filename pointer passed into the xOpen() ** method of a VFS implementation. The zParam argument is the name of the ** query parameter we seek. This routine returns the value of the zParam ** parameter if it exists. If the parameter does not exist, this routine ** returns a NULL pointer. */ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ zFilename += sqlite3Strlen30(zFilename) + 1; while( zFilename[0] ){ int x = strcmp(zFilename, zParam); zFilename += sqlite3Strlen30(zFilename) + 1; if( x==0 ) return zFilename; zFilename += sqlite3Strlen30(zFilename) + 1; } | > | 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 | ** The zFilename argument is the filename pointer passed into the xOpen() ** method of a VFS implementation. The zParam argument is the name of the ** query parameter we seek. This routine returns the value of the zParam ** parameter if it exists. If the parameter does not exist, this routine ** returns a NULL pointer. */ const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ if( zFilename==0 ) return 0; zFilename += sqlite3Strlen30(zFilename) + 1; while( zFilename[0] ){ int x = strcmp(zFilename, zParam); zFilename += sqlite3Strlen30(zFilename) + 1; if( x==0 ) return zFilename; zFilename += sqlite3Strlen30(zFilename) + 1; } |
︙ | ︙ |
Changes to src/os_unix.c.
︙ | ︙ | |||
211 212 213 214 215 216 217 218 219 220 221 222 223 | struct unixFile { sqlite3_io_methods const *pMethod; /* Always the first entry */ sqlite3_vfs *pVfs; /* The VFS that created this unixFile */ unixInodeInfo *pInode; /* Info about locks on this inode */ int h; /* The file descriptor */ unsigned char eFileLock; /* The type of lock held on this fd */ unsigned char ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ | > < | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | struct unixFile { sqlite3_io_methods const *pMethod; /* Always the first entry */ sqlite3_vfs *pVfs; /* The VFS that created this unixFile */ unixInodeInfo *pInode; /* Info about locks on this inode */ int h; /* The file descriptor */ unsigned char eFileLock; /* The type of lock held on this fd */ unsigned char ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ unsigned char szSector; /* Sectorsize/512 */ int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ #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 #if OS_VXWORKS |
︙ | ︙ | |||
259 260 261 262 263 264 265 266 267 268 269 270 271 272 | #define UNIXFILE_RDONLY 0x02 /* Connection is read only */ #define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ #ifndef SQLITE_DISABLE_DIRSYNC # define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ #else # define UNIXFILE_DIRSYNC 0x00 #endif /* ** Include code that is common to all os_*.c files */ #include "os_common.h" /* | > | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 | #define UNIXFILE_RDONLY 0x02 /* Connection is read only */ #define UNIXFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ #ifndef SQLITE_DISABLE_DIRSYNC # define UNIXFILE_DIRSYNC 0x08 /* Directory sync needed */ #else # define UNIXFILE_DIRSYNC 0x00 #endif #define UNIXFILE_ZERO_DAMAGE 0x10 /* True if SQLITE_IOCAP_ZERO_DAMAGE */ /* ** Include code that is common to all os_*.c files */ #include "os_common.h" /* |
︙ | ︙ | |||
3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 | } #endif } } return SQLITE_OK; } /* ** Information and control of an open file handle. */ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ unixFile *pFile = (unixFile*)id; switch( op ){ | > > > > > > > > > > > > > > > > | 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 | } #endif } } return SQLITE_OK; } /* ** 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. ** ** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. */ static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ if( *pArg<0 ){ *pArg = (pFile->ctrlFlags & mask)!=0; }else if( (*pArg)==0 ){ pFile->ctrlFlags &= ~mask; }else{ pFile->ctrlFlags |= mask; } } /* ** Information and control of an open file handle. */ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ unixFile *pFile = (unixFile*)id; switch( op ){ |
︙ | ︙ | |||
3533 3534 3535 3536 3537 3538 3539 | int rc; SimulateIOErrorBenign(1); rc = fcntlSizeHint(pFile, *(i64 *)pArg); SimulateIOErrorBenign(0); return rc; } case SQLITE_FCNTL_PERSIST_WAL: { | < < < < < < | > | > > | 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 | int rc; SimulateIOErrorBenign(1); rc = fcntlSizeHint(pFile, *(i64 *)pArg); SimulateIOErrorBenign(0); return rc; } case SQLITE_FCNTL_PERSIST_WAL: { unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg); return SQLITE_OK; } case SQLITE_FCNTL_ZERO_DAMAGE: { unixModeBit(pFile, UNIXFILE_ZERO_DAMAGE, (int*)pArg); return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); return SQLITE_OK; } #ifndef NDEBUG |
︙ | ︙ | |||
3585 3586 3587 3588 3589 3590 3591 | ** a database and its journal file) that the sector size will be the ** same for both. */ static int unixSectorSize(sqlite3_file *pFile){ unixFile *p = (unixFile*)pFile; if( p->szSector==0 ){ #ifdef MISSING_STATVFS | | | | > | | > > > > > > > > > | < > | | 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 | ** a database and its journal file) that the sector size will be the ** same for both. */ static int unixSectorSize(sqlite3_file *pFile){ unixFile *p = (unixFile*)pFile; if( p->szSector==0 ){ #ifdef MISSING_STATVFS p->szSector = SQLITE_DEFAULT_SECTOR_SIZE/512; #else struct statvfs x; int sz; memset(&x, 0, sizeof(x)); osStatvfs(p->zPath, &x); sz = (int)x.f_frsize; if( sz<512 || sz>65536 || (sz&(sz-1))!=0 ){ sz = SQLITE_DEFAULT_SECTOR_SIZE; } p->szSector = sz/512; #endif } return p->szSector*512; } /* ** Return the device characteristics for the file. ** ** This VFS is set up to return SQLITE_IOCAP_ZERO_DAMAGE by default. ** However, that choice is contraversial sicne technically the underlying ** file system does not always provide ZERO_DAMAGE. (In other words, after ** a power-loss event, parts of the file that were never written might end ** up being altered.) However, non-ZERO-DAMAGE behavior is very, very rare. ** And asserting ZERO_DAMAGE makes a large reduction in the amount of required ** I/O. Hence, while ZERO_DAMAGE is on by default, there is a file-control ** available to turn it off. */ static int unixDeviceCharacteristics(sqlite3_file *id){ unixFile *p = (unixFile*)id; return (p->ctrlFlags & UNIXFILE_ZERO_DAMAGE) ? SQLITE_IOCAP_ZERO_DAMAGE : 0; } #ifndef SQLITE_OMIT_WAL /* ** Object used to represent an shared memory buffer. |
︙ | ︙ | |||
4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 | int noLock, /* Omit locking if true */ int isDelete, /* Delete on close if true */ int isReadOnly /* True if the file is opened read-only */ ){ const sqlite3_io_methods *pLockingStyle; unixFile *pNew = (unixFile *)pId; int rc = SQLITE_OK; assert( pNew->pInode==NULL ); /* Parameter isDelete is only used on vxworks. Express this explicitly ** here to prevent compiler warnings about unused parameters. */ UNUSED_PARAMETER(isDelete); | > | 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 | int noLock, /* Omit locking if true */ int isDelete, /* Delete on close if true */ int isReadOnly /* True if the file is opened read-only */ ){ const sqlite3_io_methods *pLockingStyle; unixFile *pNew = (unixFile *)pId; int rc = SQLITE_OK; const char *zZeroDam; /* Value of the zero_damage query parameter */ assert( pNew->pInode==NULL ); /* Parameter isDelete is only used on vxworks. Express this explicitly ** here to prevent compiler warnings about unused parameters. */ UNUSED_PARAMETER(isDelete); |
︙ | ︙ | |||
4590 4591 4592 4593 4594 4595 4596 4597 | /* No locking occurs in temporary files */ assert( zFilename!=0 || noLock ); OSTRACE(("OPEN %-3d %s\n", h, zFilename)); pNew->h = h; pNew->pVfs = pVfs; pNew->zPath = zFilename; if( memcmp(pVfs->zName,"unix-excl",10)==0 ){ | > > > < < | | 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 | /* No locking occurs in temporary files */ assert( zFilename!=0 || noLock ); OSTRACE(("OPEN %-3d %s\n", h, zFilename)); pNew->h = h; pNew->pVfs = pVfs; pNew->zPath = zFilename; zZeroDam = sqlite3_uri_parameter(zFilename, "zero_damage"); if( zZeroDam==0 ) zZeroDam = "1"; pNew->ctrlFlags = atoi(zZeroDam) ? UNIXFILE_ZERO_DAMAGE : 1; if( memcmp(pVfs->zName,"unix-excl",10)==0 ){ pNew->ctrlFlags |= UNIXFILE_EXCL; } if( isReadOnly ){ pNew->ctrlFlags |= UNIXFILE_RDONLY; } if( syncDir ){ pNew->ctrlFlags |= UNIXFILE_DIRSYNC; } |
︙ | ︙ |
Changes to src/os_win.c.
︙ | ︙ | |||
55 56 57 58 59 60 61 | typedef struct winFile winFile; struct winFile { const sqlite3_io_methods *pMethod; /*** Must be first ***/ sqlite3_vfs *pVfs; /* The VFS used to open this file */ HANDLE h; /* Handle for accessing the file */ u8 locktype; /* Type of lock currently held on this file */ short sharedLockByte; /* Randomly chosen byte used as a shared lock */ | | > > > > > > | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | typedef struct winFile winFile; struct winFile { const sqlite3_io_methods *pMethod; /*** Must be first ***/ sqlite3_vfs *pVfs; /* The VFS used to open this file */ HANDLE h; /* Handle for accessing the file */ u8 locktype; /* Type of lock currently held on this file */ short sharedLockByte; /* Randomly chosen byte used as a shared lock */ u8 ctrlFlags; /* Flags. See WINFILE_* below */ DWORD lastErrno; /* The Windows errno from the last I/O error */ DWORD sectorSize; /* Sector size of the device file is on */ winShm *pShm; /* Instance of shared memory on this file */ const char *zPath; /* Full pathname of this file */ int szChunk; /* Chunk size configured by FCNTL_CHUNK_SIZE */ #if SQLITE_OS_WINCE LPWSTR zDeleteOnClose; /* Name of file to delete when closing */ HANDLE hMutex; /* Mutex used to control access to shared lock */ HANDLE hShared; /* Shared memory segment used for locking */ winceLock local; /* Locks obtained by this instance of winFile */ winceLock *shared; /* Global shared lock memory for the file */ #endif }; /* ** Allowed values for winFile.ctrlFlags */ #define WINFILE_PERSIST_WAL 0x04 /* Persistent WAL mode */ #define WINFILE_ZERO_DAMAGE 0x10 /* True if SQLITE_IOCAP_ZERO_DAMAGE */ /* * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the * various Win32 API heap functions instead of our own. */ #ifdef SQLITE_WIN32_MALLOC /* * The initial size of the Win32-specific heap. This value may be zero. |
︙ | ︙ | |||
2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 | } if( type>=PENDING_LOCK ){ osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); } pFile->locktype = (u8)locktype; return rc; } /* ** Control and query of the open file handle. */ static int winFileControl(sqlite3_file *id, int op, void *pArg){ winFile *pFile = (winFile*)id; switch( op ){ | > > > > > > > > > > > > > > > > | 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 | } if( type>=PENDING_LOCK ){ osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); } pFile->locktype = (u8)locktype; return rc; } /* ** 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. ** ** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags. */ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ if( *pArg<0 ){ *pArg = (pFile->ctrlFlags & mask)!=0; }else if( (*pArg)==0 ){ pFile->ctrlFlags &= ~mask; }else{ pFile->ctrlFlags |= mask; } } /* ** Control and query of the open file handle. */ static int winFileControl(sqlite3_file *id, int op, void *pArg){ winFile *pFile = (winFile*)id; switch( op ){ |
︙ | ︙ | |||
2156 2157 2158 2159 2160 2161 2162 | } } return rc; } return SQLITE_OK; } case SQLITE_FCNTL_PERSIST_WAL: { | < < | < < > | > > | 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 | } } return rc; } return SQLITE_OK; } case SQLITE_FCNTL_PERSIST_WAL: { winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); return SQLITE_OK; } case SQLITE_FCNTL_ZERO_DAMAGE: { winModeBit(pFile, WINFILE_ZERO_DAMAGE, (int*)pArg); return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { *(char**)pArg = sqlite3_mprintf("win32"); return SQLITE_OK; } case SQLITE_FCNTL_SYNC_OMITTED: { |
︙ | ︙ | |||
2208 2209 2210 2211 2212 2213 2214 | return (int)(((winFile*)id)->sectorSize); } /* ** Return a vector of device characteristics. */ static int winDeviceCharacteristics(sqlite3_file *id){ | | | | 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 | return (int)(((winFile*)id)->sectorSize); } /* ** Return a vector of device characteristics. */ static int winDeviceCharacteristics(sqlite3_file *id){ winFile *p = (winFile*)id; return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | ((p->ctrlFlags & WINFILE_ZERO_DAMAGE)?SQLITE_IOCAP_ZERO_DAMAGE:0); } #ifndef SQLITE_OMIT_WAL /* ** Windows will only let you create file view mappings ** on allocation size granularity boundaries. |
︙ | ︙ | |||
3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 | #if SQLITE_OS_WINCE int isTemp = 0; #endif winFile *pFile = (winFile*)id; void *zConverted; /* Filename in OS encoding */ const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ int cnt = 0; /* If argument zPath is a NULL pointer, this function is required to open ** a temporary file. Use this buffer to store the file name in. */ char zTmpname[MAX_PATH+1]; /* Buffer used to create temp filename */ int rc = SQLITE_OK; /* Function Return Code */ | > | 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 | #if SQLITE_OS_WINCE int isTemp = 0; #endif winFile *pFile = (winFile*)id; void *zConverted; /* Filename in OS encoding */ const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */ int cnt = 0; const char *zZeroDam; /* Value of zero_damage query parameter */ /* If argument zPath is a NULL pointer, this function is required to open ** a temporary file. Use this buffer to store the file name in. */ char zTmpname[MAX_PATH+1]; /* Buffer used to create temp filename */ int rc = SQLITE_OK; /* Function Return Code */ |
︙ | ︙ | |||
3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 | memset(pFile, 0, sizeof(*pFile)); pFile->pMethod = &winIoMethod; pFile->h = h; pFile->lastErrno = NO_ERROR; pFile->pVfs = pVfs; pFile->pShm = 0; pFile->zPath = zName; pFile->sectorSize = getSectorSize(pVfs, zUtf8Name); #if SQLITE_OS_WINCE if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB && !winceCreateLock(zName, pFile) ){ osCloseHandle(h); | > > > | 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 | memset(pFile, 0, sizeof(*pFile)); pFile->pMethod = &winIoMethod; pFile->h = h; pFile->lastErrno = NO_ERROR; pFile->pVfs = pVfs; pFile->pShm = 0; pFile->zPath = zName; zZeroDam = sqlite3_uri_parameter(zName, "zero_damage"); if( zZeroDam==0 ) zZeroDam = "1"; pFile->ctrlFlags = atoi(zZeroDam) ? WINFILE_ZERO_DAMAGE : 1; pFile->sectorSize = getSectorSize(pVfs, zUtf8Name); #if SQLITE_OS_WINCE if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB && !winceCreateLock(zName, pFile) ){ osCloseHandle(h); |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
769 770 771 772 773 774 775 776 777 778 779 780 781 782 | ** have write permission on the directory containing the database file want ** to read the database file, as the WAL and shared memory files must exist ** in order for the database to be readable. The fourth parameter to ** [sqlite3_file_control()] for this opcode should be a pointer to an integer. ** That integer is 0 to disable persistent WAL mode or 1 to enable persistent ** WAL mode. If the integer is -1, then it is overwritten with the current ** WAL persistence setting. ** ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some ** reason, the entire database file will be overwritten by the current ** transaction. This is used by VACUUM operations. ** ** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of | > > > > > > > > > | 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 | ** have write permission on the directory containing the database file want ** to read the database file, as the WAL and shared memory files must exist ** in order for the database to be readable. The fourth parameter to ** [sqlite3_file_control()] for this opcode should be a pointer to an integer. ** That integer is 0 to disable persistent WAL mode or 1 to enable persistent ** WAL mode. If the integer is -1, then it is overwritten with the current ** WAL persistence setting. ** ** ^The [SQLITE_FCNTL_ZERO_DAMAGE] opcode is used to set or query the ** persistent zero-damage setting. The zero-damage setting determines ** the [SQLITE_IOCAP_ZERO_DAMAGE] bit of the xDeviceCharacteristics methods. ** The fourth parameter to ** [sqlite3_file_control()] for this opcode should be a pointer to an integer. ** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage ** mode. If the integer is -1, then it is overwritten with the current ** zero-damage mode setting. ** ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some ** reason, the entire database file will be overwritten by the current ** transaction. This is used by VACUUM operations. ** ** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of |
︙ | ︙ | |||
798 799 800 801 802 803 804 805 806 807 808 809 810 811 | #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 /* ** 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 | > | 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 | #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_ZERO_DAMAGE 13 /* ** 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/tclsqlite.c.
︙ | ︙ | |||
2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 | int b; if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; if( b ){ flags |= SQLITE_OPEN_FULLMUTEX; flags &= ~SQLITE_OPEN_NOMUTEX; }else{ flags &= ~SQLITE_OPEN_FULLMUTEX; } }else{ Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); return TCL_ERROR; } } if( objc<3 || (objc&1)!=1 ){ | > > > > > > > > | 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 | int b; if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; if( b ){ flags |= SQLITE_OPEN_FULLMUTEX; flags &= ~SQLITE_OPEN_NOMUTEX; }else{ flags &= ~SQLITE_OPEN_FULLMUTEX; } }else if( strcmp(zArg, "-uri")==0 ){ int b; if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR; if( b ){ flags |= SQLITE_OPEN_URI; }else{ flags &= ~SQLITE_OPEN_URI; } }else{ Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0); return TCL_ERROR; } } if( objc<3 || (objc&1)!=1 ){ |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 | if( Tcl_GetIntFromObj(interp, objv[2], &bPersist) ) return TCL_ERROR; rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_PERSIST_WAL, (void*)&bPersist); sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bPersist); Tcl_AppendResult(interp, z, (char*)0); return TCL_OK; } /* ** tclcmd: file_control_vfsname DB ?AUXDB? ** ** Return a string that describes the stack of VFSes. */ static int file_control_vfsname( | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | if( Tcl_GetIntFromObj(interp, objv[2], &bPersist) ) return TCL_ERROR; rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_PERSIST_WAL, (void*)&bPersist); sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bPersist); Tcl_AppendResult(interp, z, (char*)0); return TCL_OK; } /* ** tclcmd: file_control_zero_damage DB ZERO-DAMAGE-FLAG ** ** This TCL command runs the sqlite3_file_control interface with ** the SQLITE_FCNTL_ZERO_DAMAGE opcode. */ static int file_control_zero_damage( ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ sqlite3 *db; int rc; int bDamage; char z[100]; if( objc!=3 ){ Tcl_AppendResult(interp, "wrong # args: should be \"", Tcl_GetStringFromObj(objv[0], 0), " DB FLAG", 0); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){ return TCL_ERROR; } if( Tcl_GetIntFromObj(interp, objv[2], &bDamage) ) return TCL_ERROR; rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_ZERO_DAMAGE,(void*)&bDamage); sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bDamage); Tcl_AppendResult(interp, z, (char*)0); return TCL_OK; } /* ** tclcmd: file_control_vfsname DB ?AUXDB? ** ** Return a string that describes the stack of VFSes. */ static int file_control_vfsname( |
︙ | ︙ | |||
6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 | { "file_control_test", file_control_test, 0 }, { "file_control_lasterrno_test", file_control_lasterrno_test, 0 }, { "file_control_lockproxy_test", file_control_lockproxy_test, 0 }, { "file_control_chunksize_test", file_control_chunksize_test, 0 }, { "file_control_sizehint_test", file_control_sizehint_test, 0 }, { "file_control_win32_av_retry", file_control_win32_av_retry, 0 }, { "file_control_persist_wal", file_control_persist_wal, 0 }, { "file_control_vfsname", file_control_vfsname, 0 }, { "sqlite3_vfs_list", vfs_list, 0 }, { "sqlite3_create_function_v2", test_create_function_v2, 0 }, /* Functions from os.h */ #ifndef SQLITE_OMIT_UTF16 { "add_test_collate", test_collate, 0 }, | > | 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 | { "file_control_test", file_control_test, 0 }, { "file_control_lasterrno_test", file_control_lasterrno_test, 0 }, { "file_control_lockproxy_test", file_control_lockproxy_test, 0 }, { "file_control_chunksize_test", file_control_chunksize_test, 0 }, { "file_control_sizehint_test", file_control_sizehint_test, 0 }, { "file_control_win32_av_retry", file_control_win32_av_retry, 0 }, { "file_control_persist_wal", file_control_persist_wal, 0 }, { "file_control_zero_damage", file_control_zero_damage, 0 }, { "file_control_vfsname", file_control_vfsname, 0 }, { "sqlite3_vfs_list", vfs_list, 0 }, { "sqlite3_create_function_v2", test_create_function_v2, 0 }, /* Functions from os.h */ #ifndef SQLITE_OMIT_UTF16 { "add_test_collate", test_collate, 0 }, |
︙ | ︙ |
Added test/zerodamage.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | # 2011 December 21 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # This file implements tests of the SQLITE_IOCAP_ZERO_DAMAGE property # and the SQLITE_FCNTL_ZERO_DAMAGE file-control for manipulating it. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix wal5 # ZERO_DAMAGE defaults to true # do_test zerodamage-1.0 { file_control_zero_damage db -1 } {0 1} # Check the ability to turn zero-damage on and off. # do_test zerodamage-1.1 { file_control_zero_damage db 0 file_control_zero_damage db -1 } {0 0} do_test zerodamage-1.2 { file_control_zero_damage db 1 file_control_zero_damage db -1 } {0 1} # Run a transaction with zero-damage on, a small page size and a much larger # sectorsize. Verify that the maximum journal size is small - that the # rollback journal is not being padded. # do_test zerodamage-2.0 { db close testvfs tv -default 1 tv sectorsize 8192 sqlite3 db file:test.db?zero_damage=1 -uri 1 unset -nocomplain ::max_journal_size set ::max_journal_size 0 proc xDeleteCallback {method file args} { set sz [file size $file] if {$sz>$::max_journal_size} {set ::max_journal_size $sz} } tv filter xDelete tv script xDeleteCallback register_wholenumber_module db db eval { PRAGMA page_size=1024; PRAGMA journal_mode=DELETE; PRAGMA cache_size=5; CREATE VIRTUAL TABLE nums USING wholenumber; CREATE TABLE t1(x, y); INSERT INTO t1 SELECT value, randomblob(100) FROM nums WHERE value BETWEEN 1 AND 400; } set ::max_journal_size 0 db eval { UPDATE t1 SET y=randomblob(50) WHERE x=123; } concat [file_control_zero_damage db -1] [set ::max_journal_size] } {0 1 2576} # Repeat the previous step with zero-damage turned off. This time the # maximum rollback journal size should be much larger. # do_test zerodamage-2.1 { set ::max_journal_size 0 db close sqlite3 db file:test.db?zero_damage=0 -uri 1 db eval { UPDATE t1 SET y=randomblob(50) WHERE x=124; } concat [file_control_zero_damage db -1] [set ::max_journal_size] } {0 0 24704} # Run a WAL-mode transaction with ZERO_DAMAGE on to verify that the # WAL file does not get too big. # do_test zerodamage-3.0 { db eval { PRAGMA journal_mode=WAL; } db close sqlite3 db file:test.db?zero_damage=1 -uri 1 db eval { UPDATE t1 SET y=randomblob(50) WHERE x=124; } file size test.db-wal } {1080} # Repeat the previous with ZERO_DAMAGE off. Verify that the WAL file # is padded. # do_test zerodamage-3.1 { db close sqlite3 db file:test.db?zero_damage=0 -uri 1 db eval { UPDATE t1 SET y=randomblob(50) WHERE x=124; } file size test.db-wal } {8416} |