diff --git a/src/conference/participant-device.h b/src/conference/participant-device.h index 0190baa66..5110fe48f 100644 --- a/src/conference/participant-device.h +++ b/src/conference/participant-device.h @@ -55,8 +55,10 @@ private: IdentityAddress mGruu; std::shared_ptr mSession; LinphoneEvent *mConferenceSubscribeEvent = nullptr; + + L_DISABLE_COPY(ParticipantDevice); }; LINPHONE_END_NAMESPACE -#endif // ifndef _PARTICIPANT_DEVICE_H_ \ No newline at end of file +#endif // ifndef _PARTICIPANT_DEVICE_H_ diff --git a/src/conference/participant.h b/src/conference/participant.h index 90fce744a..4f1cbfa62 100644 --- a/src/conference/participant.h +++ b/src/conference/participant.h @@ -46,6 +46,7 @@ class Participant : public Object { friend class LocalConferenceEventHandler; friend class LocalConferenceEventHandlerPrivate; friend class MainDb; + friend class MainDbPrivate; friend class MediaSessionPrivate; friend class RemoteConference; friend class RemoteConferenceCall; diff --git a/src/db/main-db-p.h b/src/db/main-db-p.h index 49a91299f..d6fe4fda6 100644 --- a/src/db/main-db-p.h +++ b/src/db/main-db-p.h @@ -61,7 +61,8 @@ private: const tm &creationTime ); long long insertChatRoom (const std::shared_ptr &chatRoom); - void insertChatRoomParticipant (long long chatRoomId, long long sipAddressId, bool isAdmin); + long long insertChatRoomParticipant (long long chatRoomId, long long sipAddressId, bool isAdmin); + void insertChatRoomParticipantDevice (long long participantId, long long sipAddressId); void insertChatMessageParticipant (long long messageEventId, long long sipAddressId, int state); long long selectSipAddressId (const std::string &sipAddress) const; diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp index 012a835eb..f50bdaa53 100644 --- a/src/db/main-db.cpp +++ b/src/db/main-db.cpp @@ -278,28 +278,58 @@ MainDb::MainDb (const shared_ptr &core) : AbstractDb(*new MainDbPrivate), insertChatRoomParticipant(id, insertSipAddress(me->getAddress().asString()), me->isAdmin()); } - for (const auto &participant : chatRoom->getParticipants()) - insertChatRoomParticipant(id, insertSipAddress(participant->getAddress().asString()), participant->isAdmin()); + for (const auto &participant : chatRoom->getParticipants()) { + long long participantId = insertChatRoomParticipant( + id, + insertSipAddress(participant->getAddress().asString()), + participant->isAdmin() + ); + for (const auto &device : participant->getPrivate()->getDevices()) + insertChatRoomParticipantDevice(participantId, insertSipAddress(device->getAddress().asString())); + } return id; } - void MainDbPrivate::insertChatRoomParticipant (long long chatRoomId, long long sipAddressId, bool isAdmin) { - // See: https://stackoverflow.com/a/15299655 (cast to reference) + long long MainDbPrivate::insertChatRoomParticipant (long long chatRoomId, long long sipAddressId, bool isAdmin) { + L_Q(); + long long id = -1; soci::session *session = dbSession.getBackendSession(); - soci::statement statement = ( - session->prepare << "UPDATE chat_room_participant SET is_admin = :isAdmin" - " WHERE chat_room_id = :chatRoomId AND participant_sip_address_id = :sipAddressId", - soci::use(static_cast(isAdmin)), soci::use(chatRoomId), soci::use(sipAddressId) - ); - statement.execute(true); - if (statement.get_affected_rows() == 0) { - lInfo() << "Insert new chat room participant in database: `" << sipAddressId << "` (isAdmin=" << isAdmin << ")."; - *session << "INSERT INTO chat_room_participant (chat_room_id, participant_sip_address_id, is_admin)" - " VALUES (:chatRoomId, :sipAddressId, :isAdmin)", - soci::use(chatRoomId), soci::use(sipAddressId), soci::use(static_cast(isAdmin)); + *session << "SELECT id from chat_room_participant" + " WHERE chat_room_id = :chatRoomId AND participant_sip_address_id = :sipAddressId", + soci::into(id), soci::use(chatRoomId), soci::use(sipAddressId); + + if (id >= 0) { + // See: https://stackoverflow.com/a/15299655 (cast to reference) + *session << "UPDATE chat_room_participant SET is_admin = :isAdmin" + " WHERE id = :id", + soci::use(static_cast(isAdmin)), soci::use(id); + return id; } + + lInfo() << "Insert new chat room participant in database: `" << sipAddressId << "` (isAdmin=" << isAdmin << ")."; + *session << "INSERT INTO chat_room_participant (chat_room_id, participant_sip_address_id, is_admin)" + " VALUES (:chatRoomId, :sipAddressId, :isAdmin)", + soci::use(chatRoomId), soci::use(sipAddressId), soci::use(static_cast(isAdmin)); + + return q->getLastInsertId(); + } + + void MainDbPrivate::insertChatRoomParticipantDevice (long long participantId, long long sipAddressId) { + soci::session *session = dbSession.getBackendSession(); + long long count; + *session << "SELECT COUNT(*) FROM chat_room_participant_device" + " WHERE chat_room_participant_id = :participantId" + " AND participant_device_sip_address_id = :sipAddressId", + soci::into(count), soci::use(participantId), soci::use(sipAddressId); + if (count) + return; + + lInfo() << "Insert new chat room participant device in database: `" << sipAddressId << "`."; + *session << "INSERT INTO chat_room_participant_device (chat_room_participant_id, participant_device_sip_address_id)" + " VALUES (:participantId, :sipAddressId)", + soci::use(participantId), soci::use(sipAddressId); } void MainDbPrivate::insertChatMessageParticipant (long long eventId, long long sipAddressId, int state) {