From 2396c11ec87d52efea6b55afbcbfccf40c8e7d7c Mon Sep 17 00:00:00 2001 From: liao-yonghuang Date: Fri, 21 Nov 2025 16:09:32 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E8=87=AA=E5=AE=9A=E4=B9=89=E8=A7=A3?= =?UTF-8?q?=E5=86=B2=E7=AA=81=E3=80=91=E3=80=90bugfix=E3=80=91=E4=BF=AE?= =?UTF-8?q?=E5=A4=8Dschema=E5=90=8C=E6=97=B6=E6=9C=89=E4=B8=BB=E9=94=AE?= =?UTF-8?q?=E5=92=8Cunique=E5=88=97=E6=97=B6=E5=90=8C=E6=AD=A5=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liao-yonghuang --- .../include/cloud/cloud_storage_utils.h | 3 +- .../storage/src/cloud/cloud_storage_utils.cpp | 37 +++++++----- ...istributeddb_rdb_conflict_handler_test.cpp | 58 +++++++++++++++++++ 3 files changed, 84 insertions(+), 14 deletions(-) diff --git a/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h b/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h index 3113d96ab46..c264c2558b8 100644 --- a/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h +++ b/frameworks/libs/distributeddb/storage/include/cloud/cloud_storage_utils.h @@ -50,7 +50,8 @@ public: std::vector &value); static std::set GetCloudPrimaryKey(const TableSchema &tableSchema); - static std::vector GetCloudPrimaryKeyField(const TableSchema &tableSchema, bool sortByName = false); + static std::vector GetCloudPrimaryKeyField(const TableSchema &tableSchema); + static std::vector GetCloudPrimaryKeyField(const TableSchema &tableSchema, bool sortByName); static std::map GetCloudPrimaryKeyFieldMap(const TableSchema &tableSchema, bool sortByUpper = false); static bool IsContainsPrimaryKey(const TableSchema &tableSchema); diff --git a/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp b/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp index db2a8c968ab..5b2e25510ca 100644 --- a/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp +++ b/frameworks/libs/distributeddb/storage/src/cloud/cloud_storage_utils.cpp @@ -203,11 +203,10 @@ int CloudStorageUtils::BindAsset(int index, const VBucket &vBucket, const Field std::set CloudStorageUtils::GetCloudPrimaryKey(const TableSchema &tableSchema) { + std::vector pkVec = GetCloudPrimaryKeyField(tableSchema); std::set pkSet; - for (const auto &field : tableSchema.fields) { - if (field.primary || field.dupCheckCol) { - pkSet.insert(field.colName); - } + for (const auto &field : pkVec) { + pkSet.insert(field.colName); } return pkSet; } @@ -224,14 +223,27 @@ std::vector CloudStorageUtils::GetCloudAsset(const TableSchema &tableSche return assetFields; } -std::vector CloudStorageUtils::GetCloudPrimaryKeyField(const TableSchema &tableSchema, bool sortByName) +std::vector CloudStorageUtils::GetCloudPrimaryKeyField(const TableSchema &tableSchema) { std::vector pkVec; + std::vector dupCheckColVec; for (const auto &field : tableSchema.fields) { - if (field.primary || field.dupCheckCol) { + if (field.primary) { pkVec.push_back(field); } + if (field.dupCheckCol) { + dupCheckColVec.push_back(field); + } + } + if (dupCheckColVec.empty()) { + return pkVec; } + return dupCheckColVec; +} + +std::vector CloudStorageUtils::GetCloudPrimaryKeyField(const TableSchema &tableSchema, bool sortByName) +{ + std::vector pkVec = GetCloudPrimaryKeyField(tableSchema); if (sortByName) { std::sort(pkVec.begin(), pkVec.end(), [](const Field &a, const Field &b) { return a.colName < b.colName; @@ -243,14 +255,13 @@ std::vector CloudStorageUtils::GetCloudPrimaryKeyField(const TableSchema std::map CloudStorageUtils::GetCloudPrimaryKeyFieldMap(const TableSchema &tableSchema, bool sortByUpper) { + std::vector pkVec = GetCloudPrimaryKeyField(tableSchema); std::map pkMap; - for (const auto &field : tableSchema.fields) { - if (field.primary || field.dupCheckCol) { - if (sortByUpper) { - pkMap[DBCommon::ToUpperCase(field.colName)] = field; - } else { - pkMap[field.colName] = field; - } + for (const auto &field : pkVec) { + if (sortByUpper) { + pkMap[DBCommon::ToUpperCase(field.colName)] = field; + } else { + pkMap[field.colName] = field; } } return pkMap; diff --git a/frameworks/libs/distributeddb/test/unittest/common/store_test/rdb/distributeddb_rdb_conflict_handler_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/store_test/rdb/distributeddb_rdb_conflict_handler_test.cpp index c5ee540446b..10583ede50a 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/store_test/rdb/distributeddb_rdb_conflict_handler_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/store_test/rdb/distributeddb_rdb_conflict_handler_test.cpp @@ -253,6 +253,64 @@ HWTEST_F(DistributedDBRDBConflictHandlerTest, SimpleSync005, TestSize.Level0) "intCol=2 AND stringCol1='upsert' AND uuidCol='uuid2' AND stringCol2='upsert'"), 1); } +/** + * @tc.name: SimpleSync006 + * @tc.desc: Test set both primary key and unique column in the schema and sync. + * @tc.type: FUNC + * @tc.author: liaoyonghuang + */ +HWTEST_F(DistributedDBRDBConflictHandlerTest, SimpleSync006, TestSize.Level0) +{ + /** + * @tc.steps:step1. Prepare table + * @tc.expected: step1. Return OK. + */ + std::string tableName = "CLOUD_SYNC_TABLE_B"; + std::string sql = "CREATE TABLE IF NOT EXISTS " + tableName + "(" + "id INTEGER PRIMARY KEY NOT NULL, intCol INTEGER, stringCol1 TEXT, stringCol2 TEXT, uuidCol TEXT UNIQUE)"; + EXPECT_EQ(ExecuteSQL(sql, info1_), E_OK); + EXPECT_EQ(ExecuteSQL(sql, info2_), E_OK); + const std::vector filedInfo = { + {{"id", TYPE_INDEX, true, false}, false}, + {{"intCol", TYPE_INDEX, false, true}, false}, + {{"stringCol1", TYPE_INDEX, false, true}, false}, + {{"uuidCol", TYPE_INDEX, false, true, true}, false}, + }; + UtDateBaseSchemaInfo schemaInfo = { + .tablesInfo = { + {.name = tableName, .fieldInfo = filedInfo} + } + }; + RDBGeneralUt::SetSchemaInfo(info1_, schemaInfo); + RDBGeneralUt::SetSchemaInfo(info2_, schemaInfo); + RDBGeneralUt::SetCloudDbConfig(info1_); + RDBGeneralUt::SetCloudDbConfig(info2_); + ASSERT_EQ(SetDistributedTables(info1_, {tableName}, TableSyncType::CLOUD_COOPERATION), E_OK); + ASSERT_EQ(SetDistributedTables(info2_, {tableName}, TableSyncType::CLOUD_COOPERATION), E_OK); + SetCloudConflictHandler(info2_, [](const std::string &, const VBucket &, const VBucket &, VBucket &) { + return ConflictRet::UPSERT; + }); + + /** + * @tc.steps:step2. Prepare data and sync + * @tc.expected: step2. Return OK. + */ + sql = "INSERT INTO " + tableName + " VALUES(1, 1, 'text1', 'text2', 'uuid1')"; + auto ret = ExecuteSQL(sql, info1_); + ASSERT_EQ(ret, E_OK); + sql = "INSERT INTO " + tableName + " VALUES(1, 1, 'text3', 'text4', 'uuid1')"; + ret = ExecuteSQL(sql, info2_); + ASSERT_EQ(ret, E_OK); + + Query query = Query::Select().FromTable({tableName}); + EXPECT_NO_FATAL_FAILURE(CloudBlockSync(info2_, query, SyncMode::SYNC_MODE_CLOUD_CUSTOM_PUSH, OK, OK)); + EXPECT_NO_FATAL_FAILURE(CloudBlockSync(info1_, query, SyncMode::SYNC_MODE_CLOUD_MERGE, OK, OK)); + EXPECT_EQ(CountTableData(info1_, tableName, + "id = 1 AND intCol=1 AND stringCol1='text1' AND uuidCol='uuid1' AND stringCol2='text2'"), 0); + EXPECT_EQ(CountTableData(info1_, tableName, + "id = 1 AND intCol=1 AND stringCol1='text3' AND uuidCol='uuid1' AND stringCol2='text2'"), 1); +} + void DistributedDBRDBConflictHandlerTest::AbortCloudSyncTest(const std::function &forkFunc, const std::function &cancelForkFunc, SyncMode mode) { -- Gitee