omadrm/drmengine/server/src/DRMReplayCache.cpp
changeset 0 95b198f216e5
child 18 8a03a285ab14
equal deleted inserted replaced
-1:000000000000 0:95b198f216e5
       
     1 /*
       
     2 * Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation of the parent storage for Decision Making Machine
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 
       
    21 #include <f32file.h>
       
    22 #include <S32FILE.H>
       
    23 #include <BAUTILS.H>
       
    24 #include "drmreplaycache.h"
       
    25 
       
    26 
       
    27 // EXTERNAL DATA STRUCTURES
       
    28 
       
    29 // EXTERNAL FUNCTION PROTOTYPES  
       
    30 
       
    31 // CONSTANTS
       
    32 
       
    33 // MACROS
       
    34 
       
    35 // LOCAL CONSTANTS AND MACROS
       
    36 
       
    37 _LIT( KCIDColName, "cid" );
       
    38 _LIT( KTimeColName, "time" );
       
    39 _LIT( KInsertionTimeColName, "inserttime" );
       
    40 _LIT( KReplayCacheTable, "cache" );
       
    41 _LIT( KViewInitQuery, "SELECT * FROM cache ORDER BY inserttime ASC" );
       
    42 
       
    43 LOCAL_C const TUint KDbViewInsertionTimeOrdinal = 2;
       
    44 LOCAL_C const TUint8 KDbViewTimeOrdinal = 3;
       
    45 LOCAL_C const TUint8 KDbViewIDOrdinal = 1;
       
    46 LOCAL_C const TUint16 KDbMaxNumOfItems = 100;
       
    47 
       
    48 // MODULE DATA STRUCTURES
       
    49 NONSHARABLE_STRUCT( TDoDeleteFile ) 
       
    50     {
       
    51     RFs* iFs;
       
    52     const TDesC* iFile;
       
    53     };
       
    54     
       
    55 // LOCAL FUNCTION PROTOTYPES
       
    56 LOCAL_C void DoRollBack( TAny* aAny );
       
    57 LOCAL_C void DoDeleteFile( TAny* aAny );
       
    58 
       
    59 // FORWARD DECLARATIONS
       
    60 
       
    61 
       
    62 // ============================= LOCAL FUNCTIONS ===============================
       
    63 // -----------------------------------------------------------------------------
       
    64 // DoRollBack
       
    65 //
       
    66 // Do a rollback operation to the RDbDatabase* 
       
    67 // -----------------------------------------------------------------------------
       
    68 //
       
    69 LOCAL_C void DoRollBack( TAny* aAny )
       
    70     {
       
    71     reinterpret_cast< RDbDatabase* >( aAny )->Rollback();
       
    72     }
       
    73 
       
    74 // -----------------------------------------------------------------------------
       
    75 // DoDeleteFile
       
    76 //
       
    77 // Delete the file presented by TDoDeleteFile*
       
    78 // -----------------------------------------------------------------------------
       
    79 //
       
    80 LOCAL_C void DoDeleteFile( TAny* aAny )
       
    81     {
       
    82     TDoDeleteFile* s = reinterpret_cast< TDoDeleteFile* >( aAny );
       
    83     
       
    84     s->iFs->Delete( *( s->iFile ) );    
       
    85     }
       
    86 
       
    87 // ============================ MEMBER FUNCTIONS ===============================
       
    88 
       
    89 // -----------------------------------------------------------------------------
       
    90 // RDRMReplayCache::RDRMReplayCache
       
    91 //
       
    92 // Default constructor 
       
    93 // -----------------------------------------------------------------------------
       
    94 //
       
    95 RDRMReplayCache::RDRMReplayCache():
       
    96 iFs( NULL ),
       
    97 iTimeDb(),
       
    98 iPlainDb()
       
    99     {
       
   100     // Nothing.    
       
   101     }
       
   102 
       
   103 // -----------------------------------------------------------------------------
       
   104 // RDRMReplayCache::RDRMReplayCache
       
   105 //
       
   106 // Constructor 
       
   107 // -----------------------------------------------------------------------------
       
   108 //
       
   109 RDRMReplayCache::RDRMReplayCache( RFs& aFs ) :
       
   110 iFs( &aFs ),
       
   111 iTimeDb(),
       
   112 iPlainDb()
       
   113     {
       
   114     // Nothing.
       
   115     }
       
   116     
       
   117 
       
   118 // -----------------------------------------------------------------------------
       
   119 // RDRMReplayCache::Set
       
   120 //
       
   121 // Set iFs to given aFs.
       
   122 // -----------------------------------------------------------------------------
       
   123 //    
       
   124 void RDRMReplayCache::Set( RFs& aFs )
       
   125     {
       
   126     iFs = &aFs;
       
   127     }
       
   128 
       
   129 // -----------------------------------------------------------------------------
       
   130 // RDRMReplayCache::Close
       
   131 //
       
   132 // Closes the databases.
       
   133 // -----------------------------------------------------------------------------
       
   134 //    
       
   135 void RDRMReplayCache::Close()
       
   136     {
       
   137     // iView.Close();
       
   138     iTimeDb.Close();
       
   139     iPlainDb.Close();
       
   140     }
       
   141 
       
   142 // -----------------------------------------------------------------------------
       
   143 // RDRMReplayCache::InitL
       
   144 //
       
   145 // Initialize the databases.
       
   146 // -----------------------------------------------------------------------------
       
   147 //    
       
   148 void RDRMReplayCache::InitL( const TDesC& aTimedDb,
       
   149                              const TDesC& aPlainDb )
       
   150     {
       
   151     InitDbL( iTimeDb, aTimedDb, ETimeDb );
       
   152     InitDbL( iPlainDb, aPlainDb, EPlainDb );
       
   153     }
       
   154 
       
   155 
       
   156 // -----------------------------------------------------------------------------
       
   157 // RDRMReplayCache::InCacheL
       
   158 //
       
   159 // Check whether the given entry is in cache. Overloaded.
       
   160 // -----------------------------------------------------------------------------
       
   161 //
       
   162 TBool RDRMReplayCache::InCacheL( const TDesC8& aID, 
       
   163                                  const TTime& aTime )
       
   164     {
       
   165     TBool res = EFalse;
       
   166     
       
   167     RDbView view;
       
   168     InitViewLC( view, ETimeDb, EFalse );
       
   169     
       
   170     view.FirstL();
       
   171     
       
   172     while ( view.AtRow() && !res )
       
   173         {
       
   174         view.GetL();
       
   175         TTime time = view.ColInt64( KDbViewTimeOrdinal );
       
   176 
       
   177         if ( time == aTime )
       
   178             {
       
   179             res = CompareCIDL( view, aID );
       
   180             }
       
   181         view.NextL();
       
   182         }
       
   183         
       
   184     CleanupStack::PopAndDestroy(); // view
       
   185     
       
   186     return res;
       
   187     }
       
   188 
       
   189 // -----------------------------------------------------------------------------
       
   190 // RDRMReplayCache::InCacheL
       
   191 //
       
   192 // Check whether the given entry is in cache. Overloaded.
       
   193 // -----------------------------------------------------------------------------
       
   194 //   
       
   195 TBool RDRMReplayCache::InCacheL( const TDesC8& aID )
       
   196     {
       
   197     TBool res = EFalse;
       
   198     
       
   199     RDbView view;
       
   200     InitViewLC( view, EPlainDb, EFalse );
       
   201     
       
   202     view.FirstL();
       
   203     
       
   204     while ( view.AtRow() && !res )
       
   205         {
       
   206         view.GetL();
       
   207         
       
   208         res = CompareCIDL( view, aID );
       
   209         
       
   210         view.NextL();
       
   211         }
       
   212         
       
   213     CleanupStack::PopAndDestroy(); // view
       
   214     
       
   215     return res;
       
   216     }
       
   217 
       
   218 // -----------------------------------------------------------------------------
       
   219 // RDRMReplayCache::AddL
       
   220 //
       
   221 // Add an entry to the database. Overloaded.
       
   222 // -----------------------------------------------------------------------------
       
   223 //    
       
   224 void RDRMReplayCache::AddL( const TDesC8& aID, 
       
   225                             const TTime& aTime,
       
   226                             const TTime& aInsertionTime )
       
   227     {
       
   228     RDbColWriteStream stream;
       
   229     RDbView view;
       
   230         
       
   231     PushL( iTimeDb );
       
   232     
       
   233     InitViewLC( view, ETimeDb, ETrue );
       
   234     CompactViewL( view );
       
   235 
       
   236     // Oldest ones are in the list earlier, and as long as clock works 
       
   237     // correctly, insertiontime(n-1)<insertiontime(n).
       
   238     view.EndL();
       
   239     
       
   240     User::LeaveIfError( iTimeDb.Begin() );
       
   241     
       
   242     view.InsertL(); 
       
   243     
       
   244     InsertIdL( view, aID );
       
   245     view.SetColL( KDbViewInsertionTimeOrdinal, aInsertionTime.Int64() );
       
   246     view.SetColL( KDbViewTimeOrdinal, aTime.Int64() );
       
   247     
       
   248     view.PutL();
       
   249     
       
   250     CleanupStack::PopAndDestroy(); // view
       
   251     
       
   252     User::LeaveIfError( iTimeDb.Commit() );
       
   253     User::LeaveIfError( iTimeDb.Compact() );
       
   254     
       
   255     Pop(); // iTimeDb
       
   256     }
       
   257     
       
   258 // -----------------------------------------------------------------------------
       
   259 // RDRMReplayCache::AddL
       
   260 //
       
   261 // Add an entry to the database. Overloaded.
       
   262 // -----------------------------------------------------------------------------
       
   263 //   
       
   264 void RDRMReplayCache::AddL( const TDesC8& aID,
       
   265                             const TTime& aInsertionTime )
       
   266     {
       
   267     
       
   268     RDbView view;
       
   269     
       
   270     PushL( iPlainDb );
       
   271     
       
   272     InitViewLC( view, EPlainDb, ETrue );
       
   273     CompactViewL( view );
       
   274     
       
   275     view .EndL();
       
   276     
       
   277     User::LeaveIfError( iPlainDb.Begin() );
       
   278     
       
   279     view.InsertL();
       
   280     InsertIdL( view, aID );
       
   281     view.SetColL( KDbViewInsertionTimeOrdinal, aInsertionTime.Int64() );
       
   282     
       
   283     view.PutL();
       
   284     
       
   285     CleanupStack::PopAndDestroy(); // view
       
   286     
       
   287     User::LeaveIfError( iPlainDb.Commit() );
       
   288     User::LeaveIfError( iPlainDb.Compact() );
       
   289     
       
   290     Pop(); // iPlainDb
       
   291     }
       
   292 
       
   293 // -----------------------------------------------------------------------------
       
   294 // RDRMReplayCache::InitDbL
       
   295 //
       
   296 // Initialize the databases.
       
   297 // -----------------------------------------------------------------------------
       
   298 //       
       
   299 void RDRMReplayCache::InitDbL( RDbNamedDatabase& aDb, 
       
   300                                const TDesC& aFileName,
       
   301                                TDatabaseId aId )
       
   302     {
       
   303     TInt error = KErrNone;
       
   304     TBool exists = BaflUtils::FileExists( *iFs, aFileName );
       
   305     
       
   306     if ( exists )
       
   307         {
       
   308         TRAP( error, OpenDbL( aDb, aFileName ) );
       
   309         }
       
   310     if ( error || !exists )
       
   311         {
       
   312         ReplaceDbL( aDb, aFileName, aId );
       
   313         }
       
   314     }
       
   315     
       
   316 // -----------------------------------------------------------------------------
       
   317 // RDRMReplayCache::~RDRMReplayCache
       
   318 //
       
   319 // Destructor.
       
   320 // -----------------------------------------------------------------------------
       
   321 //   
       
   322 RDRMReplayCache::~RDRMReplayCache()
       
   323     {
       
   324     }
       
   325 
       
   326 // -----------------------------------------------------------------------------
       
   327 // RDRMReplayCache::OpenDbL
       
   328 //
       
   329 // Open the database.
       
   330 // -----------------------------------------------------------------------------
       
   331 //   
       
   332 void RDRMReplayCache::OpenDbL( RDbNamedDatabase& aDb, 
       
   333                                const TDesC& aFileName )
       
   334     {
       
   335     CDbTableNames* tables = NULL;
       
   336     
       
   337     User::LeaveIfError( aDb.Open( *iFs, aFileName ) );
       
   338     CleanupClosePushL( aDb );
       
   339     
       
   340     if ( aDb.IsDamaged() )
       
   341         {
       
   342         User::LeaveIfError( aDb.Recover() );
       
   343         }
       
   344         
       
   345     // Sanity check.
       
   346     tables = aDb.TableNamesL();
       
   347     CleanupStack::PushL( tables );
       
   348     
       
   349     if ( tables->Count() != 1 || ( *tables )[ 0 ].Compare( KReplayCacheTable ) )
       
   350         {
       
   351         User::Leave( KErrCorrupt );
       
   352         }
       
   353     
       
   354     CleanupStack::PopAndDestroy(); // tables
       
   355     CleanupStack::Pop(); // aDb
       
   356     }
       
   357 
       
   358 // -----------------------------------------------------------------------------
       
   359 // RDRMReplayCache::ReplaceDbL
       
   360 //
       
   361 // Replace the database.
       
   362 // -----------------------------------------------------------------------------
       
   363 //       
       
   364 void RDRMReplayCache::ReplaceDbL( RDbNamedDatabase& aDb, 
       
   365                                   const TDesC& aFileName, 
       
   366                                   TDatabaseId aId )
       
   367     {
       
   368     CDbColSet*  colSet = NULL;
       
   369 //    CDbKey* key = NULL;
       
   370     TDbCol cidCol( KCIDColName, EDbColLongText8 );
       
   371     TDbCol insertionTimeCol( KInsertionTimeColName, EDbColInt64 );
       
   372     TDbCol timeCol( KTimeColName, EDbColInt64 );
       
   373     
       
   374     TDoDeleteFile deletefile = { iFs, &aFileName };
       
   375     
       
   376     TCleanupItem item( DoDeleteFile, &deletefile );
       
   377     CleanupStack::PushL( item );
       
   378     
       
   379     User::LeaveIfError( aDb.Replace( *iFs, aFileName ) );
       
   380     CleanupClosePushL( aDb );
       
   381     
       
   382     // Add columns
       
   383     colSet = CDbColSet::NewLC();
       
   384     colSet->AddL( cidCol );
       
   385     colSet->AddL( insertionTimeCol );
       
   386     
       
   387     if ( aId == ETimeDb )
       
   388         {
       
   389         colSet->AddL( timeCol );
       
   390         }
       
   391     
       
   392     User::LeaveIfError( aDb.Begin() );
       
   393     User::LeaveIfError( aDb.CreateTable( KReplayCacheTable, *colSet ) );
       
   394     User::LeaveIfError( aDb.Commit() );
       
   395     
       
   396     CleanupStack::PopAndDestroy(); // colSet
       
   397     CleanupStack::Pop(); // aDb    
       
   398     CleanupStack::Pop(); // item
       
   399     }
       
   400     
       
   401 // -----------------------------------------------------------------------------
       
   402 // RDRMReplayCache::InitViewLC
       
   403 //
       
   404 // Initialize the view.
       
   405 // -----------------------------------------------------------------------------
       
   406 //   
       
   407 void RDRMReplayCache::InitViewLC( RDbView& aView, 
       
   408                                   TDatabaseId aId, 
       
   409                                   TBool aUpdate )
       
   410     {
       
   411     RDbDatabase* db = ( aId ==  ETimeDb ? &iTimeDb : &iPlainDb );
       
   412     
       
   413     User::LeaveIfError( 
       
   414         aView.Prepare( *db, 
       
   415                        TDbQuery( KViewInitQuery, EDbCompareCollated ), 
       
   416                        aUpdate ? RDbRowSet::EUpdatable : RDbRowSet::EReadOnly ) );
       
   417     
       
   418     CleanupClosePushL( aView );
       
   419     
       
   420     User::LeaveIfError( aView.EvaluateAll() );
       
   421     }
       
   422     
       
   423 // -----------------------------------------------------------------------------
       
   424 // RDRMReplayCache::CompareCIDL
       
   425 //
       
   426 // Compare whether the rowset's CID matches the given CID.
       
   427 // -----------------------------------------------------------------------------
       
   428 //       
       
   429 TBool RDRMReplayCache::CompareCIDL( RDbRowSet& aView, 
       
   430                                     const TDesC8& aCID )
       
   431     {
       
   432     TBool res = EFalse;
       
   433     
       
   434     TInt size = aView.ColLength( KDbViewIDOrdinal );
       
   435     
       
   436     RDbColReadStream colData;
       
   437     colData.OpenLC( aView, KDbViewIDOrdinal );
       
   438     
       
   439     // The data contains also the cardinality of the CID data, but anyway... 
       
   440     HBufC8* des = HBufC8::NewLC( colData, size );
       
   441 
       
   442     if ( aCID.CompareC( *des ) == 0 )
       
   443         {
       
   444         res = ETrue;
       
   445         }
       
   446     
       
   447     CleanupStack::PopAndDestroy(); // des
       
   448     CleanupStack::PopAndDestroy(); // colData
       
   449     
       
   450     return res;
       
   451     }
       
   452     
       
   453 // -----------------------------------------------------------------------------
       
   454 // RDRMReplayCache::PushL
       
   455 //
       
   456 // Push a cleanup item to cleanup stack.
       
   457 // -----------------------------------------------------------------------------
       
   458 //   
       
   459 void RDRMReplayCache::PushL( RDbDatabase& aDb )
       
   460     {
       
   461     TCleanupItem item( DoRollBack, &aDb );
       
   462     CleanupStack::PushL( item );
       
   463     }
       
   464 
       
   465 // -----------------------------------------------------------------------------
       
   466 // RDRMReplayCache::Pop
       
   467 //
       
   468 // Pop a cleanup item pushed in by PushL.
       
   469 // -----------------------------------------------------------------------------
       
   470 //       
       
   471 void RDRMReplayCache::Pop()
       
   472     {
       
   473     CleanupStack::Pop();
       
   474     }
       
   475 
       
   476 // -----------------------------------------------------------------------------
       
   477 // RDRMReplayCache::DeleteOldestL
       
   478 //
       
   479 // Delete aHowMany entries from the view.
       
   480 // -----------------------------------------------------------------------------
       
   481 //       
       
   482 void RDRMReplayCache::DeleteOldestsL( RDbRowSet& aView, TInt16 aHowMany )
       
   483     {
       
   484     aView.FirstL();
       
   485     
       
   486     while ( aHowMany > 0 )
       
   487         {
       
   488         aView.DeleteL();
       
   489         aView.NextL();
       
   490         --aHowMany;
       
   491         }
       
   492     }
       
   493 
       
   494 // -----------------------------------------------------------------------------
       
   495 // RDRMReplayCache::CompactViewL
       
   496 //
       
   497 // Compact the view, deleting items if necessary.
       
   498 // -----------------------------------------------------------------------------
       
   499 //       
       
   500 void RDRMReplayCache::CompactViewL( RDbRowSet& aView )
       
   501     {
       
   502     TInt count = aView.CountL();
       
   503     
       
   504     if ( count >= KDbMaxNumOfItems )
       
   505         {
       
   506         // usually only one item is deleted, no need to use Begin/Commit.
       
   507         DeleteOldestsL( aView, static_cast< TInt >( KDbMaxNumOfItems ) - count + 1 );
       
   508         }
       
   509     }
       
   510 
       
   511 // -----------------------------------------------------------------------------
       
   512 // RDRMReplayCache::InsertIdL
       
   513 //
       
   514 // Insert content-ID to the view.
       
   515 // -----------------------------------------------------------------------------
       
   516 //       
       
   517 void RDRMReplayCache::InsertIdL( RDbRowSet& aView, 
       
   518                                  const TDesC8& aId )
       
   519     {
       
   520     
       
   521     RDbColWriteStream stream;
       
   522     stream.OpenLC( aView, KDbViewIDOrdinal );
       
   523     stream << aId;
       
   524     
       
   525     stream.CommitL();
       
   526     CleanupStack::PopAndDestroy(); // stream
       
   527     }
       
   528     
       
   529 // End of File