/*
 * EH_DB.cpp
 * Copyright by AirDream Co., Ltd. 2010-2011 All right reserved
 *
 * Description:
 *  Created on:2011-12-22
 * Modified on:2011-12-22
 *
 */

#ifndef NOT_X86

#include "EH_DB.h"
#include "EH_DEBUG.h"

EH_DB::EH_DB(string username, string passwd,
             string addr, string port,string dbname) {
    string conn = "";
    conn.append("dbname=");
    conn.append(dbname);
    conn.append(" ");
    conn.append("host=");
    conn.append(addr);
    conn.append(" ");
    conn.append("port=");
    conn.append(port);
    conn.append(" ");
    conn.append("user=");
    conn.append(username);
    conn.append(" ");
    conn.append("password=");
    conn.append(passwd);
    m_strConnectionInfo = conn;
    m_pConn = NULL;
    m_pAction = NULL;
}

/*
 *If already have a connection,don't get a
 *new connection.
 */
void EH_DB::OpenConnection() {
    m_Lock.acquire();
    if (m_pConn == NULL) {
        m_pConn = new connection(m_strConnectionInfo);
    }
    m_Lock.release();
}

void EH_DB::ResetConnection() {
    m_Lock.acquire();
    CloseConnection();
    OpenConnection();
    m_Lock.release();
}

void EH_DB::CloseConnection() {
    m_Lock.acquire();
    if (m_pConn) {
        m_pConn->disconnect();
        delete m_pConn;
        m_pConn = NULL;
    }
    m_Lock.release();
}

void EH_DB::StartTransaction() {
    m_Lock.acquire();
    if (m_pAction) {
        delete m_pAction;
        m_pAction = NULL;
    }
    m_pAction = new transaction<>(*m_pConn, "EH_DB");
}

void EH_DB::CommitTransaction() {
    if (m_pAction) {
        m_pAction->commit();
        delete m_pAction;
        m_pAction = NULL;
        m_Lock.release();
    }
}

void EH_DB::AbortTransaction() {
	if (m_pAction) {
		m_pAction->abort();
		delete m_pAction;
		m_pAction = NULL;
		m_Lock.release();
	}
}

/*must be called when exception occur when in executing a transaction.
  usage:
	 try {
		 StartTransaction();
		 ExecuteQuery
		 ExecuteUpdate
		 .....
		 CommitTransaction();
	 } catch (...) {
		ExceptionInTransaction();//NOTE!!

		....//custom process code
	 }
 */
void EH_DB::ExceptionInTransaction() {
    if (m_pAction) {
        delete m_pAction;
        m_pAction = NULL;
    }
    m_Lock.release();
}

DBRES EH_DB::ExecuteQuery(string sql) {
    if (m_pConn == NULL) {
        throw runtime_error("EXCEPTION:connection instance is NULL");
    }
    if (m_pAction == NULL) {
        throw runtime_error("EXCEPTION:transaction instance is NULL");
    }

    result R = m_pAction->exec(sql);
    DBRES result = new DBRESVEC();
    DBROW row = NULL;
    for (uint i = 0; i < R.size(); i++) {
        row = new DBROWMAP();
        for (uint j = 0; j < R.columns(); j++) {
            string colName = R.column_name(j);
            string vlaue(R[i][colName].c_str());
            row->insert(DBROWMAP::value_type(colName, vlaue));
        }
        result->push_back(DBRESVEC::value_type(row));
        row = NULL;
    }

    return result;
}

int EH_DB::ExecuteUpdate(string sql) {
    if (m_pConn == NULL) {
        throw runtime_error("EXCEPTION:connection instance is NULL");
    }
    if (m_pAction == NULL) {
        throw runtime_error("EXCEPTION:transaction instance is NULL");
    }

    result ret = m_pAction->exec(sql);
    return ret.affected_rows();
}

void EH_DB::ReleaseResultSet(DBRES& res) {
    if (!res) {
        return;
    }

    DBRESVEC::const_iterator it = res->begin();
    while (it != res->end()) {
    	DBROW row = *it;
        if (row) {
            delete row;
            row = NULL;
        }
        ++it;
    }
    delete res;
    res = NULL;
}

EH_DB::~EH_DB() {
    CloseConnection();
}

#endif

