|
1 // Copyright (c) 2006-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 #include <mtp/cmtptypearray.h> |
|
17 #include <mtp/mtpdatatypeconstants.h> |
|
18 #include <mtp/mtpprotocolconstants.h> |
|
19 #include <mtp/mtptypessimple.h> |
|
20 |
|
21 #include "cmtpobjectstore.h" |
|
22 #include "cmtpreferencemgr.h" |
|
23 #include "dbutility.h" |
|
24 |
|
25 |
|
26 _LIT(KSQLReferenceTableName, "ReferenceStore"); |
|
27 _LIT(KSQLReferenceIndexName, "ReferenceIndex"); |
|
28 _LIT(KSQLCreateReferenceTableText,"CREATE TABLE ReferenceStore (HandleId UNSIGNED INTEGER, References LONG VARBINARY)"); |
|
29 _LIT(KSQLCreateReferenceIndexText,"CREATE UNIQUE INDEX ReferenceIndex on ReferenceStore (HandleId)"); |
|
30 |
|
31 |
|
32 static const TInt KMTPReferenceGranularity = 5; |
|
33 // Maximum value to use for granularity |
|
34 // This will result in 4KB of memory used (1024 * 4bytes) for reference SUID array |
|
35 static const TInt KMTPMaxGranularity = 1024; |
|
36 |
|
37 /** |
|
38 Two phase construction |
|
39 @param aObjectMgr Reference to the object manager |
|
40 @return a pointer to the reference manager instance |
|
41 */ |
|
42 CMTPReferenceMgr* CMTPReferenceMgr::NewL(CMTPObjectStore& aObjectStore) |
|
43 { |
|
44 CMTPReferenceMgr* self = new (ELeave) CMTPReferenceMgr(aObjectStore); |
|
45 CleanupStack::PushL(self); |
|
46 self->ConstructL(); |
|
47 CleanupStack::Pop(self); |
|
48 return self; |
|
49 } |
|
50 |
|
51 /** |
|
52 Destructor |
|
53 */ |
|
54 CMTPReferenceMgr::~CMTPReferenceMgr() |
|
55 { |
|
56 iBatched.Close(); |
|
57 } |
|
58 |
|
59 /** |
|
60 Provides an MTP array of the target object handles which are referenced |
|
61 by the specified source object handle. A pointer to the MTP array is |
|
62 placed on the cleanup stack. |
|
63 @param aFromHandle The MTP object handle of the source object from which |
|
64 the references originate. |
|
65 @return The MTP reference target object handle array. Ownership IS transferred. |
|
66 @leave One of the system wide error codes, if a processing failure occurs. |
|
67 */ |
|
68 CMTPTypeArray* CMTPReferenceMgr::ReferencesLC(const TMTPTypeUint32& aFromHandle) const |
|
69 { |
|
70 return GetReferencesLC(aFromHandle.Value()); |
|
71 } |
|
72 |
|
73 /** |
|
74 Provides an SUID array of the target object SUIDs which are referenced by |
|
75 the specified source object SUID. A pointer to the SUID array is |
|
76 placed on the cleanup stack. |
|
77 @param aFromSuid The SUID of the source object from which the references |
|
78 originate. |
|
79 @return The reference target object SUID array. Ownership IS transferred. |
|
80 @leave One of the system wide error codes, if a processing failure occurs. |
|
81 */ |
|
82 CDesCArray* CMTPReferenceMgr::ReferencesLC(const TDesC& aParentSuid) const |
|
83 { |
|
84 TUint32 handle = iObjectStore.HandleL(aParentSuid); |
|
85 return GetReferencesInDesLC(handle); |
|
86 } |
|
87 |
|
88 /** |
|
89 Removes all object reference links in which the specified SUID represents |
|
90 either the source or target reference object. |
|
91 @param aSuid The object SUID. |
|
92 @leave One of the system wide error codes, if a processing failure occurs. |
|
93 */ |
|
94 void CMTPReferenceMgr::RemoveReferencesL(const TDesC& aSuid) |
|
95 { |
|
96 TUint32 handle = iObjectStore.HandleL(aSuid); |
|
97 RemoveReferencesL(handle); |
|
98 } |
|
99 |
|
100 /** |
|
101 Creates an abstract reference linkage between the specified source and |
|
102 target object SUIDs. |
|
103 @param aFromSuid The SUID of the source object from which the reference |
|
104 originates. |
|
105 param aToSuid The SUID of the target object to which the reference is |
|
106 made. |
|
107 @leave One of the system wide error codes, if a processing failure occurs. |
|
108 */ |
|
109 void CMTPReferenceMgr::SetReferenceL(const TDesC& aFromSuid, const TDesC& aToSuid) |
|
110 { |
|
111 TUint32 fromHandle = iObjectStore.HandleL(aFromSuid); |
|
112 TUint32 toHandle = iObjectStore.HandleL(aToSuid); |
|
113 SetReferenceL(fromHandle, toHandle); |
|
114 } |
|
115 |
|
116 /** |
|
117 Replaces the abstract reference links originating from the specified |
|
118 source object handle with the specified set of target object SUIDs. |
|
119 @param aFromHandle The SUID of the source object from which the references |
|
120 originate. |
|
121 @param aToSuids The reference target MTP object SUID array. |
|
122 @leave One of the system wide error codes, if a processing failure occurs. |
|
123 */ |
|
124 void CMTPReferenceMgr::SetReferencesL(const TDesC& aParentSuid, const CDesCArray& aToSuids) |
|
125 { |
|
126 TInt count = aToSuids.Count(); |
|
127 |
|
128 if (count > 0) |
|
129 { |
|
130 TUint32 fromHandle = iObjectStore.HandleL(aParentSuid); |
|
131 |
|
132 // Limit granularity to something less or equal to KMTPMaxGranularity items |
|
133 RArray<TUint> toHandles(Min(count, KMTPMaxGranularity)); |
|
134 CleanupClosePushL(toHandles); |
|
135 |
|
136 for(TInt i = 0; i < count; i++) |
|
137 { |
|
138 TUint32 toHandle = iObjectStore.HandleL(aToSuids[i]); |
|
139 toHandles.Append(toHandle); |
|
140 } |
|
141 |
|
142 SetReferencesL(fromHandle, toHandles); |
|
143 CleanupStack::PopAndDestroy(&toHandles); |
|
144 } |
|
145 } |
|
146 |
|
147 |
|
148 /** |
|
149 Constructor/. |
|
150 */ |
|
151 CMTPReferenceMgr::CMTPReferenceMgr(CMTPObjectStore& aObjectStore): |
|
152 iObjectStore(aObjectStore) |
|
153 { |
|
154 |
|
155 } |
|
156 |
|
157 /** |
|
158 second-phase construction |
|
159 @leave One of the system wide error codes, if a processing failure occurs. |
|
160 */ |
|
161 void CMTPReferenceMgr::ConstructL() |
|
162 { |
|
163 iDatabase = &iObjectStore.Database(); |
|
164 |
|
165 if(!DBUtility::IsTableExistsL(*iDatabase, KSQLReferenceTableName)) |
|
166 { |
|
167 CreateTableL(); |
|
168 } |
|
169 if(!DBUtility::IsIndexExistsL(*iDatabase, KSQLReferenceTableName, KSQLReferenceIndexName)) |
|
170 { |
|
171 CreateIndexL(); |
|
172 } |
|
173 iBatched.Open(*iDatabase, KSQLReferenceTableName, RDbRowSet::EUpdatable); |
|
174 iBatched.SetIndex( KSQLReferenceIndexName ); |
|
175 } |
|
176 |
|
177 /** |
|
178 Create the reference table in the database |
|
179 @leave One of the system wide error codes, if a processing failure occurs. |
|
180 */ |
|
181 void CMTPReferenceMgr::CreateTableL() |
|
182 { |
|
183 User::LeaveIfError(iDatabase->Execute(KSQLCreateReferenceTableText)); |
|
184 } |
|
185 |
|
186 /** |
|
187 Create the index in the reference table |
|
188 @leave One of the system wide error codes, if a processing failure occurs. |
|
189 */ |
|
190 void CMTPReferenceMgr::CreateIndexL() |
|
191 { |
|
192 User::LeaveIfError(iDatabase->Execute(KSQLCreateReferenceIndexText)); |
|
193 } |
|
194 |
|
195 /** |
|
196 Get reference on the object identified by aIdentifier |
|
197 @param aIdentifier The 64bit internal object identifier |
|
198 @return The array containing the handles of the references |
|
199 @leave One of the system wide error codes, if a processing failure occurs. |
|
200 */ |
|
201 CMTPTypeArray* CMTPReferenceMgr::GetReferencesLC(TUint aHandle) const |
|
202 { |
|
203 RArray<TUint> toHandles; |
|
204 CleanupClosePushL(toHandles); |
|
205 GetReferencesL(aHandle, toHandles); |
|
206 |
|
207 CMTPTypeArray* mtpReferenceArray = CMTPTypeArray::NewLC(EMTPTypeAUINT32); |
|
208 mtpReferenceArray->AppendL(toHandles); |
|
209 CleanupStack::Pop(mtpReferenceArray); |
|
210 CleanupStack::PopAndDestroy(&toHandles); |
|
211 CleanupStack::PushL(mtpReferenceArray); |
|
212 return mtpReferenceArray; |
|
213 } |
|
214 |
|
215 /** |
|
216 Get reference on the object identified by aIdentifier |
|
217 @param aIdentifier The 64bit internal object identifier |
|
218 @return The array containing the suids of the references |
|
219 @leave One of the system wide error codes, if a processing failure occurs. |
|
220 */ |
|
221 CDesCArray* CMTPReferenceMgr::GetReferencesInDesLC(TUint aHandle) const |
|
222 { |
|
223 RArray<TUint> toHandles(KMTPReferenceGranularity); |
|
224 CleanupClosePushL(toHandles); |
|
225 GetReferencesL(aHandle, toHandles); |
|
226 const TInt count = toHandles.Count(); |
|
227 CDesCArray* mtpReferenceArray = new (ELeave) CDesCArrayFlat((count==0) ? 1 : count); |
|
228 CleanupStack::PushL(mtpReferenceArray); |
|
229 |
|
230 for(TInt i = 0; i < count; i++) |
|
231 { |
|
232 const TDesC& suid = iObjectStore.ObjectSuidL(toHandles[i]); |
|
233 if(suid.Length()) |
|
234 { |
|
235 mtpReferenceArray->AppendL(suid); |
|
236 } |
|
237 } |
|
238 CleanupStack::Pop(mtpReferenceArray); |
|
239 CleanupStack::PopAndDestroy(&toHandles); |
|
240 CleanupStack::PushL(mtpReferenceArray); |
|
241 return mtpReferenceArray; |
|
242 |
|
243 } |
|
244 |
|
245 /** |
|
246 Get references on the object identified by aIdentifier |
|
247 @param aIdentifier The 64bit internal object identifier |
|
248 @param aReferences The reference array, on return, containing the 64bit internal identifiers of the references |
|
249 @leave One of the system wide error codes, if a processing failure occurs. |
|
250 */ |
|
251 void CMTPReferenceMgr::GetReferencesL(TUint aHandle, RArray<TUint>& aToHandles) const |
|
252 { |
|
253 TUint32 temp = 0; |
|
254 TBool needToUpdate = EFalse; |
|
255 aToHandles.Reset(); |
|
256 if(iBatched.SeekL(aHandle)) |
|
257 { |
|
258 iBatched.GetL(); |
|
259 RDbColReadStream readStream; |
|
260 readStream.OpenLC(iBatched,2); |
|
261 TInt count = readStream.ReadInt32L(); |
|
262 while(count--) |
|
263 { |
|
264 temp = readStream.ReadUint32L(); |
|
265 if(iObjectStore.ObjectExistsL(temp)) |
|
266 aToHandles.AppendL(temp); |
|
267 else |
|
268 needToUpdate = ETrue; |
|
269 } |
|
270 CleanupStack::PopAndDestroy(&readStream); |
|
271 |
|
272 |
|
273 if(needToUpdate) |
|
274 {//Something has been deleted. Write it back to Reference list |
|
275 iBatched.UpdateL(); |
|
276 RDbColWriteStream writeStream; |
|
277 writeStream.OpenLC(iBatched,2); |
|
278 |
|
279 count = aToHandles.Count(); |
|
280 writeStream.WriteInt32L(count); |
|
281 for(TInt i = 0; i < count; i++) |
|
282 { |
|
283 writeStream.WriteUint32L(aToHandles[i]); |
|
284 } |
|
285 writeStream.CommitL(); |
|
286 CleanupStack::PopAndDestroy(&writeStream); |
|
287 iBatched.PutL(); |
|
288 } |
|
289 |
|
290 } |
|
291 return; |
|
292 |
|
293 } |
|
294 |
|
295 |
|
296 /** |
|
297 Remove reference on the object identified by aIdentifier |
|
298 @param aIdentifier The 64bit internal object identifier |
|
299 @leave One of the system wide error codes, if a processing failure occurs. |
|
300 */ |
|
301 void CMTPReferenceMgr::RemoveReferencesL(TUint aHandle) |
|
302 { |
|
303 if(iBatched.SeekL(aHandle)) |
|
304 { |
|
305 iBatched.DeleteL(); |
|
306 IncTranOpsNumL(); |
|
307 } |
|
308 } |
|
309 /** |
|
310 Set reference on the object identified by aFromIdentifier |
|
311 @param aFromIdentifier The 64bit internal object identifier of the source object |
|
312 @param aToIdentifier The 64bit internal object identifier of the referenced object |
|
313 @leave One of the system wide error codes, if a processing failure occurs. |
|
314 */ |
|
315 void CMTPReferenceMgr::SetReferenceL(TUint aFromHandle, TUint aToHandle) |
|
316 { |
|
317 RArray<TUint> aToHandleArray(1); |
|
318 CleanupClosePushL(aToHandleArray); |
|
319 aToHandleArray.AppendL(aToHandle); |
|
320 SetReferencesL(aFromHandle, aToHandleArray); |
|
321 CleanupStack::PopAndDestroy(&aToHandleArray); |
|
322 } |
|
323 |
|
324 /** |
|
325 Replaces the abstract reference links originating from the specified |
|
326 source object handle with the specified set of target object handles. |
|
327 @param aFromHandle The handle of the source object from which the references |
|
328 originate. |
|
329 @param aToHandles The reference target object handle array. |
|
330 @leave One of the system wide error codes, if a processing failure occurs. |
|
331 */ |
|
332 void CMTPReferenceMgr::SetReferencesL(const TMTPTypeUint32& aFromHandle, const CMTPTypeArray& aToHandles) |
|
333 { |
|
334 RArray<TUint> tempArray; |
|
335 CleanupClosePushL(tempArray); |
|
336 TInt count = aToHandles.NumElements(); |
|
337 for(TInt i = 0; i < count; i++) |
|
338 { |
|
339 tempArray.Append(aToHandles.ElementUint(i)); |
|
340 } |
|
341 SetReferencesL(aFromHandle.Value(), tempArray); |
|
342 CleanupStack::PopAndDestroy(&tempArray); |
|
343 } |
|
344 |
|
345 |
|
346 |
|
347 /** |
|
348 Set references on the object identified by aFromIdentifier |
|
349 @param aFromIdentifier The 64bit internal object identifier of the source object |
|
350 @param aToIdentifiers The 64bit internal object identifiers of the referenced objects |
|
351 @leave One of the system wide error codes, if a processing failure occurs. |
|
352 */ |
|
353 void CMTPReferenceMgr::SetReferencesL(TUint aHandle, const RArray<TUint>& aToHandles) |
|
354 { |
|
355 if(iBatched.SeekL(aHandle)) |
|
356 { |
|
357 iBatched.UpdateL(); |
|
358 } |
|
359 else |
|
360 { |
|
361 iBatched.InsertL(); |
|
362 } |
|
363 |
|
364 iBatched.SetColL(1, aHandle); |
|
365 |
|
366 RDbColWriteStream writeStream; |
|
367 writeStream.OpenLC(iBatched,2); |
|
368 |
|
369 const TInt count = aToHandles.Count(); |
|
370 writeStream.WriteInt32L(count); |
|
371 for(TInt i = 0; i < count; i++) |
|
372 { |
|
373 writeStream.WriteUint32L(aToHandles[i]); |
|
374 } |
|
375 writeStream.CommitL(); |
|
376 CleanupStack::PopAndDestroy(&writeStream); |
|
377 iBatched.PutL(); |
|
378 IncTranOpsNumL(); |
|
379 } |
|
380 |
|
381 |
|
382 void CMTPReferenceMgr::IncTranOpsNumL() |
|
383 { |
|
384 iObjectStore.IncTranOpsNumL(); |
|
385 } |
|
386 |
|
387 |
|
388 /** |
|
389 Verify if every reference is pointing to a valid object. If the referenced object does not exist, |
|
390 delete the object from the reference array. |
|
391 @param aReference The 64bit internal object identifiers of the referenced objects |
|
392 @leave One of the system wide error codes, if a processing failure occurs. |
|
393 */ |
|
394 /* |
|
395 void CMTPReferenceMgr::AdjustReferencesL(RArray<TUint32>&aHandles) const |
|
396 { |
|
397 TInt count = aHandles.Count(); |
|
398 while(count--) |
|
399 { |
|
400 if(!iObjectStore.ObjectExistsL(aHandles[count])) |
|
401 { |
|
402 aHandles.Remove(count); |
|
403 } |
|
404 } |
|
405 } |
|
406 */ |
|
407 |