--- /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