** sqlite3_instvfs_get()
**
** sqlite3_instvfs_binarylog
+** sqlite3_instvfs_binarylog_marker
**
** Tcl interface (omitted if SQLITE_TEST is not set):
**
#define OS_NUMEVENTS 21
+#define BINARYLOG_STRING 30
+#define BINARYLOG_MARKER 31
+
struct InstVfs {
sqlite3_vfs base;
sqlite3_vfs *pVfs;
-
+
void *pClient;
void (*xDel)(void *);
- void (*xCall)(void *, int, sqlite3_int64, const char *, int, int, sqlite3_int64);
+ void (*xCall)(void *, int, int, sqlite3_int64, int, const char *, int, int, sqlite3_int64);
/* Counters */
sqlite3_int64 aTime[OS_NUMEVENTS];
int aCount[OS_NUMEVENTS];
+
+ int iNextFileId;
};
typedef struct InstVfs InstVfs;
sqlite3_file *pReal;
InstVfs *pInstVfs;
const char *zName;
+ int iFileId; /* File id number */
int flags;
};
static int instSleep(sqlite3_vfs*, int microseconds);
static int instCurrentTime(sqlite3_vfs*, double*);
+static void binarylog_blob(sqlite3_vfs *, const char *, int);
+
static sqlite3_vfs inst_vfs = {
1, /* iVersion */
sizeof(inst_file), /* szOsFile */
pInstVfs->aTime[eEvent] += t; \
pInstVfs->aCount[eEvent] += 1; \
if( pInstVfs->xCall ){ \
- pInstVfs->xCall(pInstVfs->pClient, eEvent, t, p->zName, p->flags, A, B); \
+ pInstVfs->xCall( \
+ pInstVfs->pClient,eEvent,p->iFileId,t,rc,p->zName,p->flags,A,B \
+ ); \
} \
return rc; \
}
pInstVfs->aTime[eEvent] += t; \
pInstVfs->aCount[eEvent] += 1; \
if( pInstVfs->xCall ){ \
- pInstVfs->xCall(pInstVfs->pClient, eEvent, t, Z, flags, A, B); \
+ pInstVfs->xCall(pInstVfs->pClient,eEvent,0, t, rc, Z, flags, A, B); \
} \
return rc; \
}
** Return the current file-size of an inst-file.
*/
static int instFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
- OS_TIME_IO(OS_FILESIZE, 0, 0, p->pReal->pMethods->xFileSize(p->pReal, pSize));
+ OS_TIME_IO(OS_FILESIZE, (int)(*pSize), 0,
+ p->pReal->pMethods->xFileSize(p->pReal, pSize)
+ );
}
/*
p->pInstVfs = (InstVfs *)pVfs;
p->zName = zName;
p->flags = flags;
+ p->iFileId = ++p->pInstVfs->iNextFileId;
- OS_TIME_VFS(OS_OPEN, zName, flags, 0, 0,
+ binarylog_blob(pVfs, zName, -1);
+ OS_TIME_VFS(OS_OPEN, zName, flags, p->iFileId, 0,
REALVFS(pVfs)->xOpen(REALVFS(pVfs), zName, p->pReal, flags, pOutFlags)
);
}
** returning.
*/
static int instDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
+ binarylog_blob(pVfs, zPath, -1);
OS_TIME_VFS(OS_DELETE, zPath, 0, dirSync, 0,
REALVFS(pVfs)->xDelete(REALVFS(pVfs), zPath, dirSync)
);
** is available, or false otherwise.
*/
static int instAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
+ binarylog_blob(pVfs, zPath, -1);
OS_TIME_VFS(OS_ACCESS, zPath, 0, flags, 0,
REALVFS(pVfs)->xAccess(REALVFS(pVfs), zPath, flags)
);
void sqlite3_instvfs_configure(
sqlite3_vfs *pVfs,
- void (*xCall)(void*, int, sqlite3_int64, const char*, int, int, sqlite3_int64),
+ void (*xCall)(
+ void*,
+ int, /* File id */
+ int, /* Event code */
+ sqlite3_int64,
+ int, /* Return code */
+ const char*, /* File name */
+ int,
+ int,
+ sqlite3_int64
+ ),
void *pClient,
void (*xDel)(void *)
){
static void binarylog_xcall(
void *p,
int eEvent,
+ int iFileId,
sqlite3_int64 nClick,
+ int return_code,
const char *zName,
int flags,
int nByte,
){
InstVfsBinaryLog *pLog = (InstVfsBinaryLog *)p;
unsigned char *zRec;
- if( (20+pLog->nBuf)>BINARYLOG_BUFFERSIZE ){
+ if( (28+pLog->nBuf)>BINARYLOG_BUFFERSIZE ){
sqlite3_file *pFile = pLog->pOut;
pFile->pMethods->xWrite(pFile, pLog->zBuf, pLog->nBuf, pLog->iOffset);
pLog->iOffset += pLog->nBuf;
}
zRec = (unsigned char *)&pLog->zBuf[pLog->nBuf];
put32bits(&zRec[0], eEvent);
- put32bits(&zRec[4], (int)nClick);
- put32bits(&zRec[8], flags);
- put32bits(&zRec[12], nByte);
- put32bits(&zRec[16], (int)iOffset);
- pLog->nBuf += 20;
+ put32bits(&zRec[4], (int)iFileId);
+ put32bits(&zRec[8], (int)nClick);
+ put32bits(&zRec[12], return_code);
+ put32bits(&zRec[16], flags);
+ put32bits(&zRec[20], nByte);
+ put32bits(&zRec[24], (int)iOffset);
+ pLog->nBuf += 28;
}
static void binarylog_xdel(void *p){
sqlite3_free(pLog);
}
+static void binarylog_blob(
+ sqlite3_vfs *pVfs,
+ const char *zBlob,
+ int nBlob
+){
+ unsigned char *zRec;
+ int nWrite;
+ InstVfs *pInstVfs = (InstVfs *)pVfs;
+ InstVfsBinaryLog *pLog;
+
+ if( pVfs->xOpen!=instOpen || pInstVfs->xCall!=binarylog_xcall ){
+ return;
+ }
+
+ pLog = (InstVfsBinaryLog *)pInstVfs->pClient;
+ if( nBlob<0 ){
+ nBlob = strlen(zBlob);
+ }
+ nWrite = nBlob + 28;
+
+ if( (nWrite+pLog->nBuf)>BINARYLOG_BUFFERSIZE ){
+ sqlite3_file *pFile = pLog->pOut;
+ pFile->pMethods->xWrite(pFile, pLog->zBuf, pLog->nBuf, pLog->iOffset);
+ pLog->iOffset += pLog->nBuf;
+ pLog->nBuf = 0;
+ }
+
+ zRec = (unsigned char *)&pLog->zBuf[pLog->nBuf];
+ memset(zRec, 0, nWrite);
+ put32bits(&zRec[0], BINARYLOG_STRING);
+ put32bits(&zRec[4], (int)nBlob);
+ memcpy(&zRec[28], zBlob, nBlob);
+ pLog->nBuf += nWrite;
+}
+
+void sqlite3_instvfs_binarylog_marker(
+ sqlite3_vfs *pVfs,
+ const char *zMarker
+){
+ InstVfs *pInstVfs = (InstVfs *)pVfs;
+ InstVfsBinaryLog *pLog = (InstVfsBinaryLog *)pInstVfs->pClient;
+ binarylog_blob(pVfs, zMarker, -1);
+ binarylog_xcall(pLog, BINARYLOG_MARKER, 0, 0, 0, 0, 0, 0, 0);
+}
+
sqlite3_vfs *sqlite3_instvfs_binarylog(
const char *zVfs,
const char *zParentVfs,
static void test_instvfs_xcall(
void *p,
int eEvent,
+ int iFileId,
sqlite3_int64 nClick,
+ int return_code,
const char *zName,
int flags,
int nByte,
Tcl_Obj *CONST objv[]
){
static const char *IV_strs[] =
- { "create", "destroy", "reset", "report", "configure", "binarylog", 0 };
- enum IV_enum { IV_CREATE, IV_DESTROY, IV_RESET, IV_REPORT, IV_CONFIGURE, IV_BINARYLOG };
+ { "create", "destroy", "reset", "report", "configure", "binarylog", "marker", 0 };
+ enum IV_enum { IV_CREATE, IV_DESTROY, IV_RESET, IV_REPORT, IV_CONFIGURE, IV_BINARYLOG, IV_MARKER };
int iSub;
if( objc<2 ){
break;
}
+ case IV_MARKER: {
+ sqlite3_vfs *p;
+ if( objc!=4 ){
+ Tcl_WrongNumArgs(interp, 2, objv, "VFS MARKER");
+ return TCL_ERROR;
+ }
+ p = sqlite3_vfs_find(Tcl_GetString(objv[2]));
+ if( !p || p->xOpen!=instOpen ){
+ Tcl_AppendResult(interp, "no such vfs: ", Tcl_GetString(objv[2]), 0);
+ return TCL_ERROR;
+ }
+ sqlite3_instvfs_binarylog_marker(p, Tcl_GetString(objv[3]));
+ Tcl_ResetResult(interp);
+ break;
+ }
+
case IV_CONFIGURE: {
InstVfsCall *pCall;