|
1 /* |
|
2 * Copyright (c) 2002-2007 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: Class that provides access to landmark databases. |
|
15 * |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include <f32file.h> |
|
21 #include <EPos_Landmarks.h> |
|
22 #include <eposlmcompactdblevel.rsg> |
|
23 #include <EPos_LandmarksErrors.h> |
|
24 #include "EPos_CPosLmLocalDbAccess.h" |
|
25 #include "EPos_CPosLmResourceReader.h" |
|
26 #include "EPos_LandmarkDatabaseStructure.h" |
|
27 #include "EPos_PosLmDatabaseUtility.h" |
|
28 |
|
29 _LIT(KPosCompactDbLevelResFile, "\\resource\\eposlmcompactdblevel.rsc"); |
|
30 |
|
31 // ============================= LOCAL FUNCTIONS =============================== |
|
32 |
|
33 // ----------------------------------------------------------------------------- |
|
34 // LmDbRollback Rollbacks a transaction for the CPosLmLocalDbAccess. This |
|
35 // function can be used as a TCleanupItem. |
|
36 // ----------------------------------------------------------------------------- |
|
37 // |
|
38 void LmDbRollback (TAny* aLmLocalDbAccess) |
|
39 { |
|
40 reinterpret_cast<CPosLmLocalDbAccess*>(aLmLocalDbAccess)-> |
|
41 RollbackTransaction(); |
|
42 } |
|
43 |
|
44 // ============================ MEMBER FUNCTIONS =============================== |
|
45 |
|
46 // ----------------------------------------------------------------------------- |
|
47 // ----------------------------------------------------------------------------- |
|
48 // |
|
49 CPosLmLocalDbAccess::CPosLmLocalDbAccess(TCompactLevelType aCompactLevel) : |
|
50 iInit(ENoInit), |
|
51 iLevelType(aCompactLevel) |
|
52 { |
|
53 } |
|
54 |
|
55 // ----------------------------------------------------------------------------- |
|
56 // ----------------------------------------------------------------------------- |
|
57 // |
|
58 void CPosLmLocalDbAccess::ConstructL() |
|
59 { |
|
60 ReadCompactDbLevelL(); |
|
61 } |
|
62 |
|
63 // ----------------------------------------------------------------------------- |
|
64 // ----------------------------------------------------------------------------- |
|
65 // |
|
66 EXPORT_C CPosLmLocalDbAccess* CPosLmLocalDbAccess::NewL( |
|
67 TCompactLevelType aCompactLevel) |
|
68 { |
|
69 CPosLmLocalDbAccess* self = new (ELeave) CPosLmLocalDbAccess(aCompactLevel); |
|
70 CleanupStack::PushL(self); |
|
71 self->ConstructL(); |
|
72 CleanupStack::Pop(self); |
|
73 return self; |
|
74 } |
|
75 |
|
76 // ----------------------------------------------------------------------------- |
|
77 // ----------------------------------------------------------------------------- |
|
78 // |
|
79 EXPORT_C CPosLmLocalDbAccess::~CPosLmLocalDbAccess() |
|
80 { |
|
81 iDb.Close(); |
|
82 iDbSession.Close(); |
|
83 } |
|
84 |
|
85 // ----------------------------------------------------------------------------- |
|
86 // ----------------------------------------------------------------------------- |
|
87 // |
|
88 EXPORT_C void CPosLmLocalDbAccess::BeginTransactionLC() |
|
89 { |
|
90 User::LeaveIfError(BeginTransaction()); |
|
91 |
|
92 CleanupStack::PushL(TCleanupItem(*LmDbRollback, this)); |
|
93 } |
|
94 |
|
95 // ----------------------------------------------------------------------------- |
|
96 // ----------------------------------------------------------------------------- |
|
97 // |
|
98 EXPORT_C void CPosLmLocalDbAccess::CommitTransactionAndPopL() |
|
99 { |
|
100 User::LeaveIfError(CommitTransaction()); |
|
101 |
|
102 CleanupStack::Pop(); // LmDbRollback |
|
103 } |
|
104 |
|
105 // ----------------------------------------------------------------------------- |
|
106 // ----------------------------------------------------------------------------- |
|
107 // |
|
108 EXPORT_C void CPosLmLocalDbAccess::GetDatabase( |
|
109 RDbNamedDatabase& aDatabase) |
|
110 { |
|
111 aDatabase = iDb; |
|
112 } |
|
113 |
|
114 // ----------------------------------------------------------------------------- |
|
115 // ----------------------------------------------------------------------------- |
|
116 // |
|
117 EXPORT_C TInt CPosLmLocalDbAccess::OpenDatabaseL( |
|
118 const TDesC& aUri) |
|
119 { |
|
120 iDb.Close(); |
|
121 iDbSession.Close(); |
|
122 |
|
123 TPtrC dbPath(aUri); |
|
124 PosLmDatabaseUtility::RemoveProtocolFromUriL(dbPath); |
|
125 |
|
126 User::LeaveIfError(iDbSession.Connect()); |
|
127 TInt err = iDb.Open(iDbSession, dbPath, KPosLmDbSecureFormat); |
|
128 |
|
129 if (err == KErrNone) |
|
130 { |
|
131 err = VerifyDatabaseNeedInitializationL(); |
|
132 } |
|
133 else if (err != KErrNotFound && err != KErrPathNotFound && |
|
134 err != KErrArgument && err != KErrAlreadyExists && |
|
135 err != KErrCorrupt && err != KErrNotSupported) |
|
136 { // KErrAlreadyExists if the path includes nonexisting directory. |
|
137 User::Leave(err); |
|
138 } |
|
139 |
|
140 return err; |
|
141 } |
|
142 |
|
143 // ----------------------------------------------------------------------------- |
|
144 // ----------------------------------------------------------------------------- |
|
145 // |
|
146 EXPORT_C TInt CPosLmLocalDbAccess::BeginTransaction() |
|
147 { |
|
148 return iDb.Begin(); |
|
149 } |
|
150 |
|
151 // ----------------------------------------------------------------------------- |
|
152 // ----------------------------------------------------------------------------- |
|
153 // |
|
154 EXPORT_C TInt CPosLmLocalDbAccess::CommitTransaction() |
|
155 { |
|
156 if ( InTransaction() ) |
|
157 { |
|
158 return iDb.Commit(); |
|
159 } |
|
160 return KErrNone; |
|
161 } |
|
162 |
|
163 // ----------------------------------------------------------------------------- |
|
164 // ----------------------------------------------------------------------------- |
|
165 // |
|
166 EXPORT_C void CPosLmLocalDbAccess::RollbackTransaction() |
|
167 { |
|
168 if ( InTransaction() ) |
|
169 { |
|
170 iDb.Rollback(); |
|
171 } |
|
172 } |
|
173 |
|
174 // ----------------------------------------------------------------------------- |
|
175 // ----------------------------------------------------------------------------- |
|
176 // |
|
177 EXPORT_C TBool CPosLmLocalDbAccess::InTransaction() const |
|
178 { |
|
179 return iDb.InTransaction(); |
|
180 } |
|
181 |
|
182 // ----------------------------------------------------------------------------- |
|
183 // ----------------------------------------------------------------------------- |
|
184 // |
|
185 EXPORT_C TUint CPosLmLocalDbAccess::InitFlag() const |
|
186 { |
|
187 return iInit; |
|
188 } |
|
189 |
|
190 // ----------------------------------------------------------------------------- |
|
191 // ----------------------------------------------------------------------------- |
|
192 // |
|
193 EXPORT_C TUint* CPosLmLocalDbAccess::InitFlagPtr() |
|
194 { |
|
195 return &iInit; |
|
196 } |
|
197 |
|
198 // ----------------------------------------------------------------------------- |
|
199 // ----------------------------------------------------------------------------- |
|
200 // |
|
201 EXPORT_C void CPosLmLocalDbAccess::ResetInitFlag() |
|
202 { |
|
203 iInit = ENoInit; |
|
204 } |
|
205 |
|
206 // ----------------------------------------------------------------------------- |
|
207 // ----------------------------------------------------------------------------- |
|
208 // |
|
209 EXPORT_C TBool CPosLmLocalDbAccess::IsDamaged() |
|
210 { |
|
211 return iDb.IsDamaged(); |
|
212 } |
|
213 |
|
214 // ----------------------------------------------------------------------------- |
|
215 // ----------------------------------------------------------------------------- |
|
216 // |
|
217 EXPORT_C void CPosLmLocalDbAccess::ExecuteL( |
|
218 const TDesC& aQuery) |
|
219 { |
|
220 User::LeaveIfError(iDb.Execute(aQuery)); |
|
221 } |
|
222 |
|
223 // ----------------------------------------------------------------------------- |
|
224 // ----------------------------------------------------------------------------- |
|
225 // |
|
226 EXPORT_C void CPosLmLocalDbAccess::PrepareViewLC( |
|
227 TPreparationType aType, |
|
228 RDbView& aView, |
|
229 const TDesC& aSql, |
|
230 TDbTextComparison aComparison) |
|
231 { |
|
232 CleanupClosePushL(aView); |
|
233 |
|
234 switch (aType) |
|
235 { |
|
236 case EAddPreparation: |
|
237 User::LeaveIfError(aView.Prepare(iDb, TDbQuery(aSql, aComparison), |
|
238 TDbWindow::EUnlimited, RDbView::EInsertOnly)); |
|
239 break; |
|
240 default: // EUpdatablePreparation |
|
241 User::LeaveIfError(aView.Prepare(iDb, TDbQuery(aSql, aComparison), |
|
242 TDbWindow::EUnlimited, RDbView::EUpdatable)); |
|
243 User::LeaveIfError(aView.EvaluateAll()); |
|
244 break; |
|
245 } |
|
246 } |
|
247 |
|
248 // ----------------------------------------------------------------------------- |
|
249 // ----------------------------------------------------------------------------- |
|
250 // |
|
251 EXPORT_C CPosLandmarkDatabase::TSize CPosLmLocalDbAccess::SizeL() |
|
252 { |
|
253 CPosLandmarkDatabase::TSize size; |
|
254 |
|
255 User::LeaveIfError(iDb.UpdateStats()); |
|
256 |
|
257 size.iFileSize = iDb.Size().iSize; |
|
258 size.iUsage = TReal32(iDb.Size().iUsage) / 100; |
|
259 |
|
260 return size; |
|
261 } |
|
262 |
|
263 // ----------------------------------------------------------------------------- |
|
264 // ----------------------------------------------------------------------------- |
|
265 // |
|
266 EXPORT_C TInt CPosLmLocalDbAccess::IsInitializeNeededL( TBool& aIsNeeded ) |
|
267 { |
|
268 aIsNeeded = EFalse; |
|
269 return PerformCheckL( ETrue, aIsNeeded ); |
|
270 } |
|
271 |
|
272 // ----------------------------------------------------------------------------- |
|
273 // ----------------------------------------------------------------------------- |
|
274 // |
|
275 EXPORT_C void CPosLmLocalDbAccess::SetInitializeDoneL() |
|
276 { |
|
277 SetFlagL(EFalse, TLanguage()); |
|
278 } |
|
279 |
|
280 // ----------------------------------------------------------------------------- |
|
281 // ----------------------------------------------------------------------------- |
|
282 // |
|
283 EXPORT_C TInt CPosLmLocalDbAccess::IsLanguageChangeNeededL( |
|
284 TBool& aIsNeeded) |
|
285 { |
|
286 return PerformCheckL(EFalse, aIsNeeded); |
|
287 } |
|
288 |
|
289 // ----------------------------------------------------------------------------- |
|
290 // ----------------------------------------------------------------------------- |
|
291 // |
|
292 EXPORT_C void CPosLmLocalDbAccess::SetLanguageL( |
|
293 TLanguage aLanguage) |
|
294 { |
|
295 SetFlagL(ETrue, aLanguage); |
|
296 } |
|
297 |
|
298 // ----------------------------------------------------------------------------- |
|
299 // ----------------------------------------------------------------------------- |
|
300 // |
|
301 EXPORT_C TBool CPosLmLocalDbAccess::IsCompactNeededL() |
|
302 { |
|
303 CPosLandmarkDatabase::TSize size = SizeL(); |
|
304 |
|
305 // For local compact, compact is needed when usage is below the relative |
|
306 // level. |
|
307 // For server compact, compact is needed when the wasted database usage |
|
308 // exceeds the absolute level and usage is below the relative level. |
|
309 return (iLevelType == ELocalCompactLevel && |
|
310 size.iUsage < iRelativeCompactLevel) || |
|
311 (iLevelType == EServerCompactLevel && |
|
312 ((1 - size.iUsage) * size.iFileSize > iAbsoluteCompactLevel) && |
|
313 size.iUsage < iRelativeCompactLevel); |
|
314 } |
|
315 |
|
316 // ----------------------------------------------------------------------------- |
|
317 // ----------------------------------------------------------------------------- |
|
318 // |
|
319 TInt CPosLmLocalDbAccess::VerifyDatabaseNeedInitializationL() |
|
320 { |
|
321 TInt err = KErrNone; |
|
322 |
|
323 if ( iInit != ECreated ) |
|
324 { |
|
325 TBool isNeeded; |
|
326 err = IsInitializeNeededL( isNeeded ); |
|
327 if ( err == KErrNone ) |
|
328 { |
|
329 if ( isNeeded ) |
|
330 { |
|
331 iInit = ECreated; |
|
332 } |
|
333 else |
|
334 { |
|
335 err = IsLanguageChangeNeededL( isNeeded ); |
|
336 |
|
337 if ( err == KErrNone && isNeeded ) |
|
338 { |
|
339 iInit = ELanguage; |
|
340 } |
|
341 |
|
342 if ( IsIndexCreationNeededL() ) |
|
343 { |
|
344 iInit |= EIndexes; |
|
345 } |
|
346 } |
|
347 } |
|
348 } |
|
349 |
|
350 return err; |
|
351 } |
|
352 |
|
353 // ----------------------------------------------------------------------------- |
|
354 // ----------------------------------------------------------------------------- |
|
355 // |
|
356 void CPosLmLocalDbAccess::ReadCompactDbLevelL() |
|
357 { |
|
358 CPosLmResourceReader* resources = |
|
359 CPosLmResourceReader::NewLC(KPosCompactDbLevelResFile); |
|
360 |
|
361 if (iLevelType == ELocalCompactLevel) |
|
362 { |
|
363 iRelativeCompactLevel = TReal32(resources->ReadInt32L( |
|
364 R_POS_LM_LOCAL_COMPACT_DB_USAGE_LEVEL)) / 100; |
|
365 } |
|
366 else |
|
367 { |
|
368 iRelativeCompactLevel = TReal32(resources->ReadInt32L( |
|
369 R_POS_LM_SERVER_COMPACT_RELATIVE_DB_USAGE_LEVEL)) / 100; |
|
370 iAbsoluteCompactLevel = resources->ReadInt32L( |
|
371 R_POS_LM_SERVER_COMPACT_ABSOLUTE_WASTED_DB_USAGE_LEVEL) * 1000; |
|
372 } |
|
373 |
|
374 CleanupStack::PopAndDestroy(resources); |
|
375 } |
|
376 |
|
377 // ----------------------------------------------------------------------------- |
|
378 // ----------------------------------------------------------------------------- |
|
379 // |
|
380 TInt CPosLmLocalDbAccess::PerformCheckL( TBool aIsInitCheck, TBool& aIsNeeded ) |
|
381 { |
|
382 HBufC* sql = HBufC::NewLC( KPosLmSqlStatementMaxLen ); |
|
383 sql->Des().Format( KPosLmSqlSelect, &KPosLmSqlAll, &KPosLmSettingsTable ); |
|
384 |
|
385 RDbView view; |
|
386 CleanupClosePushL( view ); |
|
387 |
|
388 TInt err = view.Prepare( iDb, TDbQuery( *sql ), TDbWindow::EUnlimited ); |
|
389 |
|
390 if (err == KErrNotFound) |
|
391 { |
|
392 // Database is corrupt, because the settings table cannot be found. |
|
393 err = KErrCorrupt; |
|
394 } |
|
395 else |
|
396 { |
|
397 User::LeaveIfError( err ); |
|
398 User::LeaveIfError( view.EvaluateAll() ); |
|
399 |
|
400 view.FirstL(); |
|
401 if ( view.AtEnd() ) |
|
402 { |
|
403 // no records in settings - init is needed |
|
404 aIsNeeded = ETrue; |
|
405 } |
|
406 else |
|
407 { |
|
408 view.GetL(); |
|
409 |
|
410 if ( aIsInitCheck ) |
|
411 { |
|
412 // does this database |
|
413 aIsNeeded = ( view.ColInt32( EPosLmScInitFlagCol ) != ECreated ); |
|
414 } |
|
415 else |
|
416 { |
|
417 aIsNeeded = |
|
418 ( User::Language() != view.ColInt32( EPosLmScLanguageCol ) ); |
|
419 } |
|
420 } |
|
421 } |
|
422 |
|
423 CleanupStack::PopAndDestroy( &view ); |
|
424 CleanupStack::PopAndDestroy( sql ); |
|
425 |
|
426 return err; |
|
427 } |
|
428 |
|
429 // ----------------------------------------------------------------------------- |
|
430 // ----------------------------------------------------------------------------- |
|
431 // |
|
432 void CPosLmLocalDbAccess::SetFlagL( |
|
433 TBool aSetLanguage, |
|
434 TLanguage aLanguage) |
|
435 { |
|
436 HBufC* sql = HBufC::NewLC(KPosLmSqlStatementMaxLen); |
|
437 sql->Des().Format(KPosLmSqlSelect, &KPosLmSqlAll, &KPosLmSettingsTable); |
|
438 |
|
439 RDbView view; |
|
440 PrepareViewLC(EUpdatablePreparation, view, *sql); |
|
441 |
|
442 if (view.NextL()) |
|
443 { |
|
444 view.UpdateL(); |
|
445 } |
|
446 else |
|
447 { |
|
448 view.InsertL(); |
|
449 } |
|
450 |
|
451 if (!aSetLanguage) |
|
452 { |
|
453 // Set initialized flag |
|
454 view.SetColL(EPosLmScInitFlagCol, (TInt)ECreated); |
|
455 } |
|
456 else |
|
457 { |
|
458 // Set language switched flag |
|
459 view.SetColL(EPosLmScLanguageCol, (TInt)aLanguage); |
|
460 } |
|
461 |
|
462 view.PutL(); |
|
463 |
|
464 CleanupStack::PopAndDestroy(2, sql); //&view |
|
465 } |
|
466 |
|
467 // ----------------------------------------------------------------------------- |
|
468 // Some databases may be missing several indexes, which were added in later versions |
|
469 // of this component. Those a verified and if not found, initialization is requested. |
|
470 // Added indexes: |
|
471 // Index on landmark ID in landmark-field table |
|
472 // Index on landmark ID in landmark-category table |
|
473 // ----------------------------------------------------------------------------- |
|
474 // |
|
475 EXPORT_C TBool CPosLmLocalDbAccess::IsIndexCreationNeededL() const |
|
476 { |
|
477 // category table |
|
478 if ( !IndexExistsL( KPosLmLandmarkFieldTable, KPosLmFieldsLmIdIndex ) ) |
|
479 { |
|
480 return ETrue; |
|
481 } |
|
482 |
|
483 // landmark-category table |
|
484 if ( !IndexExistsL( KPosLmLandmarkCategoryTable, KPosLmCategoryLmIdIndex ) ) |
|
485 { |
|
486 return ETrue; |
|
487 } |
|
488 |
|
489 return EFalse; |
|
490 } |
|
491 |
|
492 // ----------------------------------------------------------------------------- |
|
493 // ----------------------------------------------------------------------------- |
|
494 // |
|
495 TBool CPosLmLocalDbAccess::IndexExistsL( const TDesC& aTable, const TDesC& aIndex ) const |
|
496 { |
|
497 return PosLmDatabaseUtility::IndexExistsL( iDb, aTable, aIndex ); |
|
498 } |
|
499 |