Create database before attaching it.

This commit is contained in:
levlam 2021-09-22 20:17:37 +03:00
parent a0cc1be3e6
commit 626caad19a
3 changed files with 18 additions and 6 deletions

View File

@ -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;

View File

@ -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')"));

View File

@ -160,6 +160,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();