diff --git a/td/telegram/LanguagePackManager.cpp b/td/telegram/LanguagePackManager.cpp index d1b20db83..a5395dc07 100644 --- a/td/telegram/LanguagePackManager.cpp +++ b/td/telegram/LanguagePackManager.cpp @@ -12,14 +12,36 @@ #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/Td.h" -#include "td/utils/logging.h" -#include "td/utils/Status.h" - #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" +#include "td/db/SqliteKeyValue.h" + +#include "td/utils/logging.h" +#include "td/utils/Status.h" + namespace td { +struct LanguagePackManager::LanguageDatabase { + std::mutex mutex_; + string path_; + SqliteKeyValue kv_; + std::unordered_map> language_packs_; +}; + +LanguagePackManager::~LanguagePackManager() = default; + +static Result open_database(const string &path) { + TRY_RESULT(db, SqliteDb::open_with_key(path, DbKey::empty())); + TRY_STATUS(db.exec("PRAGMA synchronous=NORMAL")); + TRY_STATUS(db.exec("PRAGMA temp_store=MEMORY")); + TRY_STATUS(db.exec("PRAGMA encoding=\"UTF-8\"")); + TRY_STATUS(db.exec("PRAGMA journal_mode=WAL")); + SqliteKeyValue kv; + TRY_STATUS(kv.init_with_connection(std::move(db), "lang")); + return std::move(kv); +} + void LanguagePackManager::start_up() { std::lock_guard lock(language_database_mutex_); manager_count_++; @@ -29,10 +51,22 @@ void LanguagePackManager::start_up() { string database_path = G()->shared_config().get_option_string("language_database_path"); auto it = language_databases_.find(database_path); if (it == language_databases_.end()) { - it = language_databases_.emplace(database_path, make_unique()).first; - it->second->path_ = std::move(database_path); + SqliteKeyValue kv; + if (!database_path.empty()) { + auto r_kv = open_database(database_path); + if (r_kv.is_error()) { + LOG(ERROR) << "Can't open language database " << database_path << ": " << r_kv.error(); + database_path = string(); + it = language_databases_.find(database_path); + } else { + kv = r_kv.move_as_ok(); + } + } - // TODO open database + if (it == language_databases_.end()) { + it = language_databases_.emplace(database_path, make_unique()).first; + it->second->path_ = std::move(database_path); + } } database_ = it->second.get(); diff --git a/td/telegram/LanguagePackManager.h b/td/telegram/LanguagePackManager.h index 20c69f8f3..32a483729 100644 --- a/td/telegram/LanguagePackManager.h +++ b/td/telegram/LanguagePackManager.h @@ -15,6 +15,7 @@ #include "td/actor/PromiseFuture.h" #include "td/utils/Container.h" +#include "td/utils/Status.h" #include #include @@ -28,6 +29,11 @@ class LanguagePackManager : public NetQueryCallback { public: explicit LanguagePackManager(ActorShared<> parent) : parent_(std::move(parent)) { } + LanguagePackManager(const LanguagePackManager &) = delete; + LanguagePackManager &operator=(const LanguagePackManager &) = delete; + LanguagePackManager(LanguagePackManager &&) = delete; + LanguagePackManager &operator=(LanguagePackManager &&) = delete; + ~LanguagePackManager() override; void on_language_pack_changed(); @@ -66,11 +72,7 @@ class LanguagePackManager : public NetQueryCallback { std::unordered_map> languages_; }; - struct LanguageDatabase { - std::mutex mutex_; - string path_; - std::unordered_map> language_packs_; - }; + struct LanguageDatabase; ActorShared<> parent_; diff --git a/td/telegram/TdDb.cpp b/td/telegram/TdDb.cpp index ba699b76b..d3b932abd 100644 --- a/td/telegram/TdDb.cpp +++ b/td/telegram/TdDb.cpp @@ -25,7 +25,9 @@ #include "td/utils/Random.h" namespace td { + namespace { + std::string get_binlog_path(const TdParameters ¶meters) { return PSTRING() << parameters.database_directory << "td" << (parameters.use_test_dc ? "_test" : "") << ".binlog"; } @@ -434,4 +436,5 @@ void TdDb::with_db_path(std::function callback) { SqliteDb::with_db_path(sqlite_path(), callback); callback(binlog_path()); } + } // namespace td diff --git a/tddb/td/db/SqliteKeyValue.h b/tddb/td/db/SqliteKeyValue.h index 53b35c502..124a4220d 100644 --- a/tddb/td/db/SqliteKeyValue.h +++ b/tddb/td/db/SqliteKeyValue.h @@ -184,6 +184,9 @@ class SqliteKeyValue { } } + bool empty() const { + return db_.empty(); + } void clear() { *this = SqliteKeyValue(); }