|
1 /* |
|
2 * Copyright (c) 2004-2006 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 class is the baseclass for all SI Controller Plugin DB |
|
15 * classes. It implements the common database functionalities. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 // INCLUDE FILES |
|
22 #include "sicommondb.h" |
|
23 #include "rubydebug.h" |
|
24 |
|
25 // CONSTANTS |
|
26 |
|
27 // Name of the DB lock mutex |
|
28 _LIT( KLockMutex, "SIGRAMMAR" ); |
|
29 |
|
30 // ============================ MEMBER FUNCTIONS =============================== |
|
31 |
|
32 // ----------------------------------------------------------------------------- |
|
33 // CSICommonDB::CSICommonDB |
|
34 // C++ default constructor can NOT contain any code, that |
|
35 // might leave. |
|
36 // ----------------------------------------------------------------------------- |
|
37 // |
|
38 CSICommonDB::CSICommonDB( RDbNamedDatabase& aDatabase, |
|
39 RDbs& aDbSession, TInt aDrive ) |
|
40 : iDb( aDatabase ), |
|
41 iDbSession( aDbSession ), |
|
42 iDrive( aDrive ) |
|
43 { |
|
44 |
|
45 TInt err = iMutex.OpenGlobal( KLockMutex ); |
|
46 if ( err != KErrNone ) |
|
47 { |
|
48 RUBY_DEBUG0( "CSICommonDB::CSICommonDB Creating new global mutex" ); |
|
49 iMutex.CreateGlobal( KLockMutex ); |
|
50 } |
|
51 else |
|
52 { |
|
53 RUBY_DEBUG0( "CSICommonDB::CSICommonDB Using existing global mutex" ); |
|
54 } |
|
55 |
|
56 } |
|
57 |
|
58 // ----------------------------------------------------------------------------- |
|
59 // CSICommonDB::CSICommonDB |
|
60 // Destructor |
|
61 // ----------------------------------------------------------------------------- |
|
62 // |
|
63 CSICommonDB::~CSICommonDB() |
|
64 { |
|
65 if ( iMutex.IsHeld() ) |
|
66 { |
|
67 iMutex.Signal(); |
|
68 } |
|
69 iMutex.Close(); |
|
70 } |
|
71 |
|
72 // ----------------------------------------------------------------------------- |
|
73 // CSICommonDB::CheckIDTableL |
|
74 // Each of controller's database files has an ID table. If the database has no |
|
75 // table, this is the first time the database is open, so the ID table is created. |
|
76 // ----------------------------------------------------------------------------- |
|
77 // |
|
78 void CSICommonDB::CreateIDTableL( const TDesC& aIdTable, |
|
79 const TDesC& aIdColumn, |
|
80 const TDesC& aIndex ) |
|
81 { |
|
82 RUBY_DEBUG_BLOCK( "CSICommonDB::CheckIDTableL - create ID table" ); |
|
83 |
|
84 TBuf<150> KSQLStatement; |
|
85 // Declare a literal string to hold the SQL statement |
|
86 // CREATE TABLE aIdTable (aIdColumn COUNTER, KClientUidColumn INTEGER NOT NULL, |
|
87 // KCounterColumn INTEGER NOT NULL, KUsedColumn BIT NOT NULL) |
|
88 _LIT(KSQLCreate1, "CREATE TABLE "); |
|
89 _LIT(KSQLCreate2, " COUNTER, "); |
|
90 _LIT(KSQLCreate3, " INTEGER NOT NULL, "); |
|
91 _LIT(KSQLCreate4, " BIT NOT NULL)"); |
|
92 |
|
93 KSQLStatement = KSQLCreate1; |
|
94 KSQLStatement.Append(aIdTable); |
|
95 KSQLStatement.Append(KOpenParen); |
|
96 KSQLStatement.Append(aIdColumn); |
|
97 KSQLStatement.Append(KSQLCreate2); |
|
98 KSQLStatement.Append(KClientUidColumn); |
|
99 KSQLStatement.Append(KSQLCreate3); |
|
100 KSQLStatement.Append(KCounterColumn); |
|
101 KSQLStatement.Append(KSQLCreate3); |
|
102 KSQLStatement.Append(KUsedColumn); |
|
103 KSQLStatement.Append(KSQLCreate4); |
|
104 |
|
105 User::LeaveIfError(iDb.Execute(KSQLStatement)); |
|
106 |
|
107 // Create an index on the 'Id' column to ensure 'Id' values are unique |
|
108 // CREATE UNIQUE INDEX aIndex ON aIdTable (aIdColumn) |
|
109 _LIT(KSQLIndex1, "CREATE UNIQUE INDEX "); |
|
110 _LIT(KSQLIndex2, " ON "); |
|
111 |
|
112 KSQLStatement = KSQLIndex1; |
|
113 KSQLStatement.Append(aIndex); |
|
114 KSQLStatement.Append(KSQLIndex2); |
|
115 KSQLStatement.Append(aIdTable); |
|
116 KSQLStatement.Append(KOpenParen); |
|
117 KSQLStatement.Append(aIdColumn); |
|
118 KSQLStatement.Append(KCloseParen); |
|
119 |
|
120 User::LeaveIfError(iDb.Execute(KSQLStatement)); |
|
121 } |
|
122 |
|
123 // ----------------------------------------------------------------------------- |
|
124 // CSICommonDB::CreateNewIDL |
|
125 // This function first checks to see if there is an "unused" ID. If one is not |
|
126 // found, it creates a new row in the table for a new ID. |
|
127 // ----------------------------------------------------------------------------- |
|
128 // |
|
129 TUint32 CSICommonDB::CreateNewIDL( |
|
130 const TDesC& aTableName, |
|
131 const TDesC& aIdColumn, |
|
132 TUid aClientUid ) |
|
133 { |
|
134 RUBY_DEBUG_BLOCKL( "CSICommonDB::CreateNewIDL" ); |
|
135 |
|
136 TUint32 newID( 0 ); |
|
137 |
|
138 iMutex.Wait(); |
|
139 |
|
140 TRAPD( error, newID = DoCreateNewIDL( aTableName, aIdColumn, aClientUid ) ); |
|
141 |
|
142 iMutex.Signal(); |
|
143 |
|
144 User::LeaveIfError( error ); |
|
145 |
|
146 return newID; |
|
147 } |
|
148 |
|
149 // ----------------------------------------------------------------------------- |
|
150 // CSICommonDB::CountL |
|
151 // This function first searches the row with aKey and returns the counter value |
|
152 // given that the row is set as "used". |
|
153 // ----------------------------------------------------------------------------- |
|
154 // |
|
155 TInt CSICommonDB::CountL( const TDesC& aTableName, const TDesC& aIndex, |
|
156 TUint aKey ) |
|
157 { |
|
158 RUBY_DEBUG_BLOCK( "CSICommonDB::CountL" ); |
|
159 RDbTable dbTable; // Provides access to table data as a rowset |
|
160 TInt count = 0; |
|
161 |
|
162 // Open model table |
|
163 User::LeaveIfError(dbTable.Open(iDb, aTableName, RDbTable::EReadOnly)); |
|
164 CleanupClosePushL(dbTable); |
|
165 User::LeaveIfError(dbTable.SetIndex(aIndex)); |
|
166 |
|
167 TDbSeekKey key(aKey); |
|
168 // Return true, if a matching row found |
|
169 if ( dbTable.SeekL(key) ) |
|
170 { |
|
171 dbTable.GetL(); |
|
172 // Get column set for column ordinals |
|
173 CDbColSet* columns = dbTable.ColSetL(); |
|
174 TDbColNo counter_col = columns->ColNo(KCounterColumn); |
|
175 TDbColNo used_col = columns->ColNo(KUsedColumn); |
|
176 delete columns; |
|
177 |
|
178 // Check if this row is currently in use |
|
179 TBool used = dbTable.ColInt(used_col); |
|
180 if ( used ) |
|
181 { |
|
182 count = dbTable.ColInt(counter_col); |
|
183 } |
|
184 else |
|
185 { |
|
186 RUBY_DEBUG1( "CSICommonDB::CountL - key=%d is unused", aKey ); |
|
187 User::Leave(KErrNotFound); |
|
188 } |
|
189 } |
|
190 else |
|
191 { |
|
192 RUBY_DEBUG1( "CSICommonDB::CountL - can't find key=%d", aKey ); |
|
193 User::Leave(KErrNotFound); |
|
194 } |
|
195 |
|
196 // Cleanup dbTable |
|
197 CleanupStack::PopAndDestroy(); |
|
198 return count; |
|
199 } |
|
200 |
|
201 // ----------------------------------------------------------------------------- |
|
202 // CSICommonDB::CreateDatabaseL |
|
203 // Creates a database file if one does not exist yet. |
|
204 // ----------------------------------------------------------------------------- |
|
205 // |
|
206 TBool CSICommonDB::FindUnusedIDL( |
|
207 RDbTable& aDbTable ) |
|
208 { |
|
209 TBuf<30> KSQLQuery; |
|
210 // Declare a literal string to hold the SQL search-condition for 'unused' row |
|
211 // KUsedColumn = KNotUsed |
|
212 KSQLQuery = KUsedColumn; |
|
213 KSQLQuery.Append(KEqual); |
|
214 KSQLQuery.AppendNum(KNotUsed); |
|
215 |
|
216 // Return true, if the table is not empty and a matching row found |
|
217 return (aDbTable.FirstL() && aDbTable.FindL(RDbTable::EForwards, TDbQuery(KSQLQuery)) != KErrNotFound); |
|
218 } |
|
219 |
|
220 // ----------------------------------------------------------------------------- |
|
221 // CSICommonDB::GetAllClientIDsL |
|
222 // This function returns all Ids in the specified table that belong to the specified client. |
|
223 // ----------------------------------------------------------------------------- |
|
224 // |
|
225 void CSICommonDB::GetAllClientIDsL( |
|
226 const TDesC& aIdTable, |
|
227 const TDesC& aIdColumn, |
|
228 TUid aClientUid, |
|
229 RArray<TUint32>& aIDs ) |
|
230 { |
|
231 TBuf<100> KSQLStatement; |
|
232 // Declare a literal string to hold the SQL statement |
|
233 // SELECT aIdColumn, KUsedColumn FROM aIdTable WHERE KClientUidColumn = uid |
|
234 // ORDER BY aIdColumn |
|
235 _LIT(KSQLSelect1, "SELECT "); |
|
236 _LIT(KSQLSelect2, " FROM "); |
|
237 _LIT(KSQLSelect3, " WHERE "); |
|
238 _LIT(KSQLSelect4, " ORDER BY "); |
|
239 |
|
240 KSQLStatement = KSQLSelect1; |
|
241 KSQLStatement.Append(aIdColumn); |
|
242 KSQLStatement.Append(KNext); |
|
243 KSQLStatement.Append(KUsedColumn); |
|
244 KSQLStatement.Append(KSQLSelect2); |
|
245 KSQLStatement.Append(aIdTable); |
|
246 KSQLStatement.Append(KSQLSelect3); |
|
247 KSQLStatement.Append(KClientUidColumn); |
|
248 KSQLStatement.Append(KEqual); |
|
249 KSQLStatement.AppendNum((TInt) aClientUid.iUid); |
|
250 KSQLStatement.Append(KSQLSelect4); |
|
251 KSQLStatement.Append(aIdColumn); |
|
252 |
|
253 RDbView view; |
|
254 CleanupClosePushL(view); |
|
255 User::LeaveIfError(view.Prepare(iDb, TDbQuery(KSQLStatement, EDbCompareNormal))); |
|
256 User::LeaveIfError(view.EvaluateAll()); |
|
257 |
|
258 // Get column set for column ordinals |
|
259 CDbColSet* columns = view.ColSetL(); |
|
260 TDbColNo id_col = columns->ColNo(aIdColumn); |
|
261 TDbColNo used_col = columns->ColNo(KUsedColumn); |
|
262 delete columns; |
|
263 |
|
264 TUint32 id; |
|
265 TBool used; |
|
266 // After evaluation, the first call to NextL() is equivalent to FirstL() |
|
267 while ( view.NextL() ) |
|
268 { |
|
269 // Retrieve the current row |
|
270 view.GetL(); |
|
271 // Check if this row is currently in use |
|
272 used = view.ColInt(used_col); |
|
273 if ( used ) |
|
274 { |
|
275 id = view.ColUint32(id_col); |
|
276 User::LeaveIfError(aIDs.Append(id)); |
|
277 } |
|
278 } |
|
279 |
|
280 // Cleanup view |
|
281 CleanupStack::PopAndDestroy(); |
|
282 } |
|
283 |
|
284 // ----------------------------------------------------------------------------- |
|
285 // CSICommonDB::GetAllIDsL |
|
286 // This function returns all Ids in the specified table. |
|
287 // ----------------------------------------------------------------------------- |
|
288 // |
|
289 void CSICommonDB::GetAllIDsL( |
|
290 const TDesC& aIdTable, |
|
291 const TDesC& aIdColumn, |
|
292 RArray<TUint32>& aIDs ) |
|
293 { |
|
294 TBuf<100> KSQLStatement; |
|
295 // Declare a literal string to hold the SQL statement |
|
296 // SELECT aIdColumn FROM aIdTable WHERE KUsedColumn = KUsed |
|
297 // ORDER BY aIdColumn |
|
298 _LIT(KSQLSelect1, "SELECT "); |
|
299 _LIT(KSQLSelect2, " FROM "); |
|
300 _LIT(KSQLSelect3, " WHERE "); |
|
301 _LIT(KSQLSelect4, " ORDER BY "); |
|
302 |
|
303 KSQLStatement = KSQLSelect1; |
|
304 KSQLStatement.Append(aIdColumn); |
|
305 KSQLStatement.Append(KSQLSelect2); |
|
306 KSQLStatement.Append(aIdTable); |
|
307 KSQLStatement.Append(KSQLSelect3); |
|
308 KSQLStatement.Append(KUsedColumn); |
|
309 KSQLStatement.Append(KEqual); |
|
310 KSQLStatement.AppendNum(KUsed); |
|
311 KSQLStatement.Append(KSQLSelect4); |
|
312 KSQLStatement.Append(aIdColumn); |
|
313 |
|
314 RDbView view; |
|
315 CleanupClosePushL(view); |
|
316 User::LeaveIfError(view.Prepare(iDb, TDbQuery(KSQLStatement, EDbCompareNormal))); |
|
317 User::LeaveIfError(view.EvaluateAll()); |
|
318 |
|
319 // Get column set for column ordinals |
|
320 CDbColSet* columns = view.ColSetL(); |
|
321 TDbColNo id_col = columns->ColNo(aIdColumn); |
|
322 delete columns; |
|
323 |
|
324 TUint32 id; |
|
325 // After evaluation, the first call to NextL() is equivalent to FirstL() |
|
326 while ( view.NextL() ) |
|
327 { |
|
328 // Retrieve the current row |
|
329 view.GetL(); |
|
330 id = view.ColUint32(id_col); |
|
331 User::LeaveIfError(aIDs.Append(id)); |
|
332 } |
|
333 |
|
334 // Cleanup view |
|
335 CleanupStack::PopAndDestroy(); |
|
336 } |
|
337 |
|
338 // ----------------------------------------------------------------------------- |
|
339 // CSICommonDB::IsValidL |
|
340 // Checks to see if aKey exists in the table and that it's set to "used". |
|
341 // ----------------------------------------------------------------------------- |
|
342 // |
|
343 TBool CSICommonDB::IsValidL( const TDesC& aTableName, const TDesC& aIndex, |
|
344 TUint aKey ) |
|
345 { |
|
346 RUBY_DEBUG_BLOCK( "CSICommonDB::IsValidL" ); |
|
347 RDbTable dbTable; // Provides access to table data as a rowset |
|
348 TBool valid = EFalse; |
|
349 |
|
350 // Open table |
|
351 User::LeaveIfError(dbTable.Open(iDb, aTableName, RDbTable::EReadOnly)); |
|
352 CleanupClosePushL(dbTable); |
|
353 User::LeaveIfError(dbTable.SetIndex(aIndex)); |
|
354 |
|
355 TDbSeekKey key(aKey); |
|
356 // Return true, if a matching row found |
|
357 if ( dbTable.SeekL(key) ) |
|
358 { |
|
359 RUBY_DEBUG1( "CSICommonDB::IsValidL - %d is found", aKey ); |
|
360 dbTable.GetL(); |
|
361 // Get column set for column ordinals |
|
362 CDbColSet* columns = dbTable.ColSetL(); |
|
363 TDbColNo used_col = columns->ColNo(KUsedColumn); |
|
364 delete columns; |
|
365 |
|
366 // Check if this row is currently in use |
|
367 valid = dbTable.ColInt(used_col); |
|
368 } |
|
369 |
|
370 // Cleanup dbTable |
|
371 CleanupStack::PopAndDestroy(); |
|
372 return valid; |
|
373 } |
|
374 |
|
375 // ----------------------------------------------------------------------------- |
|
376 // CSICommonDB::ReleaseIdL |
|
377 // Releases the ID by marking it as "unused". |
|
378 // ----------------------------------------------------------------------------- |
|
379 // |
|
380 void CSICommonDB::ReleaseIdL( |
|
381 const TDesC& aTableName, |
|
382 const TDesC& aIdColumn, |
|
383 TUint32 aId ) |
|
384 { |
|
385 RUBY_DEBUG_BLOCKL( "CSICommonDB::ReleaseIdL" ); |
|
386 |
|
387 iMutex.Wait(); |
|
388 |
|
389 TRAPD( error, DoReleaseIdL( aTableName, aIdColumn, aId ) ); |
|
390 |
|
391 iMutex.Signal(); |
|
392 |
|
393 User::LeaveIfError( error ); |
|
394 } |
|
395 |
|
396 // ----------------------------------------------------------------------------- |
|
397 // CSICommonDB::UpdateCounterL |
|
398 // Updates the counter value of the specified row. |
|
399 // ----------------------------------------------------------------------------- |
|
400 // |
|
401 void CSICommonDB::UpdateCounterL( const TDesC& aTableName, const TDesC& aIndex, |
|
402 TUint aKey, TBool aIncrement ) |
|
403 { |
|
404 RUBY_DEBUG_BLOCK( "CSICommonDB::UpdateCounterL" ); |
|
405 RDbTable dbTable; // Provides access to table data as a rowset |
|
406 |
|
407 // Open table |
|
408 User::LeaveIfError(dbTable.Open(iDb, aTableName, RDbTable::EUpdatable)); |
|
409 CleanupClosePushL(dbTable); |
|
410 User::LeaveIfError(dbTable.SetIndex(aIndex)); |
|
411 |
|
412 TDbSeekKey key(aKey); |
|
413 // Return true, if a matching row found |
|
414 if ( dbTable.SeekL(key) ) |
|
415 { |
|
416 dbTable.GetL(); |
|
417 // Get column set for column ordinals |
|
418 CDbColSet* columns = dbTable.ColSetL(); |
|
419 TDbColNo counter_col = columns->ColNo(KCounterColumn); |
|
420 delete columns; |
|
421 |
|
422 TInt counter = dbTable.ColInt(counter_col); |
|
423 |
|
424 if ( aIncrement ) |
|
425 { |
|
426 counter++; |
|
427 } |
|
428 else |
|
429 { |
|
430 counter--; |
|
431 } |
|
432 // Update found row |
|
433 dbTable.UpdateL(); |
|
434 dbTable.SetColL(counter_col, counter); |
|
435 |
|
436 // Write the updated row |
|
437 TRAPD(err, dbTable.PutL()); |
|
438 if( err != KErrNone ) |
|
439 { |
|
440 // Error: cancel update |
|
441 dbTable.Cancel(); |
|
442 dbTable.Reset(); |
|
443 User::Leave(err); |
|
444 } |
|
445 } |
|
446 else |
|
447 { |
|
448 RUBY_DEBUG1( "CSICommonDB::UpdateCounterL - can't find key=%d", aKey ); |
|
449 User::Leave(KErrNotFound); |
|
450 } |
|
451 |
|
452 // Cleanup dbTable |
|
453 CleanupStack::PopAndDestroy(); |
|
454 } |
|
455 |
|
456 // ----------------------------------------------------------------------------- |
|
457 // CSICommonDB::VerifyOwnershipL |
|
458 // Checks for data ownership. |
|
459 // ----------------------------------------------------------------------------- |
|
460 // |
|
461 void CSICommonDB::VerifyOwnershipL( TUid aClientUid, const TDesC& aTableName, |
|
462 const TDesC& aIndex, TUint aKey ) |
|
463 { |
|
464 RUBY_DEBUG_BLOCK( "CSICommonDB::VerifyOwnershipL" ); |
|
465 RDbTable dbTable; // Provides access to table data as a rowset |
|
466 |
|
467 // Open table |
|
468 User::LeaveIfError(dbTable.Open(iDb, aTableName, RDbTable::EReadOnly)); |
|
469 CleanupClosePushL(dbTable); |
|
470 User::LeaveIfError(dbTable.SetIndex(aIndex)); |
|
471 |
|
472 TDbSeekKey key(aKey); |
|
473 // Return true, if a matching row found |
|
474 if ( dbTable.SeekL(key) ) |
|
475 { |
|
476 RUBY_DEBUG1( "CSICommonDB::VerifyOwnershipL - %d is found", aKey ); |
|
477 dbTable.GetL(); |
|
478 // Get column set for column ordinals |
|
479 CDbColSet* columns = dbTable.ColSetL(); |
|
480 TDbColNo client_uid_col = columns->ColNo(KClientUidColumn); |
|
481 TDbColNo used_col = columns->ColNo(KUsedColumn); |
|
482 delete columns; |
|
483 |
|
484 // Check if this row is currently in use |
|
485 TBool used = dbTable.ColInt(used_col); |
|
486 if ( used ) |
|
487 { |
|
488 if ( dbTable.ColInt(client_uid_col) != aClientUid.iUid ) |
|
489 { |
|
490 User::Leave(KErrAsrDataRightViolation); |
|
491 } |
|
492 } |
|
493 else |
|
494 { |
|
495 RUBY_DEBUG1( "CSICommonDB::VerifyOwnershipL - key=%d is unused", aKey ); |
|
496 User::Leave(KErrNotFound); |
|
497 } |
|
498 } |
|
499 else |
|
500 { |
|
501 RUBY_DEBUG1( "CSICommonDB::VerifyOwnershipL - can't find key=%d", aKey ); |
|
502 User::Leave(KErrNotFound); |
|
503 } |
|
504 |
|
505 // Cleanup dbTable |
|
506 CleanupStack::PopAndDestroy(); |
|
507 } |
|
508 |
|
509 // ----------------------------------------------------------------------------- |
|
510 // CSICommonDB::DoReleaseIdL |
|
511 // Releases the ID by marking it as "unused". |
|
512 // ----------------------------------------------------------------------------- |
|
513 // |
|
514 void CSICommonDB::DoReleaseIdL( |
|
515 const TDesC& aTableName, |
|
516 const TDesC& aIdColumn, |
|
517 TUint32 aId ) |
|
518 { |
|
519 TBuf<100> KSQLStatement; |
|
520 // Declare a literal string to hold the SQL statement |
|
521 // UPDATE aTableName SET KUsedColumn = KNotUsed WHERE aIdColumn = aId |
|
522 _LIT(KSQLUpdate1, "UPDATE "); |
|
523 _LIT(KSQLUpdate2, " SET "); |
|
524 _LIT(KSQLUpdate3, " WHERE "); |
|
525 |
|
526 KSQLStatement = KSQLUpdate1; |
|
527 KSQLStatement.Append(aTableName); |
|
528 KSQLStatement.Append(KSQLUpdate2); |
|
529 KSQLStatement.Append(KUsedColumn); |
|
530 KSQLStatement.Append(KEqual); |
|
531 KSQLStatement.AppendNum(KNotUsed); |
|
532 KSQLStatement.Append(KSQLUpdate3); |
|
533 KSQLStatement.Append(aIdColumn); |
|
534 KSQLStatement.Append(KEqual); |
|
535 KSQLStatement.AppendNumUC(aId); |
|
536 |
|
537 User::LeaveIfError(iDb.Execute(KSQLStatement)); |
|
538 } |
|
539 |
|
540 // ----------------------------------------------------------------------------- |
|
541 // CSICommonDB::DoCreateNewIDL |
|
542 // This function first checks to see if there is an "unused" ID. If one is not |
|
543 // found, it creates a new row in the table for a new ID. |
|
544 // ----------------------------------------------------------------------------- |
|
545 // |
|
546 TUint32 CSICommonDB::DoCreateNewIDL( |
|
547 const TDesC& aTableName, |
|
548 const TDesC& aIdColumn, |
|
549 TUid aClientUid ) |
|
550 { |
|
551 RDbTable dbTable; // Provides access to table data as a rowset |
|
552 |
|
553 // Open table |
|
554 User::LeaveIfError(dbTable.Open(iDb, aTableName, RDbTable::EUpdatable)); |
|
555 CleanupClosePushL(dbTable); |
|
556 |
|
557 // Get column set for column ordinals |
|
558 CDbColSet* columns = dbTable.ColSetL(); |
|
559 TDbColNo id_col = columns->ColNo(aIdColumn); |
|
560 TDbColNo uid_col = columns->ColNo(KClientUidColumn); |
|
561 TDbColNo counter_col = columns->ColNo(KCounterColumn); |
|
562 TDbColNo used_col = columns->ColNo(KUsedColumn); |
|
563 delete columns; |
|
564 |
|
565 // Is there an unused ID? |
|
566 if( FindUnusedIDL(dbTable) ) |
|
567 { |
|
568 // Yes, update found row |
|
569 dbTable.UpdateL(); |
|
570 } |
|
571 else |
|
572 { |
|
573 // No, insert new row |
|
574 dbTable.InsertL(); |
|
575 } |
|
576 |
|
577 dbTable.SetColL(uid_col, aClientUid.iUid); |
|
578 dbTable.SetColL(counter_col, 0); |
|
579 dbTable.SetColL(used_col, KUsed); |
|
580 |
|
581 // Write the updated row |
|
582 TRAPD(err, dbTable.PutL()); |
|
583 if( err != KErrNone ) |
|
584 { |
|
585 // Error: cancel update |
|
586 dbTable.Cancel(); |
|
587 dbTable.Reset(); |
|
588 User::Leave(err); |
|
589 } |
|
590 |
|
591 TUint32 newID = dbTable.ColUint32(id_col); |
|
592 // Cleanup dbTable |
|
593 CleanupStack::PopAndDestroy(); |
|
594 return newID; |
|
595 } |
|
596 |
|
597 |
|
598 // End of File |