#include "dbtmpfeature.h"

dbtmpfeature::dbtmpfeature()
{
  dbname = "tmpfeature.db";
  mydb = NULL;
  recsz = 0;
}

dbtmpfeature::~dbtmpfeature()
{
  close();
}

int dbtmpfeature::setname( std::string name )
{
  dbname = name;
  return 0;
}

int dbtmpfeature::close()
{
  if( mydb != NULL )
    {
      mydb->sync( 0 );
      mydb->close( 0 );
      delete mydb;
    }
  mydb = NULL;
  return 0;
}

int dbtmpfeature::setrecsize( int sz )
{
  recsz = sz;
  return 0;
}

int dbtmpfeature::getrecsize( int &sz )
{
  unsigned int s;
  mydb->get_re_len( &s );
  sz = (int) s;
  return 0;
}

int dbtmpfeature::init( DbEnv *env, int clear )
{
  close();
  dbenvp = env;
  if( clear == 1 )
    {
      std::cout << "removing database\n";
      try
        {
          dbenvp->dbremove( NULL, dbname.c_str(), NULL, 0 );
        }
      catch (DbException &e)
        {
          std::cout << "ERROR: " << e.what() << "\n";
        }
    }
  mydb = new Db(dbenvp, 0);
  mydb->set_re_len( recsz );
  mydb->open( NULL, dbname.c_str(), NULL,
              DB_QUEUE, DB_CREATE | DB_THREAD, 384);
  unsigned int mysz;
  mydb->get_re_len( &mysz );
  std::cout << "database length set to " << mysz << " (" << recsz << ")\n";
  recsz = (int)mysz;
  return 0;
}

unsigned int dbtmpfeature::maxid()
{
  db_recno_t r;
  Dbt k, v;
  char *data;
  Dbc *c;
  data = new char[ recsz ];
  k.set_data( &r );
  k.set_flags( DB_DBT_USERMEM );
  k.set_ulen( sizeof( db_recno_t ) );
  v.set_data( data );
  v.set_flags( DB_DBT_USERMEM );
  v.set_ulen( recsz );
  int ret;
  ret = mydb->cursor( NULL, &c, 0 );
  if( ret != 0 )
    {
      std::cout << "ERROR getting cursor\n";
      exit(0);
    }
  ret = c->get( &k, &v, DB_LAST);
  if( ret != 0 )
    {
      std::cout << "failed in get maxid\n";
      exit(0);
    }
  c->close();
  delete [] data;
  return (unsigned int) r;
}

unsigned int dbtmpfeature::insert( char *data )
{
  Dbt k, v;
  db_recno_t recno;
  k.set_data( &recno );
  k.set_flags( DB_DBT_USERMEM );
  k.set_ulen( sizeof( db_recno_t ) );
  v.set_data( data );
  v.set_size( recsz );
  mydb->put( NULL, &k, &v, DB_APPEND );
  return (unsigned int) recno;
}

int dbtmpfeature::get( unsigned int i, char *data )
{
  Dbt k, v;
  db_recno_t recno;
  recno = i;
  k.set_data( &recno );
  k.set_size( sizeof(db_recno_t) );
  k.set_flags( DB_DBT_USERMEM );
  v.set_data( data );
  v.set_flags( DB_DBT_USERMEM );
  v.set_ulen( recsz );
  int ret;
  ret = mydb->get( NULL, &k, &v, 0 );
  return ret;
}

int dbtmpfeature::get( unsigned int i, double *data, int *vecflag, int vecsz )
{
  Dbt k, v;
  db_recno_t recno;
  double *od;
  od = new double[ vecsz ];
  recno = i;
  k.set_data( &recno );
  k.set_size( sizeof(db_recno_t) );
  k.set_flags( DB_DBT_USERMEM );
  v.set_data( od );
  v.set_flags( DB_DBT_USERMEM );
  v.set_ulen( recsz );
  int ret;
  ret = mydb->get( NULL, &k, &v, 0 );
  int ii;
  ii = 0;

  for( int z = 0; z < vecsz; z++ )
    {
      if( vecflag[z] == 1 )
        {
          data[ii] = od[z];
          ii++;
        }
    }

  delete [] od;
  return ret;
}
