#include <vector>
#include <contacts.h>
#include <memory>
+#include <unordered_map>
#include "ContactList.h"
#include "ContactPersonPhoneLog.h"
std::shared_ptr<ContactList<T>> search(const std::string &keyword);
/**
- *@brief Search by phone number ContactPersonNumber record
- *@param[in] number - phone number
- *@return Reference to ContactPersonNumber
- */
- ContactPersonNumberRef getContactPersonNumber(const std::string &number) const;
-
- /**
- *@brief Search by email address ContactPersonEmail record
- *@param[in] email - email address
- *@return Reference to ContactPersonEmail
- */
- ContactPersonEmailRef getContactPersonEmail(const std::string &email) const;
-
- /**
*@brief Search by email and phone and return ContactPersonAddress record
*@param[in] address - email or number
*@return Reference to ContactPersonAddress
*/
- ContactPersonAddressRef getContactPersonAddress(const std::string &address) const;
+ ContactPersonAddressRef getContactPersonAddress(const std::string &address);
/**
*@brief Search for contacts-id, name, phone-number and thumbnail path based on phone-number id
*@param[in] phoneId - identifier of phone-number in contacts-database
*@return Reference to ContactPersonNumber
*/
- ContactPersonNumberRef getContactPersonNumber(int phoneId) const;
+ ContactPersonNumberRef getContactPersonNumber(int phoneId);
/**
*@brief Return owner's ContactPersonAddress record
*@return Reference to ContactPersonAddress
*/
- ContactOwnerProfileRef getOwnerProfile() const;
+ ContactOwnerProfileRef getOwnerProfile();
/**
*@brief Add listener on contacts database
*@param[in] listener
*/
void addListener(IContactManagerListener &listener);
+
/**
*@brief Remove listener
*@param[in] listener - listener to be remove
void removeListener(IContactManagerListener &listener);
private:
+ typedef std::unordered_map<std::string, ContactPersonAddressRef> AddressMap;
+
+ private:
/**
*@brief A callback passed to contacts_db_add_changed_cb() to get notifications
about contacts modifications from contact service
* @brief Generic search for basic contact attributes based on custom filter passed from above
* @param[in] filter to be used for db-request. DO NOT destroy filter manually, it will be destroyed insithe this method.
*/
- ContactPersonNumberRef getContactPersonNumber(contacts_filter_h filter) const;
- ContactPersonEmailRef getContactPersonEmail(contacts_filter_h filter) const;
+ ContactPersonNumberRef getContactPersonNumber(contacts_filter_h filter);
+ ContactPersonEmailRef getContactPersonEmail(contacts_filter_h filter);
+
+ /**
+ *@brief Search by phone number ContactPersonNumber record
+ *@param[in] number - phone number
+ *@return Reference to ContactPersonNumber
+ */
+ ContactPersonNumberRef getContactPersonNumber(const std::string &number);
+
+ /**
+ *@brief Search by email address ContactPersonEmail record
+ *@param[in] email - email address
+ *@return Reference to ContactPersonEmail
+ */
+ ContactPersonEmailRef getContactPersonEmail(const std::string &email);
+
+ void invalidateCache();
+ ContactPersonAddressRef getAddress(const std::string &address);
private:
std::list<IContactManagerListener *> m_Listeners;
+ AddressMap m_AddressMap;
+ ContactOwnerProfileRef m_OwnerProfile;
};
class IContactManagerListener
namespace Msg
{
+ const int mapReservSize = 512;
+
ContactManager::ContactManager()
{
MSG_LOG("");
+ m_AddressMap.reserve(mapReservSize);
int error = contacts_connect();
if(error != 0)
{
return list ? std::make_shared<ContactList<ContactPersonEmail>>(list) : nullptr;
}
- ContactPersonNumberRef ContactManager::getContactPersonNumber(int phoneNumId) const
+ ContactPersonNumberRef ContactManager::getContactPersonNumber(int phoneNumId)
{
+ // TODO: impl cache policy if needed
contacts_filter_h filter = nullptr;
contacts_filter_create(_contacts_contact_number._uri, &filter);
contacts_filter_add_int(filter, _contacts_person_number.number_id, CONTACTS_MATCH_EQUAL, phoneNumId);
return filter ? getContactPersonNumber(filter) : nullptr;
}
- ContactPersonNumberRef ContactManager::getContactPersonNumber(const std::string &number) const
+ ContactPersonNumberRef ContactManager::getContactPersonNumber(const std::string &number)
{
contacts_filter_h filter = nullptr;
contacts_filter_create(_contacts_contact_number._uri, &filter);
return filter ? getContactPersonNumber(filter) : nullptr;
}
- ContactPersonEmailRef ContactManager::getContactPersonEmail(const std::string &email) const
+ ContactPersonEmailRef ContactManager::getContactPersonEmail(const std::string &email)
{
contacts_filter_h filter = nullptr;
contacts_filter_create(_contacts_contact_email._uri, &filter);
return filter ? getContactPersonEmail(filter) : nullptr;
}
- ContactPersonAddressRef ContactManager::getContactPersonAddress(const std::string &address) const
+ ContactPersonAddressRef ContactManager::getContactPersonAddress(const std::string &address)
{
- if(MsgUtils::isValidNumber(address))
- return getContactPersonNumber(address);
-
- return getContactPersonEmail(address);
+ return getAddress(address);
}
- ContactOwnerProfileRef ContactManager::getOwnerProfile() const
+ ContactOwnerProfileRef ContactManager::getOwnerProfile()
{
- contacts_list_h list = nullptr;
- contacts_record_h myProfile = nullptr;
- contacts_db_get_all_records(_contacts_my_profile._uri, 0, 1, &list);
- if(list)
+ if(!m_OwnerProfile)
{
- contacts_list_get_current_record_p(list, &myProfile);
- contacts_list_destroy(list, false);
+ contacts_list_h list = nullptr;
+ contacts_record_h myProfile = nullptr;
+ contacts_db_get_all_records(_contacts_my_profile._uri, 0, 1, &list);
+ if(list)
+ {
+ contacts_list_get_current_record_p(list, &myProfile);
+ contacts_list_destroy(list, false);
+ }
+ if(myProfile)
+ m_OwnerProfile.reset(new ContactOwnerProfile(true, myProfile));
}
- return myProfile ? std::make_shared<ContactOwnerProfile>(true, myProfile) : nullptr;
+ return m_OwnerProfile;
}
void ContactManager::contactChangedCb(const char *view_uri, void *user_data)
{
ContactManager *self = static_cast<ContactManager *>(user_data);
+ self->invalidateCache();
for(auto listener : self->m_Listeners)
{
listener->onContactChanged();
void ContactManager::contactDisplayOrderChangedCb(contacts_name_display_order_e name_display_order, void *user_data)
{
ContactManager *self = static_cast<ContactManager *>(user_data);
+ self->invalidateCache();
for(auto listener : self->m_Listeners)
{
listener->onContactChanged();
}
}
- ContactPersonNumberRef ContactManager::getContactPersonNumber(contacts_filter_h filter) const
+ ContactPersonNumberRef ContactManager::getContactPersonNumber(contacts_filter_h filter)
{
contacts_query_h query = nullptr;
contacts_list_h list = nullptr;
return cResValue ? std::make_shared<ContactPersonNumber>(true, cResValue) : nullptr;
}
- ContactPersonEmailRef ContactManager::getContactPersonEmail(contacts_filter_h filter) const
+ ContactPersonEmailRef ContactManager::getContactPersonEmail(contacts_filter_h filter)
{
contacts_query_h query = nullptr;
contacts_list_h list = nullptr;
contacts_list_destroy(list, false);
return cResValue ? std::make_shared<ContactPersonEmail>(true, cResValue) : nullptr;
}
+
+ ContactPersonAddressRef ContactManager::getAddress(const std::string &address)
+ {
+ auto it = m_AddressMap.find(address);
+ if(m_AddressMap.end() == it)
+ {
+ ContactPersonAddressRef personAddress = MsgUtils::isValidNumber(address) ?
+ std::static_pointer_cast<ContactPersonAddress>(getContactPersonNumber(address)):
+ std::static_pointer_cast<ContactPersonAddress>(getContactPersonEmail(address));
+ m_AddressMap[address] = personAddress;
+
+ return personAddress;
+ }
+ return it->second;
+ }
+
+ void ContactManager::invalidateCache()
+ {
+ m_AddressMap.clear();
+ m_OwnerProfile.reset();
+ }
}
const std::string strName = "Sasha";
m_ContactId = Msg::Test::ContactUtils::getInst().createContact(strName, strNumber);
- ContactPersonNumberRef item = m_ContactManager.getContactPersonNumber(strNumber);
+ auto item = m_ContactManager.getContactPersonAddress(strNumber);
std::string result = item->getDispName();
testing::Test::RecordProperty("Number", strNumber.c_str());
m_ContactId = Msg::Test::ContactUtils::getInst().createContact(strName, strNumber);
- ContactPersonNumberRef item = m_ContactManager.getContactPersonNumber(strNumber);
+ auto item = m_ContactManager.getContactPersonAddress(strNumber);
std::string result = item->getDispName();
testing::Test::RecordProperty("Number", strNumber.c_str());
m_ContactId = Msg::Test::ContactUtils::getInst().createContact(strName, strNumber);
- ContactPersonNumberRef item = m_ContactManager.getContactPersonNumber(strNumber);
+ auto item = m_ContactManager.getContactPersonAddress(strNumber);
std::string result1 = item->getDispName();
std::string result2 = Msg::Test::ContactUtils::getInst().getNameById(m_ContactId);