/* Copyright (C) 2014 InfiniDB, Inc.

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License
   as published by the Free Software Foundation; version 2 of
   the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
   MA 02110-1301, USA. */

/*****************************************************************************
 * $Id: rollback.cpp 1825 2013-01-24 18:41:00Z pleblanc $
 *
 ****************************************************************************/

/*
 * A tool to print current transactions & roll them back if necessary.
 *
 * A tool to print current transactions & roll them back if necessary.
 * The proper way to use it is:
 * 		rollback -p   (to get the transaction(s) that need to be rolled back)
 * 		rollback -r transID  	(for each one to roll them back)
 */

#include "dbrm.h"

#include <iostream>
#include <stdlib.h>

#include "IDBPolicy.h"

using namespace std;
using namespace BRM;

void help(string name)
{
  cout << "Usage: " << endl << name << " -r txnID" << endl;
  cout << name << " -p" << endl << endl;
  cout << "Options:" << endl;
  cout << "	-r -- rollback a transaction in the BRM data structures" << endl;
  cout << "	-p -- print current transactions according to the BRM" << endl;
}

void printTxnIDs()
{
  DBRM brm;
  set<VER_t> txnList;
  set<VER_t>::iterator it;
  int err;

  err = brm.getCurrentTxnIDs(txnList);

  if (err != 0)
    return;

  for (it = txnList.begin(); it != txnList.end(); it++)
    cout << *it << endl;
}

void rollbackTxn(VER_t txnID)
{
  DBRM brm;
  vector<LBID_t> lbidList;
  int err;

  err = brm.getUncommittedLBIDs(txnID, lbidList);

  if (err != 0)
    return;

  err = brm.vbRollback(txnID, lbidList);

  if (err != 0)
    return;

  cout << "OK." << endl;
}

int main(int argc, char** argv)
{
  int opt;
  char options[] = "pr:";
  VER_t txnID = -1;
  string progname(argv[0]);

  while ((opt = getopt(argc, argv, options)) != -1)
  {
    switch (opt)
    {
      case 'r':
        txnID = atoi(optarg);

        if (txnID < 1)
        {
          help(progname);
          exit(0);
        }

        idbdatafile::IDBPolicy::configIDBPolicy();
        rollbackTxn(txnID);
        exit(0);

      case 'p': printTxnIDs(); exit(0);
    }
  }

  help(progname);
  exit(0);
}
