From: Jerzy Pabich Date: Sat, 20 Dec 2014 10:20:12 +0000 (+0100) Subject: [Messaging] Added findMessages in C++ layer X-Git-Tag: submit/tizen_tv/20150603.064601~1^2~768^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=90787000a6554505baeec4b057767e35b09adcda;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Messaging] Added findMessages in C++ layer [Verification] N/A Change-Id: I47aa4e4e266d17dd4d33c949c50b85f63707c67b Signed-off-by: Jerzy Pabich --- diff --git a/src/messaging/email_manager.cc b/src/messaging/email_manager.cc index 973dc3b6..5f2530b4 100644 --- a/src/messaging/email_manager.cc +++ b/src/messaging/email_manager.cc @@ -28,7 +28,7 @@ #include //#include -//#include +#include "MsgCommon/AbstractFilter.h" #include #include @@ -42,10 +42,10 @@ //#include "MessageConversation.h" //#include "MessageCallbackUserData.h" //#include "MessagesCallbackUserData.h" -//#include "FindMsgCallbackUserData.h" +#include "find_msg_callback_user_data.h" //#include "ConversationCallbackData.h" #include "message_email.h" -//#include "MessagingDatabaseManager.h" +#include "messaging_database_manager.h" //#include "JSMessage.h" //#include "JSMessageConversation.h" @@ -59,10 +59,10 @@ //#include "DBus/LoadAttachmentProxy.h" #include -//#include +#include "MsgCommon/FilterIterator.h" -//using namespace DeviceAPI::Common; -//using namespace DeviceAPI::Tizen; +using namespace common; +using namespace extension::tizen; namespace extension { namespace messaging { @@ -88,11 +88,11 @@ EmailManager::EmailManager() if(non_err != email_service_begin()){ LoggerE("Email service failed to begin"); - throw common::UnknownException("Email service failed to begin"); + throw UnknownException("Email service failed to begin"); } if(non_err != email_open_db()){ LoggerE("Email DB failed to open"); - throw common::UnknownException("Email DB failed to open"); + throw UnknownException("Email DB failed to open"); } int slot_size = -1; @@ -106,7 +106,7 @@ EmailManager::EmailManager() DBus::Proxy::DBUS_IFACE_NETWORK_STATUS); if (!m_proxy_sync) { LoggerE("Sync proxy is null"); - throw common::UnknownException("Sync proxy is null"); + throw UnknownException("Sync proxy is null"); } m_proxy_sync->signalSubscribe(); @@ -182,7 +182,7 @@ void EmailManager::addMessagePlatform(int account_id, if(EMAIL_ERROR_NONE != err) { LoggerE("Failed to free mail data memory"); } - throw common::UnknownException("Cannot retrieve email account information"); + throw UnknownException("Cannot retrieve email account information"); } LoggerE("FROM %s", account->user_email_address); std::stringstream ss; @@ -205,7 +205,7 @@ void EmailManager::addMessagePlatform(int account_id, if(EMAIL_ERROR_NONE != err) { LoggerE("Failed to free mail data memory"); } - throw common::UnknownException("Cannot retrieve draft mailbox"); + throw UnknownException("Cannot retrieve draft mailbox"); } else { LoggerD("email_get_mailbox_by_mailbox_type success.\n"); @@ -229,7 +229,7 @@ void EmailManager::addMessagePlatform(int account_id, if (EMAIL_ERROR_NONE != err) { LoggerE("Failed to destroy mailbox"); } - throw common::UnknownException("Couldn't add message to draft mailbox"); + throw UnknownException("Couldn't add message to draft mailbox"); } else { LoggerD("email_add_mail success.\n"); @@ -248,7 +248,7 @@ void EmailManager::addMessagePlatform(int account_id, err = email_get_mail_data(message->getId(), &mail_data_final); if(EMAIL_ERROR_NONE != err) { LoggerE("Failed to retrieve added mail data"); - throw common::UnknownException("Couldn't retrieve added mail data"); + throw UnknownException("Couldn't retrieve added mail data"); } message->updateEmailMessage(*mail_data_final); @@ -290,7 +290,7 @@ static gboolean addDraftMessageCompleteCB(void *data) obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_SUCCCESS); MessagingInstance::getInstance().PostMessage(json->serialize().c_str()); } - } catch (const common::PlatformException& err) { + } catch (const PlatformException& err) { LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); callback->getMessage()->setMessageStatus(MessageStatus::STATUS_FAILED); } catch (...) { @@ -317,12 +317,13 @@ void EmailManager::addDraftMessage(MessageCallbackUserData* callback) std::lock_guard lock(m_mutex); std::shared_ptr message = callback->getMessage(); addDraftMessagePlatform(callback->getAccountId(), message); - } catch (const common::PlatformException& err) { + } catch (const PlatformException& err) { LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); callback->setError(err.name(), err.message()); } catch (...) { LoggerE("Message add draft failed"); - callback->setError("UnknownError", "Message add draft failed"); + UnknownException err("Message add draft failed"); + callback->setError(err.name(), err.message()); } //Complete task @@ -764,7 +765,7 @@ void EmailManager::stopSync(long op_id) callback = dynamic_cast( m_proxy_sync->getCallback(op_id)); } - catch (const common::PlatformException& e) { + catch (const PlatformException& e) { LoggerE("Could not get callback"); } if(!callback){ @@ -781,7 +782,7 @@ void EmailManager::stopSync(long op_id) std::shared_ptr response = callback->getJson(); picojson::object& obj = response->get(); - common::AbortException error("Sync aborted by user"); + AbortException error("Sync aborted by user"); callback->setError(error.name(), error.message()); MessagingInstance::getInstance().PostMessage(response->serialize().c_str()); m_proxy_sync->removeCallback(op_id); @@ -1029,53 +1030,54 @@ void EmailManager::stopSync(long op_id) // delete callback; // callback = NULL; //} -// -// -//void EmailManager::findMessages(FindMsgCallbackUserData* callback) -//{ -// LoggerD("Entered"); -// -// if(!callback){ -// LoggerE("Callback is null"); -// return; -// } -// -// email_mail_data_t* mailList = NULL; -// int mailListCount = 0; -// try { -// std::lock_guard lock(m_mutex); -// std::pair emails = -// MessagingDatabaseManager::getInstance().findEmails(callback); -// mailListCount = emails.first; -// LoggerD("Found %d mails", mailListCount); -// -// mailList = emails.second; -// email_mail_data_t* nth_email = mailList; -// -// for (int i = 0; i < mailListCount; ++i) { -// std::shared_ptr email = -// Message::convertPlatformEmailToObject(*nth_email); -// callback->addMessage(email); -// nth_email++; -// } -// } catch (const BasePlatformException& err) { -// LoggerE("%s (%s)", (err.getName()).c_str(), (err.getMessage()).c_str()); -// callback->setError(err.getName(), err.getMessage()); -// } catch (...) { -// LoggerE("Message find failed"); -// callback->setError(JSWebAPIErrorFactory::UNKNOWN_ERROR, "Message find failed"); -// } -// -// if (mailListCount > 0 && mailList != NULL) { -// if (EMAIL_ERROR_NONE != email_free_mail_data(&mailList, mailListCount)) { -// LoggerW("Failed to free mailList"); -// } -// } -// -// //Complete task -// LoggerD("callback: %p error:%d messages.size()=%d", callback, callback->isError(), -// callback->getMessages().size()); -// + + +void EmailManager::findMessages(FindMsgCallbackUserData* callback) +{ + LoggerD("Entered"); + + if(!callback){ + LoggerE("Callback is null"); + return; + } + + email_mail_data_t* mailList = NULL; + int mailListCount = 0; + try { + std::lock_guard lock(m_mutex); + std::pair emails = + MessagingDatabaseManager::getInstance().findEmails(callback); + mailListCount = emails.first; + LoggerD("Found %d mails", mailListCount); + + mailList = emails.second; + email_mail_data_t* nth_email = mailList; + + for (int i = 0; i < mailListCount; ++i) { + std::shared_ptr email = + Message::convertPlatformEmailToObject(*nth_email); + callback->addMessage(email); + nth_email++; + } + } catch (const PlatformException& err) { + LoggerE("%s (%s)", (err.name()).c_str(), (err.message()).c_str()); + callback->setError(err.name(), err.message()); + } catch (...) { + LoggerE("Message find failed"); + UnknownException err("Message find failed"); + callback->setError(err.name(), err.message()); + } + + if (mailListCount > 0 && mailList != NULL) { + if (EMAIL_ERROR_NONE != email_free_mail_data(&mailList, mailListCount)) { + LoggerW("Failed to free mailList"); + } + } + + //Complete task + LoggerD("callback: %p error: %d messages.size() = %d", callback, callback->isError(), + callback->getMessages().size()); + // JSContextRef context = callback->getContext(); // if (!GlobalContextManager::getInstance()->isAliveGlobalContext(context)) { // LoggerE("context was closed"); @@ -1083,30 +1085,30 @@ void EmailManager::stopSync(long op_id) // callback = NULL; // return; // } -// -// try { -// if (callback->isError()) { -// LoggerD("Calling error callback"); -// JSObjectRef errobj = JSWebAPIErrorFactory::makeErrorObject(context, + + try { + if (callback->isError()) { + LoggerD("Calling error callback"); +// JSObjectRef errobj = JSWebAPIErrorFactory::makeErrorObject(context, TODO // callback->getErrorName(), // callback->getErrorMessage()); // callback->callErrorCallback(errobj); -// } else { -// LoggerD("Calling success callback"); -// callback->callSuccessCallback(JSMessage::messageVectorToJSObjectArray(context, + } else { + LoggerD("Calling success callback"); +// callback->callSuccessCallback(JSMessage::messageVectorToJSObjectArray(context, TODO // callback->getMessages())); -// } -// } catch (const BasePlatformException& err) { -// LoggerE("Error while calling findMessages callback: %s (%s)", -// (err.getName()).c_str(), (err.getMessage()).c_str()); -// } catch (...) { -// LoggerE("Failed to call findMessages callback."); -// } -// -// delete callback; -// callback = NULL; -//} -// + } + } catch (const PlatformException& err) { + LoggerE("Error while calling findMessages callback: %s (%s)", + (err.name()).c_str(), (err.message()).c_str()); + } catch (...) { + LoggerE("Failed to call findMessages callback."); + } + + delete callback; + callback = NULL; +} + //void EmailManager::findConversations(ConversationCallbackData* callback) //{ // LoggerE("Entered"); diff --git a/src/messaging/email_manager.h b/src/messaging/email_manager.h index f1ffaa44..204e7b81 100644 --- a/src/messaging/email_manager.h +++ b/src/messaging/email_manager.h @@ -51,7 +51,7 @@ namespace messaging { //class Message; //class MessageCallbackUserData; -//class FindMsgCallbackUserData; +class FindMsgCallbackUserData; //class SyncFolderCallbackData; class EmailManager { @@ -61,7 +61,7 @@ public: void addDraftMessage(MessageCallbackUserData* callback); // void removeMessages(MessagesCallbackUserData* callback); // void updateMessages(MessagesCallbackUserData* callback); -// void findMessages(FindMsgCallbackUserData* callback); + void findMessages(FindMsgCallbackUserData* callback); // void findConversations(ConversationCallbackData* callback); // void findFolders(FoldersCallbackData* callback); // void removeConversations(ConversationCallbackData* callback); diff --git a/src/messaging/find_msg_callback_user_data.cc b/src/messaging/find_msg_callback_user_data.cc new file mode 100644 index 00000000..6820ecbd --- /dev/null +++ b/src/messaging/find_msg_callback_user_data.cc @@ -0,0 +1,146 @@ +// +// Tizen Web Device API +// Copyright (c) 2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file: FindMsgCallbackUserData.cpp + */ + +#include "find_msg_callback_user_data.h" +#include "common/picojson.h" + +namespace extension { +namespace messaging { + +FindMsgCallbackUserData::FindMsgCallbackUserData(): + CallbackUserData(), + m_limit(0), + m_offset(0), + m_is_error(false), + m_account_id(0), + m_service_type(UNDEFINED) +{ +} + +FindMsgCallbackUserData::~FindMsgCallbackUserData() +{ +} + +void FindMsgCallbackUserData::setFilter(AbstractFilterPtr filter) +{ + m_filter = filter; +} + +void FindMsgCallbackUserData::setSortMode(SortModePtr sortMode) +{ + m_sort = sortMode; +} + +void FindMsgCallbackUserData::setLimit(long limit) +{ + m_limit = limit; +} + +void FindMsgCallbackUserData::setOffset(long offset) +{ + m_offset = offset; +} + +void FindMsgCallbackUserData::addMessage(std::shared_ptr msg) +{ + m_messages.push_back(msg); +} + +std::vector> FindMsgCallbackUserData::getMessages() const +{ + return m_messages; +} + +void FindMsgCallbackUserData::setError(const std::string& err_name, + const std::string& err_message) +{ + // keep only first error in chain + if (!m_is_error) { + m_is_error = true; + m_err_name = err_name; + m_err_message = err_message; + + picojson::object& obj = m_json->get(); + obj[JSON_ACTION] = picojson::value(JSON_CALLBACK_ERROR); + + auto obj_error = picojson::object(); + obj_error[JSON_ERROR_NAME] = picojson::value(err_name); + obj_error[JSON_ERROR_MESSAGE] = picojson::value(err_message); + obj[JSON_DATA] = picojson::value(obj_error); + } +} + +bool FindMsgCallbackUserData::isError() const +{ + return m_is_error; +} + +std::string FindMsgCallbackUserData::getErrorName() const +{ + return m_err_name; +} + +std::string FindMsgCallbackUserData::getErrorMessage() const +{ + return m_err_message; +} + +void FindMsgCallbackUserData::setAccountId(int account_id){ + m_account_id = account_id; +} + +int FindMsgCallbackUserData::getAccountId() const +{ + return m_account_id; +} + +void FindMsgCallbackUserData::setMessageServiceType(MessageType m_msg_type) +{ + m_service_type = m_msg_type; +} + +MessageType FindMsgCallbackUserData::getMessageServiceType() const +{ + return m_service_type; +} + +AbstractFilterPtr FindMsgCallbackUserData::getFilter() const +{ + return m_filter; +} + +SortModePtr FindMsgCallbackUserData::getSortMode() const +{ + return m_sort; +} + +long FindMsgCallbackUserData::getLimit() const +{ + return m_limit; +} + +long FindMsgCallbackUserData::getOffset() const +{ + return m_offset; +} + +}//Messaging +}//DeviceAPI diff --git a/src/messaging/find_msg_callback_user_data.h b/src/messaging/find_msg_callback_user_data.h new file mode 100644 index 00000000..29330c43 --- /dev/null +++ b/src/messaging/find_msg_callback_user_data.h @@ -0,0 +1,84 @@ +// +// Tizen Web Device API +// Copyright (c) 2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file: FindMsgCallbackUserData.h + */ + +#ifndef __TIZEN_FIND_MSG_CALLBACK_USER_DATA_H +#define __TIZEN_FIND_MSG_CALLBACK_USER_DATA_H + +#include "common/callback_user_data.h" +#include +#include +#include +#include "MsgCommon/AttributeFilter.h" +#include "MsgCommon/SortMode.h" +#include "messaging_util.h" + +using namespace extension::tizen; + +namespace extension { +namespace messaging { + +class Message; + +class FindMsgCallbackUserData: public common::CallbackUserData { +public: + FindMsgCallbackUserData(); + virtual ~FindMsgCallbackUserData(); + + void setFilter(AbstractFilterPtr filter); + void setSortMode(SortModePtr sortMode); + void setLimit(long limit); + void setOffset(long offset); + void addMessage(std::shared_ptr msg); + std::vector> getMessages() const; + + void setError(const std::string& err_name, + const std::string& err_message); + bool isError() const; + std::string getErrorName() const; + std::string getErrorMessage() const; + + void setAccountId(int account_id); + int getAccountId() const; + + void setMessageServiceType(MessageType m_msg_type); + MessageType getMessageServiceType() const; + AbstractFilterPtr getFilter() const; + SortModePtr getSortMode() const; + long getLimit() const; + long getOffset() const; + +private: + AbstractFilterPtr m_filter; + SortModePtr m_sort; + long m_limit; + long m_offset; + bool m_is_error; + std::string m_err_name; + std::string m_err_message; + std::vector> m_messages; + int m_account_id; + MessageType m_service_type; +}; + +}//Messaging +}//DeviceAPI + +#endif /* __TIZEN_FIND_MSG_CALLBACK_USER_DATA_H */ diff --git a/src/messaging/messaging.gyp b/src/messaging/messaging.gyp index a092a9fe..d5e9e6ac 100644 --- a/src/messaging/messaging.gyp +++ b/src/messaging/messaging.gyp @@ -15,7 +15,8 @@ 'dbus-glib-1', 'capi-system-info', 'tapi', - 'vconf' + 'vconf', + 'db-util' ], }, 'sources': [ @@ -48,6 +49,10 @@ 'message_body.h', 'message_callback_user_data.cc', 'message_callback_user_data.h', + 'find_msg_callback_user_data.cc', + 'find_msg_callback_user_data.h', + 'messaging_database_manager.cc', + 'messaging_databese_manager.h', 'DBus/Connection.cpp', 'DBus/Connection.h', 'DBus/EmailSignalProxy.cpp', diff --git a/src/messaging/messaging_database_manager.cc b/src/messaging/messaging_database_manager.cc new file mode 100755 index 00000000..7a62e1c9 --- /dev/null +++ b/src/messaging/messaging_database_manager.cc @@ -0,0 +1,873 @@ +// +// tizen Web Device API +// Copyright (c) 2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file MessagingDatabaseManager.cpp + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "common/logger.h" +#include "common/platform_exception.h" + +#include "messaging_database_manager.h" +#include "messaging_manager.h" + +using namespace common; +using namespace extension::tizen; + +namespace extension { +namespace messaging { + +AttributeInfo::AttributeInfo() : + sql_name(), + sql_type(UNDEFINED_TYPE), + any_type(PrimitiveType_NoType) +{ +} + +AttributeInfo::AttributeInfo(const std::string& in_sql_name, + const SQLAttributeType in_sql_type, + const tizen::PrimitiveType in_any_type) : + sql_name(in_sql_name), + sql_type(in_sql_type), + any_type(in_any_type) +{ +} + +AttributeInfo::AttributeInfo(const AttributeInfo& other) : + sql_name(other.sql_name), + sql_type(other.sql_type), + any_type(other.any_type) +{ +} + +AttributeInfo& AttributeInfo::operator=(const AttributeInfo& other) +{ + sql_name = other.any_type; + sql_type = other.sql_type; + any_type = other.any_type; + return *this; +} + +MessagingDatabaseManager::MessagingDatabaseManager() +{ +// Attributes map for short messages ========================================== + m_msg_attr_map.insert(std::make_pair("id", + AttributeInfo("A.MSG_ID", INTEGER, PrimitiveType_String))); + m_msg_attr_map.insert(std::make_pair("serviceId", + AttributeInfo("A.MAIN_TYPE", INTEGER, PrimitiveType_String))); + m_msg_attr_map.insert(std::make_pair("folderId", + AttributeInfo("A.FOLDER_ID", INTEGER, PrimitiveType_String))); + m_msg_attr_map.insert(std::make_pair("type", + AttributeInfo("A.MAIN_TYPE", INTEGER, PrimitiveType_String))); + m_msg_attr_map.insert(std::make_pair("timestamp", + AttributeInfo("A.DISPLAY_TIME", DATETIME, PrimitiveType_Time))); + m_msg_attr_map.insert(std::make_pair("from", + AttributeInfo("B.ADDRESS_VAL", TEXT, PrimitiveType_String))); + m_msg_attr_map.insert(std::make_pair("to", + AttributeInfo("B.ADDRESS_VAL", TEXT, PrimitiveType_String))); + m_msg_attr_map.insert(std::make_pair("body.plainBody", + AttributeInfo("A.MSG_TEXT", TEXT, PrimitiveType_String))); + m_msg_attr_map.insert(std::make_pair("isRead", + AttributeInfo("A.READ_STATUS", INTEGER, PrimitiveType_Boolean))); + m_msg_attr_map.insert(std::make_pair("hasAttachment", + AttributeInfo("A.ATTACHMENT_COUNT", INTEGER, PrimitiveType_Boolean))); + m_msg_attr_map.insert(std::make_pair("isHighPriority", + AttributeInfo("A.PRIORITY", INTEGER, PrimitiveType_Boolean))); + m_msg_attr_map.insert(std::make_pair("subject", + AttributeInfo("A.SUBJECT", TEXT, PrimitiveType_String))); + m_msg_attr_map.insert(std::make_pair("direction", + AttributeInfo("A.MSG_DIRECTION", INTEGER, PrimitiveType_String))); + +// Attributes map for emails ================================================== + m_email_attr_map.insert(std::make_pair("id", + AttributeInfo("mail_id", INTEGER, PrimitiveType_String))); + m_email_attr_map.insert(std::make_pair("serviceId", + AttributeInfo("account_id", INTEGER, PrimitiveType_String))); + m_email_attr_map.insert(std::make_pair("folderId", + AttributeInfo("mailbox_id", INTEGER, PrimitiveType_String))); + m_email_attr_map.insert(std::make_pair("type", + AttributeInfo("account_id", INTEGER, PrimitiveType_String))); + m_email_attr_map.insert(std::make_pair("timestamp", + AttributeInfo("date_time", DATETIME, PrimitiveType_Time))); + m_email_attr_map.insert(std::make_pair("from", + AttributeInfo("full_address_from", TEXT, PrimitiveType_String))); + m_email_attr_map.insert(std::make_pair("to", + AttributeInfo("full_address_to", TEXT, PrimitiveType_String))); + m_email_attr_map.insert(std::make_pair("cc", + AttributeInfo("full_address_cc", TEXT, PrimitiveType_String))); + m_email_attr_map.insert(std::make_pair("bcc", + AttributeInfo("full_address_bcc", TEXT, PrimitiveType_String))); + m_email_attr_map.insert(std::make_pair("body.plainBody", + AttributeInfo("preview_text", TEXT, PrimitiveType_String))); + m_email_attr_map.insert(std::make_pair("isRead", + AttributeInfo("flags_seen_field", BOOLEAN, PrimitiveType_Boolean))); + m_email_attr_map.insert(std::make_pair("hasAttachment", + AttributeInfo("attachment_count", INTEGER, PrimitiveType_Boolean))); + m_email_attr_map.insert(std::make_pair("isHighPriority", + AttributeInfo("priority", INTEGER, PrimitiveType_Boolean))); + m_email_attr_map.insert(std::make_pair("subject", + AttributeInfo("subject", TEXT, PrimitiveType_String))); + +// Attributes map for short message conversations ============================= + m_msg_conv_attr_map.insert(std::make_pair("id", + AttributeInfo("A.CONV_ID", INTEGER, PrimitiveType_String))); + m_msg_conv_attr_map.insert(std::make_pair("type", + AttributeInfo("B.MAIN_TYPE", INTEGER, PrimitiveType_String))); + m_msg_conv_attr_map.insert(std::make_pair("timestamp", + AttributeInfo("A.DISPLAY_TIME", DATETIME, PrimitiveType_Time))); + m_msg_conv_attr_map.insert(std::make_pair("messageCount", + AttributeInfo("(A.SMS_CNT + A.MMS_CNT)", INTEGER, PrimitiveType_ULong))); + m_msg_conv_attr_map.insert(std::make_pair("unreadMessages", + AttributeInfo("A.UNREAD_CNT", INTEGER, PrimitiveType_ULong))); + m_msg_conv_attr_map.insert(std::make_pair("preview", + AttributeInfo("A.MSG_TEXT", TEXT, PrimitiveType_String))); + m_msg_conv_attr_map.insert(std::make_pair("from", + AttributeInfo("C.ADDRESS_VAL", TEXT, PrimitiveType_String))); + m_msg_conv_attr_map.insert(std::make_pair("to", + AttributeInfo("C.ADDRESS_VAL", TEXT, PrimitiveType_String))); + m_msg_conv_attr_map.insert(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() +{ + +} + +MessagingDatabaseManager& MessagingDatabaseManager::getInstance() +{ + static MessagingDatabaseManager instance; + return instance; +} + +__thread sqlite3* sqlHandle = NULL; +__thread sqlite3_stmt* stmt = NULL; + +msg_error_t MessagingDatabaseManager::connect() +{ + LOGD("Entered"); + int err = 0; + if (NULL == sqlHandle) { + char strDBName[64]; + + memset(strDBName, 0x00, sizeof(strDBName)); + snprintf(strDBName, sizeof(strDBName), "%s", MSG_DB_NAME); + + err = db_util_open(strDBName, &sqlHandle, DB_UTIL_REGISTER_HOOK_METHOD); + + if (SQLITE_OK != err) { + LOGE("DB connecting fail [%d]", err); + return MSG_ERR_DB_CONNECT; + } + + LOGD("DB connecting success: [%d]", sqlHandle); + } else { + LOGD("DB connection exists: [%d]", sqlHandle); + } + + return MSG_SUCCESS; +} + +msg_error_t MessagingDatabaseManager::disconnect() +{ + LOGD("Entered"); + msg_error_t err = 0; + if (NULL != sqlHandle) { + err = db_util_close(sqlHandle); + + if (SQLITE_OK != err) { + LOGE("DB disconnecting fail [%d]", err); + return MSG_ERR_DB_DISCONNECT; + } + + sqlHandle = NULL; + LOGD("DB disconnecting success"); + } + + return MSG_SUCCESS; +} + +msg_error_t MessagingDatabaseManager::getTable(std::string sqlQuery, + char*** results, + int* resultsCount) +{ + LOGD("Entered"); + msg_error_t err = 0; + *resultsCount = 0; + + freeTable(results); + connect(); + + + char* error_msg = NULL; + err = sqlite3_get_table(sqlHandle, sqlQuery.c_str(), results, + resultsCount, 0, &error_msg); + + if (SQLITE_OK != err) { + LOGE("Getting table fail [%d] error_msg:%s querry was:%s", err, error_msg, + sqlQuery.c_str()); + freeTable(results); + return MSG_ERR_DB_GETTABLE; + } + + LOGD("Getting table success"); + if (0 == *resultsCount) { + LOGD("No results"); + } + + disconnect(); + return MSG_SUCCESS; +} + +void MessagingDatabaseManager::freeTable(char*** results) +{ + LOGD("Entered"); + if (*results) { + sqlite3_free_table(*results); + *results = NULL; + } +} + +int MessagingDatabaseManager::cellToInt(char** array, int cellId) +{ + LOGD("Entered"); + if (NULL == array) { + LOGD("Array is NULL"); + return 0; + } + + char* tmp = *(array + cellId); + if (NULL == tmp) { + LOGD("Cell is NULL"); + return 0; + } + + return static_cast(strtol(tmp, (char**) NULL, 10)); +} + +std::string MessagingDatabaseManager::getMatchString(tizen::AnyPtr match_value, + const PrimitiveType type) const +{ + if(!match_value) { + LOGD("Warning: match value is NULL"); + return std::string(); + } + + std::ostringstream converter; + switch(type) { + case PrimitiveType_NoType: { + LOGD("Warning: match value is no type"); + return std::string(); + } + case PrimitiveType_Null: { + LOGD("Warning: match value is null"); + return std::string(); + } + case PrimitiveType_Boolean: { + converter << match_value->toBool(); + return converter.str(); + } + case PrimitiveType_Long: { + converter << match_value->toLong(); + return converter.str(); + } + case PrimitiveType_ULong: { + converter << match_value->toULong(); + return converter.str(); + } + case PrimitiveType_LongLong: { + converter << match_value->toLongLong(); + return converter.str(); + } + case PrimitiveType_ULongLong: { + converter << match_value->toULongLong(); + return converter.str(); + } + case PrimitiveType_Double: { + converter << match_value->toDouble(); + return converter.str(); + } + case PrimitiveType_String: { + return match_value->toString(); + } + case PrimitiveType_Time: { + converter << match_value->toTimeT(); + return converter.str(); + } + default: { + LOGD("Warning: match value is not specified"); + return std::string(); + } + } +} + +std::string MessagingDatabaseManager::getAttributeFilterQuery(AbstractFilterPtr filter, + AttributeInfoMap& attribute_map, MessageType msgType) +{ + LOGD("Entered"); + + std::ostringstream sqlQuery; + AttributeFilterPtr attr_filter = castToAttributeFilter(filter); + if(!attr_filter) { + LOGE("passed filter is not valid AttributeFilter!"); + throw UnknownException("Wrong filter type - not attribute filter"); + } + + const std::string attribute_name = attr_filter->getAttributeName(); + + AttributeInfoMap::iterator it = attribute_map.find(attribute_name); + if (it != attribute_map.end()) { + sqlQuery << "(" << attribute_map[attribute_name].sql_name << " "; + } else { + LOGE("The attribute: %s does not exist.", attribute_name.c_str()); + throw InvalidValuesException("The attribute does not exist."); + } + + AnyPtr match_value_any_ptr = attr_filter->getMatchValue(); + const AttributeInfo& attr_info = it->second; + std::string match_value = getMatchString(match_value_any_ptr, attr_info.any_type); + const FilterMatchFlag match_flag = attr_filter->getMatchFlag(); + + LOGD("match_value_any_ptr:%p any_type:%d attr_name:%s match_value:%s", + match_value_any_ptr.get(), attr_info.any_type, attribute_name.c_str(), + match_value.c_str()); + + if ("serviceId" == attribute_name) { + + int i_matchValue; + std::istringstream iss(match_value); + iss >> i_matchValue; + + switch(i_matchValue) { + case MessageServiceAccountId::SMS_ACCOUNT_ID: { + sqlQuery << "= " << MessageType::SMS; + break; + } + case MessageServiceAccountId::MMS_ACCOUNT_ID: { + sqlQuery << "= " << MessageType::MMS; + break; + } + default: + sqlQuery << "= " << match_value; + } + } + else if ("type" == attribute_name) { + if ("messaging.sms" == match_value && MessageType::SMS == msgType) { + sqlQuery << "= " << msgType; + } else if ("messaging.mms" == match_value && MessageType::MMS == msgType) { + sqlQuery << "= " << msgType; + } else if ("messaging.email" == match_value && MessageType::EMAIL == msgType) { + sqlQuery << "= " << attr_info.sql_name; + } else { + LOGE("attribute \"type\" matchValue:%s " + "does not match messaging.sms/mms/email\n" + "msgType:%d does not match SMS(%d), MMS(%d) nor EMAIL(%d)!", + match_value.c_str(), msgType, MessageType::SMS, MessageType::MMS, + MessageType::EMAIL); + throw UnknownException("The value does not match service type."); + } + } + else if ("isRead" == attribute_name || "hasAttachment" == attribute_name) { + if (attr_filter->getMatchValue()->toBool()) { + sqlQuery << "> 0"; + } else { + sqlQuery << "= 0"; + } + } + else if ("isHighPriority" == attribute_name) { + if (attr_filter->getMatchValue()->toBool()) { + sqlQuery << "= "; + } else { + sqlQuery << "<> "; + } + + if (MessageType::SMS == msgType || MessageType::MMS == msgType) { + sqlQuery << MSG_MESSAGE_PRIORITY_HIGH; + } else if (MessageType::EMAIL == msgType) { + sqlQuery << EMAIL_MAIL_PRIORITY_HIGH; + } + } + else { + // Addresses which are stored in database can have different form than in filters + if (MessageType::EMAIL == msgType && ("from" == attribute_name || + "to" == attribute_name || "cc" == attribute_name || + "bcc" == attribute_name)) { + std::size_t foundPos; + while ((foundPos = match_value.find('<')) != std::string::npos) { + match_value.erase(foundPos, 1); + } + + while ((foundPos = match_value.find('>')) != std::string::npos) { + match_value.erase(foundPos, 1); + } + + if (EXACTLY == match_flag) { + match_value = "%<" + match_value + ">%"; + } else if (CONTAINS == match_flag) { + match_value = "%<%" + match_value + "%>%"; + } else if (STARTSWITH == match_flag) { + match_value = "%<" + match_value + "%>%"; + } else if (ENDSWITH == match_flag) { + match_value = "%<%" + match_value + ">%"; + } + } + + switch (match_flag) { + /* + case NONE: { + // Determines if the apostrophes have to be added over match value + if (TEXT == attribute_map[attribute_name].sql_type) { + sqlQuery << "NOT LIKE '" << match_value << "'"; + } else { + sqlQuery << "<> " << match_value; + } + break; + }*/ + case EXACTLY: { + // Determines if the apostrophes have to be added over match value + if (TEXT == attribute_map[attribute_name].sql_type) { + sqlQuery << "LIKE '" << match_value << "'"; + } else { + sqlQuery << "= " << match_value; + } + break; + } + case CONTAINS: { + sqlQuery << "LIKE '%" << match_value << "%'"; + break; + } + case STARTSWITH: { + sqlQuery << "LIKE '" << match_value << "%'"; + break; + } + case ENDSWITH: { + sqlQuery << "LIKE '%" << match_value << "'"; + break; + } + case EXISTS: { + if ("unreadMessages" != attribute_name) { + sqlQuery << "IS NOT NULL"; + } else { + sqlQuery << "!= 0"; + } + break; + } + default: + throw UnknownException("The match flag is incorrect."); + } + + if (MessageType::SMS == msgType || MessageType::MMS == msgType) { + if ("from" == attribute_name) { + // "From" and "to" attributes require message direction value + sqlQuery << " AND " << attribute_map["direction"].sql_name << " = 1"; + } else if ("to" == attribute_name) { + sqlQuery << " AND " << attribute_map["direction"].sql_name << " <> 1"; + } + } else if (MessageType::EMAIL == msgType) { + if("unreadMessages" == attribute_name) { + sqlQuery << ")"; + } + } + } + sqlQuery << ") "; + return sqlQuery.str(); +} + +std::string MessagingDatabaseManager::getAttributeRangeFilterQuery(AbstractFilterPtr filter, + AttributeInfoMap& attribute_map, MessageType msg_type) +{ + LOGD("Entered"); + + std::ostringstream sql_query, converter; + std::string initial_value, end_value; + + AttributeRangeFilterPtr attr_range_filter = castToAttributeRangeFilter(filter); + if(!attr_range_filter) { + LOGE("passed filter is not valid AttributeRangeFilter!"); + throw UnknownException("Wrong filter type - not attribute range filter"); + } + + converter << attr_range_filter->getInitialValue()->toTimeT(); + initial_value = converter.str(); + converter.str(""); + converter << attr_range_filter->getEndValue()->toTimeT(); + end_value = converter.str(); + + sql_query << "(" << attribute_map[attr_range_filter->getAttributeName()].sql_name << " "; + sql_query << "BETWEEN " << initial_value << " AND " << end_value << ") "; + return sql_query.str(); +} + +std::string MessagingDatabaseManager::getCompositeFilterQuery(AbstractFilterPtr filter, + AttributeInfoMap& attribute_map, MessageType msg_type) +{ + LOGD("Entered"); + std::ostringstream sql_query; + + CompositeFilterPtr comp_filter = castToCompositeFilter(filter); + if(!comp_filter) { + LOGE("passed filter is not valid CompositeFilter!"); + throw UnknownException("Wrong filter type - not composite filter"); + } + + AbstractFilterPtrVector filters_arr = comp_filter->getFilters(); + + std::string logical_operator; + if (UNION == comp_filter->getType()) { + logical_operator = "OR "; + } else { + logical_operator = "AND "; + } + + sql_query << "("; + const unsigned int size = filters_arr.size(); + for (unsigned int i = 0; i < size; ++i) { + + const FilterType filter_type = filters_arr[i]->getFilterType(); + switch (filter_type) { + case ATTRIBUTE_FILTER: { + sql_query << getAttributeFilterQuery(filters_arr[i], attribute_map, msg_type); + break; + } + case ATTRIBUTE_RANGE_FILTER: { + sql_query << getAttributeRangeFilterQuery(filters_arr[i], attribute_map, msg_type); + break; + } + case COMPOSITE_FILTER: { + sql_query << getCompositeFilterQuery(filters_arr[i], attribute_map, msg_type); + break; + } + default: + LOGE("Error while querying message - unsupported filter type: %d", + filter_type); + throw UnknownException("Error while querying message."); + } + + if (i != (size - 1)) { + sql_query << logical_operator; + } + } + sql_query << ") "; + + return sql_query.str(); +} + +std::string MessagingDatabaseManager::addFilters(AbstractFilterPtr filter, + SortModePtr sort_mode, long limit, long offset, AttributeInfoMap& attribute_map, + MessageType msg_type) +{ + LOGD("Entered"); + std::ostringstream sql_query; + + // Service type query + if (MessageType::SMS == msg_type || MessageType::MMS == msg_type) { + if (UNDEFINED != msg_type) { + sql_query << attribute_map["type"].sql_name << " = " << msg_type << " AND "; + } else { + LOGE("The service type is incorrect - msg_type is UNDEFINED"); + throw UnknownException("The service type is incorrect."); + } + } + + if(filter) { + // Filter query + switch (filter->getFilterType()) { + case ATTRIBUTE_FILTER: { + sql_query << getAttributeFilterQuery(filter, attribute_map, msg_type); + } break; + + case ATTRIBUTE_RANGE_FILTER: { + sql_query << getAttributeRangeFilterQuery(filter, attribute_map, msg_type); + } break; + + case COMPOSITE_FILTER : { + sql_query << getCompositeFilterQuery(filter, attribute_map, msg_type); + } break; + + default: + LOGE("The filter type is incorrect: %d", filter->getFilterType()); + throw UnknownException("The filter type is incorrect."); + } + } + + // SortMode query + if (sort_mode) { + if (attribute_map.find(sort_mode->getAttributeName()) != attribute_map.end()) { + sql_query << "ORDER BY " + << attribute_map[sort_mode->getAttributeName()].sql_name << " "; + } else { + LOGE("The attribute does not exist."); + throw UnknownException("The attribute does not exist."); + } + + if (ASC == sort_mode->getOrder()) { + sql_query << "ASC "; + } else { + sql_query << "DESC "; + } + } + + // Limit query + if (0 != limit) { + sql_query << "LIMIT " << limit << " "; + } + + // Offset query + if (0 != offset) { + if( 0 == 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). + + sql_query << "LIMIT -1 "; + } + sql_query << "OFFSET " << offset << " "; + } + + return sql_query.str(); +} + +std::vector MessagingDatabaseManager::findShortMessages( + FindMsgCallbackUserData* callback) +{ + LOGD("Entered"); + std::ostringstream sqlQuery; + int attributesCount = 1; // It has to be set manually each time when the query is changed + int cellId = attributesCount; + char** results = NULL; + int resultsCount; + std::vector messagesIds; + + sqlQuery << "SELECT " << "DISTINCT(" << m_msg_attr_map["id"].sql_name << ") " + << "FROM " << MSG_MESSAGE_TABLE_NAME << " A " + << "JOIN " << MSG_ADDRESS_TABLE_NAME << " B " + << "ON A.CONV_ID = B.CONV_ID " << "WHERE B.ADDRESS_ID <> 0 AND "; + + // Adding filters query + AbstractFilterPtr filter = callback->getFilter(); + SortModePtr sortMode = callback->getSortMode(); + long limit = callback->getLimit(); + long offset = callback->getOffset(); + MessageType msgType = callback->getMessageServiceType(); + + sqlQuery << addFilters(filter, sortMode, limit, offset, m_msg_attr_map, msgType); + LOGD("%s", sqlQuery.str().c_str()); + + // Getting results from database + msg_error_t err = getTable(sqlQuery.str(), &results, &resultsCount); + if (MSG_SUCCESS != err) { + freeTable(&results); + throw UnknownException("Error while getting data from database."); + } + + for (int i = 0; i < resultsCount; ++i) { + messagesIds.push_back(cellToInt(results, cellId++)); + LOGD("id: %d", messagesIds.at(messagesIds.size() - 1)); + } + + freeTable(&results); + return messagesIds; +} + +std::pair MessagingDatabaseManager::findEmails( + FindMsgCallbackUserData* callback) +{ + LOGD("Entered"); + std::ostringstream sqlWhereClause; + int resultsCount; + email_mail_data_t* results; + + // 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(); + + sqlWhereClause << "WHERE " + << m_email_attr_map["serviceId"].sql_name << " = " << accountId << " AND " + << addFilters(filter, sortMode, limit, offset, m_email_attr_map, msgType); + LOGD("%s", sqlWhereClause.str().c_str()); + + // Getting results from database + msg_error_t err = email_query_mails(const_cast(sqlWhereClause.str().c_str()), + &results, &resultsCount); + if (EMAIL_ERROR_NONE != err) { + LOGE("Getting mail list fail [%d]", err); + + if (EMAIL_ERROR_MAIL_NOT_FOUND == err) { + resultsCount = 0; + } else { + throw UnknownException("Error while getting data from database."); + } + } + + return std::make_pair(resultsCount, results); +} + +//std::vector MessagingDatabaseManager::findShortMessageConversations( +// ConversationCallbackData* callback) +//{ +// LOGD("Entered"); +// std::ostringstream sqlQuery; +// int attributesCount = 1; // It has to be set manually each time when the query is changed +// int cellId = attributesCount; +// char** results = NULL; +// int resultsCount; +// std::vector conversationsIds; +// +// sqlQuery << "SELECT " << "DISTINCT(" << m_msg_conv_attr_map["id"].sql_name << ") " +// << "FROM " << MSG_CONVERSATION_TABLE_NAME << " A " +// << "JOIN " << MSG_MESSAGE_TABLE_NAME << " B " +// << "ON A.CONV_ID = B.CONV_ID " +// << "JOIN " << MSG_ADDRESS_TABLE_NAME << " C " +// << "ON A.CONV_ID = C.CONV_ID " +// << "WHERE (A.SMS_CNT > 0 OR A.MMS_CNT > 0) AND "; +// +// // Adding filters query +// AbstractFilterPtr filter = callback->getFilter(); +// SortModePtr sortMode = callback->getSortMode(); +// long limit = callback->getLimit(); +// long offset = callback->getOffset(); +// MessageType msgType = callback->getMessageServiceType(); +// +// sqlQuery << addFilters(filter, sortMode, limit, offset, m_msg_conv_attr_map, msgType); +// LOGD("%s", sqlQuery.str().c_str()); +// +// // Getting results from database +// msg_error_t err = getTable(sqlQuery.str(), &results, &resultsCount); +// if (MSG_SUCCESS != err) { +// freeTable(&results); +// throw UnknownException("Error while getting data from database."); +// } +// +// for (int i = 0; i < resultsCount; ++i) { +// conversationsIds.push_back(cellToInt(results, cellId++)); +// LOGD("id: %d", conversationsIds.at(conversationsIds.size() - 1)); +// } +// +// freeTable(&results); +// return conversationsIds; +//} +// +//std::vector MessagingDatabaseManager::findEmailConversations( +// ConversationCallbackData* callback) +//{ +// LOGD("Entered"); +// std::ostringstream sqlWhereClause; +// int resultsCount; +// email_mail_data_t* results; +// std::map conversationsBag; +// std::vector 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(); +// +// sqlWhereClause << "WHERE " +// << m_email_conv_attr_map["serviceId"].sql_name << " = " << accountId << " AND " +// << addFilters(filter, sortMode, limit, offset, m_email_conv_attr_map, msgType); +// LOGD("%s", sqlWhereClause.str().c_str()); +// +// // Getting results from database +// msg_error_t err = email_query_mails(const_cast(sqlWhereClause.str().c_str()), +// &results, &resultsCount); +// if (EMAIL_ERROR_NONE != err) { +// LOGE("Getting mail list fail [%d]", err); +// +// if (EMAIL_ERROR_MAIL_NOT_FOUND == err) { +// resultsCount = 0; +// } else { +// throw UnknownException("Error while getting data from database."); +// } +// } +// +// // 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)); +// } +// +// if (!(static_cast(results[i].flags_seen_field))) { +// ++conversationsBag[results[i].thread_id]; +// } +// } +// +// for (std::vector::iterator it = conversationsInfo.begin(); +// it != conversationsInfo.end(); ++it) { +// (*it).unreadMessages = conversationsBag[(*it).id]; +// } +// +// email_free_mail_data(&results, resultsCount); +// return conversationsInfo; +//} + +} // Messaging +} // DeviceAPI diff --git a/src/messaging/messaging_database_manager.h b/src/messaging/messaging_database_manager.h new file mode 100755 index 00000000..1d9ecbef --- /dev/null +++ b/src/messaging/messaging_database_manager.h @@ -0,0 +1,121 @@ +// +// tizen Web Device API +// Copyright (c) 2013 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/** + * @file MessagingDatabaseManager.h + */ + +#ifndef __TIZEN_MSG_DATABASE_MANAGER_H__ +#define __TIZEN_MSG_DATABASE_MANAGER_H__ + +#include +#include + +#include +#include +#include "MsgCommon/AbstractFilter.h" + +#include "find_msg_callback_user_data.h" +//#include "ConversationCallbackData.h" + +namespace extension { +namespace messaging { + +// ================================================================= +#define MSG_DB_NAME "/opt/usr/dbspace/.msg_service.db" +#define MSG_MESSAGE_TABLE_NAME "MSG_MESSAGE_TABLE" +#define MSG_FOLDER_TABLE_NAME "MSG_FOLDER_TABLE" +#define MSG_ADDRESS_TABLE_NAME "MSG_ADDRESS_TABLE" +#define MSG_CONVERSATION_TABLE_NAME "MSG_CONVERSATION_TABLE" +#define MSG_SIM_MSG_TABLE_NAME "MSG_SIM_TABLE" +#define MSG_FILTER_TABLE_NAME "MSG_FILTER_TABLE" +#define MSG_PUSH_MSG_TABLE_NAME "MSG_PUSH_TABLE" +#define MSG_CB_MSG_TABLE_NAME "MSG_CBMSG_TABLE" +#define MMS_PLUGIN_MESSAGE_TABLE_NAME "MSG_MMS_MESSAGE_TABLE" +#define MSG_SYNCML_MSG_TABLE_NAME "MSG_SYNCML_TABLE" +#define MSG_SCHEDULED_MSG_TABLE_NAME "MSG_SCHEDULED_TABLE" +#define MSG_SMS_SENDOPT_TABLE_NAME "MSG_SMS_SENDOPT_TABLE" +// ================================================================= +enum SQLAttributeType { + UNDEFINED_TYPE, + BOOLEAN, + INTEGER, + DATETIME, + TEXT, +}; + +struct AttributeInfo { + AttributeInfo(); + AttributeInfo(const std::string& in_sql_name, + const SQLAttributeType in_sql_type, + const tizen::PrimitiveType in_any_type); + AttributeInfo(const AttributeInfo& other); + AttributeInfo& operator=(const AttributeInfo& other); + + std::string sql_name; + SQLAttributeType sql_type; + tizen::PrimitiveType any_type; +}; + +typedef std::map AttributeInfoMap; + +struct EmailConversationInfo { + int id, unreadMessages; +}; +// ================================================================= + +class MessagingDatabaseManager { +public: + static MessagingDatabaseManager& getInstance(); + std::vector findShortMessages(FindMsgCallbackUserData* callback); + std::pair findEmails(FindMsgCallbackUserData* callback); +// std::vector findShortMessageConversations(ConversationCallbackData* callback); +// std::vector findEmailConversations(ConversationCallbackData* callback); + +private: + MessagingDatabaseManager(); + MessagingDatabaseManager(const MessagingDatabaseManager &); + void operator=(const MessagingDatabaseManager &); + virtual ~MessagingDatabaseManager(); + + msg_error_t connect(); + msg_error_t disconnect(); + msg_error_t getTable(std::string query, char*** results, int* resultsCount); + void freeTable(char*** array); + int cellToInt(char** array, int cellId); + std::string getMatchString(tizen::AnyPtr matchValue, + const tizen::PrimitiveType type) const; + std::string getAttributeFilterQuery(tizen::AbstractFilterPtr filter, + AttributeInfoMap& attributeMap, MessageType msgType); + std::string getAttributeRangeFilterQuery(tizen::AbstractFilterPtr filter, + AttributeInfoMap& attributeMap, MessageType msgType); + std::string getCompositeFilterQuery(tizen::AbstractFilterPtr filter, + AttributeInfoMap& attributeMap, MessageType msgType); + std::string addFilters(tizen::AbstractFilterPtr filter, tizen::SortModePtr sortMode, + long limit, long offset, AttributeInfoMap& attributeMap, MessageType msgType); + + AttributeInfoMap m_msg_attr_map; + AttributeInfoMap m_email_attr_map; + + AttributeInfoMap m_msg_conv_attr_map; + AttributeInfoMap m_email_conv_attr_map; +}; + +} // Messaging +} // DeviceAPI + +#endif // __TIZEN_MSG_DATABASE_MANAGER_H__