diff -r 826cea16efd9 -r 13a33d82ad98 videoscheduler/SchedulerServer/src/CCseScheduleDB.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videoscheduler/SchedulerServer/src/CCseScheduleDB.cpp Wed Sep 01 12:20:37 2010 +0100 @@ -0,0 +1,2077 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "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 where to store scheduled events.* +*/ + + + + +// INCLUDE FILES +#include "CCseScheduleDB.h" // Header file for this class +#include // Represent one schedule in database +#include +#include "CseDebug.h" // Debug macros +#include + +// EXTERNAL DATA STRUCTURES +// None + +// EXTERNAL FUNCTION PROTOTYPES +// None + +// CONSTANTS +_LIT( KCseCDiskPrefix, "c:" ); +_LIT( KCseSqlGetAll, "SELECT * FROM ScheduleEvent"); +_LIT( KCseSelectFromDb, "SELECT * FROM " ); +_LIT( KCseWhere, " WHERE " ); +_LIT( KCseEqual, " = " ); +_LIT( KCseOrderBy, " ORDER BY " ); +_LIT( KCseAnd, " AND " ); +_LIT( KCseLess, " < " ); +_LIT( KCseMore, " > " ); + +static TUint KScheduleNameMaxLength = 255; +static TUint KCseDatbaseVersionNumber = 1; + +// MACROS +// None + +// LOCAL CONSTANTS AND MACROS +// None + +// MODULE DATA STRUCTURES +// None + +// LOCAL FUNCTION PROTOTYPES +// None + +// FORWARD DECLARATIONS +// None + +// ============================ MEMBER FUNCTIONS =============================== +// --------------------------------------------------------------------------- +// CCseScheduleDB::CCseScheduleDB() +// +// --------------------------------------------------------------------------- +CCseScheduleDB::CCseScheduleDB() : iDbAccess( ECseDbOpen ) + { + CSELOGSTRING_HIGH_LEVEL(">>>CCseScheduleDB::CCseScheduleDB"); + // Default C++ Constructor + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::~CCseScheduleDB"); + + iScheduleDb.Close(); + delete iScheduleFileStore; + iFsSession.Close(); + + if( iCompactTimer ) + { + iCompactTimer->Cancel(); + delete iCompactTimer; + } + delete iBackupWrapper; + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::NewL"); + CCseScheduleDB* self = new ( ELeave ) CCseScheduleDB(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::ConstructL"); + + User::LeaveIfError( iFsSession.Connect() ); + + iCompactTimer = CPeriodic::NewL( CActive::EPriorityStandard ); + + iBackupWrapper = CBaBackupSessionWrapper::NewL(); + + TRAPD( err, OpenOrCreateDbL() ); + + if ( err != KErrNone ) + { + CSELOGSTRING2_HIGH_LEVEL( "CCseScheduleDB::ConstructL - Opening or creating the database FAILED: %d", err ); + + if ( err != KErrNoMemory && + err != KErrLocked && + err != KErrDisMounted && + err != KErrDiskFull && + err != KErrNotReady ) + { + // Delete and recreate database file. Cannot recover other way. + CSELOGSTRING_HIGH_LEVEL( "CCseScheduleDB::ConstructL - deleting database" ); + RemoveDbL(); + CSELOGSTRING_HIGH_LEVEL( "CCseScheduleDB::ConstructL - recreating database" ); + TRAPD( err, OpenOrCreateDbL() ); + if ( err != KErrNone ) + { + CSELOGSTRING2_HIGH_LEVEL( "CCseScheduleDB::ConstructL couldnt recreate database (%d), leaving", err ); + User::Leave( err ); + } + } + else + { + CSELOGSTRING2_HIGH_LEVEL( "CCseScheduleDB::ConstructL leaving (%d)", err ); + User::Leave( err ); + } + } + CSELOGSTRING_HIGH_LEVEL("<<& aArray ) + { + CSELOGSTRING2_HIGH_LEVEL(">>>CCseScheduleDB::GetApplicationSchedulesL - AppUid: %d", + aAppUid); + + LeaveIfDbLockedL(); + ResetCompactTimer(); + + // Gets program occurence(s) that are going to happen next + // from database + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleApplicationUIDCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.AppendNum( aAppUid ); + sqlStatement.Append( KCseOrderBy ); + sqlStatement.Append( KCseScheduleStartTimeCol ); + + // Order table based on start time + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + view.FirstL(); + + CDbColSet* colSetOrder = view.ColSetL(); + CleanupStack::PushL( colSetOrder ); + + // Get the SQL table indexes. + TDbColNo keyIndex = colSetOrder->ColNo( KCseScheduleDbKeyCol ); + TDbColNo nameIndex = colSetOrder->ColNo( KCseScheduleNameCol ); + TDbColNo startTimeIndex = colSetOrder->ColNo( KCseScheduleStartTimeCol ); + TDbColNo endTimeIndex = colSetOrder->ColNo( KCseScheduleEndTimeCol ); + TDbColNo applicationUidIdIndex = colSetOrder->ColNo( KCseScheduleApplicationUIDCol ); + TDbColNo plugInUidIndex = colSetOrder->ColNo( KCseSchedulePlugInUIDCol ); + TDbColNo applicationSpecificIndex = colSetOrder->ColNo( KCseScheduleApplicationSpecificCol ); + TDbColNo scheduleTypeIndex = colSetOrder->ColNo( KCseScheduleTypeCol ); + TDbColNo pluginTypeIndex = colSetOrder->ColNo( KCseSchedulePluginTypeCol ); + + CleanupStack::PopAndDestroy( colSetOrder ); + + // Loop through the tables + while ( view.AtRow() ) + { + // Create new CCseSceduledProgram to be added to array + CCseScheduledProgram* prog = CCseScheduledProgram::NewL(); + CleanupStack::PushL( prog ); + + // Fill created schedule with DB information + view.GetL(); + prog->SetDbIdentifier( view.ColUint32( keyIndex ) ); + prog->SetName( view.ColDes8( nameIndex ) ); + prog->SetStartTime( view.ColTime( startTimeIndex ) ); + prog->SetEndTime( view.ColTime( endTimeIndex ) ); + prog->SetAppUid( view.ColInt32( applicationUidIdIndex ) ); + prog->SetPluginUid( view.ColInt32( plugInUidIndex ) ); + prog->SetScheduleType( view.ColInt32( scheduleTypeIndex ) ); + prog->SetPluginType( view.ColInt32( pluginTypeIndex ) ); + + TInt streamLen( 0 ); + streamLen = view.ColLength( applicationSpecificIndex ); + + HBufC8* appDataBuffer = HBufC8::NewL( streamLen ); + + CleanupStack::PushL( appDataBuffer ); + + TPtr8 buffPtr( appDataBuffer->Des() ); + RDbColReadStream readStream; + readStream.OpenLC( view, applicationSpecificIndex ); + readStream.ReadL( buffPtr, streamLen ); + readStream.Release(); + CleanupStack::PopAndDestroy(); // readStream + + prog->SetApplicationDataL( *appDataBuffer ); + + CleanupStack::PopAndDestroy( appDataBuffer ); + User::LeaveIfError( aArray.Append( prog ) ); + CleanupStack::Pop( prog ); + view.NextL(); + } + + CleanupStack::PopAndDestroy( &view ); // Closes view + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::OpenOrCreateDbL"); + TBuf path; + + // Get path to CSE's private directory + TInt err( iFsSession.PrivatePath( path ) ); + if ( err != KErrNone ) + { + CSELOGSTRING2_HIGH_LEVEL("iFsSession.PrivatePath() failed: %d", err ); + User::Leave( err ); + } + + iDbFile.Zero(); + iDbFile.Append( KCseCDiskPrefix ); + iDbFile.Append( path ); + if ( BaflUtils::CheckFolder( iFsSession, iDbFile ) != KErrNone ) + { + err = iFsSession.CreatePrivatePath( EDriveC ); + if ( err != KErrNone ) + { + CSELOGSTRING2_HIGH_LEVEL( "CreatePrivatePath failed! %d", err ); + User::Leave( err ); + } + } + + iDbFile.Append( KCseScheduleDBName() ); + + // If file doesn't exist create it + if ( !BaflUtils::FileExists( iFsSession, iDbFile ) ) + { + CSELOGSTRING_HIGH_LEVEL("CCseScheduleDB::OpenOrCreateDbL Create New"); + iScheduleDb.Close(); + + if( iScheduleFileStore ) + { + delete iScheduleFileStore; + iScheduleFileStore = NULL; + } + + iScheduleFileStore = CPermanentFileStore::ReplaceL( iFsSession, + iDbFile, + EFileRead|EFileWrite ); + // Set file store type + iScheduleFileStore->SetTypeL( iScheduleFileStore->Layout() ); + // Create stream object + TStreamId id = iScheduleDb.CreateL( iScheduleFileStore ); + // Keep database id as root of store + iScheduleFileStore->SetRootL( id ); + // Complete creation by commiting + iScheduleFileStore->CommitL(); + + CreateDatabaseTableL( iScheduleDb ); + CreateScheduleTableL( iScheduleDb ); + SetDatabaseVersionL( ); + } + // Or if it exists then just open it. + else + { + iScheduleDb.Close(); + delete iScheduleFileStore; + iScheduleFileStore = NULL; + iScheduleFileStore = CPermanentFileStore::OpenL( iFsSession, iDbFile, + EFileRead|EFileWrite ); + iScheduleFileStore->SetTypeL( iScheduleFileStore->Layout() ); + iScheduleDb.OpenL( iScheduleFileStore, iScheduleFileStore->Root() ); + CheckDbVersionL(); + User::LeaveIfError( iScheduleDb.Compact() ); + } + + if ( !iBackupWrapper ) + { + iBackupWrapper = CBaBackupSessionWrapper::NewL(); + } + + iBackupWrapper->RegisterFileL( iDbFile, *this ); + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::CheckDbVersionL"); + + TInt dbVersion( 0 ); + + TRAPD( leave, dbVersion = GetDbVersionL() ); + + if ( dbVersion != KCseDatbaseVersionNumber || leave != KErrNone ) + { + CSELOGSTRING3_HIGH_LEVEL( + "CCseScheduleDB::CheckDbVersionL Not ok, version: %d, error: %d", + dbVersion, leave ); + + // Destroy the old one + iScheduleDb.Close(); + delete iScheduleFileStore; + iScheduleFileStore = NULL; + + // Create new one + iScheduleFileStore = CPermanentFileStore::ReplaceL( iFsSession, + iDbFile, + EFileRead|EFileWrite ); + + // Set file store type + iScheduleFileStore->SetTypeL( iScheduleFileStore->Layout() ); + // Create stream object + TStreamId id = iScheduleDb.CreateL( iScheduleFileStore ); + // Keep database id as root of store + iScheduleFileStore->SetRootL( id ); + // Complete creation by commiting + iScheduleFileStore->CommitL(); + + CreateDatabaseTableL( iScheduleDb ); + CreateScheduleTableL( iScheduleDb ); + SetDatabaseVersionL( ); + } + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::GetDbVersionL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + TInt dbVersion(0); + + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseDatabaseTable ); + + // Order table based on start time + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + // Get the next reminder + view.FirstL(); + + CDbColSet* colSetOrder = view.ColSetL(); + CleanupStack::PushL( colSetOrder ); + + TDbColNo versionIndex = colSetOrder->ColNo( KCseDatabaseVersionCol ); + + CleanupStack::PopAndDestroy( colSetOrder ); + + if ( view.AtRow() ) + { + view.GetL(); + dbVersion = view.ColInt32( versionIndex ); + } + CleanupStack::PopAndDestroy( &view ); // Closes view + + CSELOGSTRING2_HIGH_LEVEL( + "<<>>CCseScheduleDB::CreateScheduleTableL"); + + // Create columns for the database. + TDbCol keyCol( KCseScheduleDbKeyCol, EDbColUint32 ); + keyCol.iAttributes = TDbCol::EAutoIncrement; + + TDbCol nameCol( KCseScheduleNameCol, EDbColText8, KScheduleNameMaxLength ); + TDbCol startTimeCol( KCseScheduleStartTimeCol, EDbColDateTime ); + TDbCol endTimeCol( KCseScheduleEndTimeCol, EDbColDateTime ); + TDbCol applicationUidCol( KCseScheduleApplicationUIDCol, EDbColInt32 ); + TDbCol plugInUidCol( KCseSchedulePlugInUIDCol, EDbColInt32 ); + TDbCol typeCol( KCseScheduleTypeCol, EDbColInt32 ); + TDbCol applicationSpecificCol( KCseScheduleApplicationSpecificCol, EDbColLongBinary ); + TDbCol runCountCol( KCseScheduleRunCountCol, EDbColInt32 ); + TDbCol stateCol( KCseScheduleStateCol, EDbColInt32 ); + TDbCol pluginTypeCol( KCseSchedulePluginTypeCol, EDbColInt32 ); + TDbCol reserved1Col( KCseScheduleReserved1Col, EDbColInt32 ); + TDbCol reserved2Col( KCseScheduleReserved2Col, EDbColInt32 ); + + // Create column set and add defined columns in to the set + CDbColSet* scheduleColSet = CDbColSet::NewLC(); + scheduleColSet->AddL( keyCol ); + scheduleColSet->AddL( nameCol ); + scheduleColSet->AddL( startTimeCol ); + scheduleColSet->AddL( endTimeCol ); + scheduleColSet->AddL( applicationUidCol ); + scheduleColSet->AddL( plugInUidCol ); + scheduleColSet->AddL( typeCol ); + scheduleColSet->AddL( applicationSpecificCol ); + scheduleColSet->AddL( runCountCol ); + scheduleColSet->AddL( stateCol ); + scheduleColSet->AddL( pluginTypeCol ); + scheduleColSet->AddL( reserved1Col ); + scheduleColSet->AddL( reserved2Col ); + + // Create new table to the database with created columnset + User::LeaveIfError( aDatabase.CreateTable( KCseScheduleTable, + *scheduleColSet ) ); + + CleanupStack::PopAndDestroy( scheduleColSet ); + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::CreateDatabaseTableL"); + + // Create columns for the database. + TDbCol versionCol( KCseDatabaseVersionCol, EDbColInt32 ); + TDbCol reserved1Col( KCseDatabaseReserved1Col, EDbColInt32 ); + TDbCol reserved2Col( KCseDatabaseReserved2Col, EDbColInt32 ); + + // Create column set and add defined columns in to the set + CDbColSet* databaseColSet = CDbColSet::NewLC(); + databaseColSet->AddL( versionCol ); + databaseColSet->AddL( reserved1Col ); + databaseColSet->AddL( reserved2Col ); + + // Create new table to the database with created columnset + User::LeaveIfError( aDatabase.CreateTable( KCseDatabaseTable, + *databaseColSet ) ); + + CleanupStack::PopAndDestroy( databaseColSet ); + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::SetDatabaseVersionL"); + + iSqlSchedule.Zero(); + iSqlSchedule.Append( KCseSelectFromDb ); + iSqlSchedule.Append( KCseDatabaseTable ); + + RDbView view; + CleanupClosePushL( view ); + + // Prepare DB for update + User::LeaveIfError(view.Prepare( iScheduleDb, + TDbQuery( iSqlSchedule ), + TDbWindow::EUnlimited, + RDbView::EInsertOnly )); + view.InsertL(); + + // Create colomn set (row) to be added + CDbColSet* databaseColSet = view.ColSetL(); + CleanupStack::PushL( databaseColSet ); + + // Fill row with Schedule information + view.SetColL( databaseColSet->ColNo( KCseDatabaseVersionCol ), + KCseDatbaseVersionNumber ); + CleanupStack::PopAndDestroy( databaseColSet ); + view.PutL(); + CleanupStack::PopAndDestroy( &view ); // closes view + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::AddScheduleL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + iSqlSchedule.Zero(); + iSqlSchedule.Append( KCseSqlGetAll ); + RDbView view; + CleanupClosePushL( view ); + + // Prepare DB for update + User::LeaveIfError(view.Prepare( iScheduleDb, + TDbQuery( iSqlSchedule ), + TDbWindow::EUnlimited, + RDbView::EInsertOnly )); + view.InsertL(); + + // Create colomn set (row) to be added + CDbColSet* scheduleColSet = view.ColSetL(); + CleanupStack::PushL( scheduleColSet ); + + // Fill row with Schedule information + view.SetColL( scheduleColSet->ColNo( KCseScheduleNameCol ), + aData.Name() ); + + view.SetColL( scheduleColSet->ColNo( KCseScheduleStartTimeCol ), + aData.StartTime() ); + + view.SetColL( scheduleColSet->ColNo( KCseScheduleEndTimeCol ), + aData.EndTime() ); + + view.SetColL( scheduleColSet->ColNo( KCseScheduleApplicationUIDCol ), + aData.AppUid() ); + + view.SetColL( scheduleColSet->ColNo( KCseSchedulePlugInUIDCol ), + aData.PluginUid() ); + + view.SetColL( scheduleColSet->ColNo( KCseScheduleTypeCol ), + aData.ScheduleType() ); + + view.SetColL( scheduleColSet->ColNo( KCseScheduleRunCountCol ), + 0 ); + + view.SetColL( scheduleColSet->ColNo( KCseScheduleStateCol ), + ECseWaiting ); + + view.SetColL( scheduleColSet->ColNo( KCseSchedulePluginTypeCol ), + aData.PluginType() ); + + // Description is long one, it needs to be handled by stream + RDbColWriteStream write; + write.OpenLC( view, scheduleColSet->ColNo( KCseScheduleApplicationSpecificCol ) ); + write.WriteL( aData.ApplicationData() ); + write.CommitL(); + CleanupStack::PopAndDestroy(); // write + + TDbColNo keyColumnNo = scheduleColSet->ColNo( KCseScheduleDbKeyCol ); + CleanupStack::PopAndDestroy( scheduleColSet ); + view.PutL(); + + // Get new program key + aData.SetDbIdentifier( view.ColUint32( keyColumnNo ) ); + + CleanupStack::PopAndDestroy( &view ); // closes view + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::RemoveScheduleL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + // Create SQL string to find given schedule from DB + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleDbKeyCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.AppendNum( aDbIdentifier ); + + User::LeaveIfError( iScheduleDb.Begin() ); + + // Prepare DB to update + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + view.FirstL(); + + TInt count( 0 ); + + // If schedule found, remove it. + while ( view.AtRow() ) + { + view.DeleteL(); + count++; + view.NextL(); + } + + CleanupStack::PopAndDestroy( &view ); // closes view + User::LeaveIfError( iScheduleDb.Commit() ); + + CSELOGSTRING3_HIGH_LEVEL("---- %d Items for identifier %d removed from DB", count, aDbIdentifier); + if ( count == 0 ) + { + User::Leave( KErrNotFound ); + } + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::GetNextScheduleTimeL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + // Create SQL satring to get schedule occurence(s) that are + // going to happen next from database. + TTime nextScheduleTime( 0 ); + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleStateCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.AppendNum( ECseWaiting ); + sqlStatement.Append( KCseOrderBy ); + sqlStatement.Append( KCseScheduleStartTimeCol ); + + // Order table based on start time + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + // Get the next schedule + view.FirstL(); + + CDbColSet* colSetOrder = view.ColSetL(); + CleanupStack::PushL( colSetOrder ); + + TDbColNo startTimeIndex = colSetOrder->ColNo( KCseScheduleStartTimeCol ); + + CleanupStack::PopAndDestroy( colSetOrder ); + + // Schedule found get its start time. + if ( view.AtRow() ) + { + view.GetL(); + nextScheduleTime = view.ColTime( startTimeIndex ); + } + + CleanupStack::PopAndDestroy( &view ); // Closes view + + CSELOGSTRING_HIGH_LEVEL("<<& aNextScheduleArray ) + { + CSELOGSTRING_HIGH_LEVEL(">>>CCseScheduleDB::FillScheduleArrayByTimeL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + // Gets program occurence(s) that are going to happen next + // from database + TBuf<100> startTimeBuf; + + _LIT( KDateTimeFormat,"# %1%*D/%2%*M/%3%*Y %H:%T:%S.%C#" ); + + aScheduleTime.FormatL( startTimeBuf, KDateTimeFormat ); + + // Create SQL string to get all schedules to be happen at given time + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleStartTimeCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.Append( startTimeBuf ); + + // Order table based on start time + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + // Get the next reminder + view.FirstL(); + + CDbColSet* colSetOrder = view.ColSetL(); + CleanupStack::PushL( colSetOrder ); + + // Get column indexes + TDbColNo keyIndex = colSetOrder->ColNo( KCseScheduleDbKeyCol ); + TDbColNo nameIndex = colSetOrder->ColNo( KCseScheduleNameCol ); + TDbColNo startTimeIndex = colSetOrder->ColNo( KCseScheduleStartTimeCol ); + TDbColNo endTimeIndex = colSetOrder->ColNo( KCseScheduleEndTimeCol ); + TDbColNo applicationUidIdIndex = colSetOrder->ColNo( KCseScheduleApplicationUIDCol ); + TDbColNo plugInUidIndex = colSetOrder->ColNo( KCseSchedulePlugInUIDCol ); + TDbColNo typeIndex = colSetOrder->ColNo( KCseScheduleTypeCol ); + TDbColNo applicationSpecificIndex = colSetOrder->ColNo( KCseScheduleApplicationSpecificCol ); + TDbColNo pluginTypeIndex = colSetOrder->ColNo( KCseSchedulePluginTypeCol ); + + CleanupStack::PopAndDestroy( colSetOrder ); + + // Loop through all found schedules. + while ( view.AtRow() ) + { + // Create new schedule to be added to array + CCseScheduledProgram* prog = CCseScheduledProgram::NewL(); + CleanupStack::PushL( prog ); + view.GetL(); + + // Copy information from DB to schedule. + prog->SetDbIdentifier( view.ColUint32( keyIndex ) ); + prog->SetName( view.ColDes8( nameIndex ) ); + prog->SetStartTime( view.ColTime( startTimeIndex ) ); + prog->SetEndTime( view.ColTime( endTimeIndex ) ); + prog->SetAppUid( view.ColInt32( applicationUidIdIndex ) ); + prog->SetPluginUid( view.ColInt32( plugInUidIndex ) ); + prog->SetScheduleType( CCseScheduledProgram::TCseScheduleType( + view.ColInt32( typeIndex ) ) ); + prog->SetPluginType( CCseScheduledProgram::TCsePluginType( + view.ColInt32( pluginTypeIndex ) ) ); + TInt streamLen( view.ColLength( applicationSpecificIndex ) ); + + HBufC8* appDataBuffer = HBufC8::NewL( streamLen ); + CleanupStack::PushL( appDataBuffer ); + + TPtr8 buffPtr( appDataBuffer->Des() ); + RDbColReadStream readStream; + readStream.OpenLC( view, applicationSpecificIndex ); + readStream.ReadL( buffPtr, streamLen ); + readStream.Release(); + CleanupStack::PopAndDestroy(); // readStream; + + prog->SetApplicationDataL( *appDataBuffer ); + + CleanupStack::PopAndDestroy( appDataBuffer ); + User::LeaveIfError( aNextScheduleArray.Append( prog ) ); + CleanupStack::Pop( prog ); + + // And next schedule... + view.NextL(); + } + + CleanupStack::PopAndDestroy( &view ); // Closes view + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::GetScheduleByDbIdentifierL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + if ( !aSchedule ) + { + return; + } + + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleDbKeyCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.AppendNum( aDbIdentifier ); + + // Order table based on start time + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + // Get the next reminder + view.FirstL(); + + CDbColSet* colSetOrder = view.ColSetL(); + CleanupStack::PushL( colSetOrder ); + + TDbColNo keyIndex = colSetOrder->ColNo( KCseScheduleDbKeyCol ); + TDbColNo nameIndex = colSetOrder->ColNo( KCseScheduleNameCol ); + TDbColNo startTimeIndex = colSetOrder->ColNo( KCseScheduleStartTimeCol ); + TDbColNo endTimeIndex = colSetOrder->ColNo( KCseScheduleEndTimeCol ); + TDbColNo applicationUidIdIndex = colSetOrder->ColNo( KCseScheduleApplicationUIDCol ); + TDbColNo plugInUidIndex = colSetOrder->ColNo( KCseSchedulePlugInUIDCol ); + TDbColNo typeIndex = colSetOrder->ColNo( KCseScheduleTypeCol ); + TDbColNo applicationSpecificIndex = colSetOrder->ColNo( KCseScheduleApplicationSpecificCol ); + TDbColNo pluginTypeIndex = colSetOrder->ColNo( KCseSchedulePluginTypeCol ); + + CleanupStack::PopAndDestroy( colSetOrder ); + + while ( view.AtRow() ) + { + view.GetL(); + aSchedule->SetDbIdentifier( view.ColUint32( keyIndex ) ); + aSchedule->SetName( view.ColDes8( nameIndex ) ); + aSchedule->SetStartTime( view.ColTime( startTimeIndex ) ); + aSchedule->SetEndTime( view.ColTime( endTimeIndex ) ); + aSchedule->SetAppUid( view.ColInt32( applicationUidIdIndex ) ); + aSchedule->SetPluginUid( view.ColInt32( plugInUidIndex ) ); + + aSchedule->SetScheduleType( CCseScheduledProgram::TCseScheduleType( + view.ColInt32( typeIndex ) ) ); + aSchedule->SetPluginType( CCseScheduledProgram::TCsePluginType( + view.ColInt32( pluginTypeIndex ) ) ); + + TInt streamLen( 0 ); + streamLen = view.ColLength( applicationSpecificIndex ); + + HBufC8* appDataBuffer = HBufC8::NewL( streamLen ); + CleanupStack::PushL( appDataBuffer ); + + TPtr8 buffPtr( appDataBuffer->Des() ); + RDbColReadStream readStream; + readStream.OpenLC( view, applicationSpecificIndex ); // |->1 + readStream.ReadL(buffPtr, streamLen); + readStream.Release(); + CleanupStack::PopAndDestroy( ); // 1<-| Popping pointer to Col that we dont have here + TPtrC8 ptr8( appDataBuffer->Des() ); + aSchedule->SetApplicationDataL( *appDataBuffer ); + CleanupStack::PopAndDestroy( appDataBuffer ); + view.NextL(); + } + + CleanupStack::PopAndDestroy( &view ); // Closes view + + CSELOGSTRING_HIGH_LEVEL("<<& aResultArray + ) + { + CSELOGSTRING_HIGH_LEVEL(">>>CCseScheduleDB::GetOverlappingSchedulesL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + TBuf<100> startTimeBuf; + _LIT( KDateTimeFormat,"# %1%*D/%2%*M/%3%*Y %H:%T:%S#" ); + aStartTime.FormatL( startTimeBuf, KDateTimeFormat ); + TBuf<100> endTimeBuf; + aEndTime.FormatL( endTimeBuf, KDateTimeFormat ); + + // Create SQL string to find all overlapping schedules from database between given + // timeframe. + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleTypeCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.AppendNum( aType ); + sqlStatement.Append( KCseAnd ); + sqlStatement.Append( KCseScheduleStartTimeCol ); + sqlStatement.Append( KCseLess ); + sqlStatement.Append( endTimeBuf ); + sqlStatement.Append( KCseAnd ); + sqlStatement.Append( KCseScheduleEndTimeCol ); + sqlStatement.Append( KCseMore ); + sqlStatement.Append( startTimeBuf ); + sqlStatement.Append( KCseOrderBy ); + sqlStatement.Append( KCseScheduleStartTimeCol ); + + // Order table + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + // Move to the first row + view.FirstL(); + + CDbColSet* colSetOrder = view.ColSetL(); + CleanupStack::PushL( colSetOrder ); + + // Get colon indexes. + TDbColNo keyIndex = colSetOrder->ColNo( KCseScheduleDbKeyCol ); + TDbColNo nameIndex = colSetOrder->ColNo( KCseScheduleNameCol ); + TDbColNo startTimeIndex = colSetOrder->ColNo( KCseScheduleStartTimeCol ); + TDbColNo endTimeIndex = colSetOrder->ColNo( KCseScheduleEndTimeCol ); + TDbColNo applicationUidIdIndex = colSetOrder->ColNo( KCseScheduleApplicationUIDCol ); + TDbColNo plugInUidIndex = colSetOrder->ColNo( KCseSchedulePlugInUIDCol ); + TDbColNo typeIndex = colSetOrder->ColNo( KCseScheduleTypeCol ); + TDbColNo applicationSpecificIndex = colSetOrder->ColNo( KCseScheduleApplicationSpecificCol ); + TDbColNo pluginTypeIndex = colSetOrder->ColNo( KCseSchedulePluginTypeCol ); + + CleanupStack::PopAndDestroy( colSetOrder ); + + // Loop through all found schedules. + while ( view.AtRow() ) + { + // Create new schedule to be added to array. + CCseScheduledProgram* schedule = CCseScheduledProgram::NewL(); + CleanupStack::PushL( schedule ); + view.GetL(); + + // Set schedule information. + schedule->SetDbIdentifier( view.ColUint32( keyIndex ) ); + schedule->SetName( view.ColDes8( nameIndex ) ); + schedule->SetStartTime( view.ColTime( startTimeIndex ) ); + schedule->SetEndTime( view.ColTime( endTimeIndex ) ); + schedule->SetAppUid( view.ColInt32( applicationUidIdIndex ) ); + schedule->SetPluginUid( view.ColInt32( plugInUidIndex ) ); + + schedule->SetScheduleType( CCseScheduledProgram::TCseScheduleType( + view.ColInt32( typeIndex ) ) ); + schedule->SetPluginType( CCseScheduledProgram::TCsePluginType( + view.ColInt32( pluginTypeIndex ) ) ); + + TInt streamLen( 0 ); + streamLen = view.ColLength( applicationSpecificIndex ); + + HBufC8* appDataBuffer = HBufC8::NewL( streamLen ); + CleanupStack::PushL( appDataBuffer ); + + TPtr8 buffPtr( appDataBuffer->Des() ); + RDbColReadStream readStream; // |->1 + readStream.OpenLC( view, applicationSpecificIndex ); + readStream.ReadL(buffPtr, streamLen); + readStream.Release(); + CleanupStack::PopAndDestroy( ); // 1<-| Popping pointer to Col that we dont have here + TPtrC8 ptr8( appDataBuffer->Des() ); + schedule->SetApplicationDataL( *appDataBuffer ); + CleanupStack::PopAndDestroy( appDataBuffer ); + if ( schedule->StartTime() < aEndTime && schedule->EndTime() > aStartTime ) + { + aResultArray.AppendL( schedule ); + CleanupStack::Pop( schedule ); + } + else + { + CleanupStack::PopAndDestroy( schedule ); + schedule = NULL; + } + + // Next shcedule... + view.NextL(); + } + CleanupStack::PopAndDestroy( &view ); // Closes view + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::IncreaseRunCountL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + // Create SQL string to find given schedule + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleDbKeyCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.AppendNum( aDbIdentifier ); + + // Order table based on DB identifier + RDbView readView; + CleanupClosePushL( readView ); + + User::LeaveIfError( readView.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( readView.EvaluateAll() ); + + // Get the next reminder + readView.FirstL(); + + // First we read existint run count + CDbColSet* readColSet = readView.ColSetL(); + CleanupStack::PushL( readColSet ); + TDbColNo runCountCol = readColSet->ColNo( KCseScheduleRunCountCol ); + CleanupStack::PopAndDestroy( readColSet ); + TInt32 runCount( 0 ); + if ( readView.AtRow() ) + { + readView.GetL(); + runCount = readView.ColInt32( runCountCol ); + runCount++; + } + // Close read view + CleanupStack::PopAndDestroy( &readView ); + + // Update run count + if ( runCount > 0 ) + { + // Open write view + RDbView writeView; + CleanupClosePushL( writeView ); + User::LeaveIfError( writeView.Prepare( iScheduleDb, + TDbQuery( sqlStatement ), + TDbWindow::EUnlimited, + RDbView::EUpdatable )); + User::LeaveIfError( writeView.EvaluateAll() ); + + writeView.FirstL(); + CDbColSet* writeColSet = writeView.ColSetL(); + CleanupStack::PushL( writeColSet ); + TDbColNo runCountColNo = writeColSet->ColNo( KCseScheduleRunCountCol ); + CleanupStack::PopAndDestroy( writeColSet ); + + writeView.UpdateL(); + + // If we found (as we should) schedule again we update its value. + if ( writeView.AtRow() ) + { + writeView.SetColL( runCountColNo, runCount ); + } + + writeView.PutL(); + + CleanupStack::PopAndDestroy( &writeView ); + } + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::GetRunCountL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + TInt32 runCount( 0 ); + + // Create SQL string to find given schedule + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleDbKeyCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.AppendNum( aDbIdentifier ); + + // Order table based on start time + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + // Get the next reminder + view.FirstL(); + + CDbColSet* colSetOrder = view.ColSetL(); + CleanupStack::PushL( colSetOrder ); + + TDbColNo runCountCol = colSetOrder->ColNo( KCseScheduleRunCountCol ); + + CleanupStack::PopAndDestroy( colSetOrder ); + + // If we found schedule get its run count. + if ( view.AtRow() ) + { + view.GetL(); + + runCount = view.ColInt32( runCountCol ); + } + + CleanupStack::PopAndDestroy( &view ); // Closes view + + CSELOGSTRING2_HIGH_LEVEL("<<>>CCseScheduleDB::SetScheduleStateL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + // Create SQL string to find given schedule + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleDbKeyCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.AppendNum( aDbIdentifier ); + + // Open write view + RDbView writeView; + CleanupClosePushL( writeView ); + User::LeaveIfError( writeView.Prepare( iScheduleDb, + TDbQuery( sqlStatement ), + TDbWindow::EUnlimited, + RDbView::EUpdatable )); + User::LeaveIfError( writeView.EvaluateAll() ); + + writeView.FirstL(); + CDbColSet* writeColSet = writeView.ColSetL(); + CleanupStack::PushL( writeColSet ); + TDbColNo stateColNo = writeColSet->ColNo( KCseScheduleStateCol ); + CleanupStack::PopAndDestroy( writeColSet ); + + writeView.UpdateL(); + + // If we found schedule, we change the column value. + if ( writeView.AtRow() ) + { + writeView.SetColL( stateColNo, aState ); + } + + writeView.PutL(); + CleanupStack::PopAndDestroy( &writeView ); + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::GetScheduleStateL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + // Create SQL string to find given schedule + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleDbKeyCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.AppendNum( aDbIdentifier ); + + // Order table based on DB identifier + RDbView readView; + CleanupClosePushL( readView ); + User::LeaveIfError( readView.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( readView.EvaluateAll() ); + + // Get the reminder + readView.FirstL(); + + CDbColSet* readColSet = readView.ColSetL(); + CleanupStack::PushL( readColSet ); + TDbColNo stateCol = readColSet->ColNo( KCseScheduleStateCol ); + CleanupStack::PopAndDestroy( readColSet ); + TInt32 state( KErrNotFound ); + + // If we found schedule, get the schedule state. + if ( readView.AtRow() ) + { + readView.GetL(); + state = readView.ColInt32( stateCol ); + } + // Close read view + CleanupStack::PopAndDestroy( &readView ); + + CSELOGSTRING_HIGH_LEVEL("<<& aScheduleArray ) + { + CSELOGSTRING_HIGH_LEVEL(">>>CCseScheduleDB::StartupSchedulesL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + // Create SQL string to find wanted schedules. + // At startup phase we are first interested for + // those schedules that were on run when phone was + // shutdown (eg runcount is bigger than 0). + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleRunCountCol ); + sqlStatement.Append( KCseMore ); + sqlStatement.AppendNum( 0 ); + + // Order table + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + // Get the first reminder + view.FirstL(); + + CDbColSet* colSetOrder = view.ColSetL(); + CleanupStack::PushL( colSetOrder ); + + // Column indexes + TDbColNo keyIndex = colSetOrder->ColNo( KCseScheduleDbKeyCol ); + TDbColNo nameIndex = colSetOrder->ColNo( KCseScheduleNameCol ); + TDbColNo startTimeIndex = colSetOrder->ColNo( KCseScheduleStartTimeCol ); + TDbColNo endTimeIndex = colSetOrder->ColNo( KCseScheduleEndTimeCol ); + TDbColNo applicationUidIdIndex = colSetOrder->ColNo( KCseScheduleApplicationUIDCol ); + TDbColNo plugInUidIndex = colSetOrder->ColNo( KCseSchedulePlugInUIDCol ); + TDbColNo typeIndex = colSetOrder->ColNo( KCseScheduleTypeCol ); + TDbColNo applicationSpecificIndex = colSetOrder->ColNo( KCseScheduleApplicationSpecificCol ); + TDbColNo pluginTypeIndex = colSetOrder->ColNo( KCseSchedulePluginTypeCol ); + + CleanupStack::PopAndDestroy( colSetOrder ); + + // Loop through the found schedules. + while ( view.AtRow() ) + { + // Create CseScheduledProgram to be added to string. + CCseScheduledProgram* prog = CCseScheduledProgram::NewL(); + CleanupStack::PushL( prog ); + view.GetL(); + + // Set schedule information. + prog->SetDbIdentifier( view.ColUint32( keyIndex ) ); + prog->SetName( view.ColDes8( nameIndex ) ); + prog->SetStartTime( view.ColTime( startTimeIndex ) ); + prog->SetEndTime( view.ColTime( endTimeIndex ) ); + prog->SetAppUid( view.ColInt32( applicationUidIdIndex ) ); + prog->SetPluginUid( view.ColInt32( plugInUidIndex ) ); + + prog->SetScheduleType( CCseScheduledProgram::TCseScheduleType( + view.ColInt32( typeIndex ) ) ); + prog->SetPluginType( CCseScheduledProgram::TCsePluginType( + view.ColInt32( pluginTypeIndex ) ) ); + + TInt streamLen( view.ColLength( applicationSpecificIndex ) ); + + HBufC8* appDataBuffer = HBufC8::NewL( streamLen ); + CleanupStack::PushL( appDataBuffer ); + + TPtr8 buffPtr( appDataBuffer->Des() ); + RDbColReadStream readStream; + readStream.OpenLC( view, applicationSpecificIndex ); // |->1 + readStream.ReadL( buffPtr, streamLen ); + readStream.Release(); + CleanupStack::PopAndDestroy( ); // 1<-| Popping pointer to Col that we dont have here + + prog->SetApplicationDataL( *appDataBuffer ); + + CleanupStack::PopAndDestroy( appDataBuffer ); + User::LeaveIfError( aScheduleArray.Append( prog ) ); + CleanupStack::Pop( prog ); + + // Next shcedule + view.NextL(); + } + + CleanupStack::PopAndDestroy( &view ); // Closes view + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::ResetCompactTimer"); + + // If iCompatTimer is not running start it. + if( !iCompactTimer ) + { + TRAPD(err, iCompactTimer = CPeriodic::NewL( CActive::EPriorityStandard )); + + if(err != KErrNone ) + { + CSELOGSTRING2_HIGH_LEVEL("CCseScheduleDB::ResetCompactTimer - Can't create iCompactTimer: %d", err); + } + } + + // If iCompactTimer is running cancel it and start over again. + if( iCompactTimer ) + { + iCompactTimer->Cancel(); + + iCompactTimer->Start( KCseDbCompactTimeout, + KCseDbCompactTimeout, + TCallBack( CompactCallback, this ) ); + } + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::CompactCallback"); + + // Direct call to class method. + static_cast( aThis )->CompactDb(); + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::CompactDb"); + // Compact database + + if( iDbAccess != ECseDbLocked ) + { + TInt err( iScheduleDb.Compact() ); + if ( err != KErrNone ) + { + CSELOGSTRING2_HIGH_LEVEL("iScheduleDb.Compact() failed: %d", err); + } + } + + // Cancel timer if it is running + if ( iCompactTimer ) + { + iCompactTimer->Cancel(); + delete iCompactTimer; + iCompactTimer = NULL; + } + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::ChangeFileLockL" ); + + switch ( aFlags ) + { + case MBackupObserver::EReleaseLockReadOnly: + case MBackupObserver::EReleaseLockNoAccess: + { + // Backup and restore starting, close the db + CloseDbFile(); + + // Cancel timer if it is running + if ( iCompactTimer ) + { + iCompactTimer->Cancel(); + delete iCompactTimer; + iCompactTimer = NULL; + } + } + break; + + default: + { + OpenDbFileL(); + } + break; + } + + CSELOGSTRING_HIGH_LEVEL( "<<>>CCseScheduleDB::CloseDbFile"); + + iDbAccess = ECseDbLocked; + iScheduleDb.Close(); + delete iScheduleFileStore; + iScheduleFileStore = NULL; + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::OpenDbFileL"); + + iScheduleDb.Close(); + if( iScheduleFileStore ) + { + delete iScheduleFileStore; + iScheduleFileStore = NULL; + } + iScheduleFileStore = CPermanentFileStore::OpenL( iFsSession, iDbFile, + EFileRead|EFileWrite ); + iScheduleFileStore->SetTypeL( iScheduleFileStore->Layout() ); + iScheduleDb.OpenL( iScheduleFileStore, iScheduleFileStore->Root() ); + User::LeaveIfError( iScheduleDb.Compact() ); + + iDbAccess = ECseDbOpen; + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::LeaveIfDbLocked"); + + if(iDbAccess == ECseDbLocked) + { + CSELOGSTRING_HIGH_LEVEL("<<& aArray ) + { + + CSELOGSTRING_HIGH_LEVEL(">>>CCseScheduleDB::GetSchedulesByPluginL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + // Gets program occurence(s) that are going to happen next + // from database + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseSchedulePlugInUIDCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.AppendNum( aPluginUid ); + sqlStatement.Append( KCseOrderBy ); + sqlStatement.Append( KCseScheduleStartTimeCol ); + + // Order table based on start time + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + view.FirstL(); + + CDbColSet* colSetOrder = view.ColSetL(); + CleanupStack::PushL( colSetOrder ); + + // Get the SQL table indexes. + TDbColNo keyIndex = colSetOrder->ColNo( KCseScheduleDbKeyCol ); + TDbColNo nameIndex = colSetOrder->ColNo( KCseScheduleNameCol ); + TDbColNo startTimeIndex = colSetOrder->ColNo( KCseScheduleStartTimeCol ); + TDbColNo endTimeIndex = colSetOrder->ColNo( KCseScheduleEndTimeCol ); + TDbColNo applicationUidIdIndex = colSetOrder->ColNo( KCseScheduleApplicationUIDCol ); + TDbColNo plugInUidIndex = colSetOrder->ColNo( KCseSchedulePlugInUIDCol ); + TDbColNo applicationSpecificIndex = colSetOrder->ColNo( KCseScheduleApplicationSpecificCol ); + TDbColNo scheduleTypeIndex = colSetOrder->ColNo( KCseScheduleTypeCol ); + TDbColNo pluginTypeIndex = colSetOrder->ColNo( KCseSchedulePluginTypeCol ); + + CleanupStack::PopAndDestroy( colSetOrder ); + + // Loop through the tables + while ( view.AtRow() ) + { + // Create new CCseSceduledProgram to be added to array + CCseScheduledProgram* prog = CCseScheduledProgram::NewL(); + CleanupStack::PushL( prog ); + + // Fill created schedule with DB information + view.GetL(); + prog->SetDbIdentifier( view.ColUint32( keyIndex ) ); + prog->SetName( view.ColDes8( nameIndex ) ); + prog->SetStartTime( view.ColTime( startTimeIndex ) ); + prog->SetEndTime( view.ColTime( endTimeIndex ) ); + prog->SetAppUid( view.ColInt32( applicationUidIdIndex ) ); + prog->SetPluginUid( view.ColInt32( plugInUidIndex ) ); + prog->SetScheduleType( view.ColInt32( scheduleTypeIndex ) ); + prog->SetPluginType( view.ColInt32( pluginTypeIndex ) ); + + TInt streamLen( 0 ); + streamLen = view.ColLength( applicationSpecificIndex ); + + HBufC8* appDataBuffer = HBufC8::NewL( streamLen ); + + CleanupStack::PushL( appDataBuffer ); + + TPtr8 buffPtr( appDataBuffer->Des() ); + RDbColReadStream readStream; + readStream.OpenLC( view, applicationSpecificIndex ); // |->1 + readStream.ReadL( buffPtr, streamLen ); + readStream.Release(); + CleanupStack::PopAndDestroy( ); // 1<-| Popping pointer to Col that we dont have here + + prog->SetApplicationDataL( *appDataBuffer ); + + CleanupStack::PopAndDestroy( appDataBuffer ); + User::LeaveIfError( aArray.Append( prog ) ); + CleanupStack::Pop( prog ); + view.NextL(); + } + + CleanupStack::PopAndDestroy( &view ); // Closes view + + CSELOGSTRING_HIGH_LEVEL("<<& aArray ) + { + CSELOGSTRING_HIGH_LEVEL(">>>CCseScheduleDB::GetSchedulesByPluginL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + // Gets program occurence(s) that are going to happen next + // from database + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleTypeCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.AppendNum( aType ); + sqlStatement.Append( KCseOrderBy ); + sqlStatement.Append( KCseScheduleStartTimeCol ); + + // Order table based on start time + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + view.FirstL(); + + CDbColSet* colSetOrder = view.ColSetL(); + CleanupStack::PushL( colSetOrder ); + + // Get the SQL table indexes. + TDbColNo keyIndex = colSetOrder->ColNo( KCseScheduleDbKeyCol ); + TDbColNo nameIndex = colSetOrder->ColNo( KCseScheduleNameCol ); + TDbColNo startTimeIndex = colSetOrder->ColNo( KCseScheduleStartTimeCol ); + TDbColNo endTimeIndex = colSetOrder->ColNo( KCseScheduleEndTimeCol ); + TDbColNo applicationUidIdIndex = colSetOrder->ColNo( KCseScheduleApplicationUIDCol ); + TDbColNo plugInUidIndex = colSetOrder->ColNo( KCseSchedulePlugInUIDCol ); + TDbColNo applicationSpecificIndex = colSetOrder->ColNo( KCseScheduleApplicationSpecificCol ); + TDbColNo scheduleTypeIndex = colSetOrder->ColNo( KCseScheduleTypeCol ); + TDbColNo pluginTypeIndex = colSetOrder->ColNo( KCseSchedulePluginTypeCol ); + + CleanupStack::PopAndDestroy( colSetOrder ); + + // Loop through the tables + while ( view.AtRow() ) + { + // Create new CCseSceduledProgram to be added to array + CCseScheduledProgram* prog = CCseScheduledProgram::NewL(); + CleanupStack::PushL( prog ); + + // Fill created schedule with DB information + view.GetL(); + prog->SetDbIdentifier( view.ColUint32( keyIndex ) ); + prog->SetName( view.ColDes8( nameIndex ) ); + prog->SetStartTime( view.ColTime( startTimeIndex ) ); + prog->SetEndTime( view.ColTime( endTimeIndex ) ); + prog->SetAppUid( view.ColInt32( applicationUidIdIndex ) ); + prog->SetPluginUid( view.ColInt32( plugInUidIndex ) ); + prog->SetScheduleType( view.ColInt32( scheduleTypeIndex ) ); + prog->SetPluginType( view.ColInt32( pluginTypeIndex ) ); + + TInt streamLen( 0 ); + streamLen = view.ColLength( applicationSpecificIndex ); + + HBufC8* appDataBuffer = HBufC8::NewL( streamLen ); + + CleanupStack::PushL( appDataBuffer ); + + TPtr8 buffPtr( appDataBuffer->Des() ); + RDbColReadStream readStream; + readStream.OpenLC( view, applicationSpecificIndex ); // |-> 1 + readStream.ReadL( buffPtr, streamLen ); + readStream.Release(); + CleanupStack::PopAndDestroy( ); // 1 <-| Popping pointer to Col that we dont have here + + prog->SetApplicationDataL( *appDataBuffer ); + + CleanupStack::PopAndDestroy( appDataBuffer ); + User::LeaveIfError( aArray.Append( prog ) ); + CleanupStack::Pop( prog ); + view.NextL(); + } + + CleanupStack::PopAndDestroy( &view ); // Closes view + + CSELOGSTRING_HIGH_LEVEL("<<& aResultArray + ) + { + CSELOGSTRING_HIGH_LEVEL(">>>CCseScheduleDB::GetSchedulesByTimeframeL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + TBuf<100> startTimeBuf; + _LIT( KDateTimeFormat,"# %1%*D/%2%*M/%3%*Y %H:%T:%S#" ); + aBeginning.FormatL( startTimeBuf, KDateTimeFormat ); + TBuf<100> endTimeBuf; + aEnd.FormatL( endTimeBuf, KDateTimeFormat ); + + // Create SQL string to find all overlapping schedules from database between given + // timeframe. + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleStartTimeCol ); + sqlStatement.Append( KCseLess ); + sqlStatement.Append( endTimeBuf ); + sqlStatement.Append( KCseAnd ); + sqlStatement.Append( KCseScheduleEndTimeCol ); + sqlStatement.Append( KCseMore ); + sqlStatement.Append( startTimeBuf ); + sqlStatement.Append( KCseOrderBy ); + sqlStatement.Append( KCseScheduleStartTimeCol ); + + // Order table + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + // Move to the first row + view.FirstL(); + + CDbColSet* colSetOrder = view.ColSetL(); + CleanupStack::PushL( colSetOrder ); + + // Get colon indexes. + TDbColNo keyIndex = colSetOrder->ColNo( KCseScheduleDbKeyCol ); + TDbColNo nameIndex = colSetOrder->ColNo( KCseScheduleNameCol ); + TDbColNo startTimeIndex = colSetOrder->ColNo( KCseScheduleStartTimeCol ); + TDbColNo endTimeIndex = colSetOrder->ColNo( KCseScheduleEndTimeCol ); + TDbColNo applicationUidIdIndex = colSetOrder->ColNo( KCseScheduleApplicationUIDCol ); + TDbColNo plugInUidIndex = colSetOrder->ColNo( KCseSchedulePlugInUIDCol ); + TDbColNo typeIndex = colSetOrder->ColNo( KCseScheduleTypeCol ); + TDbColNo applicationSpecificIndex = colSetOrder->ColNo( KCseScheduleApplicationSpecificCol ); + TDbColNo pluginTypeIndex = colSetOrder->ColNo( KCseSchedulePluginTypeCol ); + + CleanupStack::PopAndDestroy( colSetOrder ); + + // Loop through all found schedules. + while ( view.AtRow() ) + { + // Create new schedule to be added to array. + CCseScheduledProgram* schedule = CCseScheduledProgram::NewL(); + CleanupStack::PushL( schedule ); + view.GetL(); + + // Set schedule information. + schedule->SetDbIdentifier( view.ColUint32( keyIndex ) ); + schedule->SetName( view.ColDes8( nameIndex ) ); + schedule->SetStartTime( view.ColTime( startTimeIndex ) ); + schedule->SetEndTime( view.ColTime( endTimeIndex ) ); + schedule->SetAppUid( view.ColInt32( applicationUidIdIndex ) ); + schedule->SetPluginUid( view.ColInt32( plugInUidIndex ) ); + + schedule->SetScheduleType( CCseScheduledProgram::TCseScheduleType( + view.ColInt32( typeIndex ) ) ); + schedule->SetPluginType( CCseScheduledProgram::TCseScheduleType( + view.ColInt32( pluginTypeIndex ) ) ); + + TInt streamLen( 0 ); + streamLen = view.ColLength( applicationSpecificIndex ); + + HBufC8* appDataBuffer = HBufC8::NewL( streamLen ); + CleanupStack::PushL( appDataBuffer ); + + TPtr8 buffPtr( appDataBuffer->Des() ); + RDbColReadStream readStream; + readStream.OpenLC( view, applicationSpecificIndex ); // |-> 1 + readStream.ReadL(buffPtr, streamLen); + readStream.Release(); + CleanupStack::PopAndDestroy( ); // 1 <-| Popping pointer to Col that we dont have here + TPtrC8 ptr8( appDataBuffer->Des() ); + schedule->SetApplicationDataL( *appDataBuffer ); + CleanupStack::PopAndDestroy( appDataBuffer ); + + aResultArray.AppendL( schedule ); + CleanupStack::Pop( schedule ); + + // Next shcedule... + view.NextL(); + } + CleanupStack::PopAndDestroy( &view ); // Closes view + CSELOGSTRING_HIGH_LEVEL("<<& aPlugins ) + { + CSELOGSTRING_HIGH_LEVEL(">>>CCseScheduleDB::GetPluginsL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + // Gets program occurence(s) that are going to happen next + // from database + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseOrderBy ); + sqlStatement.Append( KCseSchedulePlugInUIDCol ); + + // Order table based on start time + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + view.FirstL(); + + CDbColSet* colSetOrder = view.ColSetL(); + CleanupStack::PushL( colSetOrder ); + + // Get the SQL table indexes. + TDbColNo pluginUidIndex = colSetOrder->ColNo( KCseSchedulePlugInUIDCol ); + + CleanupStack::PopAndDestroy( colSetOrder ); + + TInt32 currentPluginUid( 0 ); + TInt32 newPluginUid( 0 ); + + // Loop through the tables + while ( view.AtRow() ) + { + view.GetL(); + + // Get plugin Uid from row + newPluginUid = view.ColInt32( pluginUidIndex ); + + // If it is different that the current plugin uid add it to + // array and set new "current" uid. + if( newPluginUid != currentPluginUid ) + { + // Query results are sorted by plugin uid + // so if uid changes we can add it to array + // without fearing that we will have + // duplicates. + aPlugins.Append( newPluginUid ); + currentPluginUid = newPluginUid; + } + + view.NextL(); + } + + view.Close(); + CleanupStack::PopAndDestroy( &view ); // Closes view + + CSELOGSTRING_HIGH_LEVEL("<<>>CCseScheduleDB::GetNextScheduleTimeByPluginL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + // Create SQL satring to get schedule occurence(s) that are + // going to happen next from database. + TTime nextScheduleTime( 0 ); + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleStateCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.AppendNum( ECseWaiting ); + sqlStatement.Append( KCseAnd ); + sqlStatement.Append( KCseSchedulePlugInUIDCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.AppendNum( aPluginUid ); + sqlStatement.Append( KCseOrderBy ); + sqlStatement.Append( KCseScheduleStartTimeCol ); + + // Order table based on start time + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + // Get the next schedule + view.FirstL(); + + CDbColSet* colSetOrder = view.ColSetL(); + CleanupStack::PushL( colSetOrder ); + + TDbColNo startTimeIndex = colSetOrder->ColNo( KCseScheduleStartTimeCol ); + + CleanupStack::PopAndDestroy( colSetOrder ); + + // Schedule found get its start time. + if ( view.AtRow() ) + { + view.GetL(); + nextScheduleTime = view.ColTime( startTimeIndex ); + } + + CleanupStack::PopAndDestroy( &view ); // Closes view + + CSELOGSTRING_HIGH_LEVEL("<<& aNextScheduleArray ) + { + CSELOGSTRING_HIGH_LEVEL(">>>CCseScheduleDB::GetSchedulesByTimeAndPluginL"); + LeaveIfDbLockedL(); + ResetCompactTimer(); + + // Gets program occurence(s) that are going to happen next + // from database + TBuf<100> startTimeBuf; + + _LIT( KDateTimeFormat,"# %1%*D/%2%*M/%3%*Y %H:%T:%S.%C#" ); + + aScheduleTime.FormatL( startTimeBuf, KDateTimeFormat ); + + // Create SQL string to get all schedules to be happen at given time + TBuf sqlStatement; + sqlStatement.Append( KCseSelectFromDb ); + sqlStatement.Append( KCseScheduleTable ); + sqlStatement.Append( KCseWhere ); + sqlStatement.Append( KCseScheduleStartTimeCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.Append( startTimeBuf ); + sqlStatement.Append( KCseAnd ); + sqlStatement.Append( KCseSchedulePlugInUIDCol ); + sqlStatement.Append( KCseEqual ); + sqlStatement.AppendNum( aPluginUid ); + + // Order table based on start time + RDbView view; + CleanupClosePushL( view ); + User::LeaveIfError( view.Prepare( iScheduleDb, + TDbQuery( sqlStatement ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + + // Get the next reminder + view.FirstL(); + + CDbColSet* colSetOrder = view.ColSetL(); + CleanupStack::PushL( colSetOrder ); + + // Get column indexes + TDbColNo keyIndex = colSetOrder->ColNo( KCseScheduleDbKeyCol ); + TDbColNo nameIndex = colSetOrder->ColNo( KCseScheduleNameCol ); + TDbColNo startTimeIndex = colSetOrder->ColNo( KCseScheduleStartTimeCol ); + TDbColNo endTimeIndex = colSetOrder->ColNo( KCseScheduleEndTimeCol ); + TDbColNo applicationUidIdIndex = colSetOrder->ColNo( KCseScheduleApplicationUIDCol ); + TDbColNo plugInUidIndex = colSetOrder->ColNo( KCseSchedulePlugInUIDCol ); + TDbColNo typeIndex = colSetOrder->ColNo( KCseScheduleTypeCol ); + TDbColNo applicationSpecificIndex = colSetOrder->ColNo( KCseScheduleApplicationSpecificCol ); + TDbColNo pluginTypeIndex = colSetOrder->ColNo( KCseSchedulePluginTypeCol ); + + CleanupStack::PopAndDestroy( colSetOrder ); + + // Loop through all found schedules. + while ( view.AtRow() ) + { + // Create new schedule to be added to array + CCseScheduledProgram* prog = CCseScheduledProgram::NewL(); + CleanupStack::PushL( prog ); + view.GetL(); + + // Copy information from DB to schedule. + prog->SetDbIdentifier( view.ColUint32( keyIndex ) ); + prog->SetName( view.ColDes8( nameIndex ) ); + prog->SetStartTime( view.ColTime( startTimeIndex ) ); + prog->SetEndTime( view.ColTime( endTimeIndex ) ); + prog->SetAppUid( view.ColInt32( applicationUidIdIndex ) ); + prog->SetPluginUid( view.ColInt32( plugInUidIndex ) ); + + prog->SetScheduleType( CCseScheduledProgram::TCseScheduleType( + view.ColInt32( typeIndex ) ) ); + prog->SetPluginType( view.ColInt32( pluginTypeIndex ) ); + TInt streamLen( view.ColLength( applicationSpecificIndex ) ); + + HBufC8* appDataBuffer = HBufC8::NewL( streamLen ); + CleanupStack::PushL( appDataBuffer ); + + TPtr8 buffPtr( appDataBuffer->Des() ); + RDbColReadStream readStream; + readStream.OpenLC( view, applicationSpecificIndex ); // |-> 1 + readStream.ReadL( buffPtr, streamLen ); + readStream.Release(); + CleanupStack::PopAndDestroy(); // 1 <-| + + prog->SetApplicationDataL( *appDataBuffer ); + + CleanupStack::PopAndDestroy( appDataBuffer ); + User::LeaveIfError( aNextScheduleArray.Append( prog ) ); + CleanupStack::Pop( prog ); + + // And next schedule... + view.NextL(); + } + + CleanupStack::PopAndDestroy( &view ); // Closes view + + CSELOGSTRING_HIGH_LEVEL("<<