wmdrm/wmdrmengine/wmdrmserver/server/src/wmdrmdb.cpp
changeset 0 95b198f216e5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wmdrm/wmdrmengine/wmdrmserver/server/src/wmdrmdb.cpp	Thu Dec 17 08:52:27 2009 +0200
@@ -0,0 +1,1543 @@
+/*
+* Copyright (c) 2008 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:  database implementation for WMDRM
+*
+*/
+
+#include <e32std.h>
+
+#include <systemwarninglevels.hrh>
+#include "wmdrmdb.h"
+#include "wmdrmfileserverclient.h"
+#include "wmdrmdatastore.h"
+#include "drmrightsstoringlocation.h"
+#include "drmutilityinternaltypes.h"
+
+#define _LOGGING_FILE L"wmdrmserver.txt"
+
+#include "flogger.h"
+#include "logfn.h"
+
+#define FROM_HEX_DIGIT(x) (x >= 'a' ? x - 'a' + 10 : x - '0')
+#define FROM_HEX(x,y) (FROM_HEX_DIGIT(x) * 16 + FROM_HEX_DIGIT(y))
+
+// For secure, sync and metering stores in the case of differentiation of stores
+// to system drive and internal mass drive or for all the stores in the case of 
+// no differentation
+_LIT( KDatabaseName, "%c:[10282F1B]hds.db" );
+
+// For license store in the case of differentation of stores. Not used
+// if no differentation is applied.                                              
+_LIT( KDatabaseName2, "%c:[10282F1B]hds2.db" );
+_LIT8( KDatabaseConfig, "cache_size=64; page_size=2048; encoding=UTF-8" );
+
+_LIT( KBeginTransaction, "BEGIN TRANSACTION" );
+_LIT( KCommitTransaction, "COMMIT TRANSACTION" );
+
+_LIT( KCreateLicenseTableString, "CREATE TABLE IF NOT EXISTS license_t (hashKey BINARY NOT NULL, uniqueKey BINARY NOT NULL, data BINARY, PRIMARY KEY(hashKey, uniqueKey))" );
+_LIT( KCreateSecureTableString, "CREATE TABLE IF NOT EXISTS secure_t (hashKey BINARY NOT NULL, uniqueKey BINARY NOT NULL, data BINARY, PRIMARY KEY(hashKey, uniqueKey))" );
+_LIT( KCreateSyncTableString, "CREATE TABLE IF NOT EXISTS sync_t (hashKey BINARY NOT NULL, uniqueKey BINARY NOT NULL, data BINARY, PRIMARY KEY(hashKey, uniqueKey))" );
+_LIT( KCreateMeteringTableString, "CREATE TABLE IF NOT EXISTS metering_t (hashKey BINARY NOT NULL, uniqueKey BINARY NOT NULL, data BINARY, PRIMARY KEY(hashKey, uniqueKey))" );
+
+_LIT( KDeleteLicenseTableString, "DROP TABLE IF EXISTS license_t" );
+_LIT( KDeleteSecureTableString, "DROP TABLE IF EXISTS secure_t" );
+_LIT( KDeleteSyncTableString, "DROP TABLE IF EXISTS sync_t" );
+_LIT( KDeleteMeteringTableString, "DROP TABLE IF EXISTS metering_t" );
+
+_LIT( KSelectNRowIDsLicenseTableString, "SELECT RowID FROM license_t LIMIT %d" );
+_LIT( KSelectNRowIDsSecureTableString, "SELECT RowID FROM secure_t LIMIT %d" );
+_LIT( KSelectNRowIDsSyncTableString, "SELECT RowID FROM sync_t LIMIT %d" );
+_LIT( KSelectNRowIDsMeteringTableString, "SELECT RowID FROM metering_t LIMIT %d" );
+
+_LIT( KDeleteWithRowIDLicenseTableString, "DELETE FROM license_t WHERE RowID = :rowID" );
+_LIT( KDeleteWithRowIDSecureTableString, "DELETE FROM secure_t WHERE RowID = :rowID" );
+_LIT( KDeleteWithRowIDSyncTableString, "DELETE FROM sync_t WHERE RowID = :rowID" );
+_LIT( KDeleteWithRowIDMeteringTableString, "DELETE FROM metering_t WHERE RowID = :rowID" );
+
+_LIT( KDeleteLicenseString, "DELETE FROM license_t WHERE hashKey = :HashKey AND uniqueKey=:UniqueKey" );
+_LIT( KDeleteSecureString, "DELETE FROM secure_t WHERE hashKey = :HashKey AND uniqueKey=:UniqueKey" );
+_LIT( KDeleteSyncString, "DELETE FROM sync_t WHERE hashKey = :HashKey AND uniqueKey=:UniqueKey" );
+_LIT( KDeleteMeteringString, "DELETE FROM metering_t WHERE hashKey = :HashKey AND uniqueKey=:UniqueKey" );
+
+_LIT( KInsertLicenseString, "INSERT INTO license_t (hashKey, uniqueKey) VALUES (:HashKey, :UniqueKey)" );
+_LIT( KInsertSecureString, "INSERT INTO secure_t (hashKey, uniqueKey) VALUES (:HashKey, :UniqueKey)" );
+_LIT( KInsertSyncString, "INSERT INTO sync_t (hashKey, uniqueKey) VALUES (:HashKey, :UniqueKey)" );
+_LIT( KInsertMeteringString, "INSERT INTO metering_t (hashKey, uniqueKey) VALUES (:HashKey, :UniqueKey)" );
+
+_LIT( KUpdateLicenseDataString, "UPDATE license_t SET data=:Data WHERE hashKey = :HashKey AND uniqueKey=:UniqueKey" );
+_LIT( KUpdateSecureDataString, "UPDATE secure_t SET data=:Data WHERE hashKey = :HashKey AND uniqueKey=:UniqueKey" );
+_LIT( KUpdateSyncDataString, "UPDATE sync_t SET data=:Data WHERE hashKey = :HashKey AND uniqueKey=:UniqueKey" );
+_LIT( KUpdateMeteringDataString, "UPDATE metering_t SET data=:Data WHERE hashKey = :HashKey AND uniqueKey=:UniqueKey" );
+
+_LIT( KSelectLicenseString, "SELECT data FROM license_t WHERE hashKey = :HashKey AND uniqueKey=:UniqueKey" );
+_LIT( KSelectSecureString, "SELECT data FROM secure_t WHERE hashKey = :HashKey AND uniqueKey=:UniqueKey" );
+_LIT( KSelectSyncString, "SELECT data FROM sync_t WHERE hashKey = :HashKey AND uniqueKey=:UniqueKey" );
+_LIT( KSelectMeteringString, "SELECT data FROM metering_t WHERE hashKey = :HashKey AND uniqueKey=:UniqueKey" );
+
+_LIT( KSelectLicenseEnumeratorString, "SELECT uniqueKey FROM license_t WHERE hashKey = :HashKey" );
+_LIT( KSelectSecureEnumeratorString, "SELECT uniqueKey FROM secure_t WHERE hashKey = :HashKey" );
+_LIT( KSelectSyncEnumeratorString, "SELECT uniqueKey FROM sync_t WHERE hashKey = :HashKey" );
+_LIT( KSelectMeteringEnumeratorString, "SELECT uniqueKey FROM metering_t WHERE hashKey = :HashKey" );
+
+_LIT( KSelectLicenseNameSpaceEnumeratorString, "SELECT hashKey, uniqueKey FROM license_t" );
+_LIT( KSelectSecureNameSpaceEnumeratorString, "SELECT hashKey, uniqueKey FROM secure_t" );
+_LIT( KSelectSyncNameSpaceEnumeratorString, "SELECT hashKey, uniqueKey FROM sync_t" );
+_LIT( KSelectMeteringNameSpaceEnumeratorString, "SELECT hashKey, uniqueKey FROM metering_t" );
+
+_LIT( KHashKeyColumn, "hashkey" );
+_LIT( KHashKeyParameter, ":HashKey" );
+_LIT( KUniqueKeyColumn, "uniquekey" );
+_LIT( KUniqueKeyParameter, ":UniqueKey" );
+_LIT( KDataColumn, "data" );
+_LIT( KDataParameter, ":Data" );
+_LIT( KRowIDColumn, "rowID" );
+_LIT( KRowIDParameter, ":rowID" );
+
+_LIT8( KSyncStore, "syncstore" );
+_LIT8( KMeteringStore, "meteringstore" );
+_LIT8( KSecureStore, "securestore" );
+_LIT8( KLicenseStore, "licstore" );
+_LIT8( KHds, "hds" );
+
+const TSecureId KWmDrmServerSecureId( 0x10282F1B );
+const TInt KMaxTIntBufLength( 10 );
+const TInt KLicenseSize( 5 * 1024 );
+const TInt KSixtySeconds( 60 );
+const TInt KMaxOperationsUntilCommit( 60 );
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::CWmDrmDb
+// ---------------------------------------------------------------------------
+//
+CWmDrmDb::CWmDrmDb( CWmDrmServer* aServer ) : CTimer( EPriorityHigh ), 
+    iServer( aServer ),
+    iAmountOperationsWithoutCommit( 0 ),
+    iSqlTransactionOngoing( EFalse ),
+    iSqlTransactionOngoing2( EFalse )   
+    {
+    CActiveScheduler::Add( this );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::ConstructL()
+    {
+    LOGFN( "CWmDrmDb::ConstructL" );
+    TDrmScheme drmScheme( EDrmSchemeWmDrm );
+    TChar driveLetter;
+	TChar systemDriveLetter;
+    
+    CTimer::ConstructL();
+    
+    // Check which drive is configured in the Central Repository Key
+    // for the desired storing location of WM DRM rights.
+	iWmDrmRightsConfigFound = DrmRightsStoringLocation::CheckDrmRightsStorageDriveL( 
+        iServer->Fs(), drmScheme, driveLetter );
+    
+    // Format the default database path on the system drive and open
+    // the database. If the storing location is not configured, this database
+    // will hold all the four stores, otherwise only the secure and metering
+    // stores.
+	if ( !iWmDrmRightsConfigFound )
+		{
+    	iDatabasePath.Format( KDatabaseName, (TUint)driveLetter );
+    	OpenDatabaseL( iDatabasePath, iDatabase, EFalse );
+    	}
+    else 
+        {
+        // Format the database path also on the internal mass drive and 
+        // open both databases. The database on the default system drive
+        // includes metering and secure stores, whereas the store on the
+        // configured drive includes sync and license stores.
+		iDatabasePath.Format( KDatabaseName, 
+		    (TUint)iServer->Fs().GetSystemDriveChar() );
+        iDatabasePath2.Format( KDatabaseName2, (TUint)driveLetter );
+        OpenDatabaseL( iDatabasePath, iDatabase, EFalse );
+		OpenDatabaseL( iDatabasePath2, iDatabase2, ETrue );
+        }               
+    }
+
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::NewL
+// ---------------------------------------------------------------------------
+//
+CWmDrmDb* CWmDrmDb::NewL( CWmDrmServer* aServer )
+    {
+    LOGFN( "CWmDrmDb::NewL" );
+    CWmDrmDb* self( CWmDrmDb::NewLC( aServer ) );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::NewLC
+// ---------------------------------------------------------------------------
+//
+CWmDrmDb* CWmDrmDb::NewLC( CWmDrmServer* aServer )
+    {
+    LOGFN( "CWmDrmDb::NewLC" );
+    CWmDrmDb* self( new( ELeave ) CWmDrmDb( aServer ) );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::~CWmDrmDb
+// ---------------------------------------------------------------------------
+//
+CWmDrmDb::~CWmDrmDb()
+    {
+    LOGFN( "CWmDrmDb::~CWmDrmDb" );
+    
+    TInt error( KErrNone );
+    
+    if ( IsActive() )
+        {
+        Cancel();
+        }
+    
+    // Checks if there are prepared SQL operations that need to be 
+    // committed before the object is destroyed.
+    TRAP( error, CheckDatabaseCommitL( ETrue ) );
+       
+    delete iData;
+    iEnumerateNamespaceStmt.Close();
+    iDatabase.Close();
+    if ( iWmDrmRightsConfigFound )
+		{
+		iDatabase2.Close();
+		}
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::RunL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::RunL()
+    {
+    LOGFN( "CWmDrmDb::RunL()" );
+    
+    switch ( iStatus.Int() )
+        {
+        case KErrNone:
+            // Normal completition
+            
+        case KErrUnderflow:
+            // Time has already passed.
+            
+        case KErrAbort:
+            // System time changed
+            CheckDatabaseCommitL( ETrue );
+            break;
+
+        default:
+            // Some other (real) error
+            // Handled in RunError
+            User::Leave( iStatus.Int() );
+        }
+    }
+
+// ------------------------------------------------------------------------
+// CWmDrmDb::RunError
+// ------------------------------------------------------------------------
+//
+#if defined( _DEBUG ) || defined( _LOGGING )
+TInt CWmDrmDb::RunError( TInt aError )
+#else
+TInt CWmDrmDb::RunError( TInt /* aError */ )
+#endif
+    {
+    LOG2( "CWmDrmDb::RunError %d", aError );
+    // Continue normally and return KErrNone.
+    return KErrNone;    
+    }
+    
+// ------------------------------------------------------------------------
+// CDRMConsume:: Activate
+// ------------------------------------------------------------------------
+void CWmDrmDb::Activate()
+    {
+    LOGFN( "CWmDrmDb::Activate()" );
+    
+    // Activate one minute timer
+    After( TTimeIntervalMicroSeconds32( KSixtySeconds * 1000000 ) );
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::InitStoreL 
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::InitStoreL( 
+    const TDesC8& aStore,
+    TBool /*aCreateIfMissing*/ )
+    {
+    LOGFN( "CWmDrmDb::InitStoreL" );
+    if ( aStore.CompareC( KHds ) == 0 )
+        {
+        if ( iWmDrmRightsConfigFound )
+            {
+            CreateDatabaseL( iDatabasePath, iDatabase, EFalse );
+            CreateDatabaseL( iDatabasePath2, iDatabase2, ETrue );
+            }
+        else
+            {
+            CreateDatabaseL( iDatabasePath, iDatabase, EFalse );
+            }
+        }
+    else
+        {
+        User::Leave( KErrNotFound );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::InitNameSpaceL 
+// ---------------------------------------------------------------------------
+//    
+void CWmDrmDb::InitNameSpaceL( 
+    const TDesC8& /*aStore*/,
+    const TDesC8& aNamespace,
+    TBool /*aCreateIfMissing*/ )
+    {
+    LOGFN( "CWmDrmDb::InitializeL" );
+    TWmDrmTableType tableType( TableTypeL( aNamespace ) );
+    if ( ( tableType == EWmDrmLicenseTable ) && iWmDrmRightsConfigFound )
+    		{  
+    		CreateTableL( tableType, iDatabase2 );
+    		}
+    else
+    		{		
+  			CreateTableL( tableType, iDatabase );
+  			}
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::RemoveStoreL 
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::RemoveStoreL( const TDesC8& aStore )
+    {
+    LOGFN( "CWmDrmDb::RemoveStoreL" );
+    if ( aStore.CompareC( KHds ) == 0 )
+        {
+        // Delete databases
+        iDatabase.Close();
+        User::LeaveIfError( RSqlDatabase::Delete( iDatabasePath ) );
+        
+        // If WM DRM rights storing configuration is found -> delete also
+        // the database on the internal mass drive.
+        if ( iWmDrmRightsConfigFound )
+            {
+            iDatabase2.Close();
+            User::LeaveIfError( RSqlDatabase::Delete( iDatabasePath2 ) );
+            CreateDatabaseL( iDatabasePath, iDatabase, EFalse );
+            CreateDatabaseL( iDatabasePath2, iDatabase2, ETrue );
+            }
+        else
+            {
+            CreateDatabaseL( iDatabasePath, iDatabase, EFalse );
+            }
+        }
+    else
+        {
+        User::Leave( KErrNotFound );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::RemoveNameSpaceL 
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::RemoveNameSpaceL( 
+    const TDesC8& /*aStore*/,
+    const TDesC8& aNamespace )
+    {
+    LOGFN( "CWmDrmDb::RemoveNameSpaceL" );
+    TWmDrmTableType tableType( TableTypeL( aNamespace ) );
+    DeleteTableL( tableType );
+    if ( ( tableType == EWmDrmLicenseTable ) && iWmDrmRightsConfigFound )
+    		{  
+    		CreateTableL( tableType, iDatabase2 );
+    		}
+    else
+    		{			
+  			CreateTableL( tableType, iDatabase );
+  			}
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::DeleteLicenseStoreL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::DeleteLicenseStoreL()
+    {
+    LOGFN( "CWmDrmDb::DeleteLicenseStoreL" );
+    
+   	DeleteTableL( EWmDrmLicenseTable );
+    DeleteTableL( EWmDrmSecureTable );
+    DeleteTableL( EWmDrmSyncTable );
+    
+    if ( iWmDrmRightsConfigFound )
+    		{
+    		CreateTableL( EWmDrmLicenseTable, iDatabase2 );
+   			}
+    else
+    		{
+    		CreateTableL( EWmDrmLicenseTable, iDatabase );
+    		}
+    CreateTableL( EWmDrmSecureTable, iDatabase );
+	CreateTableL( EWmDrmSyncTable, iDatabase );		
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::CreateRecordL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::CreateRecordL(   
+    const TDesC8& /*aStore*/,
+    const TDesC8& aNamespace,
+    const TDesC8& aHashKey,
+    const TDesC8& aUniqueKey,
+    const TInt&   aSize )
+    {
+    LOGFN( "CWmDrmDb::CreateRecordL" );
+    TPtrC statementString( NULL, 0 );
+    
+    // Check if we should begin transaction, cache operation or commit
+    // cached operations 
+    CheckDatabaseCommitL( EFalse );
+    
+    // First, find the table where record should be created
+    TWmDrmTableType tableType( TableTypeL( aNamespace ) );
+    
+    // Update the dummy database file at this point.
+    if ( iWmDrmRightsConfigFound && ( tableType == EWmDrmLicenseTable ) )
+        {
+        iServer->DataStore()->UpdateDummyDbFileL( aSize, ETrue );
+        }
+    else 
+    	{
+    	iServer->DataStore()->UpdateDummyDbFileL( aSize, EFalse );
+    	} 	    
+        
+    // bind sql statement to database
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    
+    //Select correct insert string
+    switch ( tableType )
+        {
+        case EWmDrmLicenseTable:
+            statementString.Set( KInsertLicenseString().Ptr(), 
+                                 KInsertLicenseString().Length() );
+            if ( iWmDrmRightsConfigFound )
+                {
+                stmt.PrepareL( iDatabase2, statementString );
+                }
+            else 
+                {
+                stmt.PrepareL( iDatabase, statementString );
+                }           
+            break;
+        case EWmDrmSecureTable:
+            statementString.Set( KInsertSecureString().Ptr(), 
+                                 KInsertSecureString().Length() );
+            stmt.PrepareL( iDatabase, statementString );                     
+            break;
+        case EWmDrmSyncTable:
+            statementString.Set( KInsertSyncString().Ptr(), 
+                                 KInsertSyncString().Length() );        
+        	stmt.PrepareL( iDatabase, statementString );       
+            break;
+        case EWmDrmMeteringTable:
+            statementString.Set( KInsertMeteringString().Ptr(), 
+                                 KInsertMeteringString().Length() );
+            stmt.PrepareL( iDatabase, statementString );                           
+            break;
+        default:
+            User::Leave( KErrArgument );
+            break;
+        }
+
+    // Get index of hash key parameter
+    TInt hashKeyIndex( stmt.ParameterIndex( KHashKeyParameter ) );
+    User::LeaveIfError( hashKeyIndex );
+    
+    // Replace hash key parameter
+    User::LeaveIfError( stmt.BindBinary( hashKeyIndex, aHashKey ) );
+    
+    // Get index of unique key parameter
+    TInt uniqueKeyIndex( stmt.ParameterIndex( KUniqueKeyParameter ) );
+    User::LeaveIfError( uniqueKeyIndex );
+    
+    // Replace unique key parameter
+    User::LeaveIfError( stmt.BindBinary( uniqueKeyIndex, aUniqueKey ) );
+    
+    TInt err( KErrNone );
+    // Execute SQL statement
+    err = stmt.Exec();
+    if ( err == KSqlErrConstraint )
+        {
+        User::Leave( KErrAlreadyExists );
+        }
+    User::LeaveIfError( err );
+    // Close SQL statement
+    CleanupStack::PopAndDestroy( &stmt );
+    
+    // Update the dummy database file at this point.
+    if ( iWmDrmRightsConfigFound && ( tableType == EWmDrmLicenseTable ) )
+        {
+        iServer->DataStore()->UpdateDummyDbFileL( 0, ETrue );
+        }
+    else 
+    	{    
+    	iServer->DataStore()->UpdateDummyDbFileL( 0, EFalse );
+    	}
+    		
+    iAmountOperationsWithoutCommit++;	
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::ReadRecordL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::ReadRecordL(  
+    const TDesC8& /*aStore*/,
+    const TDesC8& aNamespace,
+    const TDesC8& aHashKey,
+    const TDesC8& aUniqueKey )
+    {
+    LOGFN( "CWmDrmDb::ReadRecordL" );
+    TPtrC statementString( NULL, 0 );
+    // First, find from which table record should be read
+    TWmDrmTableType tableType( TableTypeL( aNamespace ) );
+    
+    // bind sql statement to database
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    
+    // Select correct insert string
+    switch ( tableType )
+        {
+        case EWmDrmLicenseTable:
+            statementString.Set( KSelectLicenseString().Ptr(), 
+                                 KSelectLicenseString().Length() );
+            if ( iWmDrmRightsConfigFound )
+                {
+                stmt.PrepareL( iDatabase2, statementString );
+                }
+            else 
+                {
+                stmt.PrepareL( iDatabase, statementString );
+                }                                           
+            break;
+        case EWmDrmSecureTable:
+            statementString.Set( KSelectSecureString().Ptr(), 
+                                 KSelectSecureString().Length() );
+            stmt.PrepareL( iDatabase, statementString );
+            break;
+        case EWmDrmSyncTable:
+            statementString.Set( KSelectSyncString().Ptr(), 
+                                 KSelectSyncString().Length() );     
+            stmt.PrepareL( iDatabase, statementString );                      
+            break;
+        case EWmDrmMeteringTable:
+            statementString.Set( KSelectMeteringString().Ptr(), 
+                                 KSelectMeteringString().Length() );
+            stmt.PrepareL( iDatabase, statementString );
+            break;
+        default:
+            User::Leave( KErrArgument );
+            break;
+        }
+    
+    // Get index of hash key parameter
+    TInt hashKeyIndex( stmt.ParameterIndex( KHashKeyParameter ) );
+    User::LeaveIfError( hashKeyIndex );
+
+    // Replace key parameter
+    User::LeaveIfError( stmt.BindBinary( hashKeyIndex, aHashKey ) );
+
+    TInt uniqueKeyIndex( stmt.ParameterIndex( KUniqueKeyParameter ) );
+    User::LeaveIfError( uniqueKeyIndex );
+    
+    // Replace unique key parameter
+    User::LeaveIfError( stmt.BindBinary( uniqueKeyIndex, aUniqueKey ) );
+    
+    // Read data
+    TInt dataColumnIndex( stmt.ColumnIndex( KDataColumn ) );
+    User::LeaveIfError( dataColumnIndex );
+
+    if ( stmt.Next() == KSqlAtRow )
+        {
+        // If there is previously cached data, delete it
+        delete iData;
+        iData = NULL;
+        
+        TPtrC8 data( NULL, 0 );
+        User::LeaveIfError( stmt.ColumnBinary( dataColumnIndex, data ) );
+        iData = data.AllocL();
+        }
+    else 
+        {
+        User::Leave( KErrNotFound );
+        }
+
+    // Close SQL statement
+    CleanupStack::PopAndDestroy( &stmt );
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::GetDataSizeL 
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::GetDataSizeL( TInt& aDataSize )
+    {
+    LOGFN( "CWmDrmDb::GetDataSizeL" );
+    User::LeaveIfNull( iData );
+    aDataSize = iData->Size();
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::DeleteData 
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::DeleteData()
+    {
+    LOGFN( "CWmDrmDb::DeleteData" );
+    delete iData;
+    iData = NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::DeleteRecordL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::DeleteRecordL(   
+    const TDesC8& /*aStore*/,
+    const TDesC8& aNamespace,
+    const TDesC8& aHashKey,
+    const TDesC8& aUniqueKey )
+    {
+    LOGFN( "CWmDrmDb::DeleteRecordL" );
+    TPtrC statementString( NULL, 0 );
+    
+    // Check if we should begin transaction, cache operation or commit
+    // cached operations 
+    CheckDatabaseCommitL( EFalse );
+    
+    // First, find the table where record should be created
+    TWmDrmTableType tableType( TableTypeL( aNamespace ) );
+    
+    // bind sql statement to database
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    
+    //Select correct insert string
+    switch ( tableType )
+        {
+        case EWmDrmLicenseTable:
+            statementString.Set( KDeleteLicenseString().Ptr(), 
+                                 KDeleteLicenseString().Length() );
+            if ( iWmDrmRightsConfigFound )
+                {
+                stmt.PrepareL( iDatabase2, statementString );
+                }
+            else 
+                {
+                stmt.PrepareL( iDatabase, statementString );
+                }                      
+            break;
+        case EWmDrmSecureTable:
+            statementString.Set( KDeleteSecureString().Ptr(), 
+                                 KDeleteSecureString().Length() );
+            stmt.PrepareL( iDatabase, statementString );                     
+            break;
+        case EWmDrmSyncTable:
+            statementString.Set( KDeleteSyncString().Ptr(), 
+                                 KDeleteSyncString().Length() );
+            stmt.PrepareL( iDatabase, statementString );
+            break;
+        case EWmDrmMeteringTable:
+            statementString.Set( KDeleteMeteringString().Ptr(), 
+                                 KDeleteMeteringString().Length() );
+            stmt.PrepareL( iDatabase, statementString );                     
+            break;
+        default:
+            User::Leave( KErrArgument );
+            break;
+        }
+
+    // Get index of hash key parameter
+    TInt hashKeyIndex( stmt.ParameterIndex( KHashKeyParameter ) );
+    User::LeaveIfError( hashKeyIndex );
+    
+    // Replace hash key parameter
+    User::LeaveIfError( stmt.BindBinary( hashKeyIndex, aHashKey ) );
+    
+    // Get index of unique key parameter
+    TInt uniqueKeyIndex( stmt.ParameterIndex( KUniqueKeyParameter ) );
+    User::LeaveIfError( uniqueKeyIndex );
+    
+    // Replace unique key parameter
+    User::LeaveIfError( stmt.BindBinary( uniqueKeyIndex, aUniqueKey ) );
+    
+    // Execute SQL statement
+    User::LeaveIfError( stmt.Exec() );
+    
+    // Update dummy database file at this point.
+    if ( iWmDrmRightsConfigFound && ( tableType == EWmDrmLicenseTable ) )
+        {
+        iServer->DataStore()->UpdateDummyDbFileL( 0, ETrue );
+        }
+    else 
+    	{
+    	iServer->DataStore()->UpdateDummyDbFileL( 0, EFalse );
+    	} 	  
+    
+    // Close SQL statement
+    CleanupStack::PopAndDestroy( &stmt );
+    
+    iAmountOperationsWithoutCommit++;
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::ReadDataL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::ReadDataL( TDes8& aData )
+    {
+    LOGFN( "CWmDrmDb::ReadDataL" );
+    User::LeaveIfNull( iData );
+    aData.Copy( *iData );
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::WriteDataL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::WriteDataL(   
+    const TDesC8& /*aStore*/,
+    const TDesC8& aNamespace,
+    const TDesC8& aHashKey,
+    const TDesC8& aUniqueKey, 
+    TDesC8& aData )
+    {
+    LOGFN( "CWmDrmDb::WriteDataL" );
+    TPtrC statementString( NULL, 0 );
+    
+    // Check if we should begin transaction, cache operation or commit
+    // cached operations 
+    CheckDatabaseCommitL( EFalse );
+    
+    // First, find from which table record should be read
+    TWmDrmTableType tableType( TableTypeL( aNamespace ) );
+    
+    // Update the dummy database file at this point.
+    if ( iWmDrmRightsConfigFound && ( tableType == EWmDrmLicenseTable ) )
+        {
+        iServer->DataStore()->UpdateDummyDbFileL( aData.Size(), ETrue );
+        }
+    else 
+    	{
+    	iServer->DataStore()->UpdateDummyDbFileL( aData.Size(), EFalse );
+    	} 	  
+    
+    // bind sql statement to database
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    
+    //Select correct insert string
+    switch ( tableType )
+        {
+        case EWmDrmLicenseTable:
+            statementString.Set( KUpdateLicenseDataString().Ptr(), 
+                                 KUpdateLicenseDataString().Length() );
+            if ( iWmDrmRightsConfigFound )
+                {
+                stmt.PrepareL( iDatabase2, statementString );
+                }
+            else 
+                {
+                stmt.PrepareL( iDatabase, statementString );
+                }                                           
+            break;
+        case EWmDrmSecureTable:
+            statementString.Set( KUpdateSecureDataString().Ptr(), 
+                                 KUpdateSecureDataString().Length() );
+            stmt.PrepareL( iDatabase, statementString );                     
+            break;
+        case EWmDrmSyncTable:
+            statementString.Set( KUpdateSyncDataString().Ptr(), 
+                                 KUpdateSyncDataString().Length() );
+            stmt.PrepareL( iDatabase, statementString );                                          
+            break;
+        case EWmDrmMeteringTable:
+            statementString.Set( KUpdateMeteringDataString().Ptr(), 
+                                 KUpdateMeteringDataString().Length() );
+            stmt.PrepareL( iDatabase, statementString );
+            break;
+        default:
+            User::Leave( KErrArgument );
+            break;
+        }
+    
+    // Get index of hash key parameter
+    TInt hashKeyIndex( stmt.ParameterIndex( KHashKeyParameter ) );
+    User::LeaveIfError( hashKeyIndex );
+
+    // Replace key parameter
+    User::LeaveIfError( stmt.BindBinary( hashKeyIndex, aHashKey ) );
+
+    // Get index of unique key parameter
+    TInt uniqueKeyIndex( stmt.ParameterIndex( KUniqueKeyParameter ) );
+    User::LeaveIfError( uniqueKeyIndex );
+
+    // Replace key parameter
+    User::LeaveIfError( stmt.BindBinary( uniqueKeyIndex, aUniqueKey ) );
+
+    // Get index of value parameter
+    TInt dataIndex( stmt.ParameterIndex( KDataParameter ) );
+    User::LeaveIfError( dataIndex );
+
+    // Replace value parameter
+    User::LeaveIfError( stmt.BindBinary( dataIndex, aData ) );
+
+    // Execute SQL statement
+    LOG1( "CWmDrmDb::WriteDataL exec" );
+    User::LeaveIfError( stmt.Exec() );
+    LOG1( "CWmDrmDb::WriteDataL exec ok" );
+    
+    // Close SQL statement
+    CleanupStack::PopAndDestroy( &stmt );
+    
+    iAmountOperationsWithoutCommit++;
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::EnumerateDataL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::EnumerateDataL(  
+    const TDesC8& /*aStore*/,
+    const TDesC8& aNamespace,
+    const TDesC8& aHashKey,
+    RPointerArray<HBufC8>& aUniqueKeyEntries )
+    {
+    LOGFN( "CWmDrmDb::EnumerateDataL" );
+    TPtrC statementString( NULL, 0 );
+    // First, find from which table record should be read
+    TWmDrmTableType tableType( TableTypeL( aNamespace ) );
+    
+    // bind sql statement to database
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    
+    //Select correct insert string
+    switch ( tableType )
+        {
+        case EWmDrmLicenseTable:
+            statementString.Set( KSelectLicenseEnumeratorString().Ptr(), 
+                                 KSelectLicenseEnumeratorString().Length() );
+            if ( iWmDrmRightsConfigFound )
+                {
+                stmt.PrepareL( iDatabase2, statementString );
+                }
+            else 
+                {
+                stmt.PrepareL( iDatabase, statementString );
+                }                                                
+            break;
+        case EWmDrmSecureTable:
+            statementString.Set( KSelectSecureEnumeratorString().Ptr(), 
+                                 KSelectSecureEnumeratorString().Length() );
+            stmt.PrepareL( iDatabase, statementString );                     
+            break;
+        case EWmDrmSyncTable:
+            statementString.Set( KSelectSyncEnumeratorString().Ptr(), 
+                                 KSelectSyncEnumeratorString().Length() );
+            stmt.PrepareL( iDatabase, statementString );                       
+            break;
+        case EWmDrmMeteringTable:
+            statementString.Set( KSelectMeteringEnumeratorString().Ptr(), 
+                                 KSelectMeteringEnumeratorString().Length() );
+            stmt.PrepareL( iDatabase, statementString );
+            break;
+        default:
+            User::Leave( KErrArgument );
+            break;
+        }
+
+    TInt hashKeyIndex( stmt.ParameterIndex( KHashKeyParameter ) );
+    User::LeaveIfError( hashKeyIndex );
+    
+    // Replace hash key parameter
+    User::LeaveIfError( stmt.BindBinary( hashKeyIndex, aHashKey ) );
+
+    TInt uniqueKeyColumnIndex( stmt.ColumnIndex( KUniqueKeyColumn ) );
+    User::LeaveIfError( uniqueKeyColumnIndex );
+
+    TInt err( KErrNone );
+    TInt index( 0 );
+    TPtrC8 uniqueKeyPtr( NULL, 0 );
+    HBufC8* uniquekey( NULL );
+    while( ( err = stmt.Next() ) == KSqlAtRow )
+        {
+        index++;
+        User::LeaveIfError( 
+            stmt.ColumnBinary( uniqueKeyColumnIndex, uniqueKeyPtr ) );
+        uniquekey = uniqueKeyPtr.AllocLC();
+        aUniqueKeyEntries.AppendL( uniquekey );
+        CleanupStack::Pop( uniquekey );
+        }
+    if ( err != KSqlAtEnd )
+        {
+        User::Leave( err );
+        }
+    if ( index == 0 )
+        {
+        User::Leave( KErrNotFound );
+        }
+
+    // Close SQL statement
+    CleanupStack::PopAndDestroy( &stmt );
+    }
+    
+// ---------------------------------------------------------------------------
+// CWmDrmDb::EnumerateNameSpaceStartL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::EnumerateNameSpaceStartL(  
+    const TDesC8& /*aStore*/,
+    const TDesC8& aNamespace )
+    {
+    LOGFN( "CWmDrmDb::EnumerateNameSpaceStartL" );
+    TPtrC statementString( NULL, 0 );
+    // First, find from which table record should be read
+    TWmDrmTableType tableType( TableTypeL( aNamespace ) );
+    
+    //Select correct insert string
+    switch ( tableType )
+        {
+        case EWmDrmLicenseTable:
+            statementString.Set( KSelectLicenseNameSpaceEnumeratorString().Ptr(), 
+                                 KSelectLicenseNameSpaceEnumeratorString().Length() );
+            // bind sql statement to database                     
+            iEnumerateNamespaceStmt.Close();
+            if ( iWmDrmRightsConfigFound )
+                {
+                iEnumerateNamespaceStmt.PrepareL( iDatabase2, statementString );
+                }
+            else 
+                {
+                iEnumerateNamespaceStmt.PrepareL( iDatabase, statementString );
+                }                     
+            break;
+        case EWmDrmSecureTable:
+            statementString.Set( KSelectSecureNameSpaceEnumeratorString().Ptr(), 
+                                 KSelectSecureNameSpaceEnumeratorString().Length() );                     
+            iEnumerateNamespaceStmt.Close();
+            iEnumerateNamespaceStmt.PrepareL( iDatabase, statementString );                     
+            break;
+        case EWmDrmSyncTable:
+            statementString.Set( KSelectSyncNameSpaceEnumeratorString().Ptr(), 
+                                 KSelectSyncNameSpaceEnumeratorString().Length() );                     
+            iEnumerateNamespaceStmt.Close();                     
+            iEnumerateNamespaceStmt.PrepareL( iDatabase, statementString );
+            break;
+        case EWmDrmMeteringTable:
+            statementString.Set( KSelectMeteringNameSpaceEnumeratorString().Ptr(), 
+                                 KSelectMeteringNameSpaceEnumeratorString().Length() );                     
+            iEnumerateNamespaceStmt.Close();                     
+            iEnumerateNamespaceStmt.PrepareL( iDatabase, statementString );                     
+            break;
+        default:
+            User::Leave( KErrArgument );
+            break;
+        }
+    
+    iEnumerateNamespaceHashKeyColumnIndex = 
+        iEnumerateNamespaceStmt.ColumnIndex( KHashKeyColumn );
+    User::LeaveIfError( iEnumerateNamespaceHashKeyColumnIndex );
+    
+    iEnumerateNamespaceUniqueKeyColumnIndex = 
+        iEnumerateNamespaceStmt.ColumnIndex( KUniqueKeyColumn );
+    User::LeaveIfError( iEnumerateNamespaceUniqueKeyColumnIndex );
+    iEnumerateNamespaceStarted = ETrue;
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::EnumerateNameSpaceNextL
+// ---------------------------------------------------------------------------
+//    
+void CWmDrmDb::EnumerateNameSpaceNextL(  
+    TBuf8<KWmDrmIdSize>& aHashKey,
+    TBuf8<KWmDrmIdSize>& aUniqueKey )
+    {
+    LOGFN( "CWmDrmDb::EnumerateNameSpaceNextL" );
+    if ( !iEnumerateNamespaceStarted )
+        {
+        User::Leave( KErrNotReady );
+        }
+    if ( iEnumerateNamespaceStmt.Next() == KSqlAtRow )
+        {
+        TPtrC8 hashKey( NULL, 0 );
+        TPtrC8 uniqueKey( NULL, 0 );
+        User::LeaveIfError( 
+            iEnumerateNamespaceStmt.ColumnBinary( 
+                iEnumerateNamespaceHashKeyColumnIndex, hashKey ) );
+        aHashKey.Copy( hashKey );
+        User::LeaveIfError( 
+            iEnumerateNamespaceStmt.ColumnBinary( 
+                iEnumerateNamespaceUniqueKeyColumnIndex, uniqueKey ) );
+        aUniqueKey.Copy( uniqueKey );
+        }
+    else 
+        {
+        iEnumerateNamespaceStmt.Close();
+        iEnumerateNamespaceStarted = EFalse;
+        User::Leave( KErrNotFound );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::DataBaseSize
+// ---------------------------------------------------------------------------
+//
+TInt CWmDrmDb::DataBaseSize( TBool aConfiguredDrive )
+    {
+    // Find the database size for the database which is located in the
+    // configured drive
+    if ( aConfiguredDrive )
+        {
+        return iDatabase2.Size();
+        }
+    else
+        {
+        return iDatabase.Size();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::CreateDatabaseL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::CreateDatabaseL( TFileName& aFileNamePath, RSqlDatabase&
+    aSqlDatabase, TBool aConfiguredDrive )
+    {
+    LOGFN( "CWmDrmDb::CreateDatabaseL" );
+    TSecurityPolicy defaultPolicy( KWmDrmServerSecureId );
+    RSqlSecurityPolicy securityPolicy;
+    securityPolicy.CreateL( defaultPolicy );
+    CleanupClosePushL( securityPolicy );
+ 
+    aSqlDatabase.CreateL( aFileNamePath, securityPolicy, &KDatabaseConfig );
+ 
+    if ( aConfiguredDrive ) 
+        {
+        // Create the license store to the configured drive
+        CreateTableL( EWmDrmLicenseTable, aSqlDatabase );   
+        }
+    else 
+        {
+        // Secure, metering and sync stores are located on the system drive in
+        // configured and non-configured WM DRM rights storing location case.
+        CreateTableL( EWmDrmSecureTable, aSqlDatabase );
+        CreateTableL( EWmDrmMeteringTable, aSqlDatabase );
+		CreateTableL( EWmDrmSyncTable, aSqlDatabase );
+		
+        if ( !iWmDrmRightsConfigFound )
+            {
+            CreateTableL( EWmDrmLicenseTable, aSqlDatabase );
+            }
+        }
+    
+    CleanupStack::PopAndDestroy( &securityPolicy );
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::CreateTableL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::CreateTableL( TWmDrmTableType aTableType, RSqlDatabase& aDatabase )
+    {
+    LOGFN( "CWmDrmDb::CreateTableL" );
+    switch ( aTableType )
+        {
+        case EWmDrmLicenseTable:
+            User::LeaveIfError( aDatabase.Exec( KCreateLicenseTableString ) );
+            break;
+        case EWmDrmSecureTable:
+            User::LeaveIfError( aDatabase.Exec( KCreateSecureTableString ) );
+            break;
+        case EWmDrmSyncTable:
+            User::LeaveIfError( aDatabase.Exec( KCreateSyncTableString ) );
+            break;
+        case EWmDrmMeteringTable:
+            User::LeaveIfError( aDatabase.Exec( KCreateMeteringTableString ) );
+            break;
+        default:
+            User::Leave( KErrArgument );
+            break;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::DeleteTableL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::DeleteTableL( TWmDrmTableType aTableType )
+    {
+    LOGFN( "CWmDrmDb::DeleteTableL" );
+    TInt count( 1 );
+    TInt64 freeSpace( 0 );
+    TInt databaseSize( 0 );
+    
+    // Commit the cached database operations before deleting the table
+    CheckDatabaseCommitL( ETrue );
+        
+    // Check the free space from the system drive or internal mass drive
+    // depending on the WM DRM rights storing location configuration and
+    // the table type of the database
+    if ( iWmDrmRightsConfigFound && ( aTableType == EWmDrmLicenseTable ) )
+        {
+        freeSpace = iServer->FreeSpaceL( ETrue );
+        databaseSize = DataBaseSize( ETrue );
+        User::LeaveIfError( databaseSize );
+        
+        //Just to make sure we don't have reserved space in usage
+        iDatabase2.ReleaseReserveAccess();
+        }
+    else 
+        {
+        freeSpace = iServer->FreeSpaceL( EFalse );
+        databaseSize = DataBaseSize( EFalse );
+        User::LeaveIfError( databaseSize );
+        iDatabase.ReleaseReserveAccess();
+        }
+    
+    //If size of the database < freespace or there aren't anymore any 
+    //records in the table, then drop whole table.
+    //Otherwise loop and delete as many records as possible with
+    //current amount of free space.
+    while ( databaseSize > freeSpace && count > 0 )
+        {
+        
+        //Get reserved space to usage
+        if ( iWmDrmRightsConfigFound && ( aTableType == EWmDrmLicenseTable ) )
+            {
+            User::LeaveIfError( iDatabase2.GetReserveAccess() );
+            }
+        else
+            {
+            User::LeaveIfError( iDatabase.GetReserveAccess() );
+            } 
+        
+        //Estimate how many records can be deleted with current amount of free space
+        TInt number( 0 );
+        //Very low free space, OOD-notes shown, target to get off as soon as possible
+        //without risking deletion success
+        if ( freeSpace <= KDRIVECWARNINGTHRESHOLD )
+            {
+            LOG1( "Disk space under warning level" );
+            if ( freeSpace <= KDRIVECCRITICALTHRESHOLD )
+                {
+                LOG1( "Disk space under critical level" );
+                //Use reserved space
+                number = 5;
+                }
+            else
+                {
+                //Use reserved space and space over critical level
+                TInt spaceOverCritical( freeSpace - KDRIVECCRITICALTHRESHOLD );
+                LOG2( "spaceOverCritical: %d", spaceOverCritical );
+                number = spaceOverCritical / KLicenseSize + 5;
+                }
+            }
+        //Disk is still almost full, but we don't wan't to get any OOD-notes anymore
+        else if ( freeSpace <= ( 2 * KDRIVECWARNINGTHRESHOLD ) )
+            {
+            LOG1( "Disk almost full, delete with caution and try to avoid OOD-notes" );
+            TInt spaceOverWarning( freeSpace - KDRIVECWARNINGTHRESHOLD );
+            LOG2( "spaceOverWarning: %d", spaceOverWarning );
+            //Use 1/2 space over warning level, OOD-note might still be shown
+            number = ( spaceOverWarning / 2 ) / KLicenseSize;
+            }
+        //Now there is enough space to delete larger number of records
+        //Make absolutely sure we don't anymore get OOD-notes
+        else
+            {
+            TInt spaceOver2Warnings( freeSpace - 2 * KDRIVECWARNINGTHRESHOLD );
+            LOG2( "spaceOver2Warnings: %d", spaceOver2Warnings );
+            //Use space over 2 * warning level, no OOD-notes
+            number = spaceOver2Warnings / KLicenseSize;
+            }
+        if ( number <= 0 )
+            {
+            number = 5;
+            }
+        
+        LOG2( "number: %d", number );
+        
+        //Array to hold rowIDS of to be deleted records
+        RArray<TInt64> array;
+        CleanupClosePushL( array );
+        
+        //Get number of rowIDs to array 
+        SelectNRecordsWithRowIdL( aTableType, number, array );
+        //Get amount of selected rowIds
+        count = array.Count();
+        
+        //Begin transaction
+        if ( iWmDrmRightsConfigFound && ( aTableType == EWmDrmLicenseTable ) )
+            {
+            User::LeaveIfError( iDatabase2.Exec( KBeginTransaction ) );
+            iSqlTransactionOngoing2 = ETrue;
+            //Execute delete with rowIds
+            DeleteRecordsWithRowIdsL( aTableType, array );
+            //Commit transaction
+            User::LeaveIfError( iDatabase2.Exec( KCommitTransaction ) );
+            iSqlTransactionOngoing2 = EFalse;
+            }
+        else 
+            {
+            User::LeaveIfError( iDatabase.Exec( KBeginTransaction ) );
+            iSqlTransactionOngoing = ETrue;
+            DeleteRecordsWithRowIdsL( aTableType, array );
+            User::LeaveIfError( iDatabase.Exec( KCommitTransaction ) );
+            iSqlTransactionOngoing = EFalse;
+            }
+        
+        CleanupStack::PopAndDestroy( &array );
+        
+        //Prepare for the next round
+        if ( iWmDrmRightsConfigFound && ( aTableType == EWmDrmLicenseTable ) )
+        	{
+        	freeSpace = iServer->FreeSpaceL( ETrue );
+        	databaseSize = DataBaseSize( ETrue );
+        	User::LeaveIfError( databaseSize );
+        
+        	//Release access to reserved space
+        	iDatabase2.ReleaseReserveAccess();
+        	}
+    	else 
+        	{
+        	freeSpace = iServer->FreeSpaceL( EFalse );
+        	databaseSize = DataBaseSize( EFalse );
+        	User::LeaveIfError( databaseSize );
+        	iDatabase.ReleaseReserveAccess();
+        	}
+        }		
+    DropTableL( aTableType );
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::SelectNRecordsWithRowIdL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::SelectNRecordsWithRowIdL(
+    TWmDrmTableType aTableType,
+    TInt aNumber,
+    RArray<TInt64>& aArray )
+    {
+    LOGFN( "CWmDrmDb::SelectNRecordsWithRowIdL" );
+    TPtr statementPtr( NULL, 0 );
+    HBufC* statement( NULL );
+    //Select right statement and append number to be the limit in statement
+    
+    //Prepare select statement and get rowID column index
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    
+    switch ( aTableType )
+        {
+        case EWmDrmLicenseTable:
+            statement = HBufC::NewLC( KSelectNRowIDsLicenseTableString().Length() + 
+                                      KMaxTIntBufLength );
+            statementPtr.Set( statement->Des() );
+            statementPtr.AppendFormat( KSelectNRowIDsLicenseTableString, aNumber );
+             //Prepare select statement
+            if ( iWmDrmRightsConfigFound )
+                {
+                stmt.PrepareL( iDatabase2, statementPtr );
+                }
+            else
+                {
+                stmt.PrepareL( iDatabase, statementPtr );
+                }
+            break;
+        case EWmDrmSecureTable:
+            statement = HBufC::NewLC( KSelectNRowIDsSecureTableString().Length() + 
+                                      KMaxTIntBufLength );
+            statementPtr.Set( statement->Des() );
+            statementPtr.AppendFormat( KSelectNRowIDsSecureTableString, aNumber );
+            stmt.PrepareL( iDatabase, statementPtr );
+            break;
+        case EWmDrmSyncTable:
+            statement = HBufC::NewLC( KSelectNRowIDsSyncTableString().Length() + 
+                                      KMaxTIntBufLength );
+            statementPtr.Set( statement->Des() );
+            statementPtr.AppendFormat( KSelectNRowIDsSyncTableString, aNumber );
+            stmt.PrepareL( iDatabase, statementPtr );
+            break;
+        case EWmDrmMeteringTable:
+            statement = HBufC::NewLC( KSelectNRowIDsMeteringTableString().Length() + 
+                                      KMaxTIntBufLength );
+            statementPtr.Set( statement->Des() );
+            statementPtr.AppendFormat( KSelectNRowIDsMeteringTableString, aNumber );
+            stmt.PrepareL( iDatabase, statementPtr );
+            break;
+        default:
+            User::Leave( KErrArgument );
+            break;
+        }
+    
+    //Get rowID column index
+    TInt rowIDColumnIndex( stmt.ColumnIndex( KRowIDColumn ) );
+    User::LeaveIfError( rowIDColumnIndex );
+
+    //Append all selected rowIDs to array
+    TInt err( KErrNone );
+    while ( ( err = stmt.Next() ) == KSqlAtRow )
+        {
+        aArray.AppendL( stmt.ColumnInt64( rowIDColumnIndex ) );
+        }
+
+    LOG2( "err: %d", err );
+    if ( err != KSqlAtEnd )
+        {
+        User::Leave( err );
+        }
+    CleanupStack::PopAndDestroy( 2, statement ); //stmt, statement
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::DeleteRecordsWithRowIdsL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::DeleteRecordsWithRowIdsL(   
+    TWmDrmTableType aTableType,
+    RArray<TInt64>& aArray )
+    {
+    LOGFN( "CWmDrmDb::DeleteRecordsWithRowIdsL" );
+    //Select right statement
+    TPtrC statementString( NULL, 0 );
+    RSqlStatement stmt;
+    CleanupClosePushL( stmt );
+    
+    //Prepare delete statement and get rowID parameter index
+    
+    switch ( aTableType )
+        {
+        case EWmDrmLicenseTable:
+            statementString.Set( KDeleteWithRowIDLicenseTableString().Ptr(), 
+                                 KDeleteWithRowIDLicenseTableString().Length() );
+            //Prepare delete statement
+            if ( iWmDrmRightsConfigFound )
+                {
+                stmt.PrepareL( iDatabase2, statementString );
+                }
+            else
+                {
+                stmt.PrepareL( iDatabase, statementString );
+                }                    
+            break;
+        case EWmDrmSecureTable:
+            statementString.Set( KDeleteWithRowIDSecureTableString().Ptr(), 
+                                 KDeleteWithRowIDSecureTableString().Length() );
+            stmt.PrepareL( iDatabase, statementString );                     
+            break;
+        case EWmDrmSyncTable:
+            statementString.Set( KDeleteWithRowIDSyncTableString().Ptr(), 
+                                 KDeleteWithRowIDSyncTableString().Length() );
+            //Prepare delete statement
+            stmt.PrepareL( iDatabase, statementString );                      
+            break;
+        case EWmDrmMeteringTable:
+            statementString.Set( KDeleteWithRowIDMeteringTableString().Ptr(), 
+                                 KDeleteWithRowIDMeteringTableString().Length() );
+            stmt.PrepareL( iDatabase, statementString );                     
+            break;
+        default:
+            User::Leave( KErrArgument );
+            break;
+        }
+    
+    // Get rowID parameter index
+    TInt rowIDIndex( stmt.ParameterIndex( KRowIDParameter ) );
+    User::LeaveIfError( rowIDIndex );
+    
+    //Execute delete statement with every rowID value from the array
+    LOG2( "aArray.Count(): %d", aArray.Count() );
+    for ( TInt i( 0 ); i < aArray.Count(); ++i )
+        {
+        User::LeaveIfError( stmt.BindInt64( rowIDIndex, aArray[i] ) );
+        User::LeaveIfError( stmt.Exec() );
+        User::LeaveIfError( stmt.Reset() );
+        }
+    CleanupStack::PopAndDestroy( &stmt );
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::DropTableL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::DropTableL( TWmDrmTableType aTableType )
+    {
+    LOGFN( "CWmDrmDb::DropTableL" );
+    switch ( aTableType )
+        {
+        case EWmDrmLicenseTable:
+            if ( iWmDrmRightsConfigFound )
+                {
+                User::LeaveIfError( iDatabase2.Exec( KDeleteLicenseTableString ) );
+                }
+            else 
+                {
+                User::LeaveIfError( iDatabase.Exec( KDeleteLicenseTableString ) );
+                }
+            break;
+        case EWmDrmSecureTable:
+            User::LeaveIfError( iDatabase.Exec( KDeleteSecureTableString ) );
+            break;
+        case EWmDrmSyncTable:
+        	User::LeaveIfError( iDatabase.Exec( KDeleteSyncTableString ) );
+            break;
+        case EWmDrmMeteringTable:
+            User::LeaveIfError( iDatabase.Exec( KDeleteMeteringTableString ) );
+            break;
+        default:
+            LOG1( "CWmDrmDb::DropTableL error" );
+            User::Leave( KErrArgument );
+            break; 
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::TableTypeL
+// ---------------------------------------------------------------------------
+//
+CWmDrmDb::TWmDrmTableType CWmDrmDb::TableTypeL( const TDesC8& aNamespace )
+    {
+    LOGFN( "CWmDrmDb::TableTypeL" );
+    if ( aNamespace.CompareC( KLicenseStore  ) == 0 )
+        {
+        return EWmDrmLicenseTable;
+        }
+    else if ( aNamespace.CompareC( KSecureStore  ) == 0 )
+        {
+        return EWmDrmSecureTable;
+        }
+    else if ( aNamespace.CompareC( KSyncStore  ) == 0 )
+        {
+        return EWmDrmSyncTable;
+        }
+    else if ( aNamespace.CompareC( KMeteringStore  ) == 0 )
+        {
+        return EWmDrmMeteringTable;
+        }    
+    else
+        {
+        User::Leave( KErrNotFound );
+        return EWmDrmLicenseTable;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::OpenDatabaseL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::OpenDatabaseL( TFileName& aFileNamePath, RSqlDatabase&
+    aSqlDatabase, TBool aConfiguredDrive )
+    {
+    TInt error( aSqlDatabase.Open( aFileNamePath ) );
+    LOG2( "CWmDrmDb: Opening database, status: %d", error );
+    
+    if ( error == KErrNotFound )
+        {
+        // database does not exist, create one
+        CreateDatabaseL( aFileNamePath, aSqlDatabase, aConfiguredDrive );
+		}
+    else if ( error == KSqlErrCorrupt || error == KSqlErrNotDb )
+        {
+        RemoveStoreL( KHds );
+        }
+    else
+        {
+        // Error while opening database
+        User::LeaveIfError( error );
+        }
+    User::LeaveIfError( aSqlDatabase.ReserveDriveSpace( 10 * KLicenseSize ) );
+    }
+
+// ---------------------------------------------------------------------------
+// CWmDrmDb::CheckDatabaseCommitL
+// ---------------------------------------------------------------------------
+//
+void CWmDrmDb::CheckDatabaseCommitL( TBool aEnforcedCommit )
+    {
+    LOGFN( "CWmDrmDb::CheckCommitDatabaseL()" );
+    
+    // Restart the timer for committing the changes to the database
+    if ( !aEnforcedCommit )
+        {
+        if ( IsActive() )
+            {
+            Cancel();
+            }
+        Activate();
+        }
+        
+    // Check if the amount of cached database operations reaches the upper 
+    // limit or if we need to have a forced commit.
+    if ( ( iAmountOperationsWithoutCommit >= KMaxOperationsUntilCommit ) || 
+        aEnforcedCommit )
+        {
+        if ( iWmDrmRightsConfigFound && iSqlTransactionOngoing2 )
+            {
+            User::LeaveIfError( iDatabase2.Exec( KCommitTransaction ) );
+            iSqlTransactionOngoing2 = EFalse;
+            }
+        
+        if ( iSqlTransactionOngoing )
+            {
+            User::LeaveIfError( iDatabase.Exec( KCommitTransaction ) );
+            iSqlTransactionOngoing = EFalse;
+            }
+            
+        // Reset the counter
+        iAmountOperationsWithoutCommit = 0;        
+        }
+    
+    // In case of non-forced commit, execute new BEGIN statement for caching
+    // future SQL statements.
+    if ( ( iAmountOperationsWithoutCommit == 0 ) && !aEnforcedCommit )
+        {
+        if ( iWmDrmRightsConfigFound )
+            {
+            User::LeaveIfError( iDatabase2.Exec( KBeginTransaction ) );
+            iSqlTransactionOngoing2 = ETrue;
+            }
+        User::LeaveIfError( iDatabase.Exec( KBeginTransaction ) );
+        iSqlTransactionOngoing = ETrue;
+        }
+    }
+