From 755db20a623d4982e7495969a354ec77e68825ea Mon Sep 17 00:00:00 2001 From: zwtmichael Date: Thu, 20 Oct 2022 09:57:51 +0800 Subject: [PATCH 1/2] add encrypt delete table scene problem Signed-off-by: zwtmichael --- .../relational_store_sqlite_ext.cpp | 78 +++------ ...tributeddb_storage_data_operation_test.cpp | 152 ++++++++++++++++++ ...ributeddb_relational_ver_p2p_sync_test.cpp | 34 ++++ ...rtual_relational_ver_sync_db_interface.cpp | 4 +- 4 files changed, 215 insertions(+), 53 deletions(-) diff --git a/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp b/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp index 4646d97e121..b611770d93e 100644 --- a/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp +++ b/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp @@ -357,61 +357,35 @@ int GetCurrentMaxTimestamp(sqlite3 *db, Timestamp &maxTimestamp) return E_OK; } -int ClearTheLogAfterDropTable(void *db, int actionCode, const char *tblName, - const char *useLessParam, const char *schemaName, const char *triggerName) +void ClearTheLogAfterDropTable(sqlite3 *db, const char *tableName, const char *dbName) { - (void)useLessParam; - (void)triggerName; - if (actionCode != SQLITE_DROP_TABLE) { - return SQLITE_OK; - } - if (db == nullptr || tblName == nullptr || schemaName == nullptr) { - return SQLITE_DENY; - } - auto filepath = sqlite3_db_filename(static_cast(db), schemaName); - if (filepath == nullptr) { - return SQLITE_DENY; - } - auto filename = std::string(filepath); - std::thread th([filename, tableName = std::string(tblName), dropTimeStamp = TimeHelper::GetTime(0)] { - sqlite3 *db = nullptr; - (void)sqlite3_open(filename.c_str(), &db); - if (db == nullptr) { - return; - } - - if (sqlite3_busy_timeout(db, BUSY_TIMEOUT) != SQLITE_OK) { - sqlite3_close(db); - return; - } - - sqlite3_stmt *stmt = nullptr; - std::string logTblName = "naturalbase_rdb_aux_" + std::string(tableName) + "_log"; - std::string sql = "SELECT count(*) FROM sqlite_master WHERE type='table' AND name='" + logTblName + "';"; - if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) { - (void)sqlite3_finalize(stmt); - sqlite3_close(db); - return; - } - - bool isLogTblExists = false; - if (sqlite3_step(stmt) == SQLITE_ROW && static_cast(sqlite3_column_int(stmt, 0))) { - isLogTblExists = true; - } + if (db == nullptr || tableName == nullptr) { + return; + } + sqlite3_stmt *stmt = nullptr; + std::string logTblName = "naturalbase_rdb_aux_" + std::string(tableName) + "_log"; + Timestamp dropTimeStamp = TimeHelper::GetTime(0); + std::string sql = "SELECT count(*) FROM sqlite_master WHERE type='table' AND name='" + logTblName + "';"; + if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) { (void)sqlite3_finalize(stmt); - stmt = nullptr; - - if (isLogTblExists) { - RegisterGetSysTime(db); - sql = "UPDATE " + logTblName + " SET flag=0x03, timestamp=get_sys_time(0) " - "WHERE flag&0x03=0x02 AND timestamp<" + std::to_string(dropTimeStamp); - (void)sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr); - } sqlite3_close(db); return; - }); - th.detach(); - return SQLITE_OK; + } + + bool isLogTblExists = false; + if (sqlite3_step(stmt) == SQLITE_ROW && static_cast(sqlite3_column_int(stmt, 0))) { + isLogTblExists = true; + } + (void)sqlite3_finalize(stmt); + stmt = nullptr; + + if (isLogTblExists) { + RegisterGetSysTime(db); + sql = "UPDATE " + logTblName + " SET flag=0x03, timestamp=get_sys_time(0) " + "WHERE flag&0x03=0x02 AND timestamp<" + std::to_string(dropTimeStamp); + (void)sqlite3_exec(db, sql.c_str(), nullptr, nullptr, nullptr); + } + return; } void PostHandle(sqlite3 *db) @@ -421,7 +395,7 @@ void PostHandle(sqlite3 *db) TimeHelper::Initialize(currentMaxTimestamp); RegisterCalcHash(db); RegisterGetSysTime(db); - (void)sqlite3_set_authorizer(db, &ClearTheLogAfterDropTable, db); + (void)sqlite3_set_droptable_handle(db, &ClearTheLogAfterDropTable); (void)sqlite3_busy_timeout(db, BUSY_TIMEOUT); std::string recursiveTrigger = "PRAGMA recursive_triggers = ON;"; (void)ExecuteRawSQL(db, recursiveTrigger); diff --git a/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_operation_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_operation_test.cpp index 4f9fd946f13..9f53f288897 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_operation_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_operation_test.cpp @@ -15,6 +15,7 @@ #include +#include "sqlite_import.h" #include "db_common.h" #include "db_constant.h" #include "distributeddb_data_generate_unit_test.h" @@ -41,6 +42,40 @@ namespace { const std::string SET_USER_VERSION_SQL = "PRAGMA user_version=100;"; const std::string SHA1_ALGO_ATTACH_SQL = "PRAGMA cipher_default_attach_hmac_algo=SHA1;"; const std::string SHA256_ALGO_ATTACH_SQL = "PRAGMA cipher_default_attach_hmac_algo=SHA256;"; + + std::string g_createTableSql1 = R""(create table student_1 ( + id INTEGER PRIMARY KEY, + name STRING, + level INTGER, + score INTGER + ))""; + std::string g_createTableSql2 = R""(create table student_2 ( + id INTEGER, + age STRING + ))""; + std::string g_inerstDataSql1 = "insert into student_1 (id, name, level, score) values (1001, 'xue', 2, 95);"; + std::string g_inerstDataSql2 = "insert into student_1 (id, name, level, score) values (1002, 'xue', 2, 95);"; + std::string g_inerstDataSql3 = "insert into student_2 (id, age) values (1001, 11);"; + std::string g_inerstDataSql4 = "insert into student_2 (id, age) values (1002, 12);"; + std::string g_deleteDataSql = "delete from student_1 where id='1001';"; + std::string g_createViewSql = "create view studentView as select * from student_1;"; + std::string g_createIndexSql = "create index in_id on student_2(id);"; + std::string g_deleteViewSql = "drop view studentView;"; + std::string g_dropTableSql1 = "drop table student_2;"; + std::string g_dropTableSql2 = "drop table student_1;"; + std::string g_dbFile; + std::string g_tableName; + int g_callbackTimes = 0; + void DropCallback(sqlite3 *db, const char *tableName, const char *dbName) + { + auto filepath = sqlite3_db_filename(static_cast(db), dbName); + if (filepath == nullptr) { + return; + } + EXPECT_EQ(g_dbFile, std::string(filepath)); + EXPECT_EQ(g_tableName, std::string(tableName)); + g_callbackTimes++; + } } class DistributedDBStorageDataOperationTest : public testing::Test { @@ -816,4 +851,121 @@ HWTEST_F(DistributedDBStorageDataOperationTest, ShaAlgoEncryptTest004, TestSize. EXPECT_NE(SQLiteUtils::AttachNewDatabase(db, CipherType::AES_256_GCM, g_passwd2, fileUrl, attachName), E_OK); sqlite3_close_v2(db); db = nullptr; +} + +/** + * @tc.name: DeleteTableCallbackTest001 + * @tc.desc: Test drop table callback + * @tc.type: FUNC + * @tc.require: AR000HI2JS + * @tc.author: zhuwentao + */ +HWTEST_F(DistributedDBStorageDataOperationTest, DeleteTableCallbackTest001, TestSize.Level0) +{ + sqlite3 *db = nullptr; + /** + * @tc.steps: step1. use sha256 to open db + * * @tc.expected: step1. interface return ok + */ + uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; + std::string fileUrl = g_testDir + "/DeleteTableCallbackTest001.db"; + EXPECT_EQ(sqlite3_open_v2(fileUrl.c_str(), &db, flag, nullptr), SQLITE_OK); + EXPECT_EQ(SQLiteUtils::SetKeyInner(db, CipherType::AES_256_GCM, g_passwd, DBConstant::DEFAULT_ITER_TIMES), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA256_ALGO_SQL), E_OK); + ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, SET_USER_VERSION_SQL) == E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, USER_VERSION_SQL), E_OK); + EXPECT_EQ(sqlite3_set_droptable_handle(db, DropCallback), E_OK); + /** + * @tc.steps: step1. exec some sql + * * @tc.expected: step1. interface return ok + */ + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createTableSql1), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createTableSql2), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql1), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql2), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql3), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql4), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createViewSql), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createIndexSql), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_deleteViewSql), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_dropIndex), E_OK); + EXPECT_EQ(g_callbackTimes, 0); + g_dbFile = fileUrl; + g_tableName = "student_2"; + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_dropTableSql1), E_OK); + EXPECT_EQ(g_callbackTimes, 1); + g_tableName = "student_1"; + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_dropTableSql2), E_OK); + EXPECT_EQ(g_callbackTimes, 2); + sqlite3_close_v2(db); + db = nullptr; +} + +/** + * @tc.name: DropTableCallbakTest001 + * @tc.desc: Test drop table in attach mode + * @tc.type: FUNC + * @tc.require: AR000HI2JS + * @tc.author: zhuwentao + */ +HWTEST_F(DistributedDBStorageDataOperationTest, DeleteTableCallbackTest002, TestSize.Level0) +{ + sqlite3 *db = nullptr; + g_callbackTimes = 0; + /** + * @tc.steps: step1. use sha256 to open db + * * @tc.expected: step1. interface return ok + */ + uint64_t flag = SQLITE_OPEN_URI | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; + std::string fileUrl = g_testDir + "/DeleteTableCallbackAttachTest002.db"; + EXPECT_EQ(sqlite3_open_v2(fileUrl.c_str(), &db, flag, nullptr), SQLITE_OK); + EXPECT_EQ(SQLiteUtils::SetKeyInner(db, CipherType::AES_256_GCM, g_passwd, DBConstant::DEFAULT_ITER_TIMES), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA256_ALGO_SQL), E_OK); + ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, SET_USER_VERSION_SQL) == E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, USER_VERSION_SQL), E_OK); + EXPECT_EQ(sqlite3_set_droptable_handle(db, DropCallback), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createTableSql1), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createTableSql2), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql1), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql2), E_OK); + /** + * @tc.steps: step2. close db + * * @tc.expected: step2. interface return ok + */ + sqlite3_close_v2(db); + db = nullptr; + /** + * @tc.steps: step3. open new db and attach old db + * * @tc.expected: step3. interface return ok + */ + std::string fileUrl2 = g_testDir + "/DeleteTableCallbackTest002.db"; + EXPECT_EQ(sqlite3_open_v2(fileUrl2.c_str(), &db, flag, nullptr), SQLITE_OK); + EXPECT_EQ(SQLiteUtils::SetKeyInner(db, CipherType::AES_256_GCM, g_passwd2, DBConstant::DEFAULT_ITER_TIMES), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, SHA256_ALGO_SQL), E_OK); + ASSERT_TRUE(SQLiteUtils::ExecuteRawSQL(db, SET_USER_VERSION_SQL) == E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, USER_VERSION_SQL), E_OK); + EXPECT_EQ(sqlite3_set_droptable_handle(db, DropCallback), E_OK); + std::string attachName = "AttachTest002"; + EXPECT_EQ(SQLiteUtils::AttachNewDatabase(db, CipherType::AES_256_GCM, g_passwd, fileUrl, attachName), E_OK); + /** + * @tc.steps: step4. exec some sql + * * @tc.expected: step4. interface return ok + */ + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createTableSql1), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_createTableSql2), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql1), E_OK); + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, g_inerstDataSql2), E_OK); + EXPECT_EQ(g_callbackTimes, 0); + std::string dropTableSql1 = "drop table " + attachName + ".student_2;"; + std::string dropTableSql2 = "drop table student_1;"; + g_dbFile = fileUrl; + g_tableName = "student_2"; + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, dropTableSql1), E_OK); + EXPECT_EQ(g_callbackTimes, 1); + g_dbFile = fileUrl2; + g_tableName = "student_1"; + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, dropTableSql2), E_OK); + EXPECT_EQ(g_callbackTimes, 2); + sqlite3_close_v2(db); + db = nullptr; } \ No newline at end of file diff --git a/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp index fadf3c049fd..8694600d597 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp @@ -1039,6 +1039,40 @@ HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync007, TestSize.Level1) } } +/** +* @tc.name: Normal Sync 008 +* @tc.desc: Test encry db sync for delete table; +* @tc.type: FUNC +* @tc.require: AR000GK58N +* @tc.author: zhuwentao +*/ +HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync008, TestSize.Level0) +{ + /** + * @tc.steps: step1. open rdb store, create distribute table, insert data and sync to deviceB + */ + std::map dataMap; + PrepareEnvironment(dataMap, {g_deviceB}); + BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B}); + CheckVirtualData(dataMap); + /** + * @tc.steps: step2.drop table operation and sync again + */ + sqlite3 *db = nullptr; + EXPECT_EQ(GetDB(db), SQLITE_OK); + std::string dropTableSql = "drop table TEST_TABLE;"; + EXPECT_EQ(SQLiteUtils::ExecuteRawSQL(db, dropTableSql), E_OK); + std::vector remoteDeviceVec = {g_deviceB}; + PrepareBasicTable(g_tableName, g_fieldInfoList, remoteDeviceVec, true); + BlockSync(SyncMode::SYNC_MODE_PUSH_ONLY, OK, {DEVICE_B}); + /** + * @tc.steps: step3.check data in deviceB + */ + std::vector targetData; + g_deviceB->GetAllSyncData(g_tableName, targetData); + ASSERT_EQ(targetData.size(), 0u); +} + /** * @tc.name: Normal Sync 006 * @tc.desc: Test normal pull sync for add data. diff --git a/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.cpp b/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.cpp index 8fd0f06bf60..9fe13315c38 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/syncer/virtual_relational_ver_sync_db_interface.cpp @@ -279,7 +279,9 @@ int VirtualRelationalVerSyncDBInterface::GetAllSyncData(const std::string &table return -E_NOT_FOUND; } for (const auto &entry : syncData_[tableName]) { - data.push_back(entry.second); + if (entry.second.logInfo.flag != DataItem::DELETE_FLAG) { + data.push_back(entry.second); + } } return E_OK; } -- Gitee From cf91b188553ca82238a37922caf8827d9803b3b0 Mon Sep 17 00:00:00 2001 From: zwtmichael Date: Fri, 21 Oct 2022 15:38:36 +0800 Subject: [PATCH 2/2] fix review commitment Signed-off-by: zwtmichael --- frameworks/libs/distributeddb/BUILD.gn | 1 + .../src/relational/relational_store_sqlite_ext.cpp | 4 ++-- frameworks/libs/distributeddb/test/BUILD.gn | 1 + .../storage/distributeddb_storage_data_operation_test.cpp | 3 ++- .../syncer/distributeddb_relational_ver_p2p_sync_test.cpp | 5 +---- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/frameworks/libs/distributeddb/BUILD.gn b/frameworks/libs/distributeddb/BUILD.gn index 4308a9b12c8..1a981ca47b9 100644 --- a/frameworks/libs/distributeddb/BUILD.gn +++ b/frameworks/libs/distributeddb/BUILD.gn @@ -47,6 +47,7 @@ config("distrdb_config") { "RELATIONAL_STORE", "SQLITE_DISTRIBUTE_RELATIONAL", "USE_DFX_ABILITY", + "SQLITE_ENABLE_DROPTABLE_CALLBACK", ] if (is_debug) { defines += [ "TRACE_SQLITE_EXECUTE" ] diff --git a/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp b/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp index b611770d93e..1567afe1bfd 100644 --- a/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp +++ b/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp @@ -357,9 +357,9 @@ int GetCurrentMaxTimestamp(sqlite3 *db, Timestamp &maxTimestamp) return E_OK; } -void ClearTheLogAfterDropTable(sqlite3 *db, const char *tableName, const char *dbName) +void ClearTheLogAfterDropTable(sqlite3 *db, const char *tableName, const char *schemaName) { - if (db == nullptr || tableName == nullptr) { + if (db == nullptr || tableName == nullptr || schemaName == nullptr) { return; } sqlite3_stmt *stmt = nullptr; diff --git a/frameworks/libs/distributeddb/test/BUILD.gn b/frameworks/libs/distributeddb/test/BUILD.gn index 2c57a4e3ecc..cb67e9afb65 100644 --- a/frameworks/libs/distributeddb/test/BUILD.gn +++ b/frameworks/libs/distributeddb/test/BUILD.gn @@ -61,6 +61,7 @@ config("module_private_config") { "SQLITE_DISTRIBUTE_RELATIONAL", "USE_DFX_ABILITY", "TRACE_SQLITE_EXECUTE", + "SQLITE_ENABLE_DROPTABLE_CALLBACK", ] } diff --git a/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_operation_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_operation_test.cpp index 9f53f288897..99d6d94e580 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_operation_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_storage_data_operation_test.cpp @@ -63,6 +63,7 @@ namespace { std::string g_deleteViewSql = "drop view studentView;"; std::string g_dropTableSql1 = "drop table student_2;"; std::string g_dropTableSql2 = "drop table student_1;"; + std::string g_dropIndex = "drop index in_id;"; std::string g_dbFile; std::string g_tableName; int g_callbackTimes = 0; @@ -820,7 +821,7 @@ HWTEST_F(DistributedDBStorageDataOperationTest, ShaAlgoEncryptTest003, TestSize. } /** - * @tc.name: ShaAlgoEncryptTest003 + * @tc.name: ShaAlgoEncryptTest004 * @tc.desc: Test unnormal sql * @tc.type: FUNC * @tc.require: AR000HI2JS diff --git a/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp index 8694600d597..495f9b24719 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/syncer/distributeddb_relational_ver_p2p_sync_test.cpp @@ -976,10 +976,7 @@ HWTEST_F(DistributedDBRelationalVerP2PSyncTest, NormalSync004, TestSize.Level1) std::vector dataList; EXPECT_EQ(g_deviceB->GetAllSyncData(g_tableName, dataList), E_OK); - EXPECT_EQ(static_cast(dataList.size()), 1); - for (const auto &item : dataList) { - EXPECT_EQ(item.logInfo.flag, DataItem::DELETE_FLAG); - } + EXPECT_EQ(static_cast(dataList.size()), 0); } /** -- Gitee