From b34126bcfa2c599599a437aa374a668e024abd13 Mon Sep 17 00:00:00 2001 From: lobty Date: Wed, 3 Sep 2025 09:34:09 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=8A=A0=E5=9B=BA=E4=BF=9D=E6=8A=A4extend?= =?UTF-8?q?=5Ffield=20{}=E7=9A=84=E5=9C=BA=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lobty --- .../common/src/relational/table_info.cpp | 3 ++ .../common/src/relational/tracker_table.cpp | 4 +- .../cloud_sync_log_table_manager.cpp | 2 +- .../sqlite_relational_utils_client.cpp | 2 +- ...single_ver_relational_storage_executor.cpp | 2 +- ...ver_relational_storage_extend_executor.cpp | 6 ++- ...stributeddb_interfaces_relational_test.cpp | 2 +- ...terfaces_relational_tracker_table_test.cpp | 4 +- .../rdb/distributeddb_rdb_upgrade_test.cpp | 42 +++++++++++++++++-- 9 files changed, 54 insertions(+), 13 deletions(-) diff --git a/frameworks/libs/distributeddb/common/src/relational/table_info.cpp b/frameworks/libs/distributeddb/common/src/relational/table_info.cpp index 99f9ce13845..7e583f7d2df 100644 --- a/frameworks/libs/distributeddb/common/src/relational/table_info.cpp +++ b/frameworks/libs/distributeddb/common/src/relational/table_info.cpp @@ -806,6 +806,9 @@ int TableInfo::CheckTrackerTable() return -E_SCHEMA_MISMATCH; } } + if (trackerTable_.GetExtendNames().empty()) { + LOGW("[%s [%zu]] extend col not set.", tableName.c_str(), nameLength); + } for (const auto &colName : trackerTable_.GetExtendNames()) { if (colName.empty()) { LOGE("[%s [%zu]] extend col cannot be empty.", tableName.c_str(), nameLength); diff --git a/frameworks/libs/distributeddb/common/src/relational/tracker_table.cpp b/frameworks/libs/distributeddb/common/src/relational/tracker_table.cpp index d5b2c5468cf..3277b434c94 100644 --- a/frameworks/libs/distributeddb/common/src/relational/tracker_table.cpp +++ b/frameworks/libs/distributeddb/common/src/relational/tracker_table.cpp @@ -50,7 +50,7 @@ bool IsInvalidExtendColNames(const std::set &extendColNames) const std::string GetJsonAssignValSql(bool isDelete, const std::set &extendColNames) { if (extendColNames.empty()) { - return "''"; + return "'{}'"; } std::string newOrOld = isDelete ? "OLD." : "NEW."; std::string sql = "json_object("; @@ -67,7 +67,7 @@ const std::string TrackerTable::GetAssignValSql(bool isDelete) const if (!extendColNames_.empty() && !IsInvalidExtendColNames(extendColNames_)) { return GetJsonAssignValSql(isDelete, extendColNames_); } - return "''"; + return "'{}'"; } const std::string TrackerTable::GetExtendAssignValSql(bool isDelete) const diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/relational/cloud_sync_log_table_manager.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/relational/cloud_sync_log_table_manager.cpp index f58feb79f0d..7d5c447e3a1 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/relational/cloud_sync_log_table_manager.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/relational/cloud_sync_log_table_manager.cpp @@ -209,7 +209,7 @@ std::vector CloudSyncLogTableManager::GetDropTriggers(const TableIn dropTriggers.emplace_back(updateTrigger); dropTriggers.emplace_back(deleteTrigger); if (table.GetTrackerTable().IsEmpty()) { - std::string clearExtendSql = "UPDATE " + GetLogTableName(table) + " SET extend_field = '';"; + std::string clearExtendSql = "UPDATE " + GetLogTableName(table) + " SET extend_field = '{}';"; dropTriggers.emplace_back(clearExtendSql); } return dropTriggers; diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils_client.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils_client.cpp index ecd4464ab59..d56bbecefd7 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils_client.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils_client.cpp @@ -215,7 +215,7 @@ std::string SQLiteRelationalUtils::GetExtendValue(const TrackerTable &trackerTab extendValue.pop_back(); extendValue += ")"; } else { - extendValue = "''"; + extendValue = "'{}'"; } return extendValue; } diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor.cpp index 8fa74fa878b..fd2d12315ea 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_executor.cpp @@ -201,7 +201,7 @@ int SQLiteSingleVerRelationalStorageExecutor::UpdateTrackerTable(sqlite3 *db, co std::string calPrimaryKeyHash = logMgrPtr->CalcPrimaryKeyHash("a.", tableInfo, identity); std::string sql = "INSERT OR REPLACE INTO " + logTable + " SELECT " + rowid + ", '', '', " + currentLocalTimeStr + " + " + rowid + ", " + currentLocalTimeStr + " + " + rowid + ", " + flag + ", " + calPrimaryKeyHash + - ", '', '', '', '', '', 0 FROM '" + tableName + "' AS a WHERE 1=1;"; + ", '', '{}', '', '', '', 0 FROM '" + tableName + "' AS a WHERE 1=1;"; errCode = trackerTable.ReBuildTempTrigger(db, TriggerMode::TriggerModeEnum::INSERT, [db, &sql]() { int ret = SQLiteUtils::ExecuteRawSQL(db, sql); if (ret != E_OK) { diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_extend_executor.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_extend_executor.cpp index dad090304ca..6d67e5a4df8 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_extend_executor.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_ver_relational_storage_extend_executor.cpp @@ -2049,7 +2049,8 @@ void SQLiteSingleVerRelationalStorageExecutor::RecoverNullExtendLog(const Tracke return; } std::string sql = "SELECT COUNT(1) FROM " + DBCommon::GetLogTableName(trackerSchema.tableName) + - " WHERE (json_valid(extend_field) = 0 OR json_type(extend_field) IS NOT 'object') AND data_key != -1"; + " WHERE (json_valid(extend_field) = 0 OR json_type(extend_field) IS NOT 'object' OR" + + " json_extract(extend_field, '$') = '{}') AND data_key != -1"; if (!SQLiteRelationalUtils::ExecuteCheckSql(dbHandle_, sql).second) { return; } @@ -2083,7 +2084,8 @@ int SQLiteSingleVerRelationalStorageExecutor::RecoverNullExtendLogInner(const Tr }); actions.emplace_back([this, &trackerSchema]() { return UpdateExtendField(trackerSchema.tableName, trackerSchema.extendColNames, - " AND (json_valid(log.extend_field) = 0 OR json_type(log.extend_field) IS NOT 'object')"); + " AND (json_valid(log.extend_field) = 0 OR json_type(log.extend_field) IS NOT 'object' OR" + " json_extract(extend_field, '$') = '{}')"); }); actions.emplace_back([this]() { return ClearAllTempSyncTrigger(); diff --git a/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp index c89e04dbb7a..73468efac24 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_test.cpp @@ -2102,7 +2102,7 @@ HWTEST_F(DistributedDBInterfacesRelationalTest, CreateDistributedTableTest007, T int64_t actualStatus = sqlite3_column_int64(stmt, 3); // index 3 is status EXPECT_EQ(actualFlag, static_cast(LogInfoFlag::FLAG_LOCAL) | static_cast(LogInfoFlag::FLAG_DEVICE_CLOUD_INCONSISTENCY)); - EXPECT_EQ(actualExtendVal, ""); + EXPECT_EQ(actualExtendVal, "{}"); EXPECT_EQ(actualCursor, actualCount); EXPECT_EQ(actualStatus, 0); } diff --git a/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_tracker_table_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_tracker_table_test.cpp index a8da478f2ef..9ed60327687 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_tracker_table_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_relational_tracker_table_test.cpp @@ -1163,7 +1163,7 @@ HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest020, * @tc.expected: step3. Return OK. */ sql = "select count(*) from " + DBCommon::GetLogTableName(TABLE_NAME2) + - " where extend_field is NULL " + " AND cursor is NULL"; + " where extend_field is NULL OR cursor is NULL OR json_extract(extend_field, '$') = '{}'"; EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast(0), nullptr), SQLITE_OK); @@ -1174,7 +1174,7 @@ HWTEST_F(DistributedDBInterfacesRelationalTrackerTableTest, TrackerTableTest020, schema.extendColNames = {EXTEND_COL_NAME3}; EXPECT_EQ(g_delegate->SetTrackerTable(schema), OK); sql = "select count(*) from " + std::string(DBConstant::RELATIONAL_PREFIX) + TABLE_NAME2 + - "_log where extend_field is NULL " + " AND cursor is NULL"; + "_log where extend_field is NULL OR cursor is NULL OR json_extract(extend_field, '$') = '{}'"; EXPECT_EQ(sqlite3_exec(g_db, sql.c_str(), CloudDBSyncUtilsTest::QueryCountCallback, reinterpret_cast(0), nullptr), SQLITE_OK); CloseStore(); diff --git a/frameworks/libs/distributeddb/test/unittest/common/store_test/rdb/distributeddb_rdb_upgrade_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/store_test/rdb/distributeddb_rdb_upgrade_test.cpp index f3c51b4034b..e19bad402c4 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/store_test/rdb/distributeddb_rdb_upgrade_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/store_test/rdb/distributeddb_rdb_upgrade_test.cpp @@ -132,17 +132,53 @@ HWTEST_F(DistributedDBRDBUpgradeTest, UpgradeTracker002, TestSize.Level0) * @tc.steps: step2. Insert local data and log update extend_field to empty str. * @tc.expected: step2. Ok */ - InsertLocalDBData(0, 1, info1); + int chkCnt = 10; + InsertLocalDBData(0, chkCnt, info1); std::string sql = "UPDATE " + DBCommon::GetLogTableName(DEVICE_SYNC_TABLE) + " SET extend_field=''"; EXPECT_EQ(ExecuteSQL(sql, info1), E_OK); + sql = "UPDATE " + DBCommon::GetLogTableName(DEVICE_SYNC_TABLE) + " SET extend_field='{}' where data_key > 5"; + EXPECT_EQ(ExecuteSQL(sql, info1), E_OK); EXPECT_EQ(CountTableData(info1, DBCommon::GetLogTableName(DEVICE_SYNC_TABLE), - " json_valid(extend_field) = 0"), 1); + " json_valid(extend_field) = 0 OR json_extract(extend_field, '$') = '{}'"), chkCnt); /** * @tc.steps: step3. Set tracker again and check log. * @tc.expected: step3. Ok */ EXPECT_EQ(SetTrackerTables(info1, {DEVICE_SYNC_TABLE}), E_OK); EXPECT_EQ(CountTableData(info1, DBCommon::GetLogTableName(DEVICE_SYNC_TABLE), - " json_valid(extend_field) = 0"), 0); + " json_valid(extend_field) = 0 OR json_extract(extend_field, '$') = '{}'"), 0); +} + +/** + * @tc.name: UpgradeTracker003 + * @tc.desc: Test extend col names was not set. + * @tc.type: FUNC + * @tc.author: bty + */ +HWTEST_F(DistributedDBRDBUpgradeTest, UpgradeTracker003, TestSize.Level0) +{ + /** + * @tc.steps: step1. Init delegate and set tracker schema. + * @tc.expected: step1. Ok + */ + ASSERT_NO_FATAL_FAILURE(InitUpgradeDelegate()); + auto info1 = GetStoreInfo1(); + EXPECT_EQ(SetTrackerTables(info1, {DEVICE_SYNC_TABLE}), E_OK); + /** + * @tc.steps: step2. Insert local data and not set extend col names. + * @tc.expected: step2. Ok + */ + int chkCnt = 10; + InsertLocalDBData(0, chkCnt, info1); + auto trackerSchema = GetAllTrackerSchema(info1, {DEVICE_SYNC_TABLE}); + auto store = GetDelegate(info1); + ASSERT_NE(store, nullptr); + for (const auto &trackerTable : trackerSchema) { + auto temp = trackerTable; + temp.extendColNames = {}; + EXPECT_EQ(store->SetTrackerTable(temp), E_OK); + } + EXPECT_EQ(CountTableData(info1, DBCommon::GetLogTableName(DEVICE_SYNC_TABLE), + " json_extract(extend_field, '$') = '{}'"), chkCnt); } } \ No newline at end of file -- Gitee From 9575c345f51a925cf2ffa1a73305cf838116929e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BB=96=E6=B0=B8=E7=85=8C?= Date: Tue, 9 Sep 2025 17:01:37 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E3=80=90=E5=AE=A2=E6=88=B7=E7=AB=AF?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E3=80=91=E4=BF=AE=E5=A4=8D=E4=BA=8B=E5=8A=A1?= =?UTF-8?q?=E4=B8=AD=E5=88=9B=E5=BB=BA=E6=96=B0=E8=A1=A8=E5=B9=B6=E6=8F=92?= =?UTF-8?q?=E5=85=A5=E6=95=B0=E6=8D=AE=E6=B2=A1=E6=9C=89=E9=80=9A=E5=91=8A?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 廖永煌 --- .../relational_store_sqlite_ext.cpp | 60 ++++++------------- ...b_cloud_interfaces_relational_ext_test.cpp | 41 +++++++++++++ 2 files changed, 60 insertions(+), 41 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 e1f0b50d0d2..8e4882c404b 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 @@ -434,9 +434,6 @@ std::map>> g_storeObserver std::mutex g_storeChangedDataMutex; std::map> g_storeChangedDataMap; -std::mutex g_clientCreateTableMutex; -std::set g_clientCreateTable; - std::mutex g_registerSqliteHookMutex; std::mutex g_createTempTriggerMutex; @@ -964,17 +961,25 @@ int GetTriggerSqls(sqlite3 *db, const std::map &tableInfos, s return E_OK; } -int AuthorizerCallback([[gnu::unused]] void *data, int operation, const char *tableNameChar, const char *, const char *, - const char *) +int TraceCallback(uint32_t traceType, void *traceData, void *stmt, void*) { - if (operation != SQLITE_CREATE_TABLE || tableNameChar == nullptr) { + if (traceType != SQLITE_TRACE_PROFILE || traceData == nullptr || stmt == nullptr) { return SQLITE_OK; } - std::lock_guard clientCreateTableLock(g_clientCreateTableMutex); - std::string tableName = static_cast(tableNameChar); - if (ParamCheckUtils::CheckRelationalTableName(tableName) && tableName.find("sqlite_") != 0 && - tableName.find("naturalbase_") != 0) { - g_clientCreateTable.insert(tableName); + auto statement = static_cast(stmt); + const char *sql = sqlite3_sql(statement); + if (sql == nullptr) { + return SQLITE_OK; + } + std::string sqlStr(sql); + std::transform(sqlStr.begin(), sqlStr.end(), sqlStr.begin(), ::tolower); + if (sqlStr.find("create table ") == std::string::npos) { + return SQLITE_OK; + } + auto db = static_cast(traceData); + int errCode = CreateDataChangeTempTrigger(db); + if (errCode != OK) { + LOGE("Create temp data change trigger failed after create table: %d", errCode); } return SQLITE_OK; } @@ -1029,34 +1034,6 @@ void StoreObserverCallback(sqlite3 *db, const std::string &hashFileName) } } TriggerObserver(storeObserver, hashFileName); - std::map tableInfos; - { - std::lock_guard clientCreateTableLock(g_clientCreateTableMutex); - if (g_clientCreateTable.empty()) { - return; - } - for (const auto &tableName : g_clientCreateTable) { - bool isRowid = true; - std::string type = ""; - JudgeIfGetRowid(db, tableName, type, isRowid); - tableInfos.insert(std::make_pair(tableName, isRowid)); - } - g_clientCreateTable.clear(); - } - std::vector triggerSqls; - int errCode = GetTriggerSqls(db, tableInfos, triggerSqls); - if (errCode != E_OK) { - LOGE("Get data change trigger sql failed %d", errCode); - return; - } - for (const auto &sql : triggerSqls) { - errCode = SQLiteUtils::ExecuteRawSQL(db, sql); - if (errCode != E_OK) { - LOGE("Create data change trigger failed %d", errCode); - return; - } - } - return; } int LogCommitHookCallback(void *data, sqlite3 *db, const char *zDb, int size) @@ -1138,7 +1115,7 @@ int RegisterDataChangeObserver(sqlite3 *db) void RegisterCommitAndRollbackHook(sqlite3 *db) { - sqlite3_set_authorizer(db, AuthorizerCallback, nullptr); + sqlite3_trace_v2(db, SQLITE_TRACE_PROFILE, TraceCallback, (void*)db); } int ResetStatement(sqlite3_stmt *&stmt) @@ -1665,7 +1642,6 @@ void PostHandle(bool isExists, sqlite3 *db) RegisterGetRawSysTime(db); RegisterCloudDataChangeObserver(db); RegisterDataChangeObserver(db); - RegisterCommitAndRollbackHook(db); (void)sqlite3_set_droptable_handle(db, &ClearTheLogAfterDropTable); (void)sqlite3_busy_timeout(db, BUSY_TIMEOUT); std::string recursiveTrigger = "PRAGMA recursive_triggers = ON;"; @@ -1913,6 +1889,8 @@ DB_API DistributedDB::DBStatus RegisterStoreObserver(sqlite3 *db, const std::sha return DistributedDB::DB_ERROR; } + RegisterCommitAndRollbackHook(db); + std::lock_guard lock(g_storeObserverMutex); if (std::find(g_storeObserverMap[hashFileName].begin(), g_storeObserverMap[hashFileName].end(), storeObserver) != g_storeObserverMap[hashFileName].end()) { diff --git a/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp index 377d475d5c5..2d2baeb3082 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/interfaces/distributeddb_cloud_interfaces_relational_ext_test.cpp @@ -1742,6 +1742,47 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTes EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); } +/** + * @tc.name: RegisterStoreObserverTest008 + * @tc.desc: Test store observer in transaction + * @tc.type: FUNC + * @tc.require: + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBCloudInterfacesRelationalExtTest, RegisterStoreObserverTest008, TestSize.Level1) +{ + /** + * @tc.steps:step1. prepare db. + * @tc.expected: step1. return ok. + */ + sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + EXPECT_NE(db, nullptr); + auto storeObserver = std::make_shared(); + EXPECT_EQ(RegisterStoreObserver(db, storeObserver), OK); + RegisterDbHook(db); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); + /** + * @tc.steps:step2. create tables and insert data in transaction. + * @tc.expected: step2. return ok. + */ + g_changedData.clear(); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "begin;"), SQLITE_OK); + std::string tableName = "primary_test"; + CreateTableForStoreObserver(db, tableName); + uint32_t dataCounts = 10; // 10 is count of insert options. + for (uint32_t i = 0; i < dataCounts; i++) { + std::string sql = "insert into " + tableName + " VALUES(" + std::to_string(i + 1) + ", 'zhangsan" + + std::to_string(i + 1) + "');"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), E_OK); + } + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "commit;"), SQLITE_OK); + std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_TIME)); + ASSERT_EQ(g_changedData.size(), 1u); // 1 table insert data + EXPECT_EQ(g_changedData.front().tableName, tableName); + ASSERT_EQ(g_changedData.front().primaryData[OP_INSERT].size(), dataCounts); + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); +} + /** * @tc.name: AbnormalDelegateImplTest001 * @tc.desc: Test delegateImpl interface after delegate is closed -- Gitee