devicediagnosticsfw/diagresultsdb/server/inc/diagresultsdbstore.h
changeset 0 b497e44ab2fc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devicediagnosticsfw/diagresultsdb/server/inc/diagresultsdbstore.h	Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,453 @@
+/*
+* Copyright (c) 2007-2007 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:  Permanent File Store for diagnostics test records.
+*  libraries   : 
+*
+*/
+
+
+#ifndef DIAGRESULTSDBSTORE_H
+#define DIAGRESULTSDBSTORE_H
+
+//System includes
+#include <s32file.h> //CPermanentFileStore
+#include <f32file.h> //Rfs, RFile
+#include <e32base.h>
+
+class CDiagResultsDatabaseItem;
+class CDiagResultsDbTestRecord;
+class CDiagResultsDbTestRecordHandle;
+class TDiagResultsDatabaseTestRecordInfo;
+class CDiagResultsDbRecordEngineParam;
+
+/**
+* An interface that must be implemented in order to call
+* ExistingRecordsAsyncL that is an asynchronous method.
+*
+* @since S60 v5.0
+**/
+class MRecordLoadingObserver
+    {
+public:
+    /**
+    * Returns an array of test records. Contains all test records from a 
+    * single database file.
+    *
+    * @param aError Indicates if there were any errors.
+    * @param aArray An array of test records. Ownership is transferred.
+    **/
+    virtual void ExistingRecordsL( TInt aError, 
+                       RPointerArray<CDiagResultsDbTestRecord>* aArray ) = 0;
+   
+    };
+    
+/**
+* An interface that must be implemented in order to call CompleteRecordAsyncL.
+*
+* @since S60 v5.0
+**/    
+class MRecordCompletionObserver
+    {
+public:
+
+    /**
+    * This is called when test record is completed.
+    *
+    * @param aError Symbian error code or KErrNone.
+    **/
+    virtual void CompletedRecordL( TInt aError ) = 0;
+    };    
+
+/**
+* Permanent file store class that manipulates results database file.
+* Database files are saved under server's private directory. 
+* For example epoc32\WINSCW\C\private\10282cd9\ in WINSCW.
+* Provides functions to load, save, compact and cleanup data.
+*
+* Files have format [UID].dat e.g. [21234563].dat
+*
+* Stream Ids of the test record handle are stored into the root stream.
+* Handles contain the stream ids to the test results.
+*
+* Implementation uses 3 kinds of streams:
+* 1) root stream 
+* 2) Test record handle stream
+* 3) Test result stream
+* 4) Last results buffer (buffer for overflowing test results)
+*
+* In order to retrieve a test result, we must first know which record
+* is needed and then ask from the handle where test result is. 
+* Of course we can browse all test records, because root stream
+* contains stream ids into test record handles.
+*
+* @since S60 v5.0
+**/
+class CDiagResultsDbStore : public CActive
+	{
+public:
+
+    /**
+    * Destructor
+    **/
+	~CDiagResultsDbStore();
+	
+	/**
+	* NewL.
+	*
+	* @param aUid UID of the database file. This class manipulates only one 
+	*             database file at a time. If multiple database files needs
+	*             to be open, use another instance.
+	* @return New object.
+	**/
+	static CDiagResultsDbStore* NewL( TUid aUid );
+    static CDiagResultsDbStore* NewLC( TUid aUid );
+	
+	/**
+	* Create and return a new record. Ownership is transferred.
+	*
+	* @return a new test record.
+	**/
+    CDiagResultsDbTestRecordHandle* CreateNewRecordL( 
+                             CDiagResultsDbRecordEngineParam* aEngineParam );
+    
+    /**
+    * Write test record into the database.
+    *
+    * @param aHandle The test record to be written into the database.
+    * @return KErrNone or symbian error code.                        
+    **/
+    TInt CompleteRecord( CDiagResultsDbTestRecordHandle& aHandle );
+               
+    /**
+    * Write one test item into the DB.
+    *
+    * @param aCommit Indicates should we commit the store.
+    * @param aHandle Handle that is updated to contain the item.
+    * @param aTestItem An item to be added.
+    *
+    * @return Symbian error code or KErrNone.
+    **/                         
+    TInt CompleteTestResult( TBool aCommit, 
+                             CDiagResultsDbTestRecordHandle& aHandle, 
+                             CDiagResultsDatabaseItem& aTestItem );                         
+                                                                                                           
+    /**
+    * Search database for a test record handle.
+    * Handle does not contain test results directly. It only contains
+    * stream ids to the test results and general record info.
+    *
+    * @param aUid test record is searched based on the uid.
+    * @return The found test record or NULL.
+    **/
+    CDiagResultsDbTestRecordHandle* OpenExistingHandleL( TUid aUid );
+    
+    
+    /**
+    * Search database for a test record.
+    *
+    * @param aUid test record is searched based on the uid.
+    * @param aReadOnly indicates should we allow writing.
+    * @return The found test record or NULL.
+    */
+    CDiagResultsDbTestRecord* OpenExistingRecordL( TUid aUid, 
+                                                   TBool aReadOnly );
+    
+    /**
+    * Opens a single database item. 
+    * @param aId Stream id that represents the item.
+    *
+    * @return The found item or NULL.
+    **/
+    CDiagResultsDatabaseItem* OpenExistingTestResultL( TStreamId aId );
+       
+    /**
+    * Returns all record infos. Client is responsible for deleting the array.
+    *
+    * @return Record info array.
+    **/
+    RArray<TDiagResultsDatabaseTestRecordInfo>* ExistingRecordInfosL();
+    
+    /**
+    * Retrieve all test records from the database asynchronously.
+    *
+    * @param aObserver Observer is notified after test records have 
+    *                  been loaded.
+    **/
+    void ExistingRecordsAsyncL( MRecordLoadingObserver& aObserver );
+    
+
+        
+    /**
+    * Open last results buffer. It contains the test results that would have
+    * been otherwise deleted. These are needed when all last results are
+    * retrieved. Use with CleanUpDatabaseUseLastResultsBufferL.
+    *
+    * @return Test record. 
+    **/
+    CDiagResultsDbTestRecord* OpenExistingLastResultsBufferL(); 
+    
+    /**
+    * Compacts database to have only necessary information. This should be 
+    * done as often as necessary after writing. Compacting should not be
+    * done after reading!
+    * However note that this operation could take a long time. 
+    **/
+    void CompactDatabase();
+    
+	/**
+	 * Cleanup database. Used deletion algorithm is taken from the
+	 * Central Repository.
+	 *
+	 * @param aCommit ETrue commits the store.
+	 **/ 	   
+	void CleanUpDatabaseL( TBool aCommit );
+    
+    /**
+    * Read available test record handle uids.
+    *
+    * @param aUids Contains available test record handle uids.
+    **/
+    void RecordUidsL( RArray<TUid>& aUids );
+    
+protected: //From CActive
+    
+    /**
+    * Called from CActive::Cancel.
+    **/
+    virtual void DoCancel();
+
+    /**
+    * Asynchronous service function.
+    **/
+    virtual void RunL();
+    
+    /**
+    * Called if error happens in RunL.
+    **/
+    virtual TInt RunError(TInt aError);
+    
+private:     
+    
+	/**
+	 * Cleanup database to have only certain amount of test records 
+	 * inside per each database file.
+	 *
+	 * @param aCommit ETrue commits the store.
+	 **/ 	   
+	void CleanUpDatabaseNoLastResultsL( TBool aCommit );
+       
+ 	/**
+ 	 * Cleanup database and move some of the test results into the
+ 	 * last results buffer. This function guarantees that the DB
+ 	 * keeps last results. CleanUpDatabase does not do that.    
+ 	 *
+ 	 * @param aCommit ETrue commits the store. 
+ 	 **/ 
+ 	void CleanUpDatabaseUseLastResultsBufferL( TBool aCommit );
+
+    /**
+    * Read all stream ids from the root stream.
+    * 
+    * @param aIds StreamId array.
+    **/    
+    void ReadRootStreamL( RArray<TStreamId>& aIds );
+        
+    /**
+    * Create empty root stream.
+    *
+    * @param aStore Root stream is created into this store.
+    **/
+    void CreateEmptyRootStreamL( CPermanentFileStore& aStore );
+    
+    /**
+    * Replace root stream with an array.
+    *
+    * @param aArray Array that replaces any existing root stream.
+    **/
+    void ReplaceRootStreamL( RArray<TStreamId>& aArray );
+    
+    /**
+    * Write test record into the database file.
+    *
+    * @param aCompletedRecord is the record closed/completed or not.
+    * @param aCommit Commit the store or not.
+    * @param aTestRecord The test record to be written into the file.
+    **/
+    void DoCompleteRecordL( CDiagResultsDbTestRecordHandle& aHandle );
+                        
+    /**
+    * Complete test result i.e. write it into the store.
+    * @param aHandle Handle to be written.
+    * @param aTestItem Contains test results that are written into the store.
+    **/                            
+    void DoCompleteTestResultL( TBool aCommit, 
+                                CDiagResultsDbTestRecordHandle& aHandle, 
+                                CDiagResultsDatabaseItem& aTestItem );                            
+                                   
+    
+    /**
+    * Constructor.
+    * 
+    * @param aDbUid Database file uid.
+    **/
+    CDiagResultsDbStore( TUid aDbUid );
+    
+    /**
+    * ConstructL.
+    **/
+    void ConstructL();
+    
+    /**
+    * Complete own request is needed in some cases because this class uses 
+    * CActive to partition tasks into smaller pieces. This function completes
+    * TRequestStatus so that the RunL is called.
+    **/
+    void CompleteOwnRequest();
+    
+    //State of this class. These are used only in asynchronous methods.
+    enum EState
+        {
+        ENotRunning,
+        EGetRootStream,
+        EGetRecord,
+        ERecordsReady,
+        };
+    
+    enum EDeletionAlgorithm
+        {
+        EMaxRecordCountAlgorithm,
+        ELastResultsAlgorithm,
+        };
+     
+     /**
+     * Write handle into the store. Handle knows where test results are.
+     * @param aHandle The handle that is written into the store.
+     **/   
+     void WriteHandleIntoDbL( CDiagResultsDbTestRecordHandle& aHandle );
+     
+     
+     /**
+     * Append one ID into the root stream.
+     * @param aId ID to be added.
+     **/
+     void AppendRootStreamL( TStreamId& aId );
+     
+          
+     /**
+     * Deletes the oldest handle from the store.
+     *
+     * @param aIds Root stream.
+     **/
+     void DeleteOldestHandleL( RArray<TStreamId>& aIds );
+             
+     /**
+     * Delete handle and its test results.
+     *
+     * @param aIndex Index of the handle in the root stream.
+     * @param aIds Root stream.
+     * 
+     **/             
+     void DeleteHandleL( TInt aIndex, RArray<TStreamId>& aIds );
+     
+     /**
+     * Create last results buffer. It can be used to store test results
+     * that would be deleted otherwise. 
+     **/
+     void CreateLastResultsBufferStreamL();
+     
+     /**
+     * Open test record handle and its test results.
+     *
+     * @param aId Handle root stream ID.
+     * @param aRecord Returned test record.
+     * @param aHandle Returned test record handle.
+     **/
+     void OpenExistingRecordAndHandleL( TStreamId aId, 
+                                        CDiagResultsDbTestRecord*& aRecord,
+                                        CDiagResultsDbTestRecordHandle*& aHandle );
+
+    /**
+    * Check last results buffer and add test results into it if needed.
+    *
+    * @param aIds Root stream.
+    **/                                        
+     ///@@@KSR: changes for Codescanner error val = High 
+     //void CheckOverflowingTestResults( RArray<TStreamId>& aIds );
+     void CheckOverflowingTestResultsL( RArray<TStreamId>& aIds );
+
+    /**
+     * Return maximum file size defined in the Central Repository.
+     * This can be used to prevent a DB file from using too much disk space.
+     * 
+     * @return Maximum file size in bytes.
+     **/
+    TInt GetMaximumFileSizeL();
+    
+    /**
+     * Return the deletion algorithm defined in the central repository.
+     * 
+     * @return The type of the deletion algorithm.
+     **/
+    TInt GetDeletionAlgorithmL();
+    
+    /**
+     * Get maximum file size from the central repository and check the file size.
+     * 
+     * @param aRfs Opened file server session.
+     * @param aFileName File name of the DB file.
+     * @param aFileSize Size of the DB file in bytes.
+     **/
+    void CheckMaximumFileSizeLimitL( RFs& aRfs, 
+			  						 const TDesC& aFileName,
+			  						 TInt aFileSize );
+
+private: // Data
+
+    // Store that is owned by this class. Performs many file manipulation operations.
+	CPermanentFileStore* iStore;  
+    
+    // File DB uid. [UID].dat
+    TUid iDbUid;
+
+    // File server session
+    RFs iRfs;
+    
+    // The database file.
+    RFile iFile;
+    
+    // Loading observer to be notified async.
+    MRecordLoadingObserver* iLoadingObserver;
+    
+    // Completion observer (notified async).
+    MRecordCompletionObserver* iCompletionObserver;
+    
+    // Pointer to test record arrays. Used in async methods.
+    RPointerArray<CDiagResultsDbTestRecord>* iRecordArray;
+    
+    // Contains available record ids. Used in async methods.
+    RArray<TStreamId>* iRecordIds;
+    
+    // Used in async methods to remember what record was loaded.
+    TInt iRecordNumber;
+    
+    // Contains the test record to be completed (Used only in async methods).
+    CDiagResultsDbTestRecord* iTestRecord;
+    
+    // State of the asynchronous operation.
+    EState iState;
+    
+    EDeletionAlgorithm iDeletionAlgorithm;
+	};
+
+#endif // DIAGRESULTSDBSTORE_H