locationdataharvester/mylocationsengine/src/mylocationsdatabasemanager.cpp
branchGCC_SURGE
changeset 32 9bd2e0ffe298
parent 25 a4fe51dd4d22
parent 31 8db05346071b
equal deleted inserted replaced
25:a4fe51dd4d22 32:9bd2e0ffe298
     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 <EPos_CPosLmNearestCriteria.h>
       
    25 
       
    26 #include <lbsposition.h>
       
    27 //#include <mylocations.rsg>
       
    28 #include <barsread.h>
       
    29 #include <barsc.h>
       
    30 #include <locationservicedefines.h>
       
    31 #include "mylocationsdatabasemanager.h"
       
    32 #include "mylocationlogger.h"
       
    33 #include "mylocationsdefines.h"
       
    34 
       
    35 // separator
       
    36 _LIT( KSeparator, ",");
       
    37 // space
       
    38 _LIT( KSpace, " ");
       
    39 
       
    40 // QString separator
       
    41 const QString KQStringSeparator = ",";
       
    42 // QString space
       
    43 const QString KQStringSpace = " ";
       
    44 
       
    45 // Used to set nearest landmarks search distance criteria
       
    46 const TUint32 KSearchCriteriaDistance = 100; 
       
    47 
       
    48 // -----------------------------------------------------------------------------
       
    49 // CMyLocationsDatabaseManager::ConstructL()
       
    50 // 2nd phase constructor.
       
    51 // -----------------------------------------------------------------------------
       
    52 //
       
    53 void CMyLocationsDatabaseManager::ConstructL()
       
    54 {
       
    55     __TRACE_CALLSTACK;//Open and intialize Landmark DB
       
    56     iLandmarkDb = CPosLandmarkDatabase::OpenL();
       
    57     ExecuteAndDeleteLD(iLandmarkDb->InitializeL());
       
    58 
       
    59     // create landmarks lookup database.
       
    60     iLandmarksLookupDb = CLookupDatabase::NewL(KLandmarksLookupDatabaseName);
       
    61     User::LeaveIfError( iLandmarksLookupDb->Open() );
       
    62  
       
    63     iLocationAppLookupDb = new LocationDataLookupDb();
       
    64     if( !iLocationAppLookupDb->open() )
       
    65     {
       
    66         User::Leave( KErrUnknown );
       
    67     }
       
    68     
       
    69     // Create category manager for landmarks
       
    70     iLandmarksCatManager = CPosLmCategoryManager::NewL(*iLandmarkDb);
       
    71 
       
    72     // open file session
       
    73     User::LeaveIfError(iFsSession.Connect());
       
    74 
       
    75     // Add contacts and calendar  categories
       
    76     iLmContactsCatId = AddMylocationsCategoryL(KContactsCategory);
       
    77     iLmCalendarCatId = AddMylocationsCategoryL( KCalendarCategory );
       
    78 
       
    79 }
       
    80 
       
    81 // -----------------------------------------------------------------------------
       
    82 // CMyLocationsDatabaseManager::CMyLocationsDatabaseManager()
       
    83 // Default constructor.
       
    84 // -----------------------------------------------------------------------------
       
    85 //
       
    86 CMyLocationsDatabaseManager::CMyLocationsDatabaseManager() : iLandmarkDb( NULL ),
       
    87                 iLmContactsCatId( 0 ), iLandmarksLookupDb( NULL ), 
       
    88                 iLocationAppLookupDb( NULL ),
       
    89                 iLandmarksCatManager( NULL )
       
    90 {
       
    91 }
       
    92 
       
    93 // -----------------------------------------------------------------------------
       
    94 // CMyLocationsDatabaseManager::_CMyLocationsDatabaseManager()
       
    95 // Destructor.
       
    96 // -----------------------------------------------------------------------------
       
    97 //
       
    98 CMyLocationsDatabaseManager::~CMyLocationsDatabaseManager()
       
    99 {
       
   100     __TRACE_CALLSTACK;// delete member variables.
       
   101     if (iLandmarksLookupDb)
       
   102     {
       
   103         iLandmarksLookupDb->Close();
       
   104         delete iLandmarksLookupDb;
       
   105     }
       
   106     if (iLocationAppLookupDb)
       
   107     {
       
   108         iLocationAppLookupDb->close();
       
   109         delete iLocationAppLookupDb;
       
   110     }
       
   111 
       
   112     delete iLandmarksCatManager;
       
   113 
       
   114     delete iLandmarkDb;
       
   115 
       
   116     // close the file session
       
   117     iFsSession.Close();
       
   118 
       
   119 }
       
   120 
       
   121 // -----------------------------------------------------------------------------
       
   122 // CMyLocationsDatabaseManager::AddMylocationsCategoryL()
       
   123 // Adds the category to the mylocations and landmarks database..
       
   124 // -----------------------------------------------------------------------------
       
   125 //
       
   126 TUint32 CMyLocationsDatabaseManager::AddMylocationsCategoryL( const TDesC&  aCategoryName )
       
   127 {
       
   128     __TRACE_CALLSTACK;//Open the resource file
       
   129     
       
   130     TPosLmItemId catId = 0;
       
   131     
       
   132     //create category
       
   133     CPosLandmarkCategory *category = CPosLandmarkCategory::NewL();
       
   134     CleanupStack::PushL(category);
       
   135     category->SetCategoryNameL( aCategoryName );
       
   136     
       
   137     // Add category to landmarks database
       
   138     TRAPD ( error, ( catId = iLandmarksCatManager->AddCategoryL( *category ) ) );
       
   139     if (error == KErrNone || error == KErrAlreadyExists)
       
   140     {
       
   141         catId = iLandmarksCatManager->GetCategoryL( aCategoryName );
       
   142     }
       
   143 
       
   144     CleanupStack::PopAndDestroy(category);
       
   145 
       
   146     return catId;
       
   147 }
       
   148 
       
   149 // -----------------------------------------------------------------------------
       
   150 // CMyLocationsDatabaseManager::UpdateDatabaseL()
       
   151 // Updates the location into the landmark database and lookup table. Based on 
       
   152 // the entry source type and the entry change type the updation can be 
       
   153 // addition/modification/deletion.
       
   154 // -----------------------------------------------------------------------------
       
   155 //
       
   156 void CMyLocationsDatabaseManager::UpdateDatabaseL(CPosLandmark* aLandmark,
       
   157         const TUint32 aUid, const TUint32 aSourceType, const TEntryChangeType aChangeType)
       
   158 {
       
   159     __TRACE_CALLSTACK;//open the lookup database
       
   160     switch (aChangeType)
       
   161     {
       
   162     // if the entry is added
       
   163     case EEntryAdded:
       
   164     {
       
   165         // Handle this entry in the lookup table and update landmarks db.
       
   166         HandleEntryAdditionL(aLandmark, aUid, aSourceType);
       
   167         break;
       
   168     }
       
   169         // if the entry is modified
       
   170     case EEntryModified:
       
   171     {
       
   172         // Handle this entry in the lookup table and update landmarks db.
       
   173         HandleEntryModificationL(aLandmark, aUid, aSourceType);
       
   174         break;
       
   175     }
       
   176         // if the entry is deleted
       
   177     case EEntryDeleted:
       
   178     {
       
   179         // Handle this entry in the lookup table and update landmarks db.
       
   180         HandleEntryDeletionL(aUid, aSourceType);
       
   181         break;
       
   182     }
       
   183     }
       
   184 
       
   185 }
       
   186 
       
   187 // -----------------------------------------------------------------------------
       
   188 // CMyLocationsDatabaseManager::CheckIfDuplicateExistsL()
       
   189 // Checks if this landmark is already present in database. If present returns the landmark id, else 0
       
   190 // -----------------------------------------------------------------------------
       
   191 //
       
   192 TPosLmItemId CMyLocationsDatabaseManager::CheckIfDuplicateExistsL(
       
   193                                     const CPosLandmark* aLandmark)
       
   194 {
       
   195     __TRACE_CALLSTACK;// Stores the found duplicate landmark's id. 
       
   196     TPosLmItemId retId = 0;
       
   197 
       
   198     // Initially filter only the landmarks which are nearer to the current landmark.
       
   199     // Then we can make a duplicate check on each of the found landmarks.
       
   200 
       
   201     // create a search object.
       
   202     CPosLandmarkSearch* search = CPosLandmarkSearch::NewL(
       
   203             *iLandmarkDb);
       
   204     CleanupStack::PushL(search);
       
   205 
       
   206     TBuf<KMaxAddressLength> lmAddress1;
       
   207     GetLandmarkFullAddress( lmAddress1, aLandmark );
       
   208     QString str1 = QString( (QChar*)lmAddress1.Ptr(), lmAddress1.Length());
       
   209 
       
   210     // create nearest search criteria object
       
   211     TLocality position( TCoordinate( 0, 0), 0 );
       
   212     aLandmark->GetPosition( position );
       
   213     CPosLmNearestCriteria* nearestCriteria = 
       
   214                 CPosLmNearestCriteria::NewLC( 
       
   215                         TCoordinate( position.Latitude(), position.Longitude() ) );
       
   216     nearestCriteria->SetMaxDistance( KSearchCriteriaDistance );
       
   217     
       
   218     // Start the search and execute it at once.
       
   219     ExecuteAndDeleteLD( search->StartLandmarkSearchL( *nearestCriteria ) );
       
   220     CleanupStack::PopAndDestroy( nearestCriteria );
       
   221 
       
   222     // Retrieve an iterator to access the matching landmarks.
       
   223     CPosLmItemIterator* iter = search->MatchIteratorL();
       
   224     CleanupStack::PushL(iter);
       
   225 
       
   226     // Iterate the search matches.
       
   227     TPosLmItemId lmId;
       
   228 
       
   229     while( ( lmId = iter->NextL() ) != KPosLmNullItemId )
       
   230     {
       
   231         CPosLandmark* lm = iLandmarkDb->ReadLandmarkLC( lmId );
       
   232         TBuf<KMaxAddressLength> lmAddress2;
       
   233         GetLandmarkFullAddress( lmAddress2, lm );
       
   234         QString str2 = QString( (QChar*)lmAddress2.Ptr(), lmAddress2.Length());
       
   235         CleanupStack::PopAndDestroy( lm );
       
   236         
       
   237         if( str1 == str2 )
       
   238         {
       
   239             retId = lmId;
       
   240             break;
       
   241         }
       
   242     }
       
   243 
       
   244     CleanupStack::PopAndDestroy(iter);
       
   245     CleanupStack::PopAndDestroy(search);
       
   246 
       
   247     return retId;
       
   248 }
       
   249 
       
   250 // -----------------------------------------------------------------------------
       
   251 // CMyLocationsDatabaseManager::CompareLandmarks()
       
   252 // Compares two landmarks. Only the text fields, landmark name, street, city, state country and 
       
   253 // postal code are compared.
       
   254 // -----------------------------------------------------------------------------
       
   255 //
       
   256 TBool CMyLocationsDatabaseManager::CompareLandmarks(
       
   257         const CPosLandmark* aLandmark1, const CPosLandmark* aLandmark2 )
       
   258 {
       
   259     __TRACE_CALLSTACK;
       
   260 
       
   261     TBuf<KMaxAddressLength> lmAddress1;
       
   262     GetLandmarkFullAddress( lmAddress1, aLandmark1 );
       
   263     QString str1 = QString( (QChar*)lmAddress1.Ptr(), lmAddress1.Length());
       
   264 
       
   265     TBuf<KMaxAddressLength> lmAddress2;
       
   266     GetLandmarkFullAddress( lmAddress2, aLandmark2 );
       
   267     QString str2 = QString( (QChar*)lmAddress2.Ptr(), lmAddress2.Length());
       
   268 
       
   269     if( str1 == str2 )
       
   270         return ETrue;
       
   271     else
       
   272         return EFalse;
       
   273     
       
   274     
       
   275 }
       
   276 
       
   277 // -----------------------------------------------------------------------------
       
   278 // CMyLocationsDatabaseManager::HandleEntryAdditionL()
       
   279 // Handles the entry addition in lookup table and landmarks db
       
   280 // -----------------------------------------------------------------------------
       
   281 //
       
   282 void CMyLocationsDatabaseManager::HandleEntryAdditionL(CPosLandmark* aLandmark,
       
   283         const TUint32 aUid, const TUint32 aSourceType)
       
   284 {
       
   285     __TRACE_CALLSTACK;
       
   286     // Create a lookup item
       
   287     QLookupItem lookupItem;
       
   288     lookupItem.mSourceUid = aUid;
       
   289     lookupItem.mSourceType = aSourceType;
       
   290     lookupItem.mDestId = 0;
       
   291     lookupItem.mIconType = QLookupItem::EIconTypeDefault;
       
   292     lookupItem.mIsDuplicate = 0;
       
   293     lookupItem.mIconPath = "";
       
   294     lookupItem.mMapTilePath = "";
       
   295     
       
   296     //fill address into lookup item.
       
   297     FillLookupItemAddressDetails( aLandmark, lookupItem );
       
   298 
       
   299     if ( aSourceType == ESourceLandmarks )
       
   300     {
       
   301         // Logic: check if the entry is already present in lookupdb. 
       
   302         // If present, it means the landmark corresponds to a contact/calendar. So ignore it.
       
   303         // If not present, it means the landmark is created directly into the landmarks db. So add
       
   304         // it in lookupdb as well.
       
   305         
       
   306         // check if the entry is already present in lookup db.
       
   307         QList<QLookupItem> itemArray;
       
   308         iLocationAppLookupDb->findEntriesByLandmarkId( aUid, itemArray );
       
   309         if( itemArray.count() )
       
   310         {
       
   311             return;
       
   312         }
       
   313         else
       
   314         {
       
   315             lookupItem.mDestId = aUid;
       
   316             iLocationAppLookupDb->createEntry( lookupItem );
       
   317             return;
       
   318         }
       
   319     }
       
   320 
       
   321     TPosLmItemId catId;
       
   322     if( aSourceType == ESourceCalendar )
       
   323     {
       
   324         // category id to calendar
       
   325         catId = iLmCalendarCatId;
       
   326     }
       
   327     else 
       
   328     {
       
   329         // remove landmark name, which is basically contact's name.
       
   330         aLandmark->SetLandmarkNameL( KNullDesC );
       
   331         // category id to contacts
       
   332         catId = iLmContactsCatId;
       
   333     }
       
   334     // check if this landmark is already present in database
       
   335     TPosLmItemId dupLmId = CheckIfDuplicateExistsL( aLandmark );
       
   336     if ( dupLmId )
       
   337     {
       
   338         // landmark already present in db. get the details
       
   339         CPosLandmark* dupLandmark = iLandmarkDb->ReadLandmarkLC(dupLmId);
       
   340         if( dupLandmark )
       
   341         {
       
   342             // add category.
       
   343             dupLandmark->AddCategoryL( catId );
       
   344             // update the landmark object in the db
       
   345             iLandmarkDb->UpdateLandmarkL( *dupLandmark );
       
   346             CleanupStack::PopAndDestroy( dupLandmark );
       
   347         }
       
   348 
       
   349         // point the lookup item's landmark uid to the existing landmark.
       
   350         lookupItem.mDestId = dupLmId;
       
   351         if( aSourceType == ESourceCalendar )
       
   352         {
       
   353             // set duplicate flag to true. only if it is calendar entry.
       
   354             // for contacts duplicate doesnot hold good as the location name is the contact name.
       
   355         
       
   356             // set duplicate only if there are calendar entries already pointing to this landmark. 
       
   357             if( IsDuplicateEntry( dupLmId ) )
       
   358             {
       
   359                 lookupItem.mIsDuplicate = 1;
       
   360             }
       
   361         }
       
   362     }
       
   363     else // it is a new entry, so add into the database
       
   364     {
       
   365         // add category.
       
   366         aLandmark->AddCategoryL( catId );
       
   367         // add the landmark into the db. 
       
   368         // point the lookup item's landmark uid to the newly created landmark in the db.
       
   369         lookupItem.mDestId = iLandmarkDb->AddLandmarkL( *aLandmark );
       
   370     }
       
   371 
       
   372     // create the entry in the lookup table.
       
   373     iLocationAppLookupDb->createEntry( lookupItem );
       
   374 }
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 // CMyLocationsDatabaseManager::HandleEntryModificationL()
       
   378 // Handles the entry modification in the lookup table and landmarks db.
       
   379 // -----------------------------------------------------------------------------
       
   380 //
       
   381 void CMyLocationsDatabaseManager::HandleEntryModificationL(
       
   382         CPosLandmark* aLandmark, const TUint32 aUid, const TUint32 aSourceType )
       
   383 {
       
   384     __TRACE_CALLSTACK;
       
   385     if ( aSourceType == ESourceLandmarks )
       
   386     {
       
   387         HandleLandmarkModificationL( aLandmark, aUid );
       
   388         return;
       
   389     }
       
   390 
       
   391     QLookupItem lookupItem;
       
   392     lookupItem.mSourceUid = aUid;
       
   393     lookupItem.mSourceType = aSourceType;
       
   394     lookupItem.mIconType = QLookupItem::EIconTypeDefault;
       
   395 
       
   396     // Behavior: If an entry is modified, 
       
   397     // If this entry is not present in lookup table. add the entry and update the landmarks db.
       
   398     // If this entry is already present in lookup table, check if the location info is modified or not.
       
   399     // If the location info is modified, delete the landmark from db and add the new landmark
       
   400     // into the db. 
       
   401     // Before deletion make sure that the landmark is not being refered by other lookup entries.
       
   402 
       
   403     // find the entry in the lookup table.
       
   404     if ( iLocationAppLookupDb->findEntryBySourceIdAndType( lookupItem ) )
       
   405     {
       
   406         //fill address into lookup item.
       
   407         FillLookupItemAddressDetails( aLandmark, lookupItem );
       
   408         
       
   409         QString locationName = lookupItem.mName;
       
   410     
       
   411         TPosLmItemId catId;
       
   412         
       
   413         if( aSourceType == ESourceCalendar )
       
   414         {
       
   415             catId = iLmCalendarCatId;
       
   416         }
       
   417         else
       
   418         {
       
   419             // remove landmark name, which is basically contact's name.
       
   420             aLandmark->SetLandmarkNameL( KNullDesC );
       
   421             
       
   422             // category id to contacts
       
   423             catId = iLmContactsCatId;
       
   424         }
       
   425 
       
   426         
       
   427         // check if the location info is modified by comparing the new landmark with the existing landmark
       
   428         CPosLandmark* existingLandmark = NULL;
       
   429         TRAPD( error, ( existingLandmark = 
       
   430                CheckAndReadLandmarkL( iLandmarkDb, lookupItem.mDestId ) ) );
       
   431         CleanupStack::PushL( existingLandmark );
       
   432         if ( error == KErrNotFound )
       
   433         {
       
   434             // Landmarks item deleted. So delete corresponding lookup entries.
       
   435             QList<QLookupItem> itemArray;
       
   436             iLocationAppLookupDb->findEntriesByLandmarkId( lookupItem.mDestId, itemArray );
       
   437             for ( int i = 0; i < itemArray.count(); i++)
       
   438             {
       
   439                 iLocationAppLookupDb->deleteEntryBySourceIdAndType( itemArray[i] );
       
   440             }
       
   441 
       
   442             // Add the entry into the lookup table and update landmarks db.
       
   443             HandleEntryAdditionL( aLandmark, aUid, aSourceType );
       
   444             
       
   445             CleanupStack::PopAndDestroy( existingLandmark );
       
   446             return;
       
   447         }
       
   448 
       
   449         if ( !CompareLandmarks( existingLandmark, aLandmark ) )
       
   450         {
       
   451             // landmarks are not same, means location information is modified.
       
   452 
       
   453             // Check if the new landmark is already in db.
       
   454             TPosLmItemId dupLmId = CheckIfDuplicateExistsL( aLandmark );
       
   455             if ( dupLmId )
       
   456             {
       
   457                 // landmark already present in db. get the details
       
   458                 CPosLandmark* dupLandmark = iLandmarkDb->ReadLandmarkLC( dupLmId );
       
   459                 if ( dupLandmark )
       
   460                 {
       
   461                     // add category.
       
   462                     dupLandmark->AddCategoryL( catId );
       
   463 
       
   464                     // update the landmark object in the db
       
   465                     iLandmarkDb->UpdateLandmarkL( *dupLandmark );
       
   466                 }
       
   467                 CleanupStack::PopAndDestroy( dupLandmark );
       
   468 
       
   469                 // update the lookup item to refer to the newly created landmark.
       
   470                 lookupItem.mDestId = dupLmId;
       
   471                 if( aSourceType == ESourceCalendar )
       
   472                 {
       
   473                     // for contacts duplicate doesnot hold good as the location name is the contact name.
       
   474                     if( !lookupItem.mIsDuplicate )
       
   475                     {
       
   476                         // if current lookup item duplicate property is 0, then remove next corresponding
       
   477                         // calendar lookup entry duplicate property.
       
   478                         // this is required because the current entry will be pointing to a new landmark.
       
   479                         UnsetDuplicateNextCalEntry( existingLandmark->LandmarkId() );
       
   480                     } 
       
   481 
       
   482                     // set duplicate only if there are calendar entries already pointing to this landmark. 
       
   483                     if( IsDuplicateEntry( dupLmId ) )
       
   484                     {
       
   485                         lookupItem.mIsDuplicate = 1;
       
   486                     }
       
   487 
       
   488                 }
       
   489                 
       
   490                 iLocationAppLookupDb->updateEntryBySourceIdAndType( lookupItem );
       
   491             }
       
   492             else
       
   493             {
       
   494                 // landmark not already present in db.
       
   495                 // Create a new entry in the db
       
   496                 aLandmark->AddCategoryL( catId );
       
   497                 lookupItem.mDestId = iLandmarkDb->AddLandmarkL( *aLandmark );
       
   498                 if( aSourceType == ESourceCalendar )
       
   499                 {
       
   500                     // for contacts duplicate doesnot hold good as the location name is the contact name.
       
   501                     if( !lookupItem.mIsDuplicate )
       
   502                     {
       
   503                         // if current lookup item duplicate property is 0, then remove next corresponding
       
   504                         // calendar lookup entry duplicate property.
       
   505                         // this is required because the current entry will be pointing to a new landmark.
       
   506                         UnsetDuplicateNextCalEntry( existingLandmark->LandmarkId() );
       
   507                     } 
       
   508                 }
       
   509                 
       
   510                 lookupItem.mIsDuplicate = 0;
       
   511                 // update the lookup table
       
   512                 iLocationAppLookupDb->updateEntryBySourceIdAndType( lookupItem );
       
   513             }
       
   514         }
       
   515         else
       
   516         {
       
   517             // landmarks are same, means location not modified. So return.
       
   518             if( aSourceType == ESourceContactsPref
       
   519                                     || aSourceType == ESourceContactsWork
       
   520                                     || aSourceType == ESourceContactsHome
       
   521                                     )
       
   522             {
       
   523                 // in case of contacts, there is a chance that contact name is modified. 
       
   524                 // so update the lookup database entry with that name.
       
   525                 lookupItem.mName = locationName;
       
   526                 iLocationAppLookupDb->updateEntryBySourceIdAndType( lookupItem );
       
   527             }
       
   528 
       
   529             CleanupStack::PopAndDestroy( existingLandmark );
       
   530             return;
       
   531         }
       
   532 
       
   533         // delete the existing landmark only if it not being refered by other lookup entries.
       
   534 
       
   535         // Check if any other entries are refering this landmark.
       
   536         QList<QLookupItem> itemArray;
       
   537         iLocationAppLookupDb->findEntriesByLandmarkId(
       
   538                 existingLandmark->LandmarkId(), itemArray );
       
   539 
       
   540         if ( itemArray.count() )
       
   541         {
       
   542             // There are other lookup entries refering this landmark. So do not delete the landmark
       
   543 
       
   544             // If none of these lookup item's source type is current source type, disassociate 'catId' category
       
   545             // from this landmark.
       
   546             TInt i = 0;
       
   547             while ( i < itemArray.count() )
       
   548             {
       
   549                 if( aSourceType == ESourceCalendar )
       
   550                 {
       
   551                     if ( itemArray[i].mSourceType == aSourceType )
       
   552                     {
       
   553                         // a lookup item exists which is from calendar, so 'catId' is still valid.
       
   554                         break;
       
   555                     }
       
   556                  }
       
   557                 else 
       
   558                 {
       
   559                     // a lookup item exists which is from contacts, so 'catId' is still valid.
       
   560                     break;
       
   561                 }
       
   562                 i++;
       
   563             }
       
   564             if ( i == itemArray.count() )
       
   565             {
       
   566                 // no lookup items from current source type exists refering this landmark.
       
   567                 // so disassociate 'catId' from this landmark
       
   568 
       
   569                 existingLandmark->RemoveCategory( catId );
       
   570                 iLandmarkDb->UpdateLandmarkL( *existingLandmark );
       
   571             }
       
   572         }
       
   573         else
       
   574         {
       
   575             // no other lookup entry is refering this landmark. 
       
   576             // delete the landmark.
       
   577             iLandmarkDb->RemoveLandmarkL( existingLandmark->LandmarkId() );
       
   578         }
       
   579         CleanupStack::PopAndDestroy( existingLandmark );
       
   580 
       
   581     }
       
   582     else // entry not present in lookup table
       
   583     {
       
   584         // Add the entry into the lookup table and update landmarks db.
       
   585         HandleEntryAdditionL( aLandmark, aUid, aSourceType );
       
   586     }
       
   587 }
       
   588 
       
   589 // -----------------------------------------------------------------------------
       
   590 // CMyLocationsDatabaseManager::HandleEntryDeletionL()
       
   591 // Handles the entry deletion in lookup table and landmarks db.
       
   592 // -----------------------------------------------------------------------------
       
   593 //
       
   594 void CMyLocationsDatabaseManager::HandleEntryDeletionL(const TUint32 aUid,
       
   595                                                 const TUint32 aSourceType)
       
   596 {
       
   597     __TRACE_CALLSTACK;
       
   598     QLookupItem lookupItem;
       
   599     lookupItem.mSourceUid = aUid;
       
   600     lookupItem.mSourceType = aSourceType;
       
   601 
       
   602     // Behavior: if an entry is deleted, delete the corresponding entries from 
       
   603     // both lookup table and iLandmarkDb.  
       
   604     // Before deleting the entry from iLandmarkDb, make sure that this entry is not being refered by
       
   605     // other entries of the lookup table. If it is being refered by other entries in lookup table, then
       
   606     // do not delete the landmark.
       
   607  
       
   608     if ( !iLocationAppLookupDb->findEntryBySourceIdAndType( lookupItem ) )
       
   609     {
       
   610         if( aSourceType == ESourceLandmarks )
       
   611         {
       
   612             lookupItem.mDestId = aUid;
       
   613         }
       
   614         else
       
   615         {
       
   616             return;
       
   617         }
       
   618     }
       
   619     
       
   620     // Find the corresponding landmark uid
       
   621     
       
   622 
       
   623     // delete the lookup entry.
       
   624     iLocationAppLookupDb->deleteEntryBySourceIdAndType( lookupItem );
       
   625 
       
   626     // Check if any other entries are refering this landmark.
       
   627     QList<QLookupItem> itemArray;
       
   628     iLocationAppLookupDb->findEntriesByLandmarkId( lookupItem.mDestId, itemArray );
       
   629 
       
   630     if ( itemArray.count() )
       
   631     {
       
   632     
       
   633         if( aSourceType == ESourceLandmarks )
       
   634         {
       
   635             CPosLandmark* lm = NULL;
       
   636         
       
   637             for( int i = 0; i < itemArray.count(); i++ )
       
   638             {
       
   639                 if( itemArray[i].mSourceType == ESourceCalendar )
       
   640                 {
       
   641                     // add landmark entry since a calendar item is present with this location.
       
   642                    if( !lm )
       
   643                    {
       
   644                        lm = CreateLandmarkItemLC( itemArray[i] );
       
   645                    }
       
   646                    lm->AddCategoryL( iLmCalendarCatId );
       
   647                 }
       
   648                 else
       
   649                 {
       
   650                    // add landmark entry since a contact item is present with this location.
       
   651                    if( !lm )
       
   652                    {
       
   653                        QString tempStr = itemArray[i].mName;
       
   654                        itemArray[i].mName = "";
       
   655                        lm = CreateLandmarkItemLC( itemArray[i] );
       
   656                        itemArray[i].mName = tempStr;
       
   657                    }
       
   658                    lm->AddCategoryL( iLmCalendarCatId );
       
   659                 }    
       
   660             }
       
   661 
       
   662             lookupItem.mDestId = iLandmarkDb->AddLandmarkL( *lm );
       
   663             CleanupStack::PopAndDestroy( lm );
       
   664 
       
   665             bool dupUnset = false;
       
   666             for( int i=0; i<itemArray.count(); i++ )
       
   667             {
       
   668                 itemArray[i].mDestId = lookupItem.mDestId;
       
   669                 if( itemArray[i].mSourceType == ESourceCalendar && dupUnset == false )
       
   670                 {
       
   671                     dupUnset = true;
       
   672                     itemArray[i].mIsDuplicate = 0;
       
   673                 }
       
   674                 iLocationAppLookupDb->updateEntryById( itemArray[i] );
       
   675             }   
       
   676             
       
   677             return;
       
   678         }
       
   679 
       
   680         // There are other lookup entries refering this landmark. So do not delete the landmark
       
   681 
       
   682         // If none of these lookup item's source type is current source type, disassociate current source category
       
   683         // from this landmark.
       
   684         TInt i = 0;
       
   685         while ( i < itemArray.count() )
       
   686         {
       
   687             if( aSourceType == ESourceCalendar )
       
   688             {
       
   689                 if( itemArray[i].mSourceType == aSourceType )
       
   690                 {
       
   691                     if( lookupItem.mIsDuplicate == 0 )
       
   692                     {
       
   693                         itemArray[i].mIsDuplicate = 0;
       
   694                         iLocationAppLookupDb->updateEntryById( itemArray[i] );
       
   695                     }
       
   696                     // a lookup item exists which is from calendar, so 'iLmCalendarCatId' is still valid.
       
   697                     break;
       
   698                 }
       
   699         
       
   700             }
       
   701             else if ( itemArray[i].mSourceType == ESourceContactsPref
       
   702                     || itemArray[i].mSourceType == ESourceContactsWork
       
   703                     || itemArray[i].mSourceType == ESourceContactsHome)
       
   704             {
       
   705                 // a lookup item exists which is from contacts, so 'iLmContactsCatId' is still valid.
       
   706                 break;
       
   707             }
       
   708             i++;
       
   709         }
       
   710         if ( i == itemArray.count() )
       
   711         {
       
   712             // no lookup items from current source type exists refering this landmark.
       
   713             // so disassociate current source category from this landmark
       
   714 
       
   715             CPosLandmark* landmark = iLandmarkDb->ReadLandmarkLC( lookupItem.mDestId );
       
   716             if( aSourceType == ESourceCalendar )
       
   717             {
       
   718                 landmark->RemoveCategory( iLmCalendarCatId );
       
   719             }
       
   720             else
       
   721             {
       
   722                 landmark->RemoveCategory( iLmContactsCatId );
       
   723             }
       
   724             
       
   725             iLandmarkDb->UpdateLandmarkL( *landmark );
       
   726             CleanupStack::PopAndDestroy( landmark );
       
   727         }
       
   728     }
       
   729     else
       
   730     {
       
   731         // no other lookup entry is refering this landmark. 
       
   732         // delete the landmark.
       
   733         if ( aSourceType != ESourceLandmarks )
       
   734         {
       
   735             iLandmarkDb->RemoveLandmarkL( lookupItem.mDestId );
       
   736         }
       
   737     }
       
   738 }
       
   739 
       
   740 // -----------------------------------------------------------------------------
       
   741 // CMyLocationsDatabaseManager::HandleLandmarkModificationL()
       
   742 // -----------------------------------------------------------------------------
       
   743 //
       
   744 void CMyLocationsDatabaseManager::HandleLandmarkModificationL(
       
   745         CPosLandmark* aLandmark, const TUint32 aUid )
       
   746 {
       
   747     // logic: if a landmark is modified, 
       
   748     // first update the corresponding landmark lookup entry if present, else create a new entry.
       
   749     // Check for any contact/calendar entries refering this landmark entry,
       
   750     // if exists, create a new landmark entry with that location details and update all those 
       
   751     // lookup entry's destid with the newly created landmark id.
       
   752     
       
   753     QLookupItem lookupItem;
       
   754     lookupItem.mSourceUid = aUid;
       
   755     lookupItem.mSourceType = ESourceLandmarks;
       
   756     lookupItem.mIconType = QLookupItem::EIconTypeDefault;
       
   757 
       
   758     bool found = iLocationAppLookupDb->findEntryBySourceIdAndType( lookupItem );
       
   759     //fill address into lookup item.
       
   760     FillLookupItemAddressDetails( aLandmark, lookupItem );
       
   761     lookupItem.mDestId = aUid;
       
   762     lookupItem.mIsDuplicate = 0;
       
   763     lookupItem.mIconType = QLookupItem::EIconTypeDefault;
       
   764     lookupItem.mIconPath = "";
       
   765     lookupItem.mMapTilePath = "";
       
   766 
       
   767     // update entry in lookup table.
       
   768     if ( found )
       
   769     {
       
   770         iLocationAppLookupDb->updateEntryById( lookupItem );
       
   771     }
       
   772     else
       
   773     {
       
   774         iLocationAppLookupDb->createEntry( lookupItem );
       
   775     }
       
   776     
       
   777     QList<QLookupItem> itemArray;
       
   778     iLocationAppLookupDb->findEntriesByLandmarkId( lookupItem.mDestId, itemArray );
       
   779     
       
   780     if( itemArray.count() == 1 )
       
   781     {
       
   782         //only one entry ie the entry corresponding to landmark db is present.
       
   783         return;
       
   784     }
       
   785     
       
   786     CPosLandmark* lm = NULL;
       
   787     
       
   788     for( int i = 0; i < itemArray.count(); i++ )
       
   789     {
       
   790         if( itemArray[i].mSourceType != ESourceLandmarks )
       
   791         {
       
   792             if( itemArray[i].mSourceType == ESourceCalendar )
       
   793             {
       
   794                 // add landmark entry since a calendar item is present with this location.
       
   795                if( !lm )
       
   796                {
       
   797                    lm = CreateLandmarkItemLC( itemArray[i] );
       
   798                }
       
   799                lm->AddCategoryL( iLmCalendarCatId );
       
   800             }
       
   801             else
       
   802             {
       
   803                // add landmark entry since a calendar item is present with this location.
       
   804                if( !lm )
       
   805                {
       
   806                    QString tempStr = itemArray[i].mName;
       
   807                    itemArray[i].mName = "";
       
   808                    lm = CreateLandmarkItemLC( itemArray[i] );
       
   809                    itemArray[i].mName = tempStr;
       
   810                }
       
   811                lm->AddCategoryL( iLmCalendarCatId );
       
   812             }    
       
   813         }
       
   814     }
       
   815     
       
   816     // add the entry to landmarks db
       
   817     quint32 newDestId = iLandmarkDb->AddLandmarkL( *lm );
       
   818     CleanupStack::PopAndDestroy( lm );
       
   819 
       
   820     bool calDuplicateUnset = false;
       
   821     // update all the lookup entries with new landmark id
       
   822     for( int i = 0; i < itemArray.count(); i++ )
       
   823     {
       
   824         if( itemArray[i].mSourceType != ESourceLandmarks )
       
   825         {
       
   826             itemArray[i].mDestId = newDestId;
       
   827             
       
   828             if( itemArray[i].mSourceType == ESourceCalendar )
       
   829             {
       
   830                 if( !calDuplicateUnset )
       
   831                 {
       
   832                     itemArray[i].mIsDuplicate = 0;
       
   833                     calDuplicateUnset = true;
       
   834                 }
       
   835                 else
       
   836                 {
       
   837                     itemArray[i].mIsDuplicate = 1;
       
   838                 }
       
   839             }
       
   840             iLocationAppLookupDb->updateEntryById( itemArray[i] );
       
   841         }
       
   842     }
       
   843 }
       
   844 // -----------------------------------------------------------------------------
       
   845 // CMyLocationsDatabaseManager::GetLandmarkFullAddress()
       
   846 // Gets the comma separated full address of the given landmark.
       
   847 // -----------------------------------------------------------------------------
       
   848 //
       
   849 void CMyLocationsDatabaseManager::GetLandmarkFullAddress(
       
   850         TBuf<KMaxAddressLength>& aLandmarkAddress,
       
   851         const CPosLandmark* aLandmark)
       
   852 {
       
   853     TPtrC tempStr;
       
   854     TInt retStatus;
       
   855     TBool addressEmtpy = ETrue;
       
   856     retStatus = aLandmark->GetPositionField(EPositionFieldStreet, tempStr);
       
   857     if (retStatus == KErrNone && tempStr.Length())
       
   858     {
       
   859         {
       
   860             aLandmarkAddress.Copy(tempStr);
       
   861             addressEmtpy = EFalse;
       
   862         }
       
   863     }
       
   864 
       
   865     retStatus = aLandmark->GetPositionField(EPositionFieldCity, tempStr);
       
   866     if (retStatus == KErrNone && tempStr.Length())
       
   867     {
       
   868         if (!addressEmtpy)
       
   869         {
       
   870             aLandmarkAddress.Append(KSeparator);
       
   871             aLandmarkAddress.Append(KSpace);
       
   872             aLandmarkAddress.Append(tempStr);
       
   873         }
       
   874         else
       
   875         {
       
   876             aLandmarkAddress.Copy(tempStr);
       
   877             addressEmtpy = EFalse;
       
   878         }
       
   879     }
       
   880 
       
   881     retStatus = aLandmark->GetPositionField(EPositionFieldState, tempStr);
       
   882     if (retStatus == KErrNone && tempStr.Length())
       
   883     {
       
   884         if (!addressEmtpy)
       
   885         {
       
   886             aLandmarkAddress.Append(KSeparator);
       
   887             aLandmarkAddress.Append(KSpace);
       
   888             aLandmarkAddress.Append(tempStr);
       
   889         }
       
   890         else
       
   891         {
       
   892             aLandmarkAddress.Copy(tempStr);
       
   893             addressEmtpy = EFalse;
       
   894         }
       
   895     }
       
   896 
       
   897     retStatus = aLandmark->GetPositionField(EPositionFieldCountry, tempStr);
       
   898     if (retStatus == KErrNone && tempStr.Length())
       
   899     {
       
   900         if (!addressEmtpy)
       
   901         {
       
   902             aLandmarkAddress.Append(KSeparator);
       
   903             aLandmarkAddress.Append(KSpace);
       
   904             aLandmarkAddress.Append(tempStr);
       
   905         }
       
   906         else
       
   907         {
       
   908             aLandmarkAddress.Copy(tempStr);
       
   909             addressEmtpy = EFalse;
       
   910         }
       
   911     }
       
   912 }
       
   913 
       
   914 // -----------------------------------------------------------------------------
       
   915 // CMyLocationsDatabaseManager::CheckAndReadLandmarkL()
       
   916 // Checks if given landmark id is found in the database and returns the read landmark.
       
   917 // -----------------------------------------------------------------------------
       
   918 //
       
   919 CPosLandmark* CMyLocationsDatabaseManager::CheckAndReadLandmarkL(
       
   920         CPosLandmarkDatabase* aDb, const TUint32 aLmId)
       
   921 {
       
   922     __TRACE_CALLSTACK;
       
   923     CPosLandmark* lm = aDb->ReadLandmarkLC(aLmId);
       
   924     CleanupStack::Pop(lm);    
       
   925     return lm;
       
   926 }
       
   927 
       
   928 // -----------------------------------------------------------------------------
       
   929 // CMyLocationsDatabaseManager::FillLookupItemAddressDetails()
       
   930 // Creates a new category in Mylocations Db and adds a corresponding entry in 
       
   931 // mylocations lookup table.
       
   932 // -----------------------------------------------------------------------------
       
   933 //
       
   934 void CMyLocationsDatabaseManager::FillLookupItemAddressDetails( CPosLandmark* aLandmark, QLookupItem& aLookupItem )
       
   935 {
       
   936     __TRACE_CALLSTACK;// Read the category.
       
   937 
       
   938     // fill geo-coordinates
       
   939     TLocality position;
       
   940     aLandmark->GetPosition( position );
       
   941     aLookupItem.mLatitude = position.Latitude();
       
   942     aLookupItem.mLongitude = position.Longitude();
       
   943 
       
   944     TPtrC tempStr;
       
   945     TInt retStatus;
       
   946 
       
   947     // Copy landmark name in address 1
       
   948     retStatus = aLandmark->GetLandmarkName( tempStr );
       
   949     aLookupItem.mName = "";
       
   950     if( retStatus == KErrNone && tempStr.Length() > 0 )
       
   951     {
       
   952         aLookupItem.mName = QString( (QChar*)tempStr.Ptr(), tempStr.Length() );
       
   953     }
       
   954 
       
   955     // get street
       
   956     aLookupItem.mStreet = "";
       
   957     retStatus = aLandmark->GetPositionField( EPositionFieldStreet, tempStr );
       
   958     if( retStatus == KErrNone && tempStr.Length() )
       
   959     {
       
   960         aLookupItem.mStreet = QString( (QChar*)tempStr.Ptr(), tempStr.Length());
       
   961     }
       
   962 
       
   963     // get postal code
       
   964     aLookupItem.mPostalCode = "";
       
   965     retStatus = aLandmark->GetPositionField( EPositionFieldPostalCode, tempStr );
       
   966     if( retStatus == KErrNone && tempStr.Length() )
       
   967     {
       
   968         aLookupItem.mPostalCode = QString( (QChar*)tempStr.Ptr(), tempStr.Length());
       
   969     }
       
   970 
       
   971     // get city
       
   972     aLookupItem.mCity = "";
       
   973     retStatus = aLandmark->GetPositionField( EPositionFieldCity, tempStr );
       
   974     if( retStatus == KErrNone && tempStr.Length() )
       
   975     {
       
   976         aLookupItem.mCity = QString( (QChar*)tempStr.Ptr(), tempStr.Length());
       
   977     }
       
   978 
       
   979     // get State
       
   980     aLookupItem.mState = "";
       
   981     retStatus = aLandmark->GetPositionField( EPositionFieldState, tempStr );
       
   982     if( retStatus == KErrNone && tempStr.Length() )
       
   983     {
       
   984         aLookupItem.mState = QString( (QChar*)tempStr.Ptr(), tempStr.Length());
       
   985     }
       
   986 
       
   987     // get country
       
   988     aLookupItem.mCountry = "";
       
   989     retStatus = aLandmark->GetPositionField( EPositionFieldCountry, tempStr );
       
   990     if( retStatus == KErrNone && tempStr.Length() )
       
   991     {
       
   992         aLookupItem.mCountry = QString( (QChar*)tempStr.Ptr(), tempStr.Length());
       
   993     }
       
   994 }
       
   995 
       
   996 // -----------------------------------------------------------------------------
       
   997 // CMyLocationsDatabaseManager::UnsetDuplicateNextCalEntry()
       
   998 // -----------------------------------------------------------------------------
       
   999 //
       
  1000 void CMyLocationsDatabaseManager::UnsetDuplicateNextCalEntry( quint32 aLandmarkId )
       
  1001 {
       
  1002     // get next duplicate item
       
  1003     QList<QLookupItem> itemArray;
       
  1004     iLocationAppLookupDb->findEntriesByLandmarkId( aLandmarkId, itemArray );
       
  1005     for ( int i = 0; i < itemArray.count(); i++)
       
  1006     {
       
  1007         if( itemArray[i].mSourceType == ESourceCalendar )
       
  1008         {
       
  1009             itemArray[i].mIsDuplicate = 0;
       
  1010             iLocationAppLookupDb->updateEntryById( itemArray[i] );
       
  1011             break;
       
  1012         }
       
  1013     }
       
  1014 
       
  1015 }
       
  1016 // -----------------------------------------------------------------------------
       
  1017 // CMyLocationsDatabaseManager::IsDuplicateEntry()
       
  1018 // -----------------------------------------------------------------------------
       
  1019 //
       
  1020 bool CMyLocationsDatabaseManager::IsDuplicateEntry( quint32 aLandmarkId )
       
  1021 {
       
  1022     // get next duplicate item
       
  1023     QList<QLookupItem> itemArray;
       
  1024     iLocationAppLookupDb->findEntriesByLandmarkId( aLandmarkId, itemArray );
       
  1025     for ( int i = 0; i < itemArray.count(); i++)
       
  1026     {
       
  1027         if( itemArray[i].mSourceType == ESourceCalendar ||
       
  1028             itemArray[i].mSourceType == ESourceLandmarks )
       
  1029         {
       
  1030             return true;
       
  1031         }
       
  1032     }
       
  1033     
       
  1034     return false;
       
  1035 }
       
  1036 
       
  1037 // -----------------------------------------------------------------------------
       
  1038 // CMyLocationsDatabaseManager::CreateLandmarkItemLC()
       
  1039 // -----------------------------------------------------------------------------
       
  1040 //
       
  1041 CPosLandmark* CMyLocationsDatabaseManager::CreateLandmarkItemLC( const QLookupItem &aLookupItem )
       
  1042 {
       
  1043     __TRACE_CALLSTACK;//return value
       
  1044     CPosLandmark *landmark = NULL;
       
  1045     TLocality loc( TCoordinate( aLookupItem.mLatitude, aLookupItem.mLongitude ), 0 );
       
  1046 
       
  1047     landmark = CPosLandmark::NewL();
       
  1048     CleanupStack::PushL( landmark );
       
  1049 
       
  1050     // Fill the location details into the landmark object
       
  1051     landmark->SetPositionL( loc );
       
  1052 
       
  1053     // Set the landmark name as contact name
       
  1054     TBuf<KBufSize> text( aLookupItem.mName.utf16() );
       
  1055     TRAP_IGNORE( landmark->SetLandmarkNameL( text ) );
       
  1056 
       
  1057     text.Copy( aLookupItem.mStreet.utf16() );
       
  1058     landmark->SetPositionFieldL( EPositionFieldStreet, text );
       
  1059     
       
  1060     // Set the City
       
  1061     text.Copy( aLookupItem.mCity.utf16() );
       
  1062     landmark->SetPositionFieldL( EPositionFieldCity, text );
       
  1063 
       
  1064     // Set the state/region
       
  1065     text.Copy( aLookupItem.mState.utf16() );
       
  1066     landmark->SetPositionFieldL( EPositionFieldState, text );
       
  1067 
       
  1068     // Set the Postal code
       
  1069     text.Copy( aLookupItem.mPostalCode.utf16() );
       
  1070     landmark->SetPositionFieldL( EPositionFieldPostalCode, text );
       
  1071 
       
  1072     // Set the country
       
  1073     text.Copy( aLookupItem.mCountry.utf16() );
       
  1074     landmark->SetPositionFieldL( EPositionFieldCountry, text );
       
  1075 
       
  1076     return landmark;
       
  1077 }
       
  1078 
       
  1079 // -----------------------------------------------------------------------------
       
  1080 // CMyLocationsDatabaseManager::UpdateMapTilePath()
       
  1081 // -----------------------------------------------------------------------------
       
  1082 //
       
  1083 void CMyLocationsDatabaseManager::UpdateMapTilePath( TUint32 aSourceId, TUint32 aSourceType, 
       
  1084                                             TFileName aFilePath )
       
  1085 {
       
  1086     QString filePath = QString( (QChar*)aFilePath.Ptr(), aFilePath.Length() );
       
  1087     iLocationAppLookupDb->updateMaptileBySourceIdAndType( aSourceId, aSourceType, filePath );
       
  1088 }
       
  1089 
       
  1090 // End of file