logsui/logsengine/logssymbianos/src/logsdbconnector.cpp
changeset 0 4a5361db8937
child 6 41c0a814d878
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/logsui/logsengine/logssymbianos/src/logsdbconnector.cpp	Tue May 04 12:39:37 2010 +0300
@@ -0,0 +1,605 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+// INCLUDE FILES
+#include "logsdbconnector.h"
+#include "logsevent.h"
+#include "logsengdefs.h"
+#include "logsreader.h"
+#include "logslogger.h"
+#include "logsremove.h"
+#include "logscommondata.h"
+#include <logcli.h>
+#include <f32file.h>
+#include <centralrepository.h>
+#include <LogsDomainCRKeys.h>
+
+// CONSTANTS
+
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::LogsDbConnector
+// ----------------------------------------------------------------------------
+//
+LogsDbConnector::LogsDbConnector( 
+    QList<LogsEvent*>& events, bool checkAllEvents, bool resourceControl ) 
+: QObject(), 
+  mModelEvents( events ), 
+  mCheckAllEvents( checkAllEvents ),
+  mResourceControl( resourceControl ),
+  mLogClient( 0 ), 
+  mReader( 0 ),
+  mLogsRemove( 0 ),
+  mRepository( 0 ),
+  mCompressionEnabled(false)
+{
+    LOGS_QDEBUG( "logs [ENG] <-> LogsDbConnector::LogsDbConnector()" )
+    mFsSession = new RFs();
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::~LogsDbConnector
+// ----------------------------------------------------------------------------
+//
+LogsDbConnector::~LogsDbConnector()
+{
+    LOGS_QDEBUG( "logs [ENG] -> LogsDbConnector::~LogsDbConnector()" )
+    
+    delete mReader;
+    delete mLogsRemove;
+    delete mLogClient;
+    if ( mFsSession ){
+        mFsSession->Close();
+    }
+    delete mFsSession;
+    
+    qDeleteAll( mEvents );
+    qDeleteAll( mDuplicatedEvents );
+    
+    delete mRepository;
+    
+    LOGS_QDEBUG( "logs [ENG] <- LogsDbConnector::~LogsDbConnector()" )
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::init
+// ----------------------------------------------------------------------------
+//
+int LogsDbConnector::init()
+{
+    LOGS_QDEBUG( "logs [ENG] -> LogsDbConnector::init()" )
+    
+    TRAPD( err, initL() );
+    handleTemporaryError(err);
+    
+    LOGS_QDEBUG_2( "logs [ENG] <- LogsDbConnector::init(), err:", err )
+    
+    return err;
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::start
+// ----------------------------------------------------------------------------
+//
+int LogsDbConnector::start()
+{
+    LOGS_QDEBUG( "logs [ENG] -> LogsDbConnector::start()" )
+
+#ifdef LOGSDBCONNECTOR_SIMULATION
+    
+    LOGS_QDEBUG( "logs [ENG]    Simulation enabled" )
+    int numEvents = 16;
+    QList<int> indexes;
+    for ( int i = 0; i < numEvents; i++ ){
+        QString number = QString("1223456%1").arg(i);
+        LogsEvent* event = new LogsEvent;
+        if ( i % 3 == 0 ){
+            event->setDirection(LogsEvent::DirMissed);
+            number += QString("DirMissed");        
+        }
+        else if ( i % 2 == 0 ){
+            event->setDirection(LogsEvent::DirIn);
+            number += QString("DirIn");
+        } else {
+            event->setDirection(LogsEvent::DirOut);
+            number += QString("DirOut");
+        }
+        event->setNumber(number);
+        mEvents.append(event);
+        mModelEvents.append(event);
+        indexes.append(i);
+    }
+    emit dataAdded( indexes );
+    return 0;
+    
+#endif
+    
+    if ( !mReader ){
+        LOGS_QDEBUG( "logs [ENG]    Not initialized, failure" )
+        return -1;
+    }
+    int err = mReader->start();
+    handleTemporaryError(err);
+    
+    LOGS_QDEBUG_2( "logs [ENG] <- LogsDbConnector::start(), err:", err )
+    return err;
+}
+
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::updateDetails
+// ----------------------------------------------------------------------------
+//
+int LogsDbConnector::updateDetails(bool clearCached)
+{
+    if ( !mReader ){
+        LOGS_QDEBUG( "logs [ENG]    Not initialized, failure" )
+        return -1;
+    }
+    mReader->updateDetails(clearCached);    
+    readCompleted( mEvents.count() ); //to notify of model update
+    return 0;    
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::stateChanged
+// ----------------------------------------------------------------------------
+//
+void LogsDbConnector::initL()
+{
+    if ( mReader ){
+        // Already initialized
+        return;
+    }  
+    User::LeaveIfError( mFsSession->Connect() );
+    mLogClient = CLogClient::NewL( *mFsSession );
+    mLogsRemove = new LogsRemove( *this, mCheckAllEvents );
+    
+    TLogString logString;
+    //Texts in LOGWRAP.RLS / LOGWRAP.RSS        
+    User::LeaveIfError( mLogClient->GetString( logString, R_LOG_DIR_IN ) );
+    mLogEventStrings.iInDirection = DESC_TO_QSTRING( logString );
+    User::LeaveIfError( mLogClient->GetString( logString, R_LOG_DIR_OUT ) );
+    mLogEventStrings.iOutDirection = DESC_TO_QSTRING( logString );
+    User::LeaveIfError( mLogClient->GetString( logString, R_LOG_DIR_MISSED ) );
+    mLogEventStrings.iMissedDirection = DESC_TO_QSTRING( logString );
+    //"Unknown" (Logwrap.rls)
+    User::LeaveIfError( mLogClient->GetString( logString, R_LOG_REMOTE_UNKNOWN ) ); 
+    mLogEventStrings.iUnKnownRemote = DESC_TO_QSTRING( logString );
+    //"Incoming on alternate line"
+    User::LeaveIfError( mLogClient->GetString( logString, R_LOG_DIR_IN_ALT ) ); 
+    mLogEventStrings.iInDirectionAlt = DESC_TO_QSTRING( logString );
+    User::LeaveIfError( mLogClient->GetString( logString, R_LOG_DIR_OUT_ALT ) );
+    mLogEventStrings.iOutDirectionAlt = DESC_TO_QSTRING( logString );
+    User::LeaveIfError( mLogClient->GetString( logString, R_LOG_DIR_FETCHED) );
+    mLogEventStrings.iFetched = DESC_TO_QSTRING( logString );
+    
+    mReader = new LogsReader( 
+        *mFsSession, *mLogClient, mLogEventStrings, mEvents, *this, mCheckAllEvents );
+    
+    mRepository = CRepository::NewL( KCRUidLogs );
+    
+    if ( mResourceControl ){
+        LOGS_QDEBUG( "logs [ENG] -> LogsDbConnector::initL(), resource control enabled" )
+        LogsCommonData::getInstance().configureReadSize(
+                logsReadSizeCompressEnabled, LogsEvent::DirUndefined);
+        mCompressionEnabled = true;
+    }
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::clearList
+// ----------------------------------------------------------------------------
+//
+bool LogsDbConnector::clearList(LogsModel::ClearType cleartype)
+{
+    bool clearingStarted(false);
+	if ( mLogsRemove ){
+		clearingStarted = mLogsRemove->clearList(cleartype);
+	}
+	return clearingStarted;
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::clearEvent
+// ----------------------------------------------------------------------------
+//
+bool LogsDbConnector::clearEvents(const QList<int>& eventIds)
+{
+    bool asyncClearingStarted(false);
+    if ( mLogsRemove ){
+        bool async(false);
+        int err = mLogsRemove->clearEvents(eventIds, async);
+        asyncClearingStarted = ( !err && async );
+    }    
+    return asyncClearingStarted;
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::markEventsSeen
+// ----------------------------------------------------------------------------
+//
+bool LogsDbConnector::markEventsSeen(const QList<int>& eventIds)
+{
+    LOGS_QDEBUG( "logs [ENG] -> LogsDbConnector::markEventsSeen()" )
+    
+    if ( !mReader ){
+        return false;
+    }
+    
+    foreach( int currId, eventIds ){
+        if ( !mEventsSeen.contains(currId) ){
+            mEventsSeen.append(currId);
+        }
+    }
+
+    LOGS_QDEBUG_2( "logs [ENG] -> event ids:", mEventsSeen );  
+    
+    int err = doMarkEventSeen();
+    LOGS_QDEBUG_2( "logs [ENG] <- LogsDbConnector::markEventsSeen(), marking err:", 
+                   err )
+    return ( err == 0 );
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::clearMissedCallsCounter
+// ----------------------------------------------------------------------------
+//
+int LogsDbConnector::clearMissedCallsCounter()
+{
+    LOGS_QDEBUG( "logs [ENG] -> LogsDbConnector::clearMissedCallsCounter()" )
+    if ( !mRepository ){
+        return -1;
+    }
+    TInt value(0);
+    int err = mRepository->Get( KLogsNewMissedCalls, value );
+    if ( !err && value != 0 ){
+        err = mRepository->Set( KLogsNewMissedCalls, 0 );
+    }
+    LOGS_QDEBUG_2( "logs [ENG] <- LogsDbConnector::clearMissedCallsCounter(), err", err )
+    return err;
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::readDuplicates
+// ----------------------------------------------------------------------------
+//
+int LogsDbConnector::readDuplicates(int eventId)
+{
+    LOGS_QDEBUG_2( "logs [ENG] -> LogsDbConnector::readDuplicates(), id", eventId )
+    if ( !mReader ){
+        return -1;
+    }
+    qDeleteAll(mDuplicatedEvents);
+    mDuplicatedEvents.clear();
+    return mReader->readDuplicates(eventId);
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::takeDuplicates
+// ----------------------------------------------------------------------------
+//
+QList<LogsEvent*> LogsDbConnector::takeDuplicates()
+{
+    LOGS_QDEBUG( "logs [ENG] -> LogsDbConnector::takeDuplicates()" )
+    QList<LogsEvent*> duplicates = mDuplicatedEvents;
+    mDuplicatedEvents.clear();
+    LOGS_QDEBUG( "logs [ENG] <- LogsDbConnector::takeDuplicates()" )
+    return duplicates;
+} 
+
+// -----------------------------------------------------------------------------
+// Do refresh only if compression has been enabled. Monitoring for database
+// changes is restored and current database contents are read.
+// -----------------------------------------------------------------------------
+//
+int LogsDbConnector::refreshData()
+{
+    if ( !mResourceControl ){
+        return -1;
+    }
+    LOGS_QDEBUG( "logs [ENG] -> LogsDbConnector::refreshData()" )
+    int err = 0;
+    bool prevCompressionEnabled = mCompressionEnabled;
+    mCompressionEnabled = false;
+    LogsCommonData::getInstance().configureReadSize(
+        logsReadSizeUndefined, LogsEvent::DirUndefined);
+    if ( mReader ){
+        if ( prevCompressionEnabled && !mReader->IsActive() ){
+            err = mReader->start();
+        }
+    }
+    LOGS_QDEBUG( "logs [ENG] <- LogsDbConnector::refreshData()" )
+    return err;
+}
+
+// -----------------------------------------------------------------------------
+// Compress data, only defined amount of events are kept in memory, others
+// are deleted and read back to memory once refreshData is called. Also
+// monitoring for database changes is disabled.
+// -----------------------------------------------------------------------------
+//
+int LogsDbConnector::compressData()
+{
+    if ( !mResourceControl ){
+        return -1;
+    }
+    LOGS_QDEBUG( "logs [ENG] -> LogsDbConnector::compressData()" )
+    mCompressionEnabled = true;
+    LogsCommonData::getInstance().configureReadSize(
+        logsReadSizeCompressEnabled, LogsEvent::DirUndefined);
+    if ( mReader ){
+        int numEventsLeftInMemory = qMin(mEvents.count(), logsReadSizeCompressEnabled );
+        // Simulate disappearing of compressed events
+        QList<int> removedIndexes;
+        for ( int i = 0; i < mEvents.count(); i++ ){
+            if ( i == 0 ){
+                mModelEvents.clear();
+            }
+            if ( i < numEventsLeftInMemory ){
+                mModelEvents.append(mEvents.at(i));
+            } else {
+                removedIndexes.append(mEvents.at(i)->index());
+            }
+        }
+        emit dataRemoved(removedIndexes);
+        deleteRemoved( numEventsLeftInMemory );
+        mReader->stop();
+    }
+    LOGS_QDEBUG( "logs [ENG] <- LogsDbConnector::compressData()" )
+    return 0;
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::predictiveSearchStatus
+// ----------------------------------------------------------------------------
+//
+int LogsDbConnector::predictiveSearchStatus()
+{
+    LOGS_QDEBUG( "logs [ENG] -> LogsDbConnector::predictiveSearchStatus()" )
+    int status(-1);   
+    if ( mRepository ) {
+        TInt value(0);
+        status = mRepository->Get( KLogsPredictiveSearch, value );
+        if ( !status ) { 
+            status = value;
+        }
+    }    
+    LOGS_QDEBUG_2( "logs [ENG] <- LogsDbConnector::predictiveSearchStatus(), status:",
+            status )
+    return status;
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::setPredictiveSearch
+// ----------------------------------------------------------------------------
+//
+int LogsDbConnector::setPredictiveSearch(bool enabled)
+{
+    int err(-1);
+    int status = predictiveSearchStatus();
+    //if status == 0, it means that predictive search is permanently Off
+    //and we are not allowed to modify it
+    if (status != 0 && mRepository) {
+        int value = enabled ? 1 : 2;
+        err = mRepository->Set( KLogsPredictiveSearch, value );
+    }
+    return err;
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::handleTemporaryError
+// ----------------------------------------------------------------------------
+//
+void LogsDbConnector::handleTemporaryError(int& error)
+{
+     if ( error == KErrAccessDenied ){
+        LOGS_QDEBUG(
+            "logs [ENG] LogsDbConnector::handleTemporaryError, DB temp unavailable" )
+        // TODO: handle temporary error in some meaningful way
+        error = 0;
+    }
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::deleteRemoved
+// ----------------------------------------------------------------------------
+//
+void LogsDbConnector::deleteRemoved(int newEventCount)
+{
+    // Remove events which are not anymore in db nor in model,
+    // such events are always at end of list
+    while ( mEvents.count() > newEventCount ){
+        delete mEvents.takeLast();
+    }
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::removeCompleted
+// ----------------------------------------------------------------------------
+//
+void LogsDbConnector::removeCompleted()
+{
+    LOGS_QDEBUG( "logs [ENG] -> LogsDbConnector::removeCompleted()" )
+    emit clearingCompleted(0);
+    LOGS_QDEBUG( "logs [ENG] <- LogsDbConnector::removeCompleted()" )
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::logsRemoveErrorOccured
+// ----------------------------------------------------------------------------
+//
+void LogsDbConnector::logsRemoveErrorOccured(int err)
+{
+    LOGS_QDEBUG_2( "logs [ENG] <-> LogsDbConnector::logsRemoveErrorOccured(), err:", err )
+    
+    emit clearingCompleted(err);
+    // TODO: error handling
+    
+    LOGS_QDEBUG( "logs [ENG] <- LogsDbConnector::logsRemoveErrorOccured()" )
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::readCompleted
+// ----------------------------------------------------------------------------
+//
+void LogsDbConnector::readCompleted(int readCount)
+{
+    LOGS_QDEBUG( "logs [ENG] -> LogsDbConnector::readCompleted()" )
+    LOGS_QDEBUG_EVENT_ARR(mEvents)
+    
+    // Find out updated, added and removed events
+    mRemovedEventIndexes.clear();
+    mUpdatedEventIndexes.clear();
+    mAddedEventIndexes.clear();
+    for ( int i = 0; i < mEvents.count(); i++ ){
+        if ( !mEvents.at(i)->isInView() ){
+            mRemovedEventIndexes.append( mEvents.at(i)->index() );
+        } else if ( mEvents.at(i)->eventState() == LogsEvent::EventUpdated ) {
+            mUpdatedEventIndexes.append( mEvents.at(i)->index() );
+        } else if ( mEvents.at(i)->eventState() == LogsEvent::EventAdded ) {
+            mAddedEventIndexes.append( mEvents.at(i)->index() );
+        }
+    }
+    
+    bool doModelDataReset( !mRemovedEventIndexes.isEmpty() ||
+                           !mAddedEventIndexes.isEmpty() || 
+                           !mUpdatedEventIndexes.isEmpty() );
+    if ( doModelDataReset ){
+        mModelEvents.clear();
+        int numValidEvents = qMin(mEvents.count(), readCount);
+        for ( int i = 0; i < numValidEvents; i++ ){    
+            mModelEvents.append(mEvents.at(i));
+        }
+    }
+    
+    if ( !mRemovedEventIndexes.isEmpty() ){
+        emit dataRemoved(mRemovedEventIndexes);
+    }             
+    if ( !mAddedEventIndexes.isEmpty() ){
+        emit dataAdded(mAddedEventIndexes);
+    }
+    if ( !mUpdatedEventIndexes.isEmpty() ){
+        emit dataUpdated(mUpdatedEventIndexes);
+    }
+    
+    deleteRemoved(readCount);
+    
+    if ( mCompressionEnabled ){
+        mReader->stop();
+    }    
+
+    LOGS_QDEBUG( "logs [ENG] <- LogsDbConnector::readCompleted()" )
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::errorOccurred
+// ----------------------------------------------------------------------------
+//
+void LogsDbConnector::errorOccurred(int err)
+{
+    LOGS_QDEBUG_2( "logs [ENG] <-> LogsDbConnector::errorOccurred(), err:", err )
+
+    // TODO: error handling
+    
+    handleModifyingCompletion(err);
+    
+    Q_UNUSED(err)
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::temporaryErrorOccurred
+// ----------------------------------------------------------------------------
+//
+void LogsDbConnector::temporaryErrorOccurred(int err)
+{
+    LOGS_QDEBUG_2( 
+            "logs [ENG] -> LogsDbConnector::temporaryErrorOccurred(), err:", err )
+    
+    handleTemporaryError(err);
+    
+    LOGS_QDEBUG( "logs [ENG] <- LogsDbConnector::temporaryErrorOccurred()" )
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::eventModifyingCompleted
+// ----------------------------------------------------------------------------
+//
+void LogsDbConnector::eventModifyingCompleted()
+{
+    LOGS_QDEBUG( "logs [ENG] -> LogsDbConnector::eventModifyingCompleted()" )
+    
+    if ( handleModifyingCompletion() ){
+        // Possible to continue modifying
+        int err = doMarkEventSeen();
+        if ( err != 0 ){
+            // But failed for some reason
+            LOGS_QDEBUG( "logs [ENG]    Couldn't continue modifying" )
+            handleModifyingCompletion(err);
+        }
+    }
+    
+    LOGS_QDEBUG( "logs [ENG] <- LogsDbConnector::eventModifyingCompleted()" )
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::duplicatesReadingCompleted
+// ----------------------------------------------------------------------------
+//
+void LogsDbConnector::duplicatesReadingCompleted(QList<LogsEvent*> duplicates)
+{
+    LOGS_QDEBUG( "logs [ENG] -> LogsDbConnector::duplicatesReadingCompleted()" )
+    qDeleteAll( mDuplicatedEvents );
+    mDuplicatedEvents.clear();
+    mDuplicatedEvents = duplicates;
+    emit duplicatesRead();
+    LOGS_QDEBUG( "logs [ENG] <- LogsDbConnector::duplicatesReadingCompleted()" )
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::doMarkEventSeen
+// ----------------------------------------------------------------------------
+//
+int LogsDbConnector::doMarkEventSeen()
+{
+    int err = -1;
+    if ( mEventsSeen.count() > 0 ){
+        err = mReader->markEventSeen(mEventsSeen.at(0));
+    }
+    return err;
+}
+
+// ----------------------------------------------------------------------------
+// LogsDbConnector::handleModifyingCompletion
+// ----------------------------------------------------------------------------
+//
+bool LogsDbConnector::handleModifyingCompletion(int err)
+{
+    bool continueModify( false );
+    if ( err || mEventsSeen.count() == 1 ){
+        mEventsSeen.clear();
+        emit markingCompleted(err);
+    } else if ( mEventsSeen.count() > 1 ){
+        // Item was modified succesfully and more to modify, remove handled
+        // item from queue
+        mEventsSeen.takeFirst();
+        continueModify = true;
+    } else {
+    
+    }
+    return continueModify;
+}