|
1 // Copyright (c) 2007-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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 /** |
|
17 @file |
|
18 @internalComponent |
|
19 @released |
|
20 */ |
|
21 |
|
22 #include "pltables.h" |
|
23 #include "dbsqlconstants.h" |
|
24 #include <cntdb.h> |
|
25 |
|
26 _LIT(KFirstSQLiteSchemaVersion, "1.0"); |
|
27 const TInt KArrayGrowthSize = 3; |
|
28 |
|
29 /** |
|
30 Construct a concrete CPplPreferencesPersistor object |
|
31 |
|
32 @param aDatabase Reference to RSqlDatabase. |
|
33 */ |
|
34 CPplPreferencesPersistor* CPplPreferencesPersistor::NewL(RSqlDatabase& aDatabase) |
|
35 { |
|
36 CPplPreferencesPersistor* self = new (ELeave) CPplPreferencesPersistor(aDatabase); |
|
37 CleanupStack::PushL(self); |
|
38 self->ConstructL(); |
|
39 CleanupStack::Pop(); |
|
40 return self; |
|
41 } |
|
42 |
|
43 /** |
|
44 Utility method used to write a to the preferences table the first time |
|
45 */ |
|
46 void CPplPreferencesPersistor::FirstWriteToTableL() |
|
47 { |
|
48 // insert preferences record |
|
49 // INSERT INTO preferences |
|
50 // (preference_id , data_schema_version, machine_id, creation_date, preferred_sortorder, |
|
51 // preferred template id) |
|
52 // VALUES (:NULL, VersionNum, :[created machine id], |
|
53 // :[time now], :NULL, :[-1] ); |
|
54 |
|
55 TCntSqlStatementType cntStatement(EInsert, KSqlContactPrefTableName); |
|
56 CCntSqlStatement* insertStatement = TSqlProvider::GetSqlStatementL(cntStatement); |
|
57 CleanupStack::PushL(insertStatement); |
|
58 |
|
59 // Set Id Arg |
|
60 insertStatement->SetParamL(KPrefPrefId, KPrefIdParam); |
|
61 |
|
62 // Set Schema Version Number |
|
63 insertStatement->SetParamL(KPrefSchemaVersion, KFirstSQLiteSchemaVersion()); |
|
64 |
|
65 // Set Machine Id |
|
66 insertStatement->SetParamL(KPrefMachineId, KPrefMachineIdParam); |
|
67 |
|
68 // Set Creation Date Param |
|
69 insertStatement->SetParamL(KPrefPrefCreationDate, KPrefCreationDateParam); |
|
70 |
|
71 // No sort order defined at this point |
|
72 insertStatement->SetParamL(KPrefPreferredOrder, KPrefPreferredOrderParam); |
|
73 |
|
74 // Write -1 for the pref template |
|
75 insertStatement->SetParamL(KPrefferredTemplateId, KPrefferredTemplateIdParam); |
|
76 |
|
77 RSqlStatement insertStmt; |
|
78 CleanupClosePushL(insertStmt); |
|
79 User::LeaveIfError(insertStmt.Prepare(iDatabase, insertStatement->SqlStringL())); |
|
80 |
|
81 // NULL id |
|
82 User::LeaveIfError(insertStmt.BindNull(KFirstParam)); |
|
83 |
|
84 // Machine id |
|
85 GenerateMachineUniqueID(); |
|
86 User::LeaveIfError(insertStmt.BindInt64(KFirstParam + 1, iMachineId )); |
|
87 |
|
88 // Creation Date |
|
89 TTime timeNow; |
|
90 timeNow.UniversalTime(); |
|
91 User::LeaveIfError(insertStmt.BindInt64(KFirstParam + 2, timeNow.Int64())); |
|
92 |
|
93 // 0 sort order |
|
94 RSqlParamWriteStream sortOrderStream; |
|
95 CleanupClosePushL(sortOrderStream); |
|
96 sortOrderStream.BindBinaryL(insertStmt, KFirstParam + 3); |
|
97 |
|
98 sortOrderStream.WriteInt32L(0); |
|
99 |
|
100 CleanupStack::PopAndDestroy(&sortOrderStream); |
|
101 |
|
102 // Preffered Template |
|
103 User::LeaveIfError(insertStmt.BindInt(KFirstParam + 4, KErrNotFound)); |
|
104 |
|
105 User::LeaveIfError(insertStmt.Exec()); |
|
106 CleanupStack::PopAndDestroy(2, insertStatement); |
|
107 |
|
108 iCreationDate = timeNow; // in case the Exec leaves, don't update this state until here |
|
109 } |
|
110 |
|
111 /** |
|
112 Utility method used to create a preference table in the contact database & write default content |
|
113 */ |
|
114 void CPplPreferencesPersistor::CreateTableL() |
|
115 { |
|
116 User::LeaveIfError(iDatabase.Exec(KPreferencesCreateStmnt)); |
|
117 FirstWriteToTableL(); |
|
118 } |
|
119 |
|
120 /** |
|
121 CPplPreferencesPersistor destructor |
|
122 */ |
|
123 CPplPreferencesPersistor::~CPplPreferencesPersistor() |
|
124 { |
|
125 delete iSortOrderPrefs; |
|
126 delete iUpdateStmnt; |
|
127 |
|
128 } |
|
129 |
|
130 /** |
|
131 CPplPreferencesPersistor constructor |
|
132 |
|
133 @param aDatabase reference to contact database |
|
134 */ |
|
135 CPplPreferencesPersistor::CPplPreferencesPersistor(RSqlDatabase& aDatabase): |
|
136 iDatabase(aDatabase), |
|
137 iCreationDate(Time::NullTTime()) |
|
138 { |
|
139 } |
|
140 |
|
141 /** |
|
142 Second phase constructor for CPplPreferencesPersistor object |
|
143 */ |
|
144 void CPplPreferencesPersistor::ConstructL() |
|
145 { |
|
146 TCntSqlStatementType updateType(EUpdate, KSqlContactPrefTableName() ); |
|
147 iUpdateStmnt = TSqlProvider::GetSqlStatementL(updateType); |
|
148 iSortOrderPrefs = new (ELeave) CArrayFixFlat<CContactDatabase::TSortPref>(KArrayGrowthSize); |
|
149 } |
|
150 |
|
151 /** |
|
152 Utility method used to persiste preferences in preference table |
|
153 */ |
|
154 void CPplPreferencesPersistor::PersistStateL(const TDesC& aParam, TInt aValue) |
|
155 { |
|
156 TBuf<64> temp; |
|
157 temp.Format(KIntValue, aValue); |
|
158 |
|
159 iUpdateStmnt->Reset(); |
|
160 iUpdateStmnt->SetParamL(aParam, temp); |
|
161 |
|
162 HBufC* wherePrefIdBuf = HBufC::NewLC(KPrefPrefId().Size() + KConditionClause().Size() + 1); |
|
163 |
|
164 // for WHERE pref_id = 1 |
|
165 wherePrefIdBuf->Des().AppendFormat(KConditionClause, &KPrefPrefId, 1); |
|
166 |
|
167 iUpdateStmnt->SetConditionL(*wherePrefIdBuf); |
|
168 CleanupStack::PopAndDestroy(wherePrefIdBuf); |
|
169 |
|
170 RSqlStatement updateStmt; |
|
171 CleanupClosePushL(updateStmt); |
|
172 User::LeaveIfError(updateStmt.Prepare(iDatabase, iUpdateStmnt->SqlStringL())); |
|
173 |
|
174 User::LeaveIfError(updateStmt.Exec() ); |
|
175 CleanupStack::PopAndDestroy(&updateStmt); |
|
176 } |
|
177 |
|
178 /** |
|
179 Check if the Creation Date has been set. If it has, there is nothing to do (as file is newly created and |
|
180 state set OR state has been read in already). Otherwise read in the state. |
|
181 */ |
|
182 void CPplPreferencesPersistor::ReadInStateL() |
|
183 { |
|
184 if (iCreationDate == Time::NullTTime()) // if this is not set, the state has never been read - read it all in |
|
185 { |
|
186 TCntSqlStatementType selectType(ESelect, KSqlContactPrefTableName); |
|
187 CCntSqlStatement* sqlSelectStmnt = TSqlProvider::GetSqlStatementL(selectType); |
|
188 CleanupStack::PushL(sqlSelectStmnt); |
|
189 |
|
190 sqlSelectStmnt->SetParamL(KPrefPrefCreationDate(), KNullDesC() ); |
|
191 sqlSelectStmnt->SetParamL(KPrefMachineId(), KNullDesC() ); |
|
192 sqlSelectStmnt->SetParamL(KPrefPreferredOrder(), KNullDesC() ); |
|
193 sqlSelectStmnt->SetParamL(KPrefferredTemplateId(), KNullDesC() ); |
|
194 |
|
195 RSqlStatement selectStmt; |
|
196 CleanupClosePushL(selectStmt); |
|
197 User::LeaveIfError(selectStmt.Prepare(iDatabase, sqlSelectStmnt->SqlStringL())); |
|
198 |
|
199 TInt err; |
|
200 if((err = selectStmt.Next()) == KSqlAtRow) |
|
201 { |
|
202 |
|
203 iCreationDate = selectStmt.ColumnInt64(sqlSelectStmnt->ParameterIndex(KPrefPrefCreationDate)); |
|
204 iMachineId = selectStmt.ColumnInt64(sqlSelectStmnt->ParameterIndex(KPrefMachineId)); |
|
205 iPreferCardTemplateId = selectStmt.ColumnInt(sqlSelectStmnt->ParameterIndex(KPrefferredTemplateId)); |
|
206 |
|
207 // Read In the Pref Sort Order |
|
208 TPtrC8 sortOrderDescriptor; |
|
209 selectStmt.ColumnBinary(User::LeaveIfError(selectStmt.ColumnIndex(KPrefPreferredOrder)), sortOrderDescriptor); |
|
210 RDesReadStream sortOrderStream(sortOrderDescriptor); |
|
211 CleanupClosePushL(sortOrderStream); |
|
212 |
|
213 // read in number of prefs |
|
214 CArrayFix<CContactDatabase::TSortPref>* sortOrder = new (ELeave) CArrayFixFlat<CContactDatabase::TSortPref>(KArrayGrowthSize); |
|
215 CleanupStack::PushL(sortOrder); |
|
216 const TInt KNumSortPrefs = sortOrderStream.ReadInt32L(); |
|
217 for (TInt i=0 ; i < KNumSortPrefs ; ++i) |
|
218 { |
|
219 CContactDatabase::TSortPref thisPref; |
|
220 sortOrderStream >> thisPref; |
|
221 sortOrder->AppendL(thisPref); |
|
222 } |
|
223 CleanupStack::Pop(sortOrder); |
|
224 |
|
225 CleanupStack::PopAndDestroy(3); |
|
226 delete iSortOrderPrefs; |
|
227 iSortOrderPrefs = sortOrder; |
|
228 |
|
229 } |
|
230 else |
|
231 { |
|
232 if(err == KSqlAtEnd) |
|
233 { |
|
234 User::Leave(KErrNotFound); |
|
235 } |
|
236 else |
|
237 { |
|
238 User::Leave(err); |
|
239 } |
|
240 } |
|
241 } |
|
242 } |
|
243 |
|
244 /** |
|
245 Getter method used to retrieve database schema version |
|
246 |
|
247 @return database schema version |
|
248 */ |
|
249 TDesC CPplPreferencesPersistor::DataSchemaVersion() const |
|
250 { |
|
251 return KFirstSQLiteSchemaVersion(); |
|
252 } |
|
253 /** |
|
254 Getter method used to retrieve database creation time |
|
255 |
|
256 @return database creation time |
|
257 */ |
|
258 TTime CPplPreferencesPersistor::CreationDateL() |
|
259 { |
|
260 ReadInStateL(); |
|
261 return iCreationDate; |
|
262 } |
|
263 |
|
264 /** |
|
265 Getter method used to retrieve prefered card template id |
|
266 |
|
267 @return prefered card template id |
|
268 */ |
|
269 TContactItemId CPplPreferencesPersistor::PreferredCardTemplateIdL() |
|
270 { |
|
271 ReadInStateL(); |
|
272 return iPreferCardTemplateId; |
|
273 } |
|
274 |
|
275 /** |
|
276 Getter method used to retrieve preferred sort order |
|
277 |
|
278 @return preferred sort order |
|
279 */ |
|
280 const CArrayFix<CContactDatabase::TSortPref>& CPplPreferencesPersistor::PreferredSortOrderL() |
|
281 { |
|
282 ReadInStateL(); |
|
283 return *iSortOrderPrefs; |
|
284 } |
|
285 |
|
286 /** |
|
287 Getter method used to retrieve database UID |
|
288 |
|
289 @return database UID |
|
290 */ |
|
291 TPtrC CPplPreferencesPersistor::DatabaseUidL() |
|
292 { |
|
293 ReadInStateL(); |
|
294 TInt64 part2 = iCreationDate.Int64(); |
|
295 TInt64 machineId = iMachineId; |
|
296 |
|
297 iUidString.Format(_L("%08X%08X-08X%08X"), I64HIGH(machineId), I64LOW(machineId), I64HIGH(part2), I64LOW(part2)); |
|
298 |
|
299 return iUidString; |
|
300 |
|
301 } |
|
302 |
|
303 /** |
|
304 Getter method used to retrieve machine ID |
|
305 |
|
306 @return machine ID |
|
307 */ |
|
308 TInt64 CPplPreferencesPersistor::MachineIdL() |
|
309 { |
|
310 ReadInStateL(); |
|
311 return iMachineId; |
|
312 } |
|
313 |
|
314 /** |
|
315 Setter method used to set machine id |
|
316 |
|
317 @param aDbUid new machine id |
|
318 */ |
|
319 void CPplPreferencesPersistor::SetMachineIdL(TInt64 aDbUid) |
|
320 { |
|
321 PersistStateL(KPrefMachineId, aDbUid); |
|
322 iMachineId = aDbUid; |
|
323 } |
|
324 |
|
325 |
|
326 /** |
|
327 Setter method used to set preferred sort order |
|
328 |
|
329 @param aSortPrefs new preffered sort order |
|
330 */ |
|
331 void CPplPreferencesPersistor::SetPreferredSortOrderL(CArrayFix<CContactDatabase::TSortPref>* aSortPrefs) |
|
332 { |
|
333 iUpdateStmnt->Reset(); |
|
334 iUpdateStmnt->SetParamL(KPrefPreferredOrder, KPrefPreferredOrderParam); |
|
335 |
|
336 HBufC* wherePrefIdBuf = HBufC::NewLC(KPrefPrefId().Size() + KConditionClause().Size() + 1); |
|
337 |
|
338 // for WHERE pref_id = 1 |
|
339 wherePrefIdBuf->Des().AppendFormat(KConditionClause, |
|
340 &KPrefPrefId, 1); |
|
341 |
|
342 iUpdateStmnt->SetConditionL(*wherePrefIdBuf); |
|
343 CleanupStack::PopAndDestroy(wherePrefIdBuf); |
|
344 |
|
345 RSqlStatement updateStmt; |
|
346 CleanupClosePushL(updateStmt); |
|
347 User::LeaveIfError(updateStmt.Prepare(iDatabase, iUpdateStmnt->SqlStringL())); |
|
348 |
|
349 // 0 sort order |
|
350 RSqlParamWriteStream sortOrderStream; |
|
351 CleanupClosePushL(sortOrderStream); |
|
352 sortOrderStream.BindBinaryL(updateStmt, KFirstParam); |
|
353 |
|
354 |
|
355 const TInt KNumSortPrefs = aSortPrefs->Count(); |
|
356 sortOrderStream.WriteInt32L(KNumSortPrefs); |
|
357 |
|
358 for (TInt i=0; i < KNumSortPrefs; ++i) |
|
359 { |
|
360 (*aSortPrefs)[i].ExternalizeL(sortOrderStream); |
|
361 } |
|
362 sortOrderStream.CommitL(); |
|
363 CleanupStack::PopAndDestroy(&sortOrderStream); |
|
364 |
|
365 User::LeaveIfError(updateStmt.Exec() ); |
|
366 CleanupStack::PopAndDestroy(&updateStmt); |
|
367 |
|
368 delete iSortOrderPrefs; |
|
369 iSortOrderPrefs = aSortPrefs; |
|
370 } |
|
371 |
|
372 void CPplPreferencesPersistor::SetPreferredCardTemplateIdL(TContactItemId aTemplateId) |
|
373 { |
|
374 PersistStateL(KPrefferredTemplateId, aTemplateId); |
|
375 iPreferCardTemplateId = aTemplateId; |
|
376 } |
|
377 |
|
378 |
|
379 /** |
|
380 Generate a 64-bit "unique id" that is likely to be different each time and is |
|
381 reasonably well distributed. |
|
382 */ |
|
383 void CPplPreferencesPersistor::GenerateMachineUniqueID() |
|
384 { |
|
385 // 2 different 32-bit inputs from environment: a counter and a memory |
|
386 // address. |
|
387 TUint32 temp1 = User::FastCounter(); |
|
388 // Add 1 because the address will be 32 bit aligned. |
|
389 TUint32 temp2 = reinterpret_cast<TUint32>(this) + 1; |
|
390 |
|
391 // Get 32 fairly random bits. |
|
392 TUint32 part1 = temp1 * temp2; |
|
393 |
|
394 // Jumble things around to get different 32 bits. |
|
395 TUint32 part2 = (part1*0x4321) + (0x65*temp1) + (0x87*temp2) + 0xFEDCBA98; |
|
396 |
|
397 // Combine part1 and part2 to make 64 random bits. |
|
398 TInt64 uid = MAKE_TINT64(part1,part2); |
|
399 |
|
400 // Get calendar time to randomise further. |
|
401 TTime time; |
|
402 time.UniversalTime(); |
|
403 |
|
404 iMachineId = uid + time.Int64(); |
|
405 } |
|
406 |
|
407 /** |
|
408 Utility method used to generate a guid for a contact item |
|
409 */ |
|
410 void CPplPreferencesPersistor::SetGuidL(CContactItem& aContact, TBool& aCompressed) |
|
411 { |
|
412 const TInt64 KMachineUniqueId = MachineIdL(); |
|
413 TPtrC guid=aContact.UidStringL(KMachineUniqueId); |
|
414 HBufC* guidBuf=NULL; |
|
415 aCompressed=EFalse; |
|
416 |
|
417 if (guid.Length()==0) |
|
418 { |
|
419 guidBuf=HBufC::NewLC(20); |
|
420 TPtr ptr=guidBuf->Des(); |
|
421 TTime time; |
|
422 time.UniversalTime(); |
|
423 TInt64 num=time.Int64(); |
|
424 ptr.AppendFormat(_L("%08x"),(TInt32)I64HIGH(num)); |
|
425 ptr.AppendFormat(_L("%08x"),(TInt32)I64LOW(num)); |
|
426 aCompressed=ETrue; |
|
427 } |
|
428 else |
|
429 { |
|
430 guidBuf=guid.AllocLC(); |
|
431 TPtr ptr=guidBuf->Des(); |
|
432 aCompressed=ContactGuid::GetCreationDate(ptr,KMachineUniqueId); |
|
433 } |
|
434 |
|
435 aContact.SetUidStringL(*guidBuf); |
|
436 CleanupStack::PopAndDestroy(guidBuf); |
|
437 } |
|
438 |
|
439 |