diff --git a/include/linphone/api/c-event-log.h b/include/linphone/api/c-event-log.h index 06840e39d..6450e24c2 100644 --- a/include/linphone/api/c-event-log.h +++ b/include/linphone/api/c-event-log.h @@ -56,12 +56,12 @@ LINPHONE_PUBLIC const LinphoneAddress *linphone_conference_participant_event_get const LinphoneConferenceParticipantEvent *conference_participant_event ); -LINPHONE_PUBLIC LinphoneChatMessageEvent *linphone_chat_message_event_new ( +LINPHONE_PUBLIC LinphoneConferenceChatMessageEvent *linphone_chat_message_event_new ( LinphoneChatMessage *chat_message, time_t time ); LINPHONE_PUBLIC LinphoneChatMessage *linphone_chat_message_event_get_chat_message ( - const LinphoneChatMessageEvent *chat_message_event + const LinphoneConferenceChatMessageEvent *chat_message_event ); #ifdef __cplusplus diff --git a/include/linphone/api/c-types.h b/include/linphone/api/c-types.h index cce57f2a4..6eb782d4d 100644 --- a/include/linphone/api/c-types.h +++ b/include/linphone/api/c-types.h @@ -133,7 +133,7 @@ typedef struct _LinphoneConferenceParticipantEvent LinphoneConferenceParticipant typedef struct _LinphoneConferenceParticipantDeviceEvent LinphoneConferenceParticipantDeviceEvent; typedef struct _LinphoneConferenceSubjectEvent LinphoneConferenceSubjectEvent; typedef struct _LinphoneEventLog LinphoneEventLog; -typedef struct _LinphoneChatMessageEvent LinphoneChatMessageEvent; +typedef struct _LinphoneConferenceChatMessageEvent LinphoneConferenceChatMessageEvent; // ============================================================================= // C Enums. diff --git a/include/linphone/enums/event-log-enums.h b/include/linphone/enums/event-log-enums.h index b209427bb..e5c0c92f8 100644 --- a/include/linphone/enums/event-log-enums.h +++ b/include/linphone/enums/event-log-enums.h @@ -24,11 +24,11 @@ #define L_ENUM_VALUES_EVENT_LOG_TYPE(F) \ F(None) \ - F(ChatMessage) \ F(CallStart) \ F(CallEnd) \ F(ConferenceCreated) \ F(ConferenceDestroyed) \ + F(ConferenceChatMessage) \ F(ConferenceParticipantAdded) \ F(ConferenceParticipantRemoved) \ F(ConferenceParticipantSetAdmin) \ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0ea9757d2..a861872d0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -94,7 +94,6 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES dial-plan/dial-plan.h enums.h event-log/call/call-event.h - event-log/chat/chat-message-event.h event-log/conference/conference-event-p.h event-log/conference/conference-event.h event-log/conference/conference-notified-event-p.h @@ -183,7 +182,7 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES db/session/db-session.cpp dial-plan/dial-plan.cpp event-log/call/call-event.cpp - event-log/chat/chat-message-event.cpp + event-log/conference/conference-chat-message-event.cpp event-log/conference/conference-event.cpp event-log/conference/conference-notified-event.cpp event-log/conference/conference-participant-device-event.cpp diff --git a/src/c-wrapper/api/c-event-log.cpp b/src/c-wrapper/api/c-event-log.cpp index b1469ec0c..c6a2a21d6 100644 --- a/src/c-wrapper/api/c-event-log.cpp +++ b/src/c-wrapper/api/c-event-log.cpp @@ -27,13 +27,13 @@ // ============================================================================= -L_DECLARE_C_BASE_OBJECT_IMPL(EventLog); L_DECLARE_C_BASE_OBJECT_IMPL(CallEvent); +L_DECLARE_C_BASE_OBJECT_IMPL(ConferenceChatMessageEvent); L_DECLARE_C_BASE_OBJECT_IMPL(ConferenceEvent); -L_DECLARE_C_BASE_OBJECT_IMPL(ConferenceParticipantEvent); L_DECLARE_C_BASE_OBJECT_IMPL(ConferenceParticipantDeviceEvent); +L_DECLARE_C_BASE_OBJECT_IMPL(ConferenceParticipantEvent); L_DECLARE_C_BASE_OBJECT_IMPL(ConferenceSubjectEvent); -L_DECLARE_C_BASE_OBJECT_IMPL(ChatMessageEvent); +L_DECLARE_C_BASE_OBJECT_IMPL(EventLog); using namespace std; @@ -124,11 +124,11 @@ const LinphoneAddress *linphone_conference_participant_event_get_participant_add // Message event. // ----------------------------------------------------------------------------- -LinphoneChatMessageEvent *linphone_chat_message_event_new (LinphoneChatMessage *chat_message, time_t time) { - LinphoneChatMessageEvent *chat_message_event = _linphone_ChatMessageEvent_init(); +LinphoneConferenceChatMessageEvent *linphone_chat_message_event_new (LinphoneChatMessage *chat_message, time_t time) { + LinphoneConferenceChatMessageEvent *chat_message_event = _linphone_ConferenceChatMessageEvent_init(); L_SET_CPP_PTR_FROM_C_OBJECT( chat_message_event, - new LinphonePrivate::ChatMessageEvent( + new LinphonePrivate::ConferenceChatMessageEvent( time, L_GET_CPP_PTR_FROM_C_OBJECT(chat_message) ) @@ -136,7 +136,9 @@ LinphoneChatMessageEvent *linphone_chat_message_event_new (LinphoneChatMessage * return chat_message_event; } -LinphoneChatMessage *linphone_chat_message_event_get_chat_message (const LinphoneChatMessageEvent *chat_message_event) { +LinphoneChatMessage *linphone_chat_message_event_get_chat_message ( + const LinphoneConferenceChatMessageEvent *chat_message_event +) { return L_GET_C_BACK_PTR( L_GET_CPP_PTR_FROM_C_OBJECT(chat_message_event)->getChatMessage() ); diff --git a/src/c-wrapper/c-wrapper.h b/src/c-wrapper/c-wrapper.h index c9c9bbf53..08a8d26a4 100644 --- a/src/c-wrapper/c-wrapper.h +++ b/src/c-wrapper/c-wrapper.h @@ -33,11 +33,11 @@ F(Call, Call) \ F(CallEvent, CallEvent) \ F(ChatMessage, ChatMessage) \ - F(ChatMessageEvent, ChatMessageEvent) \ F(ChatRoom, ChatRoom) \ + F(ConferenceChatMessageEvent, ConferenceChatMessageEvent) \ F(ConferenceEvent, ConferenceEvent) \ - F(ConferenceParticipantEvent, ConferenceParticipantEvent) \ F(ConferenceParticipantDeviceEvent, ConferenceParticipantDeviceEvent) \ + F(ConferenceParticipantEvent, ConferenceParticipantEvent) \ F(ConferenceSubjectEvent, ConferenceSubjectEvent) \ F(DialPlan, DialPlan) \ F(EventLog, EventLog) \ diff --git a/src/chat/chat-message/chat-message.cpp b/src/chat/chat-message/chat-message.cpp index e80b6a0d6..6253922f5 100644 --- a/src/chat/chat-message/chat-message.cpp +++ b/src/chat/chat-message/chat-message.cpp @@ -1364,6 +1364,13 @@ const list& ChatMessage::getContents () const { return d->contents; } +void ChatMessage::addContent (Content &&content) { + L_D(); + if (d->isReadOnly) return; + + d->contents.push_back(move(content)); +} + void ChatMessage::addContent (const Content &content) { L_D(); if (d->isReadOnly) return; diff --git a/src/chat/chat-message/chat-message.h b/src/chat/chat-message/chat-message.h index c45253e7f..b1c0a0139 100644 --- a/src/chat/chat-message/chat-message.h +++ b/src/chat/chat-message/chat-message.h @@ -94,6 +94,7 @@ public: bool isReadOnly () const; const std::list &getContents () const; + void addContent (Content &&content); void addContent (const Content &content); void removeContent (const Content &content); diff --git a/src/db/main-db-p.h b/src/db/main-db-p.h index 84fdf413c..421c0ecdf 100644 --- a/src/db/main-db-p.h +++ b/src/db/main-db-p.h @@ -42,29 +42,18 @@ private: long insertSipAddress (const std::string &sipAddress); void insertContent (long messageEventId, const Content &content); long insertContentType (const std::string &contentType); - long insertEvent (EventLog::Type type, const tm &date); long insertChatRoom (long sipAddressId, int capabilities, const tm &date); void insertChatRoomParticipant (long chatRoomId, long sipAddressId, bool isAdmin); - - long insertMessageEvent ( - const MessageEventReferences &references, - int state, - int direction, - const std::string &imdnMessageId, - bool isSecured, - const std::list &contents - ); - - void insertMessageParticipant (long messageEventId, long sipAddressId, int state); + void insertChatMessageParticipant (long messageEventId, long sipAddressId, int state); // --------------------------------------------------------------------------- // Events API. // --------------------------------------------------------------------------- long insertEvent (const EventLog &eventLog); - long insertCallEvent (const EventLog &eventLog); - long insertMessageEvent (const EventLog &eventLog); long insertConferenceEvent (const EventLog &eventLog, long *chatRoomId = nullptr); + long insertConferenceCallEvent (const EventLog &eventLog); + long insertConferenceChatMessageEvent (const EventLog &eventLog); long insertConferenceNotifiedEvent (const EventLog &eventLog); long insertConferenceParticipantEvent (const EventLog &eventLog); long insertConferenceParticipantDeviceEvent (const EventLog &eventLog); diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp index 191932e60..5c250afa4 100644 --- a/src/db/main-db.cpp +++ b/src/db/main-db.cpp @@ -42,13 +42,6 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -struct MessageEventReferences { - long eventId; - long localSipAddressId; - long remoteSipAddressId; - long chatRoomId; -}; - // ----------------------------------------------------------------------------- MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} @@ -73,9 +66,13 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} } static constexpr EnumToSql eventFilterToSql[] = { - { MainDb::MessageFilter, "1" }, - { MainDb::CallFilter, "2" }, - { MainDb::ConferenceFilter, "3" } + { MainDb::ConferenceCallFilter, "type = 1 OR type = 2" }, + { MainDb::ConferenceChatMessageFilter, "type = 5" }, + { + MainDb::ConferenceInfoFilter, + "type = 3 OR type = 4 OR type = 6 OR type = 7 OR type = 8 OR " + "type = 9 OR type = 10 OR type = 11 OR type = 12" + } }; static constexpr const char *mapEventFilterToSql (MainDb::Filter filter) { @@ -107,7 +104,6 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} sql += " WHERE "; } else sql += " OR "; - sql += " type = "; sql += mapEventFilterToSql(filter); } @@ -135,13 +131,13 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} soci::session *session = dbSession.getBackendSession(); long contentTypeId = insertContentType(content.getContentType().asString()); - *session << "INSERT INTO message_content (event_id, content_type_id, body) VALUES" + *session << "INSERT INTO chat_message_content (event_id, content_type_id, body) VALUES" " (:eventId, :contentTypeId, :body)", soci::use(eventId), soci::use(contentTypeId), soci::use(content.getBodyAsString()); long messageContentId = q->getLastInsertId(); for (const auto &appData : content.getAppDataMap()) - *session << "INSERT INTO message_content_app_data (message_content_id, key, data) VALUES" + *session << "INSERT INTO chat_message_content_app_data (chat_message_content_id, key, data) VALUES" " (:messageContentId, :key, :data)", soci::use(messageContentId), soci::use(appData.first), soci::use(appData.second); } @@ -159,15 +155,6 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} return q->getLastInsertId(); } - long MainDbPrivate::insertEvent (EventLog::Type type, const tm &date) { - L_Q(); - soci::session *session = dbSession.getBackendSession(); - - *session << "INSERT INTO event (type, date) VALUES (:type, :date)", - soci::use(static_cast(type)), soci::use(date); - return q->getLastInsertId(); - } - long MainDbPrivate::insertChatRoom (long sipAddressId, int capabilities, const tm &date) { soci::session *session = dbSession.getBackendSession(); @@ -199,45 +186,16 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} soci::use(chatRoomId), soci::use(sipAddressId), soci::use(static_cast(isAdmin)); } - long MainDbPrivate::insertMessageEvent ( - const MessageEventReferences &references, - int state, - int direction, - const string &imdnMessageId, - bool isSecured, - const list &contents - ) { - L_Q(); - soci::session *session = dbSession.getBackendSession(); - - *session << "INSERT INTO message_event (" - " event_id, chat_room_id, local_sip_address_id, remote_sip_address_id," - " state, direction, imdn_message_id, is_secured" - ") VALUES (" - " :eventId, :chatRoomId, :localSipaddressId, :remoteSipaddressId," - " :state, :direction, :imdnMessageId, :isSecured" - ")", soci::use(references.eventId), soci::use(references.chatRoomId), soci::use(references.localSipAddressId), - soci::use(references.remoteSipAddressId), soci::use(state), soci::use(direction), - soci::use(imdnMessageId), soci::use(isSecured ? 1 : 0); - - long eventId = q->getLastInsertId(); - - for (const auto &content : contents) - insertContent(eventId, content); - - return eventId; - } - - void MainDbPrivate::insertMessageParticipant (long eventId, long sipAddressId, int state) { + void MainDbPrivate::insertChatMessageParticipant (long eventId, long sipAddressId, int state) { soci::session *session = dbSession.getBackendSession(); soci::statement statement = ( - session->prepare << "UPDATE message_participant SET state = :state" + session->prepare << "UPDATE chat_message_participant SET state = :state" " WHERE event_id = :eventId AND sip_address_id = :sipAddressId", soci::use(state), soci::use(eventId), soci::use(sipAddressId) ); statement.execute(true); if (statement.get_affected_rows() == 0 && state != static_cast(ChatMessage::State::Displayed)) - *session << "INSERT INTO message_participant (event_id, sip_address_id, state)" + *session << "INSERT INTO chat_message_participant (event_id, sip_address_id, state)" " VALUES (:eventId, :sipAddressId, :state)", soci::use(eventId), soci::use(sipAddressId), soci::use(state); } @@ -245,42 +203,12 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} // ----------------------------------------------------------------------------- long MainDbPrivate::insertEvent (const EventLog &eventLog) { - return insertEvent(eventLog.getType(), Utils::getLongAsTm(eventLog.getTime())); - } + L_Q(); + soci::session *session = dbSession.getBackendSession(); - long MainDbPrivate::insertCallEvent (const EventLog &eventLog) { - // TODO. - return 0; - } - - long MainDbPrivate::insertMessageEvent (const EventLog &eventLog) { - shared_ptr chatMessage = static_cast(eventLog).getChatMessage(); - shared_ptr chatRoom = chatMessage->getChatRoom(); - if (!chatRoom) { - lError() << "Unable to get a valid chat room. It was removed from database."; - return -1; - } - - tm eventTime = Utils::getLongAsTm(static_cast(eventLog.getTime())); - - struct MessageEventReferences references; - references.eventId = insertEvent(EventLog::Type::ChatMessage, eventTime); - references.localSipAddressId = insertSipAddress(chatMessage->getLocalAddress().asString()); - references.remoteSipAddressId = insertSipAddress(chatMessage->getRemoteAddress().asString()); - references.chatRoomId = insertChatRoom( - references.remoteSipAddressId, - chatRoom->getCapabilities(), - eventTime - ); - - return insertMessageEvent ( - references, - static_cast(chatMessage->getState()), - static_cast(chatMessage->getDirection()), - chatMessage->getImdnMessageId(), - chatMessage->isSecured(), - chatMessage->getContents() - ); + *session << "INSERT INTO event (type, date) VALUES (:type, :date)", + soci::use(static_cast(eventLog.getType())), soci::use(Utils::getLongAsTm(eventLog.getTime())); + return q->getLastInsertId(); } long MainDbPrivate::insertConferenceEvent (const EventLog &eventLog, long *chatRoomId) { @@ -299,6 +227,44 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} return eventId; } + long MainDbPrivate::insertConferenceCallEvent (const EventLog &eventLog) { + // TODO. + return 0; + } + + long MainDbPrivate::insertConferenceChatMessageEvent (const EventLog &eventLog) { + shared_ptr chatMessage = static_cast(eventLog).getChatMessage(); + shared_ptr chatRoom = chatMessage->getChatRoom(); + if (!chatRoom) { + lError() << "Unable to get a valid chat room. It was removed from database."; + return -1; + } + + tm eventTime = Utils::getLongAsTm(static_cast(eventLog.getTime())); + + long localSipAddressId = insertSipAddress(chatMessage->getLocalAddress().asString()); + long remoteSipAddressId = insertSipAddress(chatMessage->getRemoteAddress().asString()); + insertChatRoom(remoteSipAddressId, chatRoom->getCapabilities(), eventTime); + long eventId = insertConferenceEvent(eventLog); + + soci::session *session = dbSession.getBackendSession(); + + *session << "INSERT INTO conference_chat_message_event (" + " event_id, local_sip_address_id, remote_sip_address_id," + " state, direction, imdn_message_id, is_secured" + ") VALUES (" + " :eventId, :localSipaddressId, :remoteSipaddressId," + " :state, :direction, :imdnMessageId, :isSecured" + ")", soci::use(eventId), soci::use(localSipAddressId), soci::use(remoteSipAddressId), + soci::use(static_cast(chatMessage->getState())), soci::use(static_cast(chatMessage->getDirection())), + soci::use(chatMessage->getImdnMessageId()), soci::use(chatMessage->isSecured() ? 1 : 0); + + for (const auto &content : chatMessage->getContents()) + insertContent(eventId, content); + + return eventId; + } + long MainDbPrivate::insertConferenceNotifiedEvent (const EventLog &eventLog) { long chatRoomId; long eventId = insertConferenceEvent(eventLog, &chatRoomId); @@ -351,34 +317,6 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} return eventId; } -// ----------------------------------------------------------------------------- - - #define LEGACY_MESSAGE_COL_LOCAL_ADDRESS 1 - #define LEGACY_MESSAGE_COL_REMOTE_ADDRESS 2 - #define LEGACY_MESSAGE_COL_DIRECTION 3 - #define LEGACY_MESSAGE_COL_TEXT 4 - #define LEGACY_MESSAGE_COL_STATE 7 - #define LEGACY_MESSAGE_COL_URL 8 - #define LEGACY_MESSAGE_COL_DATE 9 - #define LEGACY_MESSAGE_COL_APP_DATA 10 - #define LEGACY_MESSAGE_COL_CONTENT_ID 11 - #define LEGACY_MESSAGE_COL_IMDN_MESSAGE_ID 12 - #define LEGACY_MESSAGE_COL_CONTENT_TYPE 13 - #define LEGACY_MESSAGE_COL_IS_SECURED 14 - - template - static T getValueFromLegacyMessage (const soci::row &message, int index, bool &isNull) { - isNull = false; - - try { - return message.get(static_cast(index)); - } catch (const exception &) { - isNull = true; - } - - return T(); - } - // ----------------------------------------------------------------------------- void MainDb::init () { @@ -503,9 +441,8 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} ")"; *session << - "CREATE TABLE IF NOT EXISTS message_event (" + "CREATE TABLE IF NOT EXISTS conference_chat_message_event (" " event_id INT UNSIGNED PRIMARY KEY," - " chat_room_id INT UNSIGNED NOT NULL," " local_sip_address_id INT UNSIGNED NOT NULL," " remote_sip_address_id INT UNSIGNED NOT NULL," @@ -517,10 +454,7 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} " is_secured BOOLEAN NOT NULL," " FOREIGN KEY (event_id)" - " REFERENCES event(id)" - " ON DELETE CASCADE," - " FOREIGN KEY (chat_room_id)" - " REFERENCES chat_room(peer_sip_address_id)" + " REFERENCES conference_event(id)" " ON DELETE CASCADE," " FOREIGN KEY (local_sip_address_id)" " REFERENCES sip_address(id)" @@ -531,14 +465,14 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} ")"; *session << - "CREATE TABLE IF NOT EXISTS message_participant (" + "CREATE TABLE IF NOT EXISTS chat_message_participant (" " event_id INT UNSIGNED NOT NULL," " sip_address_id INT UNSIGNED NOT NULL," " state TINYINT UNSIGNED NOT NULL," " PRIMARY KEY (event_id, sip_address_id)," " FOREIGN KEY (event_id)" - " REFERENCES message_event(event_id)" + " REFERENCES conference_chat_message_event(event_id)" " ON DELETE CASCADE," " FOREIGN KEY (sip_address_id)" " REFERENCES sip_address(id)" @@ -546,14 +480,14 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} ")"; *session << - "CREATE TABLE IF NOT EXISTS message_content (" + "CREATE TABLE IF NOT EXISTS chat_message_content (" " id" + primaryKeyAutoIncrementStr() + "," " event_id INT UNSIGNED NOT NULL," " content_type_id INT UNSIGNED NOT NULL," " body TEXT NOT NULL," " FOREIGN KEY (event_id)" - " REFERENCES message_event(event_id)" + " REFERENCES conference_chat_message_event(event_id)" " ON DELETE CASCADE," " FOREIGN KEY (content_type_id)" " REFERENCES content_type(id)" @@ -561,46 +495,46 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} ")"; *session << - "CREATE TABLE IF NOT EXISTS message_content_app_data (" - " message_content_id INT UNSIGNED NOT NULL," + "CREATE TABLE IF NOT EXISTS chat_message_content_app_data (" + " chat_message_content_id INT UNSIGNED NOT NULL," " key VARCHAR(255)," " data BLOB," - " PRIMARY KEY (message_content_id, key)," - " FOREIGN KEY (message_content_id)" - " REFERENCES message_content(id)" + " PRIMARY KEY (chat_message_content_id, key)," + " FOREIGN KEY (chat_message_content_id)" + " REFERENCES chat_message_content(id)" " ON DELETE CASCADE" ")"; *session << - "CREATE TABLE IF NOT EXISTS message_crypto_data (" + "CREATE TABLE IF NOT EXISTS conference_message_crypto_data (" " event_id INT UNSIGNED NOT NULL," " key VARCHAR(255)," " data BLOB," " PRIMARY KEY (event_id, key)," " FOREIGN KEY (event_id)" - " REFERENCES message_event(event_id)" + " REFERENCES conference_chat_message_event(event_id)" " ON DELETE CASCADE" ")"; // Trigger to delete participant_message cache entries. string displayedId = Utils::toString(static_cast(ChatMessage::State::Displayed)); string participantMessageDeleter = - "CREATE TRIGGER IF NOT EXISTS message_participant_deleter" - " AFTER UPDATE OF state ON message_participant FOR EACH ROW" + "CREATE TRIGGER IF NOT EXISTS chat_message_participant_deleter" + " AFTER UPDATE OF state ON chat_message_participant FOR EACH ROW" " WHEN NEW.state = "; participantMessageDeleter += displayedId; participantMessageDeleter += " AND (SELECT COUNT(*) FROM (" - " SELECT state FROM message_participant WHERE" - " NEW.event_id = message_participant.event_id" + " SELECT state FROM chat_message_participant WHERE" + " NEW.event_id = chat_message_participant.event_id" " AND state <> "; participantMessageDeleter += displayedId; participantMessageDeleter += " LIMIT 1" " )) = 0" " BEGIN" - " DELETE FROM message_participant WHERE NEW.event_id = message_participant.event_id;" - " UPDATE message_event SET state = "; + " DELETE FROM chat_message_participant WHERE NEW.event_id = chat_message_participant.event_id;" + " UPDATE conference_chat_message_event SET state = "; participantMessageDeleter += displayedId; participantMessageDeleter += " WHERE event_id = NEW.event_id;" " END"; @@ -626,13 +560,13 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} case EventLog::Type::None: return false; - case EventLog::Type::ChatMessage: - d->insertMessageEvent(eventLog); + case EventLog::Type::ConferenceChatMessage: + d->insertConferenceChatMessageEvent(eventLog); break; case EventLog::Type::CallStart: case EventLog::Type::CallEnd: - d->insertCallEvent(eventLog); + d->insertConferenceCallEvent(eventLog); break; case EventLog::Type::ConferenceCreated: @@ -698,7 +632,7 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} } string query = "DELETE FROM event" + - buildSqlEventFilter({ MessageFilter, CallFilter, ConferenceFilter }, mask); + buildSqlEventFilter({ ConferenceCallFilter, ConferenceChatMessageFilter, ConferenceInfoFilter }, mask); L_BEGIN_LOG_EXCEPTION @@ -717,7 +651,7 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} } string query = "SELECT COUNT(*) FROM event" + - buildSqlEventFilter({ MessageFilter, CallFilter, ConferenceFilter }, mask); + buildSqlEventFilter({ ConferenceCallFilter, ConferenceChatMessageFilter, ConferenceInfoFilter }, mask); int count = 0; L_BEGIN_LOG_EXCEPTION @@ -744,12 +678,14 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} soci::session *session = d->dbSession.getBackendSession(); - string query = "SELECT COUNT(*) FROM message_event"; + string query = "SELECT COUNT(*) FROM conference_chat_message_event"; if (peerAddress.empty()) *session << query, soci::into(count); else { - query += " WHERE chat_room_id = (" - " SELECT id FROM sip_address WHERE value = :peerAddress" + query += " WHERE event_id IN (" + " SELECT event_id FROM conference_event WHERE chat_room_id = (" + " SELECT id FROM sip_address WHERE value = :peerAddress" + " )" ")"; *session << query, soci::use(peerAddress), soci::into(count); @@ -770,14 +706,16 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} int count = 0; - string query = "SELECT COUNT(*) FROM message_event WHERE"; + string query = "SELECT COUNT(*) FROM conference_chat_message_event WHERE"; if (!peerAddress.empty()) - query += " chat_room_id = (" - " SELECT id FROM sip_address WHERE value = :peerAddress" - ") AND "; + query += " event_id IN (" + " SELECT event_id FROM conference_event WHERE chat_room_id = (" + " SELECT id FROM sip_address WHERE value = :peerAddress" + " )" + ") AND"; query += " direction = " + Utils::toString(static_cast(ChatMessage::Direction::Incoming)) + - + " AND state <> " + Utils::toString(static_cast(ChatMessage::State::Displayed)); + + " AND state <> " + Utils::toString(static_cast(ChatMessage::State::Displayed)); L_BEGIN_LOG_EXCEPTION @@ -834,11 +772,9 @@ MainDb::MainDb () : AbstractDb(*new MainDbPrivate) {} } string query; - if (mask == MainDb::NoFilter || mask & MessageFilter) - query += "SELECT event_id FROM message_event WHERE chat_room_id = (" - " SELECT peer_sip_address_id FROM chat_room WHERE peer_sip_address_id = (" - " SELECT id FROM sip_address WHERE value = :peerAddress" - " )" + if (mask == MainDb::NoFilter || mask & ConferenceChatMessageFilter) + query += "SELECT event_id FROM conference_event WHERE chat_room_id = (" + " SELECT id FROM sip_address WHERE value = :peerAddress" ")"; if (query.empty()) @@ -890,6 +826,32 @@ shared_ptr MainDb::findChatRoom (const string &peerAddress) const { // ----------------------------------------------------------------------------- + #define LEGACY_MESSAGE_COL_LOCAL_ADDRESS 1 + #define LEGACY_MESSAGE_COL_REMOTE_ADDRESS 2 + #define LEGACY_MESSAGE_COL_DIRECTION 3 + #define LEGACY_MESSAGE_COL_TEXT 4 + #define LEGACY_MESSAGE_COL_STATE 7 + #define LEGACY_MESSAGE_COL_URL 8 + #define LEGACY_MESSAGE_COL_DATE 9 + #define LEGACY_MESSAGE_COL_APP_DATA 10 + #define LEGACY_MESSAGE_COL_CONTENT_ID 11 + #define LEGACY_MESSAGE_COL_IMDN_MESSAGE_ID 12 + #define LEGACY_MESSAGE_COL_CONTENT_TYPE 13 + #define LEGACY_MESSAGE_COL_IS_SECURED 14 + + template + static T getValueFromLegacyMessage (const soci::row &message, int index, bool &isNull) { + isNull = false; + + try { + return message.get(static_cast(index)); + } catch (const exception &) { + isNull = true; + } + + return T(); + } + bool MainDb::import (Backend, const string ¶meters) { L_D(); @@ -971,33 +933,32 @@ shared_ptr MainDb::findChatRoom (const string &peerAddress) const { content.setAppData("legacy", appData); } - struct MessageEventReferences references; - references.eventId = d->insertEvent(EventLog::Type::ChatMessage, date); - references.localSipAddressId = d->insertSipAddress(message.get(LEGACY_MESSAGE_COL_LOCAL_ADDRESS)); - references.remoteSipAddressId = d->insertSipAddress(message.get(LEGACY_MESSAGE_COL_REMOTE_ADDRESS)); - references.chatRoomId = d->insertChatRoom( - references.remoteSipAddressId, - static_cast(ChatRoom::Capabilities::Basic), - date - ); + soci::session *session = d->dbSession.getBackendSession(); + *session << "INSERT INTO event (type, date) VALUES (:type, :date)", + soci::use(static_cast(EventLog::Type::ConferenceChatMessage)), soci::use(date); - d->insertChatRoomParticipant(references.chatRoomId, references.remoteSipAddressId, false); + long eventId = getLastInsertId(); + long localSipAddressId = d->insertSipAddress(message.get(LEGACY_MESSAGE_COL_LOCAL_ADDRESS)); + long remoteSipAddressId = d->insertSipAddress(message.get(LEGACY_MESSAGE_COL_REMOTE_ADDRESS)); + long chatRoomId = d->insertChatRoom(remoteSipAddressId, static_cast(ChatRoom::Capabilities::Basic), date); - long eventId = d->insertMessageEvent ( - references, - state, - direction, - message.get(LEGACY_MESSAGE_COL_IMDN_MESSAGE_ID, ""), - !!message.get(LEGACY_MESSAGE_COL_IS_SECURED, 0), - { move(content) } - ); + *session << "INSERT INTO conference_event (event_id, chat_room_id)" + " VALUES (:eventId, :chatRoomId)", soci::use(eventId), soci::use(chatRoomId); + + *session << "INSERT INTO conference_chat_message_event (" + " event_id, local_sip_address_id, remote_sip_address_id," + " state, direction, imdn_message_id, is_secured" + ") VALUES (" + " :eventId, :localSipaddressId, :remoteSipaddressId," + " :state, :direction, '', :isSecured" + ")", soci::use(eventId), soci::use(localSipAddressId), soci::use(remoteSipAddressId), + soci::use(state), soci::use(direction), soci::use(message.get(LEGACY_MESSAGE_COL_IS_SECURED, 0)); + + d->insertContent(eventId, content); + d->insertChatRoomParticipant(chatRoomId, remoteSipAddressId, false); if (state != static_cast(ChatMessage::State::Displayed)) - d->insertMessageParticipant( - eventId, - references.remoteSipAddressId, - state - ); + d->insertChatMessageParticipant(eventId, remoteSipAddressId, state); } tr.commit(); diff --git a/src/db/main-db.h b/src/db/main-db.h index ae1dfe40f..08531f11d 100644 --- a/src/db/main-db.h +++ b/src/db/main-db.h @@ -38,9 +38,9 @@ class LINPHONE_PUBLIC MainDb : public AbstractDb { public: enum Filter { NoFilter = 0x0, - MessageFilter = 0x1, - CallFilter = 0x2, - ConferenceFilter = 0x4 + ConferenceCallFilter = 0x1, + ConferenceChatMessageFilter = 0x2, + ConferenceInfoFilter = 0x4 }; typedef int FilterMask; diff --git a/src/event-log/chat/chat-message-event.cpp b/src/event-log/conference/conference-chat-message-event.cpp similarity index 70% rename from src/event-log/chat/chat-message-event.cpp rename to src/event-log/conference/conference-chat-message-event.cpp index 498c417ac..cfc7981ef 100644 --- a/src/event-log/chat/chat-message-event.cpp +++ b/src/event-log/conference/conference-chat-message-event.cpp @@ -1,5 +1,5 @@ /* - * chat-message-event.cpp + * conference-chat-message-event.cpp * Copyright (C) 2010-2017 Belledonne Communications SARL * * This program is free software; you can redistribute it and/or @@ -17,8 +17,9 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "chat-message-event.h" -#include "event-log/event-log-p.h" +#include "chat/chat-message/chat-message.h" +#include "conference-chat-message-event.h" +#include "conference-event-p.h" // ============================================================================= @@ -26,23 +27,28 @@ using namespace std; LINPHONE_BEGIN_NAMESPACE -class ChatMessageEventPrivate : public EventLogPrivate { +class ConferenceChatMessageEventPrivate : public ConferenceEventPrivate { public: shared_ptr chatMessage; }; // ----------------------------------------------------------------------------- -ChatMessageEvent::ChatMessageEvent ( +ConferenceChatMessageEvent::ConferenceChatMessageEvent ( time_t time, const shared_ptr &chatMessage -) : EventLog(*new ChatMessageEventPrivate, EventLog::Type::ChatMessage, time) { +) : ConferenceEvent( + *new ConferenceChatMessageEventPrivate, + EventLog::Type::ConferenceChatMessage, + time, + chatMessage->getRemoteAddress() +) { L_D(); L_ASSERT(chatMessage); d->chatMessage = chatMessage; } -shared_ptr ChatMessageEvent::getChatMessage () const { +shared_ptr ConferenceChatMessageEvent::getChatMessage () const { L_D(); return d->chatMessage; } diff --git a/src/event-log/chat/chat-message-event.h b/src/event-log/conference/conference-chat-message-event.h similarity index 77% rename from src/event-log/chat/chat-message-event.h rename to src/event-log/conference/conference-chat-message-event.h index 82ccc1804..f64cf7afd 100644 --- a/src/event-log/chat/chat-message-event.h +++ b/src/event-log/conference/conference-chat-message-event.h @@ -22,24 +22,24 @@ #include -#include "event-log/event-log.h" +#include "conference-event.h" // ============================================================================= LINPHONE_BEGIN_NAMESPACE class ChatMessage; -class ChatMessageEventPrivate; +class ConferenceChatMessageEventPrivate; -class LINPHONE_PUBLIC ChatMessageEvent : public EventLog { +class LINPHONE_PUBLIC ConferenceChatMessageEvent : public ConferenceEvent { public: - ChatMessageEvent (std::time_t time, const std::shared_ptr &chatMessage); + ConferenceChatMessageEvent (std::time_t time, const std::shared_ptr &chatMessage); std::shared_ptr getChatMessage () const; private: - L_DECLARE_PRIVATE(ChatMessageEvent); - L_DISABLE_COPY(ChatMessageEvent); + L_DECLARE_PRIVATE(ConferenceChatMessageEvent); + L_DISABLE_COPY(ConferenceChatMessageEvent); }; LINPHONE_END_NAMESPACE diff --git a/src/event-log/events.h b/src/event-log/events.h index 5911acb3d..bc6b8bab9 100644 --- a/src/event-log/events.h +++ b/src/event-log/events.h @@ -21,7 +21,7 @@ #define _EVENTS_H_ #include "call/call-event.h" -#include "chat/chat-message-event.h" +#include "conference/conference-chat-message-event.h" #include "conference/conference-participant-device-event.h" #include "conference/conference-subject-event.h" diff --git a/tester/events-db-tester.cpp b/tester/events-db-tester.cpp index 159244c28..f27c425e4 100644 --- a/tester/events-db-tester.cpp +++ b/tester/events-db-tester.cpp @@ -44,9 +44,9 @@ static void get_events_count () { MainDb eventsDb; BC_ASSERT_TRUE(eventsDb.connect(MainDb::Sqlite3, getDatabasePath())); BC_ASSERT_EQUAL(eventsDb.getEventsCount(), 4976, int, "%d"); - BC_ASSERT_EQUAL(eventsDb.getEventsCount(MainDb::CallFilter), 0, int, "%d"); - BC_ASSERT_EQUAL(eventsDb.getEventsCount(MainDb::ConferenceFilter), 0, int, "%d"); - BC_ASSERT_EQUAL(eventsDb.getEventsCount(MainDb::MessageFilter), 4976, int, "%d"); + BC_ASSERT_EQUAL(eventsDb.getEventsCount(MainDb::ConferenceCallFilter), 0, int, "%d"); + BC_ASSERT_EQUAL(eventsDb.getEventsCount(MainDb::ConferenceInfoFilter), 0, int, "%d"); + BC_ASSERT_EQUAL(eventsDb.getEventsCount(MainDb::ConferenceChatMessageFilter), 4976, int, "%d"); BC_ASSERT_EQUAL(eventsDb.getEventsCount(MainDb::NoFilter), 4976, int, "%d"); }