os/persistentdata/loggingservices/eventlogger/LogServ/src/LogServCacheStrings.cpp
Update contrib.
1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "LogServCacheStrings.h"
17 #include "LogServDatabaseTransactionInterface.h"
18 #include "logservpanic.h"
19 #include "LogServSqlStrings.h"
22 Strings array granularity.
25 const TInt KLogNumberOfInitialStrings = 16;
27 /////////////////////////////////////////////////////////////////////////////////////////
28 // -----> CLogServCacheStrings (source)
29 /////////////////////////////////////////////////////////////////////////////////////////
31 CLogServCacheStrings::CLogServCacheStrings(MLogServDatabaseTransactionInterface& aDatabase) :
33 iStrings(KLogNumberOfInitialStrings)
37 CLogServCacheStrings::~CLogServCacheStrings()
42 void CLogServCacheStrings::DestroyCache()
44 for(TInt i=iStrings.Count()-1;i>=0;--i)
46 TLogServCacheStringEntry::DeleteEntry(iStrings[i]);
51 void CLogServCacheStrings::ConstructL()
53 ReadStringsFromDatabaseL();
56 CLogServCacheStrings* CLogServCacheStrings::NewL(MLogServDatabaseTransactionInterface& aDatabase)
58 CLogServCacheStrings* self = new(ELeave) CLogServCacheStrings(aDatabase);
59 CleanupStack::PushL(self);
61 CleanupStack::Pop(self);
65 /////////////////////////////////////////////////////////////////////////////////////////
66 /////////////////////////////////////////////////////////////////////////////////////////
67 /////////////////////////////////////////////////////////////////////////////////////////
70 Find the descriptor corresponding to a given string id. KNullDesC if the id is not found.
72 const TPtrC CLogServCacheStrings::FindString(TLogStringId aId) const
74 if(aId != KLogNullStringId)
76 for(TInt i=iStrings.Count()-1;i>=0;--i)
78 if(iStrings[i]->iId == aId)
80 return iStrings[i]->String();
89 Find the id of a given string. KLogNullStringId if no string is found.
91 TLogStringId CLogServCacheStrings::FindId(const TDesC& aString)
93 if(aString.Length() == 0)
95 return KLogNullStringId;
97 TInt position = iStrings.FindInOrder(aString, &CLogServCacheStrings::Compare1);
98 return position >= 0 ? iStrings[position]->iId : KLogNullStringId;
102 Find the id of a given string. Add the string to the cache if the string is not there.
103 If the aString length is 0, then do not search the cache, do not add the string, just return KLogNullStringId.
104 If the string has to be added - the string will be added to the cache and
105 a new record will be inserted into the database.
106 If the database is in transaction, the string in the cache will have its "dirty" flag set. During the rollback
107 (if a rollback occurs) all strings with "dirty" flag set will be removed from the cache.
108 The idea is to keep the cache content consistent with the database content.
110 TLogStringId CLogServCacheStrings::GetIdL(const TDesC& aString)
112 if(aString.Length() == 0)
114 return KLogNullStringId;
116 TLogStringId id = FindId(aString);
117 if(id == KLogNullStringId)
119 id = DoAddStringL(aString);
125 Clears the dirty flag of the cache entries that have been added during the last transaction.
127 void CLogServCacheStrings::Commit()
131 for(TInt i=iStrings.Count()-1;i>=0;--i)
133 iStrings[i]->iDirty = EFalse;
141 Removes any strings added to the cache of strings since the beginning of last transaction (with iDirty flag set).
143 void CLogServCacheStrings::Rollback()
147 for(TInt i=iStrings.Count()-1;i>=0;--i)
149 if(iStrings[i]->iDirty)
151 TLogServCacheStringEntry::DeleteEntry(iStrings[i]);
159 /////////////////////////////////////////////////////////////////////////////////////////
160 /////////////////////////////////////////////////////////////////////////////////////////
161 /////////////////////////////////////////////////////////////////////////////////////////
163 void CLogServCacheStrings::ReadStringsFromDatabaseL()
167 CleanupClosePushL(tbl);
168 User::LeaveIfError(tbl.Open(iDatabase.DTIDatabase(), KLogNameStringString, RDbRowSet::EReadOnly));
171 InitializeColNumsL(tbl);
172 iStrings.ReserveL(tbl.CountL());
176 const TLogStringId id = tbl.ColInt16(iIdColNo);
177 const TPtrC pString(tbl.ColDes(iStringColNo));
178 TLinearOrder<TLogServCacheStringEntry*> orderer(&CLogServCacheStrings::Compare2);
179 TLogServCacheStringEntry* entry = TLogServCacheStringEntry::NewEntryL(id, pString);
180 TInt err = iStrings.InsertInOrder(entry, orderer);
181 __ASSERT_ALWAYS(err == KErrNone, Panic(ELogStringsCacheReserved));
185 CleanupStack::PopAndDestroy(&tbl);
188 //Atomic "add string to cache" operation.
189 TLogStringId CLogServCacheStrings::DoAddStringL(const TDesC& aString)
191 //Reserve space for the new string in the cache
192 iStrings.ReserveL(iStrings.Count() + 1);
193 //Open the database table and push it on the cleanup stack.
194 //If the InitializeColNumsL() operation leaves then the table will be closed automatically.
196 CleanupClosePushL(tbl);
197 User::LeaveIfError(tbl.Open(iDatabase.DTIDatabase(), KLogNameStringString));
198 InitializeColNumsL(tbl);
199 //Allocate space for the new record in the table. Push the Cancel() function on the cleanup stack.
200 //If some of the next calls leaves, the insert operation will be automatically cancelled.
202 const TLogStringId id = tbl.ColInt16(iIdColNo);
203 tbl.SetColL(iStringColNo, aString);
204 //Create new cache entry and push it on the cleanup stack.
205 TLogServCacheStringEntry* entry = TLogServCacheStringEntry::NewEntryLC(id, aString, iDatabase.DTIInTransaction());
206 //Finish the "insert record" operation. If PutL() leaves, then:
207 // - the new cache entry is deleted
208 // - the insert operation is cancelled
209 // - the table is closed
211 //Pop the entry and the Cancel() from the cleanup stack. Close the table.
212 CleanupStack::Pop();//TLogServCacheStringEntry
213 CleanupStack::PopAndDestroy(&tbl);
214 //The next operation is guaranteed to be a non-failing "add entry" operation.
215 TLinearOrder<TLogServCacheStringEntry*> orderer(&CLogServCacheStrings::Compare2);
216 TInt err = iStrings.InsertInOrder(entry, orderer);
217 __ASSERT_ALWAYS(err == KErrNone, Panic(ELogStringsCacheReserved));
218 //Mark the cache as dirty. Later if there was an outstanding transaction and that transaction failed,
219 //The database rollback operation will restore the original state of the table.
220 //The CLogServCacheStrings::RollbackAddStringsL() will remove from the cache all "dirty" strings.
225 TInt CLogServCacheStrings::Compare1(const TDesC* aString, TLogServCacheStringEntry* const& aRight)
227 __ASSERT_DEBUG(aString != NULL, Panic(ELogStringsCacheNullArg1));
228 __ASSERT_DEBUG(aRight != NULL, Panic(ELogStringsCacheNullArg1));
229 return aString->Compare(aRight->String());
232 TInt CLogServCacheStrings::Compare2(TLogServCacheStringEntry* const& aLeft, TLogServCacheStringEntry* const& aRight)
234 __ASSERT_DEBUG(aLeft != NULL, Panic(ELogStringsCacheNullArg2));
235 __ASSERT_DEBUG(aRight != NULL, Panic(ELogStringsCacheNullArg2));
236 return aLeft->String().Compare(aRight->String());
239 void CLogServCacheStrings::InitializeColNumsL(RDbRowSet& aRowSet)
243 CDbColSet* colset = aRowSet.ColSetL();
244 iIdColNo = colset->ColNo(KLogFieldStringIdString);
245 iStringColNo = colset->ColNo(KLogFieldStringTextString);
248 __ASSERT_DEBUG(iIdColNo > 0, Panic(ELogInvalidStringColNo));
249 __ASSERT_DEBUG(iStringColNo > 0, Panic(ELogInvalidStringColNo));
252 void CLogServCacheStrings::TLogServCacheStringEntry::CleanupEntry(TAny* aEntry)
254 TLogServCacheStringEntry* entry = reinterpret_cast <TLogServCacheStringEntry*> (aEntry);
255 CLogServCacheStrings::TLogServCacheStringEntry::DeleteEntry(entry);