From b9de1b94d28d9e7ce3c30ff9265602913479db73 Mon Sep 17 00:00:00 2001 From: Arseny Smirnov Date: Wed, 12 Aug 2020 22:36:46 +0300 Subject: [PATCH] Sqlcipher: automatic migrate GitOrigin-RevId: 209360f2b40a0d05ec53bb55890518e50c05f34a --- tddb/td/db/SqliteDb.cpp | 23 +++++++++++++++++++++++ tddb/td/db/SqliteDb.h | 2 ++ 2 files changed, 25 insertions(+) diff --git a/tddb/td/db/SqliteDb.cpp b/tddb/td/db/SqliteDb.cpp index 88b07613d..926fb7a70 100644 --- a/tddb/td/db/SqliteDb.cpp +++ b/tddb/td/db/SqliteDb.cpp @@ -125,6 +125,15 @@ Result SqliteDb::get_pragma(Slice name) { CHECK(!stmt.can_step()); return std::move(res); } +Result SqliteDb::get_pragma_string(Slice name) { + TRY_RESULT(stmt, get_statement(PSLICE() << "PRAGMA " << name)); + TRY_STATUS(stmt.step()); + CHECK(stmt.has_row()); + auto res = stmt.view_string(0).str(); + TRY_STATUS(stmt.step()); + CHECK(!stmt.can_step()); + return std::move(res); +} Result SqliteDb::user_version() { TRY_RESULT(get_version_stmt, get_statement("PRAGMA user_version")); @@ -163,6 +172,14 @@ Status SqliteDb::check_encryption() { } Result SqliteDb::open_with_key(CSlice path, const DbKey &db_key) { + auto res = do_open_with_key(path, db_key, false); + if (res.is_error()) { + return do_open_with_key(path, db_key, true); + } + return res; +} + +Result SqliteDb::do_open_with_key(CSlice path, const DbKey &db_key, bool with_cipher_migrate) { SqliteDb db; TRY_STATUS(db.init(path)); if (!db_key.is_empty()) { @@ -171,6 +188,12 @@ Result SqliteDb::open_with_key(CSlice path, const DbKey &db_key) { } auto key = db_key_to_sqlcipher_key(db_key); TRY_STATUS(db.exec(PSLICE() << "PRAGMA key = " << key)); + if (with_cipher_migrate) { + TRY_RESULT(code, db.get_pragma_string("cipher_migrate")); + if (code != "0") { + return Status::Error(PSLICE() << "'PRAGMA cipher_migrate' failed - " << code); + } + } } TRY_STATUS_PREFIX(db.check_encryption(), "Can't open database: "); return std::move(db); diff --git a/tddb/td/db/SqliteDb.h b/tddb/td/db/SqliteDb.h index 6152106f6..fe2b2e518 100644 --- a/tddb/td/db/SqliteDb.h +++ b/tddb/td/db/SqliteDb.h @@ -50,6 +50,7 @@ class SqliteDb { Status exec(CSlice cmd) TD_WARN_UNUSED_RESULT; Result has_table(Slice table); Result get_pragma(Slice name); + Result get_pragma_string(Slice name); Status begin_transaction() TD_WARN_UNUSED_RESULT; Status commit_transaction() TD_WARN_UNUSED_RESULT; @@ -83,6 +84,7 @@ class SqliteDb { bool enable_logging_ = false; Status check_encryption(); + static Result do_open_with_key(CSlice path, const DbKey &db_key, bool with_cipher_migrate); }; } // namespace td