persistentstorage/sql/SRC/Server/SqlSrvDatabase.cpp
branchRCL_3
changeset 10 31a8f755b7fe
parent 9 667e88a979d7
child 11 211563e4b919
equal deleted inserted replaced
9:667e88a979d7 10:31a8f755b7fe
   389     SQLPROFILER_DB_CLOSE((TUint)iDbHandle);
   389     SQLPROFILER_DB_CLOSE((TUint)iDbHandle);
   390 	TSqlCompactDbMapIterator compactDbIt(iCompactDbMap);
   390 	TSqlCompactDbMapIterator compactDbIt(iCompactDbMap);
   391 	TSqlCompactDbPair compactDbPair;
   391 	TSqlCompactDbPair compactDbPair;
   392 	while(compactDbIt.Next(compactDbPair))
   392 	while(compactDbIt.Next(compactDbPair))
   393 		{
   393 		{
       
   394         __SQLASSERT(compactDbPair.iData, ESqlPanicInvalidObj);
   394 		::SqlServer().Compactor().ReleaseEntry(*compactDbPair.iData);
   395 		::SqlServer().Compactor().ReleaseEntry(*compactDbPair.iData);
   395 		}
   396 		}
   396 	iCompactDbMap.Close();
   397 	iCompactDbMap.Close();
   397 	//If iSecureDbName is not NULL, the current CSqlSrvDatabase object operates on a secure database.
   398 	//If iSecureDbName is not NULL, the current CSqlSrvDatabase object operates on a secure database.
   398 	//The database security policy has to be removed from the security policy map.
   399 	//The database security policy has to be removed from the security policy map.
   403 		{
   404 		{
   404 		::SqlServer().SecurityMap().Remove(iSecureDbName);
   405 		::SqlServer().SecurityMap().Remove(iSecureDbName);
   405 		//The security policy map owns iSecureDbName and iSecurityPolicy and is responsible for 
   406 		//The security policy map owns iSecureDbName and iSecurityPolicy and is responsible for 
   406 		//iSecureDbName and iSecurityPolicy destruction.
   407 		//iSecureDbName and iSecurityPolicy destruction.
   407 		}
   408 		}
       
   409     //The next step of the "resource release" process is to walk over iAttachDbMap entries, get the data part of
       
   410     //the found TSqlAttachDbPair objects, which is secure database name used as a key in iSecurityMap, and remove
       
   411     //the related entry from iSecurityMap. If the database is closed in normal circumstances, the iAttachDbMap
       
   412     //has no entries. But if the database client forgets to detach the used attached databases or if the Detach() call
       
   413     //fails (for example, with KErrNoMemory error), then at this point iAttachDbMap has one or more entries.
       
   414     //That means there are still some attached databases to this connection. This is not a problem, SQLite will take
       
   415     //care of them. The problem is that there are related entries in iSecurityMap map, owned by CSqlServer object,
       
   416     //and they won't be removed from the map till CSqlServer object is alive. This causes problems in OOM tests and in 
       
   417     //real life of the device.
       
   418     //For example, one database client opens "c:[11111111]a.db" and attaches "c:[11111111]b.db":
       
   419     // - c:[11111111]a.db database has been opened successfully. iSecurityMap has 1 entry:
       
   420     //            {"c:[11111111]a.db", <database security policy object>}.
       
   421     // - c:[11111111]b.db is attached to c:[11111111]a.db with name "db2". There will be 1 entry in iAttachDbMap:
       
   422     //            {"db2", "c:[11111111]a.db"} 
       
   423     //        and a new entry will be added to iSecurityMap:
       
   424     //            {"c:[11111111]b.db", <database security policy object>}. 2 entries in total in iSecurityMap.
       
   425     // - The database client attempts to detach the attached database but the opertaion fails during the execution
       
   426     //        of the DETACH sql statement. Both maps are intact.
       
   427     // - The database client attempts to close the database. The previous implementation of CSqlSrvDatabase::~CSqlSrvDatabase()
       
   428     //        would only remove "c:[11111111]a.db" entry from iSecurityMap and close the iAttachDbMap map.
       
   429     // The result: no opened or attached databases but there will be one entry in iSecurityMap: "c:[11111111]b.db".
       
   430     // OOM tests will report a memory leak in this case. On a real device, if "c:[11111111]b.db" gets deleted and
       
   431     // recreated again, unexpected memory leak will occur in CSqlSrvDatabase::ConstructCreateSecureL() because
       
   432     // the code there "expects" that is the first time when a "c:[11111111]b.db" entry is added to iSecurityMap.
       
   433     TSqlAttachDbMapIterator it(iAttachDbMap);
       
   434     TSqlAttachDbPair attachDbPair;
       
   435     while(it.Next(attachDbPair))
       
   436         {
       
   437         __SQLASSERT(attachDbPair.iData, ESqlPanicInvalidObj);
       
   438         ::SqlServer().SecurityMap().Remove(attachDbPair.iData);
       
   439         }
   408 	iAttachDbMap.Close();
   440 	iAttachDbMap.Close();
   409 	::CloseDbHandle(iDbHandle);
   441 	::CloseDbHandle(iDbHandle);
   410 	}
   442 	}
   411 
   443 
   412 /**
   444 /**
  1040 		//insert a new item in the map.
  1072 		//insert a new item in the map.
  1041 		__SQLASSERT(aMapKey != NULL, ESqlPanicInternalError);
  1073 		__SQLASSERT(aMapKey != NULL, ESqlPanicInternalError);
  1042 		aMapKey = ::CreateStrCopyLC(aMapKey);
  1074 		aMapKey = ::CreateStrCopyLC(aMapKey);
  1043 		CSqlSecurityPolicy* securityPolicy = aAttachedDb ? ::LoadAttachedDbSecurityPolicyLC(aFileData) :
  1075 		CSqlSecurityPolicy* securityPolicy = aAttachedDb ? ::LoadAttachedDbSecurityPolicyLC(aFileData) :
  1044 		                                                   ::LoadDbSecurityPolicyLC(iDbHandle);
  1076 		                                                   ::LoadDbSecurityPolicyLC(iDbHandle);
       
  1077         __SQLASSERT(!::SqlServer().SecurityMap().Entry(aMapKey), ESqlPanicObjExists);
  1045 		__SQLLEAVE_IF_ERROR(::SqlServer().SecurityMap().Insert(aMapKey, securityPolicy));
  1078 		__SQLLEAVE_IF_ERROR(::SqlServer().SecurityMap().Insert(aMapKey, securityPolicy));
  1046 		CleanupStack::Pop(2);//iSecurityMap owns aMapKey and securityPolicy objects
  1079 		CleanupStack::Pop(2);//iSecurityMap owns aMapKey and securityPolicy objects
  1047 		aSecurityPolicy = securityPolicy;
  1080 		aSecurityPolicy = securityPolicy;
  1048 		}
  1081 		}
  1049 	__SQLASSERT(aMapKey != NULL, ESqlPanicInternalError);
  1082 	__SQLASSERT(aMapKey != NULL, ESqlPanicInternalError);
  1113 		__SQLLEAVE(KErrGeneral);	
  1146 		__SQLLEAVE(KErrGeneral);	
  1114 		}
  1147 		}
  1115 	const TUint8* mapKey = ::CreateStrCopyLC(iFileNameBuf);
  1148 	const TUint8* mapKey = ::CreateStrCopyLC(iFileNameBuf);
  1116 	const TUint8* mapData = SecurityMapKeyL(aDbFileName);
  1149 	const TUint8* mapData = SecurityMapKeyL(aDbFileName);
  1117 	mapData = ::CreateStrCopyLC(mapData);
  1150 	mapData = ::CreateStrCopyLC(mapData);
       
  1151     __SQLASSERT(!iAttachDbMap.Entry(mapKey), ESqlPanicObjExists);
  1118 	__SQLLEAVE_IF_ERROR(iAttachDbMap.Insert(mapKey, mapData));
  1152 	__SQLLEAVE_IF_ERROR(iAttachDbMap.Insert(mapKey, mapData));
  1119 	CleanupStack::Pop(2);//iAttachDbMap owns mapKey amd mapData.
  1153 	CleanupStack::Pop(2);//iAttachDbMap owns mapKey amd mapData.
  1120 	}
  1154 	}
  1121 
  1155 
  1122 /**
  1156 /**
  1324 	TInt err = KErrNoMemory;
  1358 	TInt err = KErrNoMemory;
  1325 	HBufC* key = aDbName.Alloc();
  1359 	HBufC* key = aDbName.Alloc();
  1326 	HBufC* data = aDbFileName.Alloc();
  1360 	HBufC* data = aDbFileName.Alloc();
  1327 	if(key && data)
  1361 	if(key && data)
  1328 		{
  1362 		{
       
  1363 	    __SQLASSERT(!iCompactDbMap.Entry(key), ESqlPanicObjExists);
  1329 		err = iCompactDbMap.Insert(key, data);//returns the index of the new entry
  1364 		err = iCompactDbMap.Insert(key, data);//returns the index of the new entry
  1330 		}
  1365 		}
  1331 	if(err < 0) //If either "key" or "data" or both is NULL, then "err" is KErrNoMemory and the next "if" will be executed.
  1366 	if(err < 0) //If either "key" or "data" or both is NULL, then "err" is KErrNoMemory and the next "if" will be executed.
  1332 		{
  1367 		{
  1333 		delete data;
  1368 		delete data;
  1436 	__SQLASSERT(aSecurityPolicy != NULL, ESqlPanicBadArgument);
  1471 	__SQLASSERT(aSecurityPolicy != NULL, ESqlPanicBadArgument);
  1437 	//Insert a new item in the security policies map.
  1472 	//Insert a new item in the security policies map.
  1438 	CleanupStack::PushL(aSecurityPolicy);
  1473 	CleanupStack::PushL(aSecurityPolicy);
  1439 	const TUint8* mapKey = SecurityMapKeyL(aFileData.FileName());
  1474 	const TUint8* mapKey = SecurityMapKeyL(aFileData.FileName());
  1440 	mapKey = ::CreateStrCopyLC(mapKey);
  1475 	mapKey = ::CreateStrCopyLC(mapKey);
       
  1476     __SQLASSERT(!::SqlServer().SecurityMap().Entry(mapKey), ESqlPanicObjExists);
  1441 	__SQLLEAVE_IF_ERROR(::SqlServer().SecurityMap().Insert(mapKey, aSecurityPolicy));
  1477 	__SQLLEAVE_IF_ERROR(::SqlServer().SecurityMap().Insert(mapKey, aSecurityPolicy));
  1442 	CleanupStack::Pop(2);//iSecurityMap owns mapKey and aSecurityPolicy.
  1478 	CleanupStack::Pop(2);//iSecurityMap owns mapKey and aSecurityPolicy.
  1443 	iSecureDbName = mapKey;
  1479 	iSecureDbName = mapKey;
  1444 	iSecurityPolicy = aSecurityPolicy;
  1480 	iSecurityPolicy = aSecurityPolicy;
  1445 	//
  1481 	//