locationdataharvester/mylocationsengine/src/mylocationsdatabasemanager.cpp
changeset 17 0f22fb80ebba
child 20 cd10d5b85554
equal deleted inserted replaced
15:13ae750350c9 17:0f22fb80ebba
       
     1 /*
       
     2 * Copyright (c) 2010 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: Database manager implementation for location picker and
       
    15 *              maptile service.
       
    16 *
       
    17 */
       
    18 
       
    19 #include <EPos_CPosLandmark.h>
       
    20 #include <EPos_CPosLandmarkCategory.h>
       
    21 #include <EPos_CPosLmTextCriteria.h>
       
    22 #include <EPos_CPosLandmarkSearch.h>
       
    23 #include <EPos_CPosLmDatabaseManager.h>
       
    24 #include <lbsposition.h>
       
    25 #include <mylocations.rsg>
       
    26 #include <barsread.h>
       
    27 #include <barsc.h>
       
    28 #include "mylocationsdatabasemanager.h"
       
    29 #include "mylocationlogger.h"
       
    30 #include "mylocationsdefines.h"
       
    31 //Custom landmark database for storing the my locations details
       
    32 _LIT( KMyLocationsDatabaseUri, "file://c:MyLocationsLandmarks.ldb" );
       
    33 // separator
       
    34 _LIT( KSeparator, ",");
       
    35 // space
       
    36 _LIT( KSpace, " ");
       
    37 
       
    38 // -----------------------------------------------------------------------------
       
    39 // CMyLocationsDatabaseManager::ConstructL()
       
    40 // 2nd phase constructor.
       
    41 // -----------------------------------------------------------------------------
       
    42 //
       
    43 void CMyLocationsDatabaseManager::ConstructL()
       
    44 {
       
    45     __TRACE_CALLSTACK;//Open and intialize Landmark DB
       
    46     iLandmarkDb = CPosLandmarkDatabase::OpenL();
       
    47     ExecuteAndDeleteLD(iLandmarkDb->InitializeL());
       
    48 
       
    49     // create landmarks lookup database.
       
    50     iLandmarksLookupDb = CLookupDatabase::NewL(KLandmarksLookupDatabaseName);
       
    51     User::LeaveIfError( iLandmarksLookupDb->Open() );
       
    52     
       
    53     CPosLmDatabaseManager* dbManager = CPosLmDatabaseManager::NewL();
       
    54     CleanupStack::PushL(dbManager);
       
    55 
       
    56     //Create custom landmark database for storing my locations data
       
    57     if (!dbManager->DatabaseExistsL(KMyLocationsDatabaseUri))
       
    58     {
       
    59         HPosLmDatabaseInfo* dbInfo = HPosLmDatabaseInfo::NewLC(
       
    60                 KMyLocationsDatabaseUri);
       
    61         dbManager->CreateDatabaseL(*dbInfo);
       
    62         CleanupStack::PopAndDestroy(dbInfo);
       
    63     }
       
    64 
       
    65     CleanupStack::PopAndDestroy(dbManager);
       
    66 
       
    67     //Open and initialize the custom landmark database
       
    68     iMyLocationsLandmarksDb = CPosLandmarkDatabase::OpenL(
       
    69                                         KMyLocationsDatabaseUri);
       
    70     if (iMyLocationsLandmarksDb->IsInitializingNeeded())
       
    71     {
       
    72         ExecuteAndDeleteLD(iMyLocationsLandmarksDb->InitializeL());
       
    73     }
       
    74 
       
    75     // create mylocations lookup database.
       
    76     iMylocationsLookupDb
       
    77             = CLookupDatabase::NewL(KMylocationsLookupDatabaseName);
       
    78 
       
    79     // Create category manager for mylocations
       
    80     iMyLocationsCatManager = CPosLmCategoryManager::NewL(
       
    81             *iMyLocationsLandmarksDb);
       
    82 
       
    83     // Create category manager for landmarks
       
    84     iLandmarksCatManager = CPosLmCategoryManager::NewL(*iLandmarkDb);
       
    85 
       
    86     //open the lookup database
       
    87     User::LeaveIfError( iMylocationsLookupDb->Open() );
       
    88 
       
    89     // open file session
       
    90     User::LeaveIfError(iFsSession.Connect());
       
    91 
       
    92     // Add contacts, calendar and history categories
       
    93     AddMylocationsCategoryL(ESourceLandmarksContactsCat);
       
    94     //close the lookup database
       
    95     iMylocationsLookupDb->Close();
       
    96 
       
    97 }
       
    98 
       
    99 // -----------------------------------------------------------------------------
       
   100 // CMyLocationsDatabaseManager::CMyLocationsDatabaseManager()
       
   101 // Default constructor.
       
   102 // -----------------------------------------------------------------------------
       
   103 //
       
   104 CMyLocationsDatabaseManager::CMyLocationsDatabaseManager() : iLandmarkDb( NULL ),
       
   105                 iMyLocationsLandmarksDb( NULL ), 
       
   106                 iLmContactsCatId( 0 ), iLandmarksLookupDb( NULL ), 
       
   107                 iMylocationsLookupDb( NULL ), iMyLocationsCatManager( NULL ), 
       
   108                 iLandmarksCatManager( NULL )
       
   109 {
       
   110 }
       
   111 
       
   112 // -----------------------------------------------------------------------------
       
   113 // CMyLocationsDatabaseManager::_CMyLocationsDatabaseManager()
       
   114 // Destructor.
       
   115 // -----------------------------------------------------------------------------
       
   116 //
       
   117 CMyLocationsDatabaseManager::~CMyLocationsDatabaseManager()
       
   118 {
       
   119     __TRACE_CALLSTACK;// delete member variables.
       
   120     if (iLandmarksLookupDb)
       
   121     {
       
   122         iLandmarksLookupDb->Close();
       
   123         delete iLandmarksLookupDb;
       
   124     }
       
   125     if (iMylocationsLookupDb)
       
   126     {
       
   127         iMylocationsLookupDb->Close();
       
   128         delete iMylocationsLookupDb;
       
   129     }
       
   130 
       
   131     delete iLandmarksCatManager;
       
   132 
       
   133     delete iLandmarkDb;
       
   134 
       
   135     delete iMyLocationsCatManager;
       
   136 
       
   137     delete iMyLocationsLandmarksDb;
       
   138   
       
   139     // close the file session
       
   140     iFsSession.Close();
       
   141 
       
   142 }
       
   143 
       
   144 // -----------------------------------------------------------------------------
       
   145 // CMyLocationsDatabaseManager::AddMylocationsCategoryL()
       
   146 // Adds the category to the mylocations and landmarks database..
       
   147 // -----------------------------------------------------------------------------
       
   148 //
       
   149 void CMyLocationsDatabaseManager::AddMylocationsCategoryL( const TUint32 aCategoryType )
       
   150 {
       
   151     __TRACE_CALLSTACK;//Open the resource file
       
   152     RResourceFile resourceFile;
       
   153     resourceFile.OpenL( iFsSession, KMyLocationsResourceFile );
       
   154     CleanupClosePushL( resourceFile );
       
   155     
       
   156     // Get the category name
       
   157     HBufC8* dataBuffer = NULL;
       
   158     if (aCategoryType == ESourceLandmarksContactsCat)
       
   159     {
       
   160         dataBuffer = resourceFile.AllocReadLC(R_LOCINT_LIST_CATEGORY_CONTACTS);
       
   161     }
       
   162     
       
   163     TResourceReader resReader;
       
   164     resReader.SetBuffer(dataBuffer);
       
   165     TPtrC resData = resReader.ReadTPtrC();
       
   166 
       
   167     TLookupItem lookupItem;
       
   168     lookupItem.iLmId = 0;
       
   169     lookupItem.iSource = aCategoryType;
       
   170     lookupItem.iUid = 0;
       
   171 
       
   172     RArray<TLookupItem> itemArray;
       
   173     CleanupClosePushL(itemArray);
       
   174     iMylocationsLookupDb->FindEntriesBySourceTypeL(lookupItem.iSource,
       
   175             itemArray);
       
   176 
       
   177     // Get the category from mylocations lookup table
       
   178     if (itemArray.Count() == 0)
       
   179     {
       
   180         // category not found, so create one.
       
   181         CPosLandmarkCategory *category = CPosLandmarkCategory::NewL();
       
   182         CleanupStack::PushL(category);
       
   183         category->SetCategoryNameL(resData);
       
   184 
       
   185         if ( aCategoryType == ESourceLandmarksContactsCat)
       
   186         {
       
   187             TPosLmItemId landmarksCatId = 0;
       
   188             // Add category to landmarks database
       
   189             TRAPD ( error, ( landmarksCatId = iLandmarksCatManager->AddCategoryL( *category ) ) );
       
   190             if (error == KErrNone || error == KErrAlreadyExists)
       
   191             {
       
   192                 landmarksCatId = iLandmarksCatManager->GetCategoryL(resData);
       
   193             }
       
   194             lookupItem.iUid = landmarksCatId;
       
   195         }
       
   196 
       
   197         // Add the catefory to mylocations database
       
   198         TPosLmItemId myLocationsCatId = 0;
       
   199         // Add category to mylocations database
       
   200         TRAPD ( error, ( myLocationsCatId = iMyLocationsCatManager->AddCategoryL( *category ) ) );
       
   201         if (error == KErrNone || error == KErrAlreadyExists)
       
   202         {
       
   203             myLocationsCatId = iMyLocationsCatManager->GetCategoryL(resData);
       
   204         }
       
   205         // create this entry in mylocations lookup table
       
   206         lookupItem.iSource = aCategoryType;
       
   207         lookupItem.iLmId = myLocationsCatId;
       
   208         iMylocationsLookupDb->CreateEntryL(lookupItem);
       
   209 
       
   210         CleanupStack::PopAndDestroy(category);
       
   211     }
       
   212     else
       
   213     {
       
   214         // category found in lookup table,
       
   215         // update the corresponding category in Mylocations and landmarks database with 
       
   216         // current localized string  
       
   217 
       
   218 
       
   219         lookupItem.iLmId = itemArray[0].iLmId;
       
   220         lookupItem.iUid = itemArray[0].iUid;
       
   221         if ( aCategoryType == ESourceLandmarksContactsCat)
       
   222         {
       
   223             CPosLandmarkCategory *category =
       
   224                     iLandmarksCatManager->ReadCategoryLC(lookupItem.iUid);
       
   225             category->SetCategoryNameL(resData);
       
   226             TRAP_IGNORE ( ( iLandmarksCatManager->UpdateCategoryL( *category ) ) );
       
   227             CleanupStack::PopAndDestroy(category);
       
   228         }
       
   229         // update category in mylocations db
       
   230         CPosLandmarkCategory *category2 =
       
   231                 iMyLocationsCatManager->ReadCategoryLC(lookupItem.iLmId);
       
   232         category2->SetCategoryNameL(resData);
       
   233         TRAP_IGNORE ( ( iMyLocationsCatManager->UpdateCategoryL( *category2 ) ) );
       
   234         CleanupStack::PopAndDestroy(category2);
       
   235     }
       
   236 
       
   237     CleanupStack::PopAndDestroy(&itemArray);
       
   238 
       
   239     if ( dataBuffer )
       
   240     {
       
   241         CleanupStack::PopAndDestroy(dataBuffer);
       
   242     }
       
   243     
       
   244     if (aCategoryType == ESourceLandmarksContactsCat)
       
   245         iLmContactsCatId = lookupItem.iUid;
       
   246     
       
   247     // Close the resource file
       
   248     CleanupStack::PopAndDestroy( &resourceFile );
       
   249 
       
   250 }
       
   251 
       
   252 // -----------------------------------------------------------------------------
       
   253 // CMyLocationsDatabaseManager::UpdateDatabaseL()
       
   254 // Updates the location into the landmark database and lookup table. Based on 
       
   255 // the entry source type and the entry change type the updation can be 
       
   256 // addition/modification/deletion.
       
   257 // -----------------------------------------------------------------------------
       
   258 //
       
   259 void CMyLocationsDatabaseManager::UpdateDatabaseL(CPosLandmark* aLandmark,
       
   260         const TUint32 aUid, const TUint32 aSourceType, const TEntryChangeType aChangeType)
       
   261 {
       
   262     __TRACE_CALLSTACK;//open the lookup database
       
   263     User::LeaveIfError(iMylocationsLookupDb->Open());
       
   264     switch (aChangeType)
       
   265     {
       
   266     // if the entry is added
       
   267     case EEntryAdded:
       
   268     {
       
   269         // Handle this entry in the lookup table and update landmarks db.
       
   270         HandleEntryAdditionL(aLandmark, aUid, aSourceType);
       
   271         break;
       
   272     }
       
   273         // if the entry is modified
       
   274     case EEntryModified:
       
   275     {
       
   276         // Handle this entry in the lookup table and update landmarks db.
       
   277         HandleEntryModificationL(aLandmark, aUid, aSourceType);
       
   278         break;
       
   279     }
       
   280         // if the entry is deleted
       
   281     case EEntryDeleted:
       
   282     {
       
   283         // Handle this entry in the lookup table and update landmarks db.
       
   284         HandleEntryDeletionL(aUid, aSourceType);
       
   285         break;
       
   286     }
       
   287     }
       
   288     //close the lookup database
       
   289     iMylocationsLookupDb->Close();
       
   290 
       
   291 }
       
   292 
       
   293 // -----------------------------------------------------------------------------
       
   294 // CMyLocationsDatabaseManager::CheckIfDuplicateExistsL()
       
   295 // Checks if this landmark is already present in database. If present returns the landmark id, else 0
       
   296 // -----------------------------------------------------------------------------
       
   297 //
       
   298 TPosLmItemId CMyLocationsDatabaseManager::CheckIfDuplicateExistsL(
       
   299                                     const CPosLandmark* aLandmark)
       
   300 {
       
   301     __TRACE_CALLSTACK;// Stores the found duplicate landmark's id. 
       
   302     TPosLmItemId retId = 0;
       
   303 
       
   304     // Initially filter only the landmarks which are nearer to the current landmark.
       
   305     // Then we can make a duplicate check on each of the found landmarks.
       
   306 
       
   307     // create a search object.
       
   308     CPosLandmarkSearch* search = CPosLandmarkSearch::NewL(
       
   309             *iMyLocationsLandmarksDb);
       
   310     CleanupStack::PushL(search);
       
   311 
       
   312     TBuf<KMaxAddressLength> lmAddress;
       
   313     GetLandmarkFullAddress(lmAddress, aLandmark);
       
   314 
       
   315     // Create the search criterion
       
   316     CPosLmTextCriteria* crit = CPosLmTextCriteria::NewLC();
       
   317     crit->SetTextL(lmAddress);
       
   318     crit->SetAttributesToSearch(CPosLandmark::ELandmarkName);
       
   319 
       
   320     // Start the search and execute it at once.
       
   321     ExecuteAndDeleteLD(search->StartLandmarkSearchL(*crit));
       
   322     CleanupStack::PopAndDestroy(crit);
       
   323 
       
   324     // Retrieve an iterator to access the matching landmarks.
       
   325     CPosLmItemIterator* iter = search->MatchIteratorL();
       
   326     CleanupStack::PushL(iter);
       
   327 
       
   328     // Iterate the search matches.
       
   329     TPosLmItemId lmId;
       
   330 
       
   331     while ((lmId = iter->NextL()) != KPosLmNullItemId)
       
   332     {
       
   333         //Found duplicate entries.
       
   334         // Get the corresponding id in landmarks db
       
   335         RArray<TLookupItem> itemArray;
       
   336         CleanupClosePushL(itemArray);
       
   337         iMylocationsLookupDb->FindEntriesByLandmarkIdL(lmId, itemArray);
       
   338         if (itemArray.Count())
       
   339         {
       
   340             if (itemArray[0].iSource == ESourceLandmarks)
       
   341             {
       
   342                 // return id only if the source is from landmarks database.
       
   343                 retId = itemArray[0].iUid;
       
   344                 CleanupStack::PopAndDestroy(&itemArray);
       
   345                 break;
       
   346             }
       
   347         }
       
   348         CleanupStack::PopAndDestroy(&itemArray);
       
   349     }
       
   350 
       
   351     CleanupStack::PopAndDestroy(iter);
       
   352     CleanupStack::PopAndDestroy(search);
       
   353 
       
   354     return retId;
       
   355 }
       
   356 
       
   357 // -----------------------------------------------------------------------------
       
   358 // CMyLocationsDatabaseManager::CompareLandmarks()
       
   359 // Compares two landmarks. Only the text fields, landmark name, street, city, state country and 
       
   360 // postal code are compared.
       
   361 // -----------------------------------------------------------------------------
       
   362 //
       
   363 TBool CMyLocationsDatabaseManager::CompareLandmarks(
       
   364         const CPosLandmark* aLandmark1, const CPosLandmark* aLandmark2)
       
   365 {
       
   366     __TRACE_CALLSTACK;// Compare landmark names
       
   367     TPtrC name1, name2;
       
   368     aLandmark1->GetLandmarkName(name1);
       
   369     aLandmark2->GetLandmarkName(name2);
       
   370     if (name1 != name2)
       
   371     {
       
   372         return EFalse;
       
   373     }
       
   374 
       
   375     // Compare street info
       
   376     TPtrC street1, street2;
       
   377     aLandmark1->GetPositionField(EPositionFieldStreet, street1);
       
   378     aLandmark2->GetPositionField(EPositionFieldStreet, street2);
       
   379     if (street1 != street2)
       
   380     {
       
   381         return EFalse;
       
   382     }
       
   383 
       
   384     // Compare City info
       
   385     TPtrC city1, city2;
       
   386     aLandmark1->GetPositionField(EPositionFieldCity, city1);
       
   387     aLandmark2->GetPositionField(EPositionFieldCity, city2);
       
   388     if (city1 != city2)
       
   389     {
       
   390         return EFalse;
       
   391     }
       
   392 
       
   393     // compare state info
       
   394     TPtrC state1, state2;
       
   395     aLandmark1->GetPositionField(EPositionFieldState, state1);
       
   396     aLandmark2->GetPositionField(EPositionFieldState, state2);
       
   397     if (state1 != state2)
       
   398     {
       
   399         return EFalse;
       
   400     }
       
   401 
       
   402     // compare postal code
       
   403     TPtrC postalCode1, postalCode2;
       
   404     aLandmark1->GetPositionField(EPositionFieldPostalCode, postalCode1);
       
   405     aLandmark2->GetPositionField(EPositionFieldPostalCode, postalCode2);
       
   406     if (postalCode1 != postalCode2)
       
   407     {
       
   408         return EFalse;
       
   409     }
       
   410 
       
   411     // compare country name
       
   412     TPtrC country1, country2;
       
   413     aLandmark1->GetPositionField(EPositionFieldCountry, country1);
       
   414     aLandmark2->GetPositionField(EPositionFieldCountry, country2);
       
   415     if (country1 != country2)
       
   416     {
       
   417         return EFalse;
       
   418     }
       
   419 
       
   420     return ETrue;
       
   421 }
       
   422 
       
   423 // -----------------------------------------------------------------------------
       
   424 // CMyLocationsDatabaseManager::HandleEntryAdditionL()
       
   425 // Handles the entry addition in lookup table and landmarks db
       
   426 // -----------------------------------------------------------------------------
       
   427 //
       
   428 void CMyLocationsDatabaseManager::HandleEntryAdditionL(CPosLandmark* aLandmark,
       
   429         const TUint32 aUid, const TUint32 aSourceType)
       
   430 {
       
   431     __TRACE_CALLSTACK;
       
   432     if ( aSourceType == ESourceLandmarks )
       
   433     {
       
   434         AddToMylocationsDbL(aLandmark, aUid, aSourceType);
       
   435         return;
       
   436     }
       
   437     if ( aSourceType == ESourceLandmarksCategory )
       
   438     {
       
   439         CreateCategoryL(aUid);
       
   440         return;
       
   441     }
       
   442     // Create a lookup item
       
   443     TLookupItem lookupItem;
       
   444     lookupItem.iUid = aUid;
       
   445     lookupItem.iSource = aSourceType;
       
   446 
       
   447     // check if this landmark is already present in database
       
   448     TPosLmItemId dupLmId = CheckIfDuplicateExistsL(aLandmark);
       
   449     if (dupLmId)
       
   450     {
       
   451         // landmark already present in db. get the details
       
   452         CPosLandmark* dupLandmark = iLandmarkDb->ReadLandmarkLC(dupLmId);
       
   453         if (dupLandmark)
       
   454         {
       
   455             if (aSourceType == ESourceContactsPref || aSourceType
       
   456                     == ESourceContactsWork || aSourceType
       
   457                     == ESourceContactsHome)
       
   458             {
       
   459                 dupLandmark->AddCategoryL(iLmContactsCatId);
       
   460             }
       
   461             // update the landmark object in the db
       
   462             iLandmarkDb->UpdateLandmarkL(*dupLandmark);
       
   463             CleanupStack::PopAndDestroy(dupLandmark);
       
   464         }
       
   465 
       
   466         // point the lookup item's landmark uid to the existing landmark.
       
   467         lookupItem.iLmId = dupLmId;
       
   468     }
       
   469     else // it is a new entry, so add into the database
       
   470     {
       
   471         if (aSourceType == ESourceContactsPref || aSourceType
       
   472                 == ESourceContactsWork || aSourceType == ESourceContactsHome)
       
   473         {
       
   474             aLandmark->AddCategoryL(iLmContactsCatId);
       
   475         }
       
   476         // add the landmark into the db. 
       
   477         // point the lookup item's landmark uid to the newly created landmark in the db.
       
   478         lookupItem.iLmId = iLandmarkDb->AddLandmarkL(*aLandmark);
       
   479     }
       
   480 
       
   481     // create the entry in the lookup table.
       
   482     iLandmarksLookupDb->CreateEntryL(lookupItem);
       
   483 
       
   484 }
       
   485 
       
   486 // -----------------------------------------------------------------------------
       
   487 // CMyLocationsDatabaseManager::HandleEntryModificationL()
       
   488 // Handles the entry modification in the lookup table and landmarks db.
       
   489 // -----------------------------------------------------------------------------
       
   490 //
       
   491 void CMyLocationsDatabaseManager::HandleEntryModificationL(
       
   492         CPosLandmark* aLandmark, const TUint32 aUid, const TUint32 aSourceType)
       
   493 {
       
   494     __TRACE_CALLSTACK;
       
   495     if ( aSourceType == ESourceLandmarks )
       
   496     {
       
   497         ModifyMylocationsDbL( aLandmark, aUid, aSourceType );
       
   498         return;
       
   499     }
       
   500 
       
   501     TLookupItem lookupItem;
       
   502     lookupItem.iUid = aUid;
       
   503     lookupItem.iSource = aSourceType;
       
   504 
       
   505 
       
   506     if (aSourceType == ESourceContactsPref || aSourceType
       
   507             == ESourceContactsWork || aSourceType == ESourceContactsHome)
       
   508     {
       
   509         // Behavior: If a contact is modified, 
       
   510         // If this entry is not present in lookup table. add the entry and update the landmarks db.
       
   511         // If this entry is already present in lookup table, check if the location info is modified or not.
       
   512         // If the location info is modified, delete the landmark from db and add the new landmark
       
   513         // into the db. 
       
   514         // Before deletion make sure that the landmark is not being refered by other lookup entries.
       
   515 
       
   516         // find the entry in the lookup table.
       
   517         if (iLandmarksLookupDb->FindEntryL(lookupItem))
       
   518         {
       
   519             // check if the location info is modified by comparing the new landmark with the existing landmark
       
   520             CPosLandmark* existingLandmark = NULL;
       
   521             TRAPD( error, ( existingLandmark = 
       
   522                    CheckAndReadLandmarkL( iLandmarkDb, lookupItem.iLmId ) ) );
       
   523             CleanupStack::PushL(existingLandmark);
       
   524             if (error == KErrNotFound)
       
   525             {
       
   526                 // Landmarks item deleted. So delete corresponding lookup entries.
       
   527                 RArray<TLookupItem> itemArray;
       
   528                 CleanupClosePushL(itemArray);
       
   529                 iLandmarksLookupDb->FindEntriesByLandmarkIdL(lookupItem.iLmId,
       
   530                         itemArray);
       
   531                 for (TInt i = 0; i < itemArray.Count(); i++)
       
   532                 {
       
   533                     iLandmarksLookupDb->DeleteEntryL(itemArray[i]);
       
   534                 }
       
   535                 CleanupStack::PopAndDestroy(&itemArray);
       
   536 
       
   537                 // Add the entry into the lookup table and update landmarks db.
       
   538                 HandleEntryAdditionL(aLandmark, aUid, aSourceType);
       
   539                 
       
   540                 CleanupStack::PopAndDestroy(existingLandmark);
       
   541                 return;
       
   542             }
       
   543 
       
   544             if (!CompareLandmarks(existingLandmark, aLandmark))
       
   545             {
       
   546                 // landmarks are not same, means location information is modified.
       
   547 
       
   548                 // Check if the new landmark is already in db.
       
   549                 TPosLmItemId dupLmId = CheckIfDuplicateExistsL(aLandmark);
       
   550                 if (dupLmId)
       
   551                 {
       
   552                     // landmark already present in db. get the details
       
   553                     CPosLandmark* dupLandmark = iLandmarkDb->ReadLandmarkLC(
       
   554                             dupLmId);
       
   555                     if (dupLandmark)
       
   556                     {
       
   557                         // add category.
       
   558                         dupLandmark->AddCategoryL(iLmContactsCatId);
       
   559 
       
   560                         // update the landmark object in the db
       
   561                         iLandmarkDb->UpdateLandmarkL(*dupLandmark);
       
   562                     }
       
   563                     CleanupStack::PopAndDestroy(dupLandmark);
       
   564 
       
   565                     // update the lookup item to refer to the newly created landmark.
       
   566                     lookupItem.iLmId = dupLmId;
       
   567                     iLandmarksLookupDb->UpdateEntryL(lookupItem);
       
   568                 }
       
   569                 else
       
   570                 {
       
   571                     // landmark not already present in db.
       
   572                     // Create a new entry in the db
       
   573                     aLandmark->AddCategoryL(iLmContactsCatId);
       
   574                     lookupItem.iLmId = iLandmarkDb->AddLandmarkL(*aLandmark);
       
   575                     // update the lookup table
       
   576                     iLandmarksLookupDb->UpdateEntryL(lookupItem);
       
   577                 }
       
   578             }
       
   579             else
       
   580             {
       
   581                 // landmarks are same, means location not modified. So return.
       
   582                 CleanupStack::PopAndDestroy(existingLandmark);
       
   583                 return;
       
   584             }
       
   585 
       
   586             // delete the existing landmark only if it not being refered by other lookup entries.
       
   587 
       
   588             // Check if any other entries are refering this landmark.
       
   589             RArray<TLookupItem> itemArray;
       
   590             CleanupClosePushL(itemArray);
       
   591             iLandmarksLookupDb->FindEntriesByLandmarkIdL(
       
   592                     existingLandmark->LandmarkId(), itemArray);
       
   593 
       
   594             if (itemArray.Count())
       
   595             {
       
   596                 // There are other lookup entries refering this landmark. So do not delete the landmark
       
   597 
       
   598                 // If none of these lookup item's source type is contacts, disassociate 'iLmContactsCatId' category
       
   599                 // from this landmark.
       
   600                 TInt i = 0;
       
   601                 while (i < itemArray.Count())
       
   602                 {
       
   603                     if (itemArray[i].iSource == ESourceContactsPref
       
   604                             || itemArray[i].iSource == ESourceContactsWork
       
   605                             || itemArray[i].iSource == ESourceContactsHome
       
   606                             )
       
   607                     {
       
   608                         // a lookup item exists which is from contacts, so 'iLmContactsCatId' is still valid.
       
   609                         break;
       
   610                     }
       
   611                     i++;
       
   612                 }
       
   613                 if (i == itemArray.Count())
       
   614                 {
       
   615                     // no lookup items from contacts exists refering this landmark.
       
   616                     // so disassociate 'iLmContactsCatId' from this landmark
       
   617 
       
   618                     existingLandmark->RemoveCategory(iLmContactsCatId);
       
   619                     iLandmarkDb->UpdateLandmarkL(*existingLandmark);
       
   620                 }
       
   621             }
       
   622             else
       
   623             {
       
   624                 // no other lookup entry is refering this landmark. 
       
   625 
       
   626                 // check if any other categories is associated with this landmark.
       
   627                 // Assume this landmark is associated with a history entry or a user created landmark entry.
       
   628                 // there is a chance that this landmark is still valid.
       
   629                 // Do not delete the landmark in this case.
       
   630                 RArray<TPosLmItemId> categoryIdArray;
       
   631                 CleanupClosePushL(categoryIdArray);
       
   632                 existingLandmark->GetCategoriesL(categoryIdArray);
       
   633                 if (categoryIdArray.Count() == 1)
       
   634                 {
       
   635                     // only one category i.e, 'iLmContactsCatId' is associated.
       
   636                     // delete the landmark.
       
   637                     iLandmarkDb->RemoveLandmarkL(existingLandmark->LandmarkId());
       
   638                 }
       
   639                 CleanupStack::PopAndDestroy(&categoryIdArray);
       
   640             }
       
   641             CleanupStack::PopAndDestroy(&itemArray);
       
   642             CleanupStack::PopAndDestroy(existingLandmark);
       
   643 
       
   644         }
       
   645         else // entry not present in lookup table
       
   646         {
       
   647             // Add the entry into the lookup table and update landmarks db.
       
   648             HandleEntryAdditionL(aLandmark, aUid, aSourceType);
       
   649         }
       
   650     }
       
   651 }
       
   652 
       
   653 // -----------------------------------------------------------------------------
       
   654 // CMyLocationsDatabaseManager::HandleEntryDeletionL()
       
   655 // Handles the entry deletion in lookup table and landmarks db.
       
   656 // -----------------------------------------------------------------------------
       
   657 //
       
   658 void CMyLocationsDatabaseManager::HandleEntryDeletionL(const TUint32 aUid,
       
   659                                                 const TUint32 aSourceType)
       
   660 {
       
   661     __TRACE_CALLSTACK;
       
   662     TLookupItem lookupItem;
       
   663     lookupItem.iUid = aUid;
       
   664     lookupItem.iSource = aSourceType;
       
   665 
       
   666     if (aSourceType == ESourceContactsPref || aSourceType
       
   667             == ESourceContactsWork || aSourceType == ESourceContactsHome)
       
   668     {
       
   669         // Behavior: In the context of contacts, if a contact is deleted, the user is not interested in
       
   670         // that contact's data, hence its address as well. So, delete the corresponding entries from 
       
   671         // both lookup table and iLandmarkDb.  
       
   672         // Before deleting the entry from iLandmarkDb, make sure that this entry is not being refered by
       
   673         // other entries of the lookup table. If it is being refered by other entries in lookup table, then
       
   674         // do not delete the landmark.
       
   675 
       
   676         // Find the corresponding landmark uid
       
   677         if (iLandmarksLookupDb->FindEntryL(lookupItem))
       
   678         {
       
   679             // delete the lookup entry.
       
   680             iLandmarksLookupDb->DeleteEntryL(lookupItem);
       
   681 
       
   682             // Check if any other entries are refering this landmark.
       
   683             RArray<TLookupItem> itemArray;
       
   684             CleanupClosePushL(itemArray);
       
   685             iLandmarksLookupDb->FindEntriesByLandmarkIdL(lookupItem.iLmId,
       
   686                     itemArray);
       
   687 
       
   688             if (itemArray.Count())
       
   689             {
       
   690                 // There are other lookup entries refering this landmark. So do not delete the landmark
       
   691 
       
   692                 // If none of these lookup item's source type is contacts, disassociate 'iLmContactsCatId' category
       
   693                 // from this landmark.
       
   694                 TInt i = 0;
       
   695                 while (i < itemArray.Count())
       
   696                 {
       
   697                     if (itemArray[i].iSource == ESourceContactsPref
       
   698                             || itemArray[i].iSource == ESourceContactsWork
       
   699                             || itemArray[i].iSource == ESourceContactsHome)
       
   700                     {
       
   701                         // a lookup item exists which is from contacts/calendar, so 'iLmContactsCatId' is still valid.
       
   702                         break;
       
   703                     }
       
   704                     i++;
       
   705                 }
       
   706                 if ( i == itemArray.Count() )
       
   707                 {
       
   708                     // no lookup items from contacts exists refering this landmark.
       
   709                     // so disassociate 'iLmContactsCatId' from this landmark
       
   710 
       
   711                     CPosLandmark* landmark = iLandmarkDb->ReadLandmarkLC(
       
   712                             lookupItem.iLmId);
       
   713                     landmark->RemoveCategory(iLmContactsCatId);
       
   714                     iLandmarkDb->UpdateLandmarkL(*landmark);
       
   715                     CleanupStack::PopAndDestroy(landmark);
       
   716                 }
       
   717             }
       
   718             else
       
   719             {
       
   720                 // no other lookup entry is refering this landmark. 
       
   721 
       
   722                 // check if any other categories is associated with this landmark.
       
   723                 // Assume this landmark is associated with a history entry or a user created landmark entry.
       
   724                 // there is a chance that this landmark is still valid.
       
   725                 // Do not delete the landmark in this case.
       
   726                 CPosLandmark* landmark = iLandmarkDb->ReadLandmarkLC(
       
   727                         lookupItem.iLmId);
       
   728                 RArray<TPosLmItemId> categoryIdArray;
       
   729                 CleanupClosePushL(categoryIdArray);
       
   730                 landmark->GetCategoriesL(categoryIdArray);
       
   731                 if (categoryIdArray.Count() == 1)
       
   732                 {
       
   733                     // only one category i.e, 'iLmCalendarCatId' is associated.
       
   734                     // delete the landmark.
       
   735                     iLandmarkDb->RemoveLandmarkL(lookupItem.iLmId);
       
   736                 }
       
   737 
       
   738                 CleanupStack::PopAndDestroy(&categoryIdArray);
       
   739                 CleanupStack::PopAndDestroy(landmark);
       
   740             }
       
   741             CleanupStack::PopAndDestroy(&itemArray);
       
   742         }
       
   743     }
       
   744 
       
   745     else if (aSourceType == ESourceLandmarks)
       
   746     {
       
   747         // Landmarks item deleted. So delete corresponding lookup entries.
       
   748         RArray<TLookupItem> itemArray;
       
   749         CleanupClosePushL(itemArray);
       
   750         iLandmarksLookupDb->FindEntriesByLandmarkIdL(aUid, itemArray);
       
   751         for (TInt i = 0; i < itemArray.Count(); i++)
       
   752         {
       
   753             iLandmarksLookupDb->DeleteEntryL(itemArray[i]);
       
   754         }
       
   755 
       
   756         CleanupStack::PopAndDestroy(&itemArray);
       
   757 
       
   758         DeleteFromMylocationsDbL(aUid, aSourceType);
       
   759     }
       
   760 }
       
   761 
       
   762 
       
   763 // -----------------------------------------------------------------------------
       
   764 // CMyLocationsDatabaseManager::GetLandmarkFullAddress()
       
   765 // Gets the comma separated full address of the given landmark.
       
   766 // -----------------------------------------------------------------------------
       
   767 //
       
   768 void CMyLocationsDatabaseManager::GetLandmarkFullAddress(
       
   769         TBuf<KMaxAddressLength>& aLandmarkAddress,
       
   770         const CPosLandmark* aLandmark)
       
   771 {
       
   772     TPtrC tempStr;
       
   773     TInt retStatus;
       
   774     TBool addressEmtpy = ETrue;
       
   775     retStatus = aLandmark->GetLandmarkName(tempStr);
       
   776     if (retStatus == KErrNone && tempStr.Length())
       
   777     {
       
   778         aLandmarkAddress.Copy(tempStr);
       
   779         addressEmtpy = EFalse;
       
   780     }
       
   781 
       
   782     retStatus = aLandmark->GetPositionField(EPositionFieldStreet, tempStr);
       
   783     if (retStatus == KErrNone && tempStr.Length())
       
   784     {
       
   785         if (!addressEmtpy)
       
   786         {
       
   787             aLandmarkAddress.Append(KSeparator);
       
   788             aLandmarkAddress.Append(KSpace);
       
   789             aLandmarkAddress.Append(tempStr);
       
   790         }
       
   791         else
       
   792         {
       
   793             aLandmarkAddress.Copy(tempStr);
       
   794             addressEmtpy = EFalse;
       
   795         }
       
   796     }
       
   797 
       
   798     retStatus = aLandmark->GetPositionField(EPositionFieldCity, tempStr);
       
   799     if (retStatus == KErrNone && tempStr.Length())
       
   800     {
       
   801         if (!addressEmtpy)
       
   802         {
       
   803             aLandmarkAddress.Append(KSeparator);
       
   804             aLandmarkAddress.Append(KSpace);
       
   805             aLandmarkAddress.Append(tempStr);
       
   806         }
       
   807         else
       
   808         {
       
   809             aLandmarkAddress.Copy(tempStr);
       
   810             addressEmtpy = EFalse;
       
   811         }
       
   812     }
       
   813 
       
   814     retStatus = aLandmark->GetPositionField(EPositionFieldState, tempStr);
       
   815     if (retStatus == KErrNone && tempStr.Length())
       
   816     {
       
   817         if (!addressEmtpy)
       
   818         {
       
   819             aLandmarkAddress.Append(KSeparator);
       
   820             aLandmarkAddress.Append(KSpace);
       
   821             aLandmarkAddress.Append(tempStr);
       
   822         }
       
   823         else
       
   824         {
       
   825             aLandmarkAddress.Copy(tempStr);
       
   826             addressEmtpy = EFalse;
       
   827         }
       
   828     }
       
   829 
       
   830     retStatus = aLandmark->GetPositionField(EPositionFieldCountry, tempStr);
       
   831     if (retStatus == KErrNone && tempStr.Length())
       
   832     {
       
   833         if (!addressEmtpy)
       
   834         {
       
   835             aLandmarkAddress.Append(KSeparator);
       
   836             aLandmarkAddress.Append(KSpace);
       
   837             aLandmarkAddress.Append(tempStr);
       
   838         }
       
   839         else
       
   840         {
       
   841             aLandmarkAddress.Copy(tempStr);
       
   842             addressEmtpy = EFalse;
       
   843         }
       
   844     }
       
   845 }
       
   846 
       
   847 // -----------------------------------------------------------------------------
       
   848 // CMyLocationsDatabaseManager::CheckCategoryAvailabilityL()
       
   849 // Checks if given category id is found in the database pointed by category manager.
       
   850 // -----------------------------------------------------------------------------
       
   851 //
       
   852 void CMyLocationsDatabaseManager::CheckCategoryAvailabilityL(
       
   853         CPosLmCategoryManager* aCategoryManager, const TUint32 aCategoryId)
       
   854 {
       
   855     __TRACE_CALLSTACK;
       
   856     CPosLandmarkCategory *category = aCategoryManager->ReadCategoryLC(
       
   857             aCategoryId);
       
   858     CleanupStack::PopAndDestroy(category);
       
   859 }
       
   860 // -----------------------------------------------------------------------------
       
   861 // CMyLocationsDatabaseManager::CheckAndReadLandmarkL()
       
   862 // Checks if given landmark id is found in the database and returns the read landmark.
       
   863 // -----------------------------------------------------------------------------
       
   864 //
       
   865 CPosLandmark* CMyLocationsDatabaseManager::CheckAndReadLandmarkL(
       
   866         CPosLandmarkDatabase* aDb, const TUint32 aLmId)
       
   867 {
       
   868     __TRACE_CALLSTACK;
       
   869     CPosLandmark* lm = aDb->ReadLandmarkLC(aLmId);
       
   870     CleanupStack::Pop(lm);    
       
   871     return lm;
       
   872 }
       
   873 // -----------------------------------------------------------------------------
       
   874 // CMyLocationsDatabaseManager::AddToMylocationsDbL()
       
   875 // Adds the entry into the mylocations database and updates the lookup table.
       
   876 // -----------------------------------------------------------------------------
       
   877 //
       
   878 void CMyLocationsDatabaseManager::AddToMylocationsDbL(CPosLandmark* aLandmark,
       
   879         const TUint32 aUid, const TUint32 aSourceType)
       
   880 {
       
   881     __TRACE_CALLSTACK;
       
   882     if (aSourceType == ESourceLandmarks)
       
   883     {
       
   884         CPosLandmark* landmark = iLandmarkDb->ReadLandmarkLC(aUid);
       
   885         RArray<TPosLmItemId> catArray;
       
   886         CleanupClosePushL( catArray );
       
   887         landmark->GetCategoriesL(catArray);
       
   888        
       
   889 
       
   890         // add the categories in the mylocations database for this landmark
       
   891         for (TInt i = 0; i < catArray.Count(); i++)
       
   892         {
       
   893             TLookupItem lItem;
       
   894             lItem.iUid = catArray[i];
       
   895             lItem.iSource = ESourceLandmarksUserCat;
       
   896             lItem.iLmId = 0;
       
   897             if (!iMylocationsLookupDb->FindEntryL(lItem))
       
   898             {
       
   899                 lItem.iSource = ESourceLandmarksContactsCat;
       
   900                 if (!iMylocationsLookupDb->FindEntryL(lItem))
       
   901                 {
       
   902                     // means this is global category, so just add it
       
   903                     lItem.iLmId = lItem.iUid;
       
   904                 }
       
   905             }
       
   906             TRAP_IGNORE( aLandmark->AddCategoryL( lItem.iLmId ) );
       
   907         }
       
   908 
       
   909         CleanupStack::PopAndDestroy( &catArray );       
       
   910         TLookupItem lookupItem;
       
   911         lookupItem.iUid = aUid;
       
   912         lookupItem.iSource = aSourceType;
       
   913         TRAP_IGNORE( lookupItem.iLmId = iMyLocationsLandmarksDb->AddLandmarkL( *aLandmark ) );
       
   914         CleanupStack::PopAndDestroy(landmark);
       
   915         iMylocationsLookupDb->CreateEntryL(lookupItem);
       
   916     }
       
   917 }
       
   918 
       
   919 // -----------------------------------------------------------------------------
       
   920 // CMyLocationsDatabaseManager::ModifyMylocationsDbL()
       
   921 // Adds the entry into the mylocations database and updates the lookup table.
       
   922 // -----------------------------------------------------------------------------
       
   923 //
       
   924 void CMyLocationsDatabaseManager::ModifyMylocationsDbL(CPosLandmark* aLandmark,
       
   925         const TUint32 aUid, const TUint32 aSourceType)
       
   926 {
       
   927     __TRACE_CALLSTACK;
       
   928     TLookupItem lookupItem;
       
   929     lookupItem.iUid = aUid;
       
   930     lookupItem.iSource = aSourceType;
       
   931     iMylocationsLookupDb->FindEntryL(lookupItem);
       
   932     iMylocationsLookupDb->DeleteEntryL(lookupItem);
       
   933     iMyLocationsLandmarksDb->RemoveLandmarkL(lookupItem.iLmId);
       
   934     AddToMylocationsDbL(aLandmark, lookupItem.iUid, lookupItem.iSource);
       
   935 }
       
   936 
       
   937 // -----------------------------------------------------------------------------
       
   938 // CMyLocationsDatabaseManager::DeleteFromMylocationsDbL()
       
   939 // Deletes the entry from the mylocations database and updates the lookup table.
       
   940 // -----------------------------------------------------------------------------
       
   941 //
       
   942 void CMyLocationsDatabaseManager::DeleteFromMylocationsDbL(const TUint32 aUid,
       
   943                                                            const TUint32 aSourceType)
       
   944 {
       
   945     __TRACE_CALLSTACK;
       
   946     TLookupItem lookupItem;
       
   947     lookupItem.iUid = aUid;
       
   948     lookupItem.iSource = aSourceType;
       
   949     iMylocationsLookupDb->FindEntryL(lookupItem);
       
   950 
       
   951     iMyLocationsLandmarksDb->RemoveLandmarkL(lookupItem.iLmId);
       
   952     iMylocationsLookupDb->DeleteEntryL(lookupItem);
       
   953 }
       
   954 // -----------------------------------------------------------------------------
       
   955 // CMyLocationsDatabaseManager::CreateCategoryL()
       
   956 // Creates a new category in Mylocations Db and adds a corresponding entry in 
       
   957 // mylocations lookup table.
       
   958 // -----------------------------------------------------------------------------
       
   959 //
       
   960 void CMyLocationsDatabaseManager::CreateCategoryL(const TUint32 aUid)
       
   961 {
       
   962     __TRACE_CALLSTACK;// Read the category.
       
   963     CPosLandmarkCategory *category = iLandmarksCatManager->ReadCategoryLC(aUid);
       
   964 
       
   965     TLookupItem lookupItem;
       
   966     lookupItem.iUid = aUid;
       
   967     lookupItem.iSource = ESourceLandmarksUserCat;
       
   968     // Add category to landmarks database
       
   969     TRAPD ( err, (lookupItem.iLmId = iMyLocationsCatManager->AddCategoryL( *category ) ) );
       
   970 
       
   971     if (err == KErrNone)
       
   972     {
       
   973         iMylocationsLookupDb->CreateEntryL(lookupItem);
       
   974     }
       
   975     CleanupStack::PopAndDestroy(category);
       
   976 
       
   977 }
       
   978 
       
   979 
       
   980 // End of file