Add notification_id field to message database.

GitOrigin-RevId: 036e3fb02d7d18c04f568495ae50be9614717a0f
This commit is contained in:
levlam 2018-11-28 20:18:50 +03:00
parent 1b14cffb19
commit 07f4d0d94e
7 changed files with 68 additions and 47 deletions

View File

@ -7,6 +7,7 @@
#include "td/telegram/DialogId.h"
#include "td/telegram/MessageId.h"
#include "td/telegram/MessagesDb.h"
#include "td/telegram/NotificationId.h"
#include "td/telegram/UserId.h"
#include "td/actor/actor.h"
@ -57,7 +58,7 @@ class MessagesDbBench : public Benchmark {
// use async on same thread.
messages_db_async_->add_message({dialog_id, message_id}, unique_message_id, sender_user_id, random_id,
ttl_expires_at, 0, 0, "", std::move(data), Promise<>());
ttl_expires_at, 0, 0, "", NotificationId(), std::move(data), Promise<>());
}
}
}

View File

@ -23,7 +23,7 @@
namespace td {
// NB: must happen inside a transaction
Status init_dialog_db(SqliteDb &db, int32 version, bool &was_created) {
LOG(INFO) << "Init dialog db " << tag("version", version);
LOG(INFO) << "Init dialog database " << tag("version", version);
was_created = false;
// Check if database exists
@ -50,7 +50,7 @@ Status init_dialog_db(SqliteDb &db, int32 version, bool &was_created) {
};
if (version == 0) {
LOG(INFO) << "Create new dialog db";
LOG(INFO) << "Create new dialog database";
was_created = true;
TRY_STATUS(
db.exec("CREATE TABLE IF NOT EXISTS dialogs (dialog_id INT8 PRIMARY KEY, dialog_order INT8, data BLOB, "
@ -60,7 +60,7 @@ Status init_dialog_db(SqliteDb &db, int32 version, bool &was_created) {
TRY_STATUS(create_notification_group_id_index());
version = current_db_version();
}
if (version < static_cast<int32>(DbVersion::DialogDbLastNotificationDate)) {
if (version < static_cast<int32>(DbVersion::AddNotificationsSupport)) {
TRY_STATUS(db.exec("ALTER TABLE dialogs ADD COLUMN last_notification_date INT4"));
TRY_STATUS(db.exec("ALTER TABLE dialogs ADD COLUMN notification_group_id INT4"));
TRY_STATUS(create_last_notification_date_index());
@ -276,7 +276,8 @@ class DialogDbAsync : public DialogDbAsyncInterface {
send_closure_later(impl_, &Impl::get_dialogs_by_last_notification_date, last_notification_date, dialog_id, limit,
std::move(promise));
}
void get_dialog_by_notification_group_id(NotificationGroupId notification_group_id, Promise<BufferSlice> promise) override {
void get_dialog_by_notification_group_id(NotificationGroupId notification_group_id,
Promise<BufferSlice> promise) override {
send_closure_later(impl_, &Impl::get_dialog_by_notification_group_id, notification_group_id, std::move(promise));
}
void close(Promise<> promise) override {

View File

@ -40,7 +40,7 @@ static constexpr int32 MESSAGES_DB_INDEX_COUNT_OLD = 9;
// NB: must happen inside a transaction
Status init_messages_db(SqliteDb &db, int32 version) {
LOG(INFO) << "Init message db " << tag("version", version);
LOG(INFO) << "Init message database " << tag("version", version);
// Check if database exists
TRY_RESULT(has_table, db.has_table("messages"));
@ -92,18 +92,25 @@ Status init_messages_db(SqliteDb &db, int32 version) {
}
return Status::OK();
};
auto add_notification_id_index = [&db]() {
TRY_STATUS(
db.exec("CREATE INDEX IF NOT EXISTS message_by_notification_id ON messages (dialog_id, notification_id) "
"WHERE notification_id IS NOT NULL"));
return Status::OK();
};
if (version == 0) {
LOG(INFO) << "Create new messages db";
LOG(INFO) << "Create new message database";
TRY_STATUS(
db.exec("CREATE TABLE IF NOT EXISTS messages (dialog_id INT8, message_id INT8, "
"unique_message_id INT4, sender_user_id INT4, random_id INT8, data BLOB, "
"ttl_expires_at INT4, index_mask INT4, search_id INT8, text STRING, PRIMARY KEY "
"ttl_expires_at INT4, index_mask INT4, search_id INT8, text STRING, notification_id INT4, PRIMARY KEY "
"(dialog_id, message_id))"));
TRY_STATUS(
db.exec("CREATE INDEX IF NOT EXISTS message_by_random_id ON messages (dialog_id, random_id) "
"WHERE random_id IS NOT NULL"));
TRY_STATUS(
db.exec("CREATE INDEX IF NOT EXISTS message_by_unique_message_id ON messages "
"(unique_message_id) WHERE unique_message_id IS NOT NULL"));
@ -118,6 +125,8 @@ Status init_messages_db(SqliteDb &db, int32 version) {
TRY_STATUS(add_call_index());
TRY_STATUS(add_notification_id_index());
version = current_db_version();
}
if (version < static_cast<int32>(DbVersion::MessagesDbMediaIndex)) {
@ -135,12 +144,17 @@ Status init_messages_db(SqliteDb &db, int32 version) {
if (version < static_cast<int32>(DbVersion::MessagesCallIndex)) {
TRY_STATUS(add_call_index());
}
if (version < static_cast<int32>(DbVersion::AddNotificationsSupport)) {
TRY_STATUS(db.exec("ALTER TABLE messages ADD COLUMN notification_id INT4"));
TRY_STATUS(add_notification_id_index());
}
return Status::OK();
}
// NB: must happen inside a transaction
Status drop_messages_db(SqliteDb &db, int32 version) {
LOG(WARNING) << "Drop messages db " << tag("version", version) << tag("current_db_version", current_db_version());
LOG(WARNING) << "Drop message database " << tag("version", version)
<< tag("current_db_version", current_db_version());
return db.exec("DROP TABLE IF EXISTS messages");
}
@ -151,8 +165,9 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
}
Status init() {
TRY_RESULT(add_message_stmt,
db_.get_statement("INSERT OR REPLACE INTO messages VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)"));
TRY_RESULT(
add_message_stmt,
db_.get_statement("INSERT OR REPLACE INTO messages VALUES(?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11)"));
TRY_RESULT(delete_message_stmt, db_.get_statement("DELETE FROM messages WHERE dialog_id = ?1 AND message_id = ?2"));
TRY_RESULT(delete_all_dialog_messages_stmt,
db_.get_statement("DELETE FROM messages WHERE dialog_id = ?1 AND message_id <= ?2"));
@ -243,7 +258,7 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
Status add_message(FullMessageId full_message_id, ServerMessageId unique_message_id, UserId sender_user_id,
int64 random_id, int32 ttl_expires_at, int32 index_mask, int64 search_id, string text,
BufferSlice data) override {
NotificationId notification_id, BufferSlice data) override {
LOG(INFO) << "Add " << full_message_id << " to database";
auto dialog_id = full_message_id.get_dialog_id();
auto message_id = full_message_id.get_message_id();
@ -306,6 +321,11 @@ class MessagesDbImpl : public MessagesDbSyncInterface {
} else {
add_message_stmt_.bind_null(10).ensure();
}
if (notification_id.is_valid()) {
add_message_stmt_.bind_int32(11, notification_id.get()).ensure();
} else {
add_message_stmt_.bind_null(11).ensure();
}
add_message_stmt_.step().ensure();
@ -820,9 +840,10 @@ class MessagesDbAsync : public MessagesDbAsyncInterface {
void add_message(FullMessageId full_message_id, ServerMessageId unique_message_id, UserId sender_user_id,
int64 random_id, int32 ttl_expires_at, int32 index_mask, int64 search_id, string text,
BufferSlice data, Promise<> promise) override {
NotificationId notification_id, BufferSlice data, Promise<> promise) override {
send_closure_later(impl_, &Impl::add_message, full_message_id, unique_message_id, sender_user_id, random_id,
ttl_expires_at, index_mask, search_id, std::move(text), std::move(data), std::move(promise));
ttl_expires_at, index_mask, search_id, std::move(text), notification_id, std::move(data),
std::move(promise));
}
void delete_message(FullMessageId full_message_id, Promise<> promise) override {
@ -881,11 +902,11 @@ class MessagesDbAsync : public MessagesDbAsyncInterface {
}
void add_message(FullMessageId full_message_id, ServerMessageId unique_message_id, UserId sender_user_id,
int64 random_id, int32 ttl_expires_at, int32 index_mask, int64 search_id, string text,
BufferSlice data, Promise<> promise) {
NotificationId notification_id, BufferSlice data, Promise<> promise) {
add_write_query([=, promise = std::move(promise), data = std::move(data), text = std::move(text)](Unit) mutable {
promise.set_result(sync_db_->add_message(full_message_id, unique_message_id, sender_user_id, random_id,
ttl_expires_at, index_mask, search_id, std::move(text),
std::move(data)));
notification_id, std::move(data)));
});
}

View File

@ -8,6 +8,7 @@
#include "td/telegram/DialogId.h"
#include "td/telegram/MessageId.h"
#include "td/telegram/NotificationId.h"
#include "td/actor/PromiseFuture.h"
@ -91,7 +92,7 @@ class MessagesDbSyncInterface {
virtual Status add_message(FullMessageId full_message_id, ServerMessageId unique_message_id, UserId sender_user_id,
int64 random_id, int32 ttl_expires_at, int32 index_mask, int64 search_id, string text,
BufferSlice data) = 0;
NotificationId notification_id, BufferSlice data) = 0;
virtual Status delete_message(FullMessageId full_message_id) = 0;
virtual Status delete_all_dialog_messages(DialogId dialog_id, MessageId from_message_id) = 0;
@ -134,7 +135,7 @@ class MessagesDbAsyncInterface {
virtual void add_message(FullMessageId full_message_id, ServerMessageId unique_message_id, UserId sender_user_id,
int64 random_id, int32 ttl_expires_at, int32 index_mask, int64 search_id, string text,
BufferSlice data, Promise<> promise) = 0;
NotificationId notification_id, BufferSlice data, Promise<> promise) = 0;
virtual void delete_message(FullMessageId full_message_id, Promise<> promise) = 0;
virtual void delete_all_dialog_messages(DialogId dialog_id, MessageId from_message_id, Promise<> promise) = 0;

View File

@ -5054,7 +5054,7 @@ void MessagesManager::on_update_message_views(FullMessageId full_message_id, int
}
if (update_message_views(full_message_id.get_dialog_id(), m, views)) {
on_message_changed(d, m, "on_update_message_views");
on_message_changed(d, m, true, "on_update_message_views");
}
}
@ -7832,7 +7832,7 @@ void MessagesManager::read_all_dialog_mentions(DialogId dialog_id, Promise<Unit>
send_closure(G()->td(), &Td::send_update,
make_tl_object<td_api::updateMessageMentionRead>(dialog_id.get(), m->message_id.get(), 0));
is_update_sent = true;
on_message_changed(d, m, "read_all_mentions");
on_message_changed(d, m, true, "read_all_mentions");
}
if (d->unread_mention_count != 0) {
@ -7917,7 +7917,7 @@ bool MessagesManager::read_message_content(Dialog *d, Message *m, bool is_local_
update_opened_message_content(m->content.get()) | ttl_on_open(d, m, Time::now(), is_local_read);
if (is_mention_read || is_content_read) {
on_message_changed(d, m, "read_message_content");
on_message_changed(d, m, true, "read_message_content");
if (is_content_read) {
send_closure(G()->td(), &Td::send_update,
make_tl_object<td_api::updateMessageContentOpened>(d->dialog_id.get(), m->message_id.get()));
@ -8459,7 +8459,7 @@ void MessagesManager::ttl_on_view(const Dialog *d, Message *message, double view
!message->is_failed_to_send && !message->is_content_secret) {
message->ttl_expires_at = message->ttl + view_date;
ttl_register_message(d->dialog_id, message, now);
on_message_changed(d, message, "ttl_on_view");
on_message_changed(d, message, true, "ttl_on_view");
}
}
@ -8518,7 +8518,7 @@ void MessagesManager::ttl_loop(double now) {
auto m = get_message(d, full_message_id.get_message_id());
CHECK(m != nullptr);
on_message_ttl_expired(d, m);
on_message_changed(d, m, "ttl_loop");
on_message_changed(d, m, true, "ttl_loop");
}
}
for (auto &it : to_delete) {
@ -9915,7 +9915,7 @@ void MessagesManager::on_update_message_web_page(FullMessageId full_message_id,
set_message_content_web_page_id(content, WebPageId());
// don't need to send an update
on_message_changed(d, message, "on_update_message_web_page");
on_message_changed(d, message, true, "on_update_message_web_page");
return;
}
@ -11433,7 +11433,7 @@ Status MessagesManager::delete_dialog_reply_markup(DialogId dialog_id, MessageId
message->reply_markup->is_personal = false;
set_dialog_reply_markup(d, message_id);
on_message_changed(d, message, "delete_dialog_reply_markup");
on_message_changed(d, message, true, "delete_dialog_reply_markup");
}
} else {
// non-bots can't have messages with RemoveKeyboard
@ -12161,7 +12161,7 @@ Status MessagesManager::view_messages(DialogId dialog_id, const vector<MessageId
update_message_contains_unread_mention(d, message, false, "view_messages")) {
CHECK(message_id.is_server());
read_content_message_ids.push_back(message_id);
on_message_changed(d, message, "view_messages");
on_message_changed(d, message, true, "view_messages");
}
}
}
@ -17473,22 +17473,22 @@ int32 MessagesManager::get_dialog_pending_notification_count(Dialog *d) {
return d->server_unread_count + d->local_unread_count; // TODO remove/add some messages with unread mentions
}
void MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool force) {
bool MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool force) {
CHECK(d != nullptr);
CHECK(m != nullptr);
CHECK(!m->notification_id.is_valid());
if (m->is_outgoing || d->dialog_id == get_my_dialog_id() || td_->auth_manager_->is_bot()) {
return;
return false;
}
if (m->message_id.get() <= d->last_read_inbox_message_id.get()) {
VLOG(notifications) << "Disable notification for read " << m->message_id << " in " << d->dialog_id;
return;
return false;
}
if (d->dialog_id.get_type() == DialogType::Channel) {
if (!td_->contacts_manager_->get_channel_status(d->dialog_id.get_channel_id()).is_member() ||
m->date < td_->contacts_manager_->get_channel_date(d->dialog_id.get_channel_id())) {
return;
return false;
}
}
@ -17509,7 +17509,7 @@ void MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f
std::tie(have_settings, mute_until) = get_dialog_mute_until(settings_dialog_id, settings_dialog);
if (mute_until > G()->unix_time()) {
VLOG(notifications) << "Disable notification, because " << settings_dialog_id << " is muted";
return;
return false;
}
if (!force && (!have_settings || !d->pending_new_message_notifications.empty())) {
@ -17543,7 +17543,7 @@ void MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f
send_get_dialog_query(settings_dialog_id, std::move(promise));
}
}
return;
return false;
}
LOG_IF(WARNING, !have_settings) << "Have no notification settings for " << settings_dialog_id
@ -17555,6 +17555,7 @@ void MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f
send_closure_later(G()->notification_manager(), &NotificationManager::add_notification,
get_dialog_message_notification_group_id(d), d->dialog_id, m->date, settings_dialog_id,
m->disable_notification, m->notification_id, create_new_message_notification(m->message_id));
return true;
}
void MessagesManager::flush_pending_new_message_notifications(DialogId dialog_id, DialogId settings_dialog_id) {
@ -17575,7 +17576,9 @@ void MessagesManager::flush_pending_new_message_notifications(DialogId dialog_id
while (it != d->pending_new_message_notifications.end() && it->first == DialogId()) {
auto m = get_message(d, it->second);
if (m != nullptr) {
add_new_message_notification(d, m, true);
if (add_new_message_notification(d, m, true)) {
on_message_changed(d, m, false, "flush_pending_new_message_notifications");
}
}
++it;
}
@ -20521,10 +20524,10 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq
return result_message;
}
void MessagesManager::on_message_changed(const Dialog *d, const Message *m, const char *source) {
void MessagesManager::on_message_changed(const Dialog *d, const Message *m, bool need_send_update, const char *source) {
CHECK(d != nullptr);
CHECK(m != nullptr);
if (m->message_id == d->last_message_id) {
if (need_send_update && m->message_id == d->last_message_id) {
send_update_chat_last_message_impl(d, source);
}
@ -20585,7 +20588,8 @@ void MessagesManager::add_message_to_database(const Dialog *d, const Message *m,
}
G()->td_db()->get_messages_db_async()->add_message({d->dialog_id, message_id}, unique_message_id, m->sender_user_id,
random_id, ttl_expires_at, get_message_index_mask(d->dialog_id, m),
search_id, text, log_event_store(*m), Auto()); // TODO Promise
search_id, text, m->notification_id, log_event_store(*m),
Auto()); // TODO Promise
}
void MessagesManager::delete_all_dialog_messages_from_database(const Dialog *d, MessageId message_id,
@ -20994,14 +20998,7 @@ void MessagesManager::update_message(Dialog *d, unique_ptr<Message> &old_message
send_update_message_edited(dialog_id, old_message.get());
}
if (is_changed) {
on_message_changed(d, old_message.get(), "update_message");
} else {
// need to save message always, because it might be added to some message index
if (!message_id.is_yet_unsent()) {
add_message_to_database(d, old_message.get(), "update_message");
}
}
on_message_changed(d, old_message.get(), is_changed, "update_message");
}
bool MessagesManager::need_message_changed_warning(const Message *old_message) {

View File

@ -1430,7 +1430,7 @@ class MessagesManager : public Actor {
Message *add_message_to_dialog(Dialog *d, unique_ptr<Message> message, bool from_update, bool *need_update,
bool *need_update_dialog_pos, const char *source);
void on_message_changed(const Dialog *d, const Message *m, const char *source);
void on_message_changed(const Dialog *d, const Message *m, bool need_send_update, const char *source);
void add_message_to_database(const Dialog *d, const Message *m, const char *source);
@ -1465,7 +1465,7 @@ class MessagesManager : public Actor {
int32 get_dialog_pending_notification_count(Dialog *d);
void add_new_message_notification(Dialog *d, Message *m, bool force);
bool add_new_message_notification(Dialog *d, Message *m, bool force);
void flush_pending_new_message_notifications(DialogId dialog_id, DialogId settings_dialog_id);

View File

@ -36,7 +36,7 @@ enum class DbVersion : int32 {
MessagesDbFts,
MessagesCallIndex,
FixFileRemoteLocationKeyBug,
DialogDbLastNotificationDate,
AddNotificationsSupport,
Next
};