Beispiel #1
0
///////////////////////////////////////////////////////////////
//
// CDatabaseManagerImpl::Disconnect
//
//
//
///////////////////////////////////////////////////////////////
bool CDatabaseManagerImpl::Disconnect ( uint hConnection )
{
    ClearLastErrorMessage ();

    // Check connection
    if ( !MapContains ( m_ConnectionTypeMap, hConnection ) )
    {
        SetLastErrorMessage ( "Invalid connection" );
        return false;
    }

    // Start disconnect
    CDbJobData* pJobData = m_JobQueue->AddCommand ( EJobCommand::DISCONNECT, hConnection, "" );

    // Complete disconnect
    m_JobQueue->PollCommand ( pJobData, -1 );

    // Check for problems
    if ( pJobData->result.status == EJobResult::FAIL )
    {
        SetLastErrorMessage ( pJobData->result.strReason );
        return false;
    }

    // Remove connection refs
    MapRemove ( m_ConnectionTypeMap, hConnection );
    m_JobQueue->IgnoreConnectionResults ( hConnection );
    return true;
}
Beispiel #2
0
///////////////////////////////////////////////////////////////
//
// CDatabaseManagerImpl::QueryWithCallbackf
//
// Start a query and direct the result through a callback
//
///////////////////////////////////////////////////////////////
bool CDatabaseManagerImpl::QueryWithCallbackf ( SConnectionHandle hConnection, PFN_DBRESULT pfnDbResult, void* pCallbackContext, const char* szQuery, ... )
{
    va_list vl;
    va_start ( vl, szQuery );

    ClearLastErrorMessage ();

    // Check connection
    if ( !MapContains ( m_ConnectionTypeMap, hConnection ) )
    {
        SetLastErrorMessage ( "Invalid connection" );
        return NULL;
    }

    // Insert arguments with correct escapement
    SString strEscapedQuery = InsertQueryArguments ( hConnection, szQuery, vl );

    // Start query
    CDbJobData* pJobData = m_JobQueue->AddCommand ( EJobCommand::QUERY, hConnection, strEscapedQuery );

    // Set callback vars
    pJobData->SetCallback ( pfnDbResult, pCallbackContext );

    return true;
}
Beispiel #3
0
bool CRegistry::Exec ( const std::string& strQuery )
{
    if ( m_bOpened == false )
    {
        SetLastErrorMessage ( "SQLite3 was not opened, cannot perform query!", strQuery );
        return false;
    }

    BeginAutomaticTransaction ();
    return ExecInternal ( strQuery.c_str () );
}
Beispiel #4
0
///////////////////////////////////////////////////////////////
//
// CDatabaseManagerImpl::QueryPoll
//
// ulTimeout = 0   -  No wait if not ready
// ulTimeout > 0   -  Wait(ms) if not ready
// ulTimeout = -1  -  Wait infinity+1 if not ready
//
///////////////////////////////////////////////////////////////
bool CDatabaseManagerImpl::QueryPoll ( CDbJobData* pJobData, uint ulTimeout )
{
    ClearLastErrorMessage ();

    if ( m_JobQueue->PollCommand ( pJobData, ulTimeout ) )
    {
        if ( pJobData->result.status == EJobResult::FAIL )
            SetLastErrorMessage ( pJobData->result.strReason );
        return true;
    }

    return false;
}
Beispiel #5
0
bool CRegistry::ExecInternal ( const char* szQuery )
{
    TIMEUS startTime = GetTimeUs();
    char *szErrorMsg = NULL;

    if ( sqlite3_exec ( m_db, szQuery, NULL, NULL, &szErrorMsg ) != SQLITE_OK )
    {
        SetLastErrorMessage ( szErrorMsg, szQuery );
        sqlite3_free ( szErrorMsg );
        return false;
    }

    CPerfStatSqliteTiming::GetSingleton ()->UpdateSqliteTiming ( this, szQuery, GetTimeUs() - startTime );
    return true;
}
Beispiel #6
0
///////////////////////////////////////////////////////////////
//
// CDatabaseManagerImpl::QueryStart
//
// Start a query
//
///////////////////////////////////////////////////////////////
CDbJobData* CDatabaseManagerImpl::QueryStart ( SConnectionHandle hConnection, const SString& strQuery, CLuaArguments* pArgs )
{
    ClearLastErrorMessage ();

    // Check connection
    if ( !MapContains ( m_ConnectionTypeMap, hConnection ) )
    {
        SetLastErrorMessage ( "Invalid connection" );
        return NULL;
    }

    // Insert arguments with correct escapement
    SString strEscapedQuery = InsertQueryArguments ( hConnection, strQuery, pArgs );

    // Start query
    return m_JobQueue->AddCommand ( EJobCommand::QUERY, hConnection, strEscapedQuery );
}
Beispiel #7
0
bool CRegistry::Select ( const std::string& strColumns, const std::string& strTable, const std::string& strWhere, unsigned int uiLimit, CRegistryResult* pResult )
{
    char szBuffer[32] = {0};

    std::string strQuery = "SELECT " + strColumns + " FROM " + strTable;
    if ( !strWhere.empty () )
        strQuery += " WHERE " + strWhere;
    if ( uiLimit > 0 )
        strQuery += " LIMIT " + std::string ( itoa ( uiLimit, szBuffer, 10 ) );

    if ( m_bOpened == false )
	{
        SetLastErrorMessage ( "SQLite3 was not opened, cannot get value!", strQuery );
        return false;
    }

    // Execute the query
    return QueryInternal ( strQuery.c_str (), pResult );
}
Beispiel #8
0
///////////////////////////////////////////////////////////////
//
// CDatabaseManagerImpl::QueryStartf
//
//
//
///////////////////////////////////////////////////////////////
CDbJobData* CDatabaseManagerImpl::QueryStartf ( SConnectionHandle hConnection, const char* szQuery, ... )
{
    va_list vl;
    va_start ( vl, szQuery );

    ClearLastErrorMessage ();

    // Check connection
    if ( !MapContains ( m_ConnectionTypeMap, hConnection ) )
    {
        SetLastErrorMessage ( "Invalid connection" );
        return NULL;
    }

    // Insert arguments with correct escapement
    SString strEscapedQuery = InsertQueryArguments ( hConnection, szQuery, vl );

    // Start query
    return m_JobQueue->AddCommand ( EJobCommand::QUERY, hConnection, strEscapedQuery );
}
Beispiel #9
0
///////////////////////////////////////////////////////////////
//
// CDatabaseManagerImpl::DatabaseConnect
//
// strType is one of the supported database types i.e. "sqlite"
//
///////////////////////////////////////////////////////////////
uint CDatabaseManagerImpl::Connect ( const SString& strType, const SString& strHost, const SString& strUsername, const SString& strPassword, const SString& strOptions )
{
    ClearLastErrorMessage ();

    SString strCombo = strType + "\1" + strHost + "\1" + strUsername + "\1" + strPassword + "\1" + strOptions;

    // Start connect
    CDbJobData* pJobData = m_JobQueue->AddCommand ( EJobCommand::CONNECT, 0, strCombo );

    // Complete connect
    m_JobQueue->PollCommand ( pJobData, -1 );

    // Check for problems
    if ( pJobData->result.status == EJobResult::FAIL )
    {
        SetLastErrorMessage ( pJobData->result.strReason );
        return INVALID_DB_HANDLE;
    }

    // Process result
    MapSet ( m_ConnectionTypeMap, pJobData->result.connectionHandle, strType );
    return pJobData->result.connectionHandle;
}
Beispiel #10
0
///////////////////////////////////////////////////////////////
//
// CDatabaseManagerImpl::QueryWithResultf
//
// Start a query and wait for the result
//
///////////////////////////////////////////////////////////////
bool CDatabaseManagerImpl::QueryWithResultf ( SConnectionHandle hConnection, CRegistryResult* pResult, const char* szQuery, ... )
{
    va_list vl;
    va_start ( vl, szQuery );

    ClearLastErrorMessage ();

    // Check connection
    if ( !MapContains ( m_ConnectionTypeMap, hConnection ) )
    {
        SetLastErrorMessage ( "Invalid connection" );
        return false;
    }

    // Insert arguments with correct escapement
    SString strEscapedQuery = InsertQueryArguments ( hConnection, szQuery, vl );

    // Start query
    CDbJobData* pJobData = m_JobQueue->AddCommand ( EJobCommand::QUERY, hConnection, strEscapedQuery );

    // Wait for result
    QueryPoll ( pJobData, -1 );

    // Process result
    if ( pJobData->result.status == EJobResult::FAIL )
    {
        if ( pResult )
            *pResult = CRegistryResult ();
        return false;
    }
    else
    {
        if ( pResult )
            *pResult = pJobData->result.registryResult;
        return true;
    }
}
Beispiel #11
0
bool CRegistry::Query ( CRegistryResult* pResult, const char* szQuery, va_list vl )
{
    // Clear result
    if ( pResult )
        *pResult = CRegistryResult ();

    if ( m_bOpened == false )
	{
        SetLastErrorMessage ( "SQLite3 was not opened, cannot perform query!", szQuery );
        return false;
    }

    SString strParsedQuery;
    for ( unsigned int i = 0; szQuery[i] != '\0'; i++ )
    {
        if ( szQuery[i] != SQL_VARIABLE_PLACEHOLDER )
        {
            strParsedQuery += szQuery[i];
        }
        else
        {
            switch ( va_arg( vl, int ) )
            {
                case SQLITE_INTEGER:
                {
                    int iValue = va_arg( vl, int );
                    strParsedQuery += SString ( "%d", iValue );
                }
                break;

                case SQLITE_FLOAT:
                {
                    double fValue = va_arg( vl, double );
                    strParsedQuery += SString ( "%f", fValue );
                }
                break;

                case SQLITE_TEXT:
                {
                    const char* szValue = va_arg( vl, const char* );
                    assert ( szValue );
                    strParsedQuery += SString ( "'%s'", SQLEscape ( szValue, true, false ).c_str () );
                }
                break;

                case SQLITE_BLOB:
                {
                    strParsedQuery += "CANT_DO_BLOBS_M8";
                }
                break;

                case SQLITE_NULL:
                {
                    strParsedQuery += "NULL";
                }
                break;

                default:
                    // someone passed a value without specifying its type
                    assert ( 0 );
                    break;
            }
        }
    }
    va_end ( vl );
    // VACUUM query does not work with transactions
    if ( strParsedQuery.BeginsWithI( "VACUUM" ) )
        EndAutomaticTransaction ();
    else
        BeginAutomaticTransaction ();
    return QueryInternal ( strParsedQuery.c_str (), pResult );
}
Beispiel #12
0
bool CRegistry::Query ( const std::string& strQuery, CLuaArguments *pArgs, CRegistryResult* pResult )
{
    std::string strParsedQuery = "";

    if ( m_bOpened == false )
	{
        SetLastErrorMessage ( "SQLite3 was not opened, cannot perform query!", strQuery );
        return false;
    }

    // Walk through the query and replace the variable placeholders with the actual variables
    unsigned int uiLen = strQuery.length ();
    unsigned int a = 0, type = 0;
    const char *szContent = NULL;
    char szBuffer[32] = {0};
    for ( unsigned int i = 0; i < uiLen; i++ )
    {
        if ( strQuery.at(i) == SQL_VARIABLE_PLACEHOLDER ) {
            // If the placeholder is found, replace it with the variable
            CLuaArgument *pArgument = (*pArgs)[a++];

            // Check the type of the argument and convert it to a string we can process
            if ( pArgument ) {
                type = pArgument->GetType ();
                if ( type == LUA_TBOOLEAN ) {
                    szContent = ( pArgument->GetBoolean() ) ? "true" : "false";
                } else if ( type == LUA_TNUMBER ) {
                    snprintf ( szBuffer, 31, "%f", pArgument->GetNumber () );
                    szContent = szBuffer;
                } else if ( type == LUA_TSTRING ) {
                    szContent = pArgument->GetString ().c_str ();

                    // If we have a string, add a quote at the beginning too
                    strParsedQuery += '\'';
                }
            }

            // Copy the string into the query, and escape the single quotes as well
            if ( szContent ) {
                for ( unsigned int k = 0; szContent[k] != '\0'; k++ ) {
                    if ( szContent[k] == '\'' )
                        strParsedQuery += '\'';
                    strParsedQuery += szContent[k];
                }
                // If we have a string, add a quote at the end too
                if ( type == LUA_TSTRING ) strParsedQuery += '\'';
            } else {
                // If we don't have any content, put just output 2 quotes to indicate an empty variable
                strParsedQuery += "\'\'";
            }

        } else {
            // If we found a normal character, copy it into the destination buffer
            strParsedQuery += strQuery[i];
        }
    }

    // Catch BEGIN/END/COMMIT TRANSACTION and ignore
    SString strTest = SString ( strParsedQuery ).ToUpper ();
    if ( strTest.find ( "TRANSACTION" ) != std::string::npos )
    {
        strTest = strTest.Replace ( "\t", " " ).Replace ( "  ", " ", true ).TrimStart ( " " ).TrimEnd ( " " );
        if ( strTest.find ( "BEGIN" ) == 0 || strTest.find ( "END" ) == 0 || strTest.find ( "COMMIT" ) == 0 )
        {
            return true;
        }
    }

    BeginAutomaticTransaction ();
    return QueryInternal ( strParsedQuery.c_str (), pResult );
}
Beispiel #13
0
bool CRegistry::QueryInternal ( const char* szQuery, CRegistryResult* ppResult )
{
    TIMEUS startTime = GetTimeUs();

    // Prepare the query
    sqlite3_stmt* pStmt;
    if ( sqlite3_prepare ( m_db, szQuery, strlen ( szQuery ) + 1, &pStmt, NULL ) != SQLITE_OK )
    {
        SetLastErrorMessage ( sqlite3_errmsg ( m_db ), szQuery );
        return false;
    }

    CRegistryResult& pResult = *ppResult;
    // Get column names
    pResult->nColumns = sqlite3_column_count ( pStmt );
    pResult->ColNames.clear ();
    for ( int i = 0; i < pResult->nColumns; i++ )
    {
        pResult->ColNames.push_back ( sqlite3_column_name ( pStmt, i ) );
    }

    // Fetch the rows
    pResult->nRows = 0;
    pResult->Data.clear ();
    int status;
    while ( (status = sqlite3_step(pStmt)) == SQLITE_ROW )
    {
        pResult->Data.push_back ( vector < CRegistryResultCell > ( pResult->nColumns ) );
        vector < CRegistryResultCell > & row = pResult->Data.back();
        for ( int i = 0; i < pResult->nColumns; i++ )
        {
            CRegistryResultCell& cell = row[i];
            cell.nType = sqlite3_column_type ( pStmt, i );
            switch ( cell.nType )
            {
                case SQLITE_NULL:
                    break;
                case SQLITE_INTEGER:
                    cell.nVal = sqlite3_column_int ( pStmt, i );
                    break;
                case SQLITE_FLOAT:
                    cell.fVal = (float)sqlite3_column_double ( pStmt, i );
                    break;
                case SQLITE_BLOB:
                    cell.nLength = sqlite3_column_bytes ( pStmt, i );
                    if ( cell.nLength == 0 )
                    {
                        cell.pVal = NULL;
                    }
                    else
                    {
                        cell.pVal = new unsigned char [ cell.nLength ];
                        memcpy ( cell.pVal, sqlite3_column_blob ( pStmt, i ), cell.nLength );
                    }
                    break;
                default:
                    cell.nLength = sqlite3_column_bytes ( pStmt, i ) + 1;
                    cell.pVal = new unsigned char [ cell.nLength ];
                    memcpy ( cell.pVal, sqlite3_column_text ( pStmt, i ), cell.nLength );
                    break;
            }
        }
        pResult->nRows++;
    }

    // Did we leave the fetching loop because of an error?
    if ( status != SQLITE_DONE )
    {
        SetLastErrorMessage ( sqlite3_errmsg ( m_db ), szQuery );
        sqlite3_finalize ( pStmt );
        return false;
    }

    // All done
    sqlite3_finalize ( pStmt );

    CPerfStatSqliteTiming::GetSingleton ()->UpdateSqliteTiming ( this, szQuery, GetTimeUs() - startTime );
    return true;
}