1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "collection_option.h"
17
18 #include <algorithm>
19 #include <cstring>
20
21 #include "doc_errno.h"
22 #include "rd_json_object.h"
23 #include "rd_log_print.h"
24
25 namespace DocumentDB {
26 namespace {
27 constexpr const char *OPT_MAX_DOC = "maxdoc";
28 constexpr const char *OPT_COLLECTION_MODE = "mode";
29 constexpr const char *KV_COLLECTION_MODE = "kv";
30
CFG_IsValid(const JsonObject & config)31 int CFG_IsValid(const JsonObject &config)
32 {
33 JsonObject child = config.GetChild();
34 while (!child.IsNull()) {
35 std::string fieldName = child.GetItemField();
36 if (strcmp(OPT_COLLECTION_MODE, fieldName.c_str()) == 0) {
37 if (strcmp(child.GetItemValue().GetStringValue().c_str(), KV_COLLECTION_MODE) == 0) { // The value of mode
38 return -E_NOT_SUPPORT;
39 } else {
40 child = child.GetNext();
41 continue;
42 }
43 }
44 if (strcmp(OPT_MAX_DOC, fieldName.c_str()) != 0) {
45 GLOGE("Invalid collection config.");
46 return -E_INVALID_CONFIG_VALUE;
47 }
48 child = child.GetNext();
49 }
50 return E_OK;
51 }
52 } // namespace
53
ReadOption(const std::string & optStr,int & errCode)54 CollectionOption CollectionOption::ReadOption(const std::string &optStr, int &errCode)
55 {
56 if (optStr.empty()) {
57 return {};
58 }
59
60 std::string lowerCaseOptStr = optStr;
61 std::transform(lowerCaseOptStr.begin(), lowerCaseOptStr.end(), lowerCaseOptStr.begin(), [](unsigned char c) {
62 return std::tolower(c);
63 });
64
65 JsonObject collOpt = JsonObject::Parse(lowerCaseOptStr, errCode);
66 if (errCode != E_OK) {
67 GLOGE("Read collection option failed from str. %d", errCode);
68 return {};
69 }
70
71 errCode = CFG_IsValid(collOpt);
72 if (errCode != E_OK) {
73 GLOGE("Check collection option, not support config item. %d", errCode);
74 return {};
75 }
76
77 static const JsonFieldPath maxDocField = { OPT_MAX_DOC };
78 if (!collOpt.IsFieldExists(maxDocField)) {
79 return {};
80 }
81
82 ValueObject maxDocValue = collOpt.GetObjectByPath(maxDocField, errCode);
83 if (errCode != E_OK) {
84 GLOGE("Read collection option failed. %d", errCode);
85 return {};
86 }
87
88 if (maxDocValue.GetValueType() != ValueObject::ValueType::VALUE_NUMBER) {
89 GLOGE("Check collection option failed, the field type of maxDoc is not NUMBER.");
90 errCode = -E_INVALID_CONFIG_VALUE;
91 return {};
92 }
93
94 if (maxDocValue.GetIntValue() <= 0 || static_cast<uint64_t>(maxDocValue.GetIntValue()) > UINT32_MAX) {
95 GLOGE("Check collection option failed, invalid maxDoc value.");
96 errCode = -E_INVALID_CONFIG_VALUE;
97 return {};
98 }
99
100 CollectionOption option;
101 option.maxDoc_ = static_cast<uint32_t>(maxDocValue.GetIntValue());
102 option.option_ = optStr;
103 return option;
104 }
105 } // namespace DocumentDB