From: Pawel Wasowski Date: Sat, 9 Feb 2019 09:01:20 +0000 (+0100) Subject: [messaging] Refactor commonly used functions X-Git-Tag: submit/tizen/20190315.163126~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F36%2F199336%2F10;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [messaging] Refactor commonly used functions Functions for sorting and filtering are now more general. Dedicated function for making SQL clause, comprising only offset and limit was made to replace addFilters usage. [Verification] tct-messaging-email-tests pass rate did not change after the change was applied Change-Id: Id73331631ff2e8cd17723cb7acd882c19f0be5be Signed-off-by: Pawel Wasowski --- diff --git a/src/messaging/messaging_database_manager.cc b/src/messaging/messaging_database_manager.cc index dbdf03e4..25a6bba1 100644 --- a/src/messaging/messaging_database_manager.cc +++ b/src/messaging/messaging_database_manager.cc @@ -721,6 +721,68 @@ PlatformResult MessagingDatabaseManager::addFilters(AbstractFilterPtr filter, So return PlatformResult(ErrorCode::NO_ERROR); } +namespace { + +template +using SharedPtrVector = std::vector>; + +template +void filterVector(const AbstractFilter& filter, SharedPtrVector* vec) { + ScopeLogger(); + + auto toBeFilteredOut = [&filter](const std::shared_ptr& object_ptr) { + return !filter.isMatching(object_ptr.get()); + }; + + vec->erase(std::remove_if(vec->begin(), vec->end(), toBeFilteredOut), vec->end()); +} + +template +void sortVector(const SortMode& sortMode, SharedPtrVector* vec) { + ScopeLogger(); + + const std::string attribute = sortMode.getAttributeName(); + auto comparator = T::getComparator(attribute); + + if (SortModeOrder::ASC == sortMode.getOrder()) { + std::sort(vec->begin(), vec->end(), comparator); + } else { + std::sort(vec->rbegin(), vec->rend(), comparator); + } +} + +std::string makeSQLLimitAndOffsetClause(long limit, long offset) { + ScopeLogger(); + + std::string limitAndOffsetClause; + limitAndOffsetClause.reserve(64); + + if (limit) { + limitAndOffsetClause += "LIMIT " + std::to_string(limit) + " "; + } + + if (offset) { + if (!limit) { + // Ugly fix proposed by mySQL team: + // http://dev.mysql.com/doc/refman/5.0/en/select.html + // To retrieve all rows from a certain offset up to the end of the result set, + // you can use some large number for the second parameter. + // + // Reason: to use OFFSET you need to have LIMIT statement + // 18446744073709551615 is 2^64-1 - max value of big int + // However we will use -1 since it will work fine for various int sizes (this + // trick have been used in old implementation). + + limitAndOffsetClause += "LIMIT -1 "; + } + limitAndOffsetClause += "OFFSET " + std::to_string(offset) + " "; + } + + return limitAndOffsetClause; +} + +} // namespace + PlatformResult MessagingDatabaseManager::findShortMessages(FindMsgCallbackUserData* callback, std::vector* result) { ScopeLogger(); @@ -883,32 +945,6 @@ void convertToMessageConversations(const email_mail_data_t* mailData, int mailDa } } -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); - } -} - } // namespace PlatformResult MessagingDatabaseManager::retrieveEmailThreadsFromDatabase( @@ -916,25 +952,8 @@ PlatformResult MessagingDatabaseManager::retrieveEmailThreadsFromDatabase( 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; - } + std::string limitAndOffset = makeSQLLimitAndOffsetClause(findEmailConversationsData.getLimit(), + findEmailConversationsData.getOffset()); // clang-format off const std::string isLastMessageInThread = @@ -987,10 +1006,10 @@ PlatformResult MessagingDatabaseManager::findEmailConversations( return result; } - filterMessageConversations(*findEmailConversationsData.getFilter(), conversations); + filterVector(*findEmailConversationsData.getFilter(), conversations); if (findEmailConversationsData.getSortMode()) { - sortConversations(*findEmailConversationsData.getSortMode(), conversations); + sortVector(*findEmailConversationsData.getSortMode(), conversations); } return PlatformResult(ErrorCode::NO_ERROR);