[Messaging] Fix sorting and filtering issues in findConversations 87/191287/1
authorPawel Wasowski <p.wasowski2@partner.samsung.com>
Fri, 24 Aug 2018 16:12:09 +0000 (18:12 +0200)
committerPawel Wasowski <p.wasowski2@partner.samsung.com>
Fri, 12 Oct 2018 09:05:30 +0000 (11:05 +0200)
The commit fixes the following problems of email service's findConversations:
- conversations sorted with regard to timestamp, subject, to, from attributes
  were ordered incorrectly
- an attempt to sort results with regard to unreadMessages, isRead, cc,
  bcc, lastMessageId attributes resulted in throwing a JS exception
- unreadMessages attribute value depended on the offset argument value
- filtering by unreadMessages, did not work

The commit changes also the method of creation of MessageConversation
from database records. It may be quicker than the previous one,
that unnecessarily retrieved numerous messages from the database several times.

[Verification] TCT Pass rate: 100%
               Several filters and sort modes were tested manually,
               with Chrome DevTools.

Change-Id: I6196e316ff2b1477c909d528859ef980237454b6
Signed-off-by: Pawel Wasowski <p.wasowski2@partner.samsung.com>
src/messaging/MsgCommon/AbstractFilter.cpp
src/messaging/email_manager.cc
src/messaging/message_conversation.cc
src/messaging/message_conversation.h
src/messaging/messaging_database_manager.cc
src/messaging/messaging_database_manager.h

index ad1db04ac48b82ae296936ec191f70c8a8a30508..ebc91284fb1a2be70036ed8a006509715287175c 100644 (file)
@@ -122,26 +122,20 @@ bool FilterUtils::isTimeStampInRange(const time_t& time_stamp, tizen::AnyPtr& in
                                      tizen::AnyPtr& end_value) {
   ScopeLogger();
   time_t from_time = 0;
-  time_t to_time = 0;
 
-  bool initial_is_valid_time_value = false;
   if (initial_value && !initial_value->isNullOrUndefined()) {
     struct tm ftime = *initial_value->toDateTm();
     from_time = mktime(&ftime);
-    initial_is_valid_time_value = true;
-  }
-  if (!initial_is_valid_time_value) {
+  } else {
     LoggerE("initialValue is not Time!");
     return false;
   }
 
-  bool end_is_valid_time_value = false;
+  time_t to_time = 0;
   if (end_value && !end_value->isNullOrUndefined()) {
     struct tm ttime = *end_value->toDateTm();
     to_time = mktime(&ttime);
-    end_is_valid_time_value = true;
-  }
-  if (end_is_valid_time_value) {
+  } else {
     LoggerE("endValue is not Time!");
     return false;
   }
index 65b117cfa6b1fa9dbeceb4ea63cf30a0399e557d..aeec4e26535693f72e67b036a96f0fc9841f0e90 100644 (file)
@@ -1072,26 +1072,16 @@ void EmailManager::findMessages(FindMsgCallbackUserData* callback) {
 
 PlatformResult EmailManager::FindConversationsPlatform(ConversationCallbackData* callback) {
   ScopeLogger();
-  int convListCount = 0;
 
   std::lock_guard<std::mutex> lock(m_mutex);
-  std::vector<EmailConversationInfo> conversationsInfo;
+  std::vector<std::shared_ptr<MessageConversation>> conversationsInfo;
   PlatformResult ret =
-      MessagingDatabaseManager::getInstance().findEmailConversations(callback, &conversationsInfo);
+      MessagingDatabaseManager::getInstance().findEmailConversations(*callback, &conversationsInfo);
   if (ret.IsError()) return ret;
 
-  convListCount = conversationsInfo.size();
-  LoggerD("Found %d conversations", convListCount);
+  LoggerD("Found %zu conversations", conversationsInfo.size());
 
-  for (int i = 0; i < convListCount; ++i) {
-    std::shared_ptr<MessageConversation> conversation;
-    PlatformResult ret = MessageConversation::convertEmailConversationToObject(
-        conversationsInfo.at(i).id, &conversation);
-    if (ret.IsError()) {
-      LoggerE("%d (%s)", static_cast<int>(ret.error_code()), (ret.message()).c_str());
-      return ret;
-    }
-    conversation->setUnreadMessages(conversationsInfo.at(i).unreadMessages);
+  for (const auto& conversation : conversationsInfo) {
     callback->addConversation(conversation);
   }
 
index 3937eb45f949d90d3fc1a26f5e6bbedfa9d115e3..21d3798da5a2247f572e8de5d2dd5c69e6382411 100644 (file)
@@ -43,6 +43,85 @@ MessageConversation::MessageConversation()
   ScopeLogger("Message Conversation constructor.");
 }
 
+namespace {
+
+std::string SanitizeUtf8String(const std::string& input) {
+  ScopeLogger();
+
+  std::string result = input;
+  const gchar* end = nullptr;
+
+  while (FALSE == g_utf8_validate(result.c_str(), -1, &end)) {
+    result = result.substr(0, end - result.c_str());
+  }
+
+  return result;
+}
+
+std::vector<std::string> SanitizeUtf8StringVector(const std::vector<std::string>& string_vector) {
+  ScopeLogger();
+
+  std::vector<std::string> sanitized_strings;
+  for (const auto& string : string_vector) {
+    sanitized_strings.push_back(SanitizeUtf8String(string));
+  }
+
+  return sanitized_strings;
+}
+
+std::vector<std::string> GetSanitizedEmailRecipientsFromCString(const char* recipients_c_string) {
+  ScopeLogger();
+
+  if (!recipients_c_string) {
+    return {};
+  }
+
+  return SanitizeUtf8StringVector(Message::getEmailRecipientsFromStruct(recipients_c_string));
+}
+
+std::string GetSanitizedStringFromCString(const char* c_string) {
+  ScopeLogger();
+
+  if (!c_string) {
+    return "";
+  }
+
+  return SanitizeUtf8String(c_string);
+}
+
+std::string GetSingleSanitizedEmailAddressFromCString(const char* address_c_string) {
+  ScopeLogger();
+
+  if (!address_c_string) {
+    return "";
+  }
+
+  return SanitizeUtf8String(MessagingUtil::extractSingleEmailAddress(address_c_string));
+}
+
+}  // namespace
+
+MessageConversation::MessageConversation(const email_mail_data_t& mail_data)
+    : m_conversation_id(mail_data.thread_id),
+      m_conversation_type(MessageType::EMAIL),
+      m_timestamp(mail_data.date_time),
+      m_count(mail_data.thread_item_count),
+      m_unread_messages(0),
+      m_preview(GetSanitizedStringFromCString(mail_data.preview_text)),
+      m_conversation_subject(GetSanitizedStringFromCString(mail_data.subject)),
+      m_is_read(mail_data.flags_seen_field),
+      m_from(GetSingleSanitizedEmailAddressFromCString(mail_data.full_address_from)),
+      m_to(GetSanitizedEmailRecipientsFromCString(mail_data.full_address_to)),
+      m_cc(GetSanitizedEmailRecipientsFromCString(mail_data.full_address_cc)),
+      m_bcc(GetSanitizedEmailRecipientsFromCString(mail_data.full_address_bcc)),
+      m_last_message_id(mail_data.mail_id) {
+  ScopeLogger();
+  auto result = initializeUnreadMessagesCount();
+  if (result.IsError()) {
+    LoggerE("Could not initialize unreadMessages. conversation id: %d", m_conversation_id);
+  }
+}
+
 MessageConversation::~MessageConversation() {
   ScopeLogger("Message Conversation destructor.");
 }
@@ -327,19 +406,19 @@ PlatformResult MessageConversation::convertEmailConversationToObject(
 
     if (resultMail->full_address_from[0] != '\0') {
       conversation->m_from =
-          MessagingUtil::extractSingleEmailAddress(resultMail->full_address_from);
+          GetSingleSanitizedEmailAddressFromCString(resultMail->full_address_from);
     }
 
     if (mailData->full_address_to != NULL) {
-      conversation->m_to = Message::getEmailRecipientsFromStruct(mailData->full_address_to);
+      conversation->m_to = GetSanitizedEmailRecipientsFromCString(mailData->full_address_to);
     }
 
     if (mailData->full_address_cc != NULL) {
-      conversation->m_cc = Message::getEmailRecipientsFromStruct(mailData->full_address_cc);
+      conversation->m_cc = GetSanitizedEmailRecipientsFromCString(mailData->full_address_cc);
     }
 
     if (mailData->full_address_bcc != NULL) {
-      conversation->m_bcc = Message::getEmailRecipientsFromStruct(mailData->full_address_bcc);
+      conversation->m_bcc = GetSanitizedEmailRecipientsFromCString(mailData->full_address_bcc);
     }
 
     conversation->m_last_message_id = resultMail->mail_id;
@@ -485,17 +564,113 @@ bool MessageConversation::isMatchingAttributeRange(const std::string& attribute_
   return false;
 }
 
-std::string MessageConversation::SanitizeUtf8String(const std::string& input) {
+common::PlatformResult MessageConversation::initializeUnreadMessagesCount() {
   ScopeLogger();
 
-  std::string result = input;
-  const gchar* end = nullptr;
+  email_list_filter_t filter_list = {};
+  memset(&filter_list, 0, sizeof(email_list_filter_t));
 
-  while (FALSE == g_utf8_validate(result.c_str(), -1, &end)) {
-    result = result.substr(0, end - result.c_str());
+  filter_list.list_filter_item_type = EMAIL_LIST_FILTER_ITEM_RULE;
+  filter_list.list_filter_item.rule.rule_type = EMAIL_LIST_FILTER_RULE_EQUAL;
+  filter_list.list_filter_item.rule.target_attribute = EMAIL_MAIL_ATTRIBUTE_THREAD_ID;
+  filter_list.list_filter_item.rule.key_value.integer_type_value = m_conversation_id;
+
+  int total_messages = 0;
+  int unread_messages = 0;
+  auto result = email_count_mail(&filter_list, 1, &total_messages, &unread_messages);
+  if (EMAIL_ERROR_NONE != result) {
+    return LogAndCreateResult(
+        ErrorCode::UNKNOWN_ERR, "Error while getting data from database.",
+        ("email_count_mail error: %d (%s)", result, get_error_message(result)));
   }
 
-  return result;
+  m_unread_messages = unread_messages;
+
+  return PlatformResult{ErrorCode::NO_ERROR};
+}
+
+const MessageConversation::MessageConversationComparatorMap
+  MessageConversation::m_message_conversation_comparators = {
+    {
+      "id", [] (const ConversationPtr& a, const ConversationPtr& b) {
+          return std::to_string(a->m_conversation_id) < std::to_string(b->m_conversation_id);
+      }
+    },
+    {
+      "timestamp", [] (const ConversationPtr& a, const ConversationPtr& b) {
+        return a->m_timestamp < b->m_timestamp;
+      }
+    },
+    {
+      "messageCount", [] (const ConversationPtr& a, const ConversationPtr& b) {
+        return a->m_count < b->m_count;
+      }
+    },
+    {
+      "unreadMessages", [] (const ConversationPtr& a, const ConversationPtr& b) {
+        return a->m_unread_messages < b->m_unread_messages;
+      }
+    },
+    {
+      "preview", [] (const ConversationPtr& a, const ConversationPtr& b) {
+        return a->m_preview < b->m_preview;
+      }
+    },
+    {
+      "subject", [] (const ConversationPtr& a, const ConversationPtr& b) {
+        return a->m_conversation_subject < b->m_conversation_subject;
+      }
+    },
+    {
+      "isRead", [] (const ConversationPtr& a, const ConversationPtr& b) {
+        return a->m_is_read < b->m_is_read;
+      }
+    },
+    {
+      "from", [] (const ConversationPtr& a, const ConversationPtr& b) {
+        return a->m_from < b->m_from;
+      }
+    },
+    {
+      "to", [] (const ConversationPtr& a, const ConversationPtr& b) {
+        return a->m_to < b->m_to;
+      }
+    },
+    {
+      "cc", [] (const ConversationPtr& a, const ConversationPtr& b) {
+        return a->m_cc < b->m_cc;
+      }
+    },
+    {
+      "bcc", [] (const ConversationPtr& a, const ConversationPtr& b) {
+        return a->m_bcc < b->m_bcc;
+      }
+    },
+    {
+      "lastMessageId", [] (const ConversationPtr& a, const ConversationPtr& b) {
+        return std::to_string(a->m_last_message_id) < std::to_string(b->m_last_message_id);
+      }
+    },
+    {
+      /* Every record has EMAIL type - no element is "greater than" any other. */
+      "type", [] (const ConversationPtr& a, const ConversationPtr& b) {
+        return false;
+      }
+    }
+};
+
+MessageConversation::MessageConversationComparator MessageConversation::getComparator(
+  const std::string& attribute) {
+  auto comparator_it = m_message_conversation_comparators.find(attribute);
+  if (std::end(m_message_conversation_comparators) != comparator_it) {
+    return comparator_it->second;
+  }
+
+  auto default_comparator = [](const ConversationPtr& a, const ConversationPtr& b) {
+    return false;
+  };
+
+  return default_comparator;
 }
 
 }  // messaging
index 1d01ff5ec350c3b3eb9b9f1409df2ede5bde0c43..273f526c6a89783432a30613e17c352e4e4a4bd3 100644 (file)
@@ -25,6 +25,7 @@
 #include <string>
 #include <vector>
 #include "MsgCommon/AbstractFilter.h"
+#include "common/platform_result.h"
 #include "messaging_util.h"
 
 namespace extension {
@@ -43,6 +44,7 @@ typedef std::vector<ConversationPtr> ConversationPtrVector;
 class MessageConversation : public tizen::FilterableObject {
  public:
   MessageConversation();
+  MessageConversation(const email_mail_data_t& mail_data);
   ~MessageConversation();
 
   // attributes getters
@@ -94,8 +96,12 @@ class MessageConversation : public tizen::FilterableObject {
   virtual bool isMatchingAttributeRange(const std::string& attribute_name,
                                         tizen::AnyPtr initial_value, tizen::AnyPtr end_value) const;
 
+  using MessageConversationComparator =
+      std::function<bool(const ConversationPtr&, const ConversationPtr&)>;
+  static MessageConversationComparator getComparator(const std::string& attribute);
+
  private:
-  std::string SanitizeUtf8String(const std::string& input);
+  common::PlatformResult initializeUnreadMessagesCount();
 
   int m_conversation_id;
   MessageType m_conversation_type;
@@ -110,6 +116,9 @@ class MessageConversation : public tizen::FilterableObject {
   std::vector<std::string> m_cc;
   std::vector<std::string> m_bcc;
   int m_last_message_id;
+
+  using MessageConversationComparatorMap = std::map<std::string, MessageConversationComparator>;
+  static const MessageConversationComparatorMap m_message_conversation_comparators;
 };
 
 }  // messaging
index f0df6e6d5c31c465ea316887464491edd04429bf..4345c68ff0688812cbd1706137ec1846dd342b83 100644 (file)
@@ -21,6 +21,7 @@
 #include <time.h>
 #include <unistd.h>
 #include <sstream>
+#include <iterator>
 
 #include <email-api.h>
 #include <msg_storage.h>
 
 #include "common/logger.h"
 #include "common/platform_exception.h"
+#include "common/scope_exit.h"
 
 #include "conversation_callback_data.h"
+#include "message_conversation.h"
 #include "messaging_database_manager.h"
 #include "messaging_manager.h"
 
@@ -143,31 +146,6 @@ MessagingDatabaseManager::MessagingDatabaseManager() {
       std::make_pair("msgId", AttributeInfo("B.MSG_ID", INTEGER, PrimitiveType_String)));
   m_msg_conv_attr_map.insert(
       std::make_pair("direction", AttributeInfo("B.MSG_DIRECTION", INTEGER, PrimitiveType_String)));
-
-  // Attributes map for email conversations =====================================
-  m_email_conv_attr_map.insert(
-      std::make_pair("id", AttributeInfo("thread_id", INTEGER, PrimitiveType_String)));
-  m_email_conv_attr_map.insert(
-      std::make_pair("serviceId", AttributeInfo("account_id", INTEGER, PrimitiveType_String)));
-  m_email_conv_attr_map.insert(
-      std::make_pair("type", AttributeInfo("account_id", INTEGER, PrimitiveType_String)));
-  m_email_conv_attr_map.insert(
-      std::make_pair("timestamp", AttributeInfo("date_time", DATETIME, PrimitiveType_Time)));
-  m_email_conv_attr_map.insert(std::make_pair(
-      "messageCount", AttributeInfo("thread_item_count", INTEGER, PrimitiveType_ULong)));
-  m_email_conv_attr_map.insert(std::make_pair(
-      "unreadMessages", AttributeInfo(std::string("thread_id IN (SELECT thread_id ") +
-                                          std::string("FROM mail_tbl WHERE flags_seen_field = 0 ") +
-                                          std::string("GROUP BY thread_id HAVING COUNT(thread_id)"),
-                                      INTEGER, PrimitiveType_ULong)));
-  m_email_conv_attr_map.insert(
-      std::make_pair("preview", AttributeInfo("preview_text", TEXT, PrimitiveType_String)));
-  m_email_conv_attr_map.insert(
-      std::make_pair("subject", AttributeInfo("subject", TEXT, PrimitiveType_String)));
-  m_email_conv_attr_map.insert(
-      std::make_pair("from", AttributeInfo("full_address_from", TEXT, PrimitiveType_String)));
-  m_email_conv_attr_map.insert(
-      std::make_pair("to", AttributeInfo("full_address_to", TEXT, PrimitiveType_String)));
 }
 
 MessagingDatabaseManager::~MessagingDatabaseManager() {
@@ -891,69 +869,126 @@ PlatformResult MessagingDatabaseManager::findShortMessageConversations(
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
-PlatformResult MessagingDatabaseManager::findEmailConversations(
-    ConversationCallbackData* callback, std::vector<EmailConversationInfo>* result) {
+namespace {
+
+void convertToMessageConversations(const email_mail_data_t* mailData, int mailDataCount,
+                                   ConversationPtrVector* conversations) {
   ScopeLogger();
-  std::ostringstream sqlWhereClause;
-  int resultsCount;
-  email_mail_data_t* results;
-  std::map<int, int> conversationsBag;
-  std::vector<EmailConversationInfo> conversationsInfo;
 
-  // Adding filters query
-  AbstractFilterPtr filter = callback->getFilter();
-  SortModePtr sortMode = callback->getSortMode();
-  long limit = callback->getLimit();
-  long offset = callback->getOffset();
-  MessageType msgType = callback->getMessageServiceType();
-  int accountId = callback->getAccountId();
+  conversations->reserve(static_cast<size_t>(mailDataCount));
+  for (int i = 0; i < mailDataCount; ++i) {
+    conversations->push_back(std::make_shared<MessageConversation>(mailData[i]));
+  }
+}
 
-  std::string filters_query;
-  PlatformResult ret =
-      addFilters(filter, sortMode, limit, offset, m_email_conv_attr_map, msgType, &filters_query);
-  if (ret.IsError()) {
-    LoggerE("Add filters failed (%s)", ret.message().c_str());
-    return ret;
+void filterMessageConversations(const AbstractFilter& filter,
+                                ConversationPtrVector* conversations) {
+  ScopeLogger();
+
+  auto toBeFilteredOut = [&filter](const ConversationPtr& conversation) {
+    return !filter.isMatching(conversation.get());
+  };
+
+  conversations->erase(
+      std::remove_if(std::begin(*conversations), std::end(*conversations), toBeFilteredOut),
+      std::end(*conversations));
+}
+
+void sortConversations(const SortMode& sortMode, ConversationPtrVector* conversations) {
+  ScopeLogger();
+
+  const std::string attribute = sortMode.getAttributeName();
+  auto comparator = MessageConversation::getComparator(attribute);
+
+  if (SortModeOrder::ASC == sortMode.getOrder()) {
+    std::sort(std::begin(*conversations), std::end(*conversations), comparator);
+  } else {
+    std::sort(std::rbegin(*conversations), std::rend(*conversations), comparator);
   }
-  sqlWhereClause << "WHERE " << m_email_conv_attr_map["serviceId"].sql_name << " = " << accountId
-                 << " AND " << filters_query;
-  LoggerD("%s", sqlWhereClause.str().c_str());
+}
 
-  // Getting results from database
-  msg_error_t err =
-      email_query_mails(const_cast<char*>(sqlWhereClause.str().c_str()), &results, &resultsCount);
-  if (EMAIL_ERROR_NONE != err) {
-    LoggerE("Getting mail list fail [%d]", err);
+}  // namespace
 
-    if (EMAIL_ERROR_MAIL_NOT_FOUND == err) {
-      resultsCount = 0;
+PlatformResult MessagingDatabaseManager::retrieveEmailThreadsFromDatabase(
+    const ConversationCallbackData& findEmailConversationsData,
+    ConversationPtrVector* conversations) {
+  ScopeLogger();
+
+  std::string limitAndOffset;
+  PlatformResult result = PlatformResult{ErrorCode::UNKNOWN_ERR};
+  AttributeInfoMap emptyAttributeMap;
+  /*
+   * Sorting and filtering is done programmatically, after data retrieval from the database,
+   * because some parameters cannot be used in ORDER BY/WHERE or both clauses,
+   * passed to the email_query_mails() - e.g. there is no "unreadMessages" column in the.
+   *
+   * For that reason both filter and sort mode arguments of addFilters are null pointers.
+   */
+  result = addFilters(AbstractFilterPtr{nullptr}, SortModePtr{nullptr},
+                      findEmailConversationsData.getLimit(), findEmailConversationsData.getOffset(),
+                      emptyAttributeMap, findEmailConversationsData.getMessageServiceType(),
+                      &limitAndOffset);
+
+  if (result.IsError()) {
+    LoggerE("addFilters failed (%s)", result.message().c_str());
+    return result;
+  }
+
+  const std::string isLastMessageInThread =
+    "(MAIL_ID IN "
+    "(SELECT MAIL_ID "
+     "FROM "
+     "(SELECT MAIL_ID, MAX(DATE_TIME) "
+      "FROM MAIL_TBL "
+      "GROUP BY THREAD_ID)))";
+
+  const std::string isServiceAccountId =
+      "account_id = " + std::to_string(findEmailConversationsData.getAccountId());
+  std::string sqlWhereClause =
+      "WHERE " + isLastMessageInThread + " AND " + isServiceAccountId + " " + limitAndOffset;
+
+  LoggerD("%s", sqlWhereClause.c_str());
+
+  int threadsCount = 0;
+  email_mail_data_t* threadsList = nullptr;
+
+  SCOPE_EXIT {
+    if (threadsList) {
+      email_free_mail_data(&threadsList, threadsCount);
+    }
+  };
+
+  msg_error_t errorCode = email_query_mails(&sqlWhereClause[0], &threadsList, &threadsCount);
+  if (EMAIL_ERROR_NONE != errorCode) {
+    if (EMAIL_ERROR_MAIL_NOT_FOUND == errorCode) {
+      threadsCount = 0;
     } else {
-      return LogAndCreateResult(ErrorCode::UNKNOWN_ERR, "Error while getting data from database.",
-                                ("email_query_mails error: %d (%s)", err, get_error_message(err)));
+      return LogAndCreateResult(
+          ErrorCode::UNKNOWN_ERR, "Error while getting data from database.",
+          ("email_query_mails error: %d (%s)", errorCode, get_error_message(errorCode)));
     }
   }
 
-  // Assigning found emails to conversation
-  for (int i = 0; i < resultsCount; ++i) {
-    if (conversationsBag.find(results[i].thread_id) == conversationsBag.end()) {
-      EmailConversationInfo info;
-      info.id = results[i].thread_id;
-      conversationsInfo.push_back(info);
-      conversationsBag.insert(std::make_pair(results[i].thread_id, 0));
-    }
+  convertToMessageConversations(threadsList, threadsCount, conversations);
+  return PlatformResult{ErrorCode::NO_ERROR};
+}
 
-    if (!(static_cast<bool>(results[i].flags_seen_field))) {
-      ++conversationsBag[results[i].thread_id];
-    }
+PlatformResult MessagingDatabaseManager::findEmailConversations(
+    const ConversationCallbackData& findEmailConversationsData,
+    ConversationPtrVector* conversations) {
+  ScopeLogger();
+
+  auto result = retrieveEmailThreadsFromDatabase(findEmailConversationsData, conversations);
+  if (result.IsError()) {
+    return result;
   }
 
-  for (std::vector<EmailConversationInfo>::iterator it = conversationsInfo.begin();
-       it != conversationsInfo.end(); ++it) {
-    (*it).unreadMessages = conversationsBag[(*it).id];
+  filterMessageConversations(*findEmailConversationsData.getFilter(), conversations);
+
+  if (findEmailConversationsData.getSortMode()) {
+    sortConversations(*findEmailConversationsData.getSortMode(), conversations);
   }
 
-  email_free_mail_data(&results, resultsCount);
-  *result = conversationsInfo;
   return PlatformResult(ErrorCode::NO_ERROR);
 }
 
index dd469915dca0dd46b01885c59cd3097096b85eb7..5ab55738ee16095fd4eeb0833c30e087762e1d59 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "common/platform_result.h"
 #include "find_msg_callback_user_data.h"
+#include "message_conversation.h"
 //#include "ConversationCallbackData.h"
 
 namespace extension {
@@ -84,8 +85,8 @@ class MessagingDatabaseManager {
                                     std::pair<int, email_mail_data_t*>* result);
   common::PlatformResult findShortMessageConversations(ConversationCallbackData* callback,
                                                        std::vector<int>* result);
-  common::PlatformResult findEmailConversations(ConversationCallbackData* callback,
-                                                std::vector<EmailConversationInfo>* result);
+  common::PlatformResult findEmailConversations(const ConversationCallbackData& callback,
+                                                ConversationPtrVector* conversations);
 
  private:
   MessagingDatabaseManager();
@@ -111,12 +112,14 @@ class MessagingDatabaseManager {
   common::PlatformResult addFilters(tizen::AbstractFilterPtr filter, tizen::SortModePtr sortMode,
                                     long limit, long offset, AttributeInfoMap& attributeMap,
                                     MessageType msgType, std::string* result);
+  common::PlatformResult retrieveEmailThreadsFromDatabase(
+      const ConversationCallbackData& findEmailConversationsData,
+      ConversationPtrVector* conversations);
 
   AttributeInfoMap m_msg_attr_map;
   AttributeInfoMap m_email_attr_map;
 
   AttributeInfoMap m_msg_conv_attr_map;
-  AttributeInfoMap m_email_conv_attr_map;
 };
 
 }  // Messaging