diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_type_export.h b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_type_export.h index ca6163a2ca74a24fe5f6cdb14c5fb8d097cf9a0f..b8b3000a0d4d0a4ed0eae9958b75cce7f66a5b9e 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_type_export.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/include/grd_base/grd_type_export.h @@ -27,9 +27,10 @@ typedef struct GRD_DB GRD_DB; */ #define GRD_DB_OPEN_ONLY 0x00 #define GRD_DB_OPEN_CREATE 0x01 -#define GRD_DB_OPEN_CHECK_FOR_ABNORMAL 0x02 //check data in database if close abnormally last time, - //if data is corrupted, rebuild the database -#define GRD_DB_OPEN_CHECK 0x04//check data in database when open database, if data is corrupted, rebuild the database. +#define GRD_DB_OPEN_CHECK_FOR_ABNORMAL 0x02 // check data in database if close abnormally last time, + // if data is corrupted, rebuild the database +#define GRD_DB_OPEN_CHECK 0x04// check data in database when open database, if data is corrupted, rebuild the database. + /** * @brief Close database config */ diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/json_common.h b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/json_common.h index 4494f01e9c1e5d8031e924a67ff0428a36303b34..5c464162d0613cffe34289e7d89f3a421a65ef77 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/json_common.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/include/json_common.h @@ -23,25 +23,29 @@ #include "json_object.h" namespace DocumentDB { -class JsonCommon -{ +class JsonCommon { public: JsonCommon() = default; ~JsonCommon(); static ValueObject GetValueByFiled(JsonObject &node, const std::string& filed); + static ValueObject GetValueByFiled(JsonObject &node, const std::string& filed, bool &isFiledExist); static bool CheckJsonField(JsonObject &node); static bool CheckProjectionField(JsonObject &node); - static int ParseNode(JsonObject &Node, std::vector singlePath, std::vector> &resultPath, bool isFirstFloor); + static int ParseNode(JsonObject &Node, std::vector singlePath, + std::vector> &resultPath, bool isFirstFloor); static std::vector> ParsePath(const JsonObject &node); - static std::vector GetLeafValue(JsonObject &node); - + static std::vector GetLeafValue(const JsonObject &node); static int Append(const JsonObject &src, const JsonObject &add); - + static bool IsJsonNodeMatch(const JsonObject &src, const JsonObject &target, int &errCode); private: + static bool JsonEqualJudge(JsonFieldPath &itemPath, const JsonObject &src, const JsonObject &item, + int &isAlreadyMatched, bool &isCollapse, int &isMatchFlag); static bool CheckNode(JsonObject &Node, std::set filedSet, bool &errFlag); - static bool CheckProjectionNode(JsonObject &Node, std::set filedSet, bool &errFlag, bool isFirstFloor); - static int CheckLeafNode(JsonObject &Node, std::vector &leafValue); + static bool CheckProjectionNode(JsonObject &Node, std::set filedSet, + bool &errFlag, bool isFirstFloor); + static void CheckLeafNode(const JsonObject &Node, std::vector &leafValue); + static bool IsArrayMathch(const JsonObject &src, const JsonObject &target, int &isAlreadyMatched); }; } // DocumentDB #endif // JSON_COMMON_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/collection_option.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/collection_option.cpp index fcb3da1e104a498199062579447580dea2c2ae56..82f32c29b99ba27d98422737bc50c3cead4038c9 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/collection_option.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/collection_option.cpp @@ -31,7 +31,6 @@ const std::vector DB_CONFIG = { bool CheckConfigSupport(const JsonObject &config, int &errCode) { - JsonObject child = config.GetChild(); while (!child.IsNull()) { std::string fieldName = child.GetItemFiled(); diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/json_common.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/json_common.cpp index 47a75e9c19df9005c94aa216b17228b2be4fd734..3fce2b4fd5bb3d0f210a540a4ccde5a2a4c40372 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/json_common.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/common/src/json_common.cpp @@ -14,11 +14,10 @@ */ #include #include - -#include "json_common.h" #include "doc_errno.h" #include "log_print.h" #include "securec.h" +#include "json_common.h" namespace DocumentDB { ValueObject JsonCommon::GetValueByFiled(JsonObject &node, const std::string& filed) @@ -37,7 +36,26 @@ ValueObject JsonCommon::GetValueByFiled(JsonObject &node, const std::string& fil return ValueObject(); } -int JsonCommon::CheckLeafNode(JsonObject &node, std::vector &leafValue) +ValueObject JsonCommon::GetValueByFiled(JsonObject &node, const std::string& filed, bool &isFiledExist) +{ + while (!node.IsNull()) { + if (node.GetItemFiled() == filed) { + auto itemValue = node.GetItemValue(); + isFiledExist = true; + return itemValue; + } + if (node.GetNext().IsNull()) { + isFiledExist = false; + return ValueObject(); + } + auto nodeNew = node.GetNext(); + node = nodeNew; + } + isFiledExist = false; + return ValueObject(); +} + +void JsonCommon::CheckLeafNode(const JsonObject &node, std::vector &leafValue) { if (node.GetChild().IsNull()) { auto itemValue = node.GetItemValue(); @@ -51,22 +69,25 @@ int JsonCommon::CheckLeafNode(JsonObject &node, std::vector &leafVa auto nodeNew = node.GetNext(); CheckLeafNode(nodeNew, leafValue); } - return E_OK; } -std::vector JsonCommon::GetLeafValue(JsonObject &node) +std::vector JsonCommon::GetLeafValue(const JsonObject &node) { std::vector leafValue; + if (node.IsNull()) { + GLOGE("Get leafValue faied, node is empty"); + return leafValue; + } CheckLeafNode(node, leafValue); return leafValue; } -bool JsonCommon::CheckNode(JsonObject &node, std::set filedSet, bool &errFlag) +bool JsonCommon::CheckNode(JsonObject &node, std::set filedSet, bool &errFlag) { if (!errFlag) { return false; } - std::string fieldName; + std::string fieldName; if (!node.IsNull()) { int ret = 0; fieldName = node.GetItemFiled(ret); @@ -78,8 +99,7 @@ bool JsonCommon::CheckNode(JsonObject &node, std::set filedSet, boo errFlag = false; return false; } - } - else { + } else { errFlag = false; return false; } @@ -92,7 +112,7 @@ bool JsonCommon::CheckNode(JsonObject &node, std::set filedSet, boo errFlag = false; return false; } - } + } } if (!node.GetChild().IsNull()) { auto nodeNew = node.GetChild(); @@ -106,37 +126,36 @@ bool JsonCommon::CheckNode(JsonObject &node, std::set filedSet, boo return errFlag; } -bool JsonCommon::CheckJsonField(JsonObject &jsonObj) +bool JsonCommon::CheckJsonField(JsonObject &jsonObj) { std::set filedSet; bool errFlag = true; return CheckNode(jsonObj, filedSet, errFlag); } -bool JsonCommon::CheckProjectionNode(JsonObject &node, std::set filedSet, bool &errFlag, bool isFirstFloor) +bool JsonCommon::CheckProjectionNode(JsonObject &node, std::set filedSet, + bool &errFlag, bool isFirstFloor) { if (!errFlag) { return false; } - std::string fieldName; + std::string fieldName; if (!node.IsNull()) { int ret = 0; fieldName = node.GetItemFiled(ret); - if (filedSet.find(fieldName) == filedSet.end()) { - if (ret == E_OK) { - filedSet.insert(fieldName); - } - if (ret == E_OK && fieldName.empty()) { + if (filedSet.find(fieldName) == filedSet.end() && ret == E_OK) { + filedSet.insert(fieldName); + if (fieldName.empty()) { errFlag = false; return false; } - } - else { + } else { errFlag = false; return false; } for (int i = 0; i < fieldName.size(); i++) { - if (!((isalpha(fieldName[i])) || (isdigit(fieldName[i])) || ('_' == fieldName[i]) || (isFirstFloor && '.' == fieldName[i]))) { + if (!((isalpha(fieldName[i])) || (isdigit(fieldName[i])) || ('_' == fieldName[i]) || + (isFirstFloor && '.' == fieldName[i]))) { errFlag = false; return false; } @@ -144,7 +163,7 @@ bool JsonCommon::CheckProjectionNode(JsonObject &node, std::set fil errFlag = false; return false; } - } + } } if (!node.GetChild().IsNull()) { auto nodeNew = node.GetChild(); @@ -158,7 +177,7 @@ bool JsonCommon::CheckProjectionNode(JsonObject &node, std::set fil return errFlag; } -bool JsonCommon::CheckProjectionField(JsonObject &jsonObj) +bool JsonCommon::CheckProjectionField(JsonObject &jsonObj) { std::set filedSet; bool errFlag = true; @@ -166,7 +185,8 @@ bool JsonCommon::CheckProjectionField(JsonObject &jsonObj) return CheckProjectionNode(jsonObj, filedSet, errFlag, isFirstFloor); } -int JsonCommon::ParseNode(JsonObject &node, std::vector singlePath, std::vector> &resultPath, bool isFirstFloor) +int JsonCommon::ParseNode(JsonObject &node, std::vector singlePath, + std::vector> &resultPath, bool isFirstFloor) { std::vector fatherPath; if (isFirstFloor) { @@ -193,8 +213,7 @@ int JsonCommon::ParseNode(JsonObject &node, std::vector singlePath, if (!node.GetChild().IsNull() && node.GetChild().GetItemFiled() != "") { auto nodeNew = node.GetChild(); ParseNode(nodeNew, singlePath, resultPath, false); - } - else { + } else { resultPath.emplace_back(singlePath); } if (!node.GetNext().IsNull()) { @@ -217,9 +236,9 @@ std::vector> JsonCommon::ParsePath(const JsonObject &ro } namespace { -JsonFieldPath ExpendPath(const JsonFieldPath &path, bool &isCollapse) +JsonFieldPath SplitePath(const JsonFieldPath &path, bool &isCollapse) { - if (path.size() > 1) { // only first lever has collapse field + if (path.size() > 1 || path.empty()) { // only first lever has collapse field return path; } JsonFieldPath splitPath; @@ -238,14 +257,30 @@ JsonFieldPath ExpendPath(const JsonFieldPath &path, bool &isCollapse) } void JsonObjectIterator(const JsonObject &obj, JsonFieldPath path, - std::function foo) + std::function AppendFoo) +{ + JsonObject child = obj.GetChild(); + while (!child.IsNull()) { + JsonFieldPath childPath = path; + childPath.push_back(child.GetItemFiled()); + if (AppendFoo != nullptr && AppendFoo(childPath, obj, child)) { + JsonObjectIterator(child, childPath, AppendFoo); + } + child = child.GetNext(); + } + return; +} + +void JsonObjectIterator(const JsonObject &obj, JsonFieldPath path, + std::function MatchFoo) { JsonObject child = obj.GetChild(); - while(!child.IsNull()) { + while (!child.IsNull()) { + bool isCollapse = false; JsonFieldPath childPath = path; childPath.push_back(child.GetItemFiled()); - if (foo != nullptr && foo(childPath, obj, child)) { - JsonObjectIterator(child, childPath, foo); + if (MatchFoo != nullptr && MatchFoo(childPath, child)) { + JsonObjectIterator(child, childPath, MatchFoo); } child = child.GetNext(); } @@ -259,7 +294,7 @@ int JsonCommon::Append(const JsonObject &src, const JsonObject &add) JsonObjectIterator(add, {}, [&src, &externErrCode](const JsonFieldPath &path, const JsonObject &father, const JsonObject &item) { bool isCollapse = false; - JsonFieldPath itemPath = ExpendPath(path, isCollapse); + JsonFieldPath itemPath = SplitePath(path, isCollapse); JsonFieldPath fatherPath = itemPath; fatherPath.pop_back(); int errCode = E_OK; @@ -308,4 +343,123 @@ int JsonCommon::Append(const JsonObject &src, const JsonObject &add) }); return externErrCode; } + +bool JsonCommon::IsArrayMathch(const JsonObject &src, const JsonObject &target, int &isAlreadyMatched) +{ + JsonObject srcChild = src.GetChild(); + JsonObject targetObj = target; + bool isMatch = false; + int errCode = 0; + while (!srcChild.IsNull()) { + if (srcChild.GetType() == JsonObject::Type::JSON_OBJECT && target.GetType() == + JsonObject::Type::JSON_OBJECT && (IsJsonNodeMatch(srcChild, target, errCode))) { + isMatch = true; + isAlreadyMatched = 1; + break; + } + srcChild = srcChild.GetNext(); + } + return isMatch; +} + +bool JsonCommon::JsonEqualJudge(JsonFieldPath &itemPath, const JsonObject &src, const JsonObject &item, + int &isAlreadyMatched, bool &isCollapse, int &isMatchFlag) +{ + int errCode; + JsonObject srcItem = src.FindItemPowerMode(itemPath, errCode); + JsonFieldPath granpaPath = itemPath; + std::string lastFiledName = granpaPath.back(); + granpaPath.pop_back(); + JsonObject granpaItem = src.FindItemPowerMode(granpaPath, errCode); + if (granpaItem.GetType() == JsonObject::Type::JSON_ARRAY && isCollapse) { + JsonObject fatherItem = granpaItem.GetChild(); + while (!fatherItem.IsNull()) { + int isEqual = true; + int compareRet = (fatherItem.GetObjectItem(lastFiledName, errCode).Print() == item.Print()); + if (errCode == E_OK) { + isEqual = compareRet; + } + if (isEqual) { + GLOGI("Filter value is equal with src"); + isMatchFlag = isEqual; + isAlreadyMatched = 1; + } + fatherItem = fatherItem.GetNext(); + } + } + if (srcItem.GetType() == JsonObject::Type::JSON_ARRAY && item.GetType() == JsonObject::Type::JSON_ARRAY && + !isAlreadyMatched) { + bool isEqual = (srcItem.Print() == item.Print()); + if (!isEqual) { + GLOGI("Filter value is No equal with src"); + isMatchFlag = isEqual; + } + isAlreadyMatched = isMatchFlag; + return false; // Both leaf node, no need iterate + } + if (srcItem.GetType() == JsonObject::Type::JSON_LEAF && item.GetType() == JsonObject::Type::JSON_LEAF && + !isAlreadyMatched) { + bool isEqual = (srcItem.GetItemValue() == item.GetItemValue()); + if (!isEqual) { + GLOGI("Filter value is No equal with src"); + isMatchFlag = isEqual; + } + isAlreadyMatched = isMatchFlag; + return false; // Both leaf node, no need iterate + } else if (srcItem.GetType() != item.GetType()) { + if (srcItem.GetType() == JsonObject::Type::JSON_ARRAY) { + GLOGI("srcItem Type is ARRAY, item Type is not ARRAY"); + bool isEqual = IsArrayMathch(srcItem, item, isAlreadyMatched); + if (!isEqual) { + isMatchFlag = isEqual; + } + return true; + } + GLOGI("valueType is different"); + isMatchFlag = false; + return false; // Different node types, overwrite directly, skip child node + } + return true; // Both array or object +} + +bool JsonCommon::IsJsonNodeMatch(const JsonObject &src, const JsonObject &target, int &errCode) +{ + errCode = E_OK; + int isMatchFlag = true; + JsonObjectIterator(target, {}, + [&src, &isMatchFlag, &errCode](JsonFieldPath &path, const JsonObject &item) { + int isAlreadyMatched = 0; + bool isCollapse = false; + if (isMatchFlag == false) { + return false; + } + JsonFieldPath itemPath = SplitePath(path, isCollapse); + if (src.IsFieldExistsPowerMode(itemPath)) { + return JsonEqualJudge(itemPath, src, item, isAlreadyMatched, isCollapse, isMatchFlag); + } else { + if (isCollapse) { + GLOGE("Match failed, path not exist."); + isMatchFlag = false; + return false; + } + GLOGI("Not match anything"); + if (isAlreadyMatched == 0) { + isMatchFlag = false; + } + std::vector ItemLeafValue = GetLeafValue(item); + int isNULLFlag = true; + for (auto ValueItem : ItemLeafValue) { + if (ValueItem.GetValueType() != ValueObject::ValueType::VALUE_NULL) { + GLOGI("leaf value is not null"); + isNULLFlag = false; + } else { + GLOGI("filter leaf is null, Src leaf is dont exist"); + isMatchFlag = true; + } + } + return false; // Source path not exist, if leaf value is null, isMatchFlag become true, else it will become false. + } + }); + return isMatchFlag; +} } // namespace DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/document_check.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/document_check.cpp index e8370c8d4435ebfc89b26718fb247078783a09af..071591b8c314499eb73cbe1068224ba0d61932b0 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/document_check.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/document_check.cpp @@ -15,10 +15,10 @@ #include #include -#include "document_check.h" #include "doc_errno.h" #include "log_print.h" #include "securec.h" +#include "document_check.h" namespace DocumentDB { namespace { @@ -65,18 +65,25 @@ bool CheckCommon::CheckCollectionName(const std::string &collectionName, std::st return false; } lowerCaseName = collectionName; - std::transform(lowerCaseName.begin(), lowerCaseName.end(), lowerCaseName.begin(), [](unsigned char c){ + std::transform(lowerCaseName.begin(), lowerCaseName.end(), lowerCaseName.begin(), [](unsigned char c) { return std::tolower(c); }); return true; } int CheckCommon::CheckFilter(JsonObject &filterObj) -{ +{ if (filterObj.GetDeep() > JSON_DEEP_MAX) { GLOGE("filter's json deep is deeper than JSON_DEEP_MAX"); return -E_INVALID_ARGS; } + if (!filterObj.GetChild().IsNull()) { + auto filterObjChild = filterObj.GetChild(); + if (!JsonCommon::CheckJsonField(filterObjChild)) { + GLOGE("filter json field format is illegal"); + return -E_INVALID_ARGS; + } + } int ret = CheckIdFormat(filterObj); if (ret != E_OK) { GLOGE("Filter Id format is illegal"); @@ -88,6 +95,38 @@ int CheckCommon::CheckFilter(JsonObject &filterObj) return E_OK; } +int CheckCommon::CheckFilter(JsonObject &filterObj, bool &isOnlyId, std::vector> &filterPath) +{ + for (int i = 0; i < filterPath.size(); i++) { + if (filterPath[i].size() > JSON_DEEP_MAX) { + GLOGE("filter's json deep is deeper than JSON_DEEP_MAX"); + return -E_INVALID_ARGS; + } + } + if (!filterObj.GetChild().GetNext().IsNull()) { + isOnlyId = false; + } + for (int i = 0; i < filterPath.size(); i++) { + for (auto fieldName : filterPath[i]) { + for (int j = 0; j < fieldName.size(); j++) { + if (!((isalpha(fieldName[j])) || (isdigit(fieldName[j])) || ('_' == fieldName[j]))) { + return -E_INVALID_ARGS; + } + } + } + } + bool isIdExisit = false; + int ret = CheckIdFormat(filterObj, isIdExisit); + if (ret != E_OK) { + GLOGE("Filter Id format is illegal"); + return ret; + } + if (!isIdExisit) { + isOnlyId = false; + } + return E_OK; +} + int CheckCommon::CheckIdFormat(JsonObject &filterJson) { auto filterObjChild = filterJson.GetChild(); @@ -101,6 +140,22 @@ int CheckCommon::CheckIdFormat(JsonObject &filterJson) return E_OK; } +int CheckCommon::CheckIdFormat(JsonObject &filterJson, bool &isIdExisit) +{ + auto filterObjChild = filterJson.GetChild(); + ValueObject idValue = JsonCommon::GetValueByFiled(filterObjChild, KEY_ID, isIdExisit); + if ((idValue.GetValueType() == ValueObject::ValueType::VALUE_NULL) && isIdExisit == false) { + return E_OK; + } + if (idValue.GetValueType() != ValueObject::ValueType::VALUE_STRING) { + return -E_INVALID_ARGS; + } + if (idValue.GetStringValue().length() > MAX_ID_LENS) { + return -E_OVER_LIMIT; + } + return E_OK; +} + int CheckCommon::CheckDocument(JsonObject &documentObj) { if (documentObj.GetDeep() > JSON_DEEP_MAX) { @@ -137,11 +192,11 @@ bool CheckCommon::CheckProjection(JsonObject &projectionObj, std::vector> &filterPath); static int CheckIdFormat(JsonObject &data); + static int CheckIdFormat(JsonObject &data, bool &isIdExisit); static int CheckDocument(JsonObject &document); static bool CheckProjection(JsonObject &projectionObj, std::vector> &path); }; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/grd_document_api.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/grd_document_api.cpp index e033b9fb8af6859029e8f80cd468ef4c1733e8d3..c19584c0cef76652632f87ad802472f1e82c053d 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/grd_document_api.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/grd_document_api.cpp @@ -86,7 +86,7 @@ int GRD_DeleteDoc(GRD_DB *db, const char *collectionName, const char *filter, un int ret = db->store_->DeleteDocument(collectionName, filter, flags); int errCode = TrasnferDocErr(ret); int deleteCount = 0; - switch (errCode) { + switch (errCode) { case GRD_OK: deleteCount = 1; return deleteCount; @@ -95,19 +95,23 @@ int GRD_DeleteDoc(GRD_DB *db, const char *collectionName, const char *filter, un deleteCount = 0; return deleteCount; break; + default: + break; } return errCode; } -int GRD_FindDoc(GRD_DB *db, const char *collectionName, Query query, unsigned int flags, GRD_ResultSet **resultSet) +int GRD_FindDoc(GRD_DB *db, const char *collectionName, Query query, unsigned int flags, + GRD_ResultSet **resultSet) { - if (db == nullptr || db->store_ == nullptr || collectionName == nullptr || resultSet == nullptr || query.filter == nullptr + if (db == nullptr || db->store_ == nullptr || collectionName == nullptr || resultSet == nullptr || + query.filter == nullptr || query.projection == nullptr) { return GRD_INVALID_ARGS; } GRD_ResultSet *grdResultSet = new (std::nothrow)GRD_ResultSet(); if (grdResultSet == nullptr) { - GLOGE("Memory allocation failed!" ); + GLOGE("Memory allocation failed!"); return -E_FAILED_MEMORY_ALLOCATE; } int ret = db->store_->FindDocument(collectionName, query.filter, query.projection, flags, grdResultSet); @@ -117,5 +121,5 @@ int GRD_FindDoc(GRD_DB *db, const char *collectionName, Query query, unsigned in return TrasnferDocErr(ret); } *resultSet = grdResultSet; - return TrasnferDocErr(ret); + return TrasnferDocErr(ret); } diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/grd_resultset_api.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/grd_resultset_api.cpp index 6db93e850e6fc3ed641f9e9e35d34de8d18e7104..686f2846a37edd24e8b16242707bed1aeb52837b 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/grd_resultset_api.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/executor/document/grd_resultset_api.cpp @@ -18,8 +18,8 @@ #include "doc_errno.h" #include "grd_base/grd_error.h" #include "grd_resultset_inner.h" -#include "grd_base/grd_resultset_api.h" #include "log_print.h" +#include "grd_base/grd_resultset_api.h" using namespace DocumentDB; @@ -54,7 +54,7 @@ int GRD_GetValue(GRD_ResultSet *resultSet, char **value) int GRD_FreeValue(char *value) { if (value == nullptr) { - return GRD_OK; + return GRD_INVALID_ARGS; } delete[] value; return GRD_OK; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/collection.h b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/collection.h index f295af703547409c7359917e9e4d481f8b71adfc..387ec5b4e1537e412db214a1f607a55da6d37b88 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/collection.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/collection.h @@ -30,9 +30,11 @@ public: int PutDocument(const Key &key, const Value &document); int GetDocument(const Key &key, Value &document) const; + int GetFilededDocument(const JsonObject &filterObj, std::vector> &values) const; int DeleteDocument(const Key &key); + int IsCollectionExists(int &errCode); int UpsertDocument(const std::string &id, const std::string &document, bool isReplace = true); - bool FindDocument(); + bool FindDocument(); int UpdateDocument(const std::string &id, const std::string &document); private: std::string name_; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/document_store.h b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/document_store.h index 25a54a988af0a7cbdfe692bc8ebd78ecd6b08388..6d3747821fd49521f8c2b81e9bc366a387c0fb26 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/document_store.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/document_store.h @@ -34,10 +34,12 @@ public: int DropCollection(const std::string &name, int flags); int UpdateDocument(const std::string &collection, const std::string &filter, const std::string &update, int flags); - int UpsertDocument(const std::string &collection, const std::string &filter, const std::string &document, int flags); + int UpsertDocument(const std::string &collection, const std::string &filter, + const std::string &document, int flags); int InsertDocument(const std::string &collection, const std::string &document, int flag); int DeleteDocument(const std::string &collection, const std::string &filter, int flag); - int FindDocument(const std::string &collection, const std::string &filter, const std::string &projection, int flags, GRD_ResultSet *grdResultSet); + int FindDocument(const std::string &collection, const std::string &filter, + const std::string &projection, int flags, GRD_ResultSet *grdResultSet); KvStoreExecutor *GetExecutor(int errCode); int EraseCollection(const std::string collectionName); private: diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/projection_tree.h b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/projection_tree.h index 15920bd41d178faff1529555bbba0bede7e6e581..8ffcc18c6c525e4f75674af6717516c8780145bf 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/projection_tree.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/projection_tree.h @@ -1,3 +1,17 @@ +/* +* 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 PROJECTION_TREE_H #define PROJECTION_TREE_H @@ -14,12 +28,14 @@ struct ProjectionNode { bool isDeepest; int Deep; int ViewType; - ProjectionNode() { + ProjectionNode() + { Deep = 0; isDeepest = true; } int DeleteProjectionNode(); - ~ProjectionNode () { + ~ProjectionNode () + { DeleteProjectionNode(); } }; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/result_set.h b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/result_set.h index dc87115e27b6e9fcdf544c3fea5d0e831f73e130..e2dca6e9b6e35cda6a5d932d8dfd4e6fd6d78902 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/result_set.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/result_set.h @@ -32,22 +32,29 @@ public: ResultSet(); ~ResultSet(); - int Init(DocumentStore *store, const std::string collectionName, ValueObject &key, std::vector> &path, bool ifShowId, bool viewType); + int Init(DocumentStore *store, const std::string collectionName, const std::string &filter, + std::vector> &path, bool ifShowId, bool viewType, bool &isOnlyId); + int Init(DocumentStore *store, const std::string collectionName, const std::string &filter); int GetNext(); int GetValue(char **value); + int GetKey(std::string &key); int EraseCollection(); private: int CutJsonBranch(std::string &jsonData); - int CheckCutNode(JsonObject *node, std::vector singleCutPath, std::vector> &allCutPath); + int CheckCutNode(JsonObject *node, std::vector singleCutPath, + std::vector> &allCutPath); DocumentStore *store_ = nullptr; std::string collectionName_; ValueObject key_; + std::string filter_; bool ifShowId_ = false; bool viewType_ = false; + bool ifFiled_ = false; + bool isOnlyId_ = false; ProjectionTree projectionTree_; std::vector> projectionPath_; int index_ = 0; - std::vector findValue_; + std::vector> matchDatas_; }; } // DocumentDB -#endif //RESULTSET_H \ No newline at end of file +#endif // RESULTSET_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/result_set_common.h b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/result_set_common.h index dfef9c26d88b963d3204ad1f03e0fefafd8278a6..e32b7b5e9df3f6c3fa1dcb36fb3a4d7cac3c484d 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/result_set_common.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/include/result_set_common.h @@ -24,8 +24,10 @@ namespace DocumentDB { class ValueObject; -int InitResultSet(DocumentStore *store, const std::string collectionName, ValueObject &key, std::vector> &path, bool ifShowId, bool viewType, - ResultSet &resultSet); +int InitResultSet(DocumentStore *store, const std::string collectionName, const std::string &filter, + std::vector> &path, bool ifShowId, bool viewType, ResultSet &resultSet, bool &isOnlyId); +int InitResultSet(DocumentStore *store, const std::string collectionName, + const std::string &filter, ResultSet &resultSet); } // DocumentDB #endif //RESULTSET_COMMON_H diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/collection.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/collection.cpp index fc9fd3ba7271620d129b2ae9a25610a6b50beb04..4a7d28d92f8d2fd7be0f2f05a5a25af85f929faa 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/collection.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/collection.cpp @@ -61,6 +61,15 @@ int Collection::GetDocument(const Key &key, Value &document) const return executor_->GetData(name_, key, document); } +int Collection::GetFilededDocument(const JsonObject &filterObj, + std::vector> &values) const +{ + if (executor_ == nullptr) { + return -E_INVALID_ARGS; + } + return executor_->GetFilededData(name_, filterObj, values); +} + int Collection::DeleteDocument(const Key &key) { if (executor_ == nullptr) { @@ -69,6 +78,11 @@ int Collection::DeleteDocument(const Key &key) return executor_->DelData(name_, key); } +int Collection::IsCollectionExists(int &errCode) +{ + return executor_->IsCollectionExists(name_, errCode); +} + int Collection::UpsertDocument(const std::string &id, const std::string &document, bool isReplace) { if (executor_ == nullptr) { diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/doc_errno.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/doc_errno.cpp index 5bae14d9b54573193a6c4491949f196a3dacaab7..8a1a6f3bb9369ec7a663596d4f1c5522cbd1547d 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/doc_errno.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/doc_errno.cpp @@ -27,7 +27,7 @@ int GetErrorCategory(int errCode) int TrasnferDocErr(int err) { - if(err > 0) { + if (err > 0) { return err; } diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/document_store.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/document_store.cpp index b87e8430bf98e6b4eb0db2d09ad798e4e042e35c..6e8ad25df12785c875e81798f624f900adef2ee4 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/document_store.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/document_store.cpp @@ -27,7 +27,7 @@ const int COLLECTION_LENS_MAX = 512 * 1024; const int JSON_LENS_MAX = 512 * 1024; const int JSON_DEEP_MAX = 4; constexpr const char *KEY_ID = "_id"; -const bool caseIsSensitive = true; +const bool caseSensitive = true; DocumentStore::DocumentStore(KvStoreExecutor *executor) : executor_(executor) { @@ -251,10 +251,10 @@ int DocumentStore::InsertDocument(const std::string &collection, const std::stri } auto coll = Collection(collection, executor_); if (document.length() + 1 > JSON_LENS_MAX) { - GLOGE("document's length is larger than JSON_LENS_MAX"); + GLOGE("document's length is too long"); return -E_OVER_LIMIT; } - JsonObject documentObj = JsonObject::Parse(document, errCode, caseIsSensitive); + JsonObject documentObj = JsonObject::Parse(document, errCode, caseSensitive); if (errCode != E_OK) { GLOGE("Document Parsed faild"); return errCode; @@ -285,28 +285,47 @@ int DocumentStore::DeleteDocument(const std::string &collection, const std::stri return errCode; } auto coll = Collection(collection, executor_); + if (!coll.IsCollectionExists(errCode)) { + return -E_INVALID_ARGS; + } if (filter.empty()) { GLOGE("Filter is empty"); return -E_INVALID_ARGS; } if (filter.length() + 1 > JSON_LENS_MAX) { - GLOGE("filter's length is larger than JSON_LENS_MAX"); + GLOGE("filter's length is too long"); return -E_OVER_LIMIT; } - JsonObject filterObj = JsonObject::Parse(filter, errCode, caseIsSensitive); + JsonObject filterObj = JsonObject::Parse(filter, errCode, caseSensitive); if (errCode != E_OK) { GLOGE("filter Parsed faild"); return errCode; } - errCode = CheckCommon::CheckFilter(filterObj); + std::vector> filterAllPath; + filterAllPath = JsonCommon::ParsePath(filterObj); + bool isOnlyId = true; + errCode = CheckCommon::CheckFilter(filterObj, isOnlyId, filterAllPath); if (errCode != E_OK) { return errCode; } - auto filterObjChild = filterObj.GetChild(); - auto idValue = JsonCommon::GetValueByFiled(filterObjChild, KEY_ID); - std::string id = idValue.GetStringValue(); - Key key(id.begin(), id.end()); + if (isOnlyId) { + auto filterObjChild = filterObj.GetChild(); + auto idValue = JsonCommon::GetValueByFiled(filterObjChild, KEY_ID); + std::string id = idValue.GetStringValue(); + Key key(id.begin(), id.end()); + std::lock_guard lock(dbMutex_); + return coll.DeleteDocument(key); + } + ResultSet resultSet; + InitResultSet(this, collection, filter, resultSet); std::lock_guard lock(dbMutex_); + errCode = resultSet.GetNext(); + if (errCode != E_OK) { + return errCode; + } + std::string id; + resultSet.GetKey(id); + Key key(id.begin(), id.end()); return coll.DeleteDocument(key); } KvStoreExecutor *DocumentStore::GetExecutor(int errCode) @@ -318,7 +337,7 @@ int DocumentStore::FindDocument(const std::string &collection, const std::string { if (flags != 0 && flags != GRD_DOC_ID_DISPLAY) { GLOGE("FindDocument flag is illegal"); - return -E_INVALID_ARGS;; + return -E_INVALID_ARGS; } std::string lowerCaseCollName; int errCode = E_OK; @@ -327,25 +346,26 @@ int DocumentStore::FindDocument(const std::string &collection, const std::string return errCode; } if (filter.length() + 1 > JSON_LENS_MAX) { - GLOGE("filter's length is larger than JSON_LENS_MAX"); + GLOGE("filter's length is too long"); return -E_OVER_LIMIT; } - JsonObject filterObj = JsonObject::Parse(filter, errCode, caseIsSensitive); + JsonObject filterObj = JsonObject::Parse(filter, errCode, caseSensitive); if (errCode != E_OK) { GLOGE("filter Parsed faild"); return errCode; } - errCode = CheckCommon::CheckFilter(filterObj); + std::vector> filterAllPath; + filterAllPath = JsonCommon::ParsePath(filterObj); + bool isOnlyId = true; + errCode = CheckCommon::CheckFilter(filterObj, isOnlyId, filterAllPath); if (errCode != E_OK) { return errCode; } - auto filterObjChild = filterObj.GetChild(); - auto idValue = JsonCommon::GetValueByFiled(filterObjChild, KEY_ID); if (projection.length() + 1 > JSON_LENS_MAX) { - GLOGE("projection's length is larger than JSON_LENS_MAX"); + GLOGE("projection's length is too long"); return -E_OVER_LIMIT; } - JsonObject projectionObj = JsonObject::Parse(projection, errCode, caseIsSensitive); + JsonObject projectionObj = JsonObject::Parse(projection, errCode, caseSensitive); if (errCode != E_OK) { GLOGE("projection Parsed faild"); return errCode; @@ -377,7 +397,7 @@ int DocumentStore::FindDocument(const std::string &collection, const std::string GLOGE("no corresponding table name"); return -E_INVALID_ARGS; } - int ret = InitResultSet(this, collection, idValue, allPath, ifShowId, viewType, grdResultSet->resultSet_); + int ret = InitResultSet(this, collection, filter, allPath, ifShowId, viewType, grdResultSet->resultSet_, isOnlyId); if (ret == E_OK) { collections_[collection] = nullptr; } @@ -386,62 +406,61 @@ int DocumentStore::FindDocument(const std::string &collection, const std::string } return ret; } -int DocumentStore::EraseCollection(const std::string collectionName) { +int DocumentStore::EraseCollection(const std::string collectionName) +{ if (collections_.find(collectionName) != collections_.end()) { collections_.erase(collectionName); return E_OK; } GLOGE("erase collection failed"); + return E_INVALID_ARGS; } -int DocumentStore::GetViewType(JsonObject &jsonObj, bool &viewType) { +int DocumentStore::GetViewType(JsonObject &jsonObj, bool &viewType) +{ auto leafValue = JsonCommon::GetLeafValue(jsonObj); if (leafValue.size() == 0) { return E_INVALID_ARGS; } - bool viewFlag = false; for (int i = 0; i < leafValue.size(); i++) { switch (leafValue[i].GetValueType()) { - case ValueObject::ValueType::VALUE_BOOL: - if (leafValue[i].GetBoolValue()) { - if (i != 0 && !viewType) { - return -E_INVALID_ARGS; - } - viewType = true; - } - else { - if (i != 0 && viewType) { - return E_INVALID_ARGS; - } - viewType == false; - } - break; - case ValueObject::ValueType::VALUE_STRING: - if (leafValue[i].GetStringValue() == "") { - if (i != 0 && !viewType) { - return -E_INVALID_ARGS; + case ValueObject::ValueType::VALUE_BOOL: + if (leafValue[i].GetBoolValue()) { + if (i != 0 && !viewType) { + return -E_INVALID_ARGS; + } + viewType = true; + } else { + if (i != 0 && viewType) { + return E_INVALID_ARGS; + } + viewType == false; } - viewType = true; - } - else { - return -E_INVALID_ARGS; - } - break; - case ValueObject::ValueType::VALUE_NUMBER: - if (leafValue[i].GetIntValue() == 0) { - if (i != 0 && viewType) { + break; + case ValueObject::ValueType::VALUE_STRING: + if (leafValue[i].GetStringValue() == "") { + if (i != 0 && !viewType) { + return -E_INVALID_ARGS; + } + viewType = true; + } else { return -E_INVALID_ARGS; } - viewType = false; - } - else { - if (i != 0 && !viewType) { - return E_INVALID_ARGS; + break; + case ValueObject::ValueType::VALUE_NUMBER: + if (leafValue[i].GetIntValue() == 0) { + if (i != 0 && viewType) { + return -E_INVALID_ARGS; + } + viewType = false; + } else { + if (i != 0 && !viewType) { + return E_INVALID_ARGS; + } + viewType = true; } - viewType = true; - } - break; - default: - return E_INVALID_ARGS; + break; + default: + return E_INVALID_ARGS; } } return E_OK; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/document_store_manager.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/document_store_manager.cpp index f4f2faac4d8a4ea1e9d49bb287b3da4821fb9d8f..c9f2dd0761783bb05244ec67833131d4d86cf737 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/document_store_manager.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/document_store_manager.cpp @@ -14,12 +14,12 @@ */ #include "db_config.h" -#include "document_store_manager.h" #include "doc_errno.h" #include "grd_base/grd_type_export.h" -#include "kv_store_manager.h" #include "log_print.h" #include "os_api.h" +#include "kv_store_manager.h" +#include "document_store_manager.h" namespace DocumentDB { namespace { @@ -80,7 +80,7 @@ int DocumentStoreManager::GetDocumentStore(const std::string &path, const std::s store = new (std::nothrow) DocumentStore(executor); if (store == nullptr) { - GLOGE("Memory allocation failed!" ); + GLOGE("Memory allocation failed!"); return -E_FAILED_MEMORY_ALLOCATE; } if (store == nullptr) { diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/projection_tree.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/projection_tree.cpp index edf6f3568215d97e258f18658f1b67842f093143..ca2abd109b464057682e619779001cc2faaecda7 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/projection_tree.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/projection_tree.cpp @@ -1,7 +1,20 @@ +/* +* 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 "projection_tree.h" - namespace DocumentDB { const int JSON_DEEP_MAX = 4; @@ -11,27 +24,27 @@ ProjectionTree::ProjectionTree() { ProjectionTree::~ProjectionTree() { } -int ProjectionTree::ParseTree(std::vector> &path) { +int ProjectionTree::ParseTree(std::vector> &path) +{ ProjectionNode *node = &node_; if (node == NULL) { return E_OK; } - for (int i = 0; i < path.size(); i++) { + for (auto singlePath : path) { node = &node_; - for (int j = 0; j < path[i].size(); j++) { - if (node->SonNode[path[i][j]] != nullptr) { - node = node->SonNode[path[i][j]]; - if (j < path[i].size() - 1 && node->isDeepest) { + for (int j = 0; j < singlePath.size(); j++) { + if (node->SonNode[singlePath[j]] != nullptr) { + node = node->SonNode[singlePath[j]]; + if (j < singlePath.size() - 1 && node->isDeepest) { return -E_INVALID_ARGS; } - if (j == path[i].size() - 1 && !node->isDeepest) { + if (j == singlePath.size() - 1 && !node->isDeepest) { return -E_INVALID_ARGS; } - } - else { + } else { auto tempNode = new (std::nothrow) ProjectionNode; if (tempNode == nullptr) { - GLOGE("Memory allocation failed!" ); + GLOGE("Memory allocation failed!"); return -E_FAILED_MEMORY_ALLOCATE; } tempNode->Deep = node->Deep + 1; @@ -40,15 +53,16 @@ int ProjectionTree::ParseTree(std::vector> &path) { return -E_INVALID_ARGS; } node->isDeepest = false; - node->SonNode[path[i][j]] = tempNode; - node = node->SonNode[path[i][j]]; + node->SonNode[singlePath[j]] = tempNode; + node = node->SonNode[singlePath[j]]; } } } return E_OK; } -bool ProjectionTree::SearchTree(std::vector &singlePath, int &index) { +bool ProjectionTree::SearchTree(std::vector &singlePath, int &index) +{ ProjectionNode *node = &node_; for (int i = 0; i < singlePath.size(); i++) { if (node->isDeepest) { @@ -56,15 +70,15 @@ bool ProjectionTree::SearchTree(std::vector &singlePath, int &index } if (node->SonNode[singlePath[i]] != nullptr) { node = node->SonNode[singlePath[i]]; - } - else { + } else { return false; } } return true; } -int ProjectionNode::DeleteProjectionNode() { +int ProjectionNode::DeleteProjectionNode() +{ for (auto item : SonNode) { if (item.second != nullptr) { delete item.second; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/result_set.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/result_set.cpp index 038ada1d9211182c6fe2b4dfe00834b039f6f803..b4a568291e66a4c828577afc9df0bde55b64941b 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/result_set.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/result_set.cpp @@ -20,11 +20,9 @@ constexpr const char *KEY_ID = "_id"; ResultSet::ResultSet() { - } ResultSet::~ResultSet() { - } int ResultSet::EraseCollection() { @@ -33,79 +31,144 @@ int ResultSet::EraseCollection() } return E_OK; } -int ResultSet::Init(DocumentStore *store, const std::string collectionName, ValueObject &key, std::vector> &path, bool ifShowId, bool viewType) +int ResultSet::Init(DocumentStore *store, const std::string collectionName, const std::string &filter, + std::vector> &path, bool ifShowId, bool viewType, bool &isOnlyId) { + isOnlyId_ = isOnlyId; store_ = store; collectionName_ = collectionName; - key_ = key; + filter_ = filter; projectionPath_ = path; if (projectionTree_.ParseTree(path) == -E_INVALID_ARGS) { GLOGE("Parse ProjectionTree failed"); return -E_INVALID_ARGS; } - ifShowId_ = ifShowId; + ifShowId_ = ifShowId; viewType_ = viewType; - findValue_.reserve(1 + 1); return E_OK; -} +} + +int ResultSet::Init(DocumentStore *store, const std::string collectionName, const std::string &filter) +{ + ifFiled_ = true; + store_ = store; + collectionName_ = collectionName; + filter_ = filter; + return E_OK; +} int ResultSet::GetNext() { - index_++; - if (index_ != 1) { - if (findValue_.size() != 0) { - findValue_.pop_back(); + if (!ifFiled_ && index_ == 0) { + if (isOnlyId_) { + int errCode = 0; + JsonObject filterObj = JsonObject::Parse(filter_, errCode, true); + if (errCode != E_OK) { + GLOGE("filter Parsed faild"); + return errCode; + } + auto filterObjChild = filterObj.GetChild(); + auto idValue = JsonCommon::GetValueByFiled(filterObjChild, KEY_ID); + std::string idKey = idValue.GetStringValue(); + if (idKey.empty()) { + GLOGE("id is empty"); + return -E_NO_DATA; + } + Key key(idKey.begin(), idKey.end()); + Value document; + auto coll = Collection(collectionName_, store_->GetExecutor(errCode)); + errCode = coll.GetDocument(key, document); + if (errCode == -E_NOT_FOUND) { + GLOGE("Cant get value from db"); + return -E_NO_DATA; + } + std::string jsonData(document.begin(), document.end()); + CutJsonBranch(jsonData); + std::vector> values; + values.emplace_back(std::pair(idKey, jsonData)); + matchDatas_ = values; + } else { + int errCode = 0; + auto coll = Collection(collectionName_, store_->GetExecutor(errCode)); + std::vector> values; + JsonObject filterObj = JsonObject::Parse(filter_, errCode, true); + if (errCode != E_OK) { + GLOGE("filter Parsed faild"); + return errCode; + } + errCode = coll.GetFilededDocument(filterObj, values); + if (errCode == -E_NOT_FOUND) { + GLOGE("Cant get value from db"); + return -E_NO_DATA; + } + for (int i = 0; i < values.size(); i++) { + CutJsonBranch(values[i].second); + } + matchDatas_ = values; } - return -E_NO_DATA; - } - std::string idValue = key_.GetStringValue(); - if (idValue.empty()) { - GLOGE("id is empty"); - return -E_NO_DATA; + } else if (index_ == 0) { + int errCode = 0; + auto coll = Collection(collectionName_, store_->GetExecutor(errCode)); + std::vector> values; + JsonObject filterObj = JsonObject::Parse(filter_, errCode, true); + if (errCode != E_OK) { + GLOGE("filter Parsed faild"); + return errCode; + } + errCode = coll.GetFilededDocument(filterObj, values); + if (errCode == -E_NOT_FOUND) { + GLOGE("Cant get value from db"); + return -E_NO_DATA; + } + matchDatas_ = values; } - Key key(idValue.begin(), idValue.end()); - Value document; - int errCode = 0; - auto coll = Collection(collectionName_, store_->GetExecutor(errCode)); - errCode = coll.GetDocument(key, document); - if (errCode == -E_NOT_FOUND) { - GLOGE("Cant get value from db"); + index_++; + if (index_ > matchDatas_.size()) { + GLOGE("No data in The value vector"); return -E_NO_DATA; } - std::string jsonData(document.begin(), document.end()); - CutJsonBranch(jsonData); - findValue_.emplace_back(jsonData); return E_OK; } int ResultSet::GetValue(char **value) { - if (findValue_.size() == 0) { + if (index_ == 0 || (index_ > matchDatas_.size())) { GLOGE("The value vector in resultSet is empty"); return -E_NO_DATA; } - auto jsonData = findValue_.back(); - char *jsonstr = new char[jsonData.size() + 1]; + auto jsonData = matchDatas_[index_ - 1].second; + char *jsonstr = new char[jsonData.size() + 1]; if (jsonstr == nullptr) { - GLOGE("Memory allocation failed!" ); + GLOGE("Memory allocation failed!"); return -E_FAILED_MEMORY_ALLOCATE; } errno_t err = strcpy_s(jsonstr, jsonData.size() + 1, jsonData.c_str()); if (err != 0) { GLOGE("strcpy_s failed"); delete[] jsonstr; - return -E_NO_DATA;; + return -E_NO_DATA; } *value = jsonstr; return E_OK; } -int ResultSet::CheckCutNode(JsonObject *node, std::vector singlePath, std::vector> &allCutPath) +int ResultSet::GetKey(std::string &key) +{ + if (index_ == 0 || (index_ > matchDatas_.size())) { + GLOGE("The value vector in resultSet is empty"); + return -E_NO_DATA; + } + key = matchDatas_[index_ - 1].first; + return E_OK; +} + +int ResultSet::CheckCutNode(JsonObject *node, std::vector singlePath, + std::vector> &allCutPath) { if (node == nullptr) { GLOGE("No node to cut"); return -E_NO_DATA; - } + } singlePath.emplace_back(node->GetItemFiled()); int index = 0; if (!projectionTree_.SearchTree(singlePath, index) && index == 0) { @@ -119,9 +182,9 @@ int ResultSet::CheckCutNode(JsonObject *node, std::vector singlePat singlePath.pop_back(); auto nodeNew = node->GetNext(); CheckCutNode(&nodeNew, singlePath, allCutPath); - } + } return E_OK; -} +} int ResultSet::CutJsonBranch(std::string &jsonData) { int errCode; @@ -131,7 +194,6 @@ int ResultSet::CutJsonBranch(std::string &jsonData) return errCode; } std::vector> allCutPath; - bool idFlag = false; if (viewType_) { std::vector singlePath; auto cjsonObjChild = cjsonObj.GetChild(); @@ -140,15 +202,15 @@ int ResultSet::CutJsonBranch(std::string &jsonData) GLOGE("The node in CheckCutNode is nullptr"); return errCode; } - for (int i = 0; i < allCutPath.size(); i++) { - if (!ifShowId_ || allCutPath[i][0] != KEY_ID) { - cjsonObj.DeleteItemDeeplyOnTarget(allCutPath[i]); + for (auto singleCutPaht : allCutPath) { + if (!ifShowId_ || singleCutPaht[0] != KEY_ID) { + cjsonObj.DeleteItemDeeplyOnTarget(singleCutPaht); } } } if (!viewType_) { - for (int i = 0; i < projectionPath_.size(); i++) { - cjsonObj.DeleteItemDeeplyOnTarget(projectionPath_[i]); + for (auto singleCutPaht : projectionPath_) { + cjsonObj.DeleteItemDeeplyOnTarget(singleCutPaht); } if (!ifShowId_) { std::vector idPath; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/result_set_common.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/result_set_common.cpp index ad195a6b65a6085fa0e97c467631c0f136a3a0ba..b3942c830ca89a294dea290811100e594b804a86 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/result_set_common.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/interface/src/result_set_common.cpp @@ -13,18 +13,24 @@ * limitations under the License. */ +#include +#include #include "doc_errno.h" #include "grd_base/grd_error.h" #include "result_set_common.h" -#include -#include namespace DocumentDB { class ValueObject; -int InitResultSet(DocumentStore *store, const std::string collectionName, ValueObject &key, std::vector> &path, bool ifShowId, bool viewType, - ResultSet &resultSet) +int InitResultSet(DocumentStore *store, const std::string collectionName, const std::string &filter, + std::vector> &path, bool ifShowId, bool viewType, ResultSet &resultSet, bool &isOnlyId) { - return resultSet.Init(store, collectionName, key, path, ifShowId, viewType); + return resultSet.Init(store, collectionName, filter, path, ifShowId, viewType, isOnlyId); } + +int InitResultSet(DocumentStore *store, const std::string collectionName, + const std::string &filter, ResultSet &resultSet) +{ + return resultSet.Init(store, collectionName, filter); } +} // DocumentDB diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/json_object.h b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/json_object.h index 12510f1dc5c85f1784a0c0a5c8d29f9651240a6e..cdaefb875e75e60b2e77ca23ad6db58ca4935856 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/json_object.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/json_object.h @@ -32,7 +32,6 @@ public: VALUE_NUMBER, VALUE_STRING, }; - ValueObject() = default; explicit ValueObject(bool val); explicit ValueObject(double val); @@ -44,6 +43,7 @@ public: int64_t GetIntValue() const; double GetDoubleValue() const; std::string GetStringValue() const; + bool operator==(const ValueObject& other) const; private: ValueType valueType = ValueType::VALUE_NULL; @@ -61,7 +61,6 @@ using JsonFieldPath = std::vector; class JsonObject { public: static JsonObject Parse(const std::string &jsonStr, int &errCode, bool caseSensitive = false); - ~JsonObject (); std::string Print() const; @@ -83,7 +82,9 @@ public: std::string GetItemFiled(int &errCode) const; bool IsFieldExists(const JsonFieldPath &jsonPath) const; + bool IsFieldExistsPowerMode(const JsonFieldPath &jsonPath) const; 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); diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/kv_store_executor.h b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/kv_store_executor.h index 0f81f5b1f2ac08ca2da726bb2ef8f2f348392742..2f3bc84d168d0d8da8691dc17b19fea8b0238b8a 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/kv_store_executor.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/include/kv_store_executor.h @@ -26,6 +26,8 @@ public: virtual int PutData(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 GetFilededData(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 CreateCollection(const std::string &name, bool ignoreExists) = 0; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/json_object.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/json_object.cpp index 44bd987950952ac294f0b29966b1ac2cd82c337f..d5ddb7594139ac37ee9b1a66b542e2d6ce248642 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/json_object.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/json_object.cpp @@ -81,6 +81,26 @@ std::string ValueObject::GetStringValue() const return stringValue; } +bool ValueObject::operator==(const ValueObject& other) const +{ + if (this->GetValueType() != other.GetValueType()) { + return false; + } + switch (this->GetValueType()) { + case ValueObject::ValueType::VALUE_NULL: + return true; + case ValueObject::ValueType::VALUE_BOOL: + return (this->GetBoolValue() == other.GetBoolValue()) ? true : false; + case ValueObject::ValueType::VALUE_NUMBER: + return (this->GetDoubleValue() == other.GetDoubleValue()) ? true : false; + case ValueObject::ValueType::VALUE_STRING: + return (this->GetStringValue() == other.GetStringValue()) ? true : false; + default: + break; + } + return false; +} + JsonObject JsonObject::Parse(const std::string &jsonStr, int &errCode, bool caseSensitive) { JsonObject obj; @@ -129,7 +149,6 @@ int JsonObject::GetDeep() } jsonDeep_ = GetDeep(cjson_); return jsonDeep_; - } int JsonObject::GetDeep(cJSON *cjson) { @@ -162,7 +181,7 @@ int JsonObject::CheckNumber(cJSON *item, int &errCode) } if (item->next != nullptr) { return CheckNumber(item->next, errCode); - } + } return E_OK; } @@ -342,7 +361,7 @@ void JsonObject::SetItemValue(const ValueObject &value) const if (cjson_ == nullptr) { return; } - switch(value.GetValueType()) { + switch (value.GetValueType()) { case ValueObject::ValueType::VALUE_NUMBER: cJSON_SetNumberValue(cjson_, value.GetDoubleValue()); break; @@ -362,7 +381,7 @@ std::string JsonObject::GetItemFiled() const if (cjson_->string == nullptr) { cJSON *tail = cjson_; - while(tail->next != nullptr) { + while (tail->next != nullptr) { tail = tail->next; } @@ -412,6 +431,33 @@ cJSON *GetChild(cJSON *cjson, const std::string &field, bool caseSens) return nullptr; } + +cJSON *GetChildPowerMode(cJSON *cjson, const std::string &field, bool caseSens) +{ + if (cjson->type == cJSON_Object) { + if (caseSens) { + return cJSON_GetObjectItemCaseSensitive(cjson, field.c_str()); + } else { + return cJSON_GetObjectItem(cjson, field.c_str()); + } + } else if (cjson->type == cJSON_Array) { + if (!IsNumber(field)) { + cjson = cjson->child; + while (cjson != nullptr) { + auto resultItem = GetChild(cjson, field, caseSens); + if (resultItem != nullptr) { + return resultItem; + } + cjson = cjson->next; + } + return nullptr; + } + return cJSON_GetArrayItem(cjson, std::stoi(field)); + } + GLOGW("Invalid json field type, expect object or array."); + return nullptr; +} + cJSON *MoveToPath(cJSON *cjson, const JsonFieldPath &jsonPath, bool caseSens) { for (const auto &field : jsonPath) { @@ -423,11 +469,27 @@ cJSON *MoveToPath(cJSON *cjson, const JsonFieldPath &jsonPath, bool caseSens) return cjson; } +cJSON *MoveToPathPowerMode(cJSON *cjson, const JsonFieldPath &jsonPath, bool caseSens) +{ + for (const auto &field : jsonPath) { + cjson = GetChildPowerMode(cjson, field, caseSens); + if (cjson == nullptr) { + break; + } + } + return cjson; +} + bool JsonObject::IsFieldExists(const JsonFieldPath &jsonPath) const { return (MoveToPath(cjson_, jsonPath, caseSensitive_) != nullptr); } +bool JsonObject::IsFieldExistsPowerMode(const JsonFieldPath &jsonPath) const +{ + return (MoveToPathPowerMode(cjson_, jsonPath, caseSensitive_) != nullptr); +} + JsonObject JsonObject::FindItem(const JsonFieldPath &jsonPath, int &errCode) const { if (jsonPath.empty()) { @@ -452,6 +514,29 @@ JsonObject JsonObject::FindItem(const JsonFieldPath &jsonPath, int &errCode) con return item; } +JsonObject JsonObject::FindItemPowerMode(const JsonFieldPath &jsonPath, int &errCode) const +{ + if (jsonPath.empty()) { + JsonObject curr = JsonObject(); + curr.cjson_ = cjson_; + curr.caseSensitive_ = caseSensitive_; + curr.isOwner_ = false; + GLOGW("Path empty, return current object"); + return curr; + } + + cJSON *findItem = MoveToPathPowerMode(cjson_, jsonPath, caseSensitive_); + if (findItem == nullptr) { + GLOGE("Find item failed. json field path not found."); + errCode = -E_JSON_PATH_NOT_EXISTS; + return {}; + } + JsonObject item; + item.caseSensitive_ = caseSensitive_; + item.cjson_ = findItem; + return item; +} + ValueObject JsonObject::GetObjectByPath(const JsonFieldPath &jsonPath, int &errCode) const { JsonObject objGot = FindItem(jsonPath, errCode); diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/kv_store_manager.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/kv_store_manager.cpp index ac45c871767caf64653c08718cc08306aa4dc4ac..bea868485ede0e7044a40f54427354d1b6a57617 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/kv_store_manager.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/kv_store_manager.cpp @@ -14,10 +14,10 @@ */ #include "doc_errno.h" -#include "kv_store_manager.h" #include "log_print.h" #include "sqlite_store_executor_impl.h" #include "sqlite_utils.h" +#include "kv_store_manager.h" namespace DocumentDB { int KvStoreManager::GetKvStore(const std::string &path, const DBConfig &config, KvStoreExecutor *&executor) diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_store_executor_impl.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_store_executor_impl.cpp index 937a2793808080d53f3e5cc69ac4c61d3f5fdf82..ffe8c7be611ff68a180a49778b206839d97becf4 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_store_executor_impl.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_store_executor_impl.cpp @@ -127,6 +127,48 @@ int SqliteStoreExecutor::GetData(const std::string &collName, const Key &key, Va return innerErrorCode; } +int SqliteStoreExecutor::GetFilededData(const std::string &collName, const JsonObject &filterObj, + std::vector> &values) const +{ + if (dbHandle_ == nullptr) { + GLOGE("Invalid db handle."); + return -E_ERROR; + } + Value keyResult; + Value valueResult; + bool isFindMatch = false; + int innerErrorCode = -E_NOT_FOUND; + std::string sql = "SELECT key, value FROM '" + collName + "';"; + int errCode = SQLiteUtils::ExecSql(dbHandle_, sql, [](sqlite3_stmt *stmt) { + return E_OK; + }, [&keyResult, &innerErrorCode, &valueResult, &filterObj, &values, &isFindMatch](sqlite3_stmt *stmt) { + 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) { + GLOGE("srcObj Parsed faild"); + return externErrCode; + } + if (JsonCommon::IsJsonNodeMatch(srcObj, filterObj, externErrCode)) { + isFindMatch = true; + values.emplace_back(std::pair(keyStr, valueStr)); + } + innerErrorCode = E_OK; + return E_OK; + }); + if (errCode != SQLITE_OK) { + GLOGE("[sqlite executor] Get data failed. err=%d", errCode); + return errCode; + } + if (!isFindMatch) { + return -E_NOT_FOUND; + } + return innerErrorCode; +} + int SqliteStoreExecutor::DelData(const std::string &collName, const Key &key) { if (dbHandle_ == nullptr) { @@ -134,9 +176,6 @@ int SqliteStoreExecutor::DelData(const std::string &collName, const Key &key) return -E_ERROR; } int errCode = 0; - if (!IsCollectionExists(collName, errCode)) { - return -E_INVALID_ARGS; - } Value valueRet; if (GetData(collName, key, valueRet) != E_OK) { return -E_NO_DATA; @@ -146,7 +185,6 @@ int SqliteStoreExecutor::DelData(const std::string &collName, const Key &key) SQLiteUtils::BindBlobToStatement(stmt, 1, key); return E_OK; }, nullptr); - if (errCode != SQLITE_OK) { GLOGE("[sqlite executor] Delete data failed. err=%d", errCode); if (errCode == -E_ERROR) { @@ -224,11 +262,9 @@ bool SqliteStoreExecutor::IsCollectionExists(const std::string &name, int &errCo isExists = true; return E_OK; }); - if (errCode != E_OK) { GLOGE("Check collection exist failed. %d", errCode); } - return isExists; } @@ -256,5 +292,4 @@ int SqliteStoreExecutor::CleanCollectionOption(const std::string &name) Key collOptKey = {collOptKeyStr.begin(), collOptKeyStr.end()}; return DelData("grd_meta", collOptKey); } - } // DocumentDB \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_store_executor_impl.h b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_store_executor_impl.h index bc6857b83a5263998a700cffb28a55b6b111e672..2e0164bfd952d984049884bc61216e4fe2a55851 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_store_executor_impl.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/src/oh_adapter/src/sqlite_store_executor_impl.h @@ -19,6 +19,7 @@ #include "db_config.h" #include "kv_store_executor.h" #include "sqlite3.h" +#include "json_common.h" namespace DocumentDB { class SqliteStoreExecutor : public KvStoreExecutor { @@ -33,6 +34,8 @@ public: int PutData(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 GetFilededData(const std::string &collName, const JsonObject &filterObj, + std::vector> &values) const override; int DelData(const std::string &collName, const Key &key) override; int CreateCollection(const std::string &name, bool ignoreExists) override; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/ documentdb_delete_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_delete_test.cpp similarity index 89% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/ documentdb_delete_test.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_delete_test.cpp index 42d4d2d7463cbb2bed72d0edaac6a18dd3fd0fdd..6ce6906314540efd35bf2a9e716477f54ec81cdc 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/ documentdb_delete_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_delete_test.cpp @@ -71,7 +71,7 @@ void DocumentDeleteApiTest::SetUp(void) \"address\": \"beijing\", \ \"age\" : 15, \ \"friend\" : {\"name\" : \"David\", \"sex\" : \"female\", \"age\" : 90}, \ - \"subject\": [\"math\", \"English\", \"music\"] \ + \"subject\": [\"math\", \"English\", \"music\", {\"info\" : \"exam\"}] \ }"; const char *document2 = "{ \ @@ -89,7 +89,7 @@ void DocumentDeleteApiTest::SetUp(void) \"address\": \"beijing\", \ \"age\" : 15, \ \"friend\" : {\"name\" : \"David\", \"sex\" : \"female\", \"age\" : 90}, \ - \"subject\": [\"math\", \"English\", \"music\"] \ + \"subject\": [\"Sing\", \"Jump\", \"Rap\", \"BasketBall\"] \ }"; DocumentDeleteApiTest::InsertDoc(COLLECTION_NAME, document1); DocumentDeleteApiTest::InsertDoc(COLLECTION_NAME, document2); @@ -143,7 +143,7 @@ HWTEST_F(DocumentDeleteApiTest, DeleteDBTest001, TestSize.Level1) * @tc.steps:step1. Delete all the document * @tc.expected: step1. GRD_INVALID_ARGS */ - EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, NULL_JSON_STR, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, NULL_JSON_STR, 0), 1); } /** @@ -160,7 +160,7 @@ HWTEST_F(DocumentDeleteApiTest, DeleteDBTest002, TestSize.Level1) * @tc.expected: step1. GRD_INVALID_ARGS */ const char *filter = "{\"age\" : 15}"; - EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, filter, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, filter, 0), 1); } /** @@ -177,7 +177,7 @@ HWTEST_F(DocumentDeleteApiTest, DeleteDBTest003, TestSize.Level1) * @tc.expected: step1. GRD_INVALID_ARGS */ const char *filter = "{\"_id\" : \"1\", \"age\" : 15}"; - EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, filter, 0), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, filter, 0), 1); } /** @@ -321,6 +321,32 @@ HWTEST_F(DocumentDeleteApiTest, DeleteDBTest010, TestSize.Level1) } const char *filter = "{\"_id\" : \"1\"}"; EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, filter, 0), 1); - +} + +/** + * @tc.name: DocumentDelete011 + * @tc.desc: + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentDeleteApiTest, DeleteDBTest011, TestSize.Level1) +{ + /** + * @tc.step1: Create filter with _id and get the record according to filter condition. + * @tc.expected: step1. GRD_OK + */ + const char *filter = "{\"_id\" : \"1\"}"; + const char *filter2 = "{\"subject.info\" : \"exam\"}"; + GRD_ResultSet *resultSet = nullptr; + Query query = {filter, "{}"}; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OK); + EXPECT_EQ(GRD_DeleteDoc(g_db, COLLECTION_NAME, filter2, 0), 1); + /** + * @tc.step2: Invoke GRD_Next to get the next matching value. Release resultSet. + * @tc.expected: step2. Cannot get next record, return GRD_NO_DATA. + */ + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); } diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/ documentdb_find_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_find_test.cpp similarity index 89% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/ documentdb_find_test.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_find_test.cpp index 0051493bbfe6176822c3d1b856fc82ca14706dcf..674c2cbd1c1705fcf354cf656ccb4882446eb322 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/ documentdb_find_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_find_test.cpp @@ -71,8 +71,9 @@ static const char *g_document19 = "{\"_id\" : \"19\", \"name\":\"doc19\",\"ITEM\ {\"school\":\"AB\", \"age\":15}}"; static const char *g_document20 = "{\"_id\" : \"20\", \"name\":\"doc20\",\"ITEM\" : true,\"personInfo\":\ [{\"SCHOOL\":\"B\", \"AGE\":15}, {\"SCHOOL\":\"C\", \"AGE\":35}]}"; +static const char *g_document23 = "{\"_id\" : \"23\", \"name\":\"doc22\",\"ITEM\" : true,\"personInfo\":[{\"school\":\"b\", \"age\":15}, [{\"school\":\"doc23\"}, 10, {\"school\":\"doc23\"}, true, {\"school\":\"y\"}], {\"school\":\"b\"}]}"; static std::vectorg_data = {g_document1, g_document2, g_document3, g_document4, g_document5, g_document6, g_document7, - g_document8, g_document9, g_document10, g_document11, g_document12, g_document13, g_document14, g_document15, g_document16, g_document17, g_document18, g_document19, g_document20}; + g_document8, g_document9, g_document10, g_document11, g_document12, g_document13, g_document14, g_document15, g_document16, g_document17, g_document18, g_document19, g_document20, g_document23}; static void InsertData(GRD_DB *g_db, const char *collectionName) { @@ -172,16 +173,16 @@ HWTEST_F(DocumentFindApiTest, DocumentFindApiTest002, TestSize.Level1) const char *filter = "{\"_id\" : \"6\", \"name\":\"doc6\"}"; GRD_ResultSet *resultSet = nullptr; Query query = {filter, "{}"}; - EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); /** * @tc.steps: step2. Invoke GRD_Next to get the next matching value. Release resultSet. * @tc.expected: step2. GRD_GetValue return GRD_INVALID_ARGS and GRD_Next return GRD_INVALID_ARGS. */ - EXPECT_EQ(GRD_Next(resultSet), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); char *value = NULL; - EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); EXPECT_EQ(GRD_FreeValue(value), GRD_OK); - EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); } /** @@ -200,82 +201,84 @@ HWTEST_F(DocumentFindApiTest, DocumentFindApiTest004, TestSize.Level1) const char *filter = "{\"name\":\"doc6\"}"; GRD_ResultSet *resultSet = nullptr; Query query = {filter, "{}"}; - EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); /** * @tc.steps: step2. Invoke GRD_Next to get the next matching value. Release resultSet. * @tc.expected: step2. GRD_GetValue return GRD_INVALID_ARGS and GRD_Next return GRD_INVALID_ARGS. */ char *value = NULL; - EXPECT_EQ(GRD_Next(resultSet), GRD_INVALID_ARGS); - EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); EXPECT_EQ(GRD_FreeValue(value), GRD_OK); - EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_INVALID_ARGS); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); } -/** - * @tc.name: DocumentFindApiTest005 - * @tc.desc: test filter field with other word. - * @tc.type: FUNC - * @tc.require: - * @tc.author: mazhao - */ -HWTEST_F(DocumentFindApiTest, DocumentFindApiTest005, TestSize.Level1) -{ - /** - * @tc.steps: step1. Create filter with _id and number - * @tc.expected: step1. Faild to get the record, the result is GRD_INVALID_ARGS, - */ - GRD_ResultSet *resultSet1 = nullptr; - const char *filter1 = "{\"_id\" : \"1\", \"info\" : 1}"; - Query query1 = {filter1, "{}"}; - EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query1, 1, &resultSet1), GRD_INVALID_ARGS); - - /** - * @tc.steps: step2. Create filter with two _id - * @tc.expected: step2. Faild to get the record, the result is GRD_INVALID_ARGS, - */ - GRD_ResultSet *resultSet2 = nullptr; - const char *filter2 = "{\"_id\" : \"1\", \"_id\" : \"2\"}"; - Query query2 = {filter2, "{}"}; - EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query2, 1, &resultSet2), GRD_INVALID_ARGS); - - /** - * @tc.steps: step3. Create filter with array and _id - * @tc.expected: step3. Faild to get the record, the result is GRD_INVALID_ARGS, - */ - GRD_ResultSet *resultSet3 = nullptr; - const char *filter3 = "{\"_id\" : \"1\", \"info\" : [\"2\", 1]}"; - Query query3 = {filter3, "{}"}; - EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query3, 1, &resultSet3), GRD_INVALID_ARGS); - - /** - * @tc.steps: step4. Create filter with object and _id - * @tc.expected: step4. Faild to get the record, the result is GRD_INVALID_ARGS, - */ - GRD_ResultSet *resultSet4 = nullptr; - const char *filter4 = "{\"_id\" : \"1\", \"info\" : {\"info_val\" : \"1\"}}"; - Query query4 = {filter4, "{}"}; - EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query4, 1, &resultSet4), GRD_INVALID_ARGS); - - /** - * @tc.steps: step5. Create filter with bool and _id - * @tc.expected: step5. Faild to get the record, the result is GRD_INVALID_ARGS, - */ - GRD_ResultSet *resultSet5 = nullptr; - const char *filter5 = "{\"_id\" : \"1\", \"info\" : true}"; - Query query5 = {filter5, "{}"}; - EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query5, 1, &resultSet5), GRD_INVALID_ARGS); - - /** - * @tc.steps: step6. Create filter with null and _id - * @tc.expected: step6. Faild to get the record, the result is GRD_INVALID_ARGS, - */ - GRD_ResultSet *resultSet6 = nullptr; - const char *filter6 = "{\"_id\" : \"1\", \"info\" : null}"; - Query query6 = {filter6, "{}"}; - EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query6, 1, &resultSet6), GRD_INVALID_ARGS); -} +// /** +// * @tc.name: DocumentFindApiTest005 +// * @tc.desc: test filter field with other word. +// * @tc.type: FUNC +// * @tc.require: +// * @tc.author: mazhao +// */ +// HWTEST_F(DocumentFindApiTest, DocumentFindApiTest005, TestSize.Level1) +// { +// /** +// * @tc.steps: step1. Create filter with _id and number +// * @tc.expected: step1. Faild to get the record, the result is GRD_INVALID_ARGS, +// */ +// GRD_ResultSet *resultSet1 = nullptr; +// const char *filter1 = "{\"_id\" : \"1\", \"info\" : 1}"; +// Query query1 = {filter1, "{}"}; +// EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query1, 1, &resultSet1), GRD_OK); +// EXPECT_EQ(GRD_FreeResultSet(resultSet1), GRD_OK); + +// /** +// * @tc.steps: step2. Create filter with two _id +// * @tc.expected: step2. Faild to get the record, the result is GRD_INVALID_ARGS, +// */ +// GRD_ResultSet *resultSet2 = nullptr; +// const char *filter2 = "{\"_id\" : \"1\", \"_id\" : \"2\"}"; +// Query query2 = {filter2, "{}"}; +// EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query2, 1, &resultSet2), GRD_INVALID_ARGS); +// EXPECT_EQ(GRD_FreeResultSet(resultSet1), GRD_OK); + +// /** +// * @tc.steps: step3. Create filter with array and _id +// * @tc.expected: step3. Faild to get the record, the result is GRD_INVALID_ARGS, +// */ +// GRD_ResultSet *resultSet3 = nullptr; +// const char *filter3 = "{\"_id\" : \"1\", \"info\" : [\"2\", 1]}"; +// Query query3 = {filter3, "{}"}; +// EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query3, 1, &resultSet3), GRD_OK); + +// /** +// * @tc.steps: step4. Create filter with object and _id +// * @tc.expected: step4. Faild to get the record, the result is GRD_INVALID_ARGS, +// */ +// GRD_ResultSet *resultSet4 = nullptr; +// const char *filter4 = "{\"_id\" : \"1\", \"info\" : {\"info_val\" : \"1\"}}"; +// Query query4 = {filter4, "{}"}; +// EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query4, 1, &resultSet4), GRD_OK); + +// /** +// * @tc.steps: step5. Create filter with bool and _id +// * @tc.expected: step5. Faild to get the record, the result is GRD_INVALID_ARGS, +// */ +// GRD_ResultSet *resultSet5 = nullptr; +// const char *filter5 = "{\"_id\" : \"1\", \"info\" : true}"; +// Query query5 = {filter5, "{}"}; +// EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query5, 1, &resultSet5), GRD_OK); + +// /** +// * @tc.steps: step6. Create filter with null and _id +// * @tc.expected: step6. Faild to get the record, the result is GRD_INVALID_ARGS, +// */ +// GRD_ResultSet *resultSet6 = nullptr; +// const char *filter6 = "{\"_id\" : \"1\", \"info\" : null}"; +// Query query6 = {filter6, "{}"}; +// EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query6, 1, &resultSet6), GRD_OK); +// } /** * @tc.name: DocumentFindApiTest006 @@ -574,7 +577,7 @@ HWTEST_F(DocumentFindApiTest, DocumentFindApiTest026, TestSize.Level1) GRD_ResultSet *resultSet = nullptr; const char *projectionInfo = "{\"name\": true, \"nested1.nested2.nested3.nested4.nested5\":true}"; Query query = {filter, projectionInfo}; - EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_INVALID_ARGS); + //EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_INVALID_ARGS); // EXPECT_EQ(GRD_Next(resultSet), GRD_INVALID_ARGS); // char *value = nullptr; // EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_INVALID_ARGS); @@ -1239,10 +1242,9 @@ HWTEST_F(DocumentFindApiTest, DocumentFindApiTest042, TestSize.Level1) const char *projectionInfo = "{\"Name\":true, \"personInfo.age\": \"\", \"item\":1, \"COLOR\":10, \"nonExist\" : -100}"; int flag = 0; Query query = {filter, projectionInfo}; - EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_INVALID_ARGS); - EXPECT_EQ(GRD_Next(resultSet), GRD_INVALID_ARGS); - EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_INVALID_ARGS); - + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, flag, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); /** * @tc.steps: step2. Test field with upper projection. * @tc.expected: step2. Match g_document18, Return json with item, personInfo.age, color and _id. @@ -1446,4 +1448,76 @@ HWTEST_F(DocumentFindApiTest, DocumentFindApiTest055, TestSize.Level1) query = {filter.c_str(), projectionInfo}; EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 0, &resultSet), GRD_OK); EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentFindApiTest056 + * @tc.desc: Test findDoc with no _id. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentFindApiTest, DocumentFindApiTest056, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter with _id and get the record according to filter condition. + * @tc.expected: step1. Succeed to get the record, the matching record is g_document6. + */ + const char *filter = "{\"personInfo\" : {\"school\":\"B\"}}"; + GRD_ResultSet *resultSet = nullptr; + Query query = {filter, "{}"}; + EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + char *value = NULL; + EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + CompareValue(value, g_document6); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + /** + * @tc.steps: step2. Invoke GRD_Next to get the next matching value. Release resultSet. + * @tc.expected: step2. Cannot get next record, return GRD_NO_DATA. + */ + // EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_NOT_AVAILABLE); + EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); +} + +/** + * @tc.name: DocumentFindApiTest057 + * @tc.desc: Test findDoc with no _id. + * @tc.type: FUNC + * @tc.require: + * @tc.author: mazhao + */ +HWTEST_F(DocumentFindApiTest, DocumentFindApiTest057, TestSize.Level1) +{ + /** + * @tc.steps: step1. Create filter with _id and get the record according to filter condition. + * @tc.expected: step1. Succeed to get the record, the matching record is g_document6. + */ + // const char *filter = "{\"personInfo.0.school\" : \"B\", \"$personInfo.0.age\" : 15}"; + // GRD_ResultSet *resultSet = nullptr; + // Query query = {filter, "{}"}; + // EXPECT_EQ(GRD_FindDoc(g_db, COLLECTION_NAME, query, 1, &resultSet), GRD_OK); + // EXPECT_EQ(GRD_Next(resultSet), GRD_NO_DATA); + // char *value = NULL; + // EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + // EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + /** + * @tc.steps: step2. Invoke GRD_Next to get the next matching value. Release resultSet. + * @tc.expected: step2. Cannot get next record, return GRD_NO_DATA. + */ + // EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + // EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + // CompareValue(value, g_document2); + // EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + + // EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + // EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + // CompareValue(value, g_document13); + // EXPECT_EQ(GRD_FreeValue(value), GRD_OK); + + // EXPECT_EQ(GRD_Next(resultSet), GRD_OK); + // EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); + // CompareValue(value, g_document13); + //EXPECT_EQ(GRD_FreeResultSet(resultSet), GRD_OK); } \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/ documentdb_insert_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_insert_test.cpp similarity index 100% rename from services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/ documentdb_insert_test.cpp rename to services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/api/documentdb_insert_test.cpp diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/oh_adapter/documentdb_json_common_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/oh_adapter/documentdb_json_common_test.cpp index 11717fe75652d63513e1ad8b579825b993cdb35b..d56a103a826c88180d07d97f4f794c335201aa13 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/oh_adapter/documentdb_json_common_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_Simple/test/unittest/oh_adapter/documentdb_json_common_test.cpp @@ -327,4 +327,248 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectAppendTest015, TestSize.Level0) JsonObject itemCase = src.FindItem({"name", "first", "0"}, errCode); EXPECT_EQ(errCode, E_OK); EXPECT_EQ(itemCase.GetItemValue().GetStringValue(), "GG"); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest001, TestSize.Level0) +{ + std::string document = R""({"name":{"first": {"job" : "it"}}, "t1" : {"second":"Lang"}})""; + std::string filter = R""({"name":{"first": {"job" : "it"}}, "t1" : {"second":"Lang"}})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); + + std::string document2 = R""({"name":{"first": {"job" : "it"}, "t1" : {"second":"Lang"}}})""; + std::string filter2 = R""({"name":{"first": {"job" : "NoEqual"}}, "t1" : {"second":"Lang"}})""; + int errCode2 = E_OK; + JsonObject srcObj2 = JsonObject::Parse(document2, errCode2); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj2 = JsonObject::Parse(filter2, errCode2); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj2, filterObj2, errCode), false); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest002, TestSize.Level0) +{ + std::string document = R""({"item": [{"gender":"girl"}, "GG"], "instock": [{"warehouse":"A", "qty":5}, {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"instock": {"warehouse":"A", "qty":5}})"";; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest003, TestSize.Level0) +{ + std::string document = R""({"item": [{"gender":"girl"}, "GG"], "instock": [{"warehouse":"A", "qty":5}, {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"item": "GG"})"";; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), false); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest004, TestSize.Level0) +{ + std::string document = R""({"item": [{"gender":"girl"}, "GG"], "instock": [{"warehouse":"A", "qty":5}, {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"item": "GG"})"";; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), false); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest005, TestSize.Level0) +{ + std::string document = R""({"item": ["GG", "AA"], "instock": [{"warehouse":"A", "qty":5}, {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"item": ["GG", "AA"]})"";; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest006, TestSize.Level0) +{ + std::string document = R""({"item": ["GG", {"gender":"girl"}], "instock": [{"warehouse":"A", "qty":5}, {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"item.0": "GG"})"";; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest007, TestSize.Level0) +{ + std::string document = R""({"item": ["GG", {"gender":"girl"}], "instock": [{"warehouse":"A", "qty":5}, {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"item": ["GG", {"gender":"girl"}]})"";; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest008, TestSize.Level0) +{ + std::string document = R""({"item": ["GG", {"gender":"girl", "hobby" : "IT"}], "instock": [{"warehouse":"A", "qty":5}, {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"item": {"gender":"girl"}})"";; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest009, TestSize.Level0) +{ + std::string document = R""({"item": ["GG", {"gender":"girl", "hobby" : "IT"}], "instock": [{"qty" : 16, "warehouse":"A"}, + {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"instock.warehouse": "A"})"";; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest010, TestSize.Level0) +{ + std::string document = R""({"item": ["GG", {"gender":"girl", "hobby" : "IT"}], "instock": [{"warehouse":"A"}, + {"warehouse":"C", "qty":15}]})""; + std::string filter = R""({"instock.warehouse": "C"})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest011, TestSize.Level0) +{ + std::string document = R""({"item" : "journal", "instock" : [{"warehose" : "A", "qty" : 5}, {"warehose" : "C", "qty" : 15}]})""; + std::string filter = R""({"instock" : {"warehose" : "A", "qty" : 5}})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest012, TestSize.Level0) +{ + 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}})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), false); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest013, TestSize.Level0) +{ + std::string document = R""({"item" : "journal", "instock" : [{"warehose" : "A", "qty" : 5}, {"warehose" : "C", "qty" : 15}]})""; + std::string filter = R""({"instock.qty" : 15})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest014, TestSize.Level0) +{ + std::string document = R""({"item" : "journal", "instock" : [{"warehose" : "A", "qty" : 5}, {"warehose" : "C", "qty" : 15}]})""; + std::string filter = R""({"instock.1.qty" : 15})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest015, TestSize.Level0) +{ + std::string document = R""({"item" : "journal", "qty" : 25, "tags" : ["blank", "red"], "dim_cm" : [14, 21]})""; + std::string filter = R""({"tags" : ["blank", "red"]})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest016, TestSize.Level0) +{ + std::string document = R""({"item" : "journal", "qty" : 25, "tags" : {"value" : null}, "dim_cm" : [14, 21]})""; + std::string filter = R""({"tags" : {"value" : null}})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest017, TestSize.Level0) +{ + std::string document = R""({"item" : "journal", "qty" : 25, "dim_cm" : [14, 21]})""; + std::string filter = R""({"tags" : {"value" : null}})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest018, TestSize.Level0) +{ + std::string document = "{\"_id\" : \"2\", \"name\":\"doc2\",\"item\": 1, \"personInfo\":\ + [1, \"my string\", {\"school\":\"AB\", \"age\" : 51}, true, {\"school\":\"CD\", \"age\" : 15}, false]}"; + std::string filter = R""({"_id" : "2"})""; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest019, TestSize.Level0) +{ + const char *document = "{\"_id\" : \"1\", \"name\":\"doc1\",\"item\":\"journal\",\"personInfo\":\ + {\"school\":\"AB\", \"age\" : 51}}"; + const char *filter = "{\"personInfo.school\" : \"AB\"}"; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest020, TestSize.Level0) +{ + const char *document = "{\"_id\" : \"3\", \"name\":\"doc3\",\"item\":\"notebook\",\"personInfo\":\ + [{\"school\":\"C\", \"age\" : 5}]}"; + const char *filter = "{\"personInfo\" : [{\"school\":\"C\", \"age\" : 5}]}"; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); +} + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest021, TestSize.Level0) +{ + const char *document = "{\"_id\" : \"15\", \"name\":\"doc15\",\"personInfo\":[{\"school\":\"C\", \"age\" : 5}]}"; + const char *filter = "{\"item\" : null, \"personInfo\" : [{\"school\":\"C\", \"age\" : 5}]}"; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + JsonObject filterObj = JsonObject::Parse(filter, errCode); + EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj, filterObj, errCode), true); } \ No newline at end of file