Save language packs to database.
GitOrigin-RevId: 2c40013068881e3170821585c25d29edcc78528c
This commit is contained in:
parent
a7c2a401b8
commit
7c183449a8
@ -23,6 +23,7 @@
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <utility>
|
||||
|
||||
namespace td {
|
||||
|
||||
@ -86,6 +87,15 @@ static Result<SqliteDb> open_database(const string &path) {
|
||||
return std::move(database);
|
||||
}
|
||||
|
||||
static int32 load_database_language_version(SqliteKeyValue *kv) {
|
||||
string str_version = kv->get("!version");
|
||||
if (str_version.empty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return to_integer<int32>(str_version);
|
||||
}
|
||||
|
||||
void LanguagePackManager::start_up() {
|
||||
std::lock_guard<std::mutex> lock(language_database_mutex_);
|
||||
manager_count_++;
|
||||
@ -256,7 +266,7 @@ LanguagePackManager::Language *LanguagePackManager::get_language(LanguagePack *l
|
||||
}
|
||||
|
||||
static string get_database_table_name(const string &language_pack, const string &language_code) {
|
||||
return PSTRING() << language_pack << "_" << language_code;
|
||||
return PSTRING() << "kv_" << language_pack << "_" << language_code;
|
||||
}
|
||||
|
||||
LanguagePackManager::Language *LanguagePackManager::add_language(LanguageDatabase *database,
|
||||
@ -418,12 +428,51 @@ void LanguagePackManager::get_language_pack_strings(string language_code, vector
|
||||
}
|
||||
}
|
||||
|
||||
bool LanguagePackManager::is_valid_key(Slice key) {
|
||||
for (auto c : key) {
|
||||
if (!is_alnum(c) && c != '_' && c != '.' && c != '-') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return !key.empty();
|
||||
}
|
||||
|
||||
void LanguagePackManager::add_strings_to_database(Language *language, int32 new_version,
|
||||
vector<std::pair<string, string>> strings) {
|
||||
if (new_version == -1 && strings.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(database_->mutex_);
|
||||
auto kv = &language->kv_;
|
||||
auto old_version = load_database_language_version(kv);
|
||||
if (old_version >= new_version && (old_version != -1 || new_version != -1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
kv->begin_transaction();
|
||||
for (auto str : strings) {
|
||||
if (!is_valid_key(str.first)) {
|
||||
LOG(ERROR) << "Have invalid key \"" << str.first << '"';
|
||||
continue;
|
||||
}
|
||||
|
||||
kv->set(str.first, str.second);
|
||||
}
|
||||
if (old_version != new_version) {
|
||||
kv->set("!version", to_string(new_version));
|
||||
}
|
||||
kv->commit_transaction();
|
||||
}
|
||||
|
||||
void LanguagePackManager::on_get_language_pack_strings(
|
||||
string language_pack, string language_code, int32 version, bool is_diff, vector<string> keys,
|
||||
vector<tl_object_ptr<telegram_api::LangPackString>> results,
|
||||
Promise<td_api::object_ptr<td_api::languagePackStrings>> promise) {
|
||||
Language *language = get_language(database_, language_pack, language_code);
|
||||
bool is_version_changed = false;
|
||||
int32 new_database_version = -1;
|
||||
vector<std::pair<string, string>> database_strings;
|
||||
if (language == nullptr || (language->version_ < version || !keys.empty())) {
|
||||
if (language == nullptr) {
|
||||
language = add_language(database_, language_pack, language_code);
|
||||
@ -435,6 +484,7 @@ void LanguagePackManager::on_get_language_pack_strings(
|
||||
if (language->version_ < version && !(is_diff && language->version_ == -1)) {
|
||||
LOG(INFO) << "Set language " << language_code << " version to " << version;
|
||||
language->version_ = version;
|
||||
new_database_version = version;
|
||||
is_version_changed = true;
|
||||
}
|
||||
|
||||
@ -443,24 +493,40 @@ void LanguagePackManager::on_get_language_pack_strings(
|
||||
switch (result->get_id()) {
|
||||
case telegram_api::langPackString::ID: {
|
||||
auto str = static_cast<telegram_api::langPackString *>(result.get());
|
||||
language->ordinary_strings_[str->key_] = std::move(str->value_);
|
||||
auto it = language->ordinary_strings_.find(str->key_);
|
||||
if (it == language->ordinary_strings_.end()) {
|
||||
it = language->ordinary_strings_.emplace(str->key_, std::move(str->value_)).first;
|
||||
} else {
|
||||
it->second = std::move(str->value_);
|
||||
}
|
||||
language->pluralized_strings_.erase(str->key_);
|
||||
language->deleted_strings_.erase(str->key_);
|
||||
if (is_diff) {
|
||||
strings.push_back(get_language_pack_string_object(*language->ordinary_strings_.find(str->key_)));
|
||||
strings.push_back(get_language_pack_string_object(*it));
|
||||
}
|
||||
database_strings.emplace_back(str->key_, PSTRING() << '1' << it->second);
|
||||
break;
|
||||
}
|
||||
case telegram_api::langPackStringPluralized::ID: {
|
||||
auto str = static_cast<const telegram_api::langPackStringPluralized *>(result.get());
|
||||
language->pluralized_strings_[str->key_] = PluralizedString{
|
||||
std::move(str->zero_value_), std::move(str->one_value_), std::move(str->two_value_),
|
||||
std::move(str->few_value_), std::move(str->many_value_), std::move(str->other_value_)};
|
||||
PluralizedString value{std::move(str->zero_value_), std::move(str->one_value_),
|
||||
std::move(str->two_value_), std::move(str->few_value_),
|
||||
std::move(str->many_value_), std::move(str->other_value_)};
|
||||
auto it = language->pluralized_strings_.find(str->key_);
|
||||
if (it == language->pluralized_strings_.end()) {
|
||||
it = language->pluralized_strings_.emplace(str->key_, std::move(value)).first;
|
||||
} else {
|
||||
it->second = std::move(value);
|
||||
}
|
||||
language->ordinary_strings_.erase(str->key_);
|
||||
language->deleted_strings_.erase(str->key_);
|
||||
if (is_diff) {
|
||||
strings.push_back(get_language_pack_string_object(*language->pluralized_strings_.find(str->key_)));
|
||||
strings.push_back(get_language_pack_string_object(*it));
|
||||
}
|
||||
database_strings.emplace_back(
|
||||
str->key_, PSTRING() << '2' << it->second.zero_value_ << '\x00' << it->second.one_value_ << '\x00'
|
||||
<< it->second.two_value_ << '\x00' << it->second.few_value_ << '\x00'
|
||||
<< it->second.many_value_ << '\x00' << it->second.other_value_);
|
||||
break;
|
||||
}
|
||||
case telegram_api::langPackStringDeleted::ID: {
|
||||
@ -471,6 +537,7 @@ void LanguagePackManager::on_get_language_pack_strings(
|
||||
if (is_diff) {
|
||||
strings.push_back(get_language_pack_string_object(str->key_));
|
||||
}
|
||||
database_strings.emplace_back(str->key_, "");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -485,6 +552,7 @@ void LanguagePackManager::on_get_language_pack_strings(
|
||||
if (is_diff) {
|
||||
strings.push_back(get_language_pack_string_object(key));
|
||||
}
|
||||
database_strings.emplace_back(key, "");
|
||||
}
|
||||
}
|
||||
|
||||
@ -493,10 +561,11 @@ void LanguagePackManager::on_get_language_pack_strings(
|
||||
send_closure(G()->td(), &Td::send_update,
|
||||
td_api::make_object<td_api::updateLanguagePack>(language_pack, language_code, std::move(strings)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
add_strings_to_database(language, new_database_version, std::move(database_strings));
|
||||
|
||||
// TODO save language
|
||||
}
|
||||
}
|
||||
if (is_diff) {
|
||||
CHECK(language != nullptr);
|
||||
std::lock_guard<std::mutex> lock(language->mutex_);
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "td/actor/PromiseFuture.h"
|
||||
|
||||
#include "td/utils/Container.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/Status.h"
|
||||
|
||||
#include <mutex>
|
||||
@ -88,6 +89,10 @@ class LanguagePackManager : public NetQueryCallback {
|
||||
|
||||
void inc_generation();
|
||||
|
||||
bool is_valid_key(Slice key);
|
||||
|
||||
void add_strings_to_database(Language *language, int32 new_version, vector<std::pair<string, string>> strings);
|
||||
|
||||
void on_get_language_pack_strings(string language_pack, string language_code, int32 version, bool is_diff,
|
||||
vector<string> keys, vector<tl_object_ptr<telegram_api::LangPackString>> results,
|
||||
Promise<td_api::object_ptr<td_api::languagePackStrings>> promise);
|
||||
|
Loading…
Reference in New Issue
Block a user