diff -r b13cd05eeb2f -r 57b735022c18 srsf/sisrscontrollerplugin/src/sidatabase.cpp --- a/srsf/sisrscontrollerplugin/src/sidatabase.cpp Mon Jan 18 20:20:30 2010 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,514 +0,0 @@ -/* -* Copyright (c) 2004-2006 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 class implements the SI Controller Plugin database. -* -*/ - - -// INCLUDE FILES -#include "sidatabase.h" -#include "rubydebug.h" -#include "nssbackupobserver.h" - - -// CONSTANTS -// Estimate size in bytes for an empty database -// const TInt KSizeEstimateDb = 650; - -// Plugin database format string for secure DBMS -_LIT( KPluginDatabaseFormatString, "SECURE[10201AFF]" ); - -// Name of the DB lock mutex -_LIT( KLockMutex, "SIDATABASE" ); - -// ============================ MEMBER FUNCTIONS =============================== - -// ----------------------------------------------------------------------------- -// CSIDatabase::CSIDatabase -// C++ default constructor can NOT contain any code, that -// might leave. -// ----------------------------------------------------------------------------- -// -CSIDatabase::CSIDatabase( TFileName aDatabaseFileName ) - : iOpenTransaction( EFalse ), - iDatabaseFileName( aDatabaseFileName ), - iDatabaseOpen( EFalse ) - { - // Nothing - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::ConstructL -// Symbian 2nd phase constructor can leave. -// ----------------------------------------------------------------------------- -// -void CSIDatabase::ConstructL() - { - RUBY_DEBUG_BLOCKL( "CSIDatabase::ConstructL" ); - // Checks to see if the Database already exists. If not, it creates one. - User::LeaveIfError( iDbSession.Connect() ); - CreateDatabaseL(); - OpenDatabaseL(); - - TInt err = iMutex.OpenGlobal( KLockMutex ); - if ( err != KErrNone ) - { - RUBY_DEBUG0( "CSIDatabase::ConstructL Creating new global mutex" ); - iMutex.CreateGlobal( KLockMutex ); - } - else - { - RUBY_DEBUG0( "CSIDatabase::ConstructL Using existing global mutex" ); - } - - iCriticalSection.CreateLocal(); - iBackupObserver = CNssBackupObserver::NewL( *this ); - - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::NewL -// Two-phased constructor. -// ----------------------------------------------------------------------------- -// -CSIDatabase* CSIDatabase::NewL( TFileName aSDDatabaseFileName ) - { - RUBY_DEBUG_BLOCKL( "CSIDatabase::NewL" ); - - CSIDatabase* self = new( ELeave ) CSIDatabase( aSDDatabaseFileName ); - CleanupStack::PushL( self ); - self->ConstructL(); - CleanupStack::Pop(); - - return self; - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::Rollback -// Rollback all changes to the database. -// ----------------------------------------------------------------------------- -// -void CSIDatabase::Rollback() - { - RUBY_DEBUG0( "CSIDatabase::Rollback" ); - if ( iOpenTransaction ) - { - iDb.Rollback(); - // Try to recover the database, if it is damaged - if( iDb.IsDamaged() ) - { - iDb.Recover(); - } - iMutex.Signal(); - iCriticalSection.Signal(); - iOpenTransaction = EFalse; - } - - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::~CSIDatabase -// Destructor -// ----------------------------------------------------------------------------- -// -CSIDatabase::~CSIDatabase() - { - // Rollback if there are any changes not commited - if ( iOpenTransaction ) - { - iDb.Rollback(); - // Try to recover the database, if it is damaged - if( iDb.IsDamaged() ) - { - iDb.Recover(); - } - // Signal mutex if somebody happens to be waiting in BeginTransactionL() - iMutex.Signal(); - } - - delete iBackupObserver; - iCriticalSection.Close(); - - iDb.Close(); - iDbSession.Close(); - iDatabaseOpen = EFalse; - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::BeginTransactionL -// Begins a database transaction if not already. Waits until exclusive write lock -// has been gained. -// ----------------------------------------------------------------------------- -// -void CSIDatabase::BeginTransactionL() - { - - - if ( iOpenTransaction ) - { - // If we already have the lock, no need to take it again - RUBY_DEBUG0( "CSIDatabase::BeginTransactionL DB is already locked by current process" ); - return; - } - - // Take mutex to ensure that only one process tries to gain the lock - iMutex.Wait(); - iCriticalSection.Wait(); - - // Taking the global mutex makes it sure that this should succeed every time - TInt readLockErr = iDb.Begin(); - - if ( readLockErr == KErrNone ) - { - iOpenTransaction = ETrue; - } - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::CommitChangesL -// Commits all changes to the database. -// ----------------------------------------------------------------------------- -// -void CSIDatabase::CommitChangesL( TBool aCompact ) - { - if ( iOpenTransaction ) - { - TInt err = iDb.Commit(); - - RUBY_DEBUG1( "CSIDatabase::CommitChangesL iDb.Commit() [%d]", err ); - - if ( err != KErrNone ) - { - iDb.Rollback(); - // Try to recover the database, if it is damaged - if( iDb.IsDamaged() ) - { - iDb.Recover(); - } - - iMutex.Signal(); - iCriticalSection.Signal(); - iOpenTransaction = EFalse; - User::Leave( err ); - } - - if ( aCompact ) - { - RUBY_DEBUG0( "CSIDatabase::CommitChangesL compacting DB" ); - TInt error = iDb.Compact(); - if ( error != KErrNone ) - { - RUBY_DEBUG1( "CSIDatabase::CommitChangesL compact error: [%d]", error ); - } - } - - // Signal waiting BeginTransactionL() - iMutex.Signal(); - iCriticalSection.Signal(); - iOpenTransaction = EFalse; - - User::LeaveIfError( err ); - } - - - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::DoIDTablesExistL -// Checks to see if ID tables exist. -// ----------------------------------------------------------------------------- -// -TBool CSIDatabase::DoIDTablesExistL() - { - // Get db table names list - CDbTableNames* table_names = iDb.TableNamesL(); - TInt count = table_names->Count(); - delete table_names; - // 1 is for the lock table! - return ( count > 1 ); - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::DoesLockTableExistL -// Checks to see if lock table exists -// ----------------------------------------------------------------------------- -// -TBool CSIDatabase::DoesLockTableExistL() - { - // Get db table names list - CDbTableNames* table_names = iDb.TableNamesL(); - TInt count = table_names->Count(); - - for ( TInt counter = 0 ; counter < count ; counter++ ) - { - if ( (*table_names)[counter] == _L( "writelocktable" ) ) - { - delete table_names; - return ETrue; - } - } - - delete table_names; - return EFalse; - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::DoesModelBankTableExistL -// Checks to see if model bank table exists -// ----------------------------------------------------------------------------- -// -TBool CSIDatabase::DoesModelBankTableExistL() - { - // Get db table names list - CDbTableNames* table_names = iDb.TableNamesL(); - TInt count = table_names->Count(); - - for ( TInt counter = 0 ; counter < count ; counter++ ) - { - if ( (*table_names)[counter] == _L( "siModelBankIdTable" ) ) - { - delete table_names; - return ETrue; - } - } - - delete table_names; - return EFalse; - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::DoesLexiconTableExistL -// Checks if lexicon table exists -// ----------------------------------------------------------------------------- -// -TBool CSIDatabase::DoesLexiconTableExistL() - { - // Get db table names list - CDbTableNames* table_names = iDb.TableNamesL(); - TInt count = table_names->Count(); - - for ( TInt counter = 0 ; counter < count ; counter++ ) - { - if ( (*table_names)[counter] == _L( "siLexiconIdTable" ) ) - { - delete table_names; - return ETrue; - } - } - - delete table_names; - return EFalse; - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::DoesGrammarTableExistL -// Checks if grammar table exists -// ----------------------------------------------------------------------------- -// -TBool CSIDatabase::DoesGrammarTableExistL() - { - // Get db table names list - CDbTableNames* table_names = iDb.TableNamesL(); - TInt count = table_names->Count(); - - for ( TInt counter = 0 ; counter < count ; counter++ ) - { - if ( (*table_names)[counter] == _L( "siGrammarIdTable" ) ) - { - delete table_names; - return ETrue; - } - } - - delete table_names; - return EFalse; - } - - -// ----------------------------------------------------------------------------- -// CSIDatabase::SIDatabase -// Returns a reference to the database. -// ----------------------------------------------------------------------------- -// -RDbNamedDatabase& CSIDatabase::SIDatabase() - { - return iDb; - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::CreateDatabaseL -// Creates a database file if one does not exist yet. -// ----------------------------------------------------------------------------- -// -void CSIDatabase::CreateDatabaseL() - { - RUBY_DEBUG_BLOCKL( "CSIDatabase::CreateDatabaseL" ); - - // Get the drive of the database file - iDatabaseDrive = EDriveC; - if ( iDatabaseFileName.Locate( 'c' ) == 0 || iDatabaseFileName.Locate( 'C' ) == 0 ) - { - iDatabaseDrive = EDriveC; - } - else if ( iDatabaseFileName.Locate( 'd' ) == 0 || iDatabaseFileName.Locate( 'D' ) == 0 ) - { - iDatabaseDrive = EDriveD; - } - else if ( iDatabaseFileName.Locate( 'z' ) == 0 || iDatabaseFileName.Locate( 'Z' ) == 0 ) - { - iDatabaseDrive = EDriveZ; - } - - else if ( iDatabaseFileName.Locate( 'e' ) == 0 || iDatabaseFileName.Locate( 'E' ) == 0 ) - { - iDatabaseDrive = EDriveE; - } - else - { - User::Leave( KErrPathNotFound ); - } - - RDbNamedDatabase database; - TInt ret = database.Create( iDbSession, iDatabaseFileName, KPluginDatabaseFormatString ); - if ( ret == KErrAlreadyExists ) - { - // Ignore KErrAlreadyExists, we will use the existing one if it is there - ret = KErrNone; - } - database.Close(); - User::LeaveIfError( ret ); - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::OpenDatabaseL -// Opens the database. -// ----------------------------------------------------------------------------- -// -void CSIDatabase::OpenDatabaseL() - { - if ( !iDatabaseOpen ) - { - - User::LeaveIfError( iDb.Open( iDbSession, iDatabaseFileName, KPluginDatabaseFormatString ) ); - - // Try to recover the database, if it is damaged - if( iDb.IsDamaged() ) - { - RUBY_DEBUG0( "CSIDatabase::OpenDatabaseL - Db is damaged. Attempt to recover." ); - - User::LeaveIfError( iDb.Recover() ); - } - - iDatabaseOpen = ETrue; - } - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::CloseDatabase -// Closes the database. -// ----------------------------------------------------------------------------- -// -TInt CSIDatabase::CloseDatabase() - { - RUBY_DEBUG0( "CSIDatabase::CloseDatabase" ); - - iDb.Close(); - iDatabaseOpen = EFalse; - - return KErrNone; - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::DbSession -// Return reference to DB session. -// ----------------------------------------------------------------------------- -// -RDbs& CSIDatabase::DbSession() - { - return iDbSession; - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::DbDrive -// Returns a drive for DB file. -// ----------------------------------------------------------------------------- -// -TInt CSIDatabase::DbDrive() - { - return iDatabaseDrive; - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::CreateLockTableL -// Creates a dummy table to gain write-lock at the beginning of each transaction. -// ----------------------------------------------------------------------------- -// -void CSIDatabase::CreateLockTableL() - { - // Create writelocktable - // This table is accessed every time when transaction starts to gain - // exclusive locking of the DB - _LIT( KWriteLockTable, "writelocktable" ); - - _LIT( KCol1, "temporary" ); - - OpenDatabaseL(); - - // Create the rrd tables definition (columnset). - CDbColSet* columns = CDbColSet::NewLC(); - - // The tag id - TDbCol dbCol1( KCol1, EDbColUint32 ); - columns->AddL( dbCol1 ); - - User::LeaveIfError( iDb.CreateTable( KWriteLockTable, *columns ) ); - - // Cleanup columns - CleanupStack::PopAndDestroy( columns ); - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::LockTransactionsL -// Permit transactions and release database -// ----------------------------------------------------------------------------- -// -void CSIDatabase::LockTransactionsL() - { - // lock transactions - RUBY_DEBUG_BLOCK( "CSIDatabase::LockTransactionsL" ); - - iCriticalSection.Wait(); // wait until a possible transaction ends - - // release a database - CloseDatabase(); - } - -// ----------------------------------------------------------------------------- -// CSIDatabase::UnlockTransactionsL -// Allow transactions and reserve database -// ----------------------------------------------------------------------------- -// -void CSIDatabase::UnlockTransactionsL() - { - // unlock transactions - RUBY_DEBUG_BLOCK( "CSIDatabase::UnlockTransactionsL" ); - OpenDatabaseL(); // open database - - if ( iCriticalSection.IsBlocked() ) - { - iCriticalSection.Signal(); // allow to do transactions - } - } - -// End of File