15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2008 April 10 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code. In place of 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing: 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you do good and not evil. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you find forgiveness for yourself and forgive others. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** May you share freely, never taking more than you give. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)****************************************************************************** 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This file contains the implementation of an SQLite vfs wrapper that 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** adds instrumentation to all vfs and file methods. C and Tcl interfaces 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** are provided to control the instrumentation. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This module contains code for a wrapper VFS that causes a log of 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** most VFS calls to be written into a nominated file on disk. The log 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is stored in a compressed binary format to reduce the amount of IO 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** overhead introduced into the application by logging. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** All calls on sqlite3_file objects except xFileControl() are logged. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Additionally, calls to the xAccess(), xOpen(), and xDelete() 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** methods are logged. The other sqlite3_vfs object methods (xDlXXX, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** xRandomness, xSleep, xCurrentTime, xGetLastError and xCurrentTimeInt64) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** are not logged. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The binary log files are read using a virtual table implementation 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** also contained in this file. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** CREATING LOG FILES: 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** int sqlite3_vfslog_new( 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** const char *zVfs, // Name of new VFS 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** const char *zParentVfs, // Name of parent VFS (or NULL) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** const char *zLog // Name of log file to write to 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** int sqlite3_vfslog_finalize(const char *zVfs); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ANNOTATING LOG FILES: 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** To write an arbitrary message into a log file: 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** int sqlite3_vfslog_annotate(const char *zVfs, const char *zMsg); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** READING LOG FILES: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Log files are read using the "vfslog" virtual table implementation 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** in this file. To register the virtual table with SQLite, use: 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** int sqlite3_vfslog_register(sqlite3 *db); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Then, if the log file is named "vfs.log", the following SQL command: 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** CREATE VIRTUAL TABLE v USING vfslog('vfs.log'); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** creates a virtual table with 6 columns, as follows: 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** CREATE TABLE v( 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** event TEXT, // "xOpen", "xRead" etc. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** file TEXT, // Name of file this call applies to 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** clicks INTEGER, // Time spent in call 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** rc INTEGER, // Return value 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** size INTEGER, // Bytes read or written 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** offset INTEGER // File offset read or written 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqlite3.h" 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h> 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Maximum pathname length supported by the vfslog backend. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INST_MAX_PATHNAME 512 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_ACCESS 1 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_CHECKRESERVEDLOCK 2 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_CLOSE 3 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_CURRENTTIME 4 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_DELETE 5 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_DEVCHAR 6 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_FILECONTROL 7 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_FILESIZE 8 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_FULLPATHNAME 9 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_LOCK 11 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_OPEN 12 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_RANDOMNESS 13 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_READ 14 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_SECTORSIZE 15 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_SLEEP 16 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_SYNC 17 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_TRUNCATE 18 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_UNLOCK 19 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_WRITE 20 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_SHMUNMAP 22 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_SHMMAP 23 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_SHMLOCK 25 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_SHMBARRIER 26 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_ANNOTATE 28 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_NUMEVENTS 29 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define VFSLOG_BUFFERSIZE 8192 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct VfslogVfs VfslogVfs; 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct VfslogFile VfslogFile; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct VfslogVfs { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs base; /* VFS methods */ 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfs; /* Parent VFS */ 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iNextFileId; /* Next file id */ 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pLog; /* Log file handle */ 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_int64 iOffset; /* Log file offset of start of write buffer */ 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nBuf; /* Number of valid bytes in aBuf[] */ 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char aBuf[VFSLOG_BUFFERSIZE]; /* Write buffer */ 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct VfslogFile { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file base; /* IO methods */ 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pReal; /* Underlying file handle */ 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfslog; /* Associated VsflogVfs object */ 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iFileId; /* File id number */ 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define REALVFS(p) (((VfslogVfs *)(p))->pVfs) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Method declarations for vfslog_file. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogClose(sqlite3_file*); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogTruncate(sqlite3_file*, sqlite3_int64 size); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogSync(sqlite3_file*, int flags); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogFileSize(sqlite3_file*, sqlite3_int64 *pSize); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogLock(sqlite3_file*, int); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogUnlock(sqlite3_file*, int); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogCheckReservedLock(sqlite3_file*, int *pResOut); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogFileControl(sqlite3_file*, int op, void *pArg); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogSectorSize(sqlite3_file*); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogDeviceCharacteristics(sqlite3_file*); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogShmLock(sqlite3_file *pFile, int ofst, int n, int flags); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogShmMap(sqlite3_file *pFile,int,int,int,volatile void **); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void vfslogShmBarrier(sqlite3_file*); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogShmUnmap(sqlite3_file *pFile, int deleteFlag); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Method declarations for vfslog_vfs. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogDelete(sqlite3_vfs*, const char *zName, int syncDir); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogAccess(sqlite3_vfs*, const char *zName, int flags, int *); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *vfslogDlOpen(sqlite3_vfs*, const char *zFilename); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void vfslogDlError(sqlite3_vfs*, int nByte, char *zErrMsg); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void (*vfslogDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void vfslogDlClose(sqlite3_vfs*, void*); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogRandomness(sqlite3_vfs*, int nByte, char *zOut); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogSleep(sqlite3_vfs*, int microseconds); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogCurrentTime(sqlite3_vfs*, double*); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogGetLastError(sqlite3_vfs*, int, char *); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite3_vfs vfslog_vfs = { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, /* iVersion */ 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(VfslogFile), /* szOsFile */ 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INST_MAX_PATHNAME, /* mxPathname */ 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* pNext */ 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* zName */ 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* pAppData */ 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogOpen, /* xOpen */ 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogDelete, /* xDelete */ 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogAccess, /* xAccess */ 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogFullPathname, /* xFullPathname */ 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogDlOpen, /* xDlOpen */ 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogDlError, /* xDlError */ 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogDlSym, /* xDlSym */ 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogDlClose, /* xDlClose */ 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogRandomness, /* xRandomness */ 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogSleep, /* xSleep */ 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogCurrentTime, /* xCurrentTime */ 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogGetLastError, /* xGetLastError */ 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogCurrentTimeInt64 /* xCurrentTime */ 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite3_io_methods vfslog_io_methods = { 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2, /* iVersion */ 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogClose, /* xClose */ 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogRead, /* xRead */ 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogWrite, /* xWrite */ 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogTruncate, /* xTruncate */ 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogSync, /* xSync */ 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogFileSize, /* xFileSize */ 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogLock, /* xLock */ 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogUnlock, /* xUnlock */ 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogCheckReservedLock, /* xCheckReservedLock */ 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogFileControl, /* xFileControl */ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogSectorSize, /* xSectorSize */ 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogDeviceCharacteristics, /* xDeviceCharacteristics */ 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogShmMap, /* xShmMap */ 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogShmLock, /* xShmLock */ 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogShmBarrier, /* xShmBarrier */ 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslogShmUnmap /* xShmUnmap */ 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if SQLITE_OS_UNIX && !defined(NO_GETTOD) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/time.h> 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite3_uint64 vfslog_time(){ 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timeval sTime; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gettimeofday(&sTime, 0); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return sTime.tv_usec + (sqlite3_uint64)sTime.tv_sec * 1000000; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif SQLITE_OS_WIN 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <time.h> 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite3_uint64 vfslog_time(){ 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILETIME ft; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 u64time = 0; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetSystemTimeAsFileTime(&ft); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u64time |= ft.dwHighDateTime; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u64time <<= 32; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u64time |= ft.dwLowDateTime; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* ft is 100-nanosecond intervals, we want microseconds */ 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return u64time /(sqlite3_uint64)10; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite3_uint64 vfslog_time(){ 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void vfslog_call(sqlite3_vfs *, int, int, int, int, int, int); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void vfslog_string(sqlite3_vfs *, const char *); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Close an vfslog-file. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogClose(sqlite3_file *pFile){ 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_OK; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->pReal->pMethods ){ 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pReal->pMethods->xClose(p->pReal); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_CLOSE, p->iFileId, t, rc, 0, 0); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Read data from an vfslog-file. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogRead( 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pFile, 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *zBuf, 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iAmt, 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite_int64 iOfst 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_READ, p->iFileId, t, rc, iAmt, (int)iOfst); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write data to an vfslog-file. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogWrite( 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pFile, 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void *z, 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iAmt, 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite_int64 iOfst 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pReal->pMethods->xWrite(p->pReal, z, iAmt, iOfst); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_WRITE, p->iFileId, t, rc, iAmt, (int)iOfst); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Truncate an vfslog-file. 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogTruncate(sqlite3_file *pFile, sqlite_int64 size){ 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pReal->pMethods->xTruncate(p->pReal, size); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_TRUNCATE, p->iFileId, t, rc, 0, (int)size); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Sync an vfslog-file. 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogSync(sqlite3_file *pFile, int flags){ 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pReal->pMethods->xSync(p->pReal, flags); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_SYNC, p->iFileId, t, rc, flags, 0); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the current file-size of an vfslog-file. 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_FILESIZE, p->iFileId, t, rc, 0, (int)*pSize); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Lock an vfslog-file. 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogLock(sqlite3_file *pFile, int eLock){ 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pReal->pMethods->xLock(p->pReal, eLock); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_LOCK, p->iFileId, t, rc, eLock, 0); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Unlock an vfslog-file. 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogUnlock(sqlite3_file *pFile, int eLock){ 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pReal->pMethods->xUnlock(p->pReal, eLock); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_UNLOCK, p->iFileId, t, rc, eLock, 0); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Check if another file-handle holds a RESERVED lock on an vfslog-file. 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogCheckReservedLock(sqlite3_file *pFile, int *pResOut){ 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_CHECKRESERVEDLOCK, p->iFileId, t, rc, *pResOut, 0); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** File control method. For custom operations on an vfslog-file. 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogFileControl(sqlite3_file *pFile, int op, void *pArg){ 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return p->pReal->pMethods->xFileControl(p->pReal, op, pArg); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the sector-size in bytes for an vfslog-file. 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogSectorSize(sqlite3_file *pFile){ 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pReal->pMethods->xSectorSize(p->pReal); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_SECTORSIZE, p->iFileId, t, rc, 0, 0); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the device characteristic flags supported by an vfslog-file. 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogDeviceCharacteristics(sqlite3_file *pFile){ 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_DEVCHAR, p->iFileId, t, rc, 0, 0); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_SHMLOCK, p->iFileId, t, rc, 0, 0); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogShmMap( 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pFile, 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iRegion, 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int szRegion, 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isWrite, 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) volatile void **pp 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_SHMMAP, p->iFileId, t, rc, 0, 0); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void vfslogShmBarrier(sqlite3_file *pFile){ 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pReal->pMethods->xShmBarrier(p->pReal); 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_SHMBARRIER, p->iFileId, t, SQLITE_OK, 0, 0); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogShmUnmap(sqlite3_file *pFile, int deleteFlag){ 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pReal->pMethods->xShmUnmap(p->pReal, deleteFlag); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(p->pVfslog, OS_SHMUNMAP, p->iFileId, t, rc, 0, 0); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Open an vfslog file handle. 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogOpen( 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfs, 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zName, 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pFile, 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *pOutFlags 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogFile *p = (VfslogFile *)pFile; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogVfs *pLog = (VfslogVfs *)pVfs; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pFile->pMethods = &vfslog_io_methods; 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pReal = (sqlite3_file *)&p[1]; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pVfslog = pVfs; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->iFileId = ++pLog->iNextFileId; 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = REALVFS(pVfs)->xOpen(REALVFS(pVfs), zName, p->pReal, flags, pOutFlags); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(pVfs, OS_OPEN, p->iFileId, t, rc, 0, 0); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_string(pVfs, zName); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Delete the file located at zPath. If the dirSync argument is true, 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ensure the file-system modifications are synced to disk before 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** returning. 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = REALVFS(pVfs)->xDelete(REALVFS(pVfs), zPath, dirSync); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(pVfs, OS_DELETE, 0, t, rc, dirSync, 0); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_string(pVfs, zPath); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Test for access permissions. Return true if the requested permission 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is available, or false otherwise. 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogAccess( 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfs, 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zPath, 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags, 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int *pResOut 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_uint64 t; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time(); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = REALVFS(pVfs)->xAccess(REALVFS(pVfs), zPath, flags, pResOut); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = vfslog_time() - t; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(pVfs, OS_ACCESS, 0, t, rc, flags, *pResOut); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_string(pVfs, zPath); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Populate buffer zOut with the full canonical pathname corresponding 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to the pathname in zPath. zOut is guaranteed to point to a buffer 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of at least (INST_MAX_PATHNAME+1) bytes. 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogFullPathname( 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfs, 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zPath, 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nOut, 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zOut 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return REALVFS(pVfs)->xFullPathname(REALVFS(pVfs), zPath, nOut, zOut); 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Open the dynamic library located at zPath and return a handle. 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void *vfslogDlOpen(sqlite3_vfs *pVfs, const char *zPath){ 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return REALVFS(pVfs)->xDlOpen(REALVFS(pVfs), zPath); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Populate the buffer zErrMsg (size nByte bytes) with a human readable 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** utf-8 string describing the most recent error encountered associated 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** with dynamic libraries. 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void vfslogDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REALVFS(pVfs)->xDlError(REALVFS(pVfs), nByte, zErrMsg); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return a pointer to the symbol zSymbol in the dynamic library pHandle. 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void (*vfslogDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return REALVFS(pVfs)->xDlSym(REALVFS(pVfs), p, zSym); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Close the dynamic library handle pHandle. 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void vfslogDlClose(sqlite3_vfs *pVfs, void *pHandle){ 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) REALVFS(pVfs)->xDlClose(REALVFS(pVfs), pHandle); 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Populate the buffer pointed to by zBufOut with nByte bytes of 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** random data. 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return REALVFS(pVfs)->xRandomness(REALVFS(pVfs), nByte, zBufOut); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Sleep for nMicro microseconds. Return the number of microseconds 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** actually slept. 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogSleep(sqlite3_vfs *pVfs, int nMicro){ 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return REALVFS(pVfs)->xSleep(REALVFS(pVfs), nMicro); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the current time as a Julian Day number in *pTimeOut. 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return REALVFS(pVfs)->xCurrentTime(REALVFS(pVfs), pTimeOut); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogGetLastError(sqlite3_vfs *pVfs, int a, char *b){ 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return REALVFS(pVfs)->xGetLastError(REALVFS(pVfs), a, b); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vfslogCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return REALVFS(pVfs)->xCurrentTimeInt64(REALVFS(pVfs), p); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void vfslog_flush(VfslogVfs *p){ 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_TEST 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern int sqlite3_io_error_pending; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern int sqlite3_io_error_persist; 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extern int sqlite3_diskfull_pending; 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pending = sqlite3_io_error_pending; 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int persist = sqlite3_io_error_persist; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int diskfull = sqlite3_diskfull_pending; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_io_error_pending = 0; 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_io_error_persist = 0; 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_diskfull_pending = 0; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->nBuf ){ 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pLog->pMethods->xWrite(p->pLog, p->aBuf, p->nBuf, p->iOffset); 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->iOffset += p->nBuf; 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->nBuf = 0; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_TEST 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_io_error_pending = pending; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_io_error_persist = persist; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_diskfull_pending = diskfull; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void put32bits(unsigned char *p, unsigned int v){ 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p[0] = v>>24; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p[1] = v>>16; 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p[2] = v>>8; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p[3] = v; 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void vfslog_call( 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfs, 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int eEvent, 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iFileid, 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nClick, 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int return_code, 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size, 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int offset 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogVfs *p = (VfslogVfs *)pVfs; 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char *zRec; 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (24+p->nBuf)>sizeof(p->aBuf) ){ 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_flush(p); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zRec = (unsigned char *)&p->aBuf[p->nBuf]; 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put32bits(&zRec[0], eEvent); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put32bits(&zRec[4], iFileid); 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put32bits(&zRec[8], nClick); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put32bits(&zRec[12], return_code); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put32bits(&zRec[16], size); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put32bits(&zRec[20], offset); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->nBuf += 24; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void vfslog_string(sqlite3_vfs *pVfs, const char *zStr){ 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogVfs *p = (VfslogVfs *)pVfs; 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char *zRec; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nStr = zStr ? strlen(zStr) : 0; 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (4+nStr+p->nBuf)>sizeof(p->aBuf) ){ 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_flush(p); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zRec = (unsigned char *)&p->aBuf[p->nBuf]; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put32bits(&zRec[0], nStr); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( zStr ){ 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&zRec[4], zStr, nStr); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->nBuf += (4 + nStr); 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void vfslog_finalize(VfslogVfs *p){ 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->pLog->pMethods ){ 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_flush(p); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pLog->pMethods->xClose(p->pLog); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(p); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_vfslog_finalize(const char *zVfs){ 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfs; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pVfs = sqlite3_vfs_find(zVfs); 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !pVfs || pVfs->xOpen!=vfslogOpen ){ 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_ERROR; 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs_unregister(pVfs); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_finalize((VfslogVfs *)pVfs); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_vfslog_new( 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zVfs, /* New VFS name */ 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zParentVfs, /* Parent VFS name (or NULL) */ 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zLog /* Log file name */ 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogVfs *p; 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pParent; 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nByte; 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zFile; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nVfs; 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pParent = sqlite3_vfs_find(zParentVfs); 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !pParent ){ 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_ERROR; 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nVfs = strlen(zVfs); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nByte = sizeof(VfslogVfs) + pParent->szOsFile + nVfs+1+pParent->mxPathname+1; 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = (VfslogVfs *)sqlite3_malloc(nByte); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(p, 0, nByte); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pVfs = pParent; 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pLog = (sqlite3_file *)&p[1]; 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&p->base, &vfslog_vfs, sizeof(sqlite3_vfs)); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->base.zName = &((char *)p->pLog)[pParent->szOsFile]; 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->base.szOsFile += pParent->szOsFile; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy((char *)p->base.zName, zVfs, nVfs); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zFile = (char *)&p->base.zName[nVfs+1]; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pParent->xFullPathname(pParent, zLog, pParent->mxPathname, zFile); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MASTER_JOURNAL; 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pParent->xDelete(pParent, zFile, 0); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pParent->xOpen(pParent, zFile, p->pLog, flags, &flags); 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(p->aBuf, "sqlite_ostrace1.....", 20); 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->iOffset = 0; 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->nBuf = 20; 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_vfs_register((sqlite3_vfs *)p, 1); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc ){ 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_finalize(p); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_vfslog_annotate(const char *zVfs, const char *zMsg){ 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfs; 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pVfs = sqlite3_vfs_find(zVfs); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !pVfs || pVfs->xOpen!=vfslogOpen ){ 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_ERROR; 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_call(pVfs, OS_ANNOTATE, 0, 0, 0, 0, 0); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfslog_string(pVfs, zMsg); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char *vfslog_eventname(int eEvent){ 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *zEvent = 0; 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch( eEvent ){ 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_CLOSE: zEvent = "xClose"; break; 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_READ: zEvent = "xRead"; break; 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_WRITE: zEvent = "xWrite"; break; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_TRUNCATE: zEvent = "xTruncate"; break; 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_SYNC: zEvent = "xSync"; break; 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_FILESIZE: zEvent = "xFilesize"; break; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_LOCK: zEvent = "xLock"; break; 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_UNLOCK: zEvent = "xUnlock"; break; 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_CHECKRESERVEDLOCK: zEvent = "xCheckResLock"; break; 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_FILECONTROL: zEvent = "xFileControl"; break; 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_SECTORSIZE: zEvent = "xSectorSize"; break; 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_DEVCHAR: zEvent = "xDeviceChar"; break; 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_OPEN: zEvent = "xOpen"; break; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_DELETE: zEvent = "xDelete"; break; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_ACCESS: zEvent = "xAccess"; break; 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_FULLPATHNAME: zEvent = "xFullPathname"; break; 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_RANDOMNESS: zEvent = "xRandomness"; break; 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_SLEEP: zEvent = "xSleep"; break; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_CURRENTTIME: zEvent = "xCurrentTime"; break; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_SHMUNMAP: zEvent = "xShmUnmap"; break; 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_SHMLOCK: zEvent = "xShmLock"; break; 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_SHMBARRIER: zEvent = "xShmBarrier"; break; 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_SHMMAP: zEvent = "xShmMap"; break; 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case OS_ANNOTATE: zEvent = "annotation"; break; 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return zEvent; 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct VfslogVtab VfslogVtab; 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct VfslogCsr VfslogCsr; 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Virtual table type for the vfslog reader module. 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct VfslogVtab { 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vtab base; /* Base class */ 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_file *pFd; /* File descriptor open on vfslog file */ 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_int64 nByte; /* Size of file in bytes */ 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zFile; /* File name for pFd */ 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Virtual table cursor type for the vfslog reader module. 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct VfslogCsr { 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vtab_cursor base; /* Base class */ 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_int64 iRowid; /* Current rowid. */ 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_int64 iOffset; /* Offset of next record in file */ 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zTransient; /* Transient 'file' string */ 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nFile; /* Size of array azFile[] */ 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char **azFile; /* File strings */ 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned char aBuf[1024]; /* Current vfs log entry (read from file) */ 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned int get32bits(unsigned char *p){ 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The argument must point to a buffer containing a nul-terminated string. 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the string begins with an SQL quote character it is overwritten by 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the dequoted version. Otherwise the buffer is left unmodified. 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void dequote(char *z){ 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char quote; /* Quote character (if any ) */ 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) quote = z[0]; 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( quote=='[' || quote=='\'' || quote=='"' || quote=='`' ){ 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iIn = 1; /* Index of next byte to read from input */ 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iOut = 0; /* Index of next byte to write to output */ 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( quote=='[' ) quote = ']'; 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( z[iIn] ){ 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( z[iIn]==quote ){ 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( z[iIn+1]!=quote ) break; 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z[iOut++] = quote; 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iIn += 2; 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z[iOut++] = z[iIn++]; 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) z[iOut] = '\0'; 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Connect to or create a vfslog virtual table. 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vlogConnect( 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db, 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *pAux, 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, const char *const*argv, 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vtab **ppVtab, 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char **pzErr 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vfs *pVfs; /* VFS used to read log file */ 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int flags; /* flags passed to pVfs->xOpen() */ 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogVtab *p; 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nByte; 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zFile; 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ppVtab = 0; 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pVfs = sqlite3_vfs_find(0); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nByte = sizeof(VfslogVtab) + pVfs->szOsFile + pVfs->mxPathname; 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = sqlite3_malloc(nByte); 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p==0 ) return SQLITE_NOMEM; 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(p, 0, nByte); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pFd = (sqlite3_file *)&p[1]; 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->zFile = &((char *)p->pFd)[pVfs->szOsFile]; 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zFile = sqlite3_mprintf("%s", argv[3]); 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !zFile ){ 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(p); 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_NOMEM; 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dequote(zFile); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pVfs->xFullPathname(pVfs, zFile, pVfs->mxPathname, p->zFile); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(zFile); 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MASTER_JOURNAL; 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = pVfs->xOpen(pVfs, p->zFile, p->pFd, flags, &flags); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pFd->pMethods->xFileSize(p->pFd, &p->nByte); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_declare_vtab(db, 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "CREATE TABLE xxx(event, file, click, rc, size, offset)" 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ppVtab = &p->base; 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(p); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** There is no "best-index". This virtual table always does a linear 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** scan of the binary VFS log file. 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vlogBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pIdxInfo->estimatedCost = 10.0; 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Disconnect from or destroy a vfslog virtual table. 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vlogDisconnect(sqlite3_vtab *pVtab){ 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogVtab *p = (VfslogVtab *)pVtab; 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( p->pFd->pMethods ){ 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pFd->pMethods->xClose(p->pFd); 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p->pFd->pMethods = 0; 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(p); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Open a new vfslog cursor. 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vlogOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogCsr *pCsr; /* Newly allocated cursor object */ 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCsr = sqlite3_malloc(sizeof(VfslogCsr)); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !pCsr ) return SQLITE_NOMEM; 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(pCsr, 0, sizeof(VfslogCsr)); 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ppCursor = &pCsr->base; 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Close a vfslog cursor. 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vlogClose(sqlite3_vtab_cursor *pCursor){ 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogCsr *p = (VfslogCsr *)pCursor; 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<p->nFile; i++){ 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(p->azFile[i]); 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(p->azFile); 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(p->zTransient); 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(p); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Move a vfslog cursor to the next entry in the file. 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vlogNext(sqlite3_vtab_cursor *pCursor){ 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogCsr *pCsr = (VfslogCsr *)pCursor; 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogVtab *p = (VfslogVtab *)pCursor->pVtab; 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_OK; 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nRead; 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(pCsr->zTransient); 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCsr->zTransient = 0; 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRead = 24; 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pCsr->iOffset+nRead<=p->nByte ){ 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int eEvent; 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pFd->pMethods->xRead(p->pFd, pCsr->aBuf, nRead, pCsr->iOffset); 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) eEvent = get32bits(pCsr->aBuf); 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( (rc==SQLITE_OK) 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) && (eEvent==OS_OPEN || eEvent==OS_DELETE || eEvent==OS_ACCESS) 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ){ 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char buf[4]; 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pFd->pMethods->xRead(p->pFd, buf, 4, pCsr->iOffset+nRead); 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRead += 4; 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc==SQLITE_OK ){ 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nStr = get32bits((unsigned char *)buf); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zStr = sqlite3_malloc(nStr+1); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = p->pFd->pMethods->xRead(p->pFd, zStr, nStr, pCsr->iOffset+nRead); 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zStr[nStr] = '\0'; 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nRead += nStr; 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( eEvent==OS_OPEN ){ 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iFileid = get32bits(&pCsr->aBuf[4]); 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( iFileid>=pCsr->nFile ){ 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nNew = sizeof(pCsr->azFile[0])*(iFileid+1); 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCsr->azFile = (char **)sqlite3_realloc(pCsr->azFile, nNew); 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nNew -= sizeof(pCsr->azFile[0])*pCsr->nFile; 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(&pCsr->azFile[pCsr->nFile], 0, nNew); 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCsr->nFile = iFileid+1; 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(pCsr->azFile[iFileid]); 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCsr->azFile[iFileid] = zStr; 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCsr->zTransient = zStr; 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCsr->iRowid += 1; 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCsr->iOffset += nRead; 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vlogEof(sqlite3_vtab_cursor *pCursor){ 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogCsr *pCsr = (VfslogCsr *)pCursor; 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogVtab *p = (VfslogVtab *)pCursor->pVtab; 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (pCsr->iOffset>=p->nByte); 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vlogFilter( 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vtab_cursor *pCursor, 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idxNum, const char *idxStr, 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, sqlite3_value **argv 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogCsr *pCsr = (VfslogCsr *)pCursor; 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCsr->iRowid = 0; 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCsr->iOffset = 20; 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return vlogNext(pCursor); 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vlogColumn( 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vtab_cursor *pCursor, 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_context *ctx, 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int val; 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogCsr *pCsr = (VfslogCsr *)pCursor; 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert( i<7 ); 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val = get32bits(&pCsr->aBuf[4*i]); 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch( i ){ 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0: { 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_result_text(ctx, vfslog_eventname(val), -1, SQLITE_STATIC); 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: { 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zStr = pCsr->zTransient; 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( val!=0 && val<pCsr->nFile ){ 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zStr = pCsr->azFile[val]; 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_result_text(ctx, zStr, -1, SQLITE_TRANSIENT); 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_result_int(ctx, val); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int vlogRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VfslogCsr *pCsr = (VfslogCsr *)pCursor; 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pRowid = pCsr->iRowid; 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_vfslog_register(sqlite3 *db){ 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static sqlite3_module vfslog_module = { 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* iVersion */ 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vlogConnect, /* xCreate */ 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vlogConnect, /* xConnect */ 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vlogBestIndex, /* xBestIndex */ 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vlogDisconnect, /* xDisconnect */ 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vlogDisconnect, /* xDestroy */ 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vlogOpen, /* xOpen - open a cursor */ 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vlogClose, /* xClose - close a cursor */ 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vlogFilter, /* xFilter - configure scan constraints */ 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vlogNext, /* xNext - advance a cursor */ 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vlogEof, /* xEof - check for end of scan */ 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vlogColumn, /* xColumn - read data */ 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vlogRowid, /* xRowid - read data */ 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xUpdate */ 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xBegin */ 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xSync */ 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xCommit */ 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xRollback */ 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xFindMethod */ 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xRename */ 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_create_module(db, "vfslog", &vfslog_module, 0); 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_VIRTUALTABLE */ 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************** 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*************************************************************************** 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Tcl interface starts here. 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(SQLITE_TEST) || defined(TCLSH) 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <tcl.h> 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_vfslog( 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *clientData, 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct SqliteDb { sqlite3 *db; }; 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db; 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_CmdInfo cmdInfo; 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_ERROR; 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char *strs[] = { "annotate", "finalize", "new", "register", 0 }; 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum VL_enum { VL_ANNOTATE, VL_FINALIZE, VL_NEW, VL_REGISTER }; 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int iSub; 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc<2 ){ 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "SUB-COMMAND ..."); 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetIndexFromObj(interp, objv[1], strs, "sub-command", 0, &iSub) ){ 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch( (enum VL_enum)iSub ){ 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case VL_ANNOTATE: { 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zVfs; 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zMsg; 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=4 ){ 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 3, objv, "VFS"); 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zVfs = Tcl_GetString(objv[2]); 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zMsg = Tcl_GetString(objv[3]); 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_vfslog_annotate(zVfs, zMsg); 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=SQLITE_OK ){ 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "failed", 0); 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case VL_FINALIZE: { 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zVfs; 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=3 ){ 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 2, objv, "VFS"); 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zVfs = Tcl_GetString(objv[2]); 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_vfslog_finalize(zVfs); 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=SQLITE_OK ){ 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "failed", 0); 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case VL_NEW: { 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zVfs; 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zParent; 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zLog; 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=5 ){ 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 2, objv, "VFS PARENT LOGFILE"); 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zVfs = Tcl_GetString(objv[2]); 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zParent = Tcl_GetString(objv[3]); 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zLog = Tcl_GetString(objv[4]); 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( *zParent=='\0' ) zParent = 0; 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_vfslog_new(zVfs, zParent, zLog); 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=SQLITE_OK ){ 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "failed", 0); 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case VL_REGISTER: { 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zDb; 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=3 ){ 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 2, objv, "DB"); 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_OMIT_VIRTUALTABLE 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "vfslog not available because of " 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SQLITE_OMIT_VIRTUALTABLE", (void*)0); 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zDb = Tcl_GetString(objv[2]); 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){ 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db = ((struct SqliteDb*)cmdInfo.objClientData)->db; 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_vfslog_register(db); 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=SQLITE_OK ){ 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_AppendResult(interp, "bad sqlite3 handle: ", zDb, (void*)0); 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SqlitetestOsinst_Init(Tcl_Interp *interp){ 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_CreateObjCommand(interp, "vfslog", test_vfslog, 0, 0); 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_TEST */ 1212