/*
** Performance test for SQLite.
**
** This program reads ASCII text from a file named on the command-line
** and submits that text  to SQLite for evaluation.  A new database
** is created at the beginning of the program.  All statements are
** timed using the high-resolution timer built into Intel-class processors.
**
** To compile this program, first compile the SQLite library separately
** will full optimizations.  For example:
**
**     gcc -c -O6 -DSQLITE_THREADSAFE=0 sqlite3.c
**
** Then link against this program.  But to do optimize this program
** because that defeats the hi-res timer.
**
**     gcc speedtest8.c sqlite3.o -ldl -I../src
**
** Then run this program with a single argument which is the name of
** a file containing SQL script that you want to test:
**
**     ./a.out test.db  test.sql
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <stdarg.h>
#include "sqlite3.h"

#include "test_osinst.c"

/*
** Prepare and run a single statement of SQL.
*/
static void prepareAndRun(sqlite3_vfs *pInstVfs, sqlite3 *db, const char *zSql){
  sqlite3_stmt *pStmt;
  const char *stmtTail;
  int rc;
  char zMessage[1024];
  zMessage[1023] = '\0';

  sqlite3_uint64 iTime;

  sqlite3_snprintf(1023, zMessage, "sqlite3_prepare_v2: %s", zSql);
  sqlite3_instvfs_binarylog_marker(pInstVfs, zMessage);

  iTime = sqlite3Hwtime();
  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &stmtTail);
  iTime = sqlite3Hwtime() - iTime;
  sqlite3_instvfs_binarylog_call(pInstVfs,BINARYLOG_PREPARE_V2,iTime,rc,zSql);

  if( rc==SQLITE_OK ){
    int nRow = 0;

    sqlite3_snprintf(1023, zMessage, "sqlite3_step loop: %s", zSql);
    sqlite3_instvfs_binarylog_marker(pInstVfs, zMessage);
    iTime = sqlite3Hwtime();
    while( (rc=sqlite3_step(pStmt))==SQLITE_ROW ){ nRow++; }
    iTime = sqlite3Hwtime() - iTime;
    sqlite3_instvfs_binarylog_call(pInstVfs, BINARYLOG_STEP, iTime, rc, zSql);

    sqlite3_snprintf(1023, zMessage, "sqlite3_finalize: %s", zSql);
    sqlite3_instvfs_binarylog_marker(pInstVfs, zMessage);
    iTime = sqlite3Hwtime();
    rc = sqlite3_finalize(pStmt);
    iTime = sqlite3Hwtime() - iTime;
    sqlite3_instvfs_binarylog_call(pInstVfs, BINARYLOG_FINALIZE, iTime, rc, zSql);
  }
}

static int stringcompare(const char *zLeft, const char *zRight){
  int ii;
  for(ii=0; zLeft[ii] && zRight[ii]; ii++){
    if( zLeft[ii]!=zRight[ii] ) return 0;
  }
  return( zLeft[ii]==zRight[ii] );
}

static char *readScriptFile(const char *zFile, int *pnScript){
  sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
  sqlite3_file *p;
  int rc;
  sqlite3_int64 nByte;
  char *zData = 0;
  int flags = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_DB;

  p = (sqlite3_file *)malloc(pVfs->szOsFile);
  rc = pVfs->xOpen(pVfs, zFile, p, flags, &flags);
  if( rc!=SQLITE_OK ){
    goto error_out;
  }

  rc = p->pMethods->xFileSize(p, &nByte);
  if( rc!=SQLITE_OK ){
    goto close_out;
  }

  zData = (char *)malloc(nByte+1);
  rc = p->pMethods->xRead(p, zData, nByte, 0);
  if( rc!=SQLITE_OK ){
    goto close_out;
  }
  zData[nByte] = '\0';

  p->pMethods->xClose(p);
  free(p);
  *pnScript = nByte;
  return zData;

close_out:
  p->pMethods->xClose(p);

error_out:
  free(p);
  free(zData);
  return 0;
}

int main(int argc, char **argv){

  const char zUsageMsg[] = 
    "Usage: %s options...\n"
    "  where available options are:\n"
    "\n"
    "    -db      DATABASE-FILE  (database file to operate on)\n"
    "    -script  SCRIPT-FILE    (script file to read sql from)\n"
    "    -log     LOG-FILE       (log file to create)\n"
    "    -logdata                (log all data to log file)\n"
    "\n"
    "  Options -db, -script and -log are compulsory\n"
    "\n"
  ;

  const char *zDb = 0;
  const char *zScript = 0;
  const char *zLog = 0;
  int logdata = 0;

  int ii;
  int i, j;
  int rc;

  sqlite3_vfs *pInstVfs;                 /* Instrumentation VFS */

  char *zSql = 0;
  int nSql;

  sqlite3 *db;

  for(ii=1; ii<argc; ii++){
    if( stringcompare("-db", argv[ii]) && (ii+1)<argc ){
      zDb = argv[++ii];
    }

    else if( stringcompare("-script", argv[ii]) && (ii+1)<argc ){
      zScript = argv[++ii];
    }

    else if( stringcompare("-log", argv[ii]) && (ii+1)<argc ){
      zLog = argv[++ii];
    }

    else if( stringcompare("-logdata", argv[ii]) ){
      logdata = 1;
    }

    else {
      goto usage;
    }
  }
  if( !zDb || !zScript || !zLog ) goto usage;

  zSql = readScriptFile(zScript, &nSql);
  if( !zSql ){
    fprintf(stderr, "Failed to read script file\n");
    return -1;
  }

  pInstVfs = sqlite3_instvfs_binarylog("logging", 0, zLog, logdata);

  rc = sqlite3_open_v2(
     zDb, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, "logging"
  );
  if( rc!=SQLITE_OK ){
    fprintf(stderr, "Failed to open db: %s\n", sqlite3_errmsg(db));
    return -2;
  }

  for(i=j=0; j<nSql; j++){
    if( zSql[j]==';' ){
      int isComplete;
      char c = zSql[j+1];
      zSql[j+1] = 0;
      isComplete = sqlite3_complete(&zSql[i]);
      zSql[j+1] = c;
      if( isComplete ){
        zSql[j] = 0;
        while( i<j && isspace(zSql[i]) ){ i++; }
        if( i<j ){
          prepareAndRun(pInstVfs, db, &zSql[i]);
        }
        zSql[j] = ';';
        i = j+1;
      }
    }
  }
  
  sqlite3_instvfs_destroy(pInstVfs);
  return 0;
  
usage:
  fprintf(stderr, zUsageMsg, argv[0]);
  return -3;
}
