From 14f5ce9a29ce799f9bf715338fb647ff5ecdbe33 Mon Sep 17 00:00:00 2001 From: levlam Date: Sat, 12 Jan 2019 03:40:06 +0300 Subject: [PATCH] Delete reused notification groups from database and other fixes. GitOrigin-RevId: d07e452682df5d781bd0bb992ef572c0c3990540 --- td/telegram/DialogDb.cpp | 30 +++++++--- td/telegram/MessagesManager.cpp | 80 ++++++++++++++++---------- td/telegram/NotificationManager.cpp | 4 +- tdutils/td/utils/StackAllocator.cpp | 1 + tdutils/td/utils/port/thread_local.cpp | 2 + 5 files changed, 75 insertions(+), 42 deletions(-) diff --git a/td/telegram/DialogDb.cpp b/td/telegram/DialogDb.cpp index 3eb309f4f..a6036f99a 100644 --- a/td/telegram/DialogDb.cpp +++ b/td/telegram/DialogDb.cpp @@ -92,6 +92,8 @@ class DialogDbImpl : public DialogDbSyncInterface { TRY_RESULT(add_dialog_stmt, db_.get_statement("INSERT OR REPLACE INTO dialogs VALUES(?1, ?2, ?3)")); TRY_RESULT(add_notification_group_stmt, db_.get_statement("INSERT OR REPLACE INTO notification_groups VALUES(?1, ?2, ?3)")); + TRY_RESULT(delete_notification_group_stmt, + db_.get_statement("DELETE FROM notification_groups WHERE notification_group_id = ?1")); TRY_RESULT(get_dialog_stmt, db_.get_statement("SELECT data FROM dialogs WHERE dialog_id = ?1")); TRY_RESULT(get_dialogs_stmt, db_.get_statement("SELECT data, dialog_id, dialog_order FROM dialogs WHERE " "dialog_order < ?1 OR (dialog_order = ?1 AND dialog_id < ?2) ORDER " @@ -111,6 +113,7 @@ class DialogDbImpl : public DialogDbSyncInterface { add_dialog_stmt_ = std::move(add_dialog_stmt); add_notification_group_stmt_ = std::move(add_notification_group_stmt); + delete_notification_group_stmt_ = std::move(delete_notification_group_stmt); get_dialog_stmt_ = std::move(get_dialog_stmt); get_dialogs_stmt_ = std::move(get_dialogs_stmt); get_notification_groups_by_last_notification_date_stmt_ = @@ -138,17 +141,25 @@ class DialogDbImpl : public DialogDbSyncInterface { TRY_STATUS(add_dialog_stmt_.step()); for (auto &to_add : notification_groups) { - SCOPE_EXIT { - add_notification_group_stmt_.reset(); - }; - add_notification_group_stmt_.bind_int32(1, to_add.group_id.get()).ensure(); - add_notification_group_stmt_.bind_int64(2, to_add.dialog_id.get()).ensure(); - if (to_add.last_notification_date != 0) { - add_notification_group_stmt_.bind_int32(3, to_add.last_notification_date).ensure(); + if (to_add.dialog_id.is_valid()) { + SCOPE_EXIT { + add_notification_group_stmt_.reset(); + }; + add_notification_group_stmt_.bind_int32(1, to_add.group_id.get()).ensure(); + add_notification_group_stmt_.bind_int64(2, to_add.dialog_id.get()).ensure(); + if (to_add.last_notification_date != 0) { + add_notification_group_stmt_.bind_int32(3, to_add.last_notification_date).ensure(); + } else { + add_notification_group_stmt_.bind_null(3).ensure(); + } + TRY_STATUS(add_notification_group_stmt_.step()); } else { - add_notification_group_stmt_.bind_null(3).ensure(); + SCOPE_EXIT { + delete_notification_group_stmt_.reset(); + }; + delete_notification_group_stmt_.bind_int32(1, to_add.group_id.get()).ensure(); + TRY_STATUS(delete_notification_group_stmt_.step()); } - TRY_STATUS(add_notification_group_stmt_.step()); } return Status::OK(); } @@ -235,6 +246,7 @@ class DialogDbImpl : public DialogDbSyncInterface { SqliteStatement add_dialog_stmt_; SqliteStatement add_notification_group_stmt_; + SqliteStatement delete_notification_group_stmt_; SqliteStatement get_dialog_stmt_; SqliteStatement get_dialogs_stmt_; SqliteStatement get_notification_groups_by_last_notification_date_stmt_; diff --git a/td/telegram/MessagesManager.cpp b/td/telegram/MessagesManager.cpp index 3b1c1fcf3..6d5dc172a 100644 --- a/td/telegram/MessagesManager.cpp +++ b/td/telegram/MessagesManager.cpp @@ -3820,8 +3820,10 @@ void MessagesManager::Dialog::store(StorerT &storer) const { bool has_deleted_last_message = delete_last_message_date > 0; bool has_last_clear_history_message_id = last_clear_history_message_id.is_valid(); bool has_last_database_message_id = !has_last_database_message && last_database_message_id.is_valid(); - bool has_message_notification_group = message_notification_group.group_id.is_valid(); - bool has_mention_notification_group = mention_notification_group.group_id.is_valid(); + bool has_message_notification_group = + message_notification_group.group_id.is_valid() && !message_notification_group.try_reuse; + bool has_mention_notification_group = + mention_notification_group.group_id.is_valid() && !mention_notification_group.try_reuse; bool has_new_secret_chat_notification_id = new_secret_chat_notification_id.is_valid(); bool has_pinned_message_notification = pinned_message_notification_message_id.is_valid(); BEGIN_STORE_FLAGS(); @@ -4308,16 +4310,15 @@ void MessagesManager::save_dialog_to_database(DialogId dialog_id) { CHECK(d != nullptr); LOG(INFO) << "Save " << dialog_id << " to database"; vector changed_group_keys; - if (d->message_notification_group.is_changed) { - changed_group_keys.emplace_back(d->message_notification_group.group_id, dialog_id, - d->message_notification_group.last_notification_date); - d->message_notification_group.is_changed = false; - } - if (d->mention_notification_group.is_changed) { - changed_group_keys.emplace_back(d->mention_notification_group.group_id, dialog_id, - d->mention_notification_group.last_notification_date); - d->mention_notification_group.is_changed = false; - } + auto add_group_key = [&](auto &group_info) { + if (group_info.is_changed) { + changed_group_keys.emplace_back(group_info.group_id, group_info.try_reuse ? DialogId() : dialog_id, + group_info.last_notification_date); + group_info.is_changed = false; + } + }; + add_group_key(d->message_notification_group); + add_group_key(d->mention_notification_group); G()->td_db()->get_dialog_db_async()->add_dialog( dialog_id, d->order, get_dialog_database_value(d), std::move(changed_group_keys), PromiseCreator::lambda([dialog_id](Result<> result) { @@ -5749,8 +5750,8 @@ bool MessagesManager::update_dialog_notification_settings(DialogId dialog_id, new_settings.use_default_mute_until, new_settings.mute_until); on_dialog_updated(dialog_id, "update_dialog_notification_settings"); - LOG(INFO) << "Update notification settings in " << dialog_id << " from " << *current_settings << " to " - << new_settings; + VLOG(notifications) << "Update notification settings in " << dialog_id << " from " << *current_settings << " to " + << new_settings; *current_settings = new_settings; if (!was_muted && is_dialog_muted(d)) { @@ -5823,7 +5824,8 @@ bool MessagesManager::update_scope_notification_settings(NotificationSettingsSco } } - LOG(INFO) << "Update notification settings in " << scope << " from " << *current_settings << " to " << new_settings; + VLOG(notifications) << "Update notification settings in " << scope << " from " << *current_settings << " to " + << new_settings; *current_settings = new_settings; send_closure(G()->td(), &Td::send_update, get_update_scope_notification_settings_object(scope)); @@ -5991,7 +5993,7 @@ void MessagesManager::on_update_dialog_notify_settings( return; } - LOG(INFO) << "Receive notification settings for " << dialog_id << ": " << to_string(peer_notify_settings); + VLOG(notifications) << "Receive notification settings for " << dialog_id << ": " << to_string(peer_notify_settings); DialogNotificationSettings *current_settings = get_dialog_notification_settings(dialog_id, true); if (current_settings == nullptr) { @@ -10674,6 +10676,8 @@ void MessagesManager::remove_new_secret_chat_notification(Dialog *d, bool is_per void MessagesManager::fix_dialog_last_notification_id(Dialog *d, bool from_mentions, MessageId message_id) { MessagesConstIterator it(d, message_id); auto &group_info = from_mentions ? d->mention_notification_group : d->message_notification_group; + VLOG(notifications) << "Trying to fix last notification id in " << group_info.group_id << " from " << d->dialog_id + << " from " << message_id << "/" << group_info.last_notification_id; if (*it != nullptr && ((*it)->message_id == message_id || (*it)->have_next)) { while (*it != nullptr) { const Message *m = *it; @@ -17861,7 +17865,6 @@ MessagesManager::MessageNotificationGroup MessagesManager::get_message_notificat << d->new_secret_chat_notification_id << " and " << d->server_unread_count + d->local_unread_count << " unread messages"; result.dialog_id = d->dialog_id; - result.type = from_mentions ? NotificationGroupType::Mentions : NotificationGroupType::Messages; result.total_count = get_dialog_pending_notification_count(d, from_mentions); result.total_count -= static_cast(from_mentions ? d->pending_new_mention_notifications.size() : d->pending_new_message_notifications.size()); @@ -17871,10 +17874,12 @@ MessagesManager::MessageNotificationGroup MessagesManager::get_message_notificat } if (d->new_secret_chat_notification_id.is_valid()) { CHECK(d->dialog_id.get_type() == DialogType::SecretChat); + result.type = NotificationGroupType::SecretChat; result.notifications.emplace_back(d->new_secret_chat_notification_id, td_->contacts_manager_->get_secret_chat_date(d->dialog_id.get_secret_chat_id()), create_new_secret_chat_notification()); } else { + result.type = from_mentions ? NotificationGroupType::Mentions : NotificationGroupType::Messages; result.notifications = get_message_notifications_from_database_force( d, from_mentions, static_cast(td_->notification_manager_->get_max_notification_group_size())); } @@ -18091,6 +18096,9 @@ void MessagesManager::get_message_notifications_from_database(DialogId dialog_id if (d->message_notification_group.group_id != group_id && d->mention_notification_group.group_id != group_id) { return promise.set_value(vector()); } + + VLOG(notifications) << "Get " << limit << " message notifications from database in " << group_id << " from " + << dialog_id << " from " << from_notification_id << "/" << from_message_id; bool from_mentions = d->mention_notification_group.group_id == group_id; if (d->new_secret_chat_notification_id.is_valid()) { CHECK(d->dialog_id.get_type() == DialogType::SecretChat); @@ -22249,28 +22257,38 @@ void MessagesManager::force_create_dialog(DialogId dialog_id, const char *source if (dialog_id.get_type() == DialogType::SecretChat) { // secret chat is being created // let's copy notification settings from main chat if available + VLOG(notifications) << "Create new secret " << dialog_id << " from " << source; auto secret_chat_id = dialog_id.get_secret_chat_id(); - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(secret_chat_id); - Dialog *user_d = get_dialog_force(DialogId(user_id)); - if (user_d != nullptr && user_d->notification_settings.is_synchronized) { - LOG(INFO) << "Copy notification settings from " << user_d->dialog_id << " to " << dialog_id; - update_dialog_notification_settings(dialog_id, &d->notification_settings, user_d->notification_settings); + if (!d->notification_settings.is_synchronized) { + auto user_id = td_->contacts_manager_->get_secret_chat_user_id(secret_chat_id); + Dialog *user_d = get_dialog_force(DialogId(user_id)); + if (user_d != nullptr && user_d->notification_settings.is_synchronized) { + VLOG(notifications) << "Copy notification settings from " << user_d->dialog_id << " to " << dialog_id; + update_dialog_notification_settings(dialog_id, &d->notification_settings, user_d->notification_settings); + } + } else { + LOG(ERROR) << "Found previously created secret " << d->dialog_id << ", when creating it from " << source; } if (G()->parameters().use_message_db && !td_->auth_manager_->is_bot() && !td_->contacts_manager_->get_secret_chat_is_outbound(secret_chat_id)) { auto notification_group_id = get_dialog_notification_group_id(dialog_id, d->message_notification_group); if (notification_group_id.is_valid()) { - d->new_secret_chat_notification_id = get_next_notification_id(d, notification_group_id, MessageId()); if (d->new_secret_chat_notification_id.is_valid()) { - auto date = td_->contacts_manager_->get_secret_chat_date(secret_chat_id); - bool is_changed = set_dialog_last_notification(dialog_id, d->message_notification_group, date, - d->new_secret_chat_notification_id, "add_new_secret_chat"); - CHECK(is_changed); - VLOG(notifications) << "Create " << d->new_secret_chat_notification_id << " with " << secret_chat_id; - send_closure_later(G()->notification_manager(), &NotificationManager::add_notification, - notification_group_id, NotificationGroupType::SecretChat, dialog_id, date, dialog_id, - false, 0, d->new_secret_chat_notification_id, create_new_secret_chat_notification()); + LOG(ERROR) << "Found previously created " << d->new_secret_chat_notification_id << " in " << d->dialog_id + << ", when creating it from " << source; + } else { + d->new_secret_chat_notification_id = get_next_notification_id(d, notification_group_id, MessageId()); + if (d->new_secret_chat_notification_id.is_valid()) { + auto date = td_->contacts_manager_->get_secret_chat_date(secret_chat_id); + bool is_changed = set_dialog_last_notification(dialog_id, d->message_notification_group, date, + d->new_secret_chat_notification_id, "add_new_secret_chat"); + CHECK(is_changed); + VLOG(notifications) << "Create " << d->new_secret_chat_notification_id << " with " << secret_chat_id; + send_closure_later(G()->notification_manager(), &NotificationManager::add_notification, + notification_group_id, NotificationGroupType::SecretChat, dialog_id, date, dialog_id, + false, 0, d->new_secret_chat_notification_id, create_new_secret_chat_notification()); + } } } } diff --git a/td/telegram/NotificationManager.cpp b/td/telegram/NotificationManager.cpp index a3fafffaf..f261a4252 100644 --- a/td/telegram/NotificationManager.cpp +++ b/td/telegram/NotificationManager.cpp @@ -255,8 +255,8 @@ NotificationManager::NotificationGroups::iterator NotificationManager::get_group group.total_count = message_group.total_count; group.notifications = std::move(message_group.notifications); - VLOG(notifications) << "Finish to load " << group_id << " with total_count " << message_group.total_count - << " and notifications " << group.notifications; + VLOG(notifications) << "Finish to load " << group_id << " of type " << message_group.type << " with total_count " + << message_group.total_count << " and notifications " << group.notifications; if (send_update && group_key.last_notification_date != 0) { auto last_group_key = get_last_updated_group_key(); diff --git a/tdutils/td/utils/StackAllocator.cpp b/tdutils/td/utils/StackAllocator.cpp index 5d8c58dea..0b01b487b 100644 --- a/tdutils/td/utils/StackAllocator.cpp +++ b/tdutils/td/utils/StackAllocator.cpp @@ -15,4 +15,5 @@ StackAllocator::Impl &StackAllocator::impl() { init_thread_local(impl); return *impl; } + } // namespace td diff --git a/tdutils/td/utils/port/thread_local.cpp b/tdutils/td/utils/port/thread_local.cpp index a92df2ca1..57738f2f8 100644 --- a/tdutils/td/utils/port/thread_local.cpp +++ b/tdutils/td/utils/port/thread_local.cpp @@ -31,6 +31,7 @@ void clear_thread_locals() { delete to_delete; CHECK(detail::thread_local_destructors == nullptr); } + void set_thread_id(int32 id) { detail::thread_id_ = id; } @@ -38,4 +39,5 @@ void set_thread_id(int32 id) { int32 get_thread_id() { return detail::thread_id_; } + } // namespace td