Fix some spelling.
GitOrigin-RevId: 351e7c32fee3fb9249d561434ba1515082e757b0
This commit is contained in:
parent
cc4877d0da
commit
9d3ab75c56
@ -1041,7 +1041,7 @@ bool AuthManager::load_state() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Load auth_state from db: " << tag("state", static_cast<int32>(db_state.state_));
|
LOG(INFO) << "Load auth_state from database: " << tag("state", static_cast<int32>(db_state.state_));
|
||||||
if (db_state.state_ == State::WaitCode) {
|
if (db_state.state_ == State::WaitCode) {
|
||||||
send_code_helper_ = std::move(db_state.send_code_helper_);
|
send_code_helper_ = std::move(db_state.send_code_helper_);
|
||||||
terms_of_service_ = std::move(db_state.terms_of_service_);
|
terms_of_service_ = std::move(db_state.terms_of_service_);
|
||||||
|
@ -1416,7 +1416,7 @@ void SecretChatActor::on_save_changes_start(ChangesProcessor<StateChange>::Id sa
|
|||||||
saved_pfs_state_message_id_ = pfs_state_change.message_id;
|
saved_pfs_state_message_id_ = pfs_state_change.message_id;
|
||||||
context_->secret_chat_db()->set_value(pfs_state_change);
|
context_->secret_chat_db()->set_value(pfs_state_change);
|
||||||
}
|
}
|
||||||
// NB: we may not wait till db is flushed, because every other change will be in the same binlog
|
// NB: we may not wait till database is flushed, because every other change will be in the same binlog
|
||||||
for (auto &save_changes_finish : save_changes_finish_promises) {
|
for (auto &save_changes_finish : save_changes_finish_promises) {
|
||||||
save_changes_finish.set_value(Unit());
|
save_changes_finish.set_value(Unit());
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ class SecretChatActor : public NetQueryCallback {
|
|||||||
virtual bool close_flag() = 0;
|
virtual bool close_flag() = 0;
|
||||||
|
|
||||||
// We don't want to expose the whole NetQueryDispatcher, MessagesManager and ContactsManager.
|
// We don't want to expose the whole NetQueryDispatcher, MessagesManager and ContactsManager.
|
||||||
// So it is more clear which parts of MessagesManager is really used. And it is much easier to create tests.
|
// So it is more clear which parts of MessagesManager are really used. And it is much easier to create tests.
|
||||||
virtual void send_net_query(NetQueryPtr query, ActorShared<NetQueryCallback> callback, bool ordered) = 0;
|
virtual void send_net_query(NetQueryPtr query, ActorShared<NetQueryCallback> callback, bool ordered) = 0;
|
||||||
|
|
||||||
virtual void on_update_secret_chat(int64 access_hash, UserId user_id, SecretChatState state, bool is_outbound,
|
virtual void on_update_secret_chat(int64 access_hash, UserId user_id, SecretChatState state, bool is_outbound,
|
||||||
@ -80,7 +80,7 @@ class SecretChatActor : public NetQueryCallback {
|
|||||||
// Promise must be set only after the update is processed.
|
// Promise must be set only after the update is processed.
|
||||||
//
|
//
|
||||||
// For example, one may set promise, after update was sent to binlog. It is ok, because SecretChatsActor will delete
|
// For example, one may set promise, after update was sent to binlog. It is ok, because SecretChatsActor will delete
|
||||||
// this update thought binlog too. So it wouldn't be deleted before update is saved.
|
// this update through binlog too. So it wouldn't be deleted before update is saved.
|
||||||
|
|
||||||
// inbound messages
|
// inbound messages
|
||||||
virtual void on_inbound_message(UserId user_id, MessageId message_id, int32 date,
|
virtual void on_inbound_message(UserId user_id, MessageId message_id, int32 date,
|
||||||
@ -113,7 +113,7 @@ class SecretChatActor : public NetQueryCallback {
|
|||||||
void add_inbound_message(unique_ptr<logevent::InboundSecretMessage> message);
|
void add_inbound_message(unique_ptr<logevent::InboundSecretMessage> message);
|
||||||
|
|
||||||
// Outbound messages
|
// Outbound messages
|
||||||
// Promise will be set just after correspoiding logevent will be SENT to binlog.
|
// Promise will be set just after corresponding logevent will be SENT to binlog.
|
||||||
void send_message(tl_object_ptr<secret_api::DecryptedMessage> message,
|
void send_message(tl_object_ptr<secret_api::DecryptedMessage> message,
|
||||||
tl_object_ptr<telegram_api::InputEncryptedFile> file, Promise<> promise);
|
tl_object_ptr<telegram_api::InputEncryptedFile> file, Promise<> promise);
|
||||||
void send_message_action(tl_object_ptr<secret_api::SendMessageAction> action);
|
void send_message_action(tl_object_ptr<secret_api::SendMessageAction> action);
|
||||||
@ -137,7 +137,7 @@ class SecretChatActor : public NetQueryCallback {
|
|||||||
enum class State : int32 { Empty, SendRequest, SendAccept, WaitRequestResponse, WaitAcceptResponse, Ready, Closed };
|
enum class State : int32 { Empty, SendRequest, SendAccept, WaitRequestResponse, WaitAcceptResponse, Ready, Closed };
|
||||||
static constexpr int32 MAX_RESEND_COUNT = 1000;
|
static constexpr int32 MAX_RESEND_COUNT = 1000;
|
||||||
|
|
||||||
// We have git state that should be synchronized with db.
|
// We have git state that should be synchronized with the database.
|
||||||
// It is splitted into several parts because:
|
// It is splitted into several parts because:
|
||||||
// 1. Some parts are BIG (auth_key, for example) and are rarely updated.
|
// 1. Some parts are BIG (auth_key, for example) and are rarely updated.
|
||||||
// 2. Other are frequently updated, so probably should be as small as possible.
|
// 2. Other are frequently updated, so probably should be as small as possible.
|
||||||
@ -459,13 +459,13 @@ class SecretChatActor : public NetQueryCallback {
|
|||||||
// This is completly flawed.
|
// This is completly flawed.
|
||||||
// (A-start_save_to_binlog ----> B-start_save_to_binlog+change_memory ----> A-finish_save_to_binlog+surprise)
|
// (A-start_save_to_binlog ----> B-start_save_to_binlog+change_memory ----> A-finish_save_to_binlog+surprise)
|
||||||
//
|
//
|
||||||
// Instead I suggest general solution that is already used with SeqNoState and Qts
|
// Instead I suggest general solution that is already used with SeqNoState and qts
|
||||||
// 1. We APPLY CHANGE to memory immidiately AFTER correspoding EVENT is SENT to the binlog.
|
// 1. We APPLY CHANGE to memory immediately AFTER corresponding EVENT is SENT to the binlog.
|
||||||
// 2. We SEND CHANGE to db only after correspoiding EVENT is SAVED to the binlog.
|
// 2. We SEND CHANGE to database only after corresponding EVENT is SAVED to the binlog.
|
||||||
// 3. The we are able to ERASE EVENT just AFTER the CHANGE is SAVED to the binlog.
|
// 3. Then we are able to ERASE EVENT just AFTER the CHANGE is SAVED to the binlog.
|
||||||
//
|
//
|
||||||
// Actually the change will be saved to binlog too.
|
// Actually the change will be saved to binlog too.
|
||||||
// So we can do it immidiatelly after EVENT is SENT to the binlog, because SEND CHANGE and ERASE EVENT will be
|
// So we can do it immediatelly after EVENT is SENT to the binlog, because SEND CHANGE and ERASE EVENT will be
|
||||||
// ordered automatically.
|
// ordered automatically.
|
||||||
//
|
//
|
||||||
// We will use common ChangeProcessor for all changes (inside one SecretChatActor).
|
// We will use common ChangeProcessor for all changes (inside one SecretChatActor).
|
||||||
|
@ -32,16 +32,16 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
//
|
|
||||||
// qts and seq_no
|
// qts and seq_no
|
||||||
// Each EncryptedMessage (update_message) has qts.
|
// Each EncryptedMessage (update_message) has qts.
|
||||||
// Such updates must be handled in order of qts
|
// Such updates must be handled in order of qts
|
||||||
//
|
//
|
||||||
// Qts should be handled on level of SecretChatsManager
|
// Qts should be handled on level of SecretChatsManager
|
||||||
// 1. Each update can be received by SecretChatsManager multiple times.
|
// 1. Each update can be received by SecretChatsManager multiple times.
|
||||||
// 2. Each update should be sent to SecretChatActor only once. (Thought SecretChatActor mustn't rely it)
|
// 2. Each update should be sent to SecretChatActor only once. (Though SecretChatActor mustn't rely it)
|
||||||
// 3. Updates must be send in order of qts, without gaps.
|
// 3. Updates must be send in order of qts, without gaps.
|
||||||
// 4. SecretChatActor must notify SecretChatManager when update is processed (saved in db)
|
// 4. SecretChatActor must notify SecretChatManager when update is processed (saved in database)
|
||||||
// 5. Only after all updates <= qts are processed by SecretChatActor, UpdatesManager should be
|
// 5. Only after all updates <= qts are processed by SecretChatActor, UpdatesManager should be
|
||||||
// notified about new qts.
|
// notified about new qts.
|
||||||
//
|
//
|
||||||
@ -75,9 +75,6 @@ namespace td {
|
|||||||
// 5. Handling gaps.
|
// 5. Handling gaps.
|
||||||
// TODO
|
// TODO
|
||||||
// Just fail chat.
|
// Just fail chat.
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
|
|
||||||
SecretChatsManager::SecretChatsManager(ActorShared<> parent) : parent_(std::move(parent)) {
|
SecretChatsManager::SecretChatsManager(ActorShared<> parent) : parent_(std::move(parent)) {
|
||||||
}
|
}
|
||||||
@ -87,7 +84,7 @@ void SecretChatsManager::start_up() {
|
|||||||
dummy_mode_ = true;
|
dummy_mode_ = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO: use db wrapper
|
// TODO: use database wrapper
|
||||||
auto pmc = G()->td_db()->get_binlog_pmc();
|
auto pmc = G()->td_db()->get_binlog_pmc();
|
||||||
auto qts_str = pmc->get("updates.qts");
|
auto qts_str = pmc->get("updates.qts");
|
||||||
if (!qts_str.empty()) {
|
if (!qts_str.empty()) {
|
||||||
|
@ -3271,9 +3271,9 @@ td_api::object_ptr<td_api::AuthorizationState> Td::get_fake_authorization_state_
|
|||||||
|
|
||||||
DbKey Td::as_db_key(string key) {
|
DbKey Td::as_db_key(string key) {
|
||||||
// Database will still be effectively not encrypted, but
|
// Database will still be effectively not encrypted, but
|
||||||
// 1. sqlite db will be protected from corruption, because that's how sqlcipher works
|
// 1. SQLite database will be protected from corruption, because that's how sqlcipher works
|
||||||
// 2. security through obscurity
|
// 2. security through obscurity
|
||||||
// 3. no need for reencryption of sqlite db
|
// 3. no need for reencryption of SQLite database
|
||||||
if (key.empty()) {
|
if (key.empty()) {
|
||||||
return DbKey::raw_key("cucumber");
|
return DbKey::raw_key("cucumber");
|
||||||
}
|
}
|
||||||
|
@ -378,7 +378,7 @@ Status TdDb::init(int32 scheduler_id, const TdParameters ¶meters, DbKey key,
|
|||||||
}
|
}
|
||||||
auto init_sqlite_status = init_sqlite(scheduler_id, parameters, new_sqlite_key, old_sqlite_key, *binlog_pmc);
|
auto init_sqlite_status = init_sqlite(scheduler_id, parameters, new_sqlite_key, old_sqlite_key, *binlog_pmc);
|
||||||
if (init_sqlite_status.is_error()) {
|
if (init_sqlite_status.is_error()) {
|
||||||
LOG(ERROR) << "Destroy bad sqlite db because of: " << init_sqlite_status;
|
LOG(ERROR) << "Destroy bad SQLite database because of " << init_sqlite_status;
|
||||||
SqliteDb::destroy(get_sqlite_path(parameters)).ignore();
|
SqliteDb::destroy(get_sqlite_path(parameters)).ignore();
|
||||||
TRY_STATUS(init_sqlite(scheduler_id, parameters, new_sqlite_key, old_sqlite_key, *binlog_pmc));
|
TRY_STATUS(init_sqlite(scheduler_id, parameters, new_sqlite_key, old_sqlite_key, *binlog_pmc));
|
||||||
}
|
}
|
||||||
|
@ -561,7 +561,7 @@ void TopDialogManager::loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_enabled_) {
|
if (is_enabled_) {
|
||||||
// db sync
|
// database sync
|
||||||
Timestamp db_sync_timeout;
|
Timestamp db_sync_timeout;
|
||||||
if (db_sync_state_ == SyncState::Ok) {
|
if (db_sync_state_ == SyncState::Ok) {
|
||||||
if (first_unsync_change_) {
|
if (first_unsync_change_) {
|
||||||
|
@ -35,7 +35,7 @@ Status drop_file_db(SqliteDb &db, int32 version) {
|
|||||||
|
|
||||||
Status fix_file_remote_location_key_bug(SqliteDb &db);
|
Status fix_file_remote_location_key_bug(SqliteDb &db);
|
||||||
Status init_file_db(SqliteDb &db, int32 version) {
|
Status init_file_db(SqliteDb &db, int32 version) {
|
||||||
LOG(INFO) << "Init file db " << tag("version", version);
|
LOG(INFO) << "Init file database " << tag("version", version);
|
||||||
|
|
||||||
// Check if database exists
|
// Check if database exists
|
||||||
TRY_RESULT(has_table, db.has_table("files"));
|
TRY_RESULT(has_table, db.has_table("files"));
|
||||||
@ -143,7 +143,7 @@ class FileDb : public FileDbInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void optimize_refs(const std::vector<Id> ids, Id main_id) {
|
void optimize_refs(const std::vector<Id> ids, Id main_id) {
|
||||||
LOG(INFO) << "Optimize ids in file db" << format::as_array(ids) << " " << main_id;
|
LOG(INFO) << "Optimize ids in file database" << format::as_array(ids) << " " << main_id;
|
||||||
auto &pmc = file_pmc();
|
auto &pmc = file_pmc();
|
||||||
pmc.begin_transaction().ensure();
|
pmc.begin_transaction().ensure();
|
||||||
SCOPE_EXIT {
|
SCOPE_EXIT {
|
||||||
@ -248,7 +248,7 @@ class FileDb : public FileDbInterface {
|
|||||||
int attempt_count = 0;
|
int attempt_count = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (attempt_count > 100) {
|
if (attempt_count > 100) {
|
||||||
LOG(FATAL) << "cycle in files db?";
|
LOG(FATAL) << "cycle in file database?";
|
||||||
}
|
}
|
||||||
attempt_count++;
|
attempt_count++;
|
||||||
|
|
||||||
@ -281,7 +281,7 @@ class FileDb : public FileDbInterface {
|
|||||||
auto id_str = pmc.get(key);
|
auto id_str = pmc.get(key);
|
||||||
//LOG(DEBUG) << "Found id " << id_str << " by key " << format::as_hex_dump<4>(Slice(key));
|
//LOG(DEBUG) << "Found id " << id_str << " by key " << format::as_hex_dump<4>(Slice(key));
|
||||||
if (id_str.empty()) {
|
if (id_str.empty()) {
|
||||||
return Status::Error("There is no such a key in db");
|
return Status::Error("There is no such a key in database");
|
||||||
}
|
}
|
||||||
return to_integer<Id>(id_str);
|
return to_integer<Id>(id_str);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ int VERBOSITY_NAME(file_gc) = VERBOSITY_NAME(INFO);
|
|||||||
void FileGcWorker::do_remove_file(const FullFileInfo &info) {
|
void FileGcWorker::do_remove_file(const FullFileInfo &info) {
|
||||||
// LOG(WARNING) << "Gc remove file: " << tag("path", file) << tag("mtime", stat.mtime_nsec_ / 1000000000)
|
// LOG(WARNING) << "Gc remove file: " << tag("path", file) << tag("mtime", stat.mtime_nsec_ / 1000000000)
|
||||||
// << tag("atime", stat.atime_nsec_ / 1000000000);
|
// << tag("atime", stat.atime_nsec_ / 1000000000);
|
||||||
// TODO: remove file from db too.
|
// TODO: remove file from database too
|
||||||
auto status = unlink(info.path);
|
auto status = unlink(info.path);
|
||||||
LOG_IF(WARNING, status.is_error()) << "Failed to unlink file during files gc: " << status;
|
LOG_IF(WARNING, status.is_error()) << "Failed to unlink file during files gc: " << status;
|
||||||
send_closure(G()->file_manager(), &FileManager::on_file_unlink,
|
send_closure(G()->file_manager(), &FileManager::on_file_unlink,
|
||||||
|
@ -91,11 +91,11 @@ class Session final
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// When connection is closed, mark all queries without ack as unknown
|
// When connection is closed, mark all queries without ack as unknown.
|
||||||
// Ask state of all unknown queries when new connection is created.
|
// Ask state of all unknown queries when new connection is created.
|
||||||
//
|
//
|
||||||
// Just re-ask answer_id each time we get information about it.
|
// Just re-ask answer_id each time we get information about it.
|
||||||
// Thought mtproto::Connection must ensure delivery of such query
|
// Though mtproto::Connection must ensure delivery of such query.
|
||||||
|
|
||||||
int32 dc_id_;
|
int32 dc_id_;
|
||||||
enum class Mode : int8 { Tcp, Http } mode_ = Mode::Tcp;
|
enum class Mode : int8 { Tcp, Http } mode_ = Mode::Tcp;
|
||||||
|
@ -40,12 +40,12 @@ class SqliteConnectionSafe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void close() {
|
void close() {
|
||||||
LOG(INFO) << "Close sqlite db " << tag("path", name_);
|
LOG(INFO) << "Close SQLite database " << tag("path", name_);
|
||||||
lsls_connection_.clear_values();
|
lsls_connection_.clear_values();
|
||||||
}
|
}
|
||||||
void close_and_destroy() {
|
void close_and_destroy() {
|
||||||
close();
|
close();
|
||||||
LOG(INFO) << "Destroy sqlite db " << tag("path", name_);
|
LOG(INFO) << "Destroy SQLite database " << tag("path", name_);
|
||||||
SqliteDb::destroy(name_).ignore();
|
SqliteDb::destroy(name_).ignore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ Status SqliteDb::init(CSlice path, bool *was_created) {
|
|||||||
int rc = sqlite3_open_v2(path.c_str(), &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE /*| SQLITE_OPEN_SHAREDCACHE*/,
|
int rc = sqlite3_open_v2(path.c_str(), &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE /*| SQLITE_OPEN_SHAREDCACHE*/,
|
||||||
nullptr);
|
nullptr);
|
||||||
if (rc != SQLITE_OK) {
|
if (rc != SQLITE_OK) {
|
||||||
auto res = Status::Error(PSLICE() << "Failed to open db: " << detail::RawSqliteDb::last_error(db));
|
auto res = Status::Error(PSLICE() << "Failed to open database: " << detail::RawSqliteDb::last_error(db));
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -92,9 +92,9 @@ void SqliteDb::trace(bool flag) {
|
|||||||
Status SqliteDb::exec(CSlice cmd) {
|
Status SqliteDb::exec(CSlice cmd) {
|
||||||
CHECK(!empty());
|
CHECK(!empty());
|
||||||
char *msg;
|
char *msg;
|
||||||
VLOG(sqlite) << "Start exec " << tag("cmd", cmd) << tag("db", raw_->db());
|
VLOG(sqlite) << "Start exec " << tag("query", cmd) << tag("database", raw_->db());
|
||||||
auto rc = sqlite3_exec(raw_->db(), cmd.c_str(), nullptr, nullptr, &msg);
|
auto rc = sqlite3_exec(raw_->db(), cmd.c_str(), nullptr, nullptr, &msg);
|
||||||
VLOG(sqlite) << "Finish exec " << tag("cmd", cmd) << tag("db", raw_->db());
|
VLOG(sqlite) << "Finish exec " << tag("query", cmd) << tag("database", raw_->db());
|
||||||
if (rc != SQLITE_OK) {
|
if (rc != SQLITE_OK) {
|
||||||
CHECK(msg != nullptr);
|
CHECK(msg != nullptr);
|
||||||
return Status::Error(PSLICE() << tag("query", cmd) << " failed: " << msg);
|
return Status::Error(PSLICE() << tag("query", cmd) << " failed: " << msg);
|
||||||
@ -175,7 +175,7 @@ Status SqliteDb::change_key(CSlice path, const DbKey &new_db_key, const DbKey &o
|
|||||||
auto new_key = db_key_to_sqlcipher_key(new_db_key);
|
auto new_key = db_key_to_sqlcipher_key(new_db_key);
|
||||||
if (old_db_key.is_empty() && !new_db_key.is_empty()) {
|
if (old_db_key.is_empty() && !new_db_key.is_empty()) {
|
||||||
LOG(DEBUG) << "ENCRYPT";
|
LOG(DEBUG) << "ENCRYPT";
|
||||||
PerfWarningTimer timer("Encrypt sqlite database", 0.1);
|
PerfWarningTimer timer("Encrypt SQLite database", 0.1);
|
||||||
auto tmp_path = path.str() + ".ecnrypted";
|
auto tmp_path = path.str() + ".ecnrypted";
|
||||||
TRY_STATUS(destroy(tmp_path));
|
TRY_STATUS(destroy(tmp_path));
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ Status SqliteDb::change_key(CSlice path, const DbKey &new_db_key, const DbKey &o
|
|||||||
TRY_STATUS(rename(tmp_path, path));
|
TRY_STATUS(rename(tmp_path, path));
|
||||||
} else if (!old_db_key.is_empty() && new_db_key.is_empty()) {
|
} else if (!old_db_key.is_empty() && new_db_key.is_empty()) {
|
||||||
LOG(DEBUG) << "DECRYPT";
|
LOG(DEBUG) << "DECRYPT";
|
||||||
PerfWarningTimer timer("Decrypt sqlite database", 0.1);
|
PerfWarningTimer timer("Decrypt SQLite database", 0.1);
|
||||||
auto tmp_path = path.str() + ".ecnrypted";
|
auto tmp_path = path.str() + ".ecnrypted";
|
||||||
TRY_STATUS(destroy(tmp_path));
|
TRY_STATUS(destroy(tmp_path));
|
||||||
|
|
||||||
@ -203,7 +203,7 @@ Status SqliteDb::change_key(CSlice path, const DbKey &new_db_key, const DbKey &o
|
|||||||
TRY_STATUS(rename(tmp_path, path));
|
TRY_STATUS(rename(tmp_path, path));
|
||||||
} else {
|
} else {
|
||||||
LOG(DEBUG) << "REKEY";
|
LOG(DEBUG) << "REKEY";
|
||||||
PerfWarningTimer timer("Rekey sqlite database", 0.1);
|
PerfWarningTimer timer("Rekey SQLite database", 0.1);
|
||||||
TRY_STATUS(db.exec(PSLICE() << "PRAGMA rekey = " << new_key));
|
TRY_STATUS(db.exec(PSLICE() << "PRAGMA rekey = " << new_key));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ Result<SqliteStatement> SqliteDb::get_statement(CSlice statement) {
|
|||||||
sqlite3_stmt *stmt = nullptr;
|
sqlite3_stmt *stmt = nullptr;
|
||||||
auto rc = sqlite3_prepare_v2(get_native(), statement.c_str(), static_cast<int>(statement.size()) + 1, &stmt, nullptr);
|
auto rc = sqlite3_prepare_v2(get_native(), statement.c_str(), static_cast<int>(statement.size()) + 1, &stmt, nullptr);
|
||||||
if (rc != SQLITE_OK) {
|
if (rc != SQLITE_OK) {
|
||||||
return Status::Error(PSLICE() << "Failed to prepare sqlite " << tag("stmt", statement) << raw_->last_error());
|
return Status::Error(PSLICE() << "Failed to prepare SQLite " << tag("statement", statement) << raw_->last_error());
|
||||||
}
|
}
|
||||||
CHECK(stmt != nullptr) << statement;
|
CHECK(stmt != nullptr) << statement;
|
||||||
return SqliteStatement(stmt, raw_);
|
return SqliteStatement(stmt, raw_);
|
||||||
|
@ -22,7 +22,7 @@ int printExplainQueryPlan(StringBuilder &sb, sqlite3_stmt *pStmt) {
|
|||||||
return SQLITE_ERROR;
|
return SQLITE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
sb << "Explain " << tag("cmd", zSql);
|
sb << "Explain query " << zSql;
|
||||||
char *zExplain = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zSql);
|
char *zExplain = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zSql);
|
||||||
if (zExplain == nullptr) {
|
if (zExplain == nullptr) {
|
||||||
return SQLITE_NOMEM;
|
return SQLITE_NOMEM;
|
||||||
@ -41,7 +41,7 @@ int printExplainQueryPlan(StringBuilder &sb, sqlite3_stmt *pStmt) {
|
|||||||
int iFrom = sqlite3_column_int(pExplain, 2);
|
int iFrom = sqlite3_column_int(pExplain, 2);
|
||||||
const char *zDetail = reinterpret_cast<const char *>(sqlite3_column_text(pExplain, 3));
|
const char *zDetail = reinterpret_cast<const char *>(sqlite3_column_text(pExplain, 3));
|
||||||
|
|
||||||
sb << "\n" << iSelectid << " " << iOrder << " " << iFrom << " " << zDetail;
|
sb << '\n' << iSelectid << ' ' << iOrder << ' ' << iFrom << ' ' << zDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sqlite3_finalize(pExplain);
|
return sqlite3_finalize(pExplain);
|
||||||
@ -176,11 +176,11 @@ Status SqliteStatement::step() {
|
|||||||
if (state_ == Finish) {
|
if (state_ == Finish) {
|
||||||
return Status::Error("One has to reset statement");
|
return Status::Error("One has to reset statement");
|
||||||
}
|
}
|
||||||
VLOG(sqlite) << "Start step " << tag("cmd", sqlite3_sql(stmt_.get())) << tag("stmt", stmt_.get())
|
VLOG(sqlite) << "Start step " << tag("query", sqlite3_sql(stmt_.get())) << tag("statement", stmt_.get())
|
||||||
<< tag("db", db_.get());
|
<< tag("database", db_.get());
|
||||||
auto rc = sqlite3_step(stmt_.get());
|
auto rc = sqlite3_step(stmt_.get());
|
||||||
VLOG(sqlite) << "Finish step " << tag("cmd", sqlite3_sql(stmt_.get())) << tag("stmt", stmt_.get())
|
VLOG(sqlite) << "Finish step " << tag("query", sqlite3_sql(stmt_.get())) << tag("statement", stmt_.get())
|
||||||
<< tag("db", db_.get());
|
<< tag("database", db_.get());
|
||||||
if (rc == SQLITE_ROW) {
|
if (rc == SQLITE_ROW) {
|
||||||
state_ = GotRow;
|
state_ = GotRow;
|
||||||
return Status::OK();
|
return Status::OK();
|
||||||
|
Loading…
Reference in New Issue
Block a user