From f94aa48b0379f7d2efad6f37b48897cd2085a3b1 Mon Sep 17 00:00:00 2001 From: wanyi Date: Tue, 30 May 2023 23:34:07 +0800 Subject: [PATCH] Add a flag to distinguish whether the schema has been changed Signed-off-by: wanyi32 --- .../relational/relational_sync_able_storage.h | 2 ++ .../storage/include/cloud/schema_mgr.h | 3 ++ .../storage/src/cloud/schema_mgr.cpp | 33 +++++++++++++++---- .../src/relational_sync_able_storage.cpp | 5 +++ .../relational/sqlite_relational_store.cpp | 1 + ..._cloud_interfaces_relational_sync_test.cpp | 23 ++++++++++--- .../distributeddb_cloud_schema_mgr_test.cpp | 3 +- 7 files changed, 58 insertions(+), 12 deletions(-) diff --git a/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h b/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h index 252dedb7320..2e0b144d7fb 100644 --- a/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h +++ b/frameworks/libs/distributeddb/interfaces/src/relational/relational_sync_able_storage.h @@ -166,6 +166,8 @@ public: void SetSyncAbleEngine(std::shared_ptr syncAbleEngine); + void SetSchemaFlagToChanged(); + private: SQLiteSingleVerRelationalStorageExecutor *GetHandle(bool isWrite, int &errCode, OperatePerm perm = OperatePerm::NORMAL_PERM) const; diff --git a/frameworks/libs/distributeddb/storage/include/cloud/schema_mgr.h b/frameworks/libs/distributeddb/storage/include/cloud/schema_mgr.h index c9fada101f1..ee9638a0a8c 100644 --- a/frameworks/libs/distributeddb/storage/include/cloud/schema_mgr.h +++ b/frameworks/libs/distributeddb/storage/include/cloud/schema_mgr.h @@ -32,6 +32,7 @@ public: std::shared_ptr GetCloudDbSchema(); int GetCloudTableSchema(const TableName &tableName, TableSchema &retSchema); int ChkSchema(const TableName &tableName, RelationalSchemaObject &localSchema); + void SetFlagToChanged(); private: bool IsAssetPrimaryField(const Field &cloudField); @@ -41,6 +42,8 @@ private: int CompareFieldSchema(std::map &primaryKeys, FieldInfoMap &localFields, std::vector &cloudFields); std::shared_ptr cloudSchema_ = nullptr; + std::map lastCheckResult_; + bool hasChanged_ = true; }; } // namespace DistributedDB diff --git a/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp b/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp index e1f63c4b865..cf70a8c754e 100644 --- a/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp +++ b/frameworks/libs/distributeddb/storage/src/cloud/schema_mgr.cpp @@ -20,42 +20,61 @@ #include "cloud/cloud_db_constant.h" #include "cloud/cloud_store_types.h" #include "db_common.h" -#include "db_errno.h" + namespace DistributedDB { SchemaMgr::SchemaMgr() { } +void SchemaMgr::SetFlagToChanged() +{ + lastCheckResult_.clear(); + hasChanged_ = true; +} + int SchemaMgr::ChkSchema(const TableName &tableName, RelationalSchemaObject &localSchema) { + if (!hasChanged_ && lastCheckResult_.find(tableName) != lastCheckResult_.end()) { + return lastCheckResult_[tableName]; + } + hasChanged_ = false; if (cloudSchema_ == nullptr) { LOGE("Cloud schema has not been set"); - return -E_SCHEMA_MISMATCH; + lastCheckResult_[tableName] = -E_SCHEMA_MISMATCH; + return lastCheckResult_[tableName]; } TableInfo tableInfo = localSchema.GetTable(tableName); if (tableInfo.Empty()) { LOGE("Local schema does not contain certain table:%d", -E_SCHEMA_MISMATCH); - return -E_SCHEMA_MISMATCH; + lastCheckResult_[tableName] = -E_SCHEMA_MISMATCH; + return lastCheckResult_[tableName]; } if (tableInfo.GetTableSyncType() != TableSyncType::CLOUD_COOPERATION) { LOGE("Sync type of local table is not CLOUD_COOPERATION:%d", -E_SCHEMA_MISMATCH); - return -E_SCHEMA_MISMATCH; + lastCheckResult_[tableName] = -E_SCHEMA_MISMATCH; + return lastCheckResult_[tableName]; } TableSchema cloudTableSchema; int ret = GetCloudTableSchema(tableName, cloudTableSchema); if (ret != E_OK) { LOGE("Cloud schema does not contain certain table:%d", -E_SCHEMA_MISMATCH); - return -E_SCHEMA_MISMATCH; + lastCheckResult_[tableName] = -E_SCHEMA_MISMATCH; + return lastCheckResult_[tableName]; } std::map primaryKeys = tableInfo.GetPrimaryKey(); FieldInfoMap localFields = tableInfo.GetFields(); - return CompareFieldSchema(primaryKeys, localFields, cloudTableSchema.fields); + lastCheckResult_[tableName] = CompareFieldSchema(primaryKeys, localFields, cloudTableSchema.fields); + return lastCheckResult_[tableName]; } int SchemaMgr::CompareFieldSchema(std::map &primaryKeys, FieldInfoMap &localFields, std::vector &cloudFields) { std::unordered_set cloudColNames; + if (cloudFields.size() > localFields.size()) { + LOGE("Cloud schema has more fields than local schema: %d", -E_SCHEMA_MISMATCH); + return -E_SCHEMA_MISMATCH; + } for (const Field &cloudField : cloudFields) { if (localFields.find(cloudField.colName) == localFields.end()) { LOGE("Column name mismatch between local and cloud schema: %d", -E_SCHEMA_MISMATCH); @@ -93,6 +112,7 @@ int SchemaMgr::CompareFieldSchema(std::map &primaryKeys, FieldIn return -E_SCHEMA_MISMATCH; } } + LOGD("Schema is matched"); return E_OK; } @@ -148,6 +168,7 @@ bool SchemaMgr::ComparePrimaryField(std::map &localPrimaryKeys, void SchemaMgr::SetCloudDbSchema(const DataBaseSchema &schema) { cloudSchema_ = std::make_shared(schema); + SetFlagToChanged(); } std::shared_ptr SchemaMgr::GetCloudDbSchema() diff --git a/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp b/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp index bbddb4a42bb..dbf94f6def1 100644 --- a/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp +++ b/frameworks/libs/distributeddb/storage/src/relational_sync_able_storage.cpp @@ -1196,5 +1196,10 @@ void RelationalSyncAbleStorage::SetSyncAbleEngine(std::shared_ptrSetSchemaFlagToChanged(); storageEngine_->NotifySchemaChanged(); } return errCode; diff --git a/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp index b1a9c5fd181..45299467298 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/storage/cloud/distributeddb_cloud_interfaces_relational_sync_test.cpp @@ -91,15 +91,17 @@ namespace { "photo BLOB ," \ "asserts BLOB," \ "age INT);"; + const std::string ADD_COLUMN_SQL = + "ALTER TABLE " + g_tableName4 + " ADD COLUMN money INT;"; const std::vector g_cloudFiled1 = { {"name", TYPE_INDEX, true}, {"height", TYPE_INDEX}, {"married", TYPE_INDEX}, {"photo", TYPE_INDEX, false, false}, {"assert", TYPE_INDEX}, {"age", TYPE_INDEX} }; const std::vector g_invalidCloudFiled1 = { - {"name", TYPE_INDEX, true}, {"height", TYPE_INDEX}, + {"name", TYPE_INDEX, true}, {"height", TYPE_INDEX}, {"married", TYPE_INDEX}, {"photo", TYPE_INDEX, false, false}, - {"assert", TYPE_INDEX}, {"age", TYPE_INDEX} + {"assert", TYPE_INDEX, true}, {"age", TYPE_INDEX} }; const std::vector g_cloudFiled2 = { {"id", TYPE_INDEX, true}, {"name", TYPE_INDEX}, @@ -640,7 +642,7 @@ namespace { .fields = g_invalidCloudFiled1 }; TableSchema tableSchema2 = { - .name = g_tableName1, + .name = g_tableName2, .fields = g_cloudFiled2 }; dataBaseSchema.tables.push_back(tableSchema1); @@ -2549,8 +2551,19 @@ HWTEST_F(DistributedDBCloudInterfacesRelationalSyncTest, SchemaTest001, TestSize EXPECT_EQ(RelationalTestUtils::ExecSql(db, INTEGER_PRIMARY_KEY_TABLE_SQL_WRONG_SYNC_MODE), SQLITE_OK); ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName4, CLOUD_COOPERATION), DBStatus::OK); /** - * @tc.steps:step1. do sync - * @tc.expected: step1. return ok. + * @tc.steps:step2. do sync + * @tc.expected: step2. return ok. + */ + callSync({g_tableName4}, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); + /** + * @tc.steps:step3. Add a column to change local schema + * @tc.expected: step3. return ok. + */ + EXPECT_EQ(RelationalTestUtils::ExecSql(db, ADD_COLUMN_SQL), SQLITE_OK); + ASSERT_EQ(g_delegate->CreateDistributedTable(g_tableName4, CLOUD_COOPERATION), DBStatus::OK); + /** + * @tc.steps:step4. do sync again, observe log table and we will find that it has compare the schema again + * @tc.expected: step4. return OK. */ callSync({g_tableName4}, SYNC_MODE_CLOUD_MERGE, DBStatus::OK); CloseDb(); diff --git a/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp b/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp index 35aa24865e3..43bbd9b34bd 100644 --- a/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp +++ b/frameworks/libs/distributeddb/test/unittest/common/storage/distributeddb_cloud_schema_mgr_test.cpp @@ -455,7 +455,7 @@ HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest008, TestSize.Level0) } /** - * @tc.name: SchemaMgrTest008 + * @tc.name: SchemaMgrTest009 * @tc.desc: Test schema mgr with empty local schema * @tc.type: FUNC * @tc.require: @@ -584,6 +584,7 @@ HWTEST_F(DistributedDBCloudSchemaMgrTest, SchemaMgrTest013, TestSize.Level0) table.SetPrimaryKey(FIELD_NAME_1, 1); RelationalSchemaObject localSchemaWithAssetPrimary; localSchemaWithAssetPrimary.AddRelationalTable(table); + g_schemaMgr->SetFlagToChanged(); EXPECT_EQ(g_schemaMgr->ChkSchema(TABLE_NAME_4, localSchemaWithAssetPrimary), -E_SCHEMA_MISMATCH); } } \ No newline at end of file -- Gitee