/* --------------------------------------------------- */
/* Source-file DBDIR 1.0, (C) Wabnig Harald, 25.5.2002 */
/* --------------------------------------------------- */

#include "dbrand.h"
#include "basis.h"
#include "dirdb.h"

static DBHANDLE * pDB;

/* ---------------------------------------------------------------- */

#define DIR_DATABASE  "DIRDB"

#define TABLE_DIR     "CREATE TABLE DIR (" \
                       "  DIR_ID INTEGER," \
                       "  IVAL INTEGER" \
                       ");"
#define INDEX_XDIR01  "CREATE UNIQUE INDEX XDIR01 ON DIR (" \
                       "  DIR_ID" \
                       ");"
#define INDEX_XDIR02  "CREATE INDEX XDIR02 ON DIR ("\
                       "  IVAL" \
                       ");"

/* ------------- */

int main (int argc, char *argv[])
{
  DIR Dir, Dir1;
  int iRc = TRUE;
  int i, j, min = 0, max, iCount;
  TFTimestamp ti1, ti2;
  double d;

  DIR_Init(&Dir);
  DIR_Init(&Dir1);

  fprintf(stdout, "DB-Dir 1.1, (C) Wabnig Harald, 12.07.2003\n");
#ifdef SPEEDY1
  if (! Speedy1_Init("", DIR_DATABASE)) {
    fprintf(stderr, "Speedy1_Init error!\n");
    exit(1);
  }
  DB_Set_Error_String();
  if (! DBHANDLE_Init(&pDB, DIR_DATABASE)) {
    DB_Print_Error_String();
    fprintf(stderr, "DBHANDLE_Init error!");
    exit(1);
  }
#else
  {
    char dbname[20];

    /* determine dbname from the commandline without default 'sdsys'
       if no dbname is given use 'test' */
    strcpy(dbname, "-");
    ARGV_GetDB_Name(argv, argc, dbname);
    if (strcmp(dbname, "") == 0) 
      strcpy(dbname, DIR_DATABASE);

    if (! DBHANDLE_Init(&pDB, dbname)) {
      fprintf(stderr, "DBHANDLE_Init error!");
      exit(1);
    }
  }
#endif

  /* Create database-tables/indices if necessary */

  if (! DB_Exists_Table(pDB, "DIR")) {
    if (! DB_Create_Table(pDB, TABLE_DIR)) {
      DB_Print_Error_String();
      fprintf(stderr, "DB_Create_Table 'DIR' error!\n");
      exit(1);
    }
  }
  if (! DB_Exists_Index(pDB, "XDIR01")) {
    if (! DB_Create_Index(pDB, INDEX_XDIR01)) {
      DB_Print_Error_String();
      fprintf(stderr, "DB_Create_Index 'XDIR01' error!\n");
      exit(1);
    }
  }
  if (! DB_Exists_Index(pDB, "XDIR02")) {
    if (! DB_Create_Index(pDB, INDEX_XDIR02)) {
      DB_Print_Error_String();
      fprintf(stderr, "DB_Create_Index 'XDIR02' error!\n");
      exit(1);
    }
  }

  /* set maximum rows returned from a select to 10000000 rows */

  if (! DB_Exec_SQL(pDB, "MAX 10000000", &iCount, TRUE)) {
    fprintf(stderr, "DB_Exec_SQL error!\n");
    exit(1);
  }

  /* get min(ival) */

  if (DIR_Selectcount_Id_Max(&Dir, &iCount, pDB)) {
    if (((iCount + 1) / 100000) * 100000 == iCount + 1)
      min = iCount + 1;
    else
      min = ((iCount + 1) / 100000 + 1) * 100000;
  }

  /* print count(*) */

  printf("\n------------------------------\n");
  if (! DB_Exec_SQL(pDB, "SELECT COUNT(*) FROM DIR", &iCount, TRUE)) {
    fprintf(stderr, "DB_Exec_SQL error!");
    exit(1);
  }
  printf("------------------------------\n");

  printf("\n------------------------------");
  printf("\nstarting with DIR_Id = %d", min);
  printf("\n------------------------------\n");

  /* ------------- */
  /* fill database */
  /* ------------- */

  printf("\n-------------------------------------------------------------------------------");
  printf("\nfilling database with DIR_Id min,min+1,min+2.. and IVAL random-value 0..1000000", min);
  printf("\n-------------------------------------------------------------------------------\n");

  for (i = 0; i < 30; i++) {

    Get_SysTimestamp(&ti1);

    if (! DB_Begin(pDB)) {
      fprintf(stderr, "DB_Begin error!\n");
      exit(1);
    }

    for (j = 0; j < 1000; j++) {

      Dir.flDIR_Id = i * 1000 + j + min;
      Dir.flIVal = irand(0, 1000000);

      if (! DIR_Insert(&Dir, pDB)) {
        fprintf(stderr, "DIR_Insert error!\n");
        exit(1);
      }
    }

    max = Dir.flDIR_Id;

    if (! DB_Commit(pDB)) {
      fprintf(stderr, "DB_Commit error!\n");
      exit(1);
    }

    Get_SysTimestamp(&ti2);
    DATI_Diff(&ti2, &ti1, &d);
    printf("1000 rows inserted in %lf sec (%d rows/second)\n", d, (int)(1000.0 / d));

    if (i != 0 && (i % 10) == 0)
      printf("> %d rows inserted\n", (i / 10) * 10000);
  }

  /* print total number of rows */

  if (! DB_Exec_SQL(pDB, "SELECT COUNT(*) FROM DIR", &iCount, TRUE)) {
    fprintf(stderr, "DB_Exec_SQL error!\n");
    exit(1);
  }

  /* ============================================= */

  /* test random selects */

  printf("\n----------------------------------------");
  printf("\ntest SELECT * FROM dir WHERE dir_id = ???;");
  printf("\n----------------------------------------\n");

  for (i = 0; i < 10; i++) {

    Get_SysTimestamp(&ti1);

    if (! DB_Begin(pDB)) {
      fprintf(stderr, "DB_Begin error!\n");
      exit(1);
    }

    iCount = 0;
    for (j = 0; j < 1000; j++) {

      Dir.flDIR_Id = irand(min, max);

      if (DIR_Select_DIR_Id(&Dir, pDB)) {
        iCount++;
      }
    }

    if (! DB_Commit(pDB)) {
      fprintf(stderr, "DB_Commit error!\n");
      exit(1);
    }

    Get_SysTimestamp(&ti2);
    DATI_Diff(&ti2, &ti1, &d);
    printf("1000 selects %d fetches in %lf sec (%d/second)\n", iCount, d, (int)(1000.0 / d));

    if (i != 0 && (i % 10) == 0)
      printf("> %d selects\n", (i / 10) * 10000);
  }

  /* ----------------------------------------------- */


  printf("\n------------------------------------------------------------------");
  printf("\ntest SELECT * FROM dir WHERE ival = ???; (random value 0..1000000)");
  printf("\n------------------------------------------------------------------\n");

  for (i = 0; i < 10; i++) {

    Get_SysTimestamp(&ti1);

    if (! DB_Begin(pDB)) {
      fprintf(stderr, "DB_Begin error!");
      exit(1);
    }

    iCount = 0;
    for (j = 0; j < 1000; j++) {

      Dir.flIVal = irand(0, 1000000);

      if (! DIR_Select_IVal(&Dir, pDB)) {
        fprintf(stderr, "DIR_Select_IVal error!\n");
        exit(1);
      }
      while (DIR_Fetch_IVal(&Dir, pDB)) {
        iCount++;
      }
    }

    if (! DB_Commit(pDB)) {
      fprintf(stderr, "DB_Commit error!\n");
      exit(1);
    }

    Get_SysTimestamp(&ti2);
    DATI_Diff(&ti2, &ti1, &d);
    printf("1000 selects %d fetches in %lf sec (%d/second)\n", iCount, d, (int)(1000.0 / d));

    if (i != 0 && (i % 10) == 0)
      printf("> %d selects\n", (i / 10) * 10000);
  }

  /* ----------------------------------------------- */

  printf("\n---------------------------------------------------------------");
  printf("\ntest SELECT * FROM dir WHERE ival < ???; (random value 0..1000)");
  printf("\n---------------------------------------------------------------\n");

  for (i = 0; i < 10; i++) {

    Get_SysTimestamp(&ti1);

    if (! DB_Begin(pDB)) {
      fprintf(stderr, "DB_Begin error!\n");
      exit(1);
    }

    iCount = 0;
    for (j = 0; j < 1000; j++) {

      Dir.flIVal = irand(0, 1000);

      if (! DIR_Select_IVal_L(&Dir, pDB)) {
        fprintf(stderr, "DIR_Select_IVal_L error!\n");
        exit(1);
      }
      while (DIR_Fetch_IVal_L(&Dir, pDB)) {
        iCount++;
      }
    }

    if (! DB_Commit(pDB)) {
      fprintf(stderr, "DB_Commit error!\n");
      exit(1);
    }

    Get_SysTimestamp(&ti2);
    DATI_Diff(&ti2, &ti1, &d);
    printf("1000 selects %d fetches in %lf sec (%d/second)\n", iCount, d, (int)(1000.0 / d));

    if (i != 0 && (i % 10) == 0)
      printf("> %d selects\n", (i / 10) * 100);
  }

  /* ----------------------------------------------- */

  printf("\n----------------------------------------------------------------");
  printf("\ntest SELECT * FROM dir WHERE ival <= ???; (random value 0..1000)");
  printf("\n----------------------------------------------------------------\n");

  for (i = 0; i < 10; i++) {

    Get_SysTimestamp(&ti1);

    if (! DB_Begin(pDB)) {
      fprintf(stderr, "DB_Begin error!\n");
      exit(1);
    }

    iCount = 0;
    for (j = 0; j < 1000; j++) {

      Dir.flIVal = irand(0, 1000);

      if (! DIR_Select_IVal_LE(&Dir, pDB)) {
        fprintf(stderr, "DIR_Select_IVal_LE error!\n");
        exit(1);
      }
      while (DIR_Fetch_IVal_LE(&Dir, pDB)) {
        iCount++;
      }
    }

    if (! DB_Commit(pDB)) {
      fprintf(stderr, "DB_Commit error!\n");
      exit(1);
    }

    Get_SysTimestamp(&ti2);
    DATI_Diff(&ti2, &ti1, &d);
    printf("1000 selects %d fetches in %lf sec (%d/second)\n", iCount, d, (int)(1000.0 / d));

    if (i != 0 && (i % 10) == 0)
      printf("> %d selects\n", (i / 10) * 10000);
  }

  /* ----------------------------------------------- */

  printf("\n------------------------------------------------------------------------");
  printf("\ntest SELECT * FROM dir WHERE ival >= ???; (random value 999000..1000000)");
  printf("\n------------------------------------------------------------------------\n");

  for (i = 0; i < 10; i++) {

    Get_SysTimestamp(&ti1);

    if (! DB_Begin(pDB)) {
      fprintf(stderr, "DB_Begin error!\n");
      exit(1);
    }

    iCount = 0;
    for (j = 0; j < 1000; j++) {

      Dir.flIVal = irand(999000, 1000000);

      if (! DIR_Select_IVal_GE(&Dir, pDB)) {
        fprintf(stderr, "DIR_Select_IVal_GE error!\n");
        exit(1);
      }
      while (DIR_Fetch_IVal_GE(&Dir, pDB)) {
        iCount++;
      }
    }

    if (! DB_Commit(pDB)) {
      fprintf(stderr, "DB_Commit error!\n");
      exit(1);
    }

    Get_SysTimestamp(&ti2);
    DATI_Diff(&ti2, &ti1, &d);
    printf("1000 selects %d fetches in %lf sec (%d/second)\n", iCount, d, (int)(1000.0 / d));

    if (i != 0 && (i % 10) == 0)
      printf("> %d selects\n", (i / 10) * 10000);
  }

  /* ----------------------------------------------- */

  printf("\n-----------------------------------------------------------------------");
  printf("\ntest SELECT * FROM dir WHERE ival > ???; (random value 999000..1000000)");
  printf("\n-----------------------------------------------------------------------\n");

  for (i = 0; i < 10; i++) {

    Get_SysTimestamp(&ti1);

    if (! DB_Begin(pDB)) {
      fprintf(stderr, "DB_Begin error!\n");
      exit(1);
    }

    iCount = 0;
    for (j = 0; j < 1000; j++) {

      Dir.flIVal = irand(999000, 1000000);

      if (! DIR_Select_IVal_G(&Dir, pDB)) {
        fprintf(stderr, "DIR_Select_IVal_G error!\n");
        exit(1);
      }
      while (DIR_Fetch_IVal_G(&Dir, pDB)) {
        iCount++;
      }
    }

    if (! DB_Commit(pDB)) {
      fprintf(stderr, "DB_Commit error!\n");
      exit(1);
    }

    Get_SysTimestamp(&ti2);
    DATI_Diff(&ti2, &ti1, &d);
    printf("1000 selects %d fetches in %lf sec (%d/second)\n", iCount, d, (int)(1000.0 / d));

    if (i != 0 && (i % 10) == 0)
      printf("> %d selects\n", (i / 10) * 10000);
  }

  /* ----------------------------------------------- */

  printf("\n--------------------------------------------------------");
  printf("\ntest SELECT * FROM dir WHERE ival BETWEEN 2000 AND 3000;");
  printf("\n--------------------------------------------------------\n");

  for (i = 0; i < 10; i++) {

    Get_SysTimestamp(&ti1);

    if (! DB_Begin(pDB)) {
      fprintf(stderr, "DB_Begin error!\n");
      exit(1);
    }

    iCount = 0;
    for (j = 0; j < 1000; j++) {

      if (! DIR_Select_IVal_BETWEEN(&Dir, pDB)) {
        fprintf(stderr, "DIR_Select_IVal_BETWEEN error!\n");
        exit(1);
      }
      while (DIR_Fetch_IVal_BETWEEN(&Dir, pDB)) {
        iCount++;
      }
    }

    if (! DB_Commit(pDB)) {
      fprintf(stderr, "DB_Commit error!\n");
      exit(1);
    }

    Get_SysTimestamp(&ti2);
    DATI_Diff(&ti2, &ti1, &d);
    printf("1000 selects %d fetches in %lf sec (%d/second)\n", iCount, d, (int)(1000.0 / d));

    if (i != 0 && (i % 10) == 0)
      printf("> %d selects\n", (i / 10) * 10000);
  }

  exit(0);
}
