srsf/sisrscontrollerplugin/src/sicommondb.cpp
changeset 13 57b735022c18
parent 1 b13cd05eeb2f
equal deleted inserted replaced
1:b13cd05eeb2f 13:57b735022c18
     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