📄 test_osinst.c
字号:
int, sqlite3_int64 ), void *pClient, void (*xDel)(void *)){ InstVfs *p = (InstVfs *)pVfs; assert( pVfs->xOpen==instOpen ); if( p->xDel ){ p->xDel(p->pClient); } p->xCall = xCall; p->xDel = xDel; p->pClient = pClient;}void sqlite3_instvfs_destroy(sqlite3_vfs *pVfs){ if( pVfs ){ sqlite3_vfs_unregister(pVfs); sqlite3_instvfs_configure(pVfs, 0, 0, 0); sqlite3_free(pVfs); }}void sqlite3_instvfs_reset(sqlite3_vfs *pVfs){ InstVfs *p = (InstVfs *)pVfs; assert( pVfs->xOpen==instOpen ); memset(p->aTime, 0, sizeof(sqlite3_int64)*OS_NUMEVENTS); memset(p->aCount, 0, sizeof(int)*OS_NUMEVENTS);}const char *sqlite3_instvfs_name(int eEvent){ const char *zEvent = 0; switch( eEvent ){ case OS_CLOSE: zEvent = "xClose"; break; case OS_READ: zEvent = "xRead"; break; case OS_WRITE: zEvent = "xWrite"; break; case OS_TRUNCATE: zEvent = "xTruncate"; break; case OS_SYNC: zEvent = "xSync"; break; case OS_FILESIZE: zEvent = "xFilesize"; break; case OS_LOCK: zEvent = "xLock"; break; case OS_UNLOCK: zEvent = "xUnlock"; break; case OS_CHECKRESERVEDLOCK: zEvent = "xCheckReservedLock"; break; case OS_FILECONTROL: zEvent = "xFileControl"; break; case OS_SECTORSIZE: zEvent = "xSectorSize"; break; case OS_DEVCHAR: zEvent = "xDeviceCharacteristics"; break; case OS_OPEN: zEvent = "xOpen"; break; case OS_DELETE: zEvent = "xDelete"; break; case OS_ACCESS: zEvent = "xAccess"; break; case OS_FULLPATHNAME: zEvent = "xFullPathname"; break; case OS_RANDOMNESS: zEvent = "xRandomness"; break; case OS_SLEEP: zEvent = "xSleep"; break; case OS_CURRENTTIME: zEvent = "xCurrentTime"; break; } return zEvent;}void sqlite3_instvfs_get( sqlite3_vfs *pVfs, int eEvent, const char **pzEvent, sqlite3_int64 *pnClick, int *pnCall){ InstVfs *p = (InstVfs *)pVfs; assert( pVfs->xOpen==instOpen ); if( eEvent<1 || eEvent>=OS_NUMEVENTS ){ *pzEvent = 0; *pnClick = 0; *pnCall = 0; return; } *pzEvent = sqlite3_instvfs_name(eEvent); *pnClick = p->aTime[eEvent]; *pnCall = p->aCount[eEvent];}#define BINARYLOG_BUFFERSIZE 8192struct InstVfsBinaryLog { int nBuf; char *zBuf; sqlite3_int64 iOffset; int log_data; sqlite3_file *pOut; char *zOut; /* Log file name */};typedef struct InstVfsBinaryLog InstVfsBinaryLog;static void put32bits(unsigned char *p, unsigned int v){ p[0] = v>>24; p[1] = v>>16; p[2] = v>>8; p[3] = v;}static void binarylog_flush(InstVfsBinaryLog *pLog){ sqlite3_file *pFile = pLog->pOut;#ifdef SQLITE_TEST extern int sqlite3_io_error_pending; extern int sqlite3_io_error_persist; extern int sqlite3_diskfull_pending; int pending = sqlite3_io_error_pending; int persist = sqlite3_io_error_persist; int diskfull = sqlite3_diskfull_pending; sqlite3_io_error_pending = 0; sqlite3_io_error_persist = 0; sqlite3_diskfull_pending = 0;#endif pFile->pMethods->xWrite(pFile, pLog->zBuf, pLog->nBuf, pLog->iOffset); pLog->iOffset += pLog->nBuf; pLog->nBuf = 0;#ifdef SQLITE_TEST sqlite3_io_error_pending = pending; sqlite3_io_error_persist = persist; sqlite3_diskfull_pending = diskfull;#endif}static void binarylog_xcall( void *p, int eEvent, int iFileId, sqlite3_int64 nClick, int return_code, const char *zName, int flags, int nByte, sqlite3_int64 iOffset){ InstVfsBinaryLog *pLog = (InstVfsBinaryLog *)p; unsigned char *zRec; if( (28+pLog->nBuf)>BINARYLOG_BUFFERSIZE ){ binarylog_flush(pLog); } zRec = (unsigned char *)&pLog->zBuf[pLog->nBuf]; put32bits(&zRec[0], eEvent); 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){ /* Close the log file and free the memory allocated for the ** InstVfsBinaryLog structure. */ InstVfsBinaryLog *pLog = (InstVfsBinaryLog *)p; sqlite3_file *pFile = pLog->pOut; if( pLog->nBuf ){ binarylog_flush(pLog); } pFile->pMethods->xClose(pFile); sqlite3_free(pLog->pOut); sqlite3_free(pLog->zBuf); sqlite3_free(pLog);}static void binarylog_blob( sqlite3_vfs *pVfs, const char *zBlob, int nBlob, int isBinary){ InstVfsBinaryLog *pLog; InstVfs *pInstVfs = (InstVfs *)pVfs; if( pVfs->xOpen!=instOpen || pInstVfs->xCall!=binarylog_xcall ){ return; } pLog = (InstVfsBinaryLog *)pInstVfs->pClient; if( zBlob && (!isBinary || pLog->log_data) ){ unsigned char *zRec; int nWrite; if( nBlob<0 ){ nBlob = strlen(zBlob); } nWrite = nBlob + 28; if( (nWrite+pLog->nBuf)>BINARYLOG_BUFFERSIZE ){ binarylog_flush(pLog); } zRec = (unsigned char *)&pLog->zBuf[pLog->nBuf]; memset(zRec, 0, nWrite); put32bits(&zRec[0], BINARYLOG_STRING); put32bits(&zRec[4], (int)nBlob); put32bits(&zRec[8], (int)isBinary); memcpy(&zRec[28], zBlob, nBlob); pLog->nBuf += nWrite; }}void sqlite3_instvfs_binarylog_call( sqlite3_vfs *pVfs, int eEvent, sqlite3_int64 nClick, int return_code, const char *zString){ InstVfs *pInstVfs = (InstVfs *)pVfs; InstVfsBinaryLog *pLog = (InstVfsBinaryLog *)pInstVfs->pClient; if( zString ){ binarylog_blob(pVfs, zString, -1, 0); } binarylog_xcall(pLog, eEvent, 0, nClick, return_code, 0, 0, 0, 0);}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, 0); binarylog_xcall(pLog, BINARYLOG_MARKER, 0, 0, 0, 0, 0, 0, 0);}sqlite3_vfs *sqlite3_instvfs_binarylog( const char *zVfs, const char *zParentVfs, const char *zLog, int log_data){ InstVfsBinaryLog *p; sqlite3_vfs *pVfs; sqlite3_vfs *pParent; int nByte; int flags; int rc; pParent = sqlite3_vfs_find(zParentVfs); if( !pParent ){ return 0; } nByte = sizeof(InstVfsBinaryLog) + pParent->mxPathname+1; p = (InstVfsBinaryLog *)sqlite3_malloc(nByte); memset(p, 0, nByte); p->zBuf = sqlite3_malloc(BINARYLOG_BUFFERSIZE); p->zOut = (char *)&p[1]; p->pOut = (sqlite3_file *)sqlite3_malloc(pParent->szOsFile); p->log_data = log_data; pParent->xFullPathname(pParent, zLog, pParent->mxPathname, p->zOut); flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MASTER_JOURNAL; pParent->xDelete(pParent, p->zOut, 0); rc = pParent->xOpen(pParent, p->zOut, p->pOut, flags, &flags); if( rc==SQLITE_OK ){ memcpy(p->zBuf, "sqlite_ostrace1.....", 20); p->iOffset = 0; p->nBuf = 20; } if( rc ){ binarylog_xdel(p); return 0; } pVfs = sqlite3_instvfs_create(zVfs, zParentVfs); if( pVfs ){ sqlite3_instvfs_configure(pVfs, binarylog_xcall, p, binarylog_xdel); } return pVfs;}#endif /* SQLITE_ENABLE_INSTVFS *//******************************************************************************************************************************************************* Tcl interface starts here.*/#if SQLITE_TEST#include <tcl.h>#ifdef SQLITE_ENABLE_INSTVFSstruct InstVfsCall { Tcl_Interp *interp; Tcl_Obj *pScript;};typedef struct InstVfsCall InstVfsCall;static void test_instvfs_xcall( void *p, int eEvent, int iFileId, sqlite3_int64 nClick, int return_code, const char *zName, int flags, int nByte, sqlite3_int64 iOffset){ int rc; InstVfsCall *pCall = (InstVfsCall *)p; Tcl_Obj *pObj = Tcl_DuplicateObj( pCall->pScript); const char *zEvent = sqlite3_instvfs_name(eEvent); Tcl_IncrRefCount(pObj); Tcl_ListObjAppendElement(0, pObj, Tcl_NewStringObj(zEvent, -1)); Tcl_ListObjAppendElement(0, pObj, Tcl_NewWideIntObj(nClick)); Tcl_ListObjAppendElement(0, pObj, Tcl_NewStringObj(zName, -1)); Tcl_ListObjAppendElement(0, pObj, Tcl_NewIntObj(nByte)); Tcl_ListObjAppendElement(0, pObj, Tcl_NewWideIntObj(iOffset)); rc = Tcl_EvalObjEx(pCall->interp, pObj, TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT); if( rc ){ Tcl_BackgroundError(pCall->interp); } Tcl_DecrRefCount(pObj);}static void test_instvfs_xdel(void *p){ InstVfsCall *pCall = (InstVfsCall *)p; Tcl_DecrRefCount(pCall->pScript); sqlite3_free(pCall);}static int test_sqlite3_instvfs( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){ static const char *IV_strs[] = { "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 ){ Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ..."); } if( Tcl_GetIndexFromObj(interp, objv[1], IV_strs, "sub-command", 0, &iSub) ){ return TCL_ERROR; } switch( (enum IV_enum)iSub ){ case IV_CREATE: { char *zParent = 0; sqlite3_vfs *p; int isDefault = 0; if( objc>2 && 0==strcmp("-default", Tcl_GetString(objv[2])) ){ isDefault = 1; } if( (objc-isDefault)!=4 && (objc-isDefault)!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "?-default? NAME ?PARENT-VFS?"); return TCL_ERROR; } if( objc==(4+isDefault) ){ zParent = Tcl_GetString(objv[3+isDefault]); } p = sqlite3_instvfs_create(Tcl_GetString(objv[2+isDefault]), zParent); if( !p ){ Tcl_AppendResult(interp, "error creating vfs ", 0); return TCL_ERROR; } if( isDefault ){ sqlite3_vfs_register(p, 1); } Tcl_SetObjResult(interp, objv[2]); break; } case IV_BINARYLOG: { char *zName = 0; char *zLog = 0; char *zParent = 0; sqlite3_vfs *p; int isDefault = 0; int isLogdata = 0; int argbase = 2; for(argbase=2; argbase<(objc-2); argbase++){ if( 0==strcmp("-default", Tcl_GetString(objv[argbase])) ){ isDefault = 1; } else if( 0==strcmp("-parent", Tcl_GetString(objv[argbase])) ){ argbase++; zParent = Tcl_GetString(objv[argbase]); } else if( 0==strcmp("-logdata", Tcl_GetString(objv[argbase])) ){ isLogdata = 1; }else{ break; } } if( (objc-argbase)!=2 ){ Tcl_WrongNumArgs( interp, 2, objv, "?-default? ?-parent VFS? ?-logdata? NAME LOGFILE" ); return TCL_ERROR; } zName = Tcl_GetString(objv[argbase]); zLog = Tcl_GetString(objv[argbase+1]); p = sqlite3_instvfs_binarylog(zName, zParent, zLog, isLogdata); if( !p ){ Tcl_AppendResult(interp, "error creating vfs ", 0); return TCL_ERROR; } if( isDefault ){ sqlite3_vfs_register(p, 1); } Tcl_SetObjResult(interp, objv[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; sqlite3_vfs *p; if( objc!=4 ){ Tcl_WrongNumArgs(interp, 2, objv, "NAME SCRIPT"); 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; } if( strlen(Tcl_GetString(objv[3])) ){ pCall = (InstVfsCall *)sqlite3_malloc(sizeof(InstVfsCall)); pCall->interp = interp; pCall->pScript = Tcl_DuplicateObj(objv[3]); Tcl_IncrRefCount(pCall->pScript); sqlite3_instvfs_configure(p, test_instvfs_xcall, (void *)pCall, test_instvfs_xdel ); }else{ sqlite3_instvfs_configure(p, 0, 0, 0); } break; } case IV_REPORT: case IV_DESTROY: case IV_RESET: { sqlite3_vfs *p; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 2, objv, "NAME"); 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; } if( ((enum IV_enum)iSub)==IV_DESTROY ){ sqlite3_instvfs_destroy(p); } if( ((enum IV_enum)iSub)==IV_RESET ){ sqlite3_instvfs_reset(p); } if( ((enum IV_enum)iSub)==IV_REPORT ){ int ii; Tcl_Obj *pRet = Tcl_NewObj(); const char *zName = (char *)1; sqlite3_int64 nClick; int nCall; for(ii=1; zName; ii++){ sqlite3_instvfs_get(p, ii, &zName, &nClick, &nCall); if( zName ){ Tcl_Obj *pElem = Tcl_NewObj(); Tcl_ListObjAppendElement(0, pElem, Tcl_NewStringObj(zName, -1)); Tcl_ListObjAppendElement(0, pElem, Tcl_NewIntObj(nCall)); Tcl_ListObjAppendElement(0, pElem, Tcl_NewWideIntObj(nClick)); Tcl_ListObjAppendElement(0, pRet, pElem); } } Tcl_SetObjResult(interp, pRet); } break; } } return TCL_OK;}#endif /* SQLITE_ENABLE_INSTVFS *//* Alternative implementation of sqlite3_instvfs when the real** implementation is unavailable. */#ifndef SQLITE_ENABLE_INSTVFSstatic int test_sqlite3_instvfs( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]){ Tcl_AppendResult(interp, "not compiled with -DSQLITE_ENABLE_INSTVFS; sqlite3_instvfs is " "unavailable", (char*)0); return TCL_ERROR;}#endif /* !defined(SQLITE_ENABLE_INSTVFS) */int SqlitetestOsinst_Init(Tcl_Interp *interp){ Tcl_CreateObjCommand(interp, "sqlite3_instvfs", test_sqlite3_instvfs, 0, 0); return TCL_OK;}#endif /* SQLITE_TEST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -