--- /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;
+}