|
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: This contains basis for the implementation of the database. |
|
15 * |
|
16 * Constructs instances of database subclasses CCbsDbImpSettings, |
|
17 * CCbsDbImpTopicCollection, CCbsDbTopicList and CCbsDbTopicMessages. |
|
18 * On initialization determines whether datafiles already exist. |
|
19 * If all of them are present and valid, no special action is taken. |
|
20 * |
|
21 * If some or all datafiles are missing or corrupt, all datafiles |
|
22 * are deleted and new files created. |
|
23 * Factory default settings, if available, are then loaded from |
|
24 * Shared Data and stored in server datafiles. This is done by |
|
25 * database subinstances. |
|
26 * |
|
27 */ |
|
28 |
|
29 |
|
30 // INCLUDE FILES |
|
31 |
|
32 #include <barsc.h> |
|
33 #include <e32svr.h> |
|
34 #include <bautils.h> |
|
35 |
|
36 #include <CbsServer.rsg> |
|
37 |
|
38 #include "CbsUtils.h" |
|
39 #include "CbsServerPanic.h" |
|
40 #include "CCbsDbImp.H" |
|
41 #include "CbsDbConstants.h" |
|
42 #include "CCbsDbImpSettings.H" |
|
43 #include "CCbsDbImpTopicMessages.h" |
|
44 #include "CCbsDbImpTopicList.h" |
|
45 #include "CCbsDbImpTopicCollection.h" |
|
46 #include "CCbsBackupMonitor.h" |
|
47 #include "CCbsDiskSpaceMonitor.h" |
|
48 |
|
49 #include "CbsLogger.h" |
|
50 |
|
51 // Data file names |
|
52 _LIT( KCbsTopicsAndMsgsFileName, "cbtopicsmsgs.dat" ); |
|
53 _LIT( KCbsUnsavedMsgsFileName, "cbunsaved.dat" ); |
|
54 |
|
55 // ================= MEMBER FUNCTIONS ======================= |
|
56 |
|
57 // ----------------------------------------------------------------------------- |
|
58 // CCbsDbImp::CCbsDbImp |
|
59 // C++ default constructor can NOT contain any code, that |
|
60 // might leave. |
|
61 // ----------------------------------------------------------------------------- |
|
62 // |
|
63 CCbsDbImp::CCbsDbImp() |
|
64 { |
|
65 } |
|
66 |
|
67 // ----------------------------------------------------------------------------- |
|
68 // CCbsDbImp::ConstructL |
|
69 // Symbian 2nd phase constructor can leave. |
|
70 // ----------------------------------------------------------------------------- |
|
71 // |
|
72 void CCbsDbImp::ConstructL() |
|
73 { |
|
74 User::LeaveIfError( iFs.Connect() ); |
|
75 |
|
76 // Create the disk space monitor |
|
77 iDiskSpaceMonitor = CCbsDiskSpaceMonitor::NewL( *this ); |
|
78 |
|
79 TInt errorCode( KErrNone ); |
|
80 |
|
81 #ifdef __SECURE_BACKUP__ |
|
82 // Use PubSub for monitoring |
|
83 iBackupMonitor = CCbsBackupMonitor::NewL( *this ); |
|
84 #else |
|
85 // Create a backup observer wrapper. If an error is returned, |
|
86 // ignore it and leave iBackupWrapper to NULL. |
|
87 TRAP( errorCode, ( iBackupWrapper = CBaBackupSessionWrapper::NewL() ) ); |
|
88 #endif |
|
89 |
|
90 // Try to create the database components. If we couldn't because |
|
91 // the disk is almost full, that's alright. We'll try again |
|
92 // later. |
|
93 TRAP( errorCode, CreateComponentsL() ); |
|
94 if ( errorCode == KErrDiskFull ) |
|
95 { |
|
96 // Install an observer for the critical level |
|
97 WaitForCriticalLevel(); |
|
98 } |
|
99 else |
|
100 { |
|
101 User::LeaveIfError( errorCode ); |
|
102 } |
|
103 } |
|
104 |
|
105 // ----------------------------------------------------------------------------- |
|
106 // CCbsDbImp::NewL |
|
107 // Two-phased constructor. |
|
108 // ----------------------------------------------------------------------------- |
|
109 // |
|
110 CCbsDbImp* CCbsDbImp::NewL() |
|
111 { |
|
112 CCbsDbImp* self = new ( ELeave ) CCbsDbImp; |
|
113 CleanupStack::PushL( self ); |
|
114 self->ConstructL(); |
|
115 CleanupStack::Pop(); |
|
116 return self; |
|
117 } |
|
118 |
|
119 // Destructor |
|
120 CCbsDbImp::~CCbsDbImp() |
|
121 { |
|
122 CBSLOGSTRING("CBSSERVER: >>> CCbsDbImp::~CCbsDbImp()"); |
|
123 if ( iDiskSpaceMonitor ) |
|
124 { |
|
125 delete iDiskSpaceMonitor; |
|
126 } |
|
127 |
|
128 DeleteComponents(); |
|
129 |
|
130 iFs.Close(); |
|
131 CBSLOGSTRING("CBSSERVER: <<< CCbsDbImp::~CCbsDbImp()"); |
|
132 } |
|
133 |
|
134 // ----------------------------------------------------------------------------- |
|
135 // CCbsDbImp::TopicListL |
|
136 // Returns a reference to the current active topic list. |
|
137 // (other items were commented in a header). |
|
138 // ----------------------------------------------------------------------------- |
|
139 // |
|
140 CCbsDbImpTopicList& CCbsDbImp::TopicListL() |
|
141 { |
|
142 // Check if we have initialized the database succesfully |
|
143 if ( !iTopicList ) |
|
144 { |
|
145 User::Leave( KErrDiskFull ); |
|
146 } |
|
147 |
|
148 return *iTopicList; |
|
149 } |
|
150 |
|
151 // ----------------------------------------------------------------------------- |
|
152 // CCbsDbImp::TopicMessagesL |
|
153 // Returns a reference to the current topic messages DB object. |
|
154 // (other items were commented in a header). |
|
155 // ----------------------------------------------------------------------------- |
|
156 // |
|
157 CCbsDbImpTopicMessages& CCbsDbImp::TopicMessagesL() |
|
158 { |
|
159 CBSLOGSTRING("CBSSERVER: >>> CCbsDbImp::TopicMessagesL()"); |
|
160 |
|
161 // Check if we have initialized the database succesfully |
|
162 if ( !iTopicMessages ) |
|
163 { |
|
164 CBSLOGSTRING("CBSSERVER: CCbsDbImp::TopicMessagesL(): No iTopicMessages instance, leaving with KErrDiskFull..."); |
|
165 User::Leave( KErrDiskFull ); |
|
166 } |
|
167 |
|
168 CBSLOGSTRING("CBSSERVER: <<< CCbsDbImp::TopicMessagesL(), returning *iTopicMessages."); |
|
169 return *iTopicMessages; |
|
170 } |
|
171 |
|
172 // ----------------------------------------------------------------------------- |
|
173 // CCbsDbImp::SettingsL |
|
174 // Returns a reference to the settings DB object. |
|
175 // (other items were commented in a header). |
|
176 // ----------------------------------------------------------------------------- |
|
177 // |
|
178 CCbsDbImpSettings& CCbsDbImp::SettingsL() |
|
179 { |
|
180 // Check if we have initialized the database succesfully |
|
181 if ( !iSettings ) |
|
182 { |
|
183 User::Leave( KErrDiskFull ); |
|
184 } |
|
185 |
|
186 return *iSettings; |
|
187 } |
|
188 |
|
189 // ----------------------------------------------------------------------------- |
|
190 // CCbsDbImp::TopicCollectionL |
|
191 // Returns a reference to the topic collection. |
|
192 // (other items were commented in a header). |
|
193 // ----------------------------------------------------------------------------- |
|
194 // |
|
195 CCbsDbImpTopicCollection& CCbsDbImp::TopicCollectionL() |
|
196 { |
|
197 // Check if we have initialized the database succesfully |
|
198 if ( !iTopicCollection ) |
|
199 { |
|
200 User::Leave( KErrDiskFull ); |
|
201 } |
|
202 |
|
203 return *iTopicCollection; |
|
204 } |
|
205 |
|
206 // ----------------------------------------------------------------------------- |
|
207 // CCbsDbImp::BackupWrapperL |
|
208 // Returns a reference to the backup wrapper. |
|
209 // (other items were commented in a header). |
|
210 // ----------------------------------------------------------------------------- |
|
211 // |
|
212 CBaBackupSessionWrapper& CCbsDbImp::BackupWrapperL() |
|
213 { |
|
214 if ( !iBackupWrapper ) |
|
215 { |
|
216 User::Leave( KErrGeneral ); |
|
217 } |
|
218 |
|
219 return *iBackupWrapper; |
|
220 } |
|
221 |
|
222 // --------------------------------------------------------- |
|
223 // IsInitialized() |
|
224 // |
|
225 // --------------------------------------------------------- |
|
226 TBool CCbsDbImp::IsInitialized() const |
|
227 { |
|
228 return iSettings != NULL; |
|
229 } |
|
230 |
|
231 // ----------------------------------------------------------------------------- |
|
232 // CCbsDbImp::CreateComponentsL |
|
233 // Creates topic list, settings topic messages and topic |
|
234 // collection instances and loads factory settings if necessary. |
|
235 // (other items were commented in a header). |
|
236 // ----------------------------------------------------------------------------- |
|
237 // |
|
238 void CCbsDbImp::CreateComponentsL() |
|
239 { |
|
240 CBSLOGSTRING("CBSSERVER: >>> CCbsDbImp::CreateComponentsL()"); |
|
241 |
|
242 // Return if we have already been initialized |
|
243 if ( IsInitialized() ) |
|
244 { |
|
245 return; |
|
246 } |
|
247 |
|
248 TBuf<16> topicsFile( KCbsTopicsAndMsgsFileName ); |
|
249 TBuf<16> messagesFile( KCbsUnsavedMsgsFileName ); |
|
250 |
|
251 // Delete the old file for unsaved messages |
|
252 CbsUtils::DeleteFileL( iFs, messagesFile ); |
|
253 CBSLOGSTRING("CBSSERVER: CCbsDbImp::CreateComponentsL(): messagesFile deleted."); |
|
254 |
|
255 // Make sure that data file paths exist. |
|
256 iFs.MkDirAll( topicsFile ); |
|
257 iFs.MkDirAll( messagesFile ); |
|
258 |
|
259 // Create the individual components. If creating any of the components |
|
260 // fails, this method leaves and created components are deleted. |
|
261 CCbsDbImpSettings* settings = CreateSettingsL(); |
|
262 CleanupStack::PushL( settings ); |
|
263 |
|
264 CCbsDbImpTopicList* topicList = CreateTopicListL( topicsFile, messagesFile ); |
|
265 CleanupStack::PushL( topicList ); |
|
266 |
|
267 CCbsDbImpTopicMessages* topicMessages = CreateTopicMessagesL( *topicList ); |
|
268 CleanupStack::PushL( topicMessages ); |
|
269 |
|
270 CCbsDbImpTopicCollection* topicCollection = CreateTopicCollectionL(); |
|
271 CleanupStack::PushL( topicCollection ); |
|
272 |
|
273 |
|
274 #ifndef __SECURE_BACKUP__ |
|
275 |
|
276 CBSLOGSTRING("CBSSERVER: CCbsDbImp::CreateComponentsL(): __SECURE_BACKUP__ not defined."); |
|
277 |
|
278 // Register the file to backup server |
|
279 if ( iBackupWrapper ) |
|
280 { |
|
281 iBackupWrapper->RegisterFileL( *topicsFile, *topicList ); |
|
282 } |
|
283 #endif |
|
284 |
|
285 // We have succesfully created all components. Set them to member |
|
286 // variables. |
|
287 iTopicList = topicList; |
|
288 iSettings = settings; |
|
289 iTopicMessages = topicMessages; |
|
290 iTopicCollection = topicCollection; |
|
291 |
|
292 // Does not transfer ownership. |
|
293 iTopicList->SetTopicMessages( iTopicMessages ); |
|
294 |
|
295 // If we could create the database, cancel the disk space notify request |
|
296 WaitForCriticalLevelCancel(); |
|
297 |
|
298 // The database components are preserved, but the resource reader and |
|
299 // related buffers are deleted. |
|
300 CleanupStack::Pop( 4 ); // topicMessages, settings, topicList, topicCollection |
|
301 |
|
302 CBSLOGSTRING("CBSSERVER: <<< CCbsDbImp::CreateComponentsL()"); |
|
303 } |
|
304 |
|
305 // --------------------------------------------------------- |
|
306 // DeleteComponents() |
|
307 // |
|
308 // --------------------------------------------------------- |
|
309 void CCbsDbImp::DeleteComponents() |
|
310 { |
|
311 delete iTopicMessages; |
|
312 iTopicMessages = NULL; |
|
313 |
|
314 delete iTopicCollection; |
|
315 iTopicCollection = NULL; |
|
316 |
|
317 #ifdef __SECURE_BACKUP__ |
|
318 |
|
319 #else |
|
320 // Delete owned objects and deregister files from |
|
321 // backup server. |
|
322 if ( iBackupWrapper && iSettings ) |
|
323 { |
|
324 //iBackupWrapper->DeregisterFile( iSettings->FileName() ); |
|
325 } |
|
326 |
|
327 if ( iBackupWrapper && iTopicList ) |
|
328 { |
|
329 //iBackupWrapper->DeregisterFile( iTopicList->TopicFilename() ); |
|
330 } |
|
331 #endif |
|
332 |
|
333 delete iSettings; |
|
334 iSettings = NULL; |
|
335 |
|
336 delete iTopicList; |
|
337 iTopicList = NULL; |
|
338 |
|
339 #ifdef __SECURE_BACKUP__ |
|
340 delete iBackupMonitor; |
|
341 iBackupMonitor = NULL; |
|
342 #else |
|
343 delete iBackupWrapper; |
|
344 iBackupWrapper = NULL; |
|
345 #endif |
|
346 } |
|
347 |
|
348 // --------------------------------------------------------- |
|
349 // CreateSettingsL() |
|
350 // |
|
351 // --------------------------------------------------------- |
|
352 CCbsDbImpSettings* CCbsDbImp::CreateSettingsL() |
|
353 { |
|
354 CCbsDbImpSettings* settings = NULL; |
|
355 TRAPD( err, ( settings = CCbsDbImpSettings::NewL( *this ) ) ); |
|
356 User::LeaveIfError( err ); |
|
357 return settings; |
|
358 } |
|
359 |
|
360 // --------------------------------------------------------- |
|
361 // CreateTopicListL() |
|
362 // |
|
363 // --------------------------------------------------------- |
|
364 CCbsDbImpTopicList* CCbsDbImp::CreateTopicListL( |
|
365 const TDesC& aTopicsFile, |
|
366 const TDesC& aMessagesFile ) |
|
367 { |
|
368 // Try to create the topic list. |
|
369 CCbsDbImpTopicList* topicList = NULL; |
|
370 TRAPD( err, ( topicList = CCbsDbImpTopicList::NewL( |
|
371 iFs, aTopicsFile, aMessagesFile, *this ) ) ); |
|
372 |
|
373 // Handle data file corruption here. |
|
374 switch ( err ) |
|
375 { |
|
376 case KErrNone: |
|
377 break; |
|
378 |
|
379 case KErrCorrupt: |
|
380 case KErrEof: |
|
381 // The data file was corrupt. Delete it and try again. |
|
382 CbsUtils::DeleteFileL( iFs, aTopicsFile ); |
|
383 CbsUtils::DeleteFileL( iFs, aMessagesFile ); |
|
384 topicList = CCbsDbImpTopicList::NewL( |
|
385 iFs, aTopicsFile, aMessagesFile, *this ); |
|
386 break; |
|
387 |
|
388 default: |
|
389 User::Leave( err ); |
|
390 break; |
|
391 } |
|
392 |
|
393 return topicList; |
|
394 } |
|
395 |
|
396 // --------------------------------------------------------- |
|
397 // CreateTopicMessagesL() |
|
398 // |
|
399 // --------------------------------------------------------- |
|
400 CCbsDbImpTopicMessages* CCbsDbImp::CreateTopicMessagesL( |
|
401 CCbsDbImpTopicList& aTopicList ) |
|
402 { |
|
403 // This cannot leave because of data file corruption. |
|
404 return CCbsDbImpTopicMessages::NewL( aTopicList, iFs ); |
|
405 } |
|
406 |
|
407 |
|
408 // --------------------------------------------------------- |
|
409 // CreateTopicCollectionL() |
|
410 // |
|
411 // --------------------------------------------------------- |
|
412 CCbsDbImpTopicCollection* CCbsDbImp::CreateTopicCollectionL() |
|
413 { |
|
414 // This does not create a data file. |
|
415 return CCbsDbImpTopicCollection::NewL(); |
|
416 } |
|
417 |
|
418 // --------------------------------------------------------- |
|
419 // WaitForCriticalLevelL() |
|
420 // |
|
421 // --------------------------------------------------------- |
|
422 void CCbsDbImp::WaitForCriticalLevel() |
|
423 { |
|
424 // We are running low on disk space. Ask for a notification |
|
425 // when there is space again. |
|
426 iDiskSpaceMonitor->IssueRequest(); |
|
427 } |
|
428 |
|
429 |
|
430 // --------------------------------------------------------- |
|
431 // WaitForCriticalLevelCancel() |
|
432 // |
|
433 // --------------------------------------------------------- |
|
434 void CCbsDbImp::WaitForCriticalLevelCancel() |
|
435 { |
|
436 // Cancel the notification for critical level |
|
437 iDiskSpaceMonitor->Cancel(); |
|
438 } |
|
439 |
|
440 // --------------------------------------------------------- |
|
441 // ChangeFileLocksL() |
|
442 // |
|
443 // Releases all files for backup/restore, or takes the |
|
444 // files into use again. |
|
445 // --------------------------------------------------------- |
|
446 |
|
447 void CCbsDbImp::ChangeFileLocksL( const TCbsBackupRequest& aRequest ) |
|
448 { |
|
449 CBSLOGSTRING("CBSSERVER: >>> CCbsDbImp::ChangeFileLocksL()"); |
|
450 |
|
451 // Check/change the topiclist/topics/saved messages file |
|
452 iTopicList->ChangeFileLockL( aRequest ); |
|
453 |
|
454 CBSLOGSTRING("CBSSERVER: <<< CCbsDbImp::ChangeFileLocksL()"); |
|
455 } |
|
456 |
|
457 // ================= OTHER EXPORTED FUNCTIONS ============== |
|
458 |
|
459 // End of File |