aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlevlam <levlam@telegram.org>2021-09-22 20:17:37 +0300
committerlevlam <levlam@telegram.org>2021-09-22 20:17:37 +0300
commit626caad19aa07fa4492a7f7b23828f487f54c969 (patch)
tree72059cd082d2c7e730397d16e0a2537888babf3b
parenta0cc1be3e6009850f24a7e704f09328ed31a2702 (diff)
Create database before attaching it.
-rw-r--r--td/telegram/DialogDb.cpp8
-rw-r--r--tddb/td/db/SqliteDb.cpp15
-rw-r--r--test/db.cpp1
3 files changed, 18 insertions, 6 deletions
diff --git a/td/telegram/DialogDb.cpp b/td/telegram/DialogDb.cpp
index 0eb1af32f..2a28a195f 100644
--- a/td/telegram/DialogDb.cpp
+++ b/td/telegram/DialogDb.cpp
@@ -105,13 +105,17 @@ Status init_dialog_db(SqliteDb &db, int32 version, KeyValueSyncInterface &binlog
// NB: must happen inside a transaction
Status drop_dialog_db(SqliteDb &db, int version) {
if (version < static_cast<int32>(DbVersion::DialogDbCreated)) {
- LOG(WARNING) << "Drop old pmc dialog_db";
+ if (version != 0) {
+ LOG(WARNING) << "Drop old pmc dialog_db";
+ }
SqliteKeyValue kv;
kv.init_with_connection(db.clone(), "common").ensure();
kv.erase_by_prefix("di");
}
- LOG(WARNING) << "Drop dialog_db " << tag("version", version) << tag("current_db_version", current_db_version());
+ if (version != 0) {
+ LOG(WARNING) << "Drop dialog_db " << tag("version", version) << tag("current_db_version", current_db_version());
+ }
auto status = db.exec("DROP TABLE IF EXISTS dialogs");
TRY_STATUS(db.exec("DROP TABLE IF EXISTS notification_groups"));
return status;
diff --git a/tddb/td/db/SqliteDb.cpp b/tddb/td/db/SqliteDb.cpp
index 0922e8888..8abf5e4ea 100644
--- a/tddb/td/db/SqliteDb.cpp
+++ b/tddb/td/db/SqliteDb.cpp
@@ -83,7 +83,8 @@ Status SqliteDb::init(CSlice path, bool allow_creation) {
sqlite3 *db;
CHECK(sqlite3_threadsafe() != 0);
- int rc = sqlite3_open_v2(path.c_str(), &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
+ int rc =
+ sqlite3_open_v2(path.c_str(), &db, SQLITE_OPEN_READWRITE | (allow_creation ? SQLITE_OPEN_CREATE : 0), nullptr);
if (rc != SQLITE_OK) {
auto res = detail::RawSqliteDb::last_error(db, path);
sqlite3_close(db);
@@ -246,6 +247,12 @@ Result<SqliteDb> SqliteDb::change_key(CSlice path, bool allow_creation, const Db
}
}
+ auto create_database = [](CSlice tmp_path) -> Status {
+ TRY_STATUS(destroy(tmp_path));
+ SqliteDb db;
+ return db.init(tmp_path, true);
+ };
+
TRY_RESULT(db, open_with_key(path, false, old_db_key));
TRY_RESULT(user_version, db.user_version());
auto new_key = db_key_to_sqlcipher_key(new_db_key);
@@ -253,9 +260,9 @@ Result<SqliteDb> SqliteDb::change_key(CSlice path, bool allow_creation, const Db
LOG(DEBUG) << "ENCRYPT";
PerfWarningTimer timer("Encrypt SQLite database", 0.1);
auto tmp_path = path.str() + ".encrypted";
- TRY_STATUS(destroy(tmp_path));
+ TRY_STATUS(create_database(tmp_path));
- // make shure that database is not empty
+ // make sure that database is not empty
TRY_STATUS(db.exec("CREATE TABLE IF NOT EXISTS encryption_dummy_table(id INT PRIMARY KEY)"));
TRY_STATUS(db.exec(PSLICE() << "ATTACH DATABASE '" << quote_string(tmp_path) << "' AS encrypted KEY " << new_key));
TRY_STATUS(db.exec("SELECT sqlcipher_export('encrypted')"));
@@ -267,7 +274,7 @@ Result<SqliteDb> SqliteDb::change_key(CSlice path, bool allow_creation, const Db
LOG(DEBUG) << "DECRYPT";
PerfWarningTimer timer("Decrypt SQLite database", 0.1);
auto tmp_path = path.str() + ".encrypted";
- TRY_STATUS(destroy(tmp_path));
+ TRY_STATUS(create_database(tmp_path));
TRY_STATUS(db.exec(PSLICE() << "ATTACH DATABASE '" << quote_string(tmp_path) << "' AS decrypted KEY ''"));
TRY_STATUS(db.exec("SELECT sqlcipher_export('decrypted')"));
diff --git a/test/db.cpp b/test/db.cpp
index c7cf1d1c8..44c4fab68 100644
--- a/test/db.cpp
+++ b/test/db.cpp
@@ -161,6 +161,7 @@ TEST(DB, sqlite_encryption) {
SqliteDb::open_with_key(path, false, cucumber).ensure_error();
SqliteDb::change_key(path, false, cucumber, empty).ensure();
+ SqliteDb::change_key(path, false, cucumber, empty).ensure();
SqliteDb::open_with_key(path, false, tomato).ensure_error();
{