From 8390768a27d191c912584733896129a69146b45d Mon Sep 17 00:00:00 2001
From: Julien Wadel <julien.wadel@belledonne-communications.com>
Date: Mon, 3 Jul 2023 10:27:17 +0200
Subject: [PATCH] Load unread message count while requesting chat rooms list.

---
 src/db/main-db.cpp | 43 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 35 insertions(+), 8 deletions(-)

diff --git a/src/db/main-db.cpp b/src/db/main-db.cpp
index cc49feb3dd..234bc03a91 100644
--- a/src/db/main-db.cpp
+++ b/src/db/main-db.cpp
@@ -4579,13 +4579,18 @@ void MainDb::disableDisplayNotificationRequired(const std::shared_ptr<const Even
 list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms() const {
 #ifdef HAVE_DB_STORAGE
 	static const string query =
-	    "SELECT chat_room.id, peer_sip_address.value, local_sip_address.value,"
-	    " creation_time, last_update_time, capabilities, subject, last_notify_id, flags, last_message_id,"
-	    " ephemeral_enabled, ephemeral_messages_lifetime"
-	    " FROM chat_room, sip_address AS peer_sip_address, sip_address AS local_sip_address"
-	    " WHERE chat_room.peer_sip_address_id = peer_sip_address.id AND chat_room.local_sip_address_id = "
-	    "local_sip_address.id"
-	    " ORDER BY last_update_time DESC";
+		"SELECT chat_room.id, peer_sip_address.value, local_sip_address.value,"
+		" creation_time, last_update_time, capabilities, subject, last_notify_id, flags, last_message_id,"
+		" ephemeral_enabled, ephemeral_messages_lifetime,"
+		" unread_messages_count.message_count"
+		" FROM chat_room, sip_address AS peer_sip_address, sip_address AS local_sip_address"
+		" LEFT JOIN (SELECT conference_event.chat_room_id, count(*) as message_count"
+		" FROM conference_chat_message_event, conference_event"
+		" WHERE conference_chat_message_event.event_id=conference_event.event_id AND conference_chat_message_event.marked_as_read==0"
+		" GROUP BY conference_event.chat_room_id) AS unread_messages_count"
+		" ON unread_messages_count.chat_room_id = chat_room.id"
+		" WHERE chat_room.peer_sip_address_id = peer_sip_address.id AND chat_room.local_sip_address_id = local_sip_address.id"
+		" ORDER BY last_update_time DESC";
 
 	DurationLogger durationLogger("Get chat rooms.");
 
@@ -4599,8 +4604,24 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms() const {
 		soci::session *session = d->dbSession.getBackendSession();
 
 		soci::rowset<soci::row> rows = (session->prepare << query);
+// SOCI use a hack for sqlite3:
+// "sqlite3 type system does not have a date or time field.  Also it does not reliably id other data types.
+// It has a tendency to see everything as text.
+// sqlite3_column_decltype returns the text that is used in the create table statement"
+// The data type on the count can be a string (as of SOCI 4.0.0) but as it is a "hack", we have to work with both types (integer and string)
+		soci::data_type unreadMessageCountType;
+		bool typeHasBeenSet = false;
+		d->unreadChatMessageCountCache.clear();
+
 		for (const auto &row : rows) {
-			ConferenceId conferenceId(Address(row.get<string>(1), true), Address(row.get<string>(2), true));
+			if(!typeHasBeenSet) {
+				unreadMessageCountType = row.get_properties(12).get_data_type();
+				typeHasBeenSet = true;
+			}
+			ConferenceId conferenceId = ConferenceId(
+				ConferenceAddress(row.get<string>(1)),
+				ConferenceAddress(row.get<string>(2))
+			);
 
 			shared_ptr<AbstractChatRoom> chatRoom = core->findChatRoom(conferenceId, false);
 			if (chatRoom) {
@@ -4610,6 +4631,12 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms() const {
 
 			const long long &dbChatRoomId = d->dbSession.resolveId(row, 0);
 			d->cache(conferenceId, dbChatRoomId);
+			int unreadMessagesCount = 0;
+			if(unreadMessageCountType == soci::dt_string)
+				unreadMessagesCount = std::stoi(row.get<string>(12,"0"));
+			else
+				unreadMessagesCount = row.get<int>(12,0);
+			d->unreadChatMessageCountCache.insert(conferenceId,unreadMessagesCount);
 
 			time_t creationTime = d->dbSession.getTime(row, 3);
 			time_t lastUpdateTime = d->dbSession.getTime(row, 4);
-- 
GitLab