|
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 |