From 9b8ef2ad47727f0d36c3c0d373e2b69bf9c96067 Mon Sep 17 00:00:00 2001 From: lianhuix Date: Thu, 5 May 2022 17:04:49 +0800 Subject: [PATCH 1/9] Add single table mode interface Signed-off-by: lianhuix --- .../libs/distributeddb/include/types_export.h | 6 ++++++ .../include/relational/relational_store_delegate.h | 1 + .../interfaces/src/relational/relational_store_manager.cpp | 1 + .../distributeddb/storage/include/relationaldb_properties.h | 2 ++ .../distributeddb/storage/src/relationaldb_properties.cpp | 2 ++ 5 files changed, 12 insertions(+) diff --git a/services/distributeddataservice/libs/distributeddb/include/types_export.h b/services/distributeddataservice/libs/distributeddb/include/types_export.h index b084156c1..1e6f925e1 100644 --- a/services/distributeddataservice/libs/distributeddb/include/types_export.h +++ b/services/distributeddataservice/libs/distributeddb/include/types_export.h @@ -175,5 +175,11 @@ enum class CompressAlgorithm : uint8_t { NONE = 0, ZLIB = 1 }; + +// Table mode of device data for relational store +enum DistributedTableMode : int { + COLLABORATION = 0, // Save all devices data in user table + SPLIT_BY_DEVICE // Save device data in each table split by device +}; } // namespace DistributedDB #endif // DISTRIBUTEDDB_TYPES_EXPORT_H diff --git a/services/distributeddataservice/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h b/services/distributeddataservice/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h index 448d22642..0dc3dd626 100644 --- a/services/distributeddataservice/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h +++ b/services/distributeddataservice/libs/distributeddb/interfaces/include/relational/relational_store_delegate.h @@ -30,6 +30,7 @@ public: struct Option { StoreObserver *observer = nullptr; // split mode + DistributedTableMode tableMode = SPLIT_BY_DEVICE; }; DB_API virtual DBStatus CreateDistributedTable(const std::string &tableName) = 0; diff --git a/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp b/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp index 408cf336a..10b343bf1 100644 --- a/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp +++ b/services/distributeddataservice/libs/distributeddb/interfaces/src/relational/relational_store_manager.cpp @@ -82,6 +82,7 @@ DB_API DBStatus RelationalStoreManager::OpenStore(const std::string &path, const RelationalDBProperties properties; InitStoreProp(canonicalDir, appId_, userId_, storeId, properties); + properties.SetIntProp(RelationalDBProperties::DISTRIBUTED_TABLE_MODE, option.tableMode); int errCode = E_OK; auto *conn = GetOneConnectionWithRetry(properties, errCode); diff --git a/services/distributeddataservice/libs/distributeddb/storage/include/relationaldb_properties.h b/services/distributeddataservice/libs/distributeddb/storage/include/relationaldb_properties.h index 2b60fede5..5dfda7243 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/include/relationaldb_properties.h +++ b/services/distributeddataservice/libs/distributeddb/storage/include/relationaldb_properties.h @@ -37,6 +37,8 @@ public: // get schema RelationalSchemaObject GetSchema() const; + static const std::string DISTRIBUTED_TABLE_MODE; + private: RelationalSchemaObject schema_; }; diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/relationaldb_properties.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/relationaldb_properties.cpp index 52d34820a..13b748c2d 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/relationaldb_properties.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/relationaldb_properties.cpp @@ -16,6 +16,8 @@ #include "relationaldb_properties.h" namespace DistributedDB { +const std::string RelationalDBProperties::DISTRIBUTED_TABLE_MODE = "distributed_table_mode"; + RelationalDBProperties::RelationalDBProperties() {} -- Gitee From 8f90aa06bedf671835af978b7ffc89aacb8a3656 Mon Sep 17 00:00:00 2001 From: zqq Date: Thu, 28 Apr 2022 09:25:54 +0800 Subject: [PATCH 2/9] fix compile error Signed-off-by: zqq --- .../common/distributeddb/src/distributed_test_sysinfo.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/distributeddataservice/test/common/distributeddb/src/distributed_test_sysinfo.cpp b/services/distributeddataservice/test/common/distributeddb/src/distributed_test_sysinfo.cpp index e5be30527..4a2c5c66b 100644 --- a/services/distributeddataservice/test/common/distributeddb/src/distributed_test_sysinfo.cpp +++ b/services/distributeddataservice/test/common/distributeddb/src/distributed_test_sysinfo.cpp @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include #include #include "distributed_test_sysinfo.h" #include "distributeddb_data_generator.h" @@ -78,7 +79,8 @@ void DistributedTestSysInfo::GetSysMemOccpy(SeqNo seqNo) if (result3 != 2 || result4 != 2 || result5 != 2) { // there are 2 incoming param. MST_LOG("get mem2 info failed."); } - MST_LOG(" [MemTotal] = %llu \n [MemFree] = %llu \n [Buffers] = %llu \n [Cached] = %llu \n [SwapCached] = %llu ", + MST_LOG(" [MemTotal] = %" PRIu64 " \n [MemFree] = %" PRIu64 " \n [Buffers] = %" PRIu64 + " \n [Cached] = %" PRIu64 " \n [SwapCached] = %" PRIu64, memOccupy->memTotal_, memOccupy->memFree_, memOccupy->buffers_, memOccupy->cached_, memOccupy->swapCached_); fclose(fp); -- Gitee From bc81c01d0275bd9a47c9947029cedc6d558e975b Mon Sep 17 00:00:00 2001 From: zqq Date: Tue, 10 May 2022 01:55:25 +0000 Subject: [PATCH 3/9] =?UTF-8?q?!284=20=E5=A2=9E=E5=8A=A0UT=E7=94=A8?= =?UTF-8?q?=E4=BE=8B=20*=20add=20ut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../distributeddb_mock_sync_module_test.cpp | 45 +++++++++++++++++++ .../unittest/common/syncer/mock_sync_engine.h | 28 ++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_sync_engine.h diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp index 9f971581a..266af6d07 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/distributeddb_mock_sync_module_test.cpp @@ -23,6 +23,7 @@ #include "mock_meta_data.h" #include "mock_single_ver_data_sync.h" #include "mock_single_ver_state_machine.h" +#include "mock_sync_engine.h" #include "mock_sync_task_context.h" #include "single_ver_kv_syncer.h" #include "single_ver_relational_sync_task_context.h" @@ -598,4 +599,48 @@ HWTEST_F(DistributedDBMockSyncModuleTest, MessageScheduleTest001, TestSize.Level RefObject::KillAndDecObjRef(context); std::this_thread::sleep_for(std::chrono::seconds(1)); EXPECT_TRUE(last); +} + +/** + * @tc.name: SyncEngineTest001 + * @tc.desc: Test SyncEngine receive message when closing. + * @tc.type: FUNC + * @tc.require: AR000CCPOM + * @tc.author: zhangqiquan + */ +HWTEST_F(DistributedDBMockSyncModuleTest, SyncEngineTest001, TestSize.Level1) +{ + std::unique_ptr enginePtr = std::make_unique(); + EXPECT_CALL(*enginePtr, CreateSyncTaskContext()).WillRepeatedly(Return(nullptr)); + VirtualCommunicatorAggregator *virtualCommunicatorAggregator = new VirtualCommunicatorAggregator(); + VirtualSingleVerSyncDBInterface syncDBInterface; + std::shared_ptr metaData = std::make_shared(); + ASSERT_NE(virtualCommunicatorAggregator, nullptr); + RuntimeContext::GetInstance()->SetCommunicatorAggregator(virtualCommunicatorAggregator); + enginePtr->Initialize(&syncDBInterface, metaData, nullptr, nullptr, nullptr); + auto communicator = + static_cast(virtualCommunicatorAggregator->GetCommunicator("real_device")); + RefObject::IncObjRef(communicator); + std::thread thread1([&]() { + if (communicator == nullptr) { + return; + } + for (int count = 0; count < 100; count++) { // loop 100 times + auto *message = new(std::nothrow) DistributedDB::Message(); + communicator->CallbackOnMessage("src", message); + } + }); + std::thread thread2([&]() { + enginePtr->Close(); + }); + thread1.join(); + thread2.join(); + + LOGD("FINISHED"); + RefObject::KillAndDecObjRef(communicator); + communicator = nullptr; + enginePtr = nullptr; + metaData = nullptr; + RuntimeContext::GetInstance()->SetCommunicatorAggregator(nullptr); + virtualCommunicatorAggregator = nullptr; } \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_sync_engine.h b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_sync_engine.h new file mode 100644 index 000000000..1be10d2bc --- /dev/null +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/syncer/mock_sync_engine.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef MOCK_SYNC_ENGINE_H +#define MOCK_SYNC_ENGINE_H + +#include +#include "sync_engine.h" + +namespace DistributedDB { +class MockSyncEngine : public SyncEngine { +public: + MOCK_METHOD0(CreateSyncTaskContext, ISyncTaskContext *(void)); +}; +} // namespace DistributedDB +#endif // #define MOCK_SYNC_ENGINE_H \ No newline at end of file -- Gitee From 5b4597dc6908600b8af1dc9752144cb155d28816 Mon Sep 17 00:00:00 2001 From: wbq_sky Date: Tue, 10 May 2022 12:03:14 +0800 Subject: [PATCH 4/9] Fix the compile problem Signed-off-by: wbq_sky --- .../libs/distributeddb/storage/src/result_entries_window.cpp | 1 + .../sqlite/sqlite_single_ver_relational_storage_executor.cpp | 3 +++ .../libs/distributeddb/syncer/src/subscribe_manager.cpp | 2 ++ 3 files changed, 6 insertions(+) diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/result_entries_window.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/result_entries_window.cpp index 775ef833a..570938085 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/result_entries_window.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/result_entries_window.cpp @@ -15,6 +15,7 @@ #include "result_entries_window.h" +#include #include "db_constant.h" #include "db_errno.h" diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp index 42bc14fe7..3474a3558 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp @@ -14,7 +14,10 @@ */ #ifdef RELATIONAL_STORE #include "sqlite_single_ver_relational_storage_executor.h" + #include +#include + #include "data_transformer.h" #include "db_common.h" diff --git a/services/distributeddataservice/libs/distributeddb/syncer/src/subscribe_manager.cpp b/services/distributeddataservice/libs/distributeddb/syncer/src/subscribe_manager.cpp index 572cd9154..3b2b9dfbd 100644 --- a/services/distributeddataservice/libs/distributeddb/syncer/src/subscribe_manager.cpp +++ b/services/distributeddataservice/libs/distributeddb/syncer/src/subscribe_manager.cpp @@ -13,6 +13,8 @@ * limitations under the License. */ #include "subscribe_manager.h" + +#include #include "db_common.h" #include "sync_types.h" -- Gitee From 125f7cbc4c783ff5508d1a518c27524064d438c9 Mon Sep 17 00:00:00 2001 From: lianhuix Date: Mon, 9 May 2022 16:25:54 +0800 Subject: [PATCH 5/9] Add constraint check form COLLABORATION mode Signed-off-by: lianhuix --- .../relational/relational_schema_object.h | 14 +- .../common/include/schema_constant.h | 1 + .../relational/relational_schema_object.cpp | 85 ++++++-- .../common/src/schema_constant.cpp | 2 +- .../common/src/schema_negotiate.cpp | 6 + .../relational/sqlite_relational_store.cpp | 4 +- ...qlite_single_relational_storage_engine.cpp | 13 +- .../sqlite_single_relational_storage_engine.h | 4 +- ...single_ver_relational_storage_executor.cpp | 46 +++- ...e_single_ver_relational_storage_executor.h | 3 +- .../storage/src/sqlite/sqlite_utils.cpp | 49 +++-- ...ibuteddb_relational_schema_object_test.cpp | 136 +++++++++++- ...ributeddb_interfaces_create_table_test.cpp | 196 ++++++++++++++++++ ...distributeddb_relational_get_data_test.cpp | 4 +- ...uteddb_relational_schema_analysis_test.cpp | 147 +++++++++++++ 15 files changed, 656 insertions(+), 54 deletions(-) create mode 100644 services/distributeddataservice/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_create_table_test.cpp create mode 100644 services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_schema_analysis_test.cpp diff --git a/services/distributeddataservice/libs/distributeddb/common/include/relational/relational_schema_object.h b/services/distributeddataservice/libs/distributeddb/common/include/relational/relational_schema_object.h index 884dcd4ce..073f57f4b 100644 --- a/services/distributeddataservice/libs/distributeddb/common/include/relational/relational_schema_object.h +++ b/services/distributeddataservice/libs/distributeddb/common/include/relational/relational_schema_object.h @@ -20,6 +20,7 @@ #include "json_object.h" #include "parcel.h" #include "ischema.h" +#include "schema_constant.h" namespace DistributedDB { using CompositeFields = std::vector; @@ -64,15 +65,16 @@ public: const std::string &GetCreateTableSql() const; const std::map &GetFields() const; // const std::map &GetIndexDefine() const; - const FieldName &GetPrimaryKey() const; + const std::map &GetPrimaryKey() const; void SetTableName(const std::string &tableName); void SetAutoIncrement(bool autoInc); void SetCreateTableSql(std::string sql); // set 'autoInc_' flag when set sql void AddField(const FieldInfo &field); void AddIndexDefine(const std::string &indexName, const CompositeFields &indexDefine); - void SetPrimaryKey(const FieldName &fieldName); // not support composite index now - std::string ToTableInfoString() const; + void SetPrimaryKey(const std::map &key); + void SetPrimaryKey(const FieldName &fieldName, int keyIndex); + std::string ToTableInfoString(const std::string &schemaVersion) const; int CompareWithTable(const TableInfo &inTableInfo) const; std::map GetSchemaDefine() const; @@ -91,7 +93,7 @@ private: bool autoInc_ = false; // only 'INTEGER PRIMARY KEY' could be defined as 'AUTOINCREMENT' std::string sql_; std::map fields_; - FieldName primaryKey_; + std::map primaryKey_; std::map indexDefines_; mutable std::vector fieldInfos_; }; @@ -120,6 +122,8 @@ public: TableInfo GetTable(const std::string& tableName) const; + std::string GetSchemaVersion() const; + private: int CompareAgainstSchemaObject(const std::string &inSchemaString, std::map &cmpRst) const; @@ -143,7 +147,7 @@ private: bool isValid_ = false; // set to true after parse success from string or add at least one relational table SchemaType schemaType_ = SchemaType::RELATIVE; // Default RELATIVE std::string schemaString_; // The minified and valid schemaString - std::string schemaVersion_; + std::string schemaVersion_ = SchemaConstant::SCHEMA_SUPPORT_VERSION_V2; // Default version 2.0 std::map tables_; }; } // namespace DistributedDB diff --git a/services/distributeddataservice/libs/distributeddb/common/include/schema_constant.h b/services/distributeddataservice/libs/distributeddb/common/include/schema_constant.h index 81077bc83..9921a4e2a 100644 --- a/services/distributeddataservice/libs/distributeddb/common/include/schema_constant.h +++ b/services/distributeddataservice/libs/distributeddb/common/include/schema_constant.h @@ -49,6 +49,7 @@ public: static const std::string KEYWORD_TYPE_RELATIVE; static const std::string SCHEMA_SUPPORT_VERSION; static const std::string SCHEMA_SUPPORT_VERSION_V2; + static const std::string SCHEMA_SUPPORT_VERSION_V2_1; static const uint32_t SCHEMA_META_FEILD_COUNT_MAX; static const uint32_t SCHEMA_META_FEILD_COUNT_MIN; diff --git a/services/distributeddataservice/libs/distributeddb/common/src/relational/relational_schema_object.cpp b/services/distributeddataservice/libs/distributeddb/common/src/relational/relational_schema_object.cpp index 75e565da7..043df7406 100644 --- a/services/distributeddataservice/libs/distributeddb/common/src/relational/relational_schema_object.cpp +++ b/services/distributeddataservice/libs/distributeddb/common/src/relational/relational_schema_object.cpp @@ -212,14 +212,23 @@ void TableInfo::AddIndexDefine(const std::string &indexName, const CompositeFiel indexDefines_[indexName] = indexDefine; } -const FieldName &TableInfo::GetPrimaryKey() const +const std::map &TableInfo::GetPrimaryKey() const { return primaryKey_; } -void TableInfo::SetPrimaryKey(const FieldName &fieldName) +void TableInfo::SetPrimaryKey(const std::map &key) { - primaryKey_ = fieldName; + primaryKey_ = key; +} + +void TableInfo::SetPrimaryKey(const FieldName &fieldName, int keyIndex) +{ + if (keyIndex <= 0) { + return; + } + + primaryKey_[keyIndex - 1] = fieldName; } void TableInfo::AddFieldDefineString(std::string &attrStr) const @@ -338,7 +347,7 @@ int TableInfo::CompareWithTableIndex(const std::mapsecond.ToTableInfoString(); + schemaString_ += it->second.ToTableInfoString(schemaVersion_); } schemaString_ += R"(])"; schemaString_ += "}"; @@ -441,6 +459,9 @@ void RelationalSchemaObject::AddRelationalTable(const TableInfo &tb) { tables_[tb.GetTableName()] = tb; isValid_ = true; + if (tb.GetPrimaryKey().size() > 1) { // Table with composite primary key + schemaVersion_ = SchemaConstant::SCHEMA_SUPPORT_VERSION_V2_1; + } GenerateSchemaString(); } @@ -474,6 +495,11 @@ TableInfo RelationalSchemaObject::GetTable(const std::string &tableName) const return {}; } +std::string RelationalSchemaObject::GetSchemaVersion() const +{ + return schemaVersion_; +} + int RelationalSchemaObject::CompareAgainstSchemaObject(const std::string &inSchemaString, std::map &cmpRst) const { @@ -542,12 +568,14 @@ int RelationalSchemaObject::ParseCheckSchemaVersion(const JsonObject &inJsonObje return errCode; } - if (SchemaUtils::Strip(fieldValue.stringValue) != SchemaConstant::SCHEMA_SUPPORT_VERSION_V2) { - LOGE("[RelationalSchema][Parse] Unexpected SCHEMA_VERSION=%s.", fieldValue.stringValue.c_str()); - return -E_SCHEMA_PARSE_FAIL; + if (SchemaUtils::Strip(fieldValue.stringValue) == SchemaConstant::SCHEMA_SUPPORT_VERSION_V2 || + SchemaUtils::Strip(fieldValue.stringValue) == SchemaConstant::SCHEMA_SUPPORT_VERSION_V2_1) { + schemaVersion_ = fieldValue.stringValue; + return E_OK; } - schemaVersion_ = SchemaConstant::SCHEMA_SUPPORT_VERSION_V2; - return E_OK; + + LOGE("[RelationalSchema][Parse] Unexpected SCHEMA_VERSION=%s.", fieldValue.stringValue.c_str()); + return -E_SCHEMA_PARSE_FAIL; } int RelationalSchemaObject::ParseCheckSchemaType(const JsonObject &inJsonObject) @@ -715,10 +743,33 @@ int RelationalSchemaObject::ParseCheckTableAutoInc(const JsonObject &inJsonObjec int RelationalSchemaObject::ParseCheckTablePrimaryKey(const JsonObject &inJsonObject, TableInfo &resultTable) { - FieldValue fieldValue; - int errCode = GetMemberFromJsonObject(inJsonObject, "PRIMARY_KEY", FieldType::LEAF_FIELD_STRING, false, fieldValue); - if (errCode == E_OK) { - resultTable.SetPrimaryKey(fieldValue.stringValue); + if (!inJsonObject.IsFieldPathExist(FieldPath {"PRIMARY_KEY"})) { + return E_OK; + } + + FieldType type; + int errCode = inJsonObject.GetFieldTypeByFieldPath(FieldPath {"PRIMARY_KEY"}, type); + if (errCode != E_OK) { + return errCode; + } + + if (type == FieldType::LEAF_FIELD_STRING) { // Compatible with schema 2.0 + FieldValue fieldValue; + errCode = GetMemberFromJsonObject(inJsonObject, "PRIMARY_KEY", FieldType::LEAF_FIELD_STRING, false, fieldValue); + if (errCode == E_OK) { + resultTable.SetPrimaryKey(fieldValue.stringValue, 1); + } + } else if (type == FieldType::LEAF_FIELD_ARRAY) { + CompositeFields multiPrimaryKey; + errCode = inJsonObject.GetStringArrayByFieldPath(FieldPath {"PRIMARY_KEY"}, multiPrimaryKey); + if (errCode == E_OK) { + int index = 1; // primary key index + for (const auto &item : multiPrimaryKey) { + resultTable.SetPrimaryKey(item, index++); + } + } + } else { + errCode = -E_SCHEMA_PARSE_FAIL; } return errCode; } diff --git a/services/distributeddataservice/libs/distributeddb/common/src/schema_constant.cpp b/services/distributeddataservice/libs/distributeddb/common/src/schema_constant.cpp index d833a7eeb..a1574a4fd 100644 --- a/services/distributeddataservice/libs/distributeddb/common/src/schema_constant.cpp +++ b/services/distributeddataservice/libs/distributeddb/common/src/schema_constant.cpp @@ -43,6 +43,7 @@ const std::string SchemaConstant::KEYWORD_ATTR_VALUE_FALSE = "false"; const std::string SchemaConstant::KEYWORD_TYPE_RELATIVE = "RELATIVE"; const std::string SchemaConstant::SCHEMA_SUPPORT_VERSION = "1.0"; const std::string SchemaConstant::SCHEMA_SUPPORT_VERSION_V2 = "2.0"; +const std::string SchemaConstant::SCHEMA_SUPPORT_VERSION_V2_1 = "2.1"; const uint32_t SchemaConstant::SCHEMA_META_FEILD_COUNT_MAX = 5; const uint32_t SchemaConstant::SCHEMA_META_FEILD_COUNT_MIN = 3; @@ -58,4 +59,3 @@ const uint32_t SchemaConstant::SCHEMA_SKIPSIZE_MAX = 4194302; // 4M - 2 Bytes const uint32_t SchemaConstant::SECURE_BYTE_ALIGN = 8; // 8 bytes align } // namespace DistributedDB - diff --git a/services/distributeddataservice/libs/distributeddb/common/src/schema_negotiate.cpp b/services/distributeddataservice/libs/distributeddb/common/src/schema_negotiate.cpp index ad031644b..ef184922e 100644 --- a/services/distributeddataservice/libs/distributeddb/common/src/schema_negotiate.cpp +++ b/services/distributeddataservice/libs/distributeddb/common/src/schema_negotiate.cpp @@ -123,6 +123,12 @@ RelationalSyncOpinion SchemaNegotiate::MakeLocalSyncOpinion(const RelationalSche return {}; } + if (localSchema.GetSchemaVersion() != remoteSchemaObj.GetSchemaVersion()) { + LOGW("[RelationalSchema][opinion] Schema version not match, local %s, remote %s", + localSchema.GetSchemaVersion().c_str(), remoteSchemaObj.GetSchemaVersion().c_str()); + return {}; + } + RelationalSyncOpinion opinion; for (const auto &it : localSchema.GetTables()) { if (remoteSchemaObj.GetTable(it.first).GetTableName() != it.first) { diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp index 6708d9a5a..19faaab7e 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_store.cpp @@ -328,7 +328,9 @@ void SQLiteRelationalStore::WakeUpSyncer() int SQLiteRelationalStore::CreateDistributedTable(const std::string &tableName) { bool schemaChanged = false; - int errCode = sqliteStorageEngine_->CreateDistributedTable(tableName, schemaChanged); + DistributedTableMode mode = static_cast(properties_.GetIntProp( + RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE)); + int errCode = sqliteStorageEngine_->CreateDistributedTable(tableName, mode, schemaChanged); if (errCode != E_OK) { LOGE("Create distributed table failed. %d", errCode); } diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp index a6e113162..7f140729f 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp @@ -130,13 +130,14 @@ int SaveSchemaToMetaTable(SQLiteSingleVerRelationalStorageExecutor *handle, cons } } -int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::string &tableName, bool &schemaChanged) +int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::string &tableName, + DistributedTableMode mode, bool &schemaChanged) { std::lock_guard lock(schemaMutex_); RelationalSchemaObject tmpSchema = schema_; bool isUpgrade = false; if (tmpSchema.GetTable(tableName).GetTableName() == tableName) { - LOGW("distributed table was already created."); + LOGI("distributed table was already created."); isUpgrade = true; int errCode = UpgradeDistributedTable(tableName); if (errCode != E_OK) { @@ -150,6 +151,12 @@ int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::strin return -E_MAX_LIMITS; } + return CreateDistributedTable(tableName, mode, isUpgrade, schemaChanged, tmpSchema); +} + +int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::string &tableName, + DistributedTableMode mode, bool isUpgrade, bool &schemaChanged, RelationalSchemaObject &tmpSchema) +{ LOGD("Create distributed table."); int errCode = E_OK; auto *handle = static_cast(FindExecutor(true, OperatePerm::NORMAL_PERM, @@ -165,7 +172,7 @@ int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::strin } TableInfo table; - errCode = handle->CreateDistributedTable(tableName, table, isUpgrade); + errCode = handle->CreateDistributedTable(tableName, mode, table, isUpgrade); if (errCode != E_OK) { LOGE("create distributed table failed. %d", errCode); (void)handle->Rollback(); diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h index d09014b6e..1e35a395f 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h @@ -33,7 +33,7 @@ public: const RelationalSchemaObject &GetSchemaRef() const; - int CreateDistributedTable(const std::string &tableName, bool &schemaChanged); + int CreateDistributedTable(const std::string &tableName, DistributedTableMode mode, bool &schemaChanged); int CleanDistributedDeviceTable(std::vector &missingTables); @@ -50,6 +50,8 @@ private: int RegisterFunction(sqlite3 *db) const; int UpgradeDistributedTable(const std::string &tableName); + int CreateDistributedTable(const std::string &tableName, DistributedTableMode mode, bool isUpgrade, + bool &schemaChanged, RelationalSchemaObject &tmpSchema); RelationalSchemaObject schema_; mutable std::mutex schemaMutex_; diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp index 3474a3558..804a75ac4 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp @@ -26,8 +26,43 @@ SQLiteSingleVerRelationalStorageExecutor::SQLiteSingleVerRelationalStorageExecut : SQLiteStorageExecutor(dbHandle, writable, false) {} -int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedTable(const std::string &tableName, TableInfo &table, - bool isUpgrade) +int CheckTableconstraint(const TableInfo &table, DistributedTableMode mode) +{ + + if (table.GetCreateTableSql().find("WITHOUT ROWID") != std::string::npos) { + LOGE("[CreateDistributedTable] Not support create distributed table without rowid."); + return -E_NOT_SUPPORT; + } + + if (mode == DistributedTableMode::COLLABORATION) { + if (table.GetCreateTableSql().find("CHECK") != std::string::npos) { + LOGE("[CreateDistributedTable] Not support create distributed table with 'CHECK' constraint."); + return -E_NOT_SUPPORT; + } + + if (table.GetCreateTableSql().find("ON CONFLICT") != std::string::npos) { + LOGE("[CreateDistributedTable] Not support create distributed table with 'ON CONFLICT' constraint."); + return -E_NOT_SUPPORT; + } + + if (table.GetCreateTableSql().find("REFERENCES") != std::string::npos) { + LOGE("[CreateDistributedTable] Not support create distributed table with 'FOREIGN KEY' constraint."); + return -E_NOT_SUPPORT; + } + } + + if (mode == DistributedTableMode::SPLIT_BY_DEVICE) { + if (table.GetPrimaryKey().size() > 1) { + LOGE("[CreateDistributedTable] Not support create distributed table with composite primary key."); + return -E_NOT_SUPPORT; + } + } + + return E_OK; +} + +int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedTable(const std::string &tableName, + DistributedTableMode mode, TableInfo &table, bool isUpgrade) { if (dbHandle_ == nullptr) { return -E_INVALID_DB; @@ -39,9 +74,10 @@ int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedTable(const std:: return errCode; } - if (table.GetCreateTableSql().find("WITHOUT ROWID") != std::string::npos) { - LOGE("[CreateDistributedTable] Not support create distributed table without rowid."); - return -E_NOT_SUPPORT; + errCode = CheckTableconstraint(table, mode); + if (errCode != E_OK) { + LOGE("[CreateDistributedTable] check table constraint failed."); + return errCode; } bool isTableEmpty = false; diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h index 6a0db0d14..520579515 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h @@ -33,7 +33,8 @@ public: // Delete the copy and assign constructors DISABLE_COPY_ASSIGN_MOVE(SQLiteSingleVerRelationalStorageExecutor); - int CreateDistributedTable(const std::string &tableName, TableInfo &table, bool isUpgrade); + int CreateDistributedTable(const std::string &tableName, DistributedTableMode mode, TableInfo &table, + bool isUpgrade); int UpgradeDistributedTable(const TableInfo &tableInfo, TableInfo &newTableInfo); diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp index ef578bcd9..d7483a854 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_utils.cpp @@ -747,13 +747,9 @@ int SetFieldInfo(sqlite3_stmt *statement, TableInfo &table) field.SetDefaultValue(tmpString); } - if (sqlite3_column_int64(statement, 5) != 0) { // 5 means primary key index - if (!table.GetPrimaryKey().empty()) { - // Primary key is already set, usually because the primary key has multiple fields, not support - LOGE("[AnalysisSchema] Not support for composite primary key"); - return -E_NOT_SUPPORT; - } - table.SetPrimaryKey(field.GetFieldName()); + int keyIndex = sqlite3_column_int64(statement, 5); // 5 means primary key index + if (keyIndex != 0) { // not 0 means is a primary key + table.SetPrimaryKey(field.GetFieldName(), keyIndex); } table.AddField(field); return E_OK; @@ -786,7 +782,7 @@ int AnalysisSchemaFieldDefine(sqlite3 *db, const std::string &tableName, TableIn } while (true); if (table.GetPrimaryKey().empty()) { - table.SetPrimaryKey("rowid"); + table.SetPrimaryKey("rowid", 1); } SQLiteUtils::ResetStatement(statement, true, errCode); @@ -796,6 +792,10 @@ int AnalysisSchemaFieldDefine(sqlite3 *db, const std::string &tableName, TableIn int SQLiteUtils::AnalysisSchema(sqlite3 *db, const std::string &tableName, TableInfo &table) { + if (db == nullptr) { + return -E_INVALID_DB; + } + int errCode = AnalysisSchemaSqlAndTrigger(db, tableName, table); if (errCode != E_OK) { LOGE("[AnalysisSchema] Analysis sql and trigger failed. errCode = [%d]", errCode); @@ -1354,6 +1354,17 @@ int SQLiteUtils::CreateRelationalLogTable(sqlite3 *db, const std::string &oriTab } namespace { +std::string CalcPrimaryKeyHash(const std::string &references, const TableInfo &table) +{ + std::string sql; + for (const auto &it : table.GetPrimaryKey()) { + sql += "calc_hash(" + references + it.second + ")||"; + } + sql.pop_back(); // remove last "||" + sql.pop_back(); + return sql; +} + std::string GetInsertTrigger(const TableInfo &table) { std::string logTblName = DBConstant::RELATIONAL_PREFIX + table.GetTableName() + "_log"; @@ -1365,9 +1376,9 @@ std::string GetInsertTrigger(const TableInfo &table) insertTrigger += " (data_key, device, ori_device, timestamp, wtimestamp, flag, hash_key)"; insertTrigger += " VALUES (new.rowid, '', '',"; insertTrigger += " get_sys_time(0), get_sys_time(0),"; - insertTrigger += " CASE WHEN (SELECT count(*)<>0 FROM " + logTblName + " WHERE hash_key=calc_hash(new." + - table.GetPrimaryKey() + ") AND flag&0x02=0x02) THEN 0x22 ELSE 0x02 END,"; - insertTrigger += " calc_hash(new." + table.GetPrimaryKey() + "));\n"; + insertTrigger += " CASE WHEN (SELECT count(*)<>0 FROM " + logTblName + " WHERE hash_key=" + + CalcPrimaryKeyHash("NEW.", table) + " AND flag&0x02=0x02) THEN 0x22 ELSE 0x02 END,"; + insertTrigger += CalcPrimaryKeyHash("NEW.", table) + ");\n"; insertTrigger += "END;"; return insertTrigger; } @@ -1380,7 +1391,7 @@ std::string GetUpdateTrigger(const TableInfo &table) updateTrigger += "BEGIN\n"; updateTrigger += "\t UPDATE " + DBConstant::RELATIONAL_PREFIX + table.GetTableName() + "_log"; updateTrigger += " SET timestamp=get_sys_time(0), device='', flag=0x22"; - updateTrigger += " where hash_key=calc_hash(old." + table.GetPrimaryKey() + ") and flag&0x02=0x02;\n"; + updateTrigger += " where hash_key=" + CalcPrimaryKeyHash("OLD.", table) + " and flag&0x02=0x02;\n"; updateTrigger += "END;"; return updateTrigger; } @@ -1393,7 +1404,7 @@ std::string GetDeleteTrigger(const TableInfo &table) deleteTrigger += "BEGIN\n"; deleteTrigger += "\t UPDATE " + DBConstant::RELATIONAL_PREFIX + table.GetTableName() + "_log"; deleteTrigger += " SET flag=0x03,timestamp=get_sys_time(0)"; - deleteTrigger += " where hash_key=calc_hash(old." + table.GetPrimaryKey() + ") and flag&0x02=0x02;\n"; + deleteTrigger += " where hash_key=" + CalcPrimaryKeyHash("OLD.", table) + " and flag&0x02=0x02;\n"; deleteTrigger += "END;"; return deleteTrigger; } @@ -1426,11 +1437,17 @@ int SQLiteUtils::CreateSameStuTable(sqlite3 *db, const TableInfo &baseTbl, const if (fields.at(fieldName).HasDefaultValue()) { sql += " DEFAULT " + fields.at(fieldName).GetDefaultValue(); } - if (fieldName == baseTbl.GetPrimaryKey()) { - sql += " PRIMARY KEY"; - } sql += ","; } + // base table has primary key + if (!(baseTbl.GetPrimaryKey().size() == 1 && baseTbl.GetPrimaryKey().at(0) == "rowid")) { + sql += " PRIMARY KEY ("; + for (const auto &it : baseTbl.GetPrimaryKey()) { + sql += it.second + ","; + } + sql.pop_back(); + sql += "),"; + } sql.pop_back(); sql += ");"; int errCode = SQLiteUtils::ExecuteRawSQL(db, sql); diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/common/distributeddb_relational_schema_object_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/common/distributeddb_relational_schema_object_test.cpp index 2192f0688..e7d922703 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/common/distributeddb_relational_schema_object_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/common/distributeddb_relational_schema_object_test.cpp @@ -81,6 +81,56 @@ namespace { }] })""; + const std::string NORMAL_SCHEMA_V2_1 = R""({ + "SCHEMA_VERSION": "2.1", + "SCHEMA_TYPE": "RELATIVE", + "TABLES": [{ + "NAME": "FIRST", + "DEFINE": { + "field_name1": { + "COLUMN_ID":1, + "TYPE": "STRING", + "NOT_NULL": true, + "DEFAULT": "abcd" + }, + "field_name2": { + "COLUMN_ID":2, + "TYPE": "MYINT(21)", + "NOT_NULL": false, + "DEFAULT": "222" + }, + "field_name3": { + "COLUMN_ID":3, + "TYPE": "INTGER", + "NOT_NULL": false, + "DEFAULT": "1" + } + }, + "AUTOINCREMENT": true, + "UNIQUE": ["field_name1", ["field_name2", "field_name3"]], + "PRIMARY_KEY": ["field_name1", "field_name3"], + "INDEX": { + "index_name1": ["field_name1", "field_name2"], + "index_name2": ["field_name3"] + } + }, { + "NAME": "SECOND", + "DEFINE": { + "key": { + "COLUMN_ID":1, + "TYPE": "BLOB", + "NOT_NULL": true + }, + "value": { + "COLUMN_ID":2, + "TYPE": "BLOB", + "NOT_NULL": false + } + }, + "PRIMARY_KEY": ["field_name1"] + }] + })""; + const std::string INVALID_SCHEMA = R""({ "SCHEMA_VERSION": "2.0", "SCHEMA_TYPE": "RELATIVE", @@ -113,6 +163,7 @@ namespace { const std::string SCHEMA_VERSION_STR_1 = R"("SCHEMA_VERSION": "1.0",)"; const std::string SCHEMA_VERSION_STR_2 = R"("SCHEMA_VERSION": "2.0",)"; + const std::string SCHEMA_VERSION_STR_2_1 = R"("SCHEMA_VERSION": "2.1",)"; const std::string SCHEMA_VERSION_STR_INVALID = R"("SCHEMA_VERSION": "awd3",)"; const std::string SCHEMA_TYPE_STR_NONE = R"("SCHEMA_TYPE": "NONE",)"; const std::string SCHEMA_TYPE_STR_JSON = R"("SCHEMA_TYPE": "JSON",)"; @@ -179,7 +230,8 @@ namespace { "DEFAULT": "abcd" }},)""; const std::string TABLE_DEFINE_STR_KEY = R""("PRIMARY_KEY": "field_name1")""; - const std::string TABLE_DEFINE_STR_KEY_INVALID = R""("PRIMARY_KEY": false)""; + const std::string TABLE_DEFINE_BOOL_KEY_INVALID = R""("PRIMARY_KEY": false)""; + const std::string TABLE_DEFINE_BOOL_ARRAY_KEY_INVALID = R""("PRIMARY_KEY": [false, true, true])""; } class DistributedDBRelationalSchemaObjectTest : public testing::Test { @@ -310,7 +362,12 @@ HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest003, EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL); std::string invalidTableStr05 = "{" + TABLE_DEFINE_STR_NAME + TABLE_DEFINE_STR_FIELDS + - TABLE_DEFINE_STR_KEY_INVALID + "}"; + TABLE_DEFINE_BOOL_KEY_INVALID + "}"; + errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr05 + "]")); + EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL); + + std::string invalidTableStr06 = "{" + TABLE_DEFINE_STR_NAME + TABLE_DEFINE_STR_FIELDS + + TABLE_DEFINE_BOOL_ARRAY_KEY_INVALID + "}"; errCode = schemaObj.ParseFromSchemaString(GenerateFromTableStr("[" + invalidTableStr05 + "]")); EXPECT_EQ(errCode, -E_SCHEMA_PARSE_FAIL); @@ -318,6 +375,24 @@ HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest003, EXPECT_EQ(errCode, -E_INVALID_ARGS); } + +/** + * @tc.name: RelationalSchemaParseTest004 + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaParseTest004, TestSize.Level1) +{ + RelationalSchemaObject schemaObj; + int errCode = E_OK; + + std::string schema = "{" + SCHEMA_VERSION_STR_2_1 + SCHEMA_TYPE_STR_RELATIVE + SCHEMA_TABLE_STR + "}"; + errCode = schemaObj.ParseFromSchemaString(schema); + EXPECT_EQ(errCode, -E_OK); +} + /** * @tc.name: RelationalSchemaCompareTest001 * @tc.desc: Test relational schema negotiate with same schema string @@ -338,6 +413,63 @@ HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaCompareTest001 EXPECT_EQ(opinion.at("FIRST").requirePeerConvert, false); } +/** + * @tc.name: RelationalSchemaCompareTest002 + * @tc.desc: Test relational schema v2.1 negotiate with same schema string + * @tc.type: FUNC + * @tc.require: AR000H2PKN + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaCompareTest002, TestSize.Level1) +{ + RelationalSchemaObject schemaObj; + int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA_V2_1); + EXPECT_EQ(errCode, E_OK); + + RelationalSyncOpinion opinion = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, NORMAL_SCHEMA_V2_1, + static_cast(SchemaType::RELATIVE)); + EXPECT_EQ(opinion.at("FIRST").permitSync, true); + EXPECT_EQ(opinion.at("FIRST").checkOnReceive, false); + EXPECT_EQ(opinion.at("FIRST").requirePeerConvert, false); + +} + +/** + * @tc.name: RelationalSchemaCompareTest003 + * @tc.desc: Test relational schema v2.1 negotiate with schema v2.0 + * @tc.type: FUNC + * @tc.require: AR000H2PKN + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaCompareTest003, TestSize.Level1) +{ + RelationalSchemaObject schemaObj; + int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA_V2_1); + EXPECT_EQ(errCode, E_OK); + + RelationalSyncOpinion opinion = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, NORMAL_SCHEMA, + static_cast(SchemaType::RELATIVE)); + EXPECT_TRUE(opinion.empty()); +} + +/** + * @tc.name: RelationalSchemaCompareTest004 + * @tc.desc: Test relational schema v2.0 negotiate with schema v2.1 + * @tc.type: FUNC + * @tc.require: AR000H2PKN + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBRelationalSchemaObjectTest, RelationalSchemaCompareTest004, TestSize.Level1) +{ + RelationalSchemaObject schemaObj; + int errCode = schemaObj.ParseFromSchemaString(NORMAL_SCHEMA); + EXPECT_EQ(errCode, E_OK); + + RelationalSyncOpinion opinion = SchemaNegotiate::MakeLocalSyncOpinion(schemaObj, NORMAL_SCHEMA_V2_1, + static_cast(SchemaType::RELATIVE)); + EXPECT_TRUE(opinion.empty()); +} + /** * @tc.name: RelationalTableCompareTest001 * @tc.desc: Test relational schema negotiate with same schema string diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_create_table_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_create_table_test.cpp new file mode 100644 index 000000000..f76902f6b --- /dev/null +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/interfaces/distributeddb_interfaces_create_table_test.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "db_common.h" +#include "distributeddb_data_generate_unit_test.h" +#include "distributeddb_tools_unit_test.h" +#include "log_print.h" +#include "platform_specific.h" +#include "relational_store_manager.h" +#include "relational_store_sqlite_ext.h" + +using namespace testing::ext; +using namespace DistributedDB; +using namespace DistributedDBUnitTest; +using namespace std; + +namespace { + constexpr const char* DB_SUFFIX = ".db"; + constexpr const char* STORE_ID = "Relational_Store_ID"; + std::string g_testDir; + std::string g_dbDir; + DistributedDB::RelationalStoreManager g_mgr(APP_ID, USER_ID); +} + +class DistributedDBInterfacesCreateTableTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +protected: + sqlite3 *db_ = nullptr; + RelationalStoreDelegate *delegate_ = nullptr; +}; + +void DistributedDBInterfacesCreateTableTest::SetUpTestCase(void) +{ + DistributedDBToolsUnitTest::TestDirInit(g_testDir); + LOGD("Test dir is %s", g_testDir.c_str()); + g_dbDir = g_testDir + "/"; + DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir); +} + +void DistributedDBInterfacesCreateTableTest::TearDownTestCase(void) +{ +} + +void DistributedDBInterfacesCreateTableTest::SetUp(void) +{ + DistributedDBToolsUnitTest::PrintTestCaseInfo(); + db_ = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + ASSERT_NE(db_, nullptr); + EXPECT_EQ(RelationalTestUtils::ExecSql(db_, "PRAGMA journal_mode=WAL;"), SQLITE_OK); + + RelationalStoreDelegate::Option option {}; + option.tableMode = DistributedTableMode::COLLABORATION; + + DBStatus status = g_mgr.OpenStore(g_dbDir + STORE_ID + DB_SUFFIX, STORE_ID, option, delegate_); + EXPECT_EQ(status, OK); + ASSERT_NE(delegate_, nullptr); +} + +void DistributedDBInterfacesCreateTableTest::TearDown(void) +{ + DBStatus status = g_mgr.CloseStore(delegate_); + EXPECT_EQ(status, OK); + + EXPECT_EQ(sqlite3_close_v2(db_), SQLITE_OK); + DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir); +} + +/** + * @tc.name: CreateTableTest001 + * @tc.desc: create distributed table with composite primary key + * @tc.type: FUNC + * @tc.require: AR000H2PKN + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBInterfacesCreateTableTest, CreateTableTest001, TestSize.Level1) +{ + std::string COMPOSITE_PRIMARY_KEY_TABLE_SQL = R"(CREATE TABLE workers ( + worker_id INTEGER, + last_name VARCHAR NOT NULL, + first_name VARCHAR, + join_date DATE, + PRIMARY KEY (last_name, first_name) + );)"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db_, COMPOSITE_PRIMARY_KEY_TABLE_SQL), SQLITE_OK); + EXPECT_EQ(delegate_->CreateDistributedTable("workers"), OK); +} + +/** + * @tc.name: CreateTableTest002 + * @tc.desc: create distributed table with foreign key + * @tc.type: FUNC + * @tc.require: AR000H2PKN + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBInterfacesCreateTableTest, CreateTableTest002, TestSize.Level1) +{ + std::string parent = "CREATE TABLE parent(a, b, PRIMARY KEY(a,b))"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db_, parent), SQLITE_OK); + + std::string child = "CREATE TABLE child(x, y, FOREIGN KEY(x,y) REFERENCES parent); "; + EXPECT_EQ(RelationalTestUtils::ExecSql(db_, child), SQLITE_OK); + EXPECT_EQ(delegate_->CreateDistributedTable("child"), NOT_SUPPORT); +} + +/** + * @tc.name: CreateTableTest003 + * @tc.desc: create distributed table with foreign key + * @tc.type: FUNC + * @tc.require: AR000H2PKN + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBInterfacesCreateTableTest, CreateTableTest003, TestSize.Level1) +{ + std::string parent = "CREATE TABLE parent(a, b, PRIMARY KEY(a,b))"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db_, parent), SQLITE_OK); + + std::string child = "CREATE TABLE child(x, y REFERENCES parent(a)); "; + EXPECT_EQ(RelationalTestUtils::ExecSql(db_, child), SQLITE_OK); + EXPECT_EQ(delegate_->CreateDistributedTable("child"), NOT_SUPPORT); +} + +/** + * @tc.name: CreateTableTest004 + * @tc.desc: create distributed table with check constraint + * @tc.type: FUNC + * @tc.require: AR000H2PKN + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBInterfacesCreateTableTest, CreateTableTest004, TestSize.Level1) +{ + std::string child = "CREATE TABLE child(x, y CHECK(y > 30)); "; + EXPECT_EQ(RelationalTestUtils::ExecSql(db_, child), SQLITE_OK); + EXPECT_EQ(delegate_->CreateDistributedTable("child"), NOT_SUPPORT); +} + +/** + * @tc.name: CreateTableTest005 + * @tc.desc: create distributed table with check constraint + * @tc.type: FUNC + * @tc.require: AR000H2PKN + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBInterfacesCreateTableTest, CreateTableTest005, TestSize.Level1) +{ + std::string child = "CREATE TABLE child(x, y, CHECK(y > 30)); "; + EXPECT_EQ(RelationalTestUtils::ExecSql(db_, child), SQLITE_OK); + EXPECT_EQ(delegate_->CreateDistributedTable("child"), NOT_SUPPORT); +} + +/** + * @tc.name: CreateTableTest006 + * @tc.desc: create distributed table with on conflict constraint + * @tc.type: FUNC + * @tc.require: AR000H2PKN + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBInterfacesCreateTableTest, CreateTableTest006, TestSize.Level1) +{ + std::string child = "CREATE TABLE child(x PRIMARY KEY ON CONFLICT REPLACE, y);"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db_, child), SQLITE_OK); + EXPECT_EQ(delegate_->CreateDistributedTable("child"), NOT_SUPPORT); +} + +/** + * @tc.name: CreateTableTest007 + * @tc.desc: create distributed table with on conflict constraint + * @tc.type: FUNC + * @tc.require: AR000H2PKN + * @tc.author: lianhuix + */ +HWTEST_F(DistributedDBInterfacesCreateTableTest, CreateTableTest007, TestSize.Level1) +{ + std::string child = "CREATE TABLE child(x , y, z, PRIMARY KEY(x, y) ON CONFLICT REPLACE);"; + EXPECT_EQ(RelationalTestUtils::ExecSql(db_, child), SQLITE_OK); + EXPECT_EQ(delegate_->CreateDistributedTable("child"), NOT_SUPPORT); +} \ No newline at end of file diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp index ec1835144..7d2e61677 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_get_data_test.cpp @@ -1190,9 +1190,9 @@ HWTEST_F(DistributedDBRelationalGetDataTest, CompatibleData2, TestSize.Level1) * @tc.expected: The create sql is correct. */ std::string expectSql = "CREATE TABLE naturalbase_rdb_aux_data_" - "265a9c8c3c690cdfdac72acfe7a50f748811802635d987bb7d69dc602ed3794f(key integer NOT NULL PRIMARY KEY," + "265a9c8c3c690cdfdac72acfe7a50f748811802635d987bb7d69dc602ed3794f(key integer NOT NULL," "value integer, integer_type integer NOT NULL DEFAULT 123, text_type text NOT NULL DEFAULT 'high_version', " - "real_type real NOT NULL DEFAULT 123.123456, blob_type blob NOT NULL DEFAULT 123)"; + "real_type real NOT NULL DEFAULT 123.123456, blob_type blob NOT NULL DEFAULT 123, PRIMARY KEY (key))"; sql = "SELECT sql FROM sqlite_master WHERE tbl_name='" + DBConstant::RELATIONAL_PREFIX + g_tableName + "_" + DBCommon::TransferStringToHex(DBCommon::TransferHashString(deviceID)) + "';"; EXPECT_EQ(GetOneText(db, sql), expectSql); diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_schema_analysis_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_schema_analysis_test.cpp new file mode 100644 index 000000000..94a8d78a6 --- /dev/null +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_schema_analysis_test.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef RELATIONAL_STORE +#include + +#include "distributeddb_tools_unit_test.h" +#include "sqlite_utils.h" + +using namespace testing::ext; +using namespace DistributedDB; +using namespace DistributedDBUnitTest; +using namespace std; + +namespace { + constexpr const char* DB_SUFFIX = ".db"; + constexpr const char* STORE_ID = "Relational_Store_ID"; + string g_testDir; + string g_dbDir; + const std::string NORMAL_CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS sync_data(" \ + "key BLOB NOT NULL UNIQUE," \ + "value BLOB," \ + "timestamp INT NOT NULL," \ + "flag INT NOT NULL," \ + "device BLOB," \ + "ori_device BLOB," \ + "hash_key BLOB PRIMARY KEY NOT NULL," \ + "w_timestamp INT," \ + "UNIQUE(device, ori_device));" \ + "CREATE INDEX key_index ON sync_data (key, flag);"; + + + const std::string MULTI_PRIMARI_KEY_SQL = "CREATE TABLE IF NOT EXISTS sync_data(" \ + "key BLOB NOT NULL UNIQUE," \ + "value BLOB," \ + "timestamp INT NOT NULL," \ + "flag INT NOT NULL," \ + "device BLOB," \ + "ori_device BLOB," \ + "hash_key BLOB NOT NULL," \ + "w_timestamp INT," \ + "PRIMARY KEY(hash_key, device)" \ + "UNIQUE(device, ori_device));" \ + "CREATE INDEX key_index ON sync_data (key, flag);"; + + const std::string NO_PRIMARI_KEY_SQL = "CREATE TABLE IF NOT EXISTS t1 (a INT, b INT, c INT);"; +} + +class DistributedDBRelationalSchemaAnalysisTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void DistributedDBRelationalSchemaAnalysisTest::SetUpTestCase(void) +{ + DistributedDBToolsUnitTest::TestDirInit(g_testDir); + DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir); + LOGI("The test db is:%s", g_testDir.c_str()); + g_dbDir = g_testDir + "/"; +} + +void DistributedDBRelationalSchemaAnalysisTest::TearDownTestCase(void) +{} + +void DistributedDBRelationalSchemaAnalysisTest::SetUp(void) +{ + DistributedDBToolsUnitTest::PrintTestCaseInfo(); +} + +void DistributedDBRelationalSchemaAnalysisTest::TearDown(void) +{ + if (DistributedDBToolsUnitTest::RemoveTestDbFiles(g_testDir) != 0) { + LOGE("rm test db files error."); + } + return; +} + + +namespace { +TableInfo AnalysisTable(const std::string &name, const std::string &sql) { + sqlite3 *db = RelationalTestUtils::CreateDataBase(g_dbDir + STORE_ID + DB_SUFFIX); + EXPECT_NE(db, nullptr); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, "PRAGMA journal_mode=WAL;"), SQLITE_OK); + EXPECT_EQ(RelationalTestUtils::ExecSql(db, sql), SQLITE_OK); + + TableInfo table; + int errcode = SQLiteUtils::AnalysisSchema(db, name, table); + EXPECT_EQ(errcode, E_OK); + EXPECT_EQ(sqlite3_close_v2(db), SQLITE_OK); + return table; +} +} + +/** + * @tc.name: AnalysisTable001 + * @tc.desc: Analysis with table which has one primary key + * @tc.type: FUNC + * @tc.require: AR000H2PKN + * @tc.author: xulianhui + */ +HWTEST_F(DistributedDBRelationalSchemaAnalysisTest, AnalysisTable001, TestSize.Level1) +{ + TableInfo table = AnalysisTable("sync_data", NORMAL_CREATE_TABLE_SQL); + EXPECT_EQ(table.GetPrimaryKey().size(), 1); +} + +/** + * @tc.name: AnalysisTable002 + * @tc.desc: Analysis with table which has multi primary key + * @tc.type: FUNC + * @tc.require: AR000H2PKN + * @tc.author: xulianhui + */ +HWTEST_F(DistributedDBRelationalSchemaAnalysisTest, AnalysisTable002, TestSize.Level1) +{ + TableInfo table = AnalysisTable("sync_data", MULTI_PRIMARI_KEY_SQL); + EXPECT_EQ(table.GetPrimaryKey().size(), 2); +} + +/** + * @tc.name: AnalysisTable003 + * @tc.desc: Analysis with table which has no primary key + * @tc.type: FUNC + * @tc.require: AR000H2PKN + * @tc.author: xulianhui + */ +HWTEST_F(DistributedDBRelationalSchemaAnalysisTest, AnalysisTable003, TestSize.Level1) +{ + TableInfo table = AnalysisTable("t1", NO_PRIMARI_KEY_SQL); + EXPECT_EQ(table.GetPrimaryKey().size(), 1); +} +#endif // RELATIONAL_STORE \ No newline at end of file -- Gitee From cea9fcee7140b2b75dff473aa9c065af049d062d Mon Sep 17 00:00:00 2001 From: lianhuix Date: Mon, 9 May 2022 19:53:36 +0800 Subject: [PATCH 6/9] Fix reviews. Signed-off-by: lianhuix --- .../relational/relational_schema_object.cpp | 13 +++++-- .../common/src/schema_negotiate.cpp | 2 +- ...qlite_single_relational_storage_engine.cpp | 34 +++++++++---------- .../sqlite_single_relational_storage_engine.h | 2 +- ...single_ver_relational_storage_executor.cpp | 4 +-- ...e_single_ver_relational_storage_executor.h | 2 +- 6 files changed, 33 insertions(+), 24 deletions(-) diff --git a/services/distributeddataservice/libs/distributeddb/common/src/relational/relational_schema_object.cpp b/services/distributeddataservice/libs/distributeddb/common/src/relational/relational_schema_object.cpp index 043df7406..647211688 100644 --- a/services/distributeddataservice/libs/distributeddb/common/src/relational/relational_schema_object.cpp +++ b/services/distributeddataservice/libs/distributeddb/common/src/relational/relational_schema_object.cpp @@ -225,6 +225,7 @@ void TableInfo::SetPrimaryKey(const std::map &key) void TableInfo::SetPrimaryKey(const FieldName &fieldName, int keyIndex) { if (keyIndex <= 0) { + LOGW("Set primary key index %d less than or equal to 0", keyIndex); return; } @@ -559,6 +560,15 @@ int RelationalSchemaObject::ParseRelationalSchema(const JsonObject &inJsonObject return ParseCheckSchemaTableDefine(inJsonObject); } +namespace { +inline bool IsSchemaVersionValid(const std::string &version) +{ + std::string stripedVersion = SchemaUtils::Strip(version); + return stripedVersion == SchemaConstant::SCHEMA_SUPPORT_VERSION_V2 || + stripedVersion == SchemaConstant::SCHEMA_SUPPORT_VERSION_V2_1; +} +} + int RelationalSchemaObject::ParseCheckSchemaVersion(const JsonObject &inJsonObject) { FieldValue fieldValue; @@ -568,8 +578,7 @@ int RelationalSchemaObject::ParseCheckSchemaVersion(const JsonObject &inJsonObje return errCode; } - if (SchemaUtils::Strip(fieldValue.stringValue) == SchemaConstant::SCHEMA_SUPPORT_VERSION_V2 || - SchemaUtils::Strip(fieldValue.stringValue) == SchemaConstant::SCHEMA_SUPPORT_VERSION_V2_1) { + if (IsSchemaVersionValid(fieldValue.stringValue)) { schemaVersion_ = fieldValue.stringValue; return E_OK; } diff --git a/services/distributeddataservice/libs/distributeddb/common/src/schema_negotiate.cpp b/services/distributeddataservice/libs/distributeddb/common/src/schema_negotiate.cpp index ef184922e..4ecb83f2d 100644 --- a/services/distributeddataservice/libs/distributeddb/common/src/schema_negotiate.cpp +++ b/services/distributeddataservice/libs/distributeddb/common/src/schema_negotiate.cpp @@ -124,7 +124,7 @@ RelationalSyncOpinion SchemaNegotiate::MakeLocalSyncOpinion(const RelationalSche } if (localSchema.GetSchemaVersion() != remoteSchemaObj.GetSchemaVersion()) { - LOGW("[RelationalSchema][opinion] Schema version not match, local %s, remote %s", + LOGW("[RelationalSchema][opinion] Schema version mismatch, local %s, remote %s", localSchema.GetSchemaVersion().c_str(), remoteSchemaObj.GetSchemaVersion().c_str()); return {}; } diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp index 7f140729f..a043a05fd 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.cpp @@ -134,11 +134,11 @@ int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::strin DistributedTableMode mode, bool &schemaChanged) { std::lock_guard lock(schemaMutex_); - RelationalSchemaObject tmpSchema = schema_; - bool isUpgrade = false; - if (tmpSchema.GetTable(tableName).GetTableName() == tableName) { - LOGI("distributed table was already created."); - isUpgrade = true; + RelationalSchemaObject schema = schema_; + bool isUpgraded = false; + if (schema.GetTable(tableName).GetTableName() == tableName) { + LOGI("distributed table bas been created."); + isUpgraded = true; int errCode = UpgradeDistributedTable(tableName); if (errCode != E_OK) { LOGE("Upgrade distributed table failed. %d", errCode); @@ -146,16 +146,16 @@ int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::strin } } - if (tmpSchema.GetTables().size() >= DBConstant::MAX_DISTRIBUTED_TABLE_COUNT) { + if (schema.GetTables().size() >= DBConstant::MAX_DISTRIBUTED_TABLE_COUNT) { LOGE("The number of distributed tables is exceeds limit."); return -E_MAX_LIMITS; } - return CreateDistributedTable(tableName, mode, isUpgrade, schemaChanged, tmpSchema); + return CreateDistributedTable(tableName, mode, isUpgraded, schemaChanged, schema); } int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::string &tableName, - DistributedTableMode mode, bool isUpgrade, bool &schemaChanged, RelationalSchemaObject &tmpSchema) + DistributedTableMode mode, bool isUpgraded, bool &schemaChanged, RelationalSchemaObject &schema) { LOGD("Create distributed table."); int errCode = E_OK; @@ -172,15 +172,15 @@ int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::strin } TableInfo table; - errCode = handle->CreateDistributedTable(tableName, mode, table, isUpgrade); + errCode = handle->CreateDistributedTable(tableName, mode, table, isUpgraded); if (errCode != E_OK) { LOGE("create distributed table failed. %d", errCode); (void)handle->Rollback(); return errCode; } - tmpSchema.AddRelationalTable(table); - errCode = SaveSchemaToMetaTable(handle, tmpSchema); + schema.AddRelationalTable(table); + errCode = SaveSchemaToMetaTable(handle, schema); if (errCode != E_OK) { LOGE("Save schema to meta table for create distributed table failed. %d", errCode); (void)handle->Rollback(); @@ -189,7 +189,7 @@ int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::strin errCode = handle->Commit(); if (errCode == E_OK) { - schema_ = tmpSchema; + schema_ = schema; schemaChanged = true; } return errCode; @@ -198,7 +198,7 @@ int SQLiteSingleRelationalStorageEngine::CreateDistributedTable(const std::strin int SQLiteSingleRelationalStorageEngine::UpgradeDistributedTable(const std::string &tableName) { LOGD("Upgrade distributed table."); - RelationalSchemaObject tmpSchema = schema_; + RelationalSchemaObject schema = schema_; int errCode = E_OK; auto *handle = static_cast(FindExecutor(true, OperatePerm::NORMAL_PERM, errCode)); @@ -213,7 +213,7 @@ int SQLiteSingleRelationalStorageEngine::UpgradeDistributedTable(const std::stri } TableInfo newTable; - errCode = handle->UpgradeDistributedTable(tmpSchema.GetTable(tableName), newTable); + errCode = handle->UpgradeDistributedTable(schema.GetTable(tableName), newTable); if (errCode != E_OK) { LOGE("Upgrade distributed table failed. %d", errCode); (void)handle->Rollback(); @@ -221,8 +221,8 @@ int SQLiteSingleRelationalStorageEngine::UpgradeDistributedTable(const std::stri return errCode; } - tmpSchema.AddRelationalTable(newTable); - errCode = SaveSchemaToMetaTable(handle, tmpSchema); + schema.AddRelationalTable(newTable); + errCode = SaveSchemaToMetaTable(handle, schema); if (errCode != E_OK) { LOGE("Save schema to meta table for upgrade distributed table failed. %d", errCode); (void)handle->Rollback(); @@ -232,7 +232,7 @@ int SQLiteSingleRelationalStorageEngine::UpgradeDistributedTable(const std::stri errCode = handle->Commit(); if (errCode == E_OK) { - schema_ = tmpSchema; + schema_ = schema; } ReleaseExecutor(handle); return errCode; diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h index 1e35a395f..fbaccf28c 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/relational/sqlite_single_relational_storage_engine.h @@ -50,7 +50,7 @@ private: int RegisterFunction(sqlite3 *db) const; int UpgradeDistributedTable(const std::string &tableName); - int CreateDistributedTable(const std::string &tableName, DistributedTableMode mode, bool isUpgrade, + int CreateDistributedTable(const std::string &tableName, DistributedTableMode mode, bool isUpgraded, bool &schemaChanged, RelationalSchemaObject &tmpSchema); RelationalSchemaObject schema_; diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp index 804a75ac4..973c5d53c 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.cpp @@ -62,7 +62,7 @@ int CheckTableconstraint(const TableInfo &table, DistributedTableMode mode) } int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedTable(const std::string &tableName, - DistributedTableMode mode, TableInfo &table, bool isUpgrade) + DistributedTableMode mode, TableInfo &table, bool isUpgraded) { if (dbHandle_ == nullptr) { return -E_INVALID_DB; @@ -87,7 +87,7 @@ int SQLiteSingleVerRelationalStorageExecutor::CreateDistributedTable(const std:: return errCode; } - if (!isUpgrade && !isTableEmpty) { // create distributed table should on an empty table + if (!isUpgraded && !isTableEmpty) { // create distributed table should on an empty table LOGE("[CreateDistributedTable] Create distributed table should on an empty table when first create."); return -E_NOT_SUPPORT; } diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h index 520579515..75808af45 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_relational_storage_executor.h @@ -34,7 +34,7 @@ public: DISABLE_COPY_ASSIGN_MOVE(SQLiteSingleVerRelationalStorageExecutor); int CreateDistributedTable(const std::string &tableName, DistributedTableMode mode, TableInfo &table, - bool isUpgrade); + bool isUpgraded); int UpgradeDistributedTable(const TableInfo &tableInfo, TableInfo &newTableInfo); -- Gitee From a1583ea3eead36964ac8d72583c7aa64caf99ac7 Mon Sep 17 00:00:00 2001 From: lianhuix Date: Wed, 11 May 2022 10:06:00 +0800 Subject: [PATCH 7/9] Fix compile issue Signed-off-by: lianhuix --- .../distributeddb_relational_schema_analysis_test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_schema_analysis_test.cpp b/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_schema_analysis_test.cpp index 94a8d78a6..ab90527d7 100644 --- a/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_schema_analysis_test.cpp +++ b/services/distributeddataservice/libs/distributeddb/test/unittest/common/storage/distributeddb_relational_schema_analysis_test.cpp @@ -116,7 +116,7 @@ TableInfo AnalysisTable(const std::string &name, const std::string &sql) { HWTEST_F(DistributedDBRelationalSchemaAnalysisTest, AnalysisTable001, TestSize.Level1) { TableInfo table = AnalysisTable("sync_data", NORMAL_CREATE_TABLE_SQL); - EXPECT_EQ(table.GetPrimaryKey().size(), 1); + EXPECT_EQ(table.GetPrimaryKey().size(), 1u); } /** @@ -129,7 +129,7 @@ HWTEST_F(DistributedDBRelationalSchemaAnalysisTest, AnalysisTable001, TestSize.L HWTEST_F(DistributedDBRelationalSchemaAnalysisTest, AnalysisTable002, TestSize.Level1) { TableInfo table = AnalysisTable("sync_data", MULTI_PRIMARI_KEY_SQL); - EXPECT_EQ(table.GetPrimaryKey().size(), 2); + EXPECT_EQ(table.GetPrimaryKey().size(), 2u); } /** @@ -142,6 +142,6 @@ HWTEST_F(DistributedDBRelationalSchemaAnalysisTest, AnalysisTable002, TestSize.L HWTEST_F(DistributedDBRelationalSchemaAnalysisTest, AnalysisTable003, TestSize.Level1) { TableInfo table = AnalysisTable("t1", NO_PRIMARI_KEY_SQL); - EXPECT_EQ(table.GetPrimaryKey().size(), 1); + EXPECT_EQ(table.GetPrimaryKey().size(), 1u); } #endif // RELATIONAL_STORE \ No newline at end of file -- Gitee From 2a70297c47c81383c4c5d08199aa182640dab1ef Mon Sep 17 00:00:00 2001 From: zqq Date: Tue, 17 May 2022 18:56:35 +0800 Subject: [PATCH 8/9] fix code check Signed-off-by: zqq --- .../distributeddataservice/libs/distributeddb/include/query.h | 4 ++-- .../src/multiver/multi_ver_natural_store_connection.cpp | 4 +--- .../storage/src/operation/multi_ver_database_oper.cpp | 3 +-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/services/distributeddataservice/libs/distributeddb/include/query.h b/services/distributeddataservice/libs/distributeddb/include/query.h index 2f01c676c..8a340f14b 100644 --- a/services/distributeddataservice/libs/distributeddb/include/query.h +++ b/services/distributeddataservice/libs/distributeddb/include/query.h @@ -99,7 +99,7 @@ public: DB_API Query &In(const std::string &field, const std::vector &values) { std::vector fieldValues; - QueryValueType type; + QueryValueType type = QueryValueType::VALUE_TYPE_INVALID; for (const auto &value : values) { FieldValue fieldValue; type = GetFieldTypeAndValue(value, fieldValue); @@ -114,7 +114,7 @@ public: DB_API Query &NotIn(const std::string &field, const std::vector &values) { std::vector fieldValues; - QueryValueType type; + QueryValueType type = QueryValueType::VALUE_TYPE_INVALID; for (const auto &value : values) { FieldValue fieldValue; type = GetFieldTypeAndValue(value, fieldValue); diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/multiver/multi_ver_natural_store_connection.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/multiver/multi_ver_natural_store_connection.cpp index 0820c9adc..6ba32ddb8 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/multiver/multi_ver_natural_store_connection.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/multiver/multi_ver_natural_store_connection.cpp @@ -238,9 +238,7 @@ int MultiVerNaturalStoreConnection::DeleteBatch(const IOption &option, const std errCode = writeHandle_->Delete(item); if (errCode == E_OK) { needCommit = true; - } else if (errCode == -E_NOT_FOUND) { - errCode = E_OK; - } else { + } else if (errCode != -E_NOT_FOUND) { if (isAuto) { (void)(RollBackTransactionInner()); } diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/operation/multi_ver_database_oper.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/operation/multi_ver_database_oper.cpp index a7aeccc49..76a33727a 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/operation/multi_ver_database_oper.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/operation/multi_ver_database_oper.cpp @@ -123,8 +123,7 @@ int MultiVerDatabaseOper::RekeyPostHandle(const CipherPassword &passwd) if (errCode != E_OK) { return errCode; } - errCode = RekeyRecover(multiVerNaturalStore_->GetDbProperties()); - return E_OK; + return RekeyRecover(multiVerNaturalStore_->GetDbProperties()); } int MultiVerDatabaseOper::ExportAllDatabases(const std::string ¤tDir, const CipherPassword &passwd, -- Gitee From 79cdfa56ed572f2a4bb4db06e9219d43cc769664 Mon Sep 17 00:00:00 2001 From: lidwchn Date: Wed, 18 May 2022 11:34:17 +0800 Subject: [PATCH 9/9] Fix unused variable. Signed-off-by: lidwchn --- .../storage/src/sqlite/sqlite_single_ver_storage_executor.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.cpp b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.cpp index 52e65653b..63d102620 100644 --- a/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.cpp +++ b/services/distributeddataservice/libs/distributeddb/storage/src/sqlite/sqlite_single_ver_storage_executor.cpp @@ -498,6 +498,10 @@ int SQLiteSingleVerStorageExecutor::GetSyncDataItems(std::vector &data errCode = SQLiteUtils::StepWithRetry(statement, isMemDb_); if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { errCode = GetDataItemForSync(statement, dataItem); + if (errCode != E_OK) { + LOGE("GetDataItemForSync failed:%d", errCode); + return errCode; + } } else { if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { LOGD("Get sync data finished, size of packet:%zu, number of item:%zu", dataTotalSize, dataItems.size()); -- Gitee