///////////////////////////////////////////////////////////////
//
// CDatabaseJobQueueImpl::ProcessQuery
//
//
//
///////////////////////////////////////////////////////////////
void CDatabaseJobQueueImpl::ProcessQuery ( CDbJobData* pJobData )
{
    // CDatabaseConnection* from handle
    CDatabaseConnection* pConnection = GetConnectionFromHandle ( pJobData->command.connectionHandle );
    if ( !pConnection )
    {
        pJobData->result.status = EJobResult::FAIL;
        pJobData->result.strReason = "Invalid connection";
        return;
    }

    // And query
    if ( !pConnection->Query ( pJobData->command.strData, pJobData->result.registryResult ) )
    {
        pJobData->result.status = EJobResult::FAIL;
        pJobData->result.strReason = pConnection->GetLastErrorMessage ();
        pJobData->result.uiErrorCode = pConnection->GetLastErrorCode ();
        pJobData->result.bErrorSuppressed = MapContains ( pConnection->m_SuppressedErrorCodes, pConnection->GetLastErrorCode () );
    }
    else
    {
        pJobData->result.status = EJobResult::SUCCESS;
    }

    // And log if required
    LogResult ( pJobData );
}
///////////////////////////////////////////////////////////////
//
// CDatabaseJobQueueImpl::ProcessConnect
//
//
//
///////////////////////////////////////////////////////////////
void CDatabaseJobQueueImpl::ProcessConnect ( CDbJobData* pJobData )
{
    // Determine which type manager to use
    std::vector < SString > parts;
    pJobData->command.strData.Split ( "\1", parts );
    if ( parts.size () < 5 )
    {
        pJobData->result.status = EJobResult::FAIL;
        pJobData->result.strReason = "Internal Error (JobQueueServer:ProcessConnect #1)";
        return;
    }

    CDatabaseType* pTypeManager = MapFindRef ( m_DatabaseTypeMap, parts[0] );
    if ( !pTypeManager )
    {
        pJobData->result.status = EJobResult::FAIL;
        pJobData->result.strReason = "Not valid type";
        return;
    }

    // Get type manager to return a CDatabaseConnection*
    CDatabaseConnection* pConnection = pTypeManager->Connect ( parts[1], parts[2], parts[3], parts[4] );
    if ( !pConnection )
    {
        pJobData->result.status = EJobResult::FAIL;
        pJobData->result.strReason = "Could not connect";
        return;
    }

    if ( !pConnection->IsValid () )
    {
        pJobData->result.status = EJobResult::FAIL;
        pJobData->result.strReason = pConnection->GetLastErrorMessage ();
        pConnection->Release ();
        return;
    }

    // Extract some options
    GetOption < CDbOptionsMap > ( parts[4], "log", pConnection->m_bLoggingEnabled, 0 );
    GetOption < CDbOptionsMap > ( parts[4], "tag", pConnection->m_strLogTag );
    GetOption < CDbOptionsMap > ( parts[4], "suppress", ",", pConnection->m_SuppressedErrorCodes );

    // Only allow error codes to be suppress with mysql, as sqlite only has one error code
    if ( pTypeManager->GetDataSourceTag () != "mysql" )
        pConnection->m_SuppressedErrorCodes.clear ();

    // Associate handle with CDatabaseConnection*
    shared.m_Mutex.Lock();
    MapSet( shared.m_HandleConnectionMap, pJobData->command.connectionHandle, pConnection );
    shared.m_Mutex.Unlock();

    // Set result
    pJobData->result.status = EJobResult::SUCCESS;
}