locationdataharvester/mylocationsengine/src/mylocationsdatabasemanager.cpp
changeset 17 0f22fb80ebba
child 20 cd10d5b85554
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/locationdataharvester/mylocationsengine/src/mylocationsdatabasemanager.cpp	Mon May 03 12:27:22 2010 +0300
@@ -0,0 +1,980 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Database manager implementation for location picker and
+*              maptile service.
+*
+*/
+
+#include <EPos_CPosLandmark.h>
+#include <EPos_CPosLandmarkCategory.h>
+#include <EPos_CPosLmTextCriteria.h>
+#include <EPos_CPosLandmarkSearch.h>
+#include <EPos_CPosLmDatabaseManager.h>
+#include <lbsposition.h>
+#include <mylocations.rsg>
+#include <barsread.h>
+#include <barsc.h>
+#include "mylocationsdatabasemanager.h"
+#include "mylocationlogger.h"
+#include "mylocationsdefines.h"
+//Custom landmark database for storing the my locations details
+_LIT( KMyLocationsDatabaseUri, "file://c:MyLocationsLandmarks.ldb" );
+// separator
+_LIT( KSeparator, ",");
+// space
+_LIT( KSpace, " ");
+
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::ConstructL()
+// 2nd phase constructor.
+// -----------------------------------------------------------------------------
+//
+void CMyLocationsDatabaseManager::ConstructL()
+{
+    __TRACE_CALLSTACK;//Open and intialize Landmark DB
+    iLandmarkDb = CPosLandmarkDatabase::OpenL();
+    ExecuteAndDeleteLD(iLandmarkDb->InitializeL());
+
+    // create landmarks lookup database.
+    iLandmarksLookupDb = CLookupDatabase::NewL(KLandmarksLookupDatabaseName);
+    User::LeaveIfError( iLandmarksLookupDb->Open() );
+    
+    CPosLmDatabaseManager* dbManager = CPosLmDatabaseManager::NewL();
+    CleanupStack::PushL(dbManager);
+
+    //Create custom landmark database for storing my locations data
+    if (!dbManager->DatabaseExistsL(KMyLocationsDatabaseUri))
+    {
+        HPosLmDatabaseInfo* dbInfo = HPosLmDatabaseInfo::NewLC(
+                KMyLocationsDatabaseUri);
+        dbManager->CreateDatabaseL(*dbInfo);
+        CleanupStack::PopAndDestroy(dbInfo);
+    }
+
+    CleanupStack::PopAndDestroy(dbManager);
+
+    //Open and initialize the custom landmark database
+    iMyLocationsLandmarksDb = CPosLandmarkDatabase::OpenL(
+                                        KMyLocationsDatabaseUri);
+    if (iMyLocationsLandmarksDb->IsInitializingNeeded())
+    {
+        ExecuteAndDeleteLD(iMyLocationsLandmarksDb->InitializeL());
+    }
+
+    // create mylocations lookup database.
+    iMylocationsLookupDb
+            = CLookupDatabase::NewL(KMylocationsLookupDatabaseName);
+
+    // Create category manager for mylocations
+    iMyLocationsCatManager = CPosLmCategoryManager::NewL(
+            *iMyLocationsLandmarksDb);
+
+    // Create category manager for landmarks
+    iLandmarksCatManager = CPosLmCategoryManager::NewL(*iLandmarkDb);
+
+    //open the lookup database
+    User::LeaveIfError( iMylocationsLookupDb->Open() );
+
+    // open file session
+    User::LeaveIfError(iFsSession.Connect());
+
+    // Add contacts, calendar and history categories
+    AddMylocationsCategoryL(ESourceLandmarksContactsCat);
+    //close the lookup database
+    iMylocationsLookupDb->Close();
+
+}
+
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::CMyLocationsDatabaseManager()
+// Default constructor.
+// -----------------------------------------------------------------------------
+//
+CMyLocationsDatabaseManager::CMyLocationsDatabaseManager() : iLandmarkDb( NULL ),
+                iMyLocationsLandmarksDb( NULL ), 
+                iLmContactsCatId( 0 ), iLandmarksLookupDb( NULL ), 
+                iMylocationsLookupDb( NULL ), iMyLocationsCatManager( NULL ), 
+                iLandmarksCatManager( NULL )
+{
+}
+
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::_CMyLocationsDatabaseManager()
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CMyLocationsDatabaseManager::~CMyLocationsDatabaseManager()
+{
+    __TRACE_CALLSTACK;// delete member variables.
+    if (iLandmarksLookupDb)
+    {
+        iLandmarksLookupDb->Close();
+        delete iLandmarksLookupDb;
+    }
+    if (iMylocationsLookupDb)
+    {
+        iMylocationsLookupDb->Close();
+        delete iMylocationsLookupDb;
+    }
+
+    delete iLandmarksCatManager;
+
+    delete iLandmarkDb;
+
+    delete iMyLocationsCatManager;
+
+    delete iMyLocationsLandmarksDb;
+  
+    // close the file session
+    iFsSession.Close();
+
+}
+
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::AddMylocationsCategoryL()
+// Adds the category to the mylocations and landmarks database..
+// -----------------------------------------------------------------------------
+//
+void CMyLocationsDatabaseManager::AddMylocationsCategoryL( const TUint32 aCategoryType )
+{
+    __TRACE_CALLSTACK;//Open the resource file
+    RResourceFile resourceFile;
+    resourceFile.OpenL( iFsSession, KMyLocationsResourceFile );
+    CleanupClosePushL( resourceFile );
+    
+    // Get the category name
+    HBufC8* dataBuffer = NULL;
+    if (aCategoryType == ESourceLandmarksContactsCat)
+    {
+        dataBuffer = resourceFile.AllocReadLC(R_LOCINT_LIST_CATEGORY_CONTACTS);
+    }
+    
+    TResourceReader resReader;
+    resReader.SetBuffer(dataBuffer);
+    TPtrC resData = resReader.ReadTPtrC();
+
+    TLookupItem lookupItem;
+    lookupItem.iLmId = 0;
+    lookupItem.iSource = aCategoryType;
+    lookupItem.iUid = 0;
+
+    RArray<TLookupItem> itemArray;
+    CleanupClosePushL(itemArray);
+    iMylocationsLookupDb->FindEntriesBySourceTypeL(lookupItem.iSource,
+            itemArray);
+
+    // Get the category from mylocations lookup table
+    if (itemArray.Count() == 0)
+    {
+        // category not found, so create one.
+        CPosLandmarkCategory *category = CPosLandmarkCategory::NewL();
+        CleanupStack::PushL(category);
+        category->SetCategoryNameL(resData);
+
+        if ( aCategoryType == ESourceLandmarksContactsCat)
+        {
+            TPosLmItemId landmarksCatId = 0;
+            // Add category to landmarks database
+            TRAPD ( error, ( landmarksCatId = iLandmarksCatManager->AddCategoryL( *category ) ) );
+            if (error == KErrNone || error == KErrAlreadyExists)
+            {
+                landmarksCatId = iLandmarksCatManager->GetCategoryL(resData);
+            }
+            lookupItem.iUid = landmarksCatId;
+        }
+
+        // Add the catefory to mylocations database
+        TPosLmItemId myLocationsCatId = 0;
+        // Add category to mylocations database
+        TRAPD ( error, ( myLocationsCatId = iMyLocationsCatManager->AddCategoryL( *category ) ) );
+        if (error == KErrNone || error == KErrAlreadyExists)
+        {
+            myLocationsCatId = iMyLocationsCatManager->GetCategoryL(resData);
+        }
+        // create this entry in mylocations lookup table
+        lookupItem.iSource = aCategoryType;
+        lookupItem.iLmId = myLocationsCatId;
+        iMylocationsLookupDb->CreateEntryL(lookupItem);
+
+        CleanupStack::PopAndDestroy(category);
+    }
+    else
+    {
+        // category found in lookup table,
+        // update the corresponding category in Mylocations and landmarks database with 
+        // current localized string  
+
+
+        lookupItem.iLmId = itemArray[0].iLmId;
+        lookupItem.iUid = itemArray[0].iUid;
+        if ( aCategoryType == ESourceLandmarksContactsCat)
+        {
+            CPosLandmarkCategory *category =
+                    iLandmarksCatManager->ReadCategoryLC(lookupItem.iUid);
+            category->SetCategoryNameL(resData);
+            TRAP_IGNORE ( ( iLandmarksCatManager->UpdateCategoryL( *category ) ) );
+            CleanupStack::PopAndDestroy(category);
+        }
+        // update category in mylocations db
+        CPosLandmarkCategory *category2 =
+                iMyLocationsCatManager->ReadCategoryLC(lookupItem.iLmId);
+        category2->SetCategoryNameL(resData);
+        TRAP_IGNORE ( ( iMyLocationsCatManager->UpdateCategoryL( *category2 ) ) );
+        CleanupStack::PopAndDestroy(category2);
+    }
+
+    CleanupStack::PopAndDestroy(&itemArray);
+
+    if ( dataBuffer )
+    {
+        CleanupStack::PopAndDestroy(dataBuffer);
+    }
+    
+    if (aCategoryType == ESourceLandmarksContactsCat)
+        iLmContactsCatId = lookupItem.iUid;
+    
+    // Close the resource file
+    CleanupStack::PopAndDestroy( &resourceFile );
+
+}
+
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::UpdateDatabaseL()
+// Updates the location into the landmark database and lookup table. Based on 
+// the entry source type and the entry change type the updation can be 
+// addition/modification/deletion.
+// -----------------------------------------------------------------------------
+//
+void CMyLocationsDatabaseManager::UpdateDatabaseL(CPosLandmark* aLandmark,
+        const TUint32 aUid, const TUint32 aSourceType, const TEntryChangeType aChangeType)
+{
+    __TRACE_CALLSTACK;//open the lookup database
+    User::LeaveIfError(iMylocationsLookupDb->Open());
+    switch (aChangeType)
+    {
+    // if the entry is added
+    case EEntryAdded:
+    {
+        // Handle this entry in the lookup table and update landmarks db.
+        HandleEntryAdditionL(aLandmark, aUid, aSourceType);
+        break;
+    }
+        // if the entry is modified
+    case EEntryModified:
+    {
+        // Handle this entry in the lookup table and update landmarks db.
+        HandleEntryModificationL(aLandmark, aUid, aSourceType);
+        break;
+    }
+        // if the entry is deleted
+    case EEntryDeleted:
+    {
+        // Handle this entry in the lookup table and update landmarks db.
+        HandleEntryDeletionL(aUid, aSourceType);
+        break;
+    }
+    }
+    //close the lookup database
+    iMylocationsLookupDb->Close();
+
+}
+
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::CheckIfDuplicateExistsL()
+// Checks if this landmark is already present in database. If present returns the landmark id, else 0
+// -----------------------------------------------------------------------------
+//
+TPosLmItemId CMyLocationsDatabaseManager::CheckIfDuplicateExistsL(
+                                    const CPosLandmark* aLandmark)
+{
+    __TRACE_CALLSTACK;// Stores the found duplicate landmark's id. 
+    TPosLmItemId retId = 0;
+
+    // Initially filter only the landmarks which are nearer to the current landmark.
+    // Then we can make a duplicate check on each of the found landmarks.
+
+    // create a search object.
+    CPosLandmarkSearch* search = CPosLandmarkSearch::NewL(
+            *iMyLocationsLandmarksDb);
+    CleanupStack::PushL(search);
+
+    TBuf<KMaxAddressLength> lmAddress;
+    GetLandmarkFullAddress(lmAddress, aLandmark);
+
+    // Create the search criterion
+    CPosLmTextCriteria* crit = CPosLmTextCriteria::NewLC();
+    crit->SetTextL(lmAddress);
+    crit->SetAttributesToSearch(CPosLandmark::ELandmarkName);
+
+    // Start the search and execute it at once.
+    ExecuteAndDeleteLD(search->StartLandmarkSearchL(*crit));
+    CleanupStack::PopAndDestroy(crit);
+
+    // Retrieve an iterator to access the matching landmarks.
+    CPosLmItemIterator* iter = search->MatchIteratorL();
+    CleanupStack::PushL(iter);
+
+    // Iterate the search matches.
+    TPosLmItemId lmId;
+
+    while ((lmId = iter->NextL()) != KPosLmNullItemId)
+    {
+        //Found duplicate entries.
+        // Get the corresponding id in landmarks db
+        RArray<TLookupItem> itemArray;
+        CleanupClosePushL(itemArray);
+        iMylocationsLookupDb->FindEntriesByLandmarkIdL(lmId, itemArray);
+        if (itemArray.Count())
+        {
+            if (itemArray[0].iSource == ESourceLandmarks)
+            {
+                // return id only if the source is from landmarks database.
+                retId = itemArray[0].iUid;
+                CleanupStack::PopAndDestroy(&itemArray);
+                break;
+            }
+        }
+        CleanupStack::PopAndDestroy(&itemArray);
+    }
+
+    CleanupStack::PopAndDestroy(iter);
+    CleanupStack::PopAndDestroy(search);
+
+    return retId;
+}
+
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::CompareLandmarks()
+// Compares two landmarks. Only the text fields, landmark name, street, city, state country and 
+// postal code are compared.
+// -----------------------------------------------------------------------------
+//
+TBool CMyLocationsDatabaseManager::CompareLandmarks(
+        const CPosLandmark* aLandmark1, const CPosLandmark* aLandmark2)
+{
+    __TRACE_CALLSTACK;// Compare landmark names
+    TPtrC name1, name2;
+    aLandmark1->GetLandmarkName(name1);
+    aLandmark2->GetLandmarkName(name2);
+    if (name1 != name2)
+    {
+        return EFalse;
+    }
+
+    // Compare street info
+    TPtrC street1, street2;
+    aLandmark1->GetPositionField(EPositionFieldStreet, street1);
+    aLandmark2->GetPositionField(EPositionFieldStreet, street2);
+    if (street1 != street2)
+    {
+        return EFalse;
+    }
+
+    // Compare City info
+    TPtrC city1, city2;
+    aLandmark1->GetPositionField(EPositionFieldCity, city1);
+    aLandmark2->GetPositionField(EPositionFieldCity, city2);
+    if (city1 != city2)
+    {
+        return EFalse;
+    }
+
+    // compare state info
+    TPtrC state1, state2;
+    aLandmark1->GetPositionField(EPositionFieldState, state1);
+    aLandmark2->GetPositionField(EPositionFieldState, state2);
+    if (state1 != state2)
+    {
+        return EFalse;
+    }
+
+    // compare postal code
+    TPtrC postalCode1, postalCode2;
+    aLandmark1->GetPositionField(EPositionFieldPostalCode, postalCode1);
+    aLandmark2->GetPositionField(EPositionFieldPostalCode, postalCode2);
+    if (postalCode1 != postalCode2)
+    {
+        return EFalse;
+    }
+
+    // compare country name
+    TPtrC country1, country2;
+    aLandmark1->GetPositionField(EPositionFieldCountry, country1);
+    aLandmark2->GetPositionField(EPositionFieldCountry, country2);
+    if (country1 != country2)
+    {
+        return EFalse;
+    }
+
+    return ETrue;
+}
+
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::HandleEntryAdditionL()
+// Handles the entry addition in lookup table and landmarks db
+// -----------------------------------------------------------------------------
+//
+void CMyLocationsDatabaseManager::HandleEntryAdditionL(CPosLandmark* aLandmark,
+        const TUint32 aUid, const TUint32 aSourceType)
+{
+    __TRACE_CALLSTACK;
+    if ( aSourceType == ESourceLandmarks )
+    {
+        AddToMylocationsDbL(aLandmark, aUid, aSourceType);
+        return;
+    }
+    if ( aSourceType == ESourceLandmarksCategory )
+    {
+        CreateCategoryL(aUid);
+        return;
+    }
+    // Create a lookup item
+    TLookupItem lookupItem;
+    lookupItem.iUid = aUid;
+    lookupItem.iSource = aSourceType;
+
+    // check if this landmark is already present in database
+    TPosLmItemId dupLmId = CheckIfDuplicateExistsL(aLandmark);
+    if (dupLmId)
+    {
+        // landmark already present in db. get the details
+        CPosLandmark* dupLandmark = iLandmarkDb->ReadLandmarkLC(dupLmId);
+        if (dupLandmark)
+        {
+            if (aSourceType == ESourceContactsPref || aSourceType
+                    == ESourceContactsWork || aSourceType
+                    == ESourceContactsHome)
+            {
+                dupLandmark->AddCategoryL(iLmContactsCatId);
+            }
+            // update the landmark object in the db
+            iLandmarkDb->UpdateLandmarkL(*dupLandmark);
+            CleanupStack::PopAndDestroy(dupLandmark);
+        }
+
+        // point the lookup item's landmark uid to the existing landmark.
+        lookupItem.iLmId = dupLmId;
+    }
+    else // it is a new entry, so add into the database
+    {
+        if (aSourceType == ESourceContactsPref || aSourceType
+                == ESourceContactsWork || aSourceType == ESourceContactsHome)
+        {
+            aLandmark->AddCategoryL(iLmContactsCatId);
+        }
+        // add the landmark into the db. 
+        // point the lookup item's landmark uid to the newly created landmark in the db.
+        lookupItem.iLmId = iLandmarkDb->AddLandmarkL(*aLandmark);
+    }
+
+    // create the entry in the lookup table.
+    iLandmarksLookupDb->CreateEntryL(lookupItem);
+
+}
+
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::HandleEntryModificationL()
+// Handles the entry modification in the lookup table and landmarks db.
+// -----------------------------------------------------------------------------
+//
+void CMyLocationsDatabaseManager::HandleEntryModificationL(
+        CPosLandmark* aLandmark, const TUint32 aUid, const TUint32 aSourceType)
+{
+    __TRACE_CALLSTACK;
+    if ( aSourceType == ESourceLandmarks )
+    {
+        ModifyMylocationsDbL( aLandmark, aUid, aSourceType );
+        return;
+    }
+
+    TLookupItem lookupItem;
+    lookupItem.iUid = aUid;
+    lookupItem.iSource = aSourceType;
+
+
+    if (aSourceType == ESourceContactsPref || aSourceType
+            == ESourceContactsWork || aSourceType == ESourceContactsHome)
+    {
+        // Behavior: If a contact is modified, 
+        // If this entry is not present in lookup table. add the entry and update the landmarks db.
+        // If this entry is already present in lookup table, check if the location info is modified or not.
+        // If the location info is modified, delete the landmark from db and add the new landmark
+        // into the db. 
+        // Before deletion make sure that the landmark is not being refered by other lookup entries.
+
+        // find the entry in the lookup table.
+        if (iLandmarksLookupDb->FindEntryL(lookupItem))
+        {
+            // check if the location info is modified by comparing the new landmark with the existing landmark
+            CPosLandmark* existingLandmark = NULL;
+            TRAPD( error, ( existingLandmark = 
+                   CheckAndReadLandmarkL( iLandmarkDb, lookupItem.iLmId ) ) );
+            CleanupStack::PushL(existingLandmark);
+            if (error == KErrNotFound)
+            {
+                // Landmarks item deleted. So delete corresponding lookup entries.
+                RArray<TLookupItem> itemArray;
+                CleanupClosePushL(itemArray);
+                iLandmarksLookupDb->FindEntriesByLandmarkIdL(lookupItem.iLmId,
+                        itemArray);
+                for (TInt i = 0; i < itemArray.Count(); i++)
+                {
+                    iLandmarksLookupDb->DeleteEntryL(itemArray[i]);
+                }
+                CleanupStack::PopAndDestroy(&itemArray);
+
+                // Add the entry into the lookup table and update landmarks db.
+                HandleEntryAdditionL(aLandmark, aUid, aSourceType);
+                
+                CleanupStack::PopAndDestroy(existingLandmark);
+                return;
+            }
+
+            if (!CompareLandmarks(existingLandmark, aLandmark))
+            {
+                // landmarks are not same, means location information is modified.
+
+                // Check if the new landmark is already in db.
+                TPosLmItemId dupLmId = CheckIfDuplicateExistsL(aLandmark);
+                if (dupLmId)
+                {
+                    // landmark already present in db. get the details
+                    CPosLandmark* dupLandmark = iLandmarkDb->ReadLandmarkLC(
+                            dupLmId);
+                    if (dupLandmark)
+                    {
+                        // add category.
+                        dupLandmark->AddCategoryL(iLmContactsCatId);
+
+                        // update the landmark object in the db
+                        iLandmarkDb->UpdateLandmarkL(*dupLandmark);
+                    }
+                    CleanupStack::PopAndDestroy(dupLandmark);
+
+                    // update the lookup item to refer to the newly created landmark.
+                    lookupItem.iLmId = dupLmId;
+                    iLandmarksLookupDb->UpdateEntryL(lookupItem);
+                }
+                else
+                {
+                    // landmark not already present in db.
+                    // Create a new entry in the db
+                    aLandmark->AddCategoryL(iLmContactsCatId);
+                    lookupItem.iLmId = iLandmarkDb->AddLandmarkL(*aLandmark);
+                    // update the lookup table
+                    iLandmarksLookupDb->UpdateEntryL(lookupItem);
+                }
+            }
+            else
+            {
+                // landmarks are same, means location not modified. So return.
+                CleanupStack::PopAndDestroy(existingLandmark);
+                return;
+            }
+
+            // delete the existing landmark only if it not being refered by other lookup entries.
+
+            // Check if any other entries are refering this landmark.
+            RArray<TLookupItem> itemArray;
+            CleanupClosePushL(itemArray);
+            iLandmarksLookupDb->FindEntriesByLandmarkIdL(
+                    existingLandmark->LandmarkId(), itemArray);
+
+            if (itemArray.Count())
+            {
+                // There are other lookup entries refering this landmark. So do not delete the landmark
+
+                // If none of these lookup item's source type is contacts, disassociate 'iLmContactsCatId' category
+                // from this landmark.
+                TInt i = 0;
+                while (i < itemArray.Count())
+                {
+                    if (itemArray[i].iSource == ESourceContactsPref
+                            || itemArray[i].iSource == ESourceContactsWork
+                            || itemArray[i].iSource == ESourceContactsHome
+                            )
+                    {
+                        // a lookup item exists which is from contacts, so 'iLmContactsCatId' is still valid.
+                        break;
+                    }
+                    i++;
+                }
+                if (i == itemArray.Count())
+                {
+                    // no lookup items from contacts exists refering this landmark.
+                    // so disassociate 'iLmContactsCatId' from this landmark
+
+                    existingLandmark->RemoveCategory(iLmContactsCatId);
+                    iLandmarkDb->UpdateLandmarkL(*existingLandmark);
+                }
+            }
+            else
+            {
+                // no other lookup entry is refering this landmark. 
+
+                // check if any other categories is associated with this landmark.
+                // Assume this landmark is associated with a history entry or a user created landmark entry.
+                // there is a chance that this landmark is still valid.
+                // Do not delete the landmark in this case.
+                RArray<TPosLmItemId> categoryIdArray;
+                CleanupClosePushL(categoryIdArray);
+                existingLandmark->GetCategoriesL(categoryIdArray);
+                if (categoryIdArray.Count() == 1)
+                {
+                    // only one category i.e, 'iLmContactsCatId' is associated.
+                    // delete the landmark.
+                    iLandmarkDb->RemoveLandmarkL(existingLandmark->LandmarkId());
+                }
+                CleanupStack::PopAndDestroy(&categoryIdArray);
+            }
+            CleanupStack::PopAndDestroy(&itemArray);
+            CleanupStack::PopAndDestroy(existingLandmark);
+
+        }
+        else // entry not present in lookup table
+        {
+            // Add the entry into the lookup table and update landmarks db.
+            HandleEntryAdditionL(aLandmark, aUid, aSourceType);
+        }
+    }
+}
+
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::HandleEntryDeletionL()
+// Handles the entry deletion in lookup table and landmarks db.
+// -----------------------------------------------------------------------------
+//
+void CMyLocationsDatabaseManager::HandleEntryDeletionL(const TUint32 aUid,
+                                                const TUint32 aSourceType)
+{
+    __TRACE_CALLSTACK;
+    TLookupItem lookupItem;
+    lookupItem.iUid = aUid;
+    lookupItem.iSource = aSourceType;
+
+    if (aSourceType == ESourceContactsPref || aSourceType
+            == ESourceContactsWork || aSourceType == ESourceContactsHome)
+    {
+        // Behavior: In the context of contacts, if a contact is deleted, the user is not interested in
+        // that contact's data, hence its address as well. So, delete the corresponding entries from 
+        // both lookup table and iLandmarkDb.  
+        // Before deleting the entry from iLandmarkDb, make sure that this entry is not being refered by
+        // other entries of the lookup table. If it is being refered by other entries in lookup table, then
+        // do not delete the landmark.
+
+        // Find the corresponding landmark uid
+        if (iLandmarksLookupDb->FindEntryL(lookupItem))
+        {
+            // delete the lookup entry.
+            iLandmarksLookupDb->DeleteEntryL(lookupItem);
+
+            // Check if any other entries are refering this landmark.
+            RArray<TLookupItem> itemArray;
+            CleanupClosePushL(itemArray);
+            iLandmarksLookupDb->FindEntriesByLandmarkIdL(lookupItem.iLmId,
+                    itemArray);
+
+            if (itemArray.Count())
+            {
+                // There are other lookup entries refering this landmark. So do not delete the landmark
+
+                // If none of these lookup item's source type is contacts, disassociate 'iLmContactsCatId' category
+                // from this landmark.
+                TInt i = 0;
+                while (i < itemArray.Count())
+                {
+                    if (itemArray[i].iSource == ESourceContactsPref
+                            || itemArray[i].iSource == ESourceContactsWork
+                            || itemArray[i].iSource == ESourceContactsHome)
+                    {
+                        // a lookup item exists which is from contacts/calendar, so 'iLmContactsCatId' is still valid.
+                        break;
+                    }
+                    i++;
+                }
+                if ( i == itemArray.Count() )
+                {
+                    // no lookup items from contacts exists refering this landmark.
+                    // so disassociate 'iLmContactsCatId' from this landmark
+
+                    CPosLandmark* landmark = iLandmarkDb->ReadLandmarkLC(
+                            lookupItem.iLmId);
+                    landmark->RemoveCategory(iLmContactsCatId);
+                    iLandmarkDb->UpdateLandmarkL(*landmark);
+                    CleanupStack::PopAndDestroy(landmark);
+                }
+            }
+            else
+            {
+                // no other lookup entry is refering this landmark. 
+
+                // check if any other categories is associated with this landmark.
+                // Assume this landmark is associated with a history entry or a user created landmark entry.
+                // there is a chance that this landmark is still valid.
+                // Do not delete the landmark in this case.
+                CPosLandmark* landmark = iLandmarkDb->ReadLandmarkLC(
+                        lookupItem.iLmId);
+                RArray<TPosLmItemId> categoryIdArray;
+                CleanupClosePushL(categoryIdArray);
+                landmark->GetCategoriesL(categoryIdArray);
+                if (categoryIdArray.Count() == 1)
+                {
+                    // only one category i.e, 'iLmCalendarCatId' is associated.
+                    // delete the landmark.
+                    iLandmarkDb->RemoveLandmarkL(lookupItem.iLmId);
+                }
+
+                CleanupStack::PopAndDestroy(&categoryIdArray);
+                CleanupStack::PopAndDestroy(landmark);
+            }
+            CleanupStack::PopAndDestroy(&itemArray);
+        }
+    }
+
+    else if (aSourceType == ESourceLandmarks)
+    {
+        // Landmarks item deleted. So delete corresponding lookup entries.
+        RArray<TLookupItem> itemArray;
+        CleanupClosePushL(itemArray);
+        iLandmarksLookupDb->FindEntriesByLandmarkIdL(aUid, itemArray);
+        for (TInt i = 0; i < itemArray.Count(); i++)
+        {
+            iLandmarksLookupDb->DeleteEntryL(itemArray[i]);
+        }
+
+        CleanupStack::PopAndDestroy(&itemArray);
+
+        DeleteFromMylocationsDbL(aUid, aSourceType);
+    }
+}
+
+
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::GetLandmarkFullAddress()
+// Gets the comma separated full address of the given landmark.
+// -----------------------------------------------------------------------------
+//
+void CMyLocationsDatabaseManager::GetLandmarkFullAddress(
+        TBuf<KMaxAddressLength>& aLandmarkAddress,
+        const CPosLandmark* aLandmark)
+{
+    TPtrC tempStr;
+    TInt retStatus;
+    TBool addressEmtpy = ETrue;
+    retStatus = aLandmark->GetLandmarkName(tempStr);
+    if (retStatus == KErrNone && tempStr.Length())
+    {
+        aLandmarkAddress.Copy(tempStr);
+        addressEmtpy = EFalse;
+    }
+
+    retStatus = aLandmark->GetPositionField(EPositionFieldStreet, tempStr);
+    if (retStatus == KErrNone && tempStr.Length())
+    {
+        if (!addressEmtpy)
+        {
+            aLandmarkAddress.Append(KSeparator);
+            aLandmarkAddress.Append(KSpace);
+            aLandmarkAddress.Append(tempStr);
+        }
+        else
+        {
+            aLandmarkAddress.Copy(tempStr);
+            addressEmtpy = EFalse;
+        }
+    }
+
+    retStatus = aLandmark->GetPositionField(EPositionFieldCity, tempStr);
+    if (retStatus == KErrNone && tempStr.Length())
+    {
+        if (!addressEmtpy)
+        {
+            aLandmarkAddress.Append(KSeparator);
+            aLandmarkAddress.Append(KSpace);
+            aLandmarkAddress.Append(tempStr);
+        }
+        else
+        {
+            aLandmarkAddress.Copy(tempStr);
+            addressEmtpy = EFalse;
+        }
+    }
+
+    retStatus = aLandmark->GetPositionField(EPositionFieldState, tempStr);
+    if (retStatus == KErrNone && tempStr.Length())
+    {
+        if (!addressEmtpy)
+        {
+            aLandmarkAddress.Append(KSeparator);
+            aLandmarkAddress.Append(KSpace);
+            aLandmarkAddress.Append(tempStr);
+        }
+        else
+        {
+            aLandmarkAddress.Copy(tempStr);
+            addressEmtpy = EFalse;
+        }
+    }
+
+    retStatus = aLandmark->GetPositionField(EPositionFieldCountry, tempStr);
+    if (retStatus == KErrNone && tempStr.Length())
+    {
+        if (!addressEmtpy)
+        {
+            aLandmarkAddress.Append(KSeparator);
+            aLandmarkAddress.Append(KSpace);
+            aLandmarkAddress.Append(tempStr);
+        }
+        else
+        {
+            aLandmarkAddress.Copy(tempStr);
+            addressEmtpy = EFalse;
+        }
+    }
+}
+
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::CheckCategoryAvailabilityL()
+// Checks if given category id is found in the database pointed by category manager.
+// -----------------------------------------------------------------------------
+//
+void CMyLocationsDatabaseManager::CheckCategoryAvailabilityL(
+        CPosLmCategoryManager* aCategoryManager, const TUint32 aCategoryId)
+{
+    __TRACE_CALLSTACK;
+    CPosLandmarkCategory *category = aCategoryManager->ReadCategoryLC(
+            aCategoryId);
+    CleanupStack::PopAndDestroy(category);
+}
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::CheckAndReadLandmarkL()
+// Checks if given landmark id is found in the database and returns the read landmark.
+// -----------------------------------------------------------------------------
+//
+CPosLandmark* CMyLocationsDatabaseManager::CheckAndReadLandmarkL(
+        CPosLandmarkDatabase* aDb, const TUint32 aLmId)
+{
+    __TRACE_CALLSTACK;
+    CPosLandmark* lm = aDb->ReadLandmarkLC(aLmId);
+    CleanupStack::Pop(lm);    
+    return lm;
+}
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::AddToMylocationsDbL()
+// Adds the entry into the mylocations database and updates the lookup table.
+// -----------------------------------------------------------------------------
+//
+void CMyLocationsDatabaseManager::AddToMylocationsDbL(CPosLandmark* aLandmark,
+        const TUint32 aUid, const TUint32 aSourceType)
+{
+    __TRACE_CALLSTACK;
+    if (aSourceType == ESourceLandmarks)
+    {
+        CPosLandmark* landmark = iLandmarkDb->ReadLandmarkLC(aUid);
+        RArray<TPosLmItemId> catArray;
+        CleanupClosePushL( catArray );
+        landmark->GetCategoriesL(catArray);
+       
+
+        // add the categories in the mylocations database for this landmark
+        for (TInt i = 0; i < catArray.Count(); i++)
+        {
+            TLookupItem lItem;
+            lItem.iUid = catArray[i];
+            lItem.iSource = ESourceLandmarksUserCat;
+            lItem.iLmId = 0;
+            if (!iMylocationsLookupDb->FindEntryL(lItem))
+            {
+                lItem.iSource = ESourceLandmarksContactsCat;
+                if (!iMylocationsLookupDb->FindEntryL(lItem))
+                {
+                    // means this is global category, so just add it
+                    lItem.iLmId = lItem.iUid;
+                }
+            }
+            TRAP_IGNORE( aLandmark->AddCategoryL( lItem.iLmId ) );
+        }
+
+        CleanupStack::PopAndDestroy( &catArray );       
+        TLookupItem lookupItem;
+        lookupItem.iUid = aUid;
+        lookupItem.iSource = aSourceType;
+        TRAP_IGNORE( lookupItem.iLmId = iMyLocationsLandmarksDb->AddLandmarkL( *aLandmark ) );
+        CleanupStack::PopAndDestroy(landmark);
+        iMylocationsLookupDb->CreateEntryL(lookupItem);
+    }
+}
+
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::ModifyMylocationsDbL()
+// Adds the entry into the mylocations database and updates the lookup table.
+// -----------------------------------------------------------------------------
+//
+void CMyLocationsDatabaseManager::ModifyMylocationsDbL(CPosLandmark* aLandmark,
+        const TUint32 aUid, const TUint32 aSourceType)
+{
+    __TRACE_CALLSTACK;
+    TLookupItem lookupItem;
+    lookupItem.iUid = aUid;
+    lookupItem.iSource = aSourceType;
+    iMylocationsLookupDb->FindEntryL(lookupItem);
+    iMylocationsLookupDb->DeleteEntryL(lookupItem);
+    iMyLocationsLandmarksDb->RemoveLandmarkL(lookupItem.iLmId);
+    AddToMylocationsDbL(aLandmark, lookupItem.iUid, lookupItem.iSource);
+}
+
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::DeleteFromMylocationsDbL()
+// Deletes the entry from the mylocations database and updates the lookup table.
+// -----------------------------------------------------------------------------
+//
+void CMyLocationsDatabaseManager::DeleteFromMylocationsDbL(const TUint32 aUid,
+                                                           const TUint32 aSourceType)
+{
+    __TRACE_CALLSTACK;
+    TLookupItem lookupItem;
+    lookupItem.iUid = aUid;
+    lookupItem.iSource = aSourceType;
+    iMylocationsLookupDb->FindEntryL(lookupItem);
+
+    iMyLocationsLandmarksDb->RemoveLandmarkL(lookupItem.iLmId);
+    iMylocationsLookupDb->DeleteEntryL(lookupItem);
+}
+// -----------------------------------------------------------------------------
+// CMyLocationsDatabaseManager::CreateCategoryL()
+// Creates a new category in Mylocations Db and adds a corresponding entry in 
+// mylocations lookup table.
+// -----------------------------------------------------------------------------
+//
+void CMyLocationsDatabaseManager::CreateCategoryL(const TUint32 aUid)
+{
+    __TRACE_CALLSTACK;// Read the category.
+    CPosLandmarkCategory *category = iLandmarksCatManager->ReadCategoryLC(aUid);
+
+    TLookupItem lookupItem;
+    lookupItem.iUid = aUid;
+    lookupItem.iSource = ESourceLandmarksUserCat;
+    // Add category to landmarks database
+    TRAPD ( err, (lookupItem.iLmId = iMyLocationsCatManager->AddCategoryL( *category ) ) );
+
+    if (err == KErrNone)
+    {
+        iMylocationsLookupDb->CreateEntryL(lookupItem);
+    }
+    CleanupStack::PopAndDestroy(category);
+
+}
+
+
+// End of file