summaryrefslogtreecommitdiff
path: root/src/test_vfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test_vfs.c')
-rw-r--r--src/test_vfs.c110
1 files changed, 85 insertions, 25 deletions
diff --git a/src/test_vfs.c b/src/test_vfs.c
index fcd5774..7ee2a93 100644
--- a/src/test_vfs.c
+++ b/src/test_vfs.c
@@ -28,6 +28,7 @@
#include "sqlite3.h"
#include "sqliteInt.h"
+#include <tcl.h>
typedef struct Testvfs Testvfs;
typedef struct TestvfsShm TestvfsShm;
@@ -126,8 +127,10 @@ struct Testvfs {
#define TESTVFS_FULLPATHNAME_MASK 0x00008000
#define TESTVFS_READ_MASK 0x00010000
#define TESTVFS_UNLOCK_MASK 0x00020000
+#define TESTVFS_LOCK_MASK 0x00040000
+#define TESTVFS_CKLOCK_MASK 0x00080000
-#define TESTVFS_ALL_MASK 0x0003FFFF
+#define TESTVFS_ALL_MASK 0x000FFFFF
#define TESTVFS_MAX_PAGES 1024
@@ -190,8 +193,11 @@ static int tvfsShmMap(sqlite3_file*,int,int,int, void volatile **);
static void tvfsShmBarrier(sqlite3_file*);
static int tvfsShmUnmap(sqlite3_file*, int);
+static int tvfsFetch(sqlite3_file*, sqlite3_int64, int, void**);
+static int tvfsUnfetch(sqlite3_file*, sqlite3_int64, void*);
+
static sqlite3_io_methods tvfs_io_methods = {
- 2, /* iVersion */
+ 3, /* iVersion */
tvfsClose, /* xClose */
tvfsRead, /* xRead */
tvfsWrite, /* xWrite */
@@ -207,7 +213,9 @@ static sqlite3_io_methods tvfs_io_methods = {
tvfsShmMap, /* xShmMap */
tvfsShmLock, /* xShmLock */
tvfsShmBarrier, /* xShmBarrier */
- tvfsShmUnmap /* xShmUnmap */
+ tvfsShmUnmap, /* xShmUnmap */
+ tvfsFetch,
+ tvfsUnfetch
};
static int tvfsResultCode(Testvfs *p, int *pRc){
@@ -460,8 +468,15 @@ static int tvfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
** Lock an tvfs-file.
*/
static int tvfsLock(sqlite3_file *pFile, int eLock){
- TestvfsFd *p = tvfsGetFd(pFile);
- return sqlite3OsLock(p->pReal, eLock);
+ TestvfsFd *pFd = tvfsGetFd(pFile);
+ Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
+ if( p->pScript && p->mask&TESTVFS_LOCK_MASK ){
+ char zLock[30];
+ sqlite3_snprintf(sizeof(zLock),zLock,"%d",eLock);
+ tvfsExecTcl(p, "xLock", Tcl_NewStringObj(pFd->zFilename, -1),
+ Tcl_NewStringObj(zLock, -1), 0, 0);
+ }
+ return sqlite3OsLock(pFd->pReal, eLock);
}
/*
@@ -470,6 +485,12 @@ static int tvfsLock(sqlite3_file *pFile, int eLock){
static int tvfsUnlock(sqlite3_file *pFile, int eLock){
TestvfsFd *pFd = tvfsGetFd(pFile);
Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
+ if( p->pScript && p->mask&TESTVFS_UNLOCK_MASK ){
+ char zLock[30];
+ sqlite3_snprintf(sizeof(zLock),zLock,"%d",eLock);
+ tvfsExecTcl(p, "xUnlock", Tcl_NewStringObj(pFd->zFilename, -1),
+ Tcl_NewStringObj(zLock, -1), 0, 0);
+ }
if( p->mask&TESTVFS_WRITE_MASK && tvfsInjectIoerr(p) ){
return SQLITE_IOERR_UNLOCK;
}
@@ -480,8 +501,13 @@ static int tvfsUnlock(sqlite3_file *pFile, int eLock){
** Check if another file-handle holds a RESERVED lock on an tvfs-file.
*/
static int tvfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
- TestvfsFd *p = tvfsGetFd(pFile);
- return sqlite3OsCheckReservedLock(p->pReal, pResOut);
+ TestvfsFd *pFd = tvfsGetFd(pFile);
+ Testvfs *p = (Testvfs *)pFd->pVfs->pAppData;
+ if( p->pScript && p->mask&TESTVFS_CKLOCK_MASK ){
+ tvfsExecTcl(p, "xCheckReservedLock", Tcl_NewStringObj(pFd->zFilename, -1),
+ 0, 0, 0);
+ }
+ return sqlite3OsCheckReservedLock(pFd->pReal, pResOut);
}
/*
@@ -618,7 +644,10 @@ static int tvfsOpen(
pMethods = (sqlite3_io_methods *)ckalloc(nByte);
memcpy(pMethods, &tvfs_io_methods, nByte);
- pMethods->iVersion = pVfs->iVersion;
+ pMethods->iVersion = pFd->pReal->pMethods->iVersion;
+ if( pMethods->iVersion>pVfs->iVersion ){
+ pMethods->iVersion = pVfs->iVersion;
+ }
if( pVfs->iVersion>1 && ((Testvfs *)pVfs->pAppData)->isNoshm ){
pMethods->xShmUnmap = 0;
pMethods->xShmLock = 0;
@@ -993,6 +1022,21 @@ static int tvfsShmUnmap(
return rc;
}
+static int tvfsFetch(
+ sqlite3_file *pFile,
+ sqlite3_int64 iOfst,
+ int iAmt,
+ void **pp
+){
+ TestvfsFd *pFd = tvfsGetFd(pFile);
+ return sqlite3OsFetch(pFd->pReal, iOfst, iAmt, pp);
+}
+
+static int tvfsUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *p){
+ TestvfsFd *pFd = tvfsGetFd(pFile);
+ return sqlite3OsUnfetch(pFd->pReal, iOfst, p);
+}
+
static int testvfs_obj_cmd(
ClientData cd,
Tcl_Interp *interp,
@@ -1087,26 +1131,32 @@ static int testvfs_obj_cmd(
break;
}
+ /* TESTVFS filter METHOD-LIST
+ **
+ ** Activate special processing for those methods contained in the list
+ */
case CMD_FILTER: {
static struct VfsMethod {
char *zName;
int mask;
} vfsmethod [] = {
- { "xShmOpen", TESTVFS_SHMOPEN_MASK },
- { "xShmLock", TESTVFS_SHMLOCK_MASK },
- { "xShmBarrier", TESTVFS_SHMBARRIER_MASK },
- { "xShmUnmap", TESTVFS_SHMCLOSE_MASK },
- { "xShmMap", TESTVFS_SHMMAP_MASK },
- { "xSync", TESTVFS_SYNC_MASK },
- { "xDelete", TESTVFS_DELETE_MASK },
- { "xWrite", TESTVFS_WRITE_MASK },
- { "xRead", TESTVFS_READ_MASK },
- { "xTruncate", TESTVFS_TRUNCATE_MASK },
- { "xOpen", TESTVFS_OPEN_MASK },
- { "xClose", TESTVFS_CLOSE_MASK },
- { "xAccess", TESTVFS_ACCESS_MASK },
- { "xFullPathname", TESTVFS_FULLPATHNAME_MASK },
- { "xUnlock", TESTVFS_UNLOCK_MASK },
+ { "xShmOpen", TESTVFS_SHMOPEN_MASK },
+ { "xShmLock", TESTVFS_SHMLOCK_MASK },
+ { "xShmBarrier", TESTVFS_SHMBARRIER_MASK },
+ { "xShmUnmap", TESTVFS_SHMCLOSE_MASK },
+ { "xShmMap", TESTVFS_SHMMAP_MASK },
+ { "xSync", TESTVFS_SYNC_MASK },
+ { "xDelete", TESTVFS_DELETE_MASK },
+ { "xWrite", TESTVFS_WRITE_MASK },
+ { "xRead", TESTVFS_READ_MASK },
+ { "xTruncate", TESTVFS_TRUNCATE_MASK },
+ { "xOpen", TESTVFS_OPEN_MASK },
+ { "xClose", TESTVFS_CLOSE_MASK },
+ { "xAccess", TESTVFS_ACCESS_MASK },
+ { "xFullPathname", TESTVFS_FULLPATHNAME_MASK },
+ { "xUnlock", TESTVFS_UNLOCK_MASK },
+ { "xLock", TESTVFS_LOCK_MASK },
+ { "xCheckReservedLock", TESTVFS_CKLOCK_MASK },
};
Tcl_Obj **apElem = 0;
int nElem = 0;
@@ -1138,6 +1188,12 @@ static int testvfs_obj_cmd(
break;
}
+ /*
+ ** TESTVFS script ?SCRIPT?
+ **
+ ** Query or set the script to be run when filtered VFS events
+ ** occur.
+ */
case CMD_SCRIPT: {
if( objc==3 ){
int nByte;
@@ -1224,6 +1280,7 @@ static int testvfs_obj_cmd(
{ "safe_append", SQLITE_IOCAP_SAFE_APPEND },
{ "undeletable_when_open", SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN },
{ "powersafe_overwrite", SQLITE_IOCAP_POWERSAFE_OVERWRITE },
+ { "immutable", SQLITE_IOCAP_IMMUTABLE },
{ 0, 0 }
};
Tcl_Obj *pRet;
@@ -1343,7 +1400,7 @@ static int testvfs_cmd(
Tcl_Obj *CONST objv[]
){
static sqlite3_vfs tvfs_vfs = {
- 2, /* iVersion */
+ 3, /* iVersion */
0, /* szOsFile */
0, /* mxPathname */
0, /* pNext */
@@ -1369,6 +1426,9 @@ static int testvfs_cmd(
tvfsCurrentTime, /* xCurrentTime */
0, /* xGetLastError */
0, /* xCurrentTimeInt64 */
+ 0, /* xSetSystemCall */
+ 0, /* xGetSystemCall */
+ 0, /* xNextSystemCall */
};
Testvfs *p; /* New object */
@@ -1382,7 +1442,7 @@ static int testvfs_cmd(
int isDefault = 0; /* True if -default is passed */
int szOsFile = 0; /* Value passed to -szosfile */
int mxPathname = -1; /* Value passed to -mxpathname */
- int iVersion = 2; /* Value passed to -iversion */
+ int iVersion = 3; /* Value passed to -iversion */
if( objc<2 || 0!=(objc%2) ) goto bad_args;
for(i=2; i<objc; i += 2){