|
1 /* |
|
2 * Copyright (c) 2007-2009 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 the License "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: |
|
15 * Implements the UPS database handle manager. See class and function |
|
16 * definitions for more information. |
|
17 * |
|
18 */ |
|
19 |
|
20 |
|
21 /** |
|
22 @file |
|
23 */ |
|
24 #include <f32file.h> |
|
25 #include "upscommon.h" |
|
26 #include <ups/upsdbw.h> |
|
27 #include "upsdbmanager.h" |
|
28 |
|
29 namespace UserPromptService |
|
30 { |
|
31 |
|
32 RUpsDbHandleMaster::RUpsDbHandleMaster(RFs &aFs) |
|
33 /** |
|
34 Construct the handle master |
|
35 |
|
36 This class should be used for synchronous database operations. |
|
37 |
|
38 If you need to do asynchronous operations then create/use an instance of the RUpsDbHandleSlave |
|
39 linked to the master. |
|
40 |
|
41 If your database operation fails, particularly due to OOM, then you should call Close your handle. You probably |
|
42 do NOT need to explicitly re-open it - it will automatically re-open when the -> operator is used. |
|
43 |
|
44 Note that the -> operator may leave. |
|
45 */ |
|
46 : iFs(aFs), iDatabase(0), iClientListHead(0) |
|
47 { |
|
48 } |
|
49 |
|
50 RUpsDbHandleMaster::~RUpsDbHandleMaster() |
|
51 /** |
|
52 Destroy the handle master |
|
53 */ |
|
54 { |
|
55 ASSERT(iClientListHead == 0); // Should be no clients!!!! |
|
56 Close(); // Deletes iDatabase... |
|
57 iClientListHead = 0; |
|
58 // Do NOT close the iFs (it is a reference to the main server's handle). |
|
59 } |
|
60 |
|
61 _LIT(KDatabaseFile,"?:\\private\\10283558\\database\\ups.db"); |
|
62 void RUpsDbHandleMaster::OpenL() |
|
63 /** |
|
64 Open the database handle |
|
65 |
|
66 It is probably clearer to explictly call this function to open the handle before first use, but the -> operator will |
|
67 auto-open it if called on a closed handle. Note that the -> operator can leave. |
|
68 |
|
69 If any database operation fails, particularly due to OOM, then you should Close your handle. Instead of |
|
70 immediately re-opening it, it is generally safer to let it auto-reopen when the -> operator is next called. |
|
71 |
|
72 */ |
|
73 { |
|
74 BULLSEYE_OFF |
|
75 if(iDatabase != 0) |
|
76 { |
|
77 // Close/delete the existing database handle. |
|
78 Close(); |
|
79 } |
|
80 BULLSEYE_RESTORE |
|
81 |
|
82 // Open up a new handle. |
|
83 TFileName databaseFileBuf = KDatabaseFile(); |
|
84 |
|
85 databaseFileBuf[0] = iFs.GetSystemDriveChar(); |
|
86 TParsePtrC databaseFile(databaseFileBuf); |
|
87 |
|
88 // Make sure the dir exists |
|
89 (void)iFs.MkDirAll(databaseFile.DriveAndPath()); |
|
90 // Create/Open the database |
|
91 iDatabase = CDecisionDbW::NewL(databaseFile.FullName(), iFs); |
|
92 } |
|
93 |
|
94 void RUpsDbHandleMaster::Close() |
|
95 /** |
|
96 Notify all client handles that the master (real) database handle is about to be closed, and then close it. |
|
97 */ |
|
98 { |
|
99 // Notify all registered clients that we are about to delete the database handle |
|
100 RUpsDbHandleSlave *p = iClientListHead; |
|
101 while(p) |
|
102 { |
|
103 ASSERT(p->iClient != 0); |
|
104 p->iClient->DbHandleAboutToBeDeleted(); |
|
105 p = p->iClientListNext; |
|
106 } |
|
107 |
|
108 // Delete database handle |
|
109 delete iDatabase; |
|
110 iDatabase = 0; |
|
111 } |
|
112 |
|
113 TBool RUpsDbHandleMaster::IsOpen() const |
|
114 /** |
|
115 Returns true if the handle is already open. |
|
116 */ |
|
117 { |
|
118 return iDatabase != 0; |
|
119 } |
|
120 |
|
121 CDecisionDbW *RUpsDbHandleMaster::operator->() |
|
122 /** |
|
123 Returns the database handle so -> can be used on an RUpsDbHandleMaster instance to call database functions |
|
124 |
|
125 If the database is not already open then it calls OpenL. |
|
126 |
|
127 This operator CAN leave. |
|
128 */ |
|
129 { |
|
130 if(iDatabase == 0) |
|
131 { |
|
132 OpenL(); |
|
133 } |
|
134 return iDatabase; |
|
135 } |
|
136 |
|
137 void RUpsDbHandleMaster::Register(RUpsDbHandleSlave *aClient) |
|
138 /** |
|
139 Register new client with us. |
|
140 */ |
|
141 { |
|
142 BULLSEYE_OFF |
|
143 if(aClient == 0) |
|
144 { |
|
145 return; |
|
146 } |
|
147 BULLSEYE_RESTORE |
|
148 |
|
149 aClient->iClientListNext = iClientListHead; |
|
150 iClientListHead = aClient; |
|
151 } |
|
152 |
|
153 void RUpsDbHandleMaster::UnRegister(RUpsDbHandleSlave *aClient) |
|
154 /** |
|
155 UnRegister client with us. |
|
156 */ |
|
157 { |
|
158 RUpsDbHandleSlave **pp = &iClientListHead; |
|
159 BULLSEYE_OFF |
|
160 while(*pp) |
|
161 { |
|
162 BULLSEYE_RESTORE |
|
163 if(*pp == aClient) |
|
164 { |
|
165 // Found ptr to client, so remove it. |
|
166 *pp = (*pp)->iClientListNext; |
|
167 aClient->iClientListNext = 0; |
|
168 break; |
|
169 } |
|
170 pp = &(*pp)->iClientListNext; |
|
171 } |
|
172 } |
|
173 |
|
174 |
|
175 |
|
176 RUpsDbHandleSlave::RUpsDbHandleSlave(RUpsDbHandleMaster & aMaster, MDbHandleClient * aClient) |
|
177 /** |
|
178 Initialise new client and register it with the RUpsDbHandleMaster |
|
179 |
|
180 This class is intended for use when asynchronous database operations are being performed. These may then be failed |
|
181 due to another database operation failing, BUT the asycnhronous operation classes (eg. a db view) needs deleting |
|
182 before the actual database handle is deleted/re-created. |
|
183 */ |
|
184 : iInUse(EFalse), iMaster(aMaster), iClient(aClient), iClientListNext(0) |
|
185 { |
|
186 ASSERT(aClient != 0); |
|
187 //RDebug::Printf("RUpsDbHandleSlave(%x, %x) - %x\n", &aMaster, aClient, this); |
|
188 } |
|
189 |
|
190 RUpsDbHandleSlave::~RUpsDbHandleSlave() |
|
191 { |
|
192 //RDebug::Printf("~RUpsDbHandleSlave() master %x client %x - %x\n", &iMaster, iClient, this); |
|
193 Close(); |
|
194 } |
|
195 |
|
196 CDecisionDbW *RUpsDbHandleSlave::operator->() |
|
197 /** |
|
198 Returns the database handle so -> can be used on an RUpsDbHandleMaster instance to call database functions |
|
199 |
|
200 If the database is not already open, then the master will open it. |
|
201 |
|
202 This operator CAN leave. |
|
203 */ |
|
204 { |
|
205 if(!iInUse) |
|
206 { |
|
207 iMaster.Register(this); |
|
208 iInUse = ETrue; |
|
209 } |
|
210 return iMaster.operator->(); |
|
211 } |
|
212 |
|
213 void RUpsDbHandleSlave::SetCallback(MDbHandleClient *aClient) |
|
214 /** |
|
215 Change what callback should be run if the master handle is closed. |
|
216 Do NOT set it to 0. |
|
217 */ |
|
218 { |
|
219 ASSERT(aClient != 0); |
|
220 //RDebug::Printf("RUpsDbHandleSlave::SetCallback client %x - %x\n", aClient, this); |
|
221 iClient = aClient; |
|
222 } |
|
223 |
|
224 void RUpsDbHandleSlave::Close() |
|
225 /** |
|
226 Close this slave handle. This does NOT close the master, it just means we de-register with the |
|
227 master to we are no longer notified if the master is closed. |
|
228 It will automatically re-register if the -> operator is subsequently used. |
|
229 */ |
|
230 { |
|
231 if(iInUse) |
|
232 { |
|
233 iMaster.UnRegister(this); |
|
234 iInUse = 0; |
|
235 } |
|
236 } |
|
237 |
|
238 void RUpsDbHandleSlave::CloseMaster() |
|
239 /** |
|
240 Notify all client handles that the master (real) database handle is about to be closed, and then close it. |
|
241 |
|
242 Typically used after a database error (particularly OOM) in an attempt to recover. Usually the database is not |
|
243 explicitly re-opened, instead the re-open is defered until the next use of the -> operator on either tha master |
|
244 or a client handle. |
|
245 */ |
|
246 { |
|
247 Close(); |
|
248 iMaster.Close(); |
|
249 } |
|
250 |
|
251 |
|
252 } // End of UserPromptService namespace |
|
253 |
|
254 // End of file |