diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/BUILD.gn b/services/distributeddataservice/service/data_share/gaussdb_rd/BUILD.gn old mode 100644 new mode 100755 index 47128f8c80d67b921fc167490beeee2ead9e6e6c..3f44a3739d2354fb04b8ed9150bd0a499a73b6a5 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/BUILD.gn +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/BUILD.gn @@ -59,6 +59,7 @@ ohos_shared_library("gaussdb_rd") { "src/executor/document/grd_resultset_api.cpp", "src/interface/src/collection.cpp", "src/interface/src/doc_errno.cpp", + "src/interface/src/document_key.cpp", "src/interface/src/document_store.cpp", "src/interface/src/document_store_manager.cpp", "src/interface/src/projection_tree.cpp", @@ -82,9 +83,9 @@ ohos_shared_library("gaussdb_rd") { external_deps = [ "c_utils:utils", - "hisysevent_native:libhisysevent", - "hitrace_native:hitrace_meter", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", ] subsystem_name = "distributeddatamgr" diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/collection_option.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/collection_option.h index 8f982807fea5db5f8b807f52c08c8723275d128c..6062f9fec76d23cb0179f39dfc5eda368e381599 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/collection_option.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/collection_option.h @@ -23,9 +23,6 @@ class CollectionOption final { public: static CollectionOption ReadOption(const std::string &optStr, int &errCode); - uint32_t GetMaxDoc() const; - std::string ToString() const; - bool operator==(const CollectionOption &targetOption) const; bool operator!=(const CollectionOption &targetOption) const; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/doc_limit.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/doc_limit.h index 557b92da52af289493c275975b93c30d6b707de2..fc2515f323e0e25c6af78f73b3e57930d62b60db 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/doc_limit.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/doc_limit.h @@ -17,6 +17,6 @@ #define DOC_LIMIT_H namespace DocumentDB { -constexpr int MAX_DB_CONFIG_LEN = 512 * 1024; // 512 * 1024: 512k length +constexpr int MAX_DB_CONFIG_LEN = 1024 * 1024; // 1024 * 1024: 1024k length } // namespace DocumentDB #endif // DOC_LIMIT_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h index ff525ecbd6d13eab66edd89a2ce53c3b81cc3286..0c767b9aed79fd14136cfdbea0e9c33f38e475c3 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h @@ -28,7 +28,7 @@ struct QueryContext { ProjectionTree projectionTree; bool ifShowId = false; bool viewType = false; - bool isOnlyId = false; + bool isIdExist = false; }; } // namespace DocumentDB #endif // DOCUMENT_TYPE_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/collection_option.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/collection_option.cpp index 324a29312c76e1160114cd56829f2cb85cf61005..d5310f73f78a580ed675f06c27ab48b302c5ac9b 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/collection_option.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/collection_option.cpp @@ -92,24 +92,4 @@ CollectionOption CollectionOption::ReadOption(const std::string &optStr, int &er option.option_ = optStr; return option; } - -uint32_t CollectionOption::GetMaxDoc() const -{ - return maxDoc_; -} - -std::string CollectionOption::ToString() const -{ - return option_; -} - -bool CollectionOption::operator==(const CollectionOption &targetOption) const -{ - return maxDoc_ == targetOption.maxDoc_; -} - -bool CollectionOption::operator!=(const CollectionOption &targetOption) const -{ - return !(*this == targetOption); -} } // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_config.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_config.cpp index 44ce39b6dfb9ef5060619d9432aec688433a0d1d..5061139eebd491f7adf5a1483d32523328320f42 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_config.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/db_config.cpp @@ -56,6 +56,10 @@ bool CheckAndGetDBConfig(const JsonObject &config, const std::string &name, cons int errCode = E_OK; ValueObject configValue = config.GetObjectByPath(configField, errCode); + if (errCode != E_OK) { + GLOGE("Can not find config Value"); + return errCode; + } if (configValue.GetValueType() != ValueObject::ValueType::VALUE_NUMBER) { GLOGE("Check DB config failed, not found or type of %s is not NUMBER.", name.c_str()); return false; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp index 61f29c65ee047542ba2292ae4814f50faa230ce6..a967d2e69125bd45aa34a6d47f1abba381eea4e8 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp @@ -14,6 +14,8 @@ */ #include "json_common.h" +#include + #include "doc_errno.h" #include "log_print.h" @@ -82,26 +84,27 @@ std::vector JsonCommon::GetLeafValue(const JsonObject &node) bool JsonCommon::CheckNode(JsonObject &node) { - while (!node.IsNull()) { - int ret = 0; + std::queue jsonQueue; + jsonQueue.push(node); + while (!jsonQueue.empty()) { std::set fieldSet; bool isFieldNameExist = true; - std::string fieldName = node.GetItemField(ret); + int ret = E_OK; + JsonObject item = jsonQueue.front(); + jsonQueue.pop(); + std::string fieldName = item.GetItemField(ret); if (ret != E_OK) { isFieldNameExist = false; } - if (fieldSet.find(fieldName) != fieldSet.end()) { return false; } - if (isFieldNameExist) { fieldSet.insert(fieldName); if (fieldName.empty()) { return false; } } - for (size_t i = 0; i < fieldName.size(); i++) { if (!((isalpha(fieldName[i])) || (isdigit(fieldName[i])) || fieldName[i] == '_')) { return false; @@ -110,14 +113,12 @@ bool JsonCommon::CheckNode(JsonObject &node) return false; } } - - if (!node.GetChild().IsNull()) { - JsonObject nodeNew = node.GetChild(); - if (!CheckNode(nodeNew)) { - return false; - } + if (!item.GetChild().IsNull()) { + jsonQueue.push(item.GetChild()); + } + if (!item.GetNext().IsNull()) { + jsonQueue.push(item.GetNext()); } - node = node.GetNext(); } return true; } @@ -129,10 +130,14 @@ bool JsonCommon::CheckJsonField(JsonObject &jsonObj) bool JsonCommon::CheckProjectionNode(JsonObject &node, bool isFirstLevel, int &errCode) { - while (!node.IsNull()) { + std::queue jsonQueue; + jsonQueue.push(node); + while (!jsonQueue.empty()) { int ret = 0; std::set fieldSet; - std::string fieldName = node.GetItemField(ret); + JsonObject item = jsonQueue.front(); + jsonQueue.pop(); + std::string fieldName = item.GetItemField(ret); if (fieldName.empty()) { errCode = -E_INVALID_ARGS; return false; @@ -154,13 +159,12 @@ bool JsonCommon::CheckProjectionNode(JsonObject &node, bool isFirstLevel, int &e return false; } } - if (!node.GetChild().IsNull()) { - JsonObject nodeNew = node.GetChild(); - if (!CheckProjectionNode(nodeNew, false, errCode)) { - return false; - } + if (!item.GetNext().IsNull()) { + jsonQueue.push(item.GetNext()); + } + if (!item.GetChild().IsNull()) { + jsonQueue.push(item.GetChild()); } - node = node.GetNext(); } return true; } @@ -214,8 +218,7 @@ int JsonCommon::ParseNode(JsonObject &node, std::vector singlePath, } if (!node.GetChild().IsNull() && node.GetChild().GetItemField() != "") { JsonObject nodeNew = node.GetChild(); - int ret = E_OK; - ret = ParseNode(nodeNew, singlePath, resultPath, false); + int ret = ParseNode(nodeNew, singlePath, resultPath, false); if (ret != E_OK) { return ret; } @@ -340,7 +343,7 @@ bool AddSpliteHitField(const JsonObject &src, const JsonObject &item, JsonFieldP return true; } - for (int i = abandonPath.size() - 1; i > -1; i--) { + for (int32_t i = static_cast(abandonPath.size()) - 1; i > -1; i--) { if (hitItem.GetType() != JsonObject::Type::JSON_OBJECT) { GLOGE("Add collapse item to object failed, path not exist."); externErrCode = -E_DATA_CONFLICT; @@ -382,7 +385,7 @@ bool AddSpliteField(const JsonObject &src, const JsonObject &item, const JsonFie return false; } JsonFieldPath newHitPath; - for (int i = abandonPath.size() - 1; i > -1; i--) { + for (int32_t i = static_cast(abandonPath.size()) - 1; i > -1; i--) { if (hitItem.GetType() != JsonObject::Type::JSON_OBJECT) { GLOGE("Add collapse item to object failed, path not exist."); externErrCode = -E_DATA_CONFLICT; @@ -505,9 +508,7 @@ bool JsonNodeAppend(const JsonObject &src, const JsonFieldPath &path, const Json int errCode = E_OK; JsonObject srcFatherItem = src.FindItem(fatherPath, errCode); std::string lastFieldName = itemPath.back(); - int isAddedFlag = false; if (errCode != E_OK) { - isAddedFlag = true; AddSpliteField(src, item, itemPath, externErrCode); return false; } @@ -521,7 +522,6 @@ bool JsonNodeAppend(const JsonObject &src, const JsonFieldPath &path, const Json GLOGE("Add item to object failed. %d", errCode); return false; } - isAddedFlag = true; return false; } if (!isCollapse) { @@ -529,13 +529,10 @@ bool JsonNodeAppend(const JsonObject &src, const JsonFieldPath &path, const Json if (!ret) { return false; // replace failed } - isAddedFlag = true; return false; // Different node types, overwrite directly, skip child node } - if (!isAddedFlag) { - GLOGE("Add nothing because data conflict"); - externErrCode = -E_DATA_CONFLICT; - } + GLOGE("Add nothing because data conflict"); + externErrCode = -E_DATA_CONFLICT; return false; // Source path not exist, overwrite directly, skip child node } } // namespace @@ -544,8 +541,8 @@ int JsonCommon::Append(const JsonObject &src, const JsonObject &add, bool isRepl { int externErrCode = E_OK; JsonObjectIterator(add, {}, - [&src, &externErrCode, &isReplace](const JsonFieldPath &path, const JsonObject &father, - const JsonObject &item) { + [&src, &externErrCode, &isReplace](const JsonFieldPath &path, + const JsonObject &father, const JsonObject &item) { bool isCollapse = false; // Whether there is a path generated by the dot operator, such as t1.t2.t3 JsonFieldPath itemPath = ExpendPathForField(path, isCollapse); if (src.IsFieldExists(itemPath)) { @@ -645,12 +642,10 @@ bool JsonCommon::IsObjectItemMatch(const JsonObject &srcItem, const JsonObject & bool JsonCommon::JsonEqualJudge(const JsonFieldPath &itemPath, const JsonObject &src, const JsonObject &item, bool &isCollapse, int &isMatchFlag) { - int errCode; - int isAlreadyMatched = 0; + int errCode = E_OK; JsonObject srcItem = src.FindItemPowerMode(itemPath, errCode); if (errCode != -E_JSON_PATH_NOT_EXISTS && srcItem == item) { isMatchFlag = true; - isAlreadyMatched = 1; return false; } JsonFieldPath granpaPath = itemPath; @@ -661,7 +656,6 @@ bool JsonCommon::JsonEqualJudge(const JsonFieldPath &itemPath, const JsonObject JsonObject fatherItem = granpaItem.GetChild(); while (!fatherItem.IsNull()) { if ((fatherItem.GetObjectItem(lastFieldName, errCode) == item)) { // this errCode is always E_OK - isAlreadyMatched = 1; isMatchFlag = true; break; } @@ -670,6 +664,7 @@ bool JsonCommon::JsonEqualJudge(const JsonFieldPath &itemPath, const JsonObject } return false; } + int isAlreadyMatched = 0; // means no match anything return IsObjectItemMatch(srcItem, item, isAlreadyMatched, isCollapse, isMatchFlag); } diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp index 01513f9f83652c107f714e2e1e4e41d288db0c66..8b17915985e9a29cde9706665278d851f0978ad3 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/executor/document/check_common.cpp @@ -75,7 +75,7 @@ bool CheckCommon::CheckCollectionName(const std::string &collectionName, std::st return true; } -int CheckCommon::CheckFilter(JsonObject &filterObj, bool &isOnlyId, std::vector> &filterPath) +int CheckCommon::CheckFilter(JsonObject &filterObj, std::vector> &filterPath, bool &isIdExist) { for (size_t i = 0; i < filterPath.size(); i++) { if (filterPath[i].size() > JSON_DEEP_MAX) { @@ -83,9 +83,6 @@ int CheckCommon::CheckFilter(JsonObject &filterObj, bool &isOnlyId, std::vector< return -E_INVALID_ARGS; } } - if (!filterObj.GetChild().GetNext().IsNull()) { // check contained other field at the same level as the id node - isOnlyId = false; - } for (size_t i = 0; i < filterPath.size(); i++) { if (filterPath[i].empty()) { return -E_INVALID_JSON_FORMAT; @@ -104,15 +101,11 @@ int CheckCommon::CheckFilter(JsonObject &filterObj, bool &isOnlyId, std::vector< return -E_INVALID_ARGS; } } - bool isIdExisit = false; - int ret = CheckIdFormat(filterObj, isIdExisit); + int ret = CheckIdFormat(filterObj, isIdExist); if (ret != E_OK) { GLOGE("Filter Id format is illegal"); return ret; } - if (!isIdExisit) { - isOnlyId = false; - } return E_OK; } @@ -132,18 +125,13 @@ int CheckCommon::CheckIdFormat(JsonObject &filterJson, bool &isIdExisit) return E_OK; } -int CheckCommon::CheckDocument(JsonObject &documentObj) +int CheckCommon::CheckDocument(JsonObject &documentObj, bool &isIdExist) { if (documentObj.GetDeep() > JSON_DEEP_MAX) { GLOGE("documentObj's json deep is deeper than JSON_DEEP_MAX"); return -E_INVALID_ARGS; } - bool isIdExist = true; int ret = CheckIdFormat(documentObj, isIdExist); - if (!isIdExist) { - GLOGE("Document Id format is illegal"); - return -E_INVALID_ARGS; - } if (ret != E_OK) { return ret; } @@ -155,34 +143,50 @@ int CheckCommon::CheckDocument(JsonObject &documentObj) return E_OK; } -int CheckCommon::CheckUpdata(JsonObject &updataObj, std::vector> &path) +int SplitFieldName(const std::string &fieldName, std::vector &allFieldsName) { - if (updataObj.GetDeep() > JSON_DEEP_MAX) { - GLOGE("projectionObj's json deep is deeper than JSON_DEEP_MAX"); - return -E_INVALID_ARGS; - } - for (size_t i = 0; i < path.size(); i++) { - if (path[i].empty()) { - return -E_INVALID_JSON_FORMAT; + std::string tempParseName; + std::string priFieldName = fieldName; + for (size_t j = 0; j < priFieldName.size(); j++) { + if (priFieldName[j] != '.') { + tempParseName += priFieldName[j]; } - for (size_t j = 0; j < path[i].size(); j++) { - if (path[i][j].empty()) { + if (priFieldName[j] == '.' || j == priFieldName.size() - 1) { + if ((j > 0 && priFieldName[j] == '.' && priFieldName[j - 1] == '.') || + (priFieldName[j] == '.' && j == priFieldName.size() - 1)) { return -E_INVALID_ARGS; } - for (auto oneChar : path[i][j]) { + allFieldsName.emplace_back(tempParseName); + tempParseName.clear(); + } + } + return E_OK; +} + +int CheckCommon::CheckUpdata(JsonObject &updataObj) +{ + JsonObject jsonTemp = updataObj.GetChild(); + size_t maxDeep = 0; + while (!jsonTemp.IsNull()) { + std::vector allFieldsName; + int errCode = SplitFieldName(jsonTemp.GetItemField(), allFieldsName); + if (errCode != E_OK) { + return errCode; + } + for (const auto &fieldName : allFieldsName) { + for (auto oneChar : fieldName) { if (!((isalpha(oneChar)) || (isdigit(oneChar)) || (oneChar == '_'))) { + GLOGE("updata fieldName is illegal"); return -E_INVALID_ARGS; } } } - if (!path[i].empty() && !path[i][0].empty() && isdigit(path[i][0][0])) { - return -E_INVALID_ARGS; - } - } - for (const auto &singlePath : path) { - if (singlePath.size() > JSON_DEEP_MAX) { + maxDeep = std::max(allFieldsName.size() + jsonTemp.GetDeep(), maxDeep); + if (maxDeep > JSON_DEEP_MAX) { + GLOGE("document's json deep is deeper than JSON_DEEP_MAX"); return -E_INVALID_ARGS; } + jsonTemp = jsonTemp.GetNext(); } bool isIdExist = true; CheckIdFormat(updataObj, isIdExist); @@ -210,7 +214,7 @@ int CheckCommon::CheckProjection(JsonObject &projectionObj, std::vector> &filterPath); - static int CheckIdFormat(JsonObject &filterJson, bool &isIdExisit); - static int CheckDocument(JsonObject &documentObj); - static int CheckUpdata(JsonObject &updataObj, std::vector> &path); + static int CheckFilter(JsonObject &document, std::vector> &filterPath, bool &isIdExist); + static int CheckIdFormat(JsonObject &data, bool &isIdExisit); + static int CheckDocument(JsonObject &document, bool &isIdExist); + static int CheckUpdata(JsonObject &updataObj); static int CheckProjection(JsonObject &projectionObj, std::vector> &path); }; using Key = std::vector; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/collection.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/collection.h index c04f5c7b9007ae17bd1e9b3f975dc6e2eeafb7a1..30d109eda401489efb6fed1ade829869290271bc 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/collection.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/collection.h @@ -25,21 +25,19 @@ namespace DocumentDB { class Collection { public: Collection(const std::string &name, KvStoreExecutor *executor); - Collection(const Collection &other); - Collection() {}; ~Collection(); - int PutDocument(const Key &key, const Value &document); - int InsertDocument(const Key &key, const Value &document); - int GetDocument(const Key &key, Value &document) const; - int GetMatchedDocument(const JsonObject &filterObj, std::vector> &values) const; - int DeleteDocument(const Key &key); + int InsertDocument(const std::string &id, const std::string &document, bool &isIdExist); + int GetDocumentById(Key &key, Value &document) const; + int GetMatchedDocument(const JsonObject &filterObj, Key &key, std::pair &values, + int isIdExist) const; + int DeleteDocument(Key &key); int IsCollectionExists(int &errCode); - int UpsertDocument(const std::string &id, const std::string &document, bool isReplace = true); - bool FindDocument(); - int UpdateDocument(const std::string &id, const std::string &document, bool isReplace = false); + int UpsertDocument(const std::string &id, const std::string &newDocument, bool &isIdExist); + int UpdateDocument(const std::string &id, const std::string &document); private: + int InsertUntilSuccess(Key &key, const std::string &id, Value &valSet); std::string name_; KvStoreExecutor *executor_ = nullptr; }; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/doc_errno.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/doc_errno.h index 274bc84148347b069bcf4b0ff3e0552420db7715..75f636b55da36eeec89ec0476e85807df1c99e9f 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/doc_errno.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/doc_errno.h @@ -40,6 +40,7 @@ constexpr int E_RESOURCE_BUSY = E_BASE + 50; constexpr int E_FAILED_MEMORY_ALLOCATE = E_BASE + 51; constexpr int E_INNER_ERROR = E_BASE + 52; constexpr int E_INVALID_FILE_FORMAT = E_BASE + 53; +constexpr int E_FAILED_FILE_OPERATION = E_BASE + 54; int TransferDocErr(int err); } // namespace DocumentDB diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_key.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_key.h new file mode 100644 index 0000000000000000000000000000000000000000..32dbd79e8b7b13ee9d8c8adc8b0d70a4def3432e --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_key.h @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2023 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 DOCUMENT_KEY_H +#define DOCUMENT_KEY_H + +#include +#include + +#include "json_object.h" + +#define GRD_DOC_OID_TIME_SIZE 4 +#define GRD_DOC_OID_INCREMENTAL_VALUE_SIZE 2 +#define GRD_DOC_OID_SIZE (GRD_DOC_OID_TIME_SIZE + GRD_DOC_OID_INCREMENTAL_VALUE_SIZE) +#define GRD_DOC_OID_HEX_SIZE (GRD_DOC_OID_SIZE * 2) +#define GRD_DOC_ID_TYPE_SIZE 1 + +namespace DocumentDB { +enum class DocIdType { + INT = 1, + STRING, +}; + +struct DocKey { +public: + int32_t keySize; + std::string key; + uint8_t type; +}; + +class DocumentKey { +public: + static int GetOidDocKey(DocKey &key); +}; +} // namespace DocumentDB +#endif // DOCUMENT_KEY_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h index cefdc9e308305435398eaf9b256ecb24bcece392..3f1deacb9279377a9e1f689672beeed5a83dd38e 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h @@ -69,13 +69,12 @@ public: private: int UpdateDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, const std::string &update, bool &isReplace); - int UpsertDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, JsonObject &documentObj, - bool &isReplace); - int InsertDataIntoDB(const std::string &collection, const std::string &document, JsonObject &documentObj); + int UpsertDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, const std::string &document, + JsonObject &documentObj, bool &isReplace); + int InsertDataIntoDB(const std::string &collection, const std::string &document, JsonObject &documentObj, + bool &isIdExist); int DeleteDataFromDB(std::shared_ptr &context, JsonObject &filterObj); int InitFindResultSet(GRD_ResultSet *grdResultSet, std::shared_ptr &context); - int CheckUpsertConflict(bool &isIdExist, std::shared_ptr &context, JsonObject &filterObj, - std::string &docId, Collection &coll); KvStoreExecutor *executor_ = nullptr; std::map collections_; std::function closeNotifier_; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/projection_tree.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/projection_tree.h index f7c7b0954c7fb32892cc6ef8f4ddfda918e4e427..3cdca06d33f336618a322849ce910432fb6a2aea 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/projection_tree.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/projection_tree.h @@ -28,7 +28,6 @@ struct ProjectionNode { std::unordered_map sonNode; bool isDeepest; int Deep; - int ViewType; ProjectionNode() { Deep = 0; @@ -43,7 +42,7 @@ struct ProjectionNode { class ProjectionTree { public: int ParseTree(std::vector> &path); - bool SearchTree(std::vector &singlePath, int &index); + bool SearchTree(std::vector &singlePath, size_t &index); private: ProjectionNode node_; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h index 65956e090968ca6d263ae318ec4f3c6d499ce1dc..01c42c63e52940b26a1eac9f54caf45fdb01252c 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h @@ -16,6 +16,7 @@ #ifndef RESULTSET_H #define RESULTSET_H +#include #include #include @@ -30,24 +31,27 @@ class ResultSet { public: ResultSet(); ~ResultSet(); - int Init(std::shared_ptr &context, DocumentStore *store, bool ifField); + int Init(std::shared_ptr &context, DocumentStore *store, bool isCutBranch); int GetNext(bool isNeedTransaction = false, bool isNeedCheckTable = false); int GetValue(char **value); + int GetValue(std::string &value); int GetKey(std::string &key); int EraseCollection(); private: int GetNextInner(bool isNeedCheckTable); - int CutJsonBranch(std::string &jsonData); + int GetValueFromDB(Key &key, JsonObject &filterObj, std::string &jsonKey, std::string &jsonData); + int CutJsonBranch(std::string &jsonKey, std::string &jsonData); int CheckCutNode(JsonObject *node, std::vector singleCutPath, std::vector> &allCutPath); int GetNextWithField(); DocumentStore *store_ = nullptr; - bool ifField_ = false; + bool isCutBranch_ = false; size_t index_ = 0; std::shared_ptr context_; - std::vector> matchDatas_; + std::pair matchData_; + std::string lastKeyIndex_; }; } // namespace DocumentDB #endif // RESULTSET_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h index 0a59f9ffd8ad2962189db64cc468f5d44a0ad85d..abdf5c9b3ce66af2c112ed19fc54bb3fec633915 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h @@ -25,6 +25,6 @@ namespace DocumentDB { class ValueObject; -int InitResultSet(std::shared_ptr &context, DocumentStore *store, ResultSet &resultSet, bool ifField); +int InitResultSet(std::shared_ptr &context, DocumentStore *store, ResultSet &resultSet, bool isCutBranch); } // namespace DocumentDB #endif // RESULTSET_COMMON_H diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/collection.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/collection.cpp index 1e6d04f2521cdfdb1dbccbc154f163353ff922fe..d06b0943d59c0519231b5f7c03481cf405b1a479 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/collection.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/collection.cpp @@ -18,11 +18,10 @@ #include "check_common.h" #include "db_constant.h" #include "doc_errno.h" +#include "document_key.h" #include "log_print.h" namespace DocumentDB { -constexpr int JSON_LENS_MAX = 1024 * 1024; - Collection::Collection(const std::string &name, KvStoreExecutor *executor) : executor_(executor) { std::string lowerCaseName = name; @@ -32,26 +31,24 @@ Collection::Collection(const std::string &name, KvStoreExecutor *executor) : exe name_ = DBConstant::COLL_PREFIX + lowerCaseName; } -Collection::Collection(const Collection &other) -{ - name_ = other.name_; - executor_ = other.executor_; -} - Collection::~Collection() { executor_ = nullptr; } -int Collection::PutDocument(const Key &key, const Value &document) +int Collection::InsertUntilSuccess(Key &key, const std::string &id, Value &valSet) { - if (executor_ == nullptr) { - return -E_INNER_ERROR; - } - return executor_->PutData(name_, key, document); + DocKey docKey; + key.assign(id.begin(), id.end()); + int errCode = executor_->InsertData(name_, key, valSet); + while (errCode == -E_DATA_CONFLICT) { // if id alreay exist, create new one. + DocumentKey::GetOidDocKey(docKey); + key.assign(docKey.key.begin(), docKey.key.end()); + errCode = executor_->InsertData(name_, key, valSet); + } + return errCode; } - -int Collection::InsertDocument(const Key &key, const Value &document) +int Collection::InsertDocument(const std::string &id, const std::string &document, bool &isIdExist) { if (executor_ == nullptr) { return -E_INNER_ERROR; @@ -64,36 +61,33 @@ int Collection::InsertDocument(const Key &key, const Value &document) if (!isCollectionExist) { return -E_INVALID_ARGS; } - return executor_->InsertData(name_, key, document); -} - -bool Collection::FindDocument() -{ - if (executor_ == nullptr) { - return -E_INNER_ERROR; + Key key; + Value valSet(document.begin(), document.end()); + if (!isIdExist) { + return InsertUntilSuccess(key, id, valSet); } - int errCode = E_OK; - return executor_->IsCollectionExists(name_, errCode); + key.assign(id.begin(), id.end()); + return executor_->InsertData(name_, key, valSet); } -int Collection::GetDocument(const Key &key, Value &document) const +int Collection::GetDocumentById(Key &key, Value &document) const { if (executor_ == nullptr) { return -E_INNER_ERROR; } - return executor_->GetData(name_, key, document); + return executor_->GetDataById(name_, key, document); } -int Collection::GetMatchedDocument(const JsonObject &filterObj, - std::vector> &values) const +int Collection::GetMatchedDocument(const JsonObject &filterObj, Key &key, std::pair &values, + int isIdExist) const { if (executor_ == nullptr) { return -E_INNER_ERROR; } - return executor_->GetFieldedData(name_, filterObj, values); + return executor_->GetDataByFilter(name_, key, filterObj, values, isIdExist); } -int Collection::DeleteDocument(const Key &key) +int Collection::DeleteDocument(Key &key) { if (executor_ == nullptr) { return -E_INNER_ERROR; @@ -114,7 +108,7 @@ int Collection::IsCollectionExists(int &errCode) return executor_->IsCollectionExists(name_, errCode); } -int Collection::UpsertDocument(const std::string &id, const std::string &document, bool isReplace) +int Collection::UpsertDocument(const std::string &id, const std::string &newDocument, bool &isDataExist) { if (executor_ == nullptr) { return -E_INNER_ERROR; @@ -129,47 +123,16 @@ int Collection::UpsertDocument(const std::string &id, const std::string &documen GLOGE("Collection not created."); return -E_INVALID_ARGS; } - - JsonObject upsertValue = JsonObject::Parse(document, errCode, true); - if (errCode != E_OK) { - GLOGD("Parse upsert value failed. %d", errCode); - return errCode; + Key key; + Value valSet(newDocument.begin(), newDocument.end()); + if (!isDataExist) { + return InsertUntilSuccess(key, id, valSet); } - - Key keyId(id.begin(), id.end()); - Value valSet(document.begin(), document.end()); - if (!isReplace) { - Value valueGot; - errCode = executor_->GetData(name_, keyId, valueGot); - std::string valueGotStr = std::string(valueGot.begin(), valueGot.end()); - if (errCode != E_OK && errCode != -E_NOT_FOUND) { - GLOGW("Get original document failed. %d", errCode); - return errCode; - } else if (errCode == E_OK) { // document has been inserted - GLOGD("Document has been inserted, append value."); - JsonObject originValue = JsonObject::Parse(valueGotStr, errCode, true); - if (errCode != E_OK) { - GLOGD("Parse original value failed. %d %s", errCode, valueGotStr.c_str()); - return errCode; - } - - errCode = JsonCommon::Append(originValue, upsertValue, isReplace); - if (errCode != E_OK) { - GLOGD("Append value failed. %d", errCode); - return errCode; - } - std::string valStr = originValue.Print(); - if (valStr.length() >= JSON_LENS_MAX) { - GLOGE("document's length is too long"); - return -E_OVER_LIMIT; - } - valSet = { valStr.begin(), valStr.end() }; - } - } - return executor_->PutData(name_, keyId, valSet); + key.assign(id.begin(), id.end()); + return executor_->PutData(name_, key, valSet); } -int Collection::UpdateDocument(const std::string &id, const std::string &update, bool isReplace) +int Collection::UpdateDocument(const std::string &id, const std::string &newDocument) { if (executor_ == nullptr) { return -E_INNER_ERROR; @@ -184,40 +147,8 @@ int Collection::UpdateDocument(const std::string &id, const std::string &update, GLOGE("Collection not created."); return -E_INVALID_ARGS; } - - JsonObject updateValue = JsonObject::Parse(update, errCode, true); - if (errCode != E_OK) { - GLOGD("Parse upsert value failed. %d", errCode); - return errCode; - } - Key keyId(id.begin(), id.end()); - Value valueGot; - errCode = executor_->GetData(name_, keyId, valueGot); - std::string valueGotStr = std::string(valueGot.begin(), valueGot.end()); - if (errCode == -E_NOT_FOUND) { - GLOGW("Get original document not found."); - return -E_NOT_FOUND; - } else if (errCode != E_OK) { - GLOGE("Get original document failed. %d", errCode); - return errCode; - } - JsonObject originValue = JsonObject::Parse(valueGotStr, errCode, true); - if (errCode != E_OK) { - GLOGD("Parse original value failed. %d %s", errCode, valueGotStr.c_str()); - return errCode; - } - errCode = JsonCommon::Append(originValue, updateValue, isReplace); - if (errCode != E_OK) { - GLOGD("Append value failed. %d", errCode); - return errCode; - } - std::string valStr = originValue.Print(); - if (valStr.length() >= JSON_LENS_MAX) { - GLOGE("document's length is too long"); - return -E_OVER_LIMIT; - } - Value valSet(valStr.begin(), valStr.end()); + Value valSet(newDocument.begin(), newDocument.end()); return executor_->PutData(name_, keyId, valSet); } } // namespace DocumentDB diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/doc_errno.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/doc_errno.cpp index 3c8887e957e606842de03c51a4ee26afbaaedc06..bf9dca10b3fba2ae988d605ec65d609531dd49e9 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/doc_errno.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/doc_errno.cpp @@ -21,8 +21,8 @@ namespace DocumentDB { int GetErrorCategory(int errCode) { int categoryCode = errCode % 1000000; // 1000000: mod to get last 6 digits - categoryCode /= 1000; // 1000: deviced to remove first 3 digits - categoryCode *= 1000; // 1000: multiply to pad the output + categoryCode /= 1000; // 1000: deviced to remove first 3 digits + categoryCode *= 1000; // 1000: multiply to pad the output return categoryCode; } @@ -63,6 +63,8 @@ int TransferDocErr(int err) return GetErrorCategory(GRD_FAILED_MEMORY_ALLOCATE); case -E_INVALID_FILE_FORMAT: return GetErrorCategory(GRD_INVALID_FILE_FORMAT); + case -E_FAILED_FILE_OPERATION: + return GetErrorCategory(GRD_FAILED_FILE_OPERATION); case -E_INNER_ERROR: default: return GetErrorCategory(GRD_INNER_ERR); diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_key.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_key.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a64932053790730da79005afe7b18b385b8d5639 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_key.cpp @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 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 "document_key.h" + +#include "doc_errno.h" +#include "log_print.h" +#include "securec.h" +namespace DocumentDB { +static uint16_t g_oIdIncNum = 0; +constexpr uint16_t MAX_NUMBER_OF_AUTOINCREMENTS = 65535; +constexpr uint16_t UINT_ZERO = 0; +static int InitDocIdFromOid(DocKey &docKey) +{ + time_t nowTime = time(nullptr); + if (nowTime < 0) { + return -E_INNER_ERROR; + } + uint32_t now = (uint32_t)nowTime; + uint16_t iv = g_oIdIncNum++; + // The maximum number of autoincrements is 65535, and if it is exceeded, it becomes 0. + if (g_oIdIncNum > MAX_NUMBER_OF_AUTOINCREMENTS) { + g_oIdIncNum = UINT_ZERO; + } + char *idTemp = new char[GRD_DOC_OID_HEX_SIZE + 1]; + if (sprintf_s(idTemp, GRD_DOC_OID_HEX_SIZE + 1, "%08x%04x", now, iv) < 0) { + GLOGE("get oid error"); + return -E_INNER_ERROR; + } + docKey.key = idTemp; + delete[] idTemp; + return E_OK; +} + +int DocumentKey::GetOidDocKey(DocKey &key) +{ + int ret = InitDocIdFromOid(key); + return ret; +} +} // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp index cb1947eb1f12c6eef18f91932c972efe84e85e74..fe2d1ded4b75c70a510f38a8e7bb3c80bffbb702 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp @@ -18,6 +18,7 @@ #include "check_common.h" #include "collection_option.h" #include "doc_errno.h" +#include "document_key.h" #include "grd_base/grd_type_export.h" #include "grd_resultset_inner.h" #include "log_print.h" @@ -43,7 +44,6 @@ int DocumentStore::CreateCollection(const std::string &name, const std::string & GLOGE("Check collection name invalid. %d", errCode); return errCode; } - errCode = E_OK; CollectionOption collOption = CollectionOption::ReadOption(option, errCode); if (errCode != E_OK) { @@ -128,7 +128,7 @@ END: return errCode; } -int TranFilter(JsonObject &filterObj, std::vector> &filterAllPath, bool &isOnlyId) +int TranFilter(JsonObject &filterObj, std::vector> &filterAllPath, bool &isIdExist) { int errCode = E_OK; filterAllPath = JsonCommon::ParsePath(filterObj, errCode); @@ -136,7 +136,7 @@ int TranFilter(JsonObject &filterObj, std::vector> &fil GLOGE("filter ParsePath failed"); return errCode; } - return CheckCommon::CheckFilter(filterObj, isOnlyId, filterAllPath); + return CheckCommon::CheckFilter(filterObj, filterAllPath, isIdExist); } int UpdateArgsCheck(const std::string &collection, const std::string &filter, const std::string &update, uint32_t flags) @@ -156,14 +156,8 @@ int UpdateArgsCheck(const std::string &collection, const std::string &filter, co GLOGE("update Parsed failed"); return errCode; } - std::vector> allPath; if (update != "{}") { - allPath = JsonCommon::ParsePath(updateObj, errCode); - if (errCode != E_OK) { - GLOGE("updateObj ParsePath failed"); - return errCode; - } - errCode = CheckCommon::CheckUpdata(updateObj, allPath); + errCode = CheckCommon::CheckUpdata(updateObj); if (errCode != E_OK) { GLOGE("Updata format is illegal"); return errCode; @@ -176,6 +170,41 @@ int UpdateArgsCheck(const std::string &collection, const std::string &filter, co return errCode; } +int GetUpDataRePlaceData(ResultSet &resultSet, const std::string &id, const std::string &update, std::string &valStr, + bool isReplace) +{ + std::string valueGotStr; + int errCode = resultSet.GetValue(valueGotStr); + if (errCode == -E_NO_DATA) { + GLOGW("Get original document not found."); + return -E_NOT_FOUND; + } else if (errCode != E_OK) { + GLOGE("Get original document failed. %d", errCode); + return errCode; + } + JsonObject updateValue = JsonObject::Parse(update, errCode, true); + if (errCode != E_OK) { + GLOGD("Parse upsert value failed. %d", errCode); + return errCode; + } + JsonObject originValue = JsonObject::Parse(valueGotStr, errCode, true); + if (errCode != E_OK) { + GLOGD("Parse original value failed. %d %s", errCode, valueGotStr.c_str()); + return errCode; + } + errCode = JsonCommon::Append(originValue, updateValue, isReplace); + if (errCode != E_OK) { + GLOGD("Append value failed. %d", errCode); + return errCode; + } + valStr = originValue.Print(); + if (valStr.length() >= JSON_LENS_MAX) { + GLOGE("document's length is too long"); + return -E_OVER_LIMIT; + } + return errCode; +} + int DocumentStore::UpdateDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, const std::string &update, bool &isReplace) { @@ -189,27 +218,28 @@ int DocumentStore::UpdateDataIntoDB(std::shared_ptr &context, Json } std::string docId; int count = 0; + std::string valStr; auto coll = Collection(context->collectionName, executor_); - if (context->isOnlyId) { - auto filterObjChild = filterObj.GetChild(); - auto idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID); - docId = idValue.GetStringValue(); - } else { - ResultSet resultSet; - std::string filter = filterObj.Print(); - InitResultSet(context, this, resultSet, true); - // no start transaction inner - errCode = resultSet.GetNext(false, true); - if (errCode == -E_NO_DATA) { - // no need to set count - errCode = E_OK; - goto END; - } else if (errCode != E_OK) { - goto END; - } - resultSet.GetKey(docId); + ResultSet resultSet; + errCode = InitResultSet(context, this, resultSet, false); + if (errCode != E_OK) { + goto END; + } + // no start transaction inner + errCode = resultSet.GetNext(false, true); + if (errCode == -E_NO_DATA) { + // no need to set count + errCode = E_OK; + goto END; + } else if (errCode != E_OK) { + goto END; + } + resultSet.GetKey(docId); + errCode = GetUpDataRePlaceData(resultSet, docId, update, valStr, isReplace); + if (errCode != E_OK) { + goto END; } - errCode = coll.UpdateDocument(docId, update, isReplace); + errCode = coll.UpdateDocument(docId, valStr); if (errCode == E_OK) { count++; } else if (errCode == -E_NOT_FOUND) { @@ -236,17 +266,18 @@ int DocumentStore::UpdateDocument(const std::string &collection, const std::stri GLOGE("filter Parsed failed"); return errCode; } - bool isOnlyId = true; + bool isIdExist = false; std::vector> filterAllPath; - errCode = TranFilter(filterObj, filterAllPath, isOnlyId); + errCode = TranFilter(filterObj, filterAllPath, isIdExist); if (errCode != E_OK) { return errCode; } bool isReplace = ((flags & GRD_DOC_REPLACE) == GRD_DOC_REPLACE); std::shared_ptr context = std::make_shared(); + context->isIdExist = isIdExist; context->collectionName = collection; - context->isOnlyId = isOnlyId; context->filter = filter; + context->ifShowId = true; return UpdateDataIntoDB(context, filterObj, update, isReplace); } @@ -270,28 +301,86 @@ int UpsertArgsCheck(const std::string &collection, const std::string &filter, co return errCode; } -int DocumentStore::CheckUpsertConflict(bool &isIdExist, std::shared_ptr &context, JsonObject &filterObj, - std::string &docId, Collection &coll) +int CheckUpsertConflict(ResultSet &resultSet, JsonObject &filterObj, std::string &docId, Collection &coll, + bool &isDataExist) { - ResultSet resultSet; - InitResultSet(context, this, resultSet, true); - int errCode = resultSet.GetNext(false, true); - bool isfilterMatch = false; + std::string val; // use to know whether there is data in the resultSet or not. + int errCode = resultSet.GetValue(val); if (errCode == E_OK) { - isfilterMatch = true; + isDataExist = true; } Value ValueDocument; - Key key(docId.begin(), docId.end()); - errCode = coll.GetDocument(key, ValueDocument); - if (errCode == E_OK && !(isfilterMatch)) { + Key id(docId.begin(), docId.end()); + errCode = coll.GetDocumentById(id, ValueDocument); + if (errCode == E_OK && !(isDataExist)) { GLOGE("id exist but filter does not match, data conflict"); errCode = -E_DATA_CONFLICT; } return errCode; } +int GetUpsertRePlaceData(ResultSet &resultSet, JsonObject &documentObj, bool isReplace, std::string &valStr) +{ + int errCode = resultSet.GetValue(valStr); + if (errCode != E_OK || isReplace) { + valStr = documentObj.Print(); // If cant not find data, insert it. + if (valStr.length() >= JSON_LENS_MAX) { + GLOGE("document's length is too long"); + return -E_OVER_LIMIT; + } + return E_OK; + } + if (errCode != E_OK && errCode != -E_NOT_FOUND) { + GLOGW("Get original document failed. %d", errCode); + return errCode; + } else if (errCode == E_OK) { // document has been inserted + JsonObject originValue = JsonObject::Parse(valStr, errCode, true); + if (errCode != E_OK) { + GLOGD("Parse original value failed. %d %s", errCode, valStr.c_str()); + return errCode; + } + errCode = JsonCommon::Append(originValue, documentObj, isReplace); + if (errCode != E_OK) { + GLOGD("Append value failed. %d", errCode); + return errCode; + } + valStr = originValue.Print(); + if (valStr.length() >= JSON_LENS_MAX) { + GLOGE("document's length is too long"); + return -E_OVER_LIMIT; + } + } + return errCode; +} + +int InsertIdToDocument(ResultSet &resultSet, JsonObject &filterObj, JsonObject &documentObj, std::string &docId) +{ + auto filterObjChild = filterObj.GetChild(); + bool isIdExist; + ValueObject idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID, isIdExist); + int errCode = E_OK; + int ret = resultSet.GetNext(false, true); // All anomalies will be judged later + if (ret != E_OK && ret != -E_NO_DATA) { + return ret; + } + if (isIdExist) { + docId = idValue.GetStringValue(); + JsonObject idObj = filterObj.GetObjectItem(KEY_ID, errCode); // this errCode will always be E_OK. + documentObj.InsertItemObject(0, idObj); + } else { + if (ret == E_OK) { // E_OK means find data. + (void)resultSet.GetKey(docId); // This errCode will always be E_OK. + } else { + DocKey docKey; + DocumentKey::GetOidDocKey(docKey); + docId = docKey.key; + } + } + return errCode; +} + int DocumentStore::UpsertDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, - JsonObject &documentObj, bool &isReplace) + const std::string &document, JsonObject &documentObj, bool &isReplace) { std::lock_guard lock(dbMutex_); if (executor_ == nullptr) { @@ -303,29 +392,29 @@ int DocumentStore::UpsertDataIntoDB(std::shared_ptr &context, Json } Collection coll = Collection(context->collectionName, executor_); int count = 0; - std::string targetDocument; std::string docId; - bool isIdExist; - auto filterObjChild = filterObj.GetChild(); - ValueObject idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID, isIdExist); - docId = idValue.GetStringValue(); - JsonObject idObj = filterObj.GetObjectItem(KEY_ID, errCode); - documentObj.InsertItemObject(0, idObj); - targetDocument = documentObj.Print(); - if (!isIdExist) { - errCode = -E_INVALID_ARGS; + ResultSet resultSet; + std::string newDocument; + bool isDataExist = false; + errCode = InitResultSet(context, this, resultSet, false); + if (errCode != E_OK) { goto END; } - if (!context->isOnlyId) { - errCode = CheckUpsertConflict(isIdExist, context, filterObj, docId, coll); - // There are only three return values, E_ OK and - E_ NO_DATA is a normal scenario, - // and that situation can continue to move forward - if (errCode == -E_DATA_CONFLICT) { - GLOGE("upsert data conflict"); - goto END; - } + errCode = InsertIdToDocument(resultSet, filterObj, documentObj, docId); + if (errCode != E_OK) { + goto END; + } + errCode = CheckUpsertConflict(resultSet, filterObj, docId, coll, isDataExist); + // There are only three return values, the two other situation can continue to move forward. + if (errCode == -E_DATA_CONFLICT) { + GLOGE("upsert data conflict"); + goto END; + } + errCode = GetUpsertRePlaceData(resultSet, documentObj, isReplace, newDocument); + if (errCode != E_OK) { + goto END; } - errCode = coll.UpsertDocument(docId, targetDocument, isReplace); + errCode = coll.UpsertDocument(docId, newDocument, isDataExist); if (errCode == E_OK) { count++; } else if (errCode == -E_NOT_FOUND) { @@ -343,13 +432,8 @@ END: int UpsertDocumentFormatCheck(const std::string &document, JsonObject &documentObj) { int errCode = E_OK; - std::vector> allPath; if (document != "{}") { - allPath = JsonCommon::ParsePath(documentObj, errCode); - if (errCode != E_OK) { - return errCode; - } - errCode = CheckCommon::CheckUpdata(documentObj, allPath); + errCode = CheckCommon::CheckUpdata(documentObj); if (errCode != E_OK) { GLOGE("UpsertDocument document format is illegal"); return errCode; @@ -357,6 +441,7 @@ int UpsertDocumentFormatCheck(const std::string &document, JsonObject &documentO } return errCode; } + int DocumentStore::UpsertDocument(const std::string &collection, const std::string &filter, const std::string &document, uint32_t flags) { @@ -379,19 +464,20 @@ int DocumentStore::UpsertDocument(const std::string &collection, const std::stri GLOGE("document format is illegal"); return errCode; } - bool isOnlyId = true; + bool isIdExist = false; std::vector> filterAllPath; - errCode = TranFilter(filterObj, filterAllPath, isOnlyId); + errCode = TranFilter(filterObj, filterAllPath, isIdExist); if (errCode != E_OK) { GLOGE("filter is invalid"); return errCode; } std::shared_ptr context = std::make_shared(); context->filter = filter; - context->isOnlyId = isOnlyId; context->collectionName = collection; + context->ifShowId = true; + context->isIdExist = isIdExist; bool isReplace = ((flags & GRD_DOC_REPLACE) == GRD_DOC_REPLACE); - return UpsertDataIntoDB(context, filterObj, documentObj, isReplace); + return UpsertDataIntoDB(context, filterObj, document, documentObj, isReplace); } int InsertArgsCheck(const std::string &collection, const std::string &document, uint32_t flags) @@ -413,16 +499,22 @@ int InsertArgsCheck(const std::string &collection, const std::string &document, return errCode; } -int DocumentStore::InsertDataIntoDB(const std::string &collection, const std::string &document, JsonObject &documentObj) +int DocumentStore::InsertDataIntoDB(const std::string &collection, const std::string &document, + JsonObject &documentObj, bool &isIdExist) { std::lock_guard lock(dbMutex_); - JsonObject documentObjChild = documentObj.GetChild(); - ValueObject idValue = JsonCommon::GetValueInSameLevel(documentObjChild, KEY_ID); - std::string id = idValue.GetStringValue(); - Key key(id.begin(), id.end()); - Value value(document.begin(), document.end()); + std::string id; + if (isIdExist) { + JsonObject documentObjChild = documentObj.GetChild(); + ValueObject idValue = JsonCommon::GetValueInSameLevel(documentObjChild, KEY_ID); + id = idValue.GetStringValue(); + } else { + DocKey docKey; + DocumentKey::GetOidDocKey(docKey); + id = docKey.key; + } Collection coll = Collection(collection, executor_); - return coll.InsertDocument(key, value); + return coll.InsertDocument(id, document, isIdExist); } int DocumentStore::InsertDocument(const std::string &collection, const std::string &document, uint32_t flags) @@ -436,11 +528,12 @@ int DocumentStore::InsertDocument(const std::string &collection, const std::stri GLOGE("Document Parsed failed"); return errCode; } - errCode = CheckCommon::CheckDocument(documentObj); + bool isIdExist = true; + errCode = CheckCommon::CheckDocument(documentObj, isIdExist); if (errCode != E_OK) { return errCode; } - return InsertDataIntoDB(collection, document, documentObj); + return InsertDataIntoDB(collection, document, documentObj, isIdExist); } int DeleteArgsCheck(const std::string &collection, const std::string &filter, uint32_t flags) @@ -478,19 +571,16 @@ int DocumentStore::DeleteDataFromDB(std::shared_ptr &context, Json return errCode; } std::string id; - if (context->isOnlyId) { - auto filterObjChild = filterObj.GetChild(); - auto idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID); - id = idValue.GetStringValue(); - } else { - ResultSet resultSet; - InitResultSet(context, this, resultSet, true); - errCode = resultSet.GetNext(false, true); - if (errCode != E_OK) { - goto END; - } - resultSet.GetKey(id); + ResultSet resultSet; + errCode = InitResultSet(context, this, resultSet, false); + if (errCode != E_OK) { + goto END; } + errCode = resultSet.GetNext(false, true); + if (errCode != E_OK) { + goto END; + } + resultSet.GetKey(id); END: if (errCode == E_OK) { Key key(id.begin(), id.end()); @@ -513,16 +603,16 @@ int DocumentStore::DeleteDocument(const std::string &collection, const std::stri if (errCode != E_OK) { return errCode; } - bool isOnlyId = true; + bool isIdExist = false; std::vector> filterAllPath; - errCode = TranFilter(filterObj, filterAllPath, isOnlyId); + errCode = TranFilter(filterObj, filterAllPath, isIdExist); if (errCode != E_OK) { return errCode; } std::shared_ptr context = std::make_shared(); + context->isIdExist = isIdExist; context->filter = filter; context->collectionName = collection; - context->isOnlyId = isOnlyId; return DeleteDataFromDB(context, filterObj); } Collection DocumentStore::GetCollection(std::string &collectionName) @@ -530,47 +620,75 @@ Collection DocumentStore::GetCollection(std::string &collectionName) return Collection(collectionName, executor_); } -int JudgeViewType(size_t &index, ValueObject &leafItem, bool &viewType) +int JudgeBoolViewType(const size_t index, ValueObject &leafItem, bool &viewType) { + if (leafItem.GetBoolValue()) { + if (index != 0 && !viewType) { + return -E_INVALID_ARGS; + } + viewType = true; + } else { + if (index != 0 && viewType) { + return -E_INVALID_ARGS; + } + viewType = false; + } + return E_OK; +} + +int JudgeStringViewType(const size_t index, ValueObject &leafItem, bool &viewType) +{ + if (leafItem.GetStringValue() == "") { + if (index != 0 && !viewType) { + return -E_INVALID_ARGS; + } + viewType = true; + } else { + return -E_INVALID_ARGS; + } + return E_OK; +} + +int JudgeIntViewType(const size_t index, ValueObject &leafItem, bool &viewType) +{ + if (leafItem.GetIntValue() == 0) { + if (index != 0 && viewType) { + return -E_INVALID_ARGS; + } + viewType = false; + } else { + if (index != 0 && !viewType) { + return -E_INVALID_ARGS; + } + viewType = true; + } + return E_OK; +} + +int JudgeViewType(const size_t index, ValueObject &leafItem, bool &viewType) +{ + int errCode = E_OK; switch (leafItem.GetValueType()) { case ValueObject::ValueType::VALUE_BOOL: - if (leafItem.GetBoolValue()) { - if (index != 0 && !viewType) { - return -E_INVALID_ARGS; - } - viewType = true; - } else { - if (index != 0 && viewType) { - return E_INVALID_ARGS; - } - viewType = false; + errCode = JudgeBoolViewType(index, leafItem, viewType); + if (errCode != E_OK) { + return errCode; } break; case ValueObject::ValueType::VALUE_STRING: - if (leafItem.GetStringValue() == "") { - if (index != 0 && !viewType) { - return -E_INVALID_ARGS; - } - viewType = true; - } else { - return -E_INVALID_ARGS; + errCode = JudgeStringViewType(index, leafItem, viewType); + if (errCode != E_OK) { + return errCode; } break; case ValueObject::ValueType::VALUE_NUMBER: - if (leafItem.GetIntValue() == 0) { - if (index != 0 && viewType) { - return -E_INVALID_ARGS; - } - viewType = false; - } else { - if (index != 0 && !viewType) { - return E_INVALID_ARGS; - } - viewType = true; + errCode = JudgeIntViewType(index, leafItem, viewType); + if (errCode != E_OK) { + return errCode; } break; default: - return E_INVALID_ARGS; + return -E_INVALID_ARGS; } return E_OK; } @@ -579,7 +697,7 @@ int GetViewType(JsonObject &jsonObj, bool &viewType) { std::vector leafValue = JsonCommon::GetLeafValue(jsonObj); if (leafValue.size() == 0) { - return E_INVALID_ARGS; + return -E_INVALID_ARGS; } int ret = E_OK; for (size_t i = 0; i < leafValue.size(); i++) { @@ -615,7 +733,7 @@ int FindArgsCheck(const std::string &collection, const std::string &filter, cons return errCode; } -int FindProjectionInit(const std::string &projection, std::shared_ptr &context) +int FindProjectionInit(const std::string &projection, const std::shared_ptr &context) { int errCode = E_OK; std::vector> allPath; @@ -667,7 +785,7 @@ int DocumentStore::InitFindResultSet(GRD_ResultSet *grdResultSet, std::shared_pt if (errCode != E_OK) { goto END; } - errCode = InitResultSet(context, this, grdResultSet->resultSet_, false); + errCode = InitResultSet(context, this, grdResultSet->resultSet_, true); if (errCode == E_OK) { collections_[context->collectionName] = nullptr; } @@ -683,37 +801,36 @@ END: int DocumentStore::FindDocument(const std::string &collection, const std::string &filter, const std::string &projection, uint32_t flags, GRD_ResultSet *grdResultSet) { - std::shared_ptr context = std::make_shared(); - int errCode = E_OK; - errCode = FindArgsCheck(collection, filter, projection, flags); + int errCode = FindArgsCheck(collection, filter, projection, flags); if (errCode != E_OK) { GLOGE("delete arg is illegal"); return errCode; } - context->collectionName = collection; - context->filter = filter; JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); if (errCode != E_OK) { GLOGE("filter Parsed failed"); return errCode; } + std::shared_ptr context = std::make_shared(); errCode = FindProjectionInit(projection, context); if (errCode != E_OK) { return errCode; } - bool isOnlyId = true; + bool isIdExist = false; std::vector> filterAllPath; - errCode = TranFilter(filterObj, filterAllPath, isOnlyId); + errCode = TranFilter(filterObj, filterAllPath, isIdExist); if (errCode != E_OK) { GLOGE("filter is invalid"); return errCode; } - context->isOnlyId = isOnlyId; if (flags == GRD_DOC_ID_DISPLAY) { context->ifShowId = true; } else { context->ifShowId = false; } + context->collectionName = collection; + context->filter = filter; + context->isIdExist = isIdExist; return InitFindResultSet(grdResultSet, context); } @@ -734,7 +851,7 @@ int DocumentStore::EraseCollection(const std::string &collectionName) return E_OK; } GLOGE("erase collection failed"); - return E_INVALID_ARGS; + return -E_INVALID_ARGS; } void DocumentStore::OnClose(const std::function ¬ifier) @@ -781,7 +898,8 @@ int DocumentStore::Rollback() bool DocumentStore::IsCollectionExists(const std::string &collectionName, int &errCode) { if (executor_ == nullptr) { - return -E_INNER_ERROR; + errCode = -E_INNER_ERROR; + return false; } return executor_->IsCollectionExists(collectionName, errCode); } diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/projection_tree.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/projection_tree.cpp index 94c56b6fe9468ea2c650750ba298a4d8b343c8a5..4ab699c391b76942f6a9512b545c408308f9ebd3 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/projection_tree.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/projection_tree.cpp @@ -54,15 +54,15 @@ int ProjectionTree::ParseTree(std::vector> &path) return E_OK; } -bool ProjectionTree::SearchTree(std::vector &singlePath, int &index) +bool ProjectionTree::SearchTree(std::vector &singlePath, size_t &index) { ProjectionNode *node = &node_; for (size_t i = 0; i < singlePath.size(); i++) { - if (node->isDeepest) { - index = i; - } if (node->sonNode[singlePath[i]] != nullptr) { node = node->sonNode[singlePath[i]]; + if (node->isDeepest) { + index = i + 1; + } } else { return false; } diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp index cadbf6703dd67a83f80cb49358665ba025245c0d..dd28c02696ac13e20c6ee42e6a5bd0fddbde028c 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp @@ -14,7 +14,10 @@ */ #include "result_set.h" +#include + #include "db_constant.h" +#include "document_key.h" #include "log_print.h" #include "securec.h" @@ -33,59 +36,65 @@ int ResultSet::EraseCollection() } return E_OK; } -int ResultSet::Init(std::shared_ptr &context, DocumentStore *store, bool ifField) +int ResultSet::Init(std::shared_ptr &context, DocumentStore *store, bool isCutBranch) { - ifField_ = ifField; + isCutBranch_ = isCutBranch; context_ = context; store_ = store; return E_OK; } -int ResultSet::GetNextWithField() +int ResultSet::GetValueFromDB(Key &key, JsonObject &filterObj, std::string &jsonKey, std::string &jsonData) { - int errCode = E_OK; - if (context_->isOnlyId) { - JsonObject filterObj = JsonObject::Parse(context_->filter, errCode, true, true); + std::pair value; + Collection coll = store_->GetCollection(context_->collectionName); + filterObj.DeleteItemFromObject(KEY_ID); + int errCode = coll.GetMatchedDocument(filterObj, key, value, context_->isIdExist); + if (errCode == -E_NOT_FOUND) { + return -E_NO_DATA; + } + jsonData.assign(value.second.begin(), value.second.end()); + jsonKey.assign(value.first.begin(), value.first.end()); + lastKeyIndex_ = jsonKey; + if (isCutBranch_) { + errCode = CutJsonBranch(jsonKey, jsonData); if (errCode != E_OK) { - GLOGE("filter Parsed failed"); - return errCode; - } - JsonObject filterObjChild = filterObj.GetChild(); - ValueObject idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID); - std::string idKey = idValue.GetStringValue(); - if (idKey.empty()) { - return -E_NO_DATA; + GLOGE("cut branch faild"); } - Key key(idKey.begin(), idKey.end()); - Value document; - Collection coll = store_->GetCollection(context_->collectionName); - errCode = coll.GetDocument(key, document); - if (errCode == -E_NOT_FOUND) { + } + return errCode; +} + +int ResultSet::GetNextWithField() +{ + int errCode = E_OK; + JsonObject filterObj = JsonObject::Parse(context_->filter, errCode, true, true); + if (errCode != E_OK) { + GLOGE("filter Parsed failed"); + return errCode; + } + Key key; + if (context_->isIdExist) { + if (index_ == 0) { // get id from filter, if alreay has got id once, get from lastKeyIndex. + JsonObject filterObjChild = filterObj.GetChild(); + ValueObject idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID); + std::string idKey = idValue.GetStringValue(); + key.assign(idKey.begin(), idKey.end()); + } else { // Use id to find data that can only get one data. + matchData_.first.clear(); // Delete previous data. + matchData_.second.clear(); return -E_NO_DATA; } - std::string jsonData(document.begin(), document.end()); - CutJsonBranch(jsonData); - std::vector> values; - values.emplace_back(std::make_pair(idKey, jsonData)); - matchDatas_ = values; } else { - Collection coll = store_->GetCollection(context_->collectionName); - std::vector> values; - JsonObject filterObj = JsonObject::Parse(context_->filter, errCode, true, true); - if (errCode != E_OK) { - GLOGE("filter Parsed failed"); - return errCode; - } - errCode = coll.GetMatchedDocument(filterObj, values); - if (errCode == -E_NOT_FOUND) { - return -E_NO_DATA; - } - for (size_t i = 0; i < values.size(); i++) { - CutJsonBranch(values[i].second); - } - matchDatas_ = values; + key.assign(lastKeyIndex_.begin(), lastKeyIndex_.end()); } - return E_OK; + matchData_.first.clear(); + matchData_.second.clear(); + std::string jsonKey; + std::string jsonData; + errCode = GetValueFromDB(key, filterObj, jsonKey, jsonData); + matchData_ = std::make_pair(jsonKey, jsonData); + return errCode; } int ResultSet::GetNextInner(bool isNeedCheckTable) @@ -104,27 +113,12 @@ int ResultSet::GetNextInner(bool isNeedCheckTable) return -E_INVALID_ARGS; } } - if (!ifField_ && index_ == 0) { - errCode = GetNextWithField(); - if (errCode != E_OK) { - return errCode; - } - } else if (index_ == 0) { - Collection coll = store_->GetCollection(context_->collectionName); - std::vector> values; - JsonObject filterObj = JsonObject::Parse(context_->filter, errCode, true, true); - if (errCode != E_OK) { - GLOGE("filter Parsed failed"); - return errCode; - } - errCode = coll.GetMatchedDocument(filterObj, values); - if (errCode == -E_NOT_FOUND) { - return -E_NO_DATA; - } - matchDatas_ = values; - } + errCode = GetNextWithField(); index_++; - if (index_ > matchDatas_.size()) { + if (errCode != E_OK) { + return errCode; + } + if (matchData_.second.empty()) { return -E_NO_DATA; } return E_OK; @@ -132,13 +126,13 @@ int ResultSet::GetNextInner(bool isNeedCheckTable) int ResultSet::GetNext(bool isNeedTransaction, bool isNeedCheckTable) { - int errCode = E_OK; if (!isNeedTransaction) { return GetNextInner(isNeedCheckTable); } std::lock_guard lock(store_->dbMutex_); - errCode = store_->StartTransaction(); + int errCode = store_->StartTransaction(); if (errCode != E_OK) { + GLOGE("Start transaction faild"); return errCode; } errCode = GetNextInner(isNeedCheckTable); @@ -153,11 +147,11 @@ int ResultSet::GetNext(bool isNeedTransaction, bool isNeedCheckTable) int ResultSet::GetValue(char **value) { std::lock_guard lock(store_->dbMutex_); - if (index_ == 0 || (index_ > matchDatas_.size())) { + if (matchData_.first.empty()) { GLOGE("The value vector in resultSet is empty"); return -E_NO_DATA; } - std::string jsonData = matchDatas_[index_ - 1].second; + std::string jsonData = matchData_.second; char *jsonstr = new char[jsonData.size() + 1]; if (jsonstr == nullptr) { GLOGE("Memory allocation failed!"); @@ -173,13 +167,23 @@ int ResultSet::GetValue(char **value) return E_OK; } -int ResultSet::GetKey(std::string &key) +int ResultSet::GetValue(std::string &value) { - if (index_ == 0 || (index_ > matchDatas_.size())) { + if (matchData_.first.empty()) { GLOGE("The value vector in resultSet is empty"); return -E_NO_DATA; } - key = matchDatas_[index_ - 1].first; + value = matchData_.second; + return E_OK; +} + +int ResultSet::GetKey(std::string &key) +{ + key = matchData_.first; + if (key.empty()) { + GLOGE("can not get data, because it is empty"); + return -E_NO_DATA; + } return E_OK; } @@ -190,23 +194,51 @@ int ResultSet::CheckCutNode(JsonObject *node, std::vector singlePat GLOGE("No node to cut"); return -E_NO_DATA; } - singlePath.emplace_back(node->GetItemField()); - int index = 0; - if (!context_->projectionTree.SearchTree(singlePath, index) && index == 0) { - allCutPath.emplace_back(singlePath); + JsonObject nodeInstance = *node; + while (!nodeInstance.IsNull()) { + singlePath.emplace_back(nodeInstance.GetItemField()); + size_t index = 0; + bool isMatch = context_->projectionTree.SearchTree(singlePath, index); + if ((nodeInstance.GetType() == JsonObject::Type::JSON_ARRAY && isMatch && index == 0) || + (!isMatch && index == 0)) { + allCutPath.emplace_back(singlePath); + } + if (nodeInstance.GetType() != JsonObject::Type::JSON_ARRAY && !nodeInstance.GetChild().IsNull()) { + JsonObject nodeChiled = nodeInstance.GetChild(); + CheckCutNode(&nodeChiled, singlePath, allCutPath); + } + singlePath.pop_back(); + nodeInstance = nodeInstance.GetNext(); } - if (!node->GetChild().IsNull()) { - JsonObject nodeNew = node->GetChild(); - CheckCutNode(&nodeNew, singlePath, allCutPath); + return E_OK; +} + +JsonObject CreatIdObj(const std::string &idStr, int errCode) +{ + std::stringstream sstream; + sstream << "{\"_id\":" + << "\"" << idStr << "\"}"; + JsonObject idObj = JsonObject::Parse(sstream.str(), errCode, true); // cant be faild. + return idObj; +} + +int InsertId(JsonObject &cjsonObj, std::string &jsonKey) +{ + if (jsonKey.empty()) { + GLOGE("Genalral Id faild"); + return -E_INNER_ERROR; } - if (!node->GetNext().IsNull()) { - singlePath.pop_back(); - JsonObject nodeNew = node->GetNext(); - CheckCutNode(&nodeNew, singlePath, allCutPath); + int errCode = E_OK; + JsonObject idObj = CreatIdObj(jsonKey, errCode); + if (errCode != E_OK) { + GLOGE("CreatIdObj faild"); + return errCode; } + cjsonObj.InsertItemObject(0, idObj.GetChild()); // idObj's child is _id node return E_OK; } -int ResultSet::CutJsonBranch(std::string &jsonData) + +int ResultSet::CutJsonBranch(std::string &jsonKey, std::string &jsonData) { int errCode; JsonObject cjsonObj = JsonObject::Parse(jsonData, errCode, true); @@ -214,6 +246,12 @@ int ResultSet::CutJsonBranch(std::string &jsonData) GLOGE("jsonData Parsed failed"); return errCode; } + bool isIdExistInValue = true; // if id exsit in the value string that get from db. + bool isInsertIdflag = false; + isIdExistInValue = cjsonObj.GetObjectItem("_id", errCode).IsNull() ? false : true; + if (context_->ifShowId && !isIdExistInValue) { + isInsertIdflag = true; // ifShowId is true,and then the data taken out does not have IDs, insert id. + } if (context_->viewType) { std::vector singlePath; JsonObject cjsonObjChild = cjsonObj.GetChild(); @@ -223,12 +261,21 @@ int ResultSet::CutJsonBranch(std::string &jsonData) GLOGE("The node in CheckCutNode is nullptr"); return errCode; } - for (const auto &singleCutPaht : allCutPath) { - if (!context_->ifShowId || singleCutPaht[0] != KEY_ID) { - cjsonObj.DeleteItemDeeplyOnTarget(singleCutPaht); + for (const auto &singleCutPath : allCutPath) { + if (!context_->ifShowId || singleCutPath[0] != KEY_ID) { + cjsonObj.DeleteItemDeeplyOnTarget(singleCutPath); + } + if (singleCutPath[0] == KEY_ID && !isIdExistInValue) { // projection has Id, and its showType is true. + isInsertIdflag = true; } } } + if (isInsertIdflag) { + errCode = InsertId(cjsonObj, jsonKey); + if (errCode != E_OK) { + return errCode; + } + } if (!context_->viewType) { for (const auto &singleCutPaht : context_->projectionPath) { cjsonObj.DeleteItemDeeplyOnTarget(singleCutPaht); diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp index d6e070aaab416e100a8991ccdb2c068bfae2478e..dd9acaeb265af70df00b0f7374f3d6df381c0c8f 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp @@ -14,20 +14,26 @@ */ #include "result_set_common.h" - +#include "grd_format_config.h" #include "doc_errno.h" #include "grd_base/grd_error.h" namespace DocumentDB { class ValueObject; -int InitResultSet(std::shared_ptr &context, DocumentStore *store, ResultSet &resultSet, bool ifField) +int InitResultSet(std::shared_ptr &context, DocumentStore *store, ResultSet &resultSet, bool isCutBranch) { - if (!ifField) { + if (isCutBranch) { + for (const auto &singlePath : context->projectionPath) { + if (singlePath[0] == KEY_ID && context->viewType == true) { // projection has Id and viewType is true + context->ifShowId = true; + break; + } + } if (context->projectionTree.ParseTree(context->projectionPath) == -E_INVALID_ARGS) { GLOGE("Parse ProjectionTree failed"); return -E_INVALID_ARGS; } } - return resultSet.Init(context, store, ifField); + return resultSet.Init(context, store, isCutBranch); } } // namespace DocumentDB diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h index afd0489dd033c0a8c6928ab4ed4dd4a1e93c33ff..bd1cba711e6efd0cd2fb5bd291fe07ff74305f0e 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/json_object.h @@ -37,7 +37,6 @@ public: explicit ValueObject(bool val); explicit ValueObject(double val); explicit ValueObject(const char *val); - explicit ValueObject(const std::string &val); ValueType GetValueType() const; bool GetBoolValue() const; @@ -68,20 +67,17 @@ public: std::string Print() const; JsonObject GetObjectItem(const std::string &field, int &errCode); - JsonObject GetArrayItem(int index, int &errCode); JsonObject GetNext() const; JsonObject GetChild() const; int DeleteItemFromObject(const std::string &field); - int AddItemToObject(const JsonObject &item); int AddItemToObject(const std::string &fieldName, const JsonObject &item); int AddItemToObject(const std::string &fieldName); ValueObject GetItemValue() const; void ReplaceItemInArray(const int &index, const JsonObject &newItem, int &errCode); void ReplaceItemInObject(const std::string &fieldName, const JsonObject &newItem, int &errCode); - void SetItemValue(const ValueObject &value) const; int InsertItemObject(int which, const JsonObject &newItem); std::string GetItemField() const; @@ -92,7 +88,6 @@ public: JsonObject FindItem(const JsonFieldPath &jsonPath, int &errCode) const; JsonObject FindItemPowerMode(const JsonFieldPath &jsonPath, int &errCode) const; ValueObject GetObjectByPath(const JsonFieldPath &jsonPath, int &errCode) const; - int DeleteItemOnTarget(const JsonFieldPath &path); int DeleteItemDeeplyOnTarget(const JsonFieldPath &path); bool IsNull() const; int GetDeep(); @@ -106,10 +101,10 @@ public: private: JsonObject(); int Init(const std::string &str, bool isFilter = false); - int CheckJsonRepeatField(cJSON *object); - int CheckSubObj(std::set &fieldSet, cJSON *subObj, int parentType); + int CheckJsonRepeatField(cJSON *object, bool isFirstFloor); + int CheckSubObj(std::set &fieldSet, cJSON *subObj, int parentType, bool isFirstFloor); int GetDeep(cJSON *cjson); - int CheckNumber(cJSON *cjson, int &errCode); + int CheckNumber(cJSON *cJSON); cJSON *cjson_ = nullptr; int jsonDeep_ = 0; bool isOwner_ = false; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h index 7dd31d4ec72776f48475e0ab97bcdcf07e2b2014..a12bda14fae0de0c52464b2369d96db5ca4c892f 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/include/kv_store_executor.h @@ -29,18 +29,18 @@ public: virtual int Commit() = 0; virtual int Rollback() = 0; - virtual int PutData(const std::string &collName, const Key &key, const Value &value) = 0; - virtual int InsertData(const std::string &collName, const Key &key, const Value &value) = 0; - virtual int GetData(const std::string &collName, const Key &key, Value &value) const = 0; - virtual int GetFieldedData(const std::string &collName, const JsonObject &filterObj, - std::vector> &values) const = 0; - virtual int DelData(const std::string &collName, const Key &key) = 0; + virtual int PutData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType = true) = 0; + virtual int InsertData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType = true) = 0; + virtual int GetDataByKey(const std::string &collName, Key &key, Value &value) const = 0; + virtual int GetDataById(const std::string &collName, Key &key, Value &value) const = 0; + virtual int GetDataByFilter(const std::string &collName, Key &key, const JsonObject &filterObj, + std::pair &values, int isIdExist) const = 0; + virtual int DelData(const std::string &collName, Key &key) = 0; virtual int CreateCollection(const std::string &name, const std::string &option, bool ignoreExists) = 0; virtual int DropCollection(const std::string &name, bool ignoreNonExists) = 0; virtual bool IsCollectionExists(const std::string &name, int &errCode) = 0; - virtual int GetCollectionOption(const std::string &name, std::string &option) = 0; virtual int SetCollectionOption(const std::string &name, const std::string &option) = 0; virtual int CleanCollectionOption(const std::string &name) = 0; }; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp index 7ac3a08c0717fc083ac31ac794a74bb24002bb12..26c50fd8667a29c81e251c6fb0a3776099ea85c1 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/json_object.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "doc_errno.h" #include "log_print.h" @@ -49,12 +50,6 @@ ValueObject::ValueObject(const char *val) stringValue = val; } -ValueObject::ValueObject(const std::string &val) -{ - valueType = ValueType::VALUE_STRING; - stringValue = val; -} - ValueObject::ValueType ValueObject::GetValueType() const { return valueType; @@ -102,7 +97,7 @@ JsonObject::~JsonObject() bool JsonObject::operator==(const JsonObject &other) const { - return (cJSON_Compare(this->cjson_, other.cjson_, 0) != 0); + return (cJSON_Compare(this->cjson_, other.cjson_, true) != 0); // CaseSensitive } bool JsonObject::IsNull() const @@ -150,19 +145,28 @@ int JsonObject::GetDeep(cJSON *cjson) return depth; } -int JsonObject::CheckNumber(cJSON *item, int &errCode) +int JsonObject::CheckNumber(cJSON *item) { - if (item != NULL && cJSON_IsNumber(item)) { - double value = cJSON_GetNumberValue(item); - if (value > __DBL_MAX__ || value < -__DBL_MAX__) { - errCode = -E_INVALID_ARGS; + std::queue cjsonQueue; + cjsonQueue.push(item); + while (!cjsonQueue.empty()) { + cJSON *node = cjsonQueue.front(); + cjsonQueue.pop(); + if (node == nullptr) { + return -E_INVALID_ARGS; + } + if (cJSON_IsNumber(node)) { // node is not null all the time + double value = cJSON_GetNumberValue(node); + if (value > __DBL_MAX__ || value < -__DBL_MAX__) { + return -E_INVALID_ARGS; + } + } + if (node->child != nullptr) { + cjsonQueue.push(node->child); + } + if (node->next != nullptr) { + cjsonQueue.push(node->next); } - } - if (item->child != nullptr) { - return CheckNumber(item->child, errCode); - } - if (item->next != nullptr) { - return CheckNumber(item->next, errCode); } return E_OK; } @@ -182,14 +186,14 @@ int JsonObject::Init(const std::string &str, bool isFilter) return -E_INVALID_ARGS; } - int ret = 0; - CheckNumber(cjson_, ret); + int ret = CheckNumber(cjson_); if (ret == -E_INVALID_ARGS) { GLOGE("Int value is larger than double"); return -E_INVALID_ARGS; } if (!isFilter) { - ret = CheckJsonRepeatField(cjson_); + bool isFirstFloor = true; + ret = CheckJsonRepeatField(cjson_, isFirstFloor); if (ret != E_OK) { return ret; } @@ -197,7 +201,7 @@ int JsonObject::Init(const std::string &str, bool isFilter) return E_OK; } -int JsonObject::CheckJsonRepeatField(cJSON *object) +int JsonObject::CheckJsonRepeatField(cJSON *object, bool isFirstFloor) { if (object == nullptr) { return -E_INVALID_ARGS; @@ -210,7 +214,7 @@ int JsonObject::CheckJsonRepeatField(cJSON *object) std::set fieldSet; cJSON *subObj = object->child; while (subObj != nullptr) { - ret = CheckSubObj(fieldSet, subObj, type); + ret = CheckSubObj(fieldSet, subObj, type, isFirstFloor); if (ret != E_OK) { break; } @@ -219,7 +223,17 @@ int JsonObject::CheckJsonRepeatField(cJSON *object) return ret; } -int JsonObject::CheckSubObj(std::set &fieldSet, cJSON *subObj, int parentType) +bool IsFieldNameLegal(const std::string &fieldName) +{ + for (auto oneChar : fieldName) { + if (!((isalpha(oneChar)) || (isdigit(oneChar)) || (oneChar == '_'))) { + return false; + } + } + return true; +} + +int JsonObject::CheckSubObj(std::set &fieldSet, cJSON *subObj, int parentType, bool isFirstFloor) { if (subObj == nullptr) { return -E_INVALID_ARGS; @@ -227,9 +241,18 @@ int JsonObject::CheckSubObj(std::set &fieldSet, cJSON *subObj, int std::string fieldName; if (subObj->string != nullptr) { fieldName = subObj->string; + if (!isFirstFloor) { + if (!IsFieldNameLegal(fieldName)) { + return -E_INVALID_ARGS; + } + } + if (!fieldName.empty() && isdigit(fieldName[0])) { + return -E_INVALID_ARGS; + } } + isFirstFloor = false; if (parentType == cJSON_Array) { - return CheckJsonRepeatField(subObj); + return CheckJsonRepeatField(subObj, isFirstFloor); } if (fieldName.empty()) { return -E_INVALID_JSON_FORMAT; @@ -239,7 +262,7 @@ int JsonObject::CheckSubObj(std::set &fieldSet, cJSON *subObj, int } else { return -E_INVALID_JSON_FORMAT; } - return CheckJsonRepeatField(subObj); + return CheckJsonRepeatField(subObj, isFirstFloor); } std::string JsonObject::Print() const @@ -273,22 +296,6 @@ JsonObject JsonObject::GetObjectItem(const std::string &field, int &errCode) return item; } -JsonObject JsonObject::GetArrayItem(int index, int &errCode) -{ - if (cjson_ == nullptr || cjson_->type != cJSON_Array) { - errCode = -E_INVALID_ARGS; - return JsonObject(); - } - - JsonObject item; - item.caseSensitive_ = caseSensitive_; - item.cjson_ = cJSON_GetArrayItem(cjson_, index); - if (item.cjson_ == nullptr) { - errCode = -E_NOT_FOUND; - } - return item; -} - JsonObject JsonObject::GetNext() const { if (cjson_ == nullptr) { @@ -326,18 +333,6 @@ int JsonObject::DeleteItemFromObject(const std::string &field) return E_OK; } -int JsonObject::AddItemToObject(const JsonObject &item) -{ - if (item.IsNull()) { - GLOGD("Add null object."); - return E_OK; - } - - cJSON *cpoyItem = cJSON_Duplicate(item.cjson_, true); - cJSON_AddItemToObject(cjson_, item.GetItemField().c_str(), cpoyItem); - return E_OK; -} - int JsonObject::AddItemToObject(const std::string &fieldName, const JsonObject &item) { if (cjson_ == nullptr) { @@ -443,23 +438,6 @@ void JsonObject::ReplaceItemInArray(const int &index, const JsonObject &newItem, } } -void JsonObject::SetItemValue(const ValueObject &value) const -{ - if (cjson_ == nullptr) { - return; - } - switch (value.GetValueType()) { - case ValueObject::ValueType::VALUE_NUMBER: - cJSON_SetNumberValue(cjson_, value.GetDoubleValue()); - break; - case ValueObject::ValueType::VALUE_STRING: - cJSON_SetValuestring(cjson_, value.GetStringValue().c_str()); - break; - default: - break; - } -} - int JsonObject::InsertItemObject(int which, const JsonObject &newItem) { if (cjson_ == nullptr) { @@ -645,39 +623,6 @@ ValueObject JsonObject::GetObjectByPath(const JsonFieldPath &jsonPath, int &errC return objGot.GetItemValue(); } -int JsonObject::DeleteItemOnTarget(const JsonFieldPath &path) -{ - if (path.empty()) { - return -E_INVALID_ARGS; - } - - std::string fieldName = path.back(); - JsonFieldPath patherPath = path; - patherPath.pop_back(); - - cJSON *nodeFather = MoveToPath(cjson_, patherPath, caseSensitive_); - if (nodeFather == nullptr) { - GLOGE("Delete item failed, json field path not found."); - return -E_JSON_PATH_NOT_EXISTS; - } - - if (nodeFather->type == cJSON_Object) { - if (caseSensitive_) { - cJSON_DeleteItemFromObjectCaseSensitive(nodeFather, fieldName.c_str()); - } else { - cJSON_DeleteItemFromObject(nodeFather, fieldName.c_str()); - } - } else if (nodeFather->type == cJSON_Array) { - if (!IsNumber(fieldName)) { - GLOGW("Invalid json field path, expect array index."); - return -E_JSON_PATH_NOT_EXISTS; - } - cJSON_DeleteItemFromArray(nodeFather, std::stoi(fieldName)); - } - - return E_OK; -} - int JsonObject::DeleteItemDeeplyOnTarget(const JsonFieldPath &path) { if (path.empty()) { @@ -690,7 +635,6 @@ int JsonObject::DeleteItemDeeplyOnTarget(const JsonFieldPath &path) cJSON *nodeFather = MoveToPath(cjson_, patherPath, caseSensitive_); if (nodeFather == nullptr) { - GLOGE("Delete item failed, json field path not found."); return -E_JSON_PATH_NOT_EXISTS; } diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp index d038491f3a02e918753f055f507fcf611fad2ad0..79cbcc868989746ffd9ce8b7b552fd2261e90643 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/kv_store_manager.cpp @@ -63,7 +63,6 @@ int KvStoreManager::GetKvStore(const std::string &path, const DBConfig &config, goto END; } } - executor = sqliteExecutor; return E_OK; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp index 1de43e0dc0f6a83750cf3caaedf1758bcf34ff22..39f34788a33f9b509b93761963f7a0aa9b082234 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.cpp @@ -18,10 +18,12 @@ #include "check_common.h" #include "db_constant.h" #include "doc_errno.h" +#include "document_key.h" #include "log_print.h" #include "sqlite_utils.h" namespace DocumentDB { +constexpr const uint8_t KEY_TYPE = uint8_t(DocIdType::STRING); int SqliteStoreExecutorImpl::CreateDatabase(const std::string &path, const DBConfig &config, sqlite3 *&db) { if (db != nullptr) { @@ -74,7 +76,7 @@ int SqliteStoreExecutorImpl::GetDBConfig(std::string &config) std::string dbConfigKeyStr = "DB_CONFIG"; Key dbConfigKey = { dbConfigKeyStr.begin(), dbConfigKeyStr.end() }; Value dbConfigVal; - int errCode = GetData("grd_meta", dbConfigKey, dbConfigVal); + int errCode = GetDataByKey("grd_meta", dbConfigKey, dbConfigVal); config.assign(dbConfigVal.begin(), dbConfigVal.end()); return errCode; } @@ -84,7 +86,7 @@ int SqliteStoreExecutorImpl::SetDBConfig(const std::string &config) std::string dbConfigKeyStr = "DB_CONFIG"; Key dbConfigKey = { dbConfigKeyStr.begin(), dbConfigKeyStr.end() }; Value dbConfigVal = { config.begin(), config.end() }; - return PutData("grd_meta", dbConfigKey, dbConfigVal); + return PutData("grd_meta", dbConfigKey, dbConfigVal, false); // dont need to add Key type; } int SqliteStoreExecutorImpl::StartTransaction() @@ -102,11 +104,14 @@ int SqliteStoreExecutorImpl::Rollback() return SQLiteUtils::RollbackTransaction(dbHandle_); } -int SqliteStoreExecutorImpl::PutData(const std::string &collName, const Key &key, const Value &value) +int SqliteStoreExecutorImpl::PutData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType) { if (dbHandle_ == nullptr) { return -E_ERROR; } + if (isNeedAddKeyType) { + key.push_back(KEY_TYPE); // Stitching ID type + } std::string sql = "INSERT OR REPLACE INTO '" + collName + "' VALUES (?,?);"; int errCode = SQLiteUtils::ExecSql( dbHandle_, sql, @@ -127,11 +132,15 @@ int SqliteStoreExecutorImpl::PutData(const std::string &collName, const Key &key return E_OK; } -int SqliteStoreExecutorImpl::InsertData(const std::string &collName, const Key &key, const Value &value) +int SqliteStoreExecutorImpl::InsertData(const std::string &collName, Key &key, const Value &value, + bool isNeedAddKeyType) { if (dbHandle_ == nullptr) { return -E_ERROR; } + if (isNeedAddKeyType) { + key.push_back(KEY_TYPE); // Stitching ID type + } std::string sql = "INSERT INTO '" + collName + "' VALUES (?,?);"; int errCode = SQLiteUtils::ExecSql( dbHandle_, sql, @@ -152,7 +161,7 @@ int SqliteStoreExecutorImpl::InsertData(const std::string &collName, const Key & return E_OK; } -int SqliteStoreExecutorImpl::GetData(const std::string &collName, const Key &key, Value &value) const +int SqliteStoreExecutorImpl::GetDataByKey(const std::string &collName, Key &key, Value &value) const { if (dbHandle_ == nullptr) { GLOGE("Invalid db handle."); @@ -166,7 +175,7 @@ int SqliteStoreExecutorImpl::GetData(const std::string &collName, const Key &key SQLiteUtils::BindBlobToStatement(stmt, 1, key); return E_OK; }, - [&value, &innerErrorCode](sqlite3_stmt *stmt) { + [&value, &innerErrorCode](sqlite3_stmt *stmt, bool &isMatchOneData) { SQLiteUtils::GetColumnBlobValue(stmt, 0, value); innerErrorCode = E_OK; return E_OK; @@ -178,8 +187,57 @@ int SqliteStoreExecutorImpl::GetData(const std::string &collName, const Key &key return innerErrorCode; } -int SqliteStoreExecutorImpl::GetFieldedData(const std::string &collName, const JsonObject &filterObj, - std::vector> &values) const +int SqliteStoreExecutorImpl::GetDataById(const std::string &collName, Key &key, Value &value) const +{ + if (dbHandle_ == nullptr) { + GLOGE("Invalid db handle."); + return -E_ERROR; + } + key.push_back(KEY_TYPE); // Stitching ID type + int innerErrorCode = -E_NOT_FOUND; + std::string sql = "SELECT value FROM '" + collName + "' WHERE key=?;"; + int errCode = SQLiteUtils::ExecSql( + dbHandle_, sql, + [key](sqlite3_stmt *stmt) { + SQLiteUtils::BindBlobToStatement(stmt, 1, key); + return E_OK; + }, + [&value, &innerErrorCode](sqlite3_stmt *stmt, bool &isMatchOneData) { + SQLiteUtils::GetColumnBlobValue(stmt, 0, value); + innerErrorCode = E_OK; + return E_OK; + }); + if (errCode != E_OK) { + GLOGE("[sqlite executor] Get data failed. err=%d", errCode); + return errCode; + } + return innerErrorCode; +} + +std::string GeneralInsertSql(const std::string &collName, Key &key, int isIdExist) +{ + std::string sqlEqual = "SELECT key, value FROM '" + collName + "' WHERE key=?;"; + std::string sqlOrder = "SELECT key, value FROM '" + collName + "' ORDER BY KEY;"; + std::string sqlLarger = "SELECT key, value FROM '" + collName + "' WHERE key>?;"; + if (isIdExist) { + return sqlEqual; + } else { + return (key.empty()) ? sqlOrder : sqlLarger; + } +} + +void AssignValueToData(std::string &keyStr, std::string &valueStr, std::pair &values, + int &innerErrorCode, bool &isMatchOneData) +{ + keyStr.pop_back(); // get id from really key. + values.first = keyStr; + values.second = valueStr; + innerErrorCode = E_OK; + isMatchOneData = true; // this args work in ExecSql fuction +} + +int SqliteStoreExecutorImpl::GetDataByFilter(const std::string &collName, Key &key, const JsonObject &filterObj, + std::pair &values, int isIdExist) const { if (dbHandle_ == nullptr) { GLOGE("Invalid db handle."); @@ -189,26 +247,32 @@ int SqliteStoreExecutorImpl::GetFieldedData(const std::string &collName, const J Value valueResult; bool isFindMatch = false; int innerErrorCode = -E_NOT_FOUND; - std::string sql = "SELECT key, value FROM '" + collName + "'ORDER BY KEY;"; + std::string sql = GeneralInsertSql(collName, key, isIdExist); + key.push_back(KEY_TYPE); + std::string keyStr(key.begin(), key.end()); int errCode = SQLiteUtils::ExecSql( dbHandle_, sql, - [](sqlite3_stmt *stmt) { + [key](sqlite3_stmt *stmt) { + if (!key.empty()) { + SQLiteUtils::BindBlobToStatement(stmt, 1, key); + } return E_OK; }, - [&keyResult, &innerErrorCode, &valueResult, &filterObj, &values, &isFindMatch](sqlite3_stmt *stmt) { + [&keyResult, &innerErrorCode, &valueResult, &filterObj, &values, &isFindMatch](sqlite3_stmt *stmt, + bool &isMatchOneData) { SQLiteUtils::GetColumnBlobValue(stmt, 0, keyResult); SQLiteUtils::GetColumnBlobValue(stmt, 1, valueResult); std::string keyStr(keyResult.begin(), keyResult.end()); std::string valueStr(valueResult.begin(), valueResult.end()); - int externErrCode; - JsonObject srcObj = JsonObject::Parse(valueStr, externErrCode, true); - if (externErrCode != E_OK) { + JsonObject srcObj = JsonObject::Parse(valueStr, innerErrorCode, true); + if (innerErrorCode != E_OK) { GLOGE("srcObj Parsed failed"); - return externErrCode; + return innerErrorCode; } - if (JsonCommon::IsJsonNodeMatch(srcObj, filterObj, externErrCode)) { - isFindMatch = true; - values.emplace_back(std::pair(keyStr, valueStr)); + if (JsonCommon::IsJsonNodeMatch(srcObj, filterObj, innerErrorCode)) { + isFindMatch = true; // this args work in this function + (void)AssignValueToData(keyStr, valueStr, values, innerErrorCode, isMatchOneData); + return E_OK; // match count; } innerErrorCode = E_OK; return E_OK; @@ -223,15 +287,16 @@ int SqliteStoreExecutorImpl::GetFieldedData(const std::string &collName, const J return innerErrorCode; } -int SqliteStoreExecutorImpl::DelData(const std::string &collName, const Key &key) +int SqliteStoreExecutorImpl::DelData(const std::string &collName, Key &key) { if (dbHandle_ == nullptr) { GLOGE("Invalid db handle."); return -E_ERROR; } + key.push_back(KEY_TYPE); int errCode = 0; Value valueRet; - if (GetData(collName, key, valueRet) != E_OK) { + if (GetDataByKey(collName, key, valueRet) != E_OK) { return -E_NO_DATA; } std::string sql = "DELETE FROM '" + collName + "' WHERE key=?;"; @@ -320,7 +385,7 @@ bool SqliteStoreExecutorImpl::IsCollectionExists(const std::string &name, int &e SQLiteUtils::BindTextToStatement(stmt, 1, name); return E_OK; }, - [&isExists](sqlite3_stmt *stmt) { + [&isExists](sqlite3_stmt *stmt, bool &isMatchOneData) { isExists = true; return E_OK; }); @@ -330,22 +395,12 @@ bool SqliteStoreExecutorImpl::IsCollectionExists(const std::string &name, int &e return isExists; } -int SqliteStoreExecutorImpl::GetCollectionOption(const std::string &name, std::string &option) -{ - std::string collOptKeyStr = "COLLECTION_OPTION_" + name; - Key collOptKey = { collOptKeyStr.begin(), collOptKeyStr.end() }; - Value collOptVal; - int errCode = GetData("grd_meta", collOptKey, collOptVal); - option.assign(collOptVal.begin(), collOptVal.end()); - return errCode; -} - int SqliteStoreExecutorImpl::SetCollectionOption(const std::string &name, const std::string &option) { std::string collOptKeyStr = "COLLECTION_OPTION_" + name; Key collOptKey = { collOptKeyStr.begin(), collOptKeyStr.end() }; Value collOptVal = { option.begin(), option.end() }; - return PutData("grd_meta", collOptKey, collOptVal); + return PutData("grd_meta", collOptKey, collOptVal, false); // dont need to add key type; } int SqliteStoreExecutorImpl::CleanCollectionOption(const std::string &name) diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h index 7b82379e3b78749a0186d83012d4f7eb7e98e610..8da9ed30f3ddfe6ac1d7b71e96daf749665c73d6 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_store_executor_impl.h @@ -37,18 +37,18 @@ public: int Commit() override; int Rollback() override; - int PutData(const std::string &collName, const Key &key, const Value &value) override; - int InsertData(const std::string &collName, const Key &key, const Value &value) override; - int GetData(const std::string &collName, const Key &key, Value &value) const override; - int GetFieldedData(const std::string &collName, const JsonObject &filterObj, - std::vector> &values) const override; - int DelData(const std::string &collName, const Key &key) override; + int PutData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType = true) override; + int InsertData(const std::string &collName, Key &key, const Value &value, bool isNeedAddKeyType = true) override; + int GetDataByKey(const std::string &collName, Key &key, Value &value) const override; + int GetDataById(const std::string &collName, Key &key, Value &value) const override; + int GetDataByFilter(const std::string &collName, Key &key, const JsonObject &filterObj, + std::pair &values, int isIdExist) const override; + int DelData(const std::string &collName, Key &key) override; int CreateCollection(const std::string &name, const std::string &option, bool ignoreExists) override; int DropCollection(const std::string &name, bool ignoreNonExists) override; bool IsCollectionExists(const std::string &name, int &errCode) override; - int GetCollectionOption(const std::string &name, std::string &option) override; int SetCollectionOption(const std::string &name, const std::string &option) override; int CleanCollectionOption(const std::string &name) override; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp index 0b40db956d3580017853729965be085fb8d59bdb..2c56227d361895f44d5ae22ebcb13497b983a6c6 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.cpp @@ -21,8 +21,7 @@ namespace DocumentDB { const int MAX_BLOB_READ_SIZE = 5 * 1024 * 1024; // 5M limit -const int MAX_TEXT_READ_SIZE = 5 * 1024 * 1024; // 5M limit -const int BUSY_TIMEOUT_MS = 3000; // 3000ms for sqlite busy timeout. +const int BUSY_TIMEOUT_MS = 3000; // 3000ms for sqlite busy timeout. const std::string BEGIN_SQL = "BEGIN TRANSACTION"; const std::string BEGIN_IMMEDIATE_SQL = "BEGIN IMMEDIATE TRANSACTION"; const std::string COMMIT_SQL = "COMMIT TRANSACTION"; @@ -36,6 +35,7 @@ int MapSqliteError(int errCode) return E_OK; case SQLITE_PERM: case SQLITE_CANTOPEN: + return -E_INVALID_ARGS; case SQLITE_READONLY: return -E_FILE_OPERATION; case SQLITE_NOTADB: @@ -162,10 +162,6 @@ int SQLiteUtils::BindBlobToStatement(sqlite3_stmt *statement, int index, const s errCode = sqlite3_bind_blob(statement, index, static_cast(value.data()), value.size(), SQLITE_TRANSIENT); } - - if (errCode != SQLITE_OK) { - GLOGE("[SQLiteUtil][Bind blob] Failed to bind the value:%d", errCode); - } return errCode; } @@ -179,7 +175,7 @@ int SQLiteUtils::GetColumnBlobValue(sqlite3_stmt *statement, int index, std::vec if (keySize < 0 || keySize > MAX_BLOB_READ_SIZE) { GLOGW("[SQLiteUtils][Column blob] size over limit:%d", keySize); value.resize(MAX_BLOB_READ_SIZE + 1); // Reset value size to invalid - return E_OK; // Return OK for continue get data, but value is invalid + return E_OK; // Return OK for continue get data, but value is invalid } auto keyRead = static_cast(sqlite3_column_blob(statement, index)); @@ -208,29 +204,6 @@ int SQLiteUtils::BindTextToStatement(sqlite3_stmt *statement, int index, const s return E_OK; } -int SQLiteUtils::GetColumnTextValue(sqlite3_stmt *statement, int index, std::string &value) -{ - if (statement == nullptr) { - return -E_INVALID_ARGS; - } - - int valSize = sqlite3_column_bytes(statement, index); - if (valSize < 0 || valSize > MAX_TEXT_READ_SIZE) { - GLOGW("[SQLiteUtils][Column text] size over limit:%d", valSize); - value.resize(MAX_TEXT_READ_SIZE + 1); // Reset value size to invalid - return E_OK; // Return OK for continue get data, but value is invalid - } - - const unsigned char *val = sqlite3_column_text(statement, index); - if (valSize == 0 || val == nullptr) { - value = {}; - } else { - value = std::string(reinterpret_cast(val)); - } - - return E_OK; -} - int SQLiteUtils::BeginTransaction(sqlite3 *db, TransactType type) { if (type == TransactType::IMMEDIATE) { @@ -267,18 +240,18 @@ int SQLiteUtils::ExecSql(sqlite3 *db, const std::string &sql) } int SQLiteUtils::ExecSql(sqlite3 *db, const std::string &sql, const std::function &bindCallback, - const std::function &resultCallback) + const std::function &resultCallback) { if (db == nullptr || sql.empty()) { return -E_INVALID_ARGS; } bool bindFinish = true; sqlite3_stmt *stmt = nullptr; + bool isMatchOneData = false; int errCode = SQLiteUtils::GetStatement(db, sql, stmt); if (errCode != E_OK) { goto END; } - do { if (bindCallback) { errCode = bindCallback(stmt); @@ -295,7 +268,10 @@ int SQLiteUtils::ExecSql(sqlite3 *db, const std::string &sql, const std::functio } else if (errCode != SQLITE_ROW) { goto END; // Step return error } - if (resultCallback != nullptr && ((errCode = resultCallback(stmt)) != E_OK)) { + if (resultCallback != nullptr) { // find one data, stop stepping. + errCode = resultCallback(stmt, isMatchOneData); + } + if (resultCallback != nullptr && ((errCode != E_OK) || isMatchOneData)) { goto END; } } diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h index 3567163c6387ef2022c2400ddc60a279027e72e1..88cc77efd2f05fb8ffb991d26a0b4cb206ad6d7d 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/oh_adapter/src/sqlite_utils.h @@ -40,7 +40,6 @@ public: static int GetColumnBlobValue(sqlite3_stmt *statement, int index, std::vector &value); static int BindTextToStatement(sqlite3_stmt *statement, int index, const std::string &value); - static int GetColumnTextValue(sqlite3_stmt *statement, int index, std::string &value); static int BeginTransaction(sqlite3 *db, TransactType type = TransactType::DEFERRED); static int CommitTransaction(sqlite3 *db); @@ -48,7 +47,7 @@ public: static int ExecSql(sqlite3 *db, const std::string &sql); static int ExecSql(sqlite3 *db, const std::string &sql, const std::function &bindCallback, - const std::function &resultCallback); + const std::function &resultCallback); private: static void SqliteLogCallback(void *data, int err, const char *msg); diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/BUILD.gn b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/BUILD.gn index b4cc59a3ae64003eaf9c8e7dc43b34fdb12a7ed1..c8a7cab5bef9293c572812296e3c230be15dd291 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/BUILD.gn +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/BUILD.gn @@ -57,6 +57,7 @@ ohos_source_set("src_file") { "../../src/executor/document/grd_resultset_api.cpp", "../../src/interface/src/collection.cpp", "../../src/interface/src/doc_errno.cpp", + "../../src/interface/src/document_key.cpp", "../../src/interface/src/document_store.cpp", "../../src/interface/src/document_store_manager.cpp", "../../src/interface/src/projection_tree.cpp", @@ -81,9 +82,9 @@ ohos_source_set("src_file") { deps += [ "//third_party/cJSON:cjson" ] external_deps = [ "c_utils:utils", - "hisysevent_native:libhisysevent", - "hitrace_native:hitrace_meter", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", ] subsystem_name = "distributeddatamgr" @@ -115,9 +116,9 @@ template("gaussdb_rd_unittest") { ] external_deps = [ "c_utils:utils", - "hisysevent_native:libhisysevent", - "hitrace_native:hitrace_meter", - "hiviewdfx_hilog_native:libhilog", + "hilog:libhilog", + "hisysevent:libhisysevent", + "hitrace:hitrace_meter", ] } } diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp index 81d9ff2569ff4c9cf8af98d260783e82fc5f78ba..93358885e594aa3f5425834b4d70f9c406961985 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_api_test.cpp @@ -16,6 +16,7 @@ #include #include "doc_errno.h" +#include "doc_limit.h" #include "documentdb_test_utils.h" #include "grd_base/grd_db_api.h" #include "grd_base/grd_error.h" @@ -65,7 +66,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBTest001, TestSize.Level0) EXPECT_EQ(GRD_CreateCollection(db, "student", "", 0), GRD_OK); - EXPECT_EQ(GRD_UpsertDoc(db, "student", R""({"_id":"10001"})"", R""({"name":"Tom","age":23})"", 0), 1); + EXPECT_EQ(GRD_UpsertDoc(db, "student", R""({"_id":"10001"})"", R""({"name":"Tom", "age":23})"", 0), 1); EXPECT_EQ(GRD_DropCollection(db, "student", 0), GRD_OK); @@ -156,7 +157,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBTest004, TestSize.Level0) HWTEST_F(DocumentDBApiTest, OpenDBPathTest001, TestSize.Level0) { GRD_DB *db = nullptr; - std::vector invalidPath = { nullptr, "", "/a/b/c/" }; + std::vector invalidPath = { nullptr, "" }; for (auto path : invalidPath) { GLOGD("OpenDBPathTest001: open db with path: %s", path); int status = GRD_DBOpen(path, nullptr, GRD_DB_OPEN_CREATE, &db); @@ -179,6 +180,21 @@ HWTEST_F(DocumentDBApiTest, OpenDBPathTest002, TestSize.Level0) EXPECT_EQ(status, GRD_FAILED_FILE_OPERATION); } +/** + * @tc.name: OpenDBPathTest004 + * @tc.desc: call GRD_DBOpen, input dbFile as existed menu + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBApiTest, OpenDBPathTest004, TestSize.Level0) +{ + GRD_DB *db = nullptr; + std::string pathNoPerm = "../build"; + int status = GRD_DBOpen(pathNoPerm.c_str(), nullptr, GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(status, GRD_INVALID_ARGS); +} + /** * @tc.name: OpenDBConfigTest001 * @tc.desc: Test open document db with invalid config option @@ -190,7 +206,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigTest001, TestSize.Level0) { GRD_DB *db = nullptr; std::string path = "./document.db"; - constexpr int MAX_JSON_LEN = 512 * 1024; + const int MAX_JSON_LEN = 1024 * 1024; std::string configStr = std::string(MAX_JSON_LEN, 'a'); int status = GRD_DBOpen(path.c_str(), configStr.c_str(), GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_OVER_LIMIT); @@ -226,6 +242,65 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigTest003, TestSize.Level0) EXPECT_EQ(status, GRD_INVALID_ARGS); } +/** + * @tc.name: OpenDBConfigTest004 + * @tc.desc: call GRD_DBOpen, input the value's length of configStr is 1024K + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ + +HWTEST_F(DocumentDBApiTest, OpenDBConfigTest004, TestSize.Level0) +{ + /** + * @tc.steps:step1. input the value's length of configStr is 1024 k(not contained '\0') + */ + GRD_DB *db = nullptr; + std::string part1 = "{ \"pageSize\": \" "; + std::string part2 = "\" }"; + std::string path = "./document.db"; + std::string val = string(MAX_DB_CONFIG_LEN - part1.size() - part2.size(), 'k'); + std::string configStr = part1 + val + part2; + int ret = GRD_DBOpen(path.c_str(), configStr.c_str(), GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(ret, GRD_OVER_LIMIT); + /** + * @tc.steps:step2. input the value's length of configStr is 1024 k(contained '\0') + */ + std::string val2 = string(MAX_DB_CONFIG_LEN - part1.size() - part2.size() - 1, 'k'); + std::string configStr2 = part1 + val2 + part2 + "\0"; + ret = GRD_DBOpen(path.c_str(), configStr2.c_str(), GRD_DB_OPEN_CREATE, &db); + EXPECT_EQ(ret, GRD_INVALID_ARGS); +} + +/** + * @tc.name: OpenDBConfigTest005 + * @tc.desc: Verify open db with different configStr connection when first connection not close, + * return GRD_INVALID_CONFIG_VALUE. + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBApiTest, OpenDBConfigTest005, TestSize.Level0) +{ + /** + * @tc.steps:step1. call GRD_DBOPEN to create a db with connection1. + * @tc.expected:step1. GRD_OK. + */ + const char *configStr = R"({"pageSize":64, "bufferPoolSize": 4096})"; + GRD_DB *db1 = nullptr; + std::string path = "./document.db"; + int result = GRD_DBOpen(path.c_str(), configStr, GRD_DB_OPEN_CREATE, &db1); + ASSERT_EQ(result, GRD_OK); + /** + * @tc.steps:step2. connection2 call GRD_DBOpen to open the db with the different configStr. + * @tc.expected:step2. return GRD_CONFIG_OPTION_MISMATCH. + */ + const char *configStr_2 = R"({"pageSize":4})"; + GRD_DB *db2 = nullptr; + result = GRD_DBOpen(path.c_str(), configStr_2, GRD_DB_OPEN_ONLY, &db2); + ASSERT_EQ(result, GRD_INVALID_ARGS); + + ASSERT_EQ(GRD_DBClose(db1, GRD_DB_CLOSE), GRD_OK); +} /** * @tc.name: OpenDBConfigMaxConnNumTest001 * @tc.desc: Test open document db with invalid config item maxConnNum @@ -245,7 +320,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigMaxConnNumTest001, TestSize.Level0) R""({"maxConnNum":1000000007})"", R""({"maxConnNum":"16"})"", R""({"maxConnNum":{"value":17}})"", - R""({"maxConnNum":[16,17,18]})"", + R""({"maxConnNum":[16, 17, 18]})"", }; for (const auto &config : configList) { GLOGD("OpenDBConfigMaxConnNumTest001: test with config:%s", config.c_str()); @@ -363,7 +438,7 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigPageSizeTest001, TestSize.Level0) R""({"pageSize":1000000007})"", R""({"pageSize":"4"})"", R""({"pageSize":{"value":8}})"", - R""({"pageSize":[16,32,64]})"", + R""({"pageSize":[16, 32, 64]})"", }; for (const auto &config : configList) { GLOGD("OpenDBConfigPageSizeTest001: test with config:%s", config.c_str()); @@ -381,9 +456,8 @@ int GetDBPageSize(const std::string &path) if (db == nullptr) { return 0; } - int pageSize = 0; - SQLiteUtils::ExecSql(db, "PRAGMA page_size;", nullptr, [&pageSize](sqlite3_stmt *stmt) { + SQLiteUtils::ExecSql(db, "PRAGMA page_size;", nullptr, [&pageSize](sqlite3_stmt *stmt, bool &isMatchOneData) { pageSize = sqlite3_column_int(stmt, 0); return E_OK; }); @@ -500,11 +574,11 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigBufferPoolTest001, TestSize.Level0) GRD_DB *db = nullptr; std::string path = "./document.db"; - int status = GRD_DBOpen(path.c_str(), R""({"pageSize":64,"bufferPoolSize":4096})"", GRD_DB_OPEN_CREATE, &db); + int status = GRD_DBOpen(path.c_str(), R""({"pageSize":64, "bufferPoolSize":4096})"", GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_OK); EXPECT_EQ(GRD_DBClose(db, 0), GRD_OK); - status = GRD_DBOpen(path.c_str(), R""({"pageSize":64,"bufferPoolSize":4095})"", GRD_DB_OPEN_CREATE, &db); + status = GRD_DBOpen(path.c_str(), R""({"pageSize":64, "bufferPoolSize":4095})"", GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_INVALID_ARGS); status = GRD_DBOpen(path.c_str(), R""({"bufferPoolSize":1023})"", GRD_DB_OPEN_CREATE, &db); @@ -526,11 +600,11 @@ HWTEST_F(DocumentDBApiTest, OpenDBConfigPubBuffTest001, TestSize.Level0) GRD_DB *db = nullptr; std::string path = "./document.db"; - int status = GRD_DBOpen(path.c_str(), R""({"pageSize":64,"redopubbufsize":4033})"", GRD_DB_OPEN_CREATE, &db); + int status = GRD_DBOpen(path.c_str(), R""({"pageSize":64, "redopubbufsize":4033})"", GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_OK); EXPECT_EQ(GRD_DBClose(db, 0), GRD_OK); - status = GRD_DBOpen(path.c_str(), R""({"pageSize":64,"redopubbufsize":4032})"", GRD_DB_OPEN_CREATE, &db); + status = GRD_DBOpen(path.c_str(), R""({"pageSize":64, "redopubbufsize":4032})"", GRD_DB_OPEN_CREATE, &db); EXPECT_EQ(status, GRD_INVALID_ARGS); status = GRD_DBOpen(path.c_str(), R""({"redopubbufsize":255})"", GRD_DB_OPEN_CREATE, &db); diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_collection_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_collection_test.cpp index 92aedcd5d871f89d2a1bf0154a0c95ba5c118a21..04431be400ba2e7d2c2ad9a79cc68edcf37f4695 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_collection_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_collection_test.cpp @@ -157,7 +157,7 @@ HWTEST_F(DocumentDBCollectionTest, CollectionTest005, TestSize.Level0) R""({"maxDoc":0})"", R""({"maxDoc":"123"})"", R""({"maxDoc":{"value":1024}})"", - R""({"maxDoc":[1,2,4,8]})"", + R""({"maxDoc":[1, 2, 4, 8]})"", R""({"minDoc":1024})"", }; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp index d43519a713f56cc57a3bd5e70ea7683210e5a642..129ea35b067d8ea17146f0a062d3ffd235368400 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_data_test.cpp @@ -32,7 +32,7 @@ namespace { std::string g_path = "./document.db"; GRD_DB *g_db = nullptr; const char *g_coll = "student"; - +constexpr int JSON_LENS_MAX = 1024 * 1024; class DocumentDBDataTest : public testing::Test { public: static void SetUpTestCase(void); @@ -133,7 +133,6 @@ HWTEST_F(DocumentDBDataTest, UpsertDataTest006, TestSize.Level0) { std::string filter = R""({"_id":"1234"})""; std::string document = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; - for (auto flags : std::vector { 2, 4, 8, 64, 1024, UINT32_MAX }) { EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), document.c_str(), flags), GRD_INVALID_ARGS); } @@ -149,7 +148,7 @@ HWTEST_F(DocumentDBDataTest, UpsertDataTest006, TestSize.Level0) HWTEST_F(DocumentDBDataTest, UpsertDataTest007, TestSize.Level0) { std::string filter = R""({"_id":"1234"})""; - std::string val = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; + std::string val = R""({"name":"Tmono", "age":18, "addr":{"city":"shanghai", "postal":200001}})""; EXPECT_EQ(GRD_UpsertDoc(g_db, "collection_not_exists", filter.c_str(), val.c_str(), GRD_DOC_REPLACE), GRD_INVALID_ARGS); } @@ -164,18 +163,22 @@ HWTEST_F(DocumentDBDataTest, UpsertDataTest007, TestSize.Level0) HWTEST_F(DocumentDBDataTest, UpsertDataTest008, TestSize.Level0) { std::string filter = R""({"_id":"1234"})""; - std::string document = R""({"name":"Tmn","age":18,"addr":{"city":"shanghai","postal":200001}})""; + std::string document = R""({"name":"Tmn", "age":18, "addr":{"city":"shanghai", "postal":200001}})""; EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), document.c_str(), GRD_DOC_REPLACE), 1); - std::string updateDoc = R""({"name":"Xue","case":2,"age":28,"addr":{"city":"shenzhen","postal":518000}})""; + std::string updateDoc = R""({"name":"Xue", "case":2, "age":28, "addr":{"city":"shenzhen", "postal":518000}})""; EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), updateDoc.c_str(), GRD_DOC_APPEND), 1); } HWTEST_F(DocumentDBDataTest, UpsertDataTest009, TestSize.Level0) { std::string filter = R""({"_id":"abcde"})""; - std::string document = R"({"field1": ")" + string(1024 * 1024 + 1, 'a') + "\"}"; - EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), document.c_str(), GRD_DOC_REPLACE), GRD_OVER_LIMIT); + std::string head = R"({"field1": ")"; + std::string document = + head + string(JSON_LENS_MAX - filter.size() - head.size() - 1, 'a') + "\"}"; // 13 is {"field1": size + EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), document.c_str(), GRD_DOC_APPEND), 1); + std::string document2 = head + string(JSON_LENS_MAX - filter.size() - head.size(), 'a') + "\"}"; + EXPECT_EQ(GRD_UpsertDoc(g_db, g_coll, filter.c_str(), document2.c_str(), GRD_DOC_REPLACE), GRD_OVER_LIMIT); } HWTEST_F(DocumentDBDataTest, UpsertDataTest010, TestSize.Level0) @@ -191,6 +194,32 @@ HWTEST_F(DocumentDBDataTest, UpsertDataTest011, TestSize.Level0) ASSERT_EQ(result, GRD_INVALID_FORMAT); } +/** + * @tc.name: UpdateDataTest012 + * @tc.desc: Input parameter collectionName is null, invoke the GRD_UpsertDoc interface to update data. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDBDataTest, UpsertDataTest012, TestSize.Level0) +{ + /** + * @tc.steps: step1. Insert a document. + * @tc.expected: step1. return GRD_OK. + */ + int result = GRD_InsertDoc(g_db, g_coll, "{}", 0); + ASSERT_EQ(result, GRD_OK); + /** + * @tc.steps: step2. Parameter collectionName is Invalid format + * @tc.expected: step2. return Update faild. + */ + result = GRD_UpsertDoc(g_db, "null", "{}", "{}", 1); + ASSERT_EQ(result, GRD_INVALID_ARGS); + + result = GRD_UpsertDoc(g_db, "!! &%$^%$&*%^。m中文、、请问E:112423123", "{}", "{}", 1); + ASSERT_EQ(result, GRD_INVALID_ARGS); +} + /** * @tc.name: UpdateDataTest001 * @tc.desc: @@ -244,24 +273,6 @@ HWTEST_F(DocumentDBDataTest, UpdateDataTest003, TestSize.Level0) } } -/** - * @tc.name: UpdateDataTest004 - * @tc.desc: Test update data with invalid filter - * @tc.type: FUNC - * @tc.require: - * @tc.author: lianhuix - */ -HWTEST_F(DocumentDBDataTest, UpdateDataTest004, TestSize.Level0) {} - -/** - * @tc.name: UpdateDataTest005 - * @tc.desc: Test update data with invalid doc - * @tc.type: FUNC - * @tc.require: - * @tc.author: lianhuix - */ -HWTEST_F(DocumentDBDataTest, UpdateDataTest005, TestSize.Level0) {} - /** * @tc.name: UpdateDataTest006 * @tc.desc: Test update data with invalid flag @@ -272,7 +283,7 @@ HWTEST_F(DocumentDBDataTest, UpdateDataTest005, TestSize.Level0) {} HWTEST_F(DocumentDBDataTest, UpdateDataTest006, TestSize.Level0) { std::string filter = R""({"_id":"1234"})""; - std::string document = R""({"name":"Tmono","age":18,"addr":{"city":"shanghai","postal":200001}})""; + std::string document = R""({"name":"Tmono", "age":18, "addr":{"city":"shanghai", "postal":200001}})""; std::vector invalidFlags = { 2, 4, 8, 1024, UINT32_MAX }; for (auto flag : invalidFlags) { GLOGD("UpdateDataTest006: update data with flag: %u", flag); @@ -293,7 +304,7 @@ HWTEST_F(DocumentDBDataTest, UpdateDataTest007, TestSize.Level0) HWTEST_F(DocumentDBDataTest, UpdateDataTest008, TestSize.Level0) { const char *updateStr = - R""({"field2":{"c_field":{"cc_field":{"ccc_field":{"ccc_field":[1,false,1.234e2,["hello world!"]]}}}}})""; + R""({"field2":{"c_field":{"cc_field":{"ccc_field":{"ccc_field":[1, false, 1.234e2, ["hello world!"]]}}}}})""; int result = GRD_UpdateDoc(g_db, g_coll, "{\"field\" : 2}", updateStr, 0); int result2 = GRD_UpsertDoc(g_db, g_coll, "{\"field\" : 2}", updateStr, 0); EXPECT_EQ(result, GRD_INVALID_ARGS); @@ -303,11 +314,11 @@ HWTEST_F(DocumentDBDataTest, UpdateDataTest008, TestSize.Level0) HWTEST_F(DocumentDBDataTest, UpdateDataTest009, TestSize.Level0) { std::string filter = R""({"_id":"1234"})""; - std::string document = R""({"_id":"1234", "field1":{"c_field":{"cc_field":{"ccc_field":1}}}, "field2" : 2})""; + std::string document = R""({"_id":"1234","field1":{"c_field":{"cc_field":{"ccc_field":1}}},"field2":2})""; EXPECT_EQ(GRD_InsertDoc(g_db, g_coll, document.c_str(), 0), GRD_OK); - std::string updata = R""({"field1":1, "FIELD1":[1, true, 1.23456789, "hello world!", null]})""; + std::string updata = R""({"field1":1,"FIELD1":[1,true,1.23456789,"hello world!",null]})""; EXPECT_EQ(GRD_UpdateDoc(g_db, g_coll, filter.c_str(), updata.c_str(), 0), 1); GRD_ResultSet *resultSet = nullptr; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_delete_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_delete_test.cpp index 15e5dce407efa3e5d13cc30a152822e6dd8201b3..8165c73b2d17300929e07ee105f245950929671d 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_delete_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_delete_test.cpp @@ -29,7 +29,7 @@ using namespace DocumentDBUnitTest; namespace { constexpr const char *COLLECTION_NAME = "student"; constexpr const char *NULL_JSON_STR = "{}"; -constexpr int MAX_COLLECTION_LENS = 511; +const int MAX_COLLECTION_LENS = 511; std::string g_path = "./document.db"; GRD_DB *g_db = nullptr; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp index 01320cbcc21d53d6c947204ae398604597e37a37..654294a3c924d00700f184eecbb24f1bb28b27e5 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp @@ -35,6 +35,7 @@ namespace { std::string g_path = "./document.db"; GRD_DB *g_db = nullptr; constexpr const char *COLLECTION_NAME = "student"; +constexpr const char *colName = "data_"; const int MAX_COLLECTION_NAME = 511; const int MAX_ID_LENS = 899; @@ -49,7 +50,9 @@ static const char *g_document4 = "{\"_id\" : \"4\", \"name\":\"doc4\",\"item\":\ static const char *g_document5 = "{\"_id\" : \"5\", \"name\":\"doc5\",\"item\":\"journal\",\"personInfo\":\ [{\"sex\" : \"woma\", \"school\" : \"B\", \"age\" : 15}, {\"school\":\"C\", \"age\" : 35}]}"; static const char *g_document6 = "{\"_id\" : \"6\", \"name\":\"doc6\",\"item\":false,\"personInfo\":\ - [{\"school\":\"B\", \"teacher\" : \"mike\",\"age\" : 15}, {\"school\":\"C\", \"teacher\" : \"moon\",\"age\":20}]}"; + [{\"school\":\"B\", \"teacher\" : \"mike\", \"age\" : 15},\ + {\"school\":\"C\", \"teacher\" : \"moon\", \"age\" : 20}]}"; + static const char *g_document7 = "{\"_id\" : \"7\", \"name\":\"doc7\",\"item\":\"fruit\",\"other_Info\":\ [{\"school\":\"BX\", \"age\" : 15}, {\"school\":\"C\", \"age\" : 35}]}"; static const char *g_document8 = "{\"_id\" : \"8\", \"name\":\"doc8\",\"item\":true,\"personInfo\":\ @@ -1438,17 +1441,14 @@ HWTEST_F(DocumentDBFindTest, DocumentDBFindTest061, TestSize.Level1) char *value = nullptr; EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); CompareValue(value, document061); - EXPECT_EQ(GRD_FreeValue(value), GRD_OK); EXPECT_EQ(GRD_Next(resultSet), GRD_OK); EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); CompareValue(value, document062); - EXPECT_EQ(GRD_FreeValue(value), GRD_OK); EXPECT_EQ(GRD_Next(resultSet), GRD_OK); EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); CompareValue(value, document063); - EXPECT_EQ(GRD_FreeValue(value), GRD_OK); EXPECT_EQ(GRD_Next(resultSet), GRD_OK); EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); @@ -1465,4 +1465,41 @@ HWTEST_F(DocumentDBFindTest, DocumentDBFindTest062, TestSize.Level1) Query query = { filter, projection }; EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_INVALID_ARGS); } + +HWTEST_F(DocumentDBFindTest, DocumentDBFindTest063, TestSize.Level1) +{ + GRD_DB *test_db = nullptr; + std::string path = "./dataShare.db"; + int status = GRD_DBOpen(path.c_str(), nullptr, GRD_DB_OPEN_CREATE, &test_db); + EXPECT_EQ(status, GRD_OK); + EXPECT_EQ(GRD_CreateCollection(test_db, colName, "", 0), GRD_OK); + string document1 = "{\"_id\":\"key2_11_com.acts.ohos.data.datasharetestclient_100\",\ + \"bundleName\":\"com.acts.ohos.data.datasharetestclient\",\"key\":\"key2\",\ + \"subscriberId\":11,\"timestamp\":1509100700,""\"userId\":100,\"value\":{\"type\":0,"; + string document2 = "\"value\":["; + string document3 = "5,"; + string document4 = document3; + for (int i = 0; i < 100000; i++) { + document4 += document3; + } + document4.push_back('5'); + string document5 = "]}}"; + string document0635 = document1 + document2 + document4 + document5; + EXPECT_EQ(GRD_InsertDoc(test_db, colName, document0635.c_str(), 0), GRD_OK); + EXPECT_EQ(status, GRD_OK); + const char *filter = "{}"; + GRD_ResultSet *resultSet = nullptr; + const char *projection = "{\"id_\":true, \"timestamp\":true, \"key\":true, \"bundleName\": true, " + "\"subscriberId\": true}"; + Query query = { filter, projection }; + EXPECT_EQ(GRD_FindDoc(test_db, colName, query, 1, &resultSet), GRD_OK); + char *value; + while (GRD_Next(resultSet) == GRD_OK) { + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + GRD_FreeValue(value); + } + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); + EXPECT_EQ(GRD_DBClose(test_db, 0), GRD_OK); + DocumentDBTestUtils::RemoveTestDbFiles(path.c_str()); +} } // namespace diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp index 54be32da739f55f4338a71f2c3d56ef418f664a8..8e862bb6f03454940e39a9bdc2d711020c5d8c2b 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_insert_test.cpp @@ -330,14 +330,14 @@ HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest014, TestSize.Level1) * @tc.expected:step1.GRD_INVALID_ARGS */ const char *document2 = R""({"level1" : {"level2" : {"level3" : [{ "level5" : "level5_1val", - "level5_2":"level5_2_val"}, "level4_val1","level4_val2"], "level3_2" : "level3_2_val"}},"_id":"14"})""; + "level5_2":"level5_2_val"}, "level4_val1","level4_val2"], "level3_2" : "level3_2_val"}}, "_id":"14"})""; EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document2, 0), GRD_INVALID_ARGS); /** * @tc.steps:step1.document's JSON depth is 4 * @tc.expected:step1.GRD_OK */ const char *document3 = R""({"level1" : {"level2" : {"level3" : { "level4" : "level5_1val"}, - "level3_2" : "level3_2_val"}},"_id":"14"})""; + "level3_2" : "level3_2_val"}}, "_id":"14"})""; EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document3, 0), GRD_OK); } @@ -563,8 +563,8 @@ HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest025, TestSize.Level1) * @tc.steps:step1.documents JSON depth is 4, which is allowed. * @tc.expected:step1.GRD_OK. */ - const char *document1 = "{\"_id\" : \"25_0\", \"level1\" : { \"level2\" : {\"level3\" :\ - {\"level4\" : \"level4Val\" } } } , \"level1_2\" : \"level1_2Val\" }"; + const char *document1 = "{\"_id\" : \"25_0\", \"level1\" : {\"level2\" : {\"level3\" :\ + {\"level4\" : \"level4Val\"}}} , \"level1_2\" : \"level1_2Val\" }"; EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_OK); /** * @tc.steps:step2.documents JSON depth is exactly 4. @@ -824,6 +824,12 @@ HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest045, TestSize.Level1) HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest046, TestSize.Level1) { const char *document1 = R""({})""; - EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_OK); +} + +HWTEST_F(DocumentDBInsertTest, DocumentDBInsertTest047, TestSize.Level1) +{ + const char *document1 = "{\"empty\" : null}"; + EXPECT_EQ(GRD_InsertDoc(g_db, RIGHT_COLLECTION_NAME, document1, 0), GRD_OK); } } // namespace diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp index bfe3a8463d90bc7e4e1c786c92ee91fb95100e0b..ff4820e9c55afd4166a3c7c835706fa5b61ddc06 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_json_common_test.cpp @@ -44,9 +44,9 @@ void DocumentDBJsonCommonTest::TearDown(void) {} HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest001, TestSize.Level0) { - std::string document = R""({"name":"Tmn","age":18,"addr":{"city":"shanghai","postal":200001}})""; - std::string updateDoc = R""({"name":"Xue","case":{"field1":1,"field2":"string","field3":[1,2,3]}, - "age":28,"addr":{"city":"shenzhen","postal":518000}})""; + std::string document = R""({"name":"Tmn", "age":18, "addr":{"city":"shanghai", "postal":200001}})""; + std::string updateDoc = R""({"name":"Xue", "case":{"field1":1, "field2":"string", "field3":[1, 2, 3]}, + "age":28, "addr":{"city":"shenzhen", "postal":518000}})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); @@ -68,9 +68,10 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest001, TestSize.Level0) HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest002, TestSize.Level0) { - std::string document = R""({"name":"Tmn","case":2,"age":[1,2,3],"addr":{"city":"shanghai","postal":200001}})""; - std::string updateDoc = R""({"name":["Xue","Neco","Lip"],"grade":99,"age":18,"addr": - [{"city":"shanghai","postal":200001},{"city":"beijing","postal":100000}]})""; + std::string document = R""({"name":"Tmn", "case":2, "age":[1, 2, 3], + "addr":{"city":"shanghai", "postal":200001}})""; + std::string updateDoc = R""({"name":["Xue", "Neco", "Lip"], "grade":99, "age":18, "addr": + [{"city":"shanghai", "postal":200001}, {"city":"beijing", "postal":100000}]})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); @@ -91,10 +92,10 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest002, TestSize.Level0) HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest003, TestSize.Level0) { - std::string document = R""({"name":["Tmn","BB","Alice"],"age":[1,2,3],"addr":[{"city":"shanghai","postal":200001}, - {"city":"wuhan","postal":430000}]})""; - std::string updateDoc = R""({"name":["Xue","Neco","Lip"],"age":18,"addr":[{"city":"shanghai","postal":200001}, - {"city":"beijing","postal":100000}]})""; + std::string document = R""({"name":["Tmn", "BB", "Alice"], "age":[1, 2, 3], + "addr":[{"city":"shanghai", "postal":200001}, {"city":"wuhan", "postal":430000}]})""; + std::string updateDoc = R""({"name":["Xue", "Neco", "Lip"], "age":18, "addr":[{"city":"shanghai", "postal":200001}, + {"city":"beijing", "postal":100000}]})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); @@ -129,7 +130,7 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest004, TestSize.Level0) HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest005, TestSize.Level0) { - std::string document = R""({"name":["Tmn","BB","Alice"]})""; + std::string document = R""({"name":["Tmn", "BB", "Alice"]})""; std::string updateDoc = R""({"name.2":"GG"})""; int errCode = E_OK; @@ -146,28 +147,9 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest005, TestSize.Level0) EXPECT_EQ(itemCase.GetItemValue().GetStringValue(), "GG"); } -HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest006, TestSize.Level0) -{ - std::string document = R""({"name":{"first":"Tno","last":"moray"}})""; - std::string updateDoc = R""({"name":{"midle.AA":"GG"}})""; - - int errCode = E_OK; - JsonObject src = JsonObject::Parse(document, errCode); - EXPECT_EQ(errCode, E_OK); - JsonObject add = JsonObject::Parse(updateDoc, errCode); - EXPECT_EQ(errCode, E_OK); - - EXPECT_EQ(JsonCommon::Append(src, add, false), E_OK); - GLOGD("result: %s", src.Print().c_str()); - - JsonObject itemCase = src.FindItem({ "name", "midle.AA" }, errCode); - EXPECT_EQ(errCode, E_OK); - EXPECT_EQ(itemCase.GetItemValue().GetStringValue(), "GG"); -} - HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest007, TestSize.Level0) { - std::string document = R""({"name":{"first":["XX","CC"],"last":"moray"}})""; + std::string document = R""({"name":{"first":["XX", "CC"], "last":"moray"}})""; std::string updateDoc = R""({"name.first.0":"LL"})""; int errCode = E_OK; @@ -186,8 +168,8 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest007, TestSize.Level0) HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest008, TestSize.Level0) { - std::string document = R""({"name":{"first":"XX","last":"moray"}})""; - std::string updateDoc = R""({"name":{"first":["XXX","BBB","CCC"]}})""; + std::string document = R""({"name":{"first":"XX", "last":"moray"}})""; + std::string updateDoc = R""({"name":{"first":["XXX", "BBB", "CCC"]}})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); @@ -205,7 +187,7 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest008, TestSize.Level0) HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest009, TestSize.Level0) { - std::string document = R""({"name":{"first":["XXX","BBB","CCC"],"last":"moray"}})""; + std::string document = R""({"name":{"first":["XXX", "BBB", "CCC"], "last":"moray"}})""; std::string updateDoc = R""({"name":{"first":"XX"}})""; int errCode = E_OK; @@ -286,8 +268,8 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest013, TestSize.Level0) HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest014, TestSize.Level0) { - std::string document = R""({"name":{"first":"Xue","second":"Lang"}, "info":"AA"})""; - std::string updateDoc = R""({"info":"GG", "name.0":"GG"})""; + std::string document = R""({"name":{"first":"Xue", "second":"Lang"}})""; + std::string updateDoc = R""({"name.0":"GG"})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); @@ -301,7 +283,7 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest014, TestSize.Level0) HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest015, TestSize.Level0) { std::string document = R""({"name":{"first":"Xue","second":"Lang"}})""; - std::string updateDoc = R""({"name.first":["GG","MM"]})""; + std::string updateDoc = R""({"name.first":["GG", "MM"]})""; int errCode = E_OK; JsonObject src = JsonObject::Parse(document, errCode); @@ -459,7 +441,7 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest012, TestSize.Leve { std::string document = R""({"item" : "journal", "instock" : [{"warehose" : "A", "qty" : 5}, {"warehose" : "C", "qty" : 15}]})""; - std::string filter = R""({"instock" : {"warehose" : "A", "bad" : "2" ,"qty" : 5}})""; + std::string filter = R""({"instock" : {"warehose" : "A", "bad" : "2" , "qty" : 5}})""; int errCode = E_OK; JsonObject srcObj = JsonObject::Parse(document, errCode); EXPECT_EQ(errCode, E_OK); @@ -608,19 +590,4 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest023, TestSize.Leve EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj1, filterObj1, errCode), true); EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj2, filterObj1, errCode), false); } - -HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest024, TestSize.Level0) -{ - std::string document = "{\"name\": 1, \"personInfo.school\": 1, \"personInfo.age\": 1}"; - int errCode = E_OK; - JsonObject srcObj = JsonObject::Parse(document, errCode); - EXPECT_EQ(errCode, E_OK); - auto path = JsonCommon::ParsePath(srcObj, errCode); - for (auto singlePath : path) { - for (auto fieldName : singlePath) { - GLOGE("fieldName is =========>%s", fieldName.c_str()); - } - GLOGE("///////////////////////////"); - } -} } // namespace \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_jsonobject_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_jsonobject_test.cpp index 93d46974db1f0e372d108a60bd25a64023e5c246..604f2c386eeb5e9d5a9f019633c9dcc4404be2ab 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_jsonobject_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_jsonobject_test.cpp @@ -49,7 +49,7 @@ void DocumentDBJsonObjectTest::TearDown(void) {} */ HWTEST_F(DocumentDBJsonObjectTest, JsonObjectTest001, TestSize.Level0) { - const std::string config = R""({"a":123,"b":{"c":234,"d":"12345"}})""; + const std::string config = R""({"a":123, "b":{"c":234, "d":"12345"}})""; int ret = E_OK; JsonObject conf = JsonObject::Parse(config, ret); diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_key_document_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_key_document_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7121f15cbb3f0a5598dcb8aa2c8412ac8ef5427f --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/oh_adapter/documentdb_key_document_test.cpp @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2023 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 "doc_errno.h" +#include "document_key.h" +#include "documentdb_test_utils.h" +#include "log_print.h" + +using namespace DocumentDB; +using namespace testing::ext; +using namespace DocumentDBUnitTest; + +namespace { +class DocumentDBKeyCommonTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + void SetUp(); + void TearDown(); +}; + +void DocumentDBKeyCommonTest::SetUpTestCase(void) {} + +void DocumentDBKeyCommonTest::TearDownTestCase(void) {} + +void DocumentDBKeyCommonTest::SetUp(void) {} + +void DocumentDBKeyCommonTest::TearDown(void) {} + +} // namespace \ No newline at end of file