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 // |