#ifndef __DBTABLE_H__
#define __DBTABLE_H__

#include <db_cxx.h>
#include <string>
#include <vector>
#include <stdlib.h>

class dbtable
{
 public:
 dbtable() : mydb(NULL)
    {
      dbenvp = NULL;
      dbname = "";
    }
  dbtable( const dbtable &in)
    {
      std::cout << "you can't copy a db table at memory address: ";
      std::cout << (unsigned long long)(&in) << "\n";
      exit(0);
    }
  virtual ~dbtable()
    {
      close();
    }
  virtual int close()
  {
    if( mydb != NULL ) 
      {
        mydb->sync(0);
        mydb->close(0);
      }
    mydb = NULL;
    return 0;
  }
  virtual int init( DbEnv *env )
  {
    close();
    dbenvp = env;
    mydb = new Db( env, 0 );
    mydb->open( NULL, dbname.c_str(), NULL,
                DB_BTREE,
                DB_CREATE | DB_THREAD, 384 );
    return 0;
  }
  virtual int cleanlog()
  {
    if( dbenvp != NULL )
      {
        char **p;
        p = NULL;
        try
          {
            dbenvp->txn_checkpoint( 0, 0, 0 );
            dbenvp->log_archive( &p, DB_ARCH_REMOVE );
          }
        catch (DbException &e)
          {
            std::cout << "ERROR: " << e.what() << "\n";
          }
      }
    return 0;
  }
  virtual int upgrade()
  {
    if( dbenvp != NULL )
      {
        Db *tdb;
        tdb = new Db(dbenvp, 0);
        for( unsigned i = 0; i < dbfiles.size(); i++ )
          {
            std::cout << "upgrading " << dbfiles[i] << "\n";
            tdb->upgrade( dbfiles[i].c_str(), 0 );
          }
        delete tdb;
      }
    return 0;
  }
  virtual int setenv( DbEnv *e )
  {
    dbenvp = e;
    return 0;
  }
  virtual int lsn_reset()
  {
    /*
    if( dbenvp != NULL )b
      {
        for( unsigned i = 0; i < dbfiles.size(); i++ )
          {
            std::cout << "reseting lsn for " << dbfiles[i] << "\n";
            dbenvp->lsn_reset( dbfiles[i].c_str(), 0 );
          }
      }
    */
    return 0;
  }
  virtual int remove()
  {
    close();
    if( dbenvp != NULL )
      {
        for( unsigned i = 0; i < dbfiles.size(); i++ )
          {
            std::cout << "removing " << dbfiles[i] << "\n";
            dbenvp->dbremove( NULL, dbfiles[i].c_str(), NULL, DB_AUTO_COMMIT );
          }
        dbfiles.clear();
      }
    return 0;
  }
  std::string name()
    {
      return dbname;
    }
 protected:
  DbEnv *dbenvp;
  Db *mydb;
  std::string dbname;
  std::vector< std::string > dbfiles;
};

#endif
