/*---------------------------------------------------------------------------*/
/* database_switch.cpp                                                       */
/* copyright (c) innovaphone 2016                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

#include <platform.h>
#include "sdk/common/interface/database.h"

#include "../lib/database_switch.h"

/*---------------------------------------------------------------------------*/
/* DatabaseSwitch                                                           */
/*---------------------------------------------------------------------------*/
DatabaseSwitch::DatabaseSwitch(class IDatabase * database)
{
    this->database = database;
    this->dataSet = NULL;
}

DatabaseSwitch::~DatabaseSwitch()
{
}

IDatabase * DatabaseSwitch::GetDatabase()
{
    return this->database;
}

// UDatabase functions
void DatabaseSwitch::DatabaseConnectComplete(IDatabase * const database)
{
    class UDatabase * user = users.front();
    users.pop_front();
    user->DatabaseConnectComplete(this);
}

void DatabaseSwitch::DatabaseError(IDatabase * const database, db_error_t reason)
{
    class UDatabase * user = users.front();
    users.clear(); // clear the queue, as no further requests can be processed after a DatabaseError
    user->DatabaseError(this, reason);
}

void DatabaseSwitch::DatabaseShutdown(IDatabase * const database, db_error_t reason)
{
    class UDatabase * user = users.front();
    users.clear();
    user->DatabaseShutdown(this, reason);
}

void DatabaseSwitch::DatabaseExecSQLResult(IDatabase * const database, class IDataSet * dataset)
{
    class UDatabase * user = users.front();
    if (!this->dataSet) this->dataSet = new class DataSetSwitch(dataset, this);
    user->DatabaseExecSQLResult(this, this->dataSet);
}

void DatabaseSwitch::DatabaseInsertSQLResult(IDatabase * const database, ulong64 id)
{
    class UDatabase * user = users.front();
    users.pop_front();
    user->DatabaseInsertSQLResult(this, id);
}

void DatabaseSwitch::DatabaseBeginTransactionResult(IDatabase * const database)
{
    class UDatabase * user = users.front();
    users.pop_front();
    user->DatabaseBeginTransactionResult(this);
}

void DatabaseSwitch::DatabaseEndTransactionResult(IDatabase * const database)
{
    class UDatabase * user = users.front();
    users.pop_front();
    user->DatabaseEndTransactionResult(this);
}

void DatabaseSwitch::DatabasePrepareStatementResult(IDatabase * const database, class IPreparedStatement * statement)
{
    class UDatabase * user = users.front();
    users.pop_front();
    user->DatabasePrepareStatementResult(this, statement);
}

void DatabaseSwitch::DataSetDeleted()
{
    this->dataSet = NULL;
    users.pop_front();
}

// IDatabase functions

void DatabaseSwitch::Connect(const char * address, const char * dbname, const char * user, const char * password)
{
    this->database->Connect(address, dbname, user, password);
}

bool DatabaseSwitch::Connected()
{
    return this->database->Connected();
}

void DatabaseSwitch::Shutdown()
{
    this->database->Shutdown();
}

void DatabaseSwitch::ExecSQL(UDatabase * const user, dword flags, const char * sqlcmd, ...)
{
    users.push_back(user);
    va_list ap;
    va_start(ap, sqlcmd);
    this->database->ExecSQLV(this, flags, sqlcmd, ap);
    va_end(ap);
}

void DatabaseSwitch::ExecSQLV(UDatabase * const user, dword flags, const char * sqlcmd, va_list argList)
{
    users.push_back(user);
    this->database->ExecSQLV(this, flags, sqlcmd, argList);
}

void DatabaseSwitch::InsertSQL(UDatabase * const user, const char * sqlcmd, ...)
{
    users.push_back(user);
    va_list ap;
    va_start(ap, sqlcmd);
    this->database->InsertSQLV(this, sqlcmd, ap);
    va_end(ap);
}

void DatabaseSwitch::InsertSQLV(UDatabase * const user, const char * sqlcmd, va_list argList)
{
    users.push_back(user);
    this->database->InsertSQLV(this, sqlcmd, argList);
}

void DatabaseSwitch::BeginTransaction(UDatabase * const user, const char * lockTableCmd)
{
    users.push_back(user);
    this->database->BeginTransaction(this, lockTableCmd);
}

void DatabaseSwitch::EndTransaction(UDatabase * const user, bool doRollback)
{
    users.push_back(user);
    this->database->EndTransaction(this, doRollback);
}

void DatabaseSwitch::PrepareStatement(UDatabase * user, const char * sqlcmd)
{
    users.push_back(user);
    this->database->PrepareStatement(this, sqlcmd);
}

void DatabaseSwitch::ExecSQL(UDatabase * const user, dword flags, class IPreparedStatement * const statement)
{
    users.push_back(user);
    this->database->ExecSQL(this, flags, statement);
}

void DatabaseSwitch::InsertSQL(UDatabase * const user, class IPreparedStatement * const statement)
{
    users.push_back(user);
    this->database->InsertSQL(this, statement);
}

size_t DatabaseSwitch::EscapeSearchLiterals(const char * value, char * buffer, size_t bufferSize)
{
    return this->database->EscapeSearchLiterals(value, buffer, bufferSize);
}

const char * DatabaseSwitch::GetLastErrorMessage()
{
    return this->database->GetLastErrorMessage();
}

const char * DatabaseSwitch::GetLastErrorCode()
{
    return this->database->GetLastErrorCode();
}
