diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h new file mode 100644 index 0000000000000000000000000000000000000000..69c95c0e637b47f378efc0881e47d639defda979 --- /dev/null +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/include/document_type.h @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2023 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef DOCUMENT_TYPE_H +#define DOCUMENT_TYPE_H + +#include + +#include "projection_tree.h" + +namespace DocumentDB { +struct QueryContext { + std::string collectionName; + std::string filter; + std::vector> path; + ProjectionTree projectionTree; + bool ifShowId = false; + bool viewType = false; + bool isOnlyId = false; +}; +} // namespace DocumentDB +#endif // DOCUMENT_TYPE_H \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp index e63cfbfffcfa0b77d4ca74a99f3abcb0cb2c365d..692fb750e271f4aa9f13b6adc4604256f61aa4b2 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/common/src/json_common.cpp @@ -236,9 +236,6 @@ std::vector> JsonCommon::ParsePath(const JsonObject &ro { std::vector> resultPath; JsonObject projectionJson = root.GetChild(); - if (projectionJson.IsNull()) { - GLOGE("projectionJson is null"); - } std::vector singlePath; errCode = ParseNode(projectionJson, singlePath, resultPath, true); return resultPath; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h index de0ce2d8b14cdf660be6dddd24c2c7ce02b120c0..cf25d6144c737b120f722892c3ef466447efac1e 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/document_store.h @@ -21,6 +21,7 @@ #include #include "collection.h" +#include "document_type.h" #include "kv_store_executor.h" struct GRD_ResultSet; @@ -49,9 +50,9 @@ public: Collection GetCollection(std::string &collectionName); - bool IsCollectionOpening(const std::string collection); + bool IsCollectionOpening(const std::string &collection); - int EraseCollection(const std::string collectionName); + int EraseCollection(const std::string &collectionName); void OnClose(const std::function ¬ifier); @@ -66,7 +67,15 @@ public: std::mutex dbMutex_; private: - int GetViewType(JsonObject &jsonObj, bool &viewType); + int UpdateDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, const std::string &update, + bool &isReplace); + int UpsertDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, JsonObject &documentObj, + bool &isReplace); + int InsertDataIntoDB(const std::string &collection, const std::string &document, JsonObject &documentObj); + int DeleteDataFromDB(std::shared_ptr &context, JsonObject &filterObj); + int InitFindResultSet(GRD_ResultSet *grdResultSet, std::shared_ptr &context); + int CheckUpsertConflict(bool &isIdExist, std::shared_ptr &context, JsonObject &filterObj, + std::string &docId, Collection &coll); KvStoreExecutor *executor_ = nullptr; std::map collections_; std::function closeNotifier_; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h index ea1bcf42589521a15d4fcd6e963578e360ce56c2..aa2cbb322b8eaeb0cad2eadda202a67b2ac2584c 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set.h @@ -24,17 +24,13 @@ #include "document_store.h" #include "grd_base/grd_type_export.h" #include "json_object.h" -#include "projection_tree.h" namespace DocumentDB { class ResultSet { public: ResultSet(); ~ResultSet(); - - 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 Init(std::shared_ptr &context, DocumentStore *store, bool ifField); int GetNext(bool isNeedTransaction = false, bool isNeedCheckTable = false); int GetValue(char **value); int GetKey(std::string &key); @@ -48,16 +44,10 @@ private: int GetNextWithField(); DocumentStore *store_ = nullptr; - std::string collectionName_; ValueObject key_; - std::string filter_; - bool ifShowId_ = false; - bool viewType_ = false; bool ifField_ = false; - bool isOnlyId_ = false; - ProjectionTree projectionTree_; - std::vector> projectionPath_; size_t index_ = 0; + std::shared_ptr context_; std::vector> matchDatas_; }; } // namespace DocumentDB diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h index fa2c17c70513edece0397bd51d972624f4387cb9..0a59f9ffd8ad2962189db64cc468f5d44a0ad85d 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/include/result_set_common.h @@ -25,9 +25,6 @@ namespace DocumentDB { class ValueObject; -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); +int InitResultSet(std::shared_ptr &context, DocumentStore *store, ResultSet &resultSet, bool ifField); } // namespace DocumentDB #endif // RESULTSET_COMMON_H diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp index cf29ac15ed53e1bb3ad86ea237cc810ac32e091d..d6fe293577da390324cf84204e021b64fae8516c 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/document_store.cpp @@ -21,6 +21,7 @@ #include "grd_base/grd_type_export.h" #include "grd_resultset_inner.h" #include "log_print.h" +#include "result_set.h" #include "result_set_common.h" namespace DocumentDB { @@ -127,8 +128,18 @@ END: return errCode; } -int DocumentStore::UpdateDocument(const std::string &collection, const std::string &filter, const std::string &update, - uint32_t flags) +int TranFilter(JsonObject &filterObj, std::vector> &filterAllPath, bool &isOnlyId) +{ + int errCode = E_OK; + filterAllPath = JsonCommon::ParsePath(filterObj, errCode); + if (errCode != E_OK) { + GLOGE("filter ParsePath failed"); + return errCode; + } + return CheckCommon::CheckFilter(filterObj, isOnlyId, filterAllPath); +} + +int UpdateArgsCheck(const std::string &collection, const std::string &filter, const std::string &update, uint32_t flags) { std::string lowerCaseCollName; int errCode = E_OK; @@ -162,41 +173,31 @@ int DocumentStore::UpdateDocument(const std::string &collection, const std::stri GLOGE("Check flags invalid."); return -E_INVALID_ARGS; } - JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); - if (errCode != E_OK) { - GLOGE("filter Parsed failed"); - return errCode; - } - std::vector> filterAllPath; - filterAllPath = JsonCommon::ParsePath(filterObj, errCode); - if (errCode != E_OK) { - GLOGE("filter ParsePath failed"); - return errCode; - } - bool isOnlyId = true; - errCode = CheckCommon::CheckFilter(filterObj, isOnlyId, filterAllPath); - if (errCode != E_OK) { - return errCode; - } - bool isReplace = ((flags & GRD_DOC_REPLACE) == GRD_DOC_REPLACE); + return errCode; +} + +int DocumentStore::UpdateDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, + const std::string &update, bool &isReplace) +{ std::lock_guard lock(dbMutex_); if (executor_ == nullptr) { return -E_INNER_ERROR; } - errCode = executor_->StartTransaction(); + int errCode = executor_->StartTransaction(); if (errCode != E_OK) { return errCode; } std::string docId; int count = 0; - auto coll = Collection(collection, executor_); - if (isOnlyId) { + auto coll = Collection(context->collectionName, executor_); + if (context->isOnlyId) { auto filterObjChild = filterObj.GetChild(); auto idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID); docId = idValue.GetStringValue(); } else { ResultSet resultSet; - InitResultSet(this, collection, filter, resultSet); + std::string filter = filterObj.Print(); + InitResultSet(context, this, resultSet, true); // no start transaction inner errCode = resultSet.GetNext(false, true); if (errCode == -E_NO_DATA) { @@ -223,8 +224,34 @@ END: return (errCode == E_OK) ? count : errCode; } -int DocumentStore::UpsertDocument(const std::string &collection, const std::string &filter, - const std::string &document, uint32_t flags) +int DocumentStore::UpdateDocument(const std::string &collection, const std::string &filter, const std::string &update, + uint32_t flags) +{ + int errCode = UpdateArgsCheck(collection, filter, update, flags); + if (errCode != E_OK) { + return errCode; + } + JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); + if (errCode != E_OK) { + GLOGE("filter Parsed failed"); + return errCode; + } + bool isOnlyId = true; + std::vector> filterAllPath; + errCode = TranFilter(filterObj, filterAllPath, isOnlyId); + if (errCode != E_OK) { + return errCode; + } + bool isReplace = ((flags & GRD_DOC_REPLACE) == GRD_DOC_REPLACE); + std::shared_ptr context = std::make_shared(); + context->collectionName = collection; + context->isOnlyId = isOnlyId; + context->filter = filter; + return UpdateDataIntoDB(context, filterObj, update, isReplace); +} + +int UpsertArgsCheck(const std::string &collection, const std::string &filter, const std::string &document, + uint32_t flags) { std::string lowerCaseCollName; int errCode = E_OK; @@ -236,87 +263,65 @@ int DocumentStore::UpsertDocument(const std::string &collection, const std::stri GLOGE("args length is too long"); return -E_OVER_LIMIT; } - JsonObject documentObj = JsonObject::Parse(document, errCode, true); - if (errCode != E_OK) { - GLOGE("document Parsed failed"); - return errCode; - } - std::vector> allPath; - if (document != "{}") { - allPath = JsonCommon::ParsePath(documentObj, errCode); - if (errCode != E_OK) { - return errCode; - } - errCode = CheckCommon::CheckUpdata(documentObj, allPath); - if (errCode != E_OK) { - GLOGE("UpsertDocument document format is illegal"); - return errCode; - } - } if (flags != GRD_DOC_APPEND && flags != GRD_DOC_REPLACE) { GLOGE("Check flags invalid."); return -E_INVALID_ARGS; } - JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); - if (errCode != E_OK) { - GLOGE("filter Parsed failed"); - return errCode; - } - std::vector> filterAllPath; - filterAllPath = JsonCommon::ParsePath(filterObj, errCode); - if (errCode != E_OK) { - return errCode; + return errCode; +} + +int DocumentStore::CheckUpsertConflict(bool &isIdExist, std::shared_ptr &context, JsonObject &filterObj, + std::string &docId, Collection &coll) +{ + ResultSet resultSet; + InitResultSet(context, this, resultSet, true); + int errCode = resultSet.GetNext(false, true); + bool isfilterMatch = false; + if (errCode == E_OK) { + isfilterMatch = true; } - bool isOnlyId = true; - bool isReplace = ((flags & GRD_DOC_REPLACE) == GRD_DOC_REPLACE); - errCode = CheckCommon::CheckFilter(filterObj, isOnlyId, filterAllPath); - if (errCode != E_OK) { - return errCode; + Value ValueDocument; + Key key(docId.begin(), docId.end()); + errCode = coll.GetDocument(key, ValueDocument); + if (errCode == E_OK && !(isfilterMatch)) { + GLOGE("id exist but filter does not match, data conflict"); + errCode = -E_DATA_CONFLICT; } + return errCode; +} + +int DocumentStore::UpsertDataIntoDB(std::shared_ptr &context, JsonObject &filterObj, + JsonObject &documentObj, bool &isReplace) +{ std::lock_guard lock(dbMutex_); if (executor_ == nullptr) { return -E_INNER_ERROR; } - errCode = executor_->StartTransaction(); + int errCode = executor_->StartTransaction(); if (errCode != E_OK) { return errCode; } - Collection coll = Collection(collection, executor_); + Collection coll = Collection(context->collectionName, executor_); int count = 0; std::string targetDocument; std::string docId; - if (isOnlyId) { - auto filterObjChild = filterObj.GetChild(); - ValueObject idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID); - docId = idValue.GetStringValue(); - JsonObject idObj = filterObj.GetObjectItem(KEY_ID, errCode); - documentObj.InsertItemObject(0, idObj); - targetDocument = documentObj.Print(); - } else { - bool isIdExist; - auto filterObjChild = filterObj.GetChild(); - ValueObject idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID, isIdExist); - if (!isIdExist) { - errCode = -E_INVALID_ARGS; - goto END; - } - ResultSet resultSet; - InitResultSet(this, collection, filter, resultSet); - errCode = resultSet.GetNext(false, true); - bool isfilterMatch = false; - if (errCode == E_OK) { - isfilterMatch = true; - } - docId = idValue.GetStringValue(); - JsonObject idObj = filterObj.GetObjectItem(KEY_ID, errCode); - documentObj.InsertItemObject(0, idObj); - targetDocument = documentObj.Print(); - Value ValueDocument; - Key key(docId.begin(), docId.end()); - errCode = coll.GetDocument(key, ValueDocument); - if (errCode == E_OK && !(isfilterMatch)) { - GLOGE("id exist but filter does not match, data conflict"); - errCode = -E_DATA_CONFLICT; + bool isIdExist; + auto filterObjChild = filterObj.GetChild(); + ValueObject idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID, isIdExist); + docId = idValue.GetStringValue(); + JsonObject idObj = filterObj.GetObjectItem(KEY_ID, errCode); + documentObj.InsertItemObject(0, idObj); + targetDocument = documentObj.Print(); + if (!isIdExist) { + errCode = -E_INVALID_ARGS; + goto END; + } + if (!context->isOnlyId) { + errCode = CheckUpsertConflict(isIdExist, context, filterObj, docId, coll); + // There are only three return values, E_ OK and - E_ NO_DATA is a normal scenario, + // and that situation can continue to move forward + if (errCode == -E_DATA_CONFLICT) { + GLOGE("upsert data conflict"); goto END; } } @@ -335,7 +340,61 @@ END: return (errCode == E_OK) ? count : errCode; } -int DocumentStore::InsertDocument(const std::string &collection, const std::string &document, uint32_t flags) +int UpsertDocumentFormatCheck(const std::string &document, JsonObject &documentObj) +{ + int errCode = E_OK; + std::vector> allPath; + if (document != "{}") { + allPath = JsonCommon::ParsePath(documentObj, errCode); + if (errCode != E_OK) { + return errCode; + } + errCode = CheckCommon::CheckUpdata(documentObj, allPath); + if (errCode != E_OK) { + GLOGE("UpsertDocument document format is illegal"); + return errCode; + } + } + return errCode; +} +int DocumentStore::UpsertDocument(const std::string &collection, const std::string &filter, + const std::string &document, uint32_t flags) +{ + int errCode = UpsertArgsCheck(collection, filter, document, flags); + if (errCode != E_OK) { + return errCode; + } + JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); + if (errCode != E_OK) { + GLOGE("filter Parsed failed"); + return errCode; + } + JsonObject documentObj = JsonObject::Parse(document, errCode, true); + if (errCode != E_OK) { + GLOGE("document Parsed failed"); + return errCode; + } + errCode = UpsertDocumentFormatCheck(document, documentObj); + if (errCode != E_OK) { + GLOGE("document format is illegal"); + return errCode; + } + bool isOnlyId = true; + std::vector> filterAllPath; + errCode = TranFilter(filterObj, filterAllPath, isOnlyId); + if (errCode != E_OK) { + GLOGE("filter is invalid"); + return errCode; + } + std::shared_ptr context = std::make_shared(); + context->filter = filter; + context->isOnlyId = isOnlyId; + context->collectionName = collection; + bool isReplace = ((flags & GRD_DOC_REPLACE) == GRD_DOC_REPLACE); + return UpsertDataIntoDB(context, filterObj, documentObj, isReplace); +} + +int InsertArgsCheck(const std::string &collection, const std::string &document, uint32_t flags) { if (flags != 0u) { GLOGE("InsertDocument flags is not zero"); @@ -351,6 +410,27 @@ int DocumentStore::InsertDocument(const std::string &collection, const std::stri GLOGE("document's length is too long"); return -E_OVER_LIMIT; } + return errCode; +} + +int DocumentStore::InsertDataIntoDB(const std::string &collection, const std::string &document, JsonObject &documentObj) +{ + std::lock_guard lock(dbMutex_); + JsonObject documentObjChild = documentObj.GetChild(); + ValueObject idValue = JsonCommon::GetValueInSameLevel(documentObjChild, KEY_ID); + std::string id = idValue.GetStringValue(); + Key key(id.begin(), id.end()); + Value value(document.begin(), document.end()); + Collection coll = Collection(collection, executor_); + return coll.InsertDocument(key, value); +} + +int DocumentStore::InsertDocument(const std::string &collection, const std::string &document, uint32_t flags) +{ + int errCode = InsertArgsCheck(collection, document, flags); + if (errCode != E_OK) { + return errCode; + } JsonObject documentObj = JsonObject::Parse(document, errCode, true); if (errCode != E_OK) { GLOGE("Document Parsed failed"); @@ -360,17 +440,10 @@ int DocumentStore::InsertDocument(const std::string &collection, const std::stri if (errCode != E_OK) { return errCode; } - JsonObject documentObjChild = documentObj.GetChild(); - ValueObject idValue = JsonCommon::GetValueInSameLevel(documentObjChild, KEY_ID); - std::string id = idValue.GetStringValue(); - Key key(id.begin(), id.end()); - Value value(document.begin(), document.end()); - std::lock_guard lock(dbMutex_); - Collection coll = Collection(collection, executor_); - return coll.InsertDocument(key, value); + return InsertDataIntoDB(collection, document, documentObj); } -int DocumentStore::DeleteDocument(const std::string &collection, const std::string &filter, uint32_t flags) +int DeleteArgsCheck(const std::string &collection, const std::string &filter, uint32_t flags) { if (flags != 0u) { GLOGE("DeleteDocument flags is not zero"); @@ -390,38 +463,28 @@ int DocumentStore::DeleteDocument(const std::string &collection, const std::stri GLOGE("filter's length is too long"); return -E_OVER_LIMIT; } - JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); - if (errCode != E_OK) { - GLOGE("filter Parsed failed"); - return errCode; - } - std::vector> filterAllPath; - filterAllPath = JsonCommon::ParsePath(filterObj, errCode); - if (errCode != E_OK) { - return errCode; - } - bool isOnlyId = true; - errCode = CheckCommon::CheckFilter(filterObj, isOnlyId, filterAllPath); - if (errCode != E_OK) { - return errCode; - } + return errCode; +} + +int DocumentStore::DeleteDataFromDB(std::shared_ptr &context, JsonObject &filterObj) +{ std::lock_guard lock(dbMutex_); if (executor_ == nullptr) { return -E_INNER_ERROR; } - Collection coll = Collection(collection, executor_); - errCode = executor_->StartTransaction(); + Collection coll = Collection(context->collectionName, executor_); + int errCode = executor_->StartTransaction(); if (errCode != E_OK) { return errCode; } std::string id; - if (isOnlyId) { + if (context->isOnlyId) { auto filterObjChild = filterObj.GetChild(); auto idValue = JsonCommon::GetValueInSameLevel(filterObjChild, KEY_ID); id = idValue.GetStringValue(); } else { ResultSet resultSet; - InitResultSet(this, collection, filter, resultSet); + InitResultSet(context, this, resultSet, true); errCode = resultSet.GetNext(false, true); if (errCode != E_OK) { goto END; @@ -440,13 +503,96 @@ END: } return errCode; } +int DocumentStore::DeleteDocument(const std::string &collection, const std::string &filter, uint32_t flags) +{ + int errCode = DeleteArgsCheck(collection, filter, flags); + if (errCode != E_OK) { + return errCode; + } + JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); + if (errCode != E_OK) { + return errCode; + } + bool isOnlyId = true; + std::vector> filterAllPath; + errCode = TranFilter(filterObj, filterAllPath, isOnlyId); + if (errCode != E_OK) { + return errCode; + } + std::shared_ptr context = std::make_shared(); + context->filter = filter; + context->collectionName = collection; + context->isOnlyId = isOnlyId; + return DeleteDataFromDB(context, filterObj); +} Collection DocumentStore::GetCollection(std::string &collectionName) { return Collection(collectionName, executor_); } -int DocumentStore::FindDocument(const std::string &collection, const std::string &filter, - const std::string &projection, uint32_t flags, GRD_ResultSet *grdResultSet) +int JudgeViewType(size_t &index, ValueObject &leafItem, bool &viewType) +{ + switch (leafItem.GetValueType()) { + case ValueObject::ValueType::VALUE_BOOL: + if (leafItem.GetBoolValue()) { + if (index != 0 && !viewType) { + return -E_INVALID_ARGS; + } + viewType = true; + } else { + if (index != 0 && viewType) { + return E_INVALID_ARGS; + } + viewType = false; + } + break; + case ValueObject::ValueType::VALUE_STRING: + if (leafItem.GetStringValue() == "") { + if (index != 0 && !viewType) { + return -E_INVALID_ARGS; + } + viewType = true; + } else { + return -E_INVALID_ARGS; + } + break; + case ValueObject::ValueType::VALUE_NUMBER: + if (leafItem.GetIntValue() == 0) { + if (index != 0 && viewType) { + return -E_INVALID_ARGS; + } + viewType = false; + } else { + if (index != 0 && !viewType) { + return E_INVALID_ARGS; + } + viewType = true; + } + break; + default: + return E_INVALID_ARGS; + } + return E_OK; +} + +int GetViewType(JsonObject &jsonObj, bool &viewType) +{ + std::vector leafValue = JsonCommon::GetLeafValue(jsonObj); + if (leafValue.size() == 0) { + return E_INVALID_ARGS; + } + int ret = E_OK; + for (size_t i = 0; i < leafValue.size(); i++) { + ret = JudgeViewType(i, leafValue[i], viewType); + if (ret != E_OK) { + return ret; + } + } + return ret; +} + +int FindArgsCheck(const std::string &collection, const std::string &filter, const std::string &projection, + uint32_t flags) { if (flags != 0u && flags != GRD_DOC_ID_DISPLAY) { GLOGE("FindDocument flags is illegal"); @@ -462,32 +608,23 @@ int DocumentStore::FindDocument(const std::string &collection, const std::string GLOGE("args length is too long"); return -E_OVER_LIMIT; } - JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); - if (errCode != E_OK) { - GLOGE("filter Parsed failed"); - return errCode; - } - std::vector> filterAllPath; - filterAllPath = JsonCommon::ParsePath(filterObj, errCode); - if (errCode != E_OK) { - return errCode; - } - bool isOnlyId = true; - errCode = CheckCommon::CheckFilter(filterObj, isOnlyId, filterAllPath); - if (errCode != E_OK) { - return errCode; - } if (projection.length() >= JSON_LENS_MAX) { GLOGE("projection's length is too long"); return -E_OVER_LIMIT; } + return errCode; +} + +int FindProjectionInit(const std::string &projection, std::shared_ptr &context) +{ + int errCode = E_OK; + std::vector> allPath; JsonObject projectionObj = JsonObject::Parse(projection, errCode, true); if (errCode != E_OK) { GLOGE("projection Parsed failed"); return errCode; } bool viewType = false; - std::vector> allPath; if (projection != "{}") { allPath = JsonCommon::ParsePath(projectionObj, errCode); if (errCode != E_OK) { @@ -503,13 +640,17 @@ int DocumentStore::FindDocument(const std::string &collection, const std::string return errCode; } } - bool ifShowId = false; - if (flags == GRD_DOC_ID_DISPLAY) { - ifShowId = true; - } + context->path = std::move(allPath); + context->viewType = viewType; + return errCode; +} + +int DocumentStore::InitFindResultSet(GRD_ResultSet *grdResultSet, std::shared_ptr &context) +{ std::lock_guard lock(dbMutex_); - Collection coll = Collection(collection, executor_); - if (IsCollectionOpening(collection)) { + int errCode = E_OK; + Collection coll = Collection(context->collectionName, executor_); + if (IsCollectionOpening(context->collectionName)) { return -E_RESOURCE_BUSY; } if (executor_ == nullptr) { @@ -526,9 +667,9 @@ int DocumentStore::FindDocument(const std::string &collection, const std::string if (errCode != E_OK) { goto END; } - errCode = InitResultSet(this, collection, filter, allPath, ifShowId, viewType, grdResultSet->resultSet_, isOnlyId); + errCode = InitResultSet(context, this, grdResultSet->resultSet_, false); if (errCode == E_OK) { - collections_[collection] = nullptr; + collections_[context->collectionName] = nullptr; } END: if (errCode == E_OK) { @@ -539,7 +680,44 @@ END: return errCode; } -bool DocumentStore::IsCollectionOpening(const std::string collection) +int DocumentStore::FindDocument(const std::string &collection, const std::string &filter, + const std::string &projection, uint32_t flags, GRD_ResultSet *grdResultSet) +{ + std::shared_ptr context = std::make_shared(); + int errCode = E_OK; + errCode = FindArgsCheck(collection, filter, projection, flags); + if (errCode != E_OK) { + GLOGE("delete arg is illegal"); + return errCode; + } + context->collectionName = collection; + context->filter = filter; + JsonObject filterObj = JsonObject::Parse(filter, errCode, true, true); + if (errCode != E_OK) { + GLOGE("filter Parsed failed"); + return errCode; + } + errCode = FindProjectionInit(projection, context); + if (errCode != E_OK) { + return errCode; + } + bool isOnlyId = true; + std::vector> filterAllPath; + errCode = TranFilter(filterObj, filterAllPath, isOnlyId); + if (errCode != E_OK) { + GLOGE("filter is invalid"); + return errCode; + } + context->isOnlyId = isOnlyId; + if (flags == GRD_DOC_ID_DISPLAY) { + context->ifShowId = true; + } else { + context->ifShowId = false; + } + return InitFindResultSet(grdResultSet, context); +} + +bool DocumentStore::IsCollectionOpening(const std::string &collection) { if (collections_.find(collection) != collections_.end()) { GLOGE("DB is resource busy"); @@ -548,7 +726,7 @@ bool DocumentStore::IsCollectionOpening(const std::string collection) return false; } -int DocumentStore::EraseCollection(const std::string collectionName) +int DocumentStore::EraseCollection(const std::string &collectionName) { std::lock_guard lock(dbMutex_); if (collections_.find(collectionName) != collections_.end()) { @@ -559,57 +737,6 @@ int DocumentStore::EraseCollection(const std::string collectionName) return E_INVALID_ARGS; } -int DocumentStore::GetViewType(JsonObject &jsonObj, bool &viewType) -{ - std::vector leafValue = JsonCommon::GetLeafValue(jsonObj); - if (leafValue.size() == 0) { - return E_INVALID_ARGS; - } - for (size_t 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; - } - viewType = true; - } else { - 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; - } - break; - default: - return E_INVALID_ARGS; - } - } - return E_OK; -} - void DocumentStore::OnClose(const std::function ¬ifier) { closeNotifier_ = notifier; diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp index 3981807385ed74a08080e07f1894625983d7db6f..bfba1da5c14de77cb7f641e3fa91c7c87accd4bc 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set.cpp @@ -22,45 +22,30 @@ namespace DocumentDB { constexpr const char *KEY_ID = "_id"; ResultSet::ResultSet() {} -ResultSet::~ResultSet() {} -int ResultSet::EraseCollection() +ResultSet::~ResultSet() { - if (store_ != nullptr) { - store_->EraseCollection(collectionName_); - } - return E_OK; + context_ = nullptr; } -int ResultSet::Init(DocumentStore *store, const std::string collectionName, const std::string &filter, - std::vector> &path, bool ifShowId, bool viewType, bool &isOnlyId) +int ResultSet::EraseCollection() { - isOnlyId_ = isOnlyId; - store_ = store; - collectionName_ = collectionName; - filter_ = filter; - projectionPath_ = path; - if (projectionTree_.ParseTree(path) == -E_INVALID_ARGS) { - GLOGE("Parse ProjectionTree failed"); - return -E_INVALID_ARGS; + if (store_ != nullptr) { + store_->EraseCollection(context_->collectionName); } - ifShowId_ = ifShowId; - viewType_ = viewType; return E_OK; } - -int ResultSet::Init(DocumentStore *store, const std::string collectionName, const std::string &filter) +int ResultSet::Init(std::shared_ptr &context, DocumentStore *store, bool ifField) { - ifField_ = true; + ifField_ = ifField; + context_ = context; store_ = store; - collectionName_ = collectionName; - filter_ = filter; return E_OK; } int ResultSet::GetNextWithField() { int errCode = E_OK; - if (isOnlyId_) { - JsonObject filterObj = JsonObject::Parse(filter_, errCode, true, true); + if (context_->isOnlyId) { + JsonObject filterObj = JsonObject::Parse(context_->filter, errCode, true, true); if (errCode != E_OK) { GLOGE("filter Parsed failed"); return errCode; @@ -73,7 +58,7 @@ int ResultSet::GetNextWithField() } Key key(idKey.begin(), idKey.end()); Value document; - Collection coll = store_->GetCollection(collectionName_); + Collection coll = store_->GetCollection(context_->collectionName); errCode = coll.GetDocument(key, document); if (errCode == -E_NOT_FOUND) { return -E_NO_DATA; @@ -84,9 +69,9 @@ int ResultSet::GetNextWithField() values.emplace_back(std::make_pair(idKey, jsonData)); matchDatas_ = values; } else { - Collection coll = store_->GetCollection(collectionName_); + Collection coll = store_->GetCollection(context_->collectionName); std::vector> values; - JsonObject filterObj = JsonObject::Parse(filter_, errCode, true, true); + JsonObject filterObj = JsonObject::Parse(context_->filter, errCode, true, true); if (errCode != E_OK) { GLOGE("filter Parsed failed"); return errCode; @@ -107,7 +92,7 @@ int ResultSet::GetNextInner(bool isNeedCheckTable) { int errCode = E_OK; if (isNeedCheckTable) { - std::string lowerCaseName = collectionName_; + std::string lowerCaseName = context_->collectionName; std::transform(lowerCaseName.begin(), lowerCaseName.end(), lowerCaseName.begin(), [](unsigned char c) { return std::tolower(c); }); @@ -125,9 +110,9 @@ int ResultSet::GetNextInner(bool isNeedCheckTable) return errCode; } } else if (index_ == 0) { - Collection coll = store_->GetCollection(collectionName_); + Collection coll = store_->GetCollection(context_->collectionName); std::vector> values; - JsonObject filterObj = JsonObject::Parse(filter_, errCode, true, true); + JsonObject filterObj = JsonObject::Parse(context_->filter, errCode, true, true); if (errCode != E_OK) { GLOGE("filter Parsed failed"); return errCode; @@ -207,7 +192,7 @@ int ResultSet::CheckCutNode(JsonObject *node, std::vector singlePat } singlePath.emplace_back(node->GetItemField()); int index = 0; - if (!projectionTree_.SearchTree(singlePath, index) && index == 0) { + if (!context_->projectionTree.SearchTree(singlePath, index) && index == 0) { allCutPath.emplace_back(singlePath); } if (!node->GetChild().IsNull()) { @@ -230,7 +215,7 @@ int ResultSet::CutJsonBranch(std::string &jsonData) return errCode; } std::vector> allCutPath; - if (viewType_) { + if (context_->viewType) { std::vector singlePath; JsonObject cjsonObjChild = cjsonObj.GetChild(); errCode = CheckCutNode(&cjsonObjChild, singlePath, allCutPath); @@ -238,17 +223,17 @@ int ResultSet::CutJsonBranch(std::string &jsonData) GLOGE("The node in CheckCutNode is nullptr"); return errCode; } - for (auto singleCutPaht : allCutPath) { - if (!ifShowId_ || singleCutPaht[0] != KEY_ID) { + for (const auto & singleCutPaht : allCutPath) { + if (!context_->ifShowId || singleCutPaht[0] != KEY_ID) { cjsonObj.DeleteItemDeeplyOnTarget(singleCutPaht); } } } - if (!viewType_) { - for (auto singleCutPaht : projectionPath_) { + if (!context_->viewType) { + for (const auto & singleCutPaht : context_->path) { // projection Path cjsonObj.DeleteItemDeeplyOnTarget(singleCutPaht); } - if (!ifShowId_) { + if (!context_->ifShowId) { std::vector idPath; idPath.emplace_back(KEY_ID); cjsonObj.DeleteItemDeeplyOnTarget(idPath); diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp index c34c4a803836e3beb4284d6e85597f3367843d26..74b41d0a36ae9538b6bd7b84fc6568503aa3f6ac 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/src/interface/src/result_set_common.cpp @@ -23,15 +23,14 @@ namespace DocumentDB { class ValueObject; -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(std::shared_ptr &context, DocumentStore *store, ResultSet &resultSet, bool ifField) { - 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); + if (ifField == false) { + if (context->projectionTree.ParseTree(context->path) == -E_INVALID_ARGS) { + GLOGE("Parse ProjectionTree failed"); + return -E_INVALID_ARGS; + } + } + return resultSet.Init(context, store, ifField); } } // namespace DocumentDB diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp index 3fa8c92d30f4c1bd4fafff4c8b61cd437b5c1193..01320cbcc21d53d6c947204ae398604597e37a37 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd/test/unittest/api/documentdb_find_test.cpp @@ -1438,14 +1438,17 @@ HWTEST_F(DocumentDBFindTest, DocumentDBFindTest061, TestSize.Level1) char *value = nullptr; EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); CompareValue(value, document061); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); EXPECT_EQ(GRD_Next(resultSet), GRD_OK); EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); CompareValue(value, document062); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); EXPECT_EQ(GRD_Next(resultSet), GRD_OK); EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK); CompareValue(value, document063); + EXPECT_EQ(GRD_FreeValue(value), GRD_OK); EXPECT_EQ(GRD_Next(resultSet), GRD_OK); EXPECT_EQ(GRD_GetValue(resultSet, &value), GRD_OK);