Store *Full to database.

GitOrigin-RevId: 160369861878befa880e2b4355fd6585977f84dc
This commit is contained in:
levlam 2019-09-18 02:14:24 +03:00
parent 1d850cb14f
commit 3377c38073
5 changed files with 389 additions and 12 deletions

View File

@ -19,6 +19,7 @@
#include "td/telegram/Global.h" #include "td/telegram/Global.h"
#include "td/telegram/InlineQueriesManager.h" #include "td/telegram/InlineQueriesManager.h"
#include "td/telegram/logevent/LogEvent.h" #include "td/telegram/logevent/LogEvent.h"
#include "td/telegram/logevent/LogEventHelper.h"
#include "td/telegram/MessagesManager.h" #include "td/telegram/MessagesManager.h"
#include "td/telegram/misc.h" #include "td/telegram/misc.h"
#include "td/telegram/net/NetQuery.h" #include "td/telegram/net/NetQuery.h"
@ -27,6 +28,7 @@
#include "td/telegram/Photo.hpp" #include "td/telegram/Photo.hpp"
#include "td/telegram/SecretChatActor.h" #include "td/telegram/SecretChatActor.h"
#include "td/telegram/StickersManager.h" #include "td/telegram/StickersManager.h"
#include "td/telegram/StickersManager.hpp"
#include "td/telegram/Td.h" #include "td/telegram/Td.h"
#include "td/telegram/TdDb.h" #include "td/telegram/TdDb.h"
#include "td/telegram/TopDialogManager.h" #include "td/telegram/TopDialogManager.h"
@ -2493,6 +2495,42 @@ void ContactsManager::parse_link_state(LinkState &link_state, ParserT &parser) {
link_state = static_cast<LinkState>(static_cast<uint8>(link_state_uint32)); link_state = static_cast<LinkState>(static_cast<uint8>(link_state_uint32));
} }
template <class StorerT>
void ContactsManager::BotInfo::store(StorerT &storer) const {
using td::store;
bool has_description = !description.empty();
bool has_commands = !commands.empty();
BEGIN_STORE_FLAGS();
STORE_FLAG(has_description);
STORE_FLAG(has_commands);
END_STORE_FLAGS();
store(version, storer);
if (has_description) {
store(description, storer);
}
if (has_commands) {
store(commands, storer);
}
}
template <class ParserT>
void ContactsManager::BotInfo::parse(ParserT &parser) {
using td::parse;
bool has_description;
bool has_commands;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(has_description);
PARSE_FLAG(has_commands);
END_PARSE_FLAGS();
parse(version, parser);
if (has_description) {
parse(description, parser);
}
if (has_commands) {
parse(commands, parser);
}
}
template <class StorerT> template <class StorerT>
void ContactsManager::User::store(StorerT &storer) const { void ContactsManager::User::store(StorerT &storer) const {
using td::store; using td::store;
@ -2627,6 +2665,53 @@ void ContactsManager::User::parse(ParserT &parser) {
} }
} }
template <class StorerT>
void ContactsManager::UserFull::store(StorerT &storer) const {
using td::store;
CHECK(is_inited);
bool has_bot_info = bot_info != nullptr;
bool has_about = !about.empty();
BEGIN_STORE_FLAGS();
STORE_FLAG(has_bot_info);
STORE_FLAG(has_about);
STORE_FLAG(is_blocked);
STORE_FLAG(can_be_called);
STORE_FLAG(has_private_calls);
END_STORE_FLAGS();
if (has_bot_info) {
store(*bot_info, storer);
}
if (has_about) {
store(about, storer);
}
store(common_chat_count, storer);
store_time(expires_at, storer);
}
template <class ParserT>
void ContactsManager::UserFull::parse(ParserT &parser) {
using td::parse;
is_inited = true;
bool has_bot_info;
bool has_about;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(has_bot_info);
PARSE_FLAG(has_about);
PARSE_FLAG(is_blocked);
PARSE_FLAG(can_be_called);
PARSE_FLAG(has_private_calls);
END_PARSE_FLAGS();
if (has_bot_info) {
bot_info = make_unique<BotInfo>();
parse(*bot_info, parser);
}
if (has_about) {
parse(about, parser);
}
parse(common_chat_count, parser);
parse_time(expires_at, parser);
}
template <class StorerT> template <class StorerT>
void ContactsManager::Chat::store(StorerT &storer) const { void ContactsManager::Chat::store(StorerT &storer) const {
using td::store; using td::store;
@ -2741,6 +2826,46 @@ void ContactsManager::Chat::parse(ParserT &parser) {
} }
} }
template <class StorerT>
void ContactsManager::ChatFull::store(StorerT &storer) const {
using td::store;
bool has_description = !description.empty();
bool has_invite_link = !invite_link.empty();
BEGIN_STORE_FLAGS();
STORE_FLAG(has_description);
STORE_FLAG(has_invite_link);
END_STORE_FLAGS();
store(version, storer);
store(creator_user_id, storer);
store(participants, storer);
if (has_description) {
store(description, storer);
}
if (has_invite_link) {
store(invite_link, storer);
}
}
template <class ParserT>
void ContactsManager::ChatFull::parse(ParserT &parser) {
using td::parse;
bool has_description;
bool has_invite_link;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(has_description);
PARSE_FLAG(has_invite_link);
END_PARSE_FLAGS();
parse(version, parser);
parse(creator_user_id, parser);
parse(participants, parser);
if (has_description) {
parse(description, parser);
}
if (has_invite_link) {
parse(invite_link, parser);
}
}
template <class StorerT> template <class StorerT>
void ContactsManager::Channel::store(StorerT &storer) const { void ContactsManager::Channel::store(StorerT &storer) const {
using td::store; using td::store;
@ -2876,6 +3001,124 @@ void ContactsManager::Channel::parse(ParserT &parser) {
} }
} }
template <class StorerT>
void ContactsManager::ChannelFull::store(StorerT &storer) const {
using td::store;
bool has_description = !description.empty();
bool has_administrator_count = administrator_count != 0;
bool has_restricted_count = restricted_count != 0;
bool has_banned_count = banned_count != 0;
bool has_invite_link = !invite_link.empty();
bool has_sticker_set = sticker_set_id != 0;
bool has_linked_channel_id = linked_channel_id.is_valid();
bool has_migrated_from_max_message_id = migrated_from_max_message_id.is_valid();
bool has_migrated_from_chat_id = migrated_from_chat_id.is_valid();
BEGIN_STORE_FLAGS();
STORE_FLAG(has_description);
STORE_FLAG(has_administrator_count);
STORE_FLAG(has_restricted_count);
STORE_FLAG(has_banned_count);
STORE_FLAG(has_invite_link);
STORE_FLAG(has_sticker_set);
STORE_FLAG(has_linked_channel_id);
STORE_FLAG(has_migrated_from_max_message_id);
STORE_FLAG(has_migrated_from_chat_id);
STORE_FLAG(can_get_participants);
STORE_FLAG(can_set_username);
STORE_FLAG(can_set_sticker_set);
STORE_FLAG(can_view_statistics);
STORE_FLAG(is_all_history_available);
END_STORE_FLAGS();
if (has_description) {
store(description, storer);
}
store(participant_count, storer);
if (has_administrator_count) {
store(administrator_count, storer);
}
if (has_restricted_count) {
store(restricted_count, storer);
}
if (has_banned_count) {
store(banned_count, storer);
}
if (has_invite_link) {
store(invite_link, storer);
}
if (has_sticker_set) {
storer.context()->td().get_actor_unsafe()->stickers_manager_->store_sticker_set_id(sticker_set_id, storer);
}
if (has_linked_channel_id) {
store(linked_channel_id, storer);
}
if (has_migrated_from_max_message_id) {
store(migrated_from_max_message_id, storer);
}
if (has_migrated_from_chat_id) {
store(migrated_from_chat_id, storer);
}
store_time(expires_at, storer);
}
template <class ParserT>
void ContactsManager::ChannelFull::parse(ParserT &parser) {
using td::parse;
bool has_description;
bool has_administrator_count;
bool has_restricted_count;
bool has_banned_count;
bool has_invite_link;
bool has_sticker_set;
bool has_linked_channel_id;
bool has_migrated_from_max_message_id;
bool has_migrated_from_chat_id;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(has_description);
PARSE_FLAG(has_administrator_count);
PARSE_FLAG(has_restricted_count);
PARSE_FLAG(has_banned_count);
PARSE_FLAG(has_invite_link);
PARSE_FLAG(has_sticker_set);
PARSE_FLAG(has_linked_channel_id);
PARSE_FLAG(has_migrated_from_max_message_id);
PARSE_FLAG(has_migrated_from_chat_id);
PARSE_FLAG(can_get_participants);
PARSE_FLAG(can_set_username);
PARSE_FLAG(can_set_sticker_set);
PARSE_FLAG(can_view_statistics);
PARSE_FLAG(is_all_history_available);
END_PARSE_FLAGS();
if (has_description) {
parse(description, parser);
}
parse(participant_count, parser);
if (has_administrator_count) {
parse(administrator_count, parser);
}
if (has_restricted_count) {
parse(restricted_count, parser);
}
if (has_banned_count) {
parse(banned_count, parser);
}
if (has_invite_link) {
parse(invite_link, parser);
}
if (has_sticker_set) {
parser.context()->td().get_actor_unsafe()->stickers_manager_->parse_sticker_set_id(sticker_set_id, parser);
}
if (has_linked_channel_id) {
parse(linked_channel_id, parser);
}
if (has_migrated_from_max_message_id) {
parse(migrated_from_max_message_id, parser);
}
if (has_migrated_from_chat_id) {
parse(migrated_from_chat_id, parser);
}
parse_time(expires_at, parser);
}
template <class StorerT> template <class StorerT>
void ContactsManager::SecretChat::store(StorerT &storer) const { void ContactsManager::SecretChat::store(StorerT &storer) const {
using td::store; using td::store;
@ -6448,6 +6691,63 @@ ContactsManager::SecretChat *ContactsManager::get_secret_chat_force(SecretChatId
return get_secret_chat(secret_chat_id); return get_secret_chat(secret_chat_id);
} }
void ContactsManager::save_user_full(UserFull *user_full, UserId user_id) {
if (!G()->parameters().use_chat_info_db) {
return;
}
LOG(INFO) << "Trying to save to database full " << user_id;
CHECK(user_full != nullptr);
G()->td_db()->get_sqlite_pmc()->set(get_user_full_database_key(user_id), get_user_full_database_value(user_full),
Auto());
}
string ContactsManager::get_user_full_database_key(UserId user_id) {
return PSTRING() << "usf" << user_id.get();
}
string ContactsManager::get_user_full_database_value(const UserFull *user_full) {
return log_event_store(*user_full).as_slice().str();
}
void ContactsManager::save_chat_full(ChatFull *chat_full, ChatId chat_id) {
if (!G()->parameters().use_chat_info_db) {
return;
}
LOG(INFO) << "Trying to save to database full " << chat_id;
CHECK(chat_full != nullptr);
G()->td_db()->get_sqlite_pmc()->set(get_chat_full_database_key(chat_id), get_chat_full_database_value(chat_full),
Auto());
}
string ContactsManager::get_chat_full_database_key(ChatId chat_id) {
return PSTRING() << "grf" << chat_id.get();
}
string ContactsManager::get_chat_full_database_value(const ChatFull *chat_full) {
return log_event_store(*chat_full).as_slice().str();
}
void ContactsManager::save_channel_full(ChannelFull *channel_full, ChannelId channel_id) {
if (!G()->parameters().use_chat_info_db) {
return;
}
LOG(INFO) << "Trying to save to database full " << channel_id;
CHECK(channel_full != nullptr);
G()->td_db()->get_sqlite_pmc()->set(get_channel_full_database_key(channel_id),
get_channel_full_database_value(channel_full), Auto());
}
string ContactsManager::get_channel_full_database_key(ChannelId channel_id) {
return PSTRING() << "chf" << channel_id.get();
}
string ContactsManager::get_channel_full_database_value(const ChannelFull *channel_full) {
return log_event_store(*channel_full).as_slice().str();
}
void ContactsManager::update_user(User *u, UserId user_id, bool from_binlog, bool from_database) { void ContactsManager::update_user(User *u, UserId user_id, bool from_binlog, bool from_database) {
CHECK(u != nullptr); CHECK(u != nullptr);
if (u->is_name_changed || u->is_username_changed || u->is_outbound_link_changed) { if (u->is_name_changed || u->is_username_changed || u->is_outbound_link_changed) {
@ -6738,7 +7038,7 @@ void ContactsManager::update_secret_chat(SecretChat *c, SecretChatId secret_chat
} }
} }
void ContactsManager::update_user_full(UserFull *user_full, UserId user_id) { void ContactsManager::update_user_full(UserFull *user_full, UserId user_id, bool from_database) {
CHECK(user_full != nullptr); CHECK(user_full != nullptr);
if (user_full->is_common_chat_count_changed) { if (user_full->is_common_chat_count_changed) {
td_->messages_manager_->drop_common_dialogs_cache(user_id); td_->messages_manager_->drop_common_dialogs_cache(user_id);
@ -6750,11 +7050,15 @@ void ContactsManager::update_user_full(UserFull *user_full, UserId user_id) {
send_closure(G()->td(), &Td::send_update, send_closure(G()->td(), &Td::send_update,
make_tl_object<td_api::updateUserFullInfo>(get_user_id_object(user_id, "updateUserFullInfo"), make_tl_object<td_api::updateUserFullInfo>(get_user_id_object(user_id, "updateUserFullInfo"),
get_user_full_info_object(user_id, user_full))); get_user_full_info_object(user_id, user_full)));
if (!from_database) {
save_user_full(user_full, user_id);
}
} }
} }
} }
void ContactsManager::update_chat_full(ChatFull *chat_full, ChatId chat_id) { void ContactsManager::update_chat_full(ChatFull *chat_full, ChatId chat_id, bool from_database) {
CHECK(chat_full != nullptr); CHECK(chat_full != nullptr);
if (chat_full->is_changed) { if (chat_full->is_changed) {
vector<UserId> administrator_user_ids; vector<UserId> administrator_user_ids;
@ -6776,10 +7080,14 @@ void ContactsManager::update_chat_full(ChatFull *chat_full, ChatId chat_id) {
G()->td(), &Td::send_update, G()->td(), &Td::send_update,
make_tl_object<td_api::updateBasicGroupFullInfo>(get_basic_group_id_object(chat_id, "update_chat_full"), make_tl_object<td_api::updateBasicGroupFullInfo>(get_basic_group_id_object(chat_id, "update_chat_full"),
get_basic_group_full_info_object(chat_full))); get_basic_group_full_info_object(chat_full)));
if (!from_database) {
save_chat_full(chat_full, chat_id);
}
} }
} }
void ContactsManager::update_channel_full(ChannelFull *channel_full, ChannelId channel_id) { void ContactsManager::update_channel_full(ChannelFull *channel_full, ChannelId channel_id, bool from_database) {
CHECK(channel_full != nullptr); CHECK(channel_full != nullptr);
if (channel_full->is_changed) { if (channel_full->is_changed) {
if (channel_full->linked_channel_id.is_valid()) { if (channel_full->linked_channel_id.is_valid()) {
@ -6793,6 +7101,10 @@ void ContactsManager::update_channel_full(ChannelFull *channel_full, ChannelId c
G()->td(), &Td::send_update, G()->td(), &Td::send_update,
make_tl_object<td_api::updateSupergroupFullInfo>(get_supergroup_id_object(channel_id, "update_channel_full"), make_tl_object<td_api::updateSupergroupFullInfo>(get_supergroup_id_object(channel_id, "update_channel_full"),
get_supergroup_full_info_object(channel_full))); get_supergroup_full_info_object(channel_full)));
if (!from_database) {
save_channel_full(channel_full, channel_id);
}
} }
} }

View File

@ -550,9 +550,16 @@ class ContactsManager : public Actor {
string description; string description;
vector<std::pair<string, string>> commands; vector<std::pair<string, string>> commands;
BotInfo() = default;
BotInfo(int32 version, string description, vector<std::pair<string, string>> &&commands) BotInfo(int32 version, string description, vector<std::pair<string, string>> &&commands)
: version(version), description(std::move(description)), commands(std::move(commands)) { : version(version), description(std::move(description)), commands(std::move(commands)) {
} }
template <class StorerT>
void store(StorerT &storer) const;
template <class ParserT>
void parse(ParserT &parser);
}; };
// do not forget to update invalidate_user_full and on_get_user_full // do not forget to update invalidate_user_full and on_get_user_full
@ -581,6 +588,12 @@ class ContactsManager : public Actor {
bool is_bot_info_expired(int32 bot_info_version) const; bool is_bot_info_expired(int32 bot_info_version) const;
bool is_expired() const; bool is_expired() const;
template <class StorerT>
void store(StorerT &storer) const;
template <class ParserT>
void parse(ParserT &parser);
}; };
struct Chat { struct Chat {
@ -632,6 +645,12 @@ class ContactsManager : public Actor {
string invite_link; string invite_link;
bool is_changed = true; bool is_changed = true;
template <class StorerT>
void store(StorerT &storer) const;
template <class ParserT>
void parse(ParserT &parser);
}; };
struct Channel { struct Channel {
@ -704,6 +723,12 @@ class ContactsManager : public Actor {
double expires_at = 0.0; double expires_at = 0.0;
bool is_expired() const; bool is_expired() const;
template <class StorerT>
void store(StorerT &storer) const;
template <class ParserT>
void parse(ParserT &parser);
}; };
struct SecretChat { struct SecretChat {
@ -1020,15 +1045,27 @@ class ContactsManager : public Actor {
void load_secret_chat_from_database_impl(SecretChatId secret_chat_id, Promise<Unit> promise); void load_secret_chat_from_database_impl(SecretChatId secret_chat_id, Promise<Unit> promise);
void on_load_secret_chat_from_database(SecretChatId secret_chat_id, string value); void on_load_secret_chat_from_database(SecretChatId secret_chat_id, string value);
void save_user_full(UserFull *user_full, UserId user_id);
static string get_user_full_database_key(UserId user_id);
static string get_user_full_database_value(const UserFull *user_full);
void save_chat_full(ChatFull *chat_full, ChatId chat_id);
static string get_chat_full_database_key(ChatId chat_id);
static string get_chat_full_database_value(const ChatFull *chat_full);
void save_channel_full(ChannelFull *channel_full, ChannelId channel_id);
static string get_channel_full_database_key(ChannelId channel_id);
static string get_channel_full_database_value(const ChannelFull *channel_full);
void update_user(User *u, UserId user_id, bool from_binlog = false, bool from_database = false); void update_user(User *u, UserId user_id, bool from_binlog = false, bool from_database = false);
void update_chat(Chat *c, ChatId chat_id, bool from_binlog = false, bool from_database = false); void update_chat(Chat *c, ChatId chat_id, bool from_binlog = false, bool from_database = false);
void update_channel(Channel *c, ChannelId channel_id, bool from_binlog = false, bool from_database = false); void update_channel(Channel *c, ChannelId channel_id, bool from_binlog = false, bool from_database = false);
void update_secret_chat(SecretChat *c, SecretChatId secret_chat_id, bool from_binlog = false, void update_secret_chat(SecretChat *c, SecretChatId secret_chat_id, bool from_binlog = false,
bool from_database = false); bool from_database = false);
void update_user_full(UserFull *user_full, UserId user_id); void update_user_full(UserFull *user_full, UserId user_id, bool from_database = false);
void update_chat_full(ChatFull *chat_full, ChatId chat_id); void update_chat_full(ChatFull *chat_full, ChatId chat_id, bool from_database = false);
void update_channel_full(ChannelFull *channel_full, ChannelId channel_id); void update_channel_full(ChannelFull *channel_full, ChannelId channel_id, bool from_database = false);
bool is_chat_full_outdated(const ChatFull *chat_full, const Chat *c, ChatId chat_id) const; bool is_chat_full_outdated(const ChatFull *chat_full, const Chat *c, ChatId chat_id) const;

View File

@ -354,6 +354,22 @@ struct DialogParticipant {
DialogParticipant(UserId user_id, UserId inviter_user_id, int32 joined_date, DialogParticipantStatus status) DialogParticipant(UserId user_id, UserId inviter_user_id, int32 joined_date, DialogParticipantStatus status)
: user_id(user_id), inviter_user_id(inviter_user_id), joined_date(joined_date), status(status) { : user_id(user_id), inviter_user_id(inviter_user_id), joined_date(joined_date), status(status) {
} }
template <class StorerT>
void store(StorerT &storer) const {
td::store(user_id, storer);
td::store(inviter_user_id, storer);
td::store(joined_date, storer);
td::store(status, storer);
}
template <class ParserT>
void parse(ParserT &parser) {
td::parse(user_id, parser);
td::parse(inviter_user_id, parser);
td::parse(joined_date, parser);
td::parse(status, parser);
}
}; };
StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipant &dialog_participant); StringBuilder &operator<<(StringBuilder &string_builder, const DialogParticipant &dialog_participant);

View File

@ -245,6 +245,12 @@ class StickersManager : public Actor {
void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const; void get_current_state(vector<td_api::object_ptr<td_api::Update>> &updates) const;
template <class StorerT>
void store_sticker_set_id(int64 sticker_set_id, StorerT &storer) const;
template <class ParserT>
void parse_sticker_set_id(int64 &sticker_set_id, ParserT &parser);
private: private:
static constexpr int32 MAX_FEATURED_STICKER_SET_VIEW_DELAY = 5; static constexpr int32 MAX_FEATURED_STICKER_SET_VIEW_DELAY = 5;
@ -448,12 +454,6 @@ class StickersManager : public Actor {
template <class ParserT> template <class ParserT>
void parse_sticker_set(StickerSet *sticker_set, ParserT &parser); void parse_sticker_set(StickerSet *sticker_set, ParserT &parser);
template <class StorerT>
void store_sticker_set_id(int64 sticker_set_id, StorerT &storer) const;
template <class ParserT>
void parse_sticker_set_id(int64 &sticker_set_id, ParserT &parser);
Result<std::tuple<FileId, bool, bool>> prepare_input_file(const tl_object_ptr<td_api::InputFile> &input_file); Result<std::tuple<FileId, bool, bool>> prepare_input_file(const tl_object_ptr<td_api::InputFile> &input_file);
Result<std::tuple<FileId, bool, bool>> prepare_input_sticker(td_api::inputSticker *sticker); Result<std::tuple<FileId, bool, bool>> prepare_input_sticker(td_api::inputSticker *sticker);

View File

@ -19,6 +19,7 @@
#include <type_traits> #include <type_traits>
#include <unordered_set> #include <unordered_set>
#include <utility>
#define BEGIN_STORE_FLAGS() \ #define BEGIN_STORE_FLAGS() \
do { \ do { \
@ -172,6 +173,17 @@ void parse(std::unordered_set<Key, Hash, KeyEqual, Allocator> &s, ParserT &parse
} }
} }
template <class U, class V, class StorerT>
void store(const std::pair<U, V> &pair, StorerT &storer) {
store(pair.first, storer);
store(pair.second, storer);
}
template <class U, class V, class ParserT>
void parse(std::pair<U, V> &pair, ParserT &parser) {
parse(pair.first, parser);
parse(pair.second, parser);
}
template <class T, class StorerT> template <class T, class StorerT>
std::enable_if_t<std::is_enum<T>::value> store(const T &val, StorerT &storer) { std::enable_if_t<std::is_enum<T>::value> store(const T &val, StorerT &storer) {
store(static_cast<int32>(val), storer); store(static_cast<int32>(val), storer);