/ Check-in [98bdc7b4]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Update utility program speedtest8inst1.c. (CVS 5201)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 98bdc7b44db737d3b77aa76c139995d2b185cd85
User & Date: danielk1977 2008-06-11 11:00:31
Context
2008-06-11
18:01
Add a test case for the database corruption in the form of cell offsets out of range in an otherwise valid btree page. (CVS 5202) check-in: c569a6cf user: drh tags: trunk
11:00
Update utility program speedtest8inst1.c. (CVS 5201) check-in: 98bdc7b4 user: danielk1977 tags: trunk
2008-06-10
17:41
A completely new design for the sqlite3_initialize() and sqlite3_shutdown() interfaces. (CVS 5200) check-in: 7dfcd73d user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/test_osinst.c.

    10     10   **
    11     11   ******************************************************************************
    12     12   **
    13     13   ** This file contains the implementation of an SQLite vfs wrapper that
    14     14   ** adds instrumentation to all vfs and file methods. C and Tcl interfaces
    15     15   ** are provided to control the instrumentation.
    16     16   **
    17         -** $Id: test_osinst.c,v 1.14 2008/06/06 11:11:26 danielk1977 Exp $
           17  +** $Id: test_osinst.c,v 1.15 2008/06/11 11:00:31 danielk1977 Exp $
    18     18   */
    19     19   
    20     20   /*
    21     21   ** C interface:
    22     22   **
    23     23   **   sqlite3_instvfs_create()
    24     24   **   sqlite3_instvfs_destroy()
................................................................................
   118    118   #define OS_UNLOCK            19
   119    119   #define OS_WRITE             20
   120    120   
   121    121   #define OS_NUMEVENTS         21
   122    122   
   123    123   #define BINARYLOG_STRING     30
   124    124   #define BINARYLOG_MARKER     31
          125  +
          126  +#define BINARYLOG_PREPARE_V2 64
          127  +#define BINARYLOG_STEP       65
          128  +#define BINARYLOG_FINALIZE   66
   125    129   
   126    130   struct InstVfs {
   127    131     sqlite3_vfs base;
   128    132     sqlite3_vfs *pVfs;
   129    133   
   130    134     void *pClient;
   131    135     void (*xDel)(void *);
................................................................................
   257    261     return rc;                             \
   258    262   }
   259    263   
   260    264   /*
   261    265   ** Close an inst-file.
   262    266   */
   263    267   static int instClose(sqlite3_file *pFile){
   264         -  OS_TIME_IO(OS_CLOSE, 0, 0, p->pReal->pMethods->xClose(p->pReal));
          268  +  OS_TIME_IO(OS_CLOSE, 0, 0, 
          269  +    (p->pReal->pMethods ? p->pReal->pMethods->xClose(p->pReal) : SQLITE_OK)
          270  +  );
   265    271   }
   266    272   
   267    273   /*
   268    274   ** Read data from an inst-file.
   269    275   */
   270    276   static int instRead(
   271    277     sqlite3_file *pFile, 
................................................................................
   728    734       put32bits(&zRec[0], BINARYLOG_STRING);
   729    735       put32bits(&zRec[4], (int)nBlob);
   730    736       put32bits(&zRec[8], (int)isBinary);
   731    737       memcpy(&zRec[28], zBlob, nBlob);
   732    738       pLog->nBuf += nWrite;
   733    739     }
   734    740   }
          741  +
          742  +void sqlite3_instvfs_binarylog_call(
          743  +  sqlite3_vfs *pVfs,
          744  +  int eEvent,
          745  +  sqlite3_int64 nClick,
          746  +  int return_code,
          747  +  const char *zString
          748  +){
          749  +  InstVfs *pInstVfs = (InstVfs *)pVfs;
          750  +  InstVfsBinaryLog *pLog = (InstVfsBinaryLog *)pInstVfs->pClient;
          751  +
          752  +  if( zString ){
          753  +    binarylog_blob(pVfs, zString, -1, 0);
          754  +  }
          755  +  binarylog_xcall(pLog, eEvent, 0, nClick, return_code, 0, 0, 0, 0);
          756  +}
   735    757   
   736    758   void sqlite3_instvfs_binarylog_marker(
   737    759     sqlite3_vfs *pVfs,
   738    760     const char *zMarker
   739    761   ){
   740    762     InstVfs *pInstVfs = (InstVfs *)pVfs;
   741    763     InstVfsBinaryLog *pLog = (InstVfsBinaryLog *)pInstVfs->pClient;

Changes to tool/speedtest8inst1.c.

    25     25   #include <string.h>
    26     26   #include <stdlib.h>
    27     27   #include <ctype.h>
    28     28   #include <unistd.h>
    29     29   #include <stdarg.h>
    30     30   #include "sqlite3.h"
    31     31   
    32         -/* 
    33         -** hwtime.h contains inline assembler code for implementing 
    34         -** high-performance timing routines.
    35         -*/
    36         -#include "hwtime.h"
    37         -
    38         -/*
    39         -** Send a message to the log file.
    40         -*/
    41         -static void logMessage(const char *zFormat, ...){
    42         -  va_list ap;
    43         -  va_start(ap, zFormat);
    44         -  vprintf(zFormat, ap);
    45         -  va_end(ap);
    46         -}
    47         -
    48         -/*
    49         -** Timers
    50         -*/
    51         -static sqlite3_uint64 prepTime = 0;
    52         -static sqlite3_uint64 runTime = 0;
    53         -static sqlite3_uint64 finalizeTime = 0;
    54         -static sqlite3_uint64 instTime = 0;
    55         -
    56         -typedef struct inst_file inst_file;
    57         -struct inst_file {
    58         -  sqlite3_file base;
    59         -  sqlite3_file *pReal;
    60         -};
    61         -
    62         -/*
    63         -** Method declarations for inst_file.
    64         -*/
    65         -static int instClose(sqlite3_file*);
    66         -static int instRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
    67         -static int instWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
    68         -static int instTruncate(sqlite3_file*, sqlite3_int64 size);
    69         -static int instSync(sqlite3_file*, int flags);
    70         -static int instFileSize(sqlite3_file*, sqlite3_int64 *pSize);
    71         -static int instLock(sqlite3_file*, int);
    72         -static int instUnlock(sqlite3_file*, int);
    73         -static int instCheckReservedLock(sqlite3_file*);
    74         -static int instFileControl(sqlite3_file*, int op, void *pArg);
    75         -static int instSectorSize(sqlite3_file*);
    76         -static int instDeviceCharacteristics(sqlite3_file*);
    77         -
    78         -/*
    79         -** Method declarations for inst_vfs.
    80         -*/
    81         -static int instOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
    82         -static int instDelete(sqlite3_vfs*, const char *zName, int syncDir);
    83         -static int instAccess(sqlite3_vfs*, const char *zName, int flags);
    84         -static int instGetTempName(sqlite3_vfs*, int nOut, char *zOut);
    85         -static int instFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
    86         -static void *instDlOpen(sqlite3_vfs*, const char *zFilename);
    87         -static void instDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
    88         -static void *instDlSym(sqlite3_vfs*,void*, const char *zSymbol);
    89         -static void instDlClose(sqlite3_vfs*, void*);
    90         -static int instRandomness(sqlite3_vfs*, int nByte, char *zOut);
    91         -static int instSleep(sqlite3_vfs*, int microseconds);
    92         -static int instCurrentTime(sqlite3_vfs*, double*);
    93         -
    94         -static sqlite3_vfs inst_vfs = {
    95         -  1,                      /* iVersion */
    96         -  0,                      /* szOsFile */
    97         -  0,                      /* mxPathname */
    98         -  0,                      /* pNext */
    99         -  "instVfs",              /* zName */
   100         -  0,                      /* pAppData */
   101         -  instOpen,               /* xOpen */
   102         -  instDelete,             /* xDelete */
   103         -  instAccess,             /* xAccess */
   104         -  instGetTempName,        /* xGetTempName */
   105         -  instFullPathname,       /* xFullPathname */
   106         -  instDlOpen,             /* xDlOpen */
   107         -  instDlError,            /* xDlError */
   108         -  instDlSym,              /* xDlSym */
   109         -  instDlClose,            /* xDlClose */
   110         -  instRandomness,         /* xRandomness */
   111         -  instSleep,              /* xSleep */
   112         -  instCurrentTime         /* xCurrentTime */
   113         -};
   114         -
   115         -static sqlite3_io_methods inst_io_methods = {
   116         -  1,                            /* iVersion */
   117         -  instClose,                      /* xClose */
   118         -  instRead,                       /* xRead */
   119         -  instWrite,                      /* xWrite */
   120         -  instTruncate,                   /* xTruncate */
   121         -  instSync,                       /* xSync */
   122         -  instFileSize,                   /* xFileSize */
   123         -  instLock,                       /* xLock */
   124         -  instUnlock,                     /* xUnlock */
   125         -  instCheckReservedLock,          /* xCheckReservedLock */
   126         -  instFileControl,                /* xFileControl */
   127         -  instSectorSize,                 /* xSectorSize */
   128         -  instDeviceCharacteristics       /* xDeviceCharacteristics */
   129         -};
   130         -
   131         -#define OS_TIME_IO(MESSAGE, A, B, CALL)      \
   132         -  int rc;                                    \
   133         -  sqlite_uint64 t1, t2;                      \
   134         -  inst_file *p = (inst_file*)pFile;          \
   135         -  t1 = sqlite3Hwtime();                      \
   136         -  rc = CALL;                                 \
   137         -  t2 = sqlite3Hwtime();                      \
   138         -  logMessage(MESSAGE, A, B, t2-t1);          \
   139         -  instTime += sqlite3Hwtime() - t2;          \
   140         -  return rc;
   141         -
   142         -#define OS_TIME_VFS(MESSAGE, A, B, CALL)                 \
   143         -  int rc;                                                \
   144         -  sqlite_uint64 t1, t2;                                  \
   145         -  sqlite3_vfs *pRealVfs = (sqlite3_vfs*)pVfs->pAppData;  \
   146         -  t1 = sqlite3Hwtime();                                  \
   147         -  rc = CALL;                                             \
   148         -  t2 = sqlite3Hwtime();                                  \
   149         -  logMessage(MESSAGE, A, B, t2-t1);                      \
   150         -  instTime += sqlite3Hwtime() - t2;                      \
   151         -  return rc;
   152         -
   153         -
   154         -/*
   155         -** Close an inst-file.
   156         -*/
   157         -static int instClose(sqlite3_file *pFile){
   158         -  OS_TIME_IO("xClose: %s%s%lld cycles\n", "", "",
   159         -    p->pReal->pMethods->xClose(p->pReal)
   160         -  );
   161         -}
   162         -
   163         -/*
   164         -** Read data from an inst-file.
   165         -*/
   166         -static int instRead(
   167         -  sqlite3_file *pFile, 
   168         -  void *zBuf, 
   169         -  int iAmt, 
   170         -  sqlite_int64 iOfst
   171         -){
   172         -  OS_TIME_IO("xRead: %d bytes at offset %lld - %lld cycles\n", iAmt, iOfst, 
   173         -    p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt,iOfst)
   174         -  );
   175         -}
   176         -
   177         -/*
   178         -** Write data to an inst-file.
   179         -*/
   180         -static int instWrite(
   181         -  sqlite3_file *pFile,
   182         -  const void *z,
   183         -  int iAmt,
   184         -  sqlite_int64 iOfst
   185         -){
   186         -  OS_TIME_IO("xWrite: %d bytes at offset %lld - %lld cycles\n", iAmt, iOfst,
   187         -    p->pReal->pMethods->xWrite(p->pReal, z, iAmt, iOfst)
   188         -  );
   189         -}
   190         -
   191         -/*
   192         -** Truncate an inst-file.
   193         -*/
   194         -static int instTruncate(sqlite3_file *pFile, sqlite_int64 size){
   195         -  OS_TIME_IO("xTruncate: to %lld bytes - %s%lld cycles\n", size, "",
   196         -    p->pReal->pMethods->xTruncate(p->pReal, size)
   197         -  );
   198         -}
   199         -
   200         -/*
   201         -** Sync an inst-file.
   202         -*/
   203         -static int instSync(sqlite3_file *pFile, int flags){
   204         -  OS_TIME_IO("xSync: %s%s%lld cycles\n", "", "", 
   205         -    p->pReal->pMethods->xSync(p->pReal, flags)
   206         -  );
   207         -}
   208         -
   209         -/*
   210         -** Return the current file-size of an inst-file.
   211         -*/
   212         -static int instFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
   213         -  OS_TIME_IO("xFileSize: %s%s%lld cycles\n", "", "", 
   214         -    p->pReal->pMethods->xFileSize(p->pReal, pSize)
   215         -  );
   216         -}
   217         -
   218         -/*
   219         -** Lock an inst-file.
   220         -*/
   221         -static int instLock(sqlite3_file *pFile, int eLock){
   222         -  OS_TIME_IO("xLock: %d %s%lld cycles\n", eLock, "",
   223         -    p->pReal->pMethods->xLock(p->pReal, eLock)
   224         -  );
   225         -}
   226         -
   227         -/*
   228         -** Unlock an inst-file.
   229         -*/
   230         -static int instUnlock(sqlite3_file *pFile, int eLock){
   231         -  OS_TIME_IO("xUnlock: %d %s%lld\n", eLock, "",
   232         -    p->pReal->pMethods->xUnlock(p->pReal, eLock)
   233         -  );
   234         -}
   235         -
   236         -/*
   237         -** Check if another file-handle holds a RESERVED lock on an inst-file.
   238         -*/
   239         -static int instCheckReservedLock(sqlite3_file *pFile){
   240         -  OS_TIME_IO("xCheckReservedLock: %s%s%lld cycles\n", "", "",
   241         -    p->pReal->pMethods->xCheckReservedLock(p->pReal)
   242         -  );
   243         -}
   244         -
   245         -/*
   246         -** File control method. For custom operations on an inst-file.
   247         -*/
   248         -static int instFileControl(sqlite3_file *pFile, int op, void *pArg){
   249         -  OS_TIME_IO("xFileControl:  op=%d - %s%lld cycles\n", op, "",
   250         -    p->pReal->pMethods->xFileControl(p->pReal, op, pArg)
   251         -  );
   252         -}
   253         -
   254         -/*
   255         -** Return the sector-size in bytes for an inst-file.
   256         -*/
   257         -static int instSectorSize(sqlite3_file *pFile){
   258         -  OS_TIME_IO("xSectorSize: %s%s%lld cycles\n", "", "",
   259         -    p->pReal->pMethods->xSectorSize(p->pReal)
   260         -  );
   261         -}
   262         -
   263         -/*
   264         -** Return the device characteristic flags supported by an inst-file.
   265         -*/
   266         -static int instDeviceCharacteristics(sqlite3_file *pFile){
   267         -  OS_TIME_IO("xDeviceCharacteristics: %s%s%lld cycles\n", "", "",
   268         -    p->pReal->pMethods->xDeviceCharacteristics(p->pReal)
   269         -  );
   270         -}
   271         -
   272         -/*
   273         -** Open an inst file handle.
   274         -*/
   275         -static int instOpen(
   276         -  sqlite3_vfs *pVfs,
   277         -  const char *zName,
   278         -  sqlite3_file *pFile,
   279         -  int flags,
   280         -  int *pOutFlags
   281         -){
   282         -  inst_file *p = (inst_file *)pFile;
   283         -  pFile->pMethods = &inst_io_methods;
   284         -  p->pReal = (sqlite3_file *)&p[1];
   285         -
   286         -  OS_TIME_VFS("xOpen: \"%s\" flags=0x04%x - %lld cycles\n", zName, flags,
   287         -    pRealVfs->xOpen(pRealVfs, zName, p->pReal, flags, pOutFlags)
   288         -  );
   289         -}
   290         -
   291         -/*
   292         -** Delete the file located at zPath. If the dirSync argument is true,
   293         -** ensure the file-system modifications are synced to disk before
   294         -** returning.
   295         -*/
   296         -static int instDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
   297         -  OS_TIME_VFS("xDelete:  \"%s\", dirSync=%d - %lld cycles\n",
   298         -    zPath, dirSync,
   299         -    pRealVfs->xDelete(pRealVfs, zPath, dirSync) 
   300         -  );
   301         -}
   302         -
   303         -/*
   304         -** Test for access permissions. Return true if the requested permission
   305         -** is available, or false otherwise.
   306         -*/
   307         -static int instAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
   308         -  OS_TIME_VFS("xAccess of \"%s\", flags=0x%04x - %lld cycles\n",
   309         -    zPath, flags,
   310         -    pRealVfs->xAccess(pRealVfs, zPath, flags) 
   311         -  );
   312         -}
   313         -
   314         -/*
   315         -** Populate buffer zBufOut with a pathname suitable for use as a 
   316         -** temporary file. zBufOut is guaranteed to point to a buffer of 
   317         -** at least (INST_MAX_PATHNAME+1) bytes.
   318         -*/
   319         -static int instGetTempName(sqlite3_vfs *pVfs, int nOut, char *zBufOut){
   320         -  OS_TIME_VFS("xGetTempName: %s%s%lld cycles\n", "", "",
   321         -    pRealVfs->xGetTempname(pRealVfs, nOut, zBufOut)
   322         -  );
   323         -}
   324         -
   325         -/*
   326         -** Populate buffer zOut with the full canonical pathname corresponding
   327         -** to the pathname in zPath. zOut is guaranteed to point to a buffer
   328         -** of at least (INST_MAX_PATHNAME+1) bytes.
   329         -*/
   330         -static int instFullPathname(
   331         -  sqlite3_vfs *pVfs, 
   332         -  const char *zPath, 
   333         -  int nOut, 
   334         -  char *zOut
   335         -){
   336         -  OS_TIME_VFS("xFullPathname: \"%s\" - %s%lld cycles\n",
   337         -    zPath, "",
   338         -    pRealVfs->xFullPathname(pRealVfs, zPath, nOut, zOut)
   339         -  );
   340         -}
   341         -
   342         -/*
   343         -** Open the dynamic library located at zPath and return a handle.
   344         -*/
   345         -static void *instDlOpen(sqlite3_vfs *pVfs, const char *zPath){
   346         -  sqlite3_vfs *pRealVfs = (sqlite3_vfs*)pVfs->pAppData;
   347         -  return pRealVfs->xDlOpen(pRealVfs, zPath);
   348         -}
   349         -
   350         -/*
   351         -** Populate the buffer zErrMsg (size nByte bytes) with a human readable
   352         -** utf-8 string describing the most recent error encountered associated 
   353         -** with dynamic libraries.
   354         -*/
   355         -static void instDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
   356         -  sqlite3_vfs *pRealVfs = (sqlite3_vfs*)pVfs->pAppData;
   357         -  pRealVfs->xDlError(pRealVfs, nByte, zErrMsg);
   358         -}
   359         -
   360         -/*
   361         -** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
   362         -*/
   363         -static void *instDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
   364         -  sqlite3_vfs *pRealVfs = (sqlite3_vfs*)pVfs->pAppData;
   365         -  return pRealVfs->xDlSym(pRealVfs, pHandle, zSymbol);
   366         -}
   367         -
   368         -/*
   369         -** Close the dynamic library handle pHandle.
   370         -*/
   371         -static void instDlClose(sqlite3_vfs *pVfs, void *pHandle){
   372         -  sqlite3_vfs *pRealVfs = (sqlite3_vfs*)pVfs->pAppData;
   373         -  pRealVfs->xDlClose(pRealVfs, pHandle);
   374         -}
   375         -
   376         -/*
   377         -** Populate the buffer pointed to by zBufOut with nByte bytes of 
   378         -** random data.
   379         -*/
   380         -static int instRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
   381         -  OS_TIME_VFS("xRandomness:  nByte=%d - %s%lld cycles\n", nByte, "",
   382         -    pRealVfs->xRandomness(pRealVfs, nByte, zBufOut)
   383         -  );
   384         -}
   385         -
   386         -/*
   387         -** Sleep for nMicro microseconds. Return the number of microseconds 
   388         -** actually slept.
   389         -*/
   390         -static int instSleep(sqlite3_vfs *pVfs, int nMicro){
   391         -  OS_TIME_VFS("xSleep:  usec=%d - %s%lld cycles\n", nMicro, "",
   392         -    pRealVfs->xSleep(pRealVfs, nMicro) 
   393         -  );
   394         -}
   395         -
   396         -/*
   397         -** Return the current time as a Julian Day number in *pTimeOut.
   398         -*/
   399         -static int instCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
   400         -  OS_TIME_VFS("xCurrentTime:  %s%s%lld cycles\n", "", "",
   401         -    pRealVfs->xCurrentTime(pRealVfs, pTimeOut) 
   402         -  );
   403         -}
   404         -
   405         -/*
   406         -** Insert the instructed VFS as the default VFS.
   407         -*/
   408         -static void setupInstrumentedVfs(void){
   409         -  sqlite3_vfs *p;
   410         -  sqlite3_vfs *pParent;
   411         -
   412         -  pParent = sqlite3_vfs_find(0);
   413         -  if( !pParent ){
   414         -    return;
   415         -  }
   416         -
   417         -  p = sqlite3_malloc(sizeof(inst_vfs));
   418         -  if( p ){
   419         -    *p = inst_vfs;
   420         -    p->szOsFile = pParent->szOsFile + sizeof(inst_file);
   421         -    p->mxPathname = pParent->mxPathname;
   422         -    p->pAppData = pParent;
   423         -    sqlite3_vfs_register(p, 1);
   424         -  }
   425         -}
   426         -
           32  +#include "test_osinst.c"
   427     33   
   428     34   /*
   429     35   ** Prepare and run a single statement of SQL.
   430     36   */
   431         -static void prepareAndRun(sqlite3 *db, const char *zSql){
           37  +static void prepareAndRun(sqlite3_vfs *pInstVfs, sqlite3 *db, const char *zSql){
   432     38     sqlite3_stmt *pStmt;
   433     39     const char *stmtTail;
   434         -  sqlite_uint64 iStart, iElapse;
   435     40     int rc;
           41  +  char zMessage[1024];
           42  +  zMessage[1023] = '\0';
   436     43     
   437         -  printf("****************************************************************\n");
   438         -  printf("SQL statement: [%s]\n", zSql);
   439         -  instTime = 0;
   440         -  iStart = sqlite3Hwtime();
           44  +  sqlite3_uint64 iTime;
           45  +
           46  +  sqlite3_snprintf(1023, zMessage, "sqlite3_prepare_v2: %s", zSql);
           47  +  sqlite3_instvfs_binarylog_marker(pInstVfs, zMessage);
           48  +
           49  +  iTime = sqlite3Hwtime();
   441     50     rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &stmtTail);
   442         -  iElapse = sqlite3Hwtime();
   443         -  iElapse -= iStart + instTime;
   444         -  prepTime += iElapse;
   445         -  printf("sqlite3_prepare_v2() returns %d in %llu cycles\n", rc, iElapse);
           51  +  iTime = sqlite3Hwtime() - iTime;
           52  +  sqlite3_instvfs_binarylog_call(pInstVfs,BINARYLOG_PREPARE_V2,iTime,rc,zSql);
           53  +
   446     54     if( rc==SQLITE_OK ){
   447     55       int nRow = 0;
   448         -    instTime = 0;
   449         -    iStart = sqlite3Hwtime();
           56  +
           57  +    sqlite3_snprintf(1023, zMessage, "sqlite3_step loop: %s", zSql);
           58  +    sqlite3_instvfs_binarylog_marker(pInstVfs, zMessage);
           59  +    iTime = sqlite3Hwtime();
   450     60       while( (rc=sqlite3_step(pStmt))==SQLITE_ROW ){ nRow++; }
   451         -    iElapse = sqlite3Hwtime();
   452         -    iElapse -= iStart + instTime;
   453         -    runTime += iElapse;
   454         -    printf("sqlite3_step() returns %d after %d rows in %llu cycles\n",
   455         -           rc, nRow, iElapse);
   456         -    instTime = 0;
   457         -    iStart = sqlite3Hwtime();
           61  +    iTime = sqlite3Hwtime() - iTime;
           62  +    sqlite3_instvfs_binarylog_call(pInstVfs, BINARYLOG_STEP, iTime, rc, zSql);
           63  +
           64  +    sqlite3_snprintf(1023, zMessage, "sqlite3_finalize: %s", zSql);
           65  +    sqlite3_instvfs_binarylog_marker(pInstVfs, zMessage);
           66  +    iTime = sqlite3Hwtime();
   458     67       rc = sqlite3_finalize(pStmt);
   459         -    iElapse = sqlite3Hwtime();
   460         -    iElapse -= iStart + instTime;
   461         -    finalizeTime += iElapse;
   462         -    printf("sqlite3_finalize() returns %d in %llu cycles\n", rc, iElapse);
           68  +    iTime = sqlite3Hwtime() - iTime;
           69  +    sqlite3_instvfs_binarylog_call(pInstVfs, BINARYLOG_FINALIZE, iTime, rc, zSql);
   463     70     }
   464     71   }
           72  +
           73  +static int stringcompare(const char *zLeft, const char *zRight){
           74  +  int ii;
           75  +  for(ii=0; zLeft[ii] && zRight[ii]; ii++){
           76  +    if( zLeft[ii]!=zRight[ii] ) return 0;
           77  +  }
           78  +  return( zLeft[ii]==zRight[ii] );
           79  +}
           80  +
           81  +static char *readScriptFile(const char *zFile, int *pnScript){
           82  +  sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
           83  +  sqlite3_file *p;
           84  +  int rc;
           85  +  sqlite3_int64 nByte;
           86  +  char *zData = 0;
           87  +  int flags = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_DB;
           88  +
           89  +  p = (sqlite3_file *)malloc(pVfs->szOsFile);
           90  +  rc = pVfs->xOpen(pVfs, zFile, p, flags, &flags);
           91  +  if( rc!=SQLITE_OK ){
           92  +    goto error_out;
           93  +  }
           94  +
           95  +  rc = p->pMethods->xFileSize(p, &nByte);
           96  +  if( rc!=SQLITE_OK ){
           97  +    goto close_out;
           98  +  }
           99  +
          100  +  zData = (char *)malloc(nByte+1);
          101  +  rc = p->pMethods->xRead(p, zData, nByte, 0);
          102  +  if( rc!=SQLITE_OK ){
          103  +    goto close_out;
          104  +  }
          105  +  zData[nByte] = '\0';
          106  +
          107  +  p->pMethods->xClose(p);
          108  +  free(p);
          109  +  *pnScript = nByte;
          110  +  return zData;
          111  +
          112  +close_out:
          113  +  p->pMethods->xClose(p);
          114  +
          115  +error_out:
          116  +  free(p);
          117  +  free(zData);
          118  +  return 0;
          119  +}
   465    120   
   466    121   int main(int argc, char **argv){
   467         -  sqlite3 *db;
   468         -  int rc;
   469         -  int nSql;
   470         -  char *zSql;
          122  +
          123  +  const char zUsageMsg[] = 
          124  +    "Usage: %s options...\n"
          125  +    "  where available options are:\n"
          126  +    "\n"
          127  +    "    -db      DATABASE-FILE  (database file to operate on)\n"
          128  +    "    -script  SCRIPT-FILE    (script file to read sql from)\n"
          129  +    "    -log     LOG-FILE       (log file to create)\n"
          130  +    "    -logdata                (log all data to log file)\n"
          131  +    "\n"
          132  +    "  Options -db, -script and -log are compulsory\n"
          133  +    "\n"
          134  +  ;
          135  +
          136  +  const char *zDb = 0;
          137  +  const char *zScript = 0;
          138  +  const char *zLog = 0;
          139  +  int logdata = 0;
          140  +
          141  +  int ii;
   471    142     int i, j;
   472         -  FILE *in;
   473         -  sqlite_uint64 iStart, iElapse;
   474         -  sqlite_uint64 iSetup = 0;
   475         -  int nStmt = 0;
   476         -  int nByte = 0;
          143  +  int rc;
          144  +
          145  +  sqlite3_vfs *pInstVfs;                 /* Instrumentation VFS */
          146  +
          147  +  char *zSql = 0;
          148  +  int nSql;
          149  +
          150  +  sqlite3 *db;
          151  +
          152  +  for(ii=1; ii<argc; ii++){
          153  +    if( stringcompare("-db", argv[ii]) && (ii+1)<argc ){
          154  +      zDb = argv[++ii];
          155  +    }
          156  +
          157  +    else if( stringcompare("-script", argv[ii]) && (ii+1)<argc ){
          158  +      zScript = argv[++ii];
          159  +    }
          160  +
          161  +    else if( stringcompare("-log", argv[ii]) && (ii+1)<argc ){
          162  +      zLog = argv[++ii];
          163  +    }
          164  +
          165  +    else if( stringcompare("-logdata", argv[ii]) ){
          166  +      logdata = 1;
          167  +    }
          168  +
          169  +    else {
          170  +      goto usage;
          171  +    }
          172  +  }
          173  +  if( !zDb || !zScript || !zLog ) goto usage;
   477    174   
   478         -  if( argc!=3 ){
   479         -    fprintf(stderr, "Usage: %s FILENAME SQL-SCRIPT\n"
   480         -                    "Runs SQL-SCRIPT against a UTF8 database\n",
   481         -                    argv[0]);
   482         -    exit(1);
          175  +  zSql = readScriptFile(zScript, &nSql);
          176  +  if( !zSql ){
          177  +    fprintf(stderr, "Failed to read script file\n");
          178  +    return -1;
   483    179     }
   484         -  in = fopen(argv[2], "r");
   485         -  fseek(in, 0L, SEEK_END);
   486         -  nSql = ftell(in);
   487         -  zSql = malloc( nSql+1 );
   488         -  fseek(in, 0L, SEEK_SET);
   489         -  nSql = fread(zSql, 1, nSql, in);
   490         -  zSql[nSql] = 0;
          180  +
          181  +  pInstVfs = sqlite3_instvfs_binarylog("logging", 0, zLog, logdata);
   491    182   
   492         -  printf("SQLite version: %d\n", sqlite3_libversion_number());
   493         -  unlink(argv[1]);
   494         -  setupInstrumentedVfs();
   495         -  instTime = 0;
   496         -  iStart = sqlite3Hwtime();
   497         -  rc = sqlite3_open(argv[1], &db);
   498         -  iElapse = sqlite3Hwtime();
   499         -  iElapse -= iStart + instTime;
   500         -  iSetup = iElapse;
   501         -  printf("sqlite3_open() returns %d in %llu cycles\n", rc, iElapse);
          183  +  rc = sqlite3_open_v2(
          184  +     zDb, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "logging"
          185  +  );
          186  +  if( rc!=SQLITE_OK ){
          187  +    fprintf(stderr, "Failed to open db: %s\n", sqlite3_errmsg(db));
          188  +    return -2;
          189  +  }
          190  +
   502    191     for(i=j=0; j<nSql; j++){
   503    192       if( zSql[j]==';' ){
   504    193         int isComplete;
   505    194         char c = zSql[j+1];
   506    195         zSql[j+1] = 0;
   507    196         isComplete = sqlite3_complete(&zSql[i]);
   508    197         zSql[j+1] = c;
   509    198         if( isComplete ){
   510    199           zSql[j] = 0;
   511    200           while( i<j && isspace(zSql[i]) ){ i++; }
   512    201           if( i<j ){
   513         -          nStmt++;
   514         -          nByte += j-i;
   515         -          prepareAndRun(db, &zSql[i]);
          202  +          prepareAndRun(pInstVfs, db, &zSql[i]);
   516    203           }
   517    204           zSql[j] = ';';
   518    205           i = j+1;
   519    206         }
   520    207       }
   521    208     }
   522         -  instTime = 0;
   523         -  iStart = sqlite3Hwtime();
   524         -  sqlite3_close(db);
   525         -  iElapse = sqlite3Hwtime();
   526         -  iElapse -= iStart + instTime;
   527         -  iSetup += iElapse;
   528         -  printf("sqlite3_close() returns in %llu cycles\n", iElapse);
   529         -  printf("\n");
   530         -  printf("Statements run:       %15d\n", nStmt);
   531         -  printf("Bytes of SQL text:    %15d\n", nByte);
   532         -  printf("Total prepare time:   %15llu cycles\n", prepTime);
   533         -  printf("Total run time:       %15llu cycles\n", runTime);
   534         -  printf("Total finalize time:  %15llu cycles\n", finalizeTime);
   535         -  printf("Open/Close time:      %15llu cycles\n", iSetup);
   536         -  printf("Total Time:           %15llu cycles\n",
   537         -      prepTime + runTime + finalizeTime + iSetup);
          209  +  
          210  +  sqlite3_instvfs_destroy(pInstVfs);
   538    211     return 0;
          212  +  
          213  +usage:
          214  +  fprintf(stderr, zUsageMsg, argv[0]);
          215  +  return -3;
   539    216   }