cbs/CbsServer/ServerSrc/CCbsDbImp.cpp
changeset 0 ff3b6d0fd310
child 50 2313cb430f28
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cbs/CbsServer/ServerSrc/CCbsDbImp.cpp	Tue Feb 02 01:11:09 2010 +0200
@@ -0,0 +1,459 @@
+/*
+* Copyright (c) 2003 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:  This contains basis for the implementation of the database.
+*    
+*                Constructs instances of database subclasses CCbsDbImpSettings,
+*                CCbsDbImpTopicCollection, CCbsDbTopicList and CCbsDbTopicMessages.
+*                On initialization determines whether datafiles already exist.
+*                If all of them are present and valid, no special action is taken.
+*
+*                If some or all datafiles are missing or corrupt, all datafiles
+*                are deleted and new files created.
+*                Factory default settings, if available, are then loaded from
+*                Shared Data and stored in server datafiles. This is done by
+*                database subinstances.
+*
+*/
+
+
+//  INCLUDE FILES
+
+#include <barsc.h>
+#include <e32svr.h>
+#include <bautils.h>
+
+#include <CbsServer.rsg>
+
+#include "CbsUtils.h"
+#include "CbsServerPanic.h"
+#include "CCbsDbImp.H"
+#include "CbsDbConstants.h"
+#include "CCbsDbImpSettings.H"
+#include "CCbsDbImpTopicMessages.h"
+#include "CCbsDbImpTopicList.h"
+#include "CCbsDbImpTopicCollection.h"
+#include "CCbsBackupMonitor.h"
+#include "CCbsDiskSpaceMonitor.h"
+
+#include "CbsLogger.h"
+
+// Data file names
+_LIT( KCbsTopicsAndMsgsFileName, "cbtopicsmsgs.dat" );
+_LIT( KCbsUnsavedMsgsFileName, "cbunsaved.dat" );
+
+// ================= MEMBER FUNCTIONS =======================
+
+// -----------------------------------------------------------------------------
+// CCbsDbImp::CCbsDbImp
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CCbsDbImp::CCbsDbImp()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CCbsDbImp::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CCbsDbImp::ConstructL()
+    {
+    User::LeaveIfError( iFs.Connect() );
+
+    // Create the disk space monitor    
+    iDiskSpaceMonitor = CCbsDiskSpaceMonitor::NewL( *this );
+
+    TInt errorCode( KErrNone );
+    
+#ifdef __SECURE_BACKUP__
+    // Use PubSub for monitoring
+    iBackupMonitor = CCbsBackupMonitor::NewL( *this );
+#else
+    // Create a backup observer wrapper. If an error is returned,
+    // ignore it and leave iBackupWrapper to NULL.
+    TRAP( errorCode, ( iBackupWrapper = CBaBackupSessionWrapper::NewL() ) );
+#endif        
+
+    // Try to create the database components. If we couldn't because
+    // the disk is almost full, that's alright. We'll try again
+    // later.
+    TRAP( errorCode, CreateComponentsL() );
+    if ( errorCode == KErrDiskFull )
+        {
+        // Install an observer for the critical level
+        WaitForCriticalLevel();
+        }
+    else
+        {
+        User::LeaveIfError( errorCode );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCbsDbImp::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CCbsDbImp* CCbsDbImp::NewL()
+    {
+    CCbsDbImp* self = new ( ELeave ) CCbsDbImp;
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+    return self;
+    }
+
+// Destructor
+CCbsDbImp::~CCbsDbImp()
+    {
+    CBSLOGSTRING("CBSSERVER: >>> CCbsDbImp::~CCbsDbImp()");
+    if ( iDiskSpaceMonitor )
+        {
+        delete iDiskSpaceMonitor;
+        }    
+    
+    DeleteComponents();
+
+    iFs.Close();
+    CBSLOGSTRING("CBSSERVER: <<< CCbsDbImp::~CCbsDbImp()");
+    }
+
+// -----------------------------------------------------------------------------
+// CCbsDbImp::TopicListL
+// Returns a reference to the current active topic list. 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CCbsDbImpTopicList& CCbsDbImp::TopicListL()
+    {
+    // Check if we have initialized the database succesfully
+    if ( !iTopicList )
+        {
+        User::Leave( KErrDiskFull );
+        }
+
+    return *iTopicList;    
+    }
+
+// -----------------------------------------------------------------------------
+// CCbsDbImp::TopicMessagesL
+// Returns a reference to the current topic messages DB object. 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CCbsDbImpTopicMessages& CCbsDbImp::TopicMessagesL()
+    {
+    CBSLOGSTRING("CBSSERVER: >>> CCbsDbImp::TopicMessagesL()");
+    
+    // Check if we have initialized the database succesfully
+    if ( !iTopicMessages )
+        {
+        CBSLOGSTRING("CBSSERVER: CCbsDbImp::TopicMessagesL(): No iTopicMessages instance, leaving with KErrDiskFull...");
+        User::Leave( KErrDiskFull );
+        }
+
+    CBSLOGSTRING("CBSSERVER: <<< CCbsDbImp::TopicMessagesL(), returning *iTopicMessages.");
+    return *iTopicMessages;
+    }
+
+// -----------------------------------------------------------------------------
+// CCbsDbImp::SettingsL
+// Returns a reference to the settings DB object.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CCbsDbImpSettings& CCbsDbImp::SettingsL()
+    {
+    // Check if we have initialized the database succesfully
+    if ( !iSettings )
+        {
+        User::Leave( KErrDiskFull );
+        }
+
+    return *iSettings;
+    }
+
+// -----------------------------------------------------------------------------
+// CCbsDbImp::TopicCollectionL
+// Returns a reference to the topic collection.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CCbsDbImpTopicCollection& CCbsDbImp::TopicCollectionL()
+    {
+    // Check if we have initialized the database succesfully
+    if ( !iTopicCollection )
+        {
+        User::Leave( KErrDiskFull );
+        }
+
+    return *iTopicCollection;
+    }
+
+// -----------------------------------------------------------------------------
+// CCbsDbImp::BackupWrapperL
+// Returns a reference to the backup wrapper. 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CBaBackupSessionWrapper& CCbsDbImp::BackupWrapperL()
+    {
+    if ( !iBackupWrapper )
+        {
+        User::Leave( KErrGeneral );
+        }
+
+    return *iBackupWrapper;
+    }
+
+// ---------------------------------------------------------
+// IsInitialized()    
+//
+// ---------------------------------------------------------
+TBool CCbsDbImp::IsInitialized() const
+    {
+    return iSettings != NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CCbsDbImp::CreateComponentsL
+// Creates topic list, settings topic messages and topic
+// collection instances and loads factory settings if necessary. 
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCbsDbImp::CreateComponentsL()
+    {
+    CBSLOGSTRING("CBSSERVER: >>> CCbsDbImp::CreateComponentsL()");
+    
+    // Return if we have already been initialized
+    if ( IsInitialized() )
+        {
+        return;
+        }    
+    
+    TBuf<16> topicsFile( KCbsTopicsAndMsgsFileName );
+    TBuf<16> messagesFile( KCbsUnsavedMsgsFileName );  
+    
+    // Delete the old file for unsaved messages 
+    CbsUtils::DeleteFileL( iFs, messagesFile );
+    CBSLOGSTRING("CBSSERVER: CCbsDbImp::CreateComponentsL(): messagesFile deleted.");
+
+    // Make sure that data file paths exist.
+    iFs.MkDirAll( topicsFile ); 
+    iFs.MkDirAll( messagesFile ); 
+    
+    // Create the individual components. If creating any of the components
+    // fails, this method leaves and created components are deleted.
+    CCbsDbImpSettings* settings = CreateSettingsL();
+    CleanupStack::PushL( settings );
+
+    CCbsDbImpTopicList* topicList = CreateTopicListL( topicsFile, messagesFile );
+    CleanupStack::PushL( topicList );
+
+    CCbsDbImpTopicMessages* topicMessages = CreateTopicMessagesL( *topicList );
+    CleanupStack::PushL( topicMessages );
+
+    CCbsDbImpTopicCollection* topicCollection = CreateTopicCollectionL();
+    CleanupStack::PushL( topicCollection );
+    
+
+#ifndef __SECURE_BACKUP__
+
+    CBSLOGSTRING("CBSSERVER: CCbsDbImp::CreateComponentsL(): __SECURE_BACKUP__ not defined.");
+    
+    // Register the file to backup server
+    if ( iBackupWrapper )
+        {
+        iBackupWrapper->RegisterFileL( *topicsFile, *topicList );
+        }
+#endif
+
+    // We have succesfully created all components. Set them to member
+    // variables.
+    iTopicList = topicList;
+    iSettings = settings;
+    iTopicMessages = topicMessages;
+    iTopicCollection = topicCollection;
+
+    // Does not transfer ownership.
+    iTopicList->SetTopicMessages( iTopicMessages );    
+
+    // If we could create the database, cancel the disk space notify request
+    WaitForCriticalLevelCancel();
+
+    // The database components are preserved, but the resource reader and
+    // related buffers are deleted.
+    CleanupStack::Pop( 4 ); // topicMessages, settings, topicList, topicCollection
+    
+    CBSLOGSTRING("CBSSERVER: <<< CCbsDbImp::CreateComponentsL()");
+    }
+
+// ---------------------------------------------------------
+// DeleteComponents()     
+//
+// ---------------------------------------------------------
+void CCbsDbImp::DeleteComponents()
+    {
+    delete iTopicMessages;
+    iTopicMessages = NULL;
+
+    delete iTopicCollection;
+    iTopicCollection = NULL;
+
+#ifdef __SECURE_BACKUP__
+
+#else
+    // Delete owned objects and deregister files from
+    // backup server.
+    if ( iBackupWrapper && iSettings )
+        {
+        //iBackupWrapper->DeregisterFile( iSettings->FileName() );
+        }
+        
+    if ( iBackupWrapper && iTopicList )
+        {
+        //iBackupWrapper->DeregisterFile( iTopicList->TopicFilename() );
+        }
+#endif        
+        
+    delete iSettings;
+    iSettings = NULL;
+    
+    delete iTopicList;
+    iTopicList = NULL;
+
+#ifdef __SECURE_BACKUP__
+    delete iBackupMonitor;
+    iBackupMonitor = NULL;
+#else
+    delete iBackupWrapper;
+    iBackupWrapper = NULL;
+#endif    
+    }
+
+// ---------------------------------------------------------
+// CreateSettingsL()     
+//
+// ---------------------------------------------------------
+CCbsDbImpSettings* CCbsDbImp::CreateSettingsL()
+    {
+    CCbsDbImpSettings* settings = NULL;
+    TRAPD( err, ( settings = CCbsDbImpSettings::NewL( *this ) ) );
+    User::LeaveIfError( err );
+    return settings;
+    }
+
+// ---------------------------------------------------------
+// CreateTopicListL()     
+//
+// ---------------------------------------------------------
+CCbsDbImpTopicList* CCbsDbImp::CreateTopicListL( 
+    const TDesC& aTopicsFile,
+    const TDesC& aMessagesFile )
+    {
+    // Try to create the topic list.
+    CCbsDbImpTopicList* topicList = NULL;
+    TRAPD( err, ( topicList = CCbsDbImpTopicList::NewL(
+        iFs, aTopicsFile, aMessagesFile, *this ) ) );
+
+    // Handle data file corruption here.
+    switch ( err )
+        {
+        case KErrNone:
+            break;
+
+        case KErrCorrupt:
+        case KErrEof:
+            // The data file was corrupt. Delete it and try again.
+            CbsUtils::DeleteFileL( iFs, aTopicsFile );
+            CbsUtils::DeleteFileL( iFs, aMessagesFile );
+            topicList = CCbsDbImpTopicList::NewL(
+                iFs, aTopicsFile, aMessagesFile, *this );
+            break;
+
+        default:
+            User::Leave( err );
+            break;
+        }
+
+    return topicList;
+    }
+
+// ---------------------------------------------------------
+// CreateTopicMessagesL()     
+//
+// ---------------------------------------------------------
+CCbsDbImpTopicMessages* CCbsDbImp::CreateTopicMessagesL( 
+    CCbsDbImpTopicList& aTopicList )
+    {
+    // This cannot leave because of data file corruption.
+    return CCbsDbImpTopicMessages::NewL( aTopicList, iFs );
+    }
+
+
+// ---------------------------------------------------------
+// CreateTopicCollectionL()     
+//
+// ---------------------------------------------------------
+CCbsDbImpTopicCollection* CCbsDbImp::CreateTopicCollectionL()
+    {
+    // This does not create a data file.
+    return CCbsDbImpTopicCollection::NewL();
+    }
+
+// ---------------------------------------------------------
+// WaitForCriticalLevelL()     
+//
+// ---------------------------------------------------------
+void CCbsDbImp::WaitForCriticalLevel()
+    {
+    // We are running low on disk space. Ask for a notification
+    // when there is space again.
+    iDiskSpaceMonitor->IssueRequest();  
+    }
+
+
+// ---------------------------------------------------------
+// WaitForCriticalLevelCancel()     
+//
+// ---------------------------------------------------------
+void CCbsDbImp::WaitForCriticalLevelCancel()
+    {
+    // Cancel the notification for critical level    
+    iDiskSpaceMonitor->Cancel();    
+    }
+
+// ---------------------------------------------------------
+// ChangeFileLocksL()
+// 
+// Releases all files for backup/restore, or takes the
+// files into use again.
+// ---------------------------------------------------------
+    
+void CCbsDbImp::ChangeFileLocksL( const TCbsBackupRequest& aRequest )
+    {
+    CBSLOGSTRING("CBSSERVER: >>> CCbsDbImp::ChangeFileLocksL()");
+    
+    // Check/change the topiclist/topics/saved messages file
+    iTopicList->ChangeFileLockL( aRequest );
+    
+    CBSLOGSTRING("CBSSERVER: <<< CCbsDbImp::ChangeFileLocksL()");
+    }
+
+// ================= OTHER EXPORTED FUNCTIONS ==============
+
+//  End of File