• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #define LOG_TAG "JSFieldNode"
16 #include "js_field_node.h"
17 #include "js_util.h"
18 #include "log_print.h"
19 #include "napi_queue.h"
20 #include "uv_queue.h"
21 
22 using namespace OHOS::DistributedKv;
23 
24 namespace OHOS::DistributedKVStore {
25 static std::string FIELD_NAME = "FIELD_NAME";
26 static std::string VALUE_TYPE = "VALUE_TYPE";
27 static std::string DEFAULT_VALUE = "DEFAULT_VALUE";
28 static std::string IS_DEFAULT_VALUE = "IS_DEFAULT_VALUE";
29 static std::string IS_NULLABLE = "IS_NULLABLE";
30 static std::string CHILDREN = "CHILDREN";
31 
32 std::map<uint32_t, std::string> JsFieldNode::valueTypeToString_ = {
33     { JSUtil::STRING, std::string("STRING") },
34     { JSUtil::INTEGER, std::string("INTEGER") },
35     { JSUtil::FLOAT, std::string("DOUBLE") },
36     { JSUtil::BYTE_ARRAY, std::string("BYTE_ARRAY") },
37     { JSUtil::BOOLEAN, std::string("BOOL") },
38     { JSUtil::DOUBLE, std::string("DOUBLE") }
39 };
40 
JsFieldNode(const std::string & fName)41 JsFieldNode::JsFieldNode(const std::string& fName)
42     : fieldName_(fName)
43 {
44 }
45 
GetFieldName()46 std::string JsFieldNode::GetFieldName()
47 {
48     return fieldName_;
49 }
50 
GetValueForJson()51 JsFieldNode::json JsFieldNode::GetValueForJson()
52 {
53     if (fields_.empty()) {
54         if (valueType_ == JSUtil::STRING) {
55             return ToString(valueType_) + ToString(isNullable_ ? "," : ", NOT NULL,") +
56                 " DEFAULT '" + ToString(defaultValue_) + "'";
57         }
58         return ToString(valueType_) + ToString(isNullable_ ? "," : ", NOT NULL,") +
59             " DEFAULT " + ToString(defaultValue_);
60     }
61 
62     json jsFields;
63     for (auto fld : fields_) {
64         jsFields[fld->fieldName_] = fld->GetValueForJson();
65     }
66     return jsFields;
67 }
68 
Constructor(napi_env env)69 napi_value JsFieldNode::Constructor(napi_env env)
70 {
71     auto lambda = []() -> std::vector<napi_property_descriptor>{
72         std::vector<napi_property_descriptor> properties = {
73             DECLARE_NAPI_FUNCTION("appendChild", JsFieldNode::AppendChild),
74             DECLARE_NAPI_GETTER_SETTER("default", JsFieldNode::GetDefaultValue, JsFieldNode::SetDefaultValue),
75             DECLARE_NAPI_GETTER_SETTER("nullable", JsFieldNode::GetNullable, JsFieldNode::SetNullable),
76             DECLARE_NAPI_GETTER_SETTER("type", JsFieldNode::GetValueType, JsFieldNode::SetValueType)
77         };
78         return properties;
79     };
80     return JSUtil::DefineClass(env, "ohos.data.distributedKVStore", "FieldNode", lambda, JsFieldNode::New);
81 }
82 
New(napi_env env,napi_callback_info info)83 napi_value JsFieldNode::New(napi_env env, napi_callback_info info)
84 {
85     ZLOGD("FieldNode::New");
86     std::string fieldName;
87     auto ctxt = std::make_shared<ContextBase>();
88     auto input = [env, ctxt, &fieldName](size_t argc, napi_value* argv) {
89         // required 1 arguments :: <fieldName>
90         ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT,
91             "Parameter error:Mandatory parameters are left unspecified");
92         ctxt->status = JSUtil::GetValue(env, argv[0], fieldName);
93         ASSERT_BUSINESS_ERR(ctxt, ((ctxt->status == napi_ok) && !fieldName.empty()),
94             Status::INVALID_ARGUMENT, "Parameter error:fieldName empty");
95     };
96     ctxt->GetCbInfoSync(env, info, input);
97     ASSERT_NULL(!ctxt->isThrowError, "JsFieldNode New exit");
98 
99     JsFieldNode* fieldNode = new (std::nothrow) JsFieldNode(fieldName);
100     ASSERT_ERR(env, fieldNode != nullptr, Status::INVALID_ARGUMENT, "Parameter error:fieldNode is nullptr");
101 
102     auto finalize = [](napi_env env, void* data, void* hint) {
103         ZLOGD("fieldNode finalize.");
104         auto* fieldNode = reinterpret_cast<JsFieldNode*>(data);
105         ASSERT_VOID(fieldNode != nullptr, "fieldNode is null!");
106         delete fieldNode;
107     };
108     ASSERT_CALL(env, napi_wrap(env, ctxt->self, fieldNode, finalize, nullptr, nullptr), fieldNode);
109     return ctxt->self;
110 }
111 
AppendChild(napi_env env,napi_callback_info info)112 napi_value JsFieldNode::AppendChild(napi_env env, napi_callback_info info)
113 {
114     ZLOGD("FieldNode::AppendChild");
115     JsFieldNode* child = nullptr;
116     auto ctxt = std::make_shared<ContextBase>();
117     auto input = [env, ctxt, &child](size_t argc, napi_value* argv) {
118         // required 1 arguments :: <child>
119         ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT,
120             "Parameter error:Mandatory parameters are left unspecified");
121         ctxt->status = JSUtil::Unwrap(env, argv[0], reinterpret_cast<void**>(&child), JsFieldNode::Constructor(env));
122         ASSERT_BUSINESS_ERR(ctxt, ((ctxt->status == napi_ok) && (child != nullptr)),
123             Status::INVALID_ARGUMENT, "Parameter error:child is nullptr");
124     };
125     ctxt->GetCbInfoSync(env, info, input);
126     ASSERT_NULL(!ctxt->isThrowError, "AppendChild exit");
127 
128     auto fieldNode = reinterpret_cast<JsFieldNode*>(ctxt->native);
129     fieldNode->fields_.push_back(child);
130 
131     napi_get_boolean(env, true, &ctxt->output);
132     return ctxt->output;
133 }
134 
GetFieldNode(napi_env env,napi_callback_info info,std::shared_ptr<ContextBase> & ctxt)135 JsFieldNode* JsFieldNode::GetFieldNode(napi_env env, napi_callback_info info, std::shared_ptr<ContextBase>& ctxt)
136 {
137     ctxt->GetCbInfoSync(env, info);
138     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
139     return reinterpret_cast<JsFieldNode*>(ctxt->native);
140 }
141 
142 template <typename T>
GetContextValue(napi_env env,std::shared_ptr<ContextBase> & ctxt,T & value)143 napi_value JsFieldNode::GetContextValue(napi_env env, std::shared_ptr<ContextBase> &ctxt, T &value)
144 {
145     JSUtil::SetValue(env, value, ctxt->output);
146     return ctxt->output;
147 }
148 
GetDefaultValue(napi_env env,napi_callback_info info)149 napi_value JsFieldNode::GetDefaultValue(napi_env env, napi_callback_info info)
150 {
151     ZLOGD("FieldNode::GetDefaultValue");
152     auto ctxt = std::make_shared<ContextBase>();
153     auto fieldNode = GetFieldNode(env, info, ctxt);
154     ASSERT(fieldNode != nullptr, "fieldNode is nullptr!", nullptr);
155     return GetContextValue(env, ctxt, fieldNode->defaultValue_);
156 }
157 
SetDefaultValue(napi_env env,napi_callback_info info)158 napi_value JsFieldNode::SetDefaultValue(napi_env env, napi_callback_info info)
159 {
160     ZLOGD("FieldNode::SetDefaultValue");
161     auto ctxt = std::make_shared<ContextBase>();
162     JSUtil::KvStoreVariant vv;
163     auto input = [env, ctxt, &vv](size_t argc, napi_value* argv) {
164         // required 1 arguments :: <defaultValue>
165         ASSERT_ARGS(ctxt, argc == 1, "invalid arguments!");
166         ctxt->status = JSUtil::GetValue(env, argv[0], vv);
167         ASSERT_STATUS(ctxt, "invalid arg[0], i.e. invalid defaultValue!");
168     };
169     ctxt->GetCbInfoSync(env, info, input);
170     NAPI_ASSERT(env, ctxt->status == napi_ok,
171         "Parameter error:Parameters type must belong one of string,number,array,bool.");
172 
173     auto fieldNode = reinterpret_cast<JsFieldNode*>(ctxt->native);
174     fieldNode->defaultValue_ = vv;
175     return nullptr;
176 }
177 
GetNullable(napi_env env,napi_callback_info info)178 napi_value JsFieldNode::GetNullable(napi_env env, napi_callback_info info)
179 {
180     ZLOGD("FieldNode::GetNullable");
181     auto ctxt = std::make_shared<ContextBase>();
182     auto fieldNode = GetFieldNode(env, info, ctxt);
183     ASSERT(fieldNode != nullptr, "fieldNode is nullptr!", nullptr);
184     return GetContextValue(env, ctxt, fieldNode->isNullable_);
185 }
186 
SetNullable(napi_env env,napi_callback_info info)187 napi_value JsFieldNode::SetNullable(napi_env env, napi_callback_info info)
188 {
189     ZLOGD("FieldNode::SetNullable");
190     auto ctxt = std::make_shared<ContextBase>();
191     bool isNullable = false;
192     auto input = [env, ctxt, &isNullable](size_t argc, napi_value* argv) {
193         // required 1 arguments :: <isNullable>
194         ASSERT_ARGS(ctxt, argc == 1, "invalid arguments!");
195         ctxt->status = JSUtil::GetValue(env, argv[0], isNullable);
196         ASSERT_STATUS(ctxt, "invalid arg[0], i.e. invalid isNullable!");
197     };
198     ctxt->GetCbInfoSync(env, info, input);
199     NAPI_ASSERT(env, ctxt->status == napi_ok, "Parameter error:Parameters type failed");
200 
201     auto fieldNode = reinterpret_cast<JsFieldNode*>(ctxt->native);
202     fieldNode->isNullable_ = isNullable;
203     return nullptr;
204 }
205 
GetValueType(napi_env env,napi_callback_info info)206 napi_value JsFieldNode::GetValueType(napi_env env, napi_callback_info info)
207 {
208     ZLOGD("FieldNode::GetValueType");
209     auto ctxt = std::make_shared<ContextBase>();
210     auto fieldNode = GetFieldNode(env, info, ctxt);
211     ASSERT(fieldNode != nullptr, "fieldNode is nullptr!", nullptr);
212     return GetContextValue(env, ctxt, fieldNode->valueType_);
213 }
214 
SetValueType(napi_env env,napi_callback_info info)215 napi_value JsFieldNode::SetValueType(napi_env env, napi_callback_info info)
216 {
217     ZLOGD("FieldNode::SetValueType");
218     auto ctxt = std::make_shared<ContextBase>();
219     uint32_t type = 0;
220     auto input = [env, ctxt, &type](size_t argc, napi_value* argv) {
221         // required 1 arguments :: <valueType>
222         ASSERT_ARGS(ctxt, argc == 1, "invalid arguments!");
223         ctxt->status = JSUtil::GetValue(env, argv[0], type);
224         ASSERT_STATUS(ctxt, "invalid arg[0], i.e. invalid valueType!");
225         ASSERT_ARGS(ctxt, (JSUtil::STRING <= type) && (type <= JSUtil::DOUBLE),
226             "invalid arg[0], i.e. invalid valueType!");
227     };
228     ctxt->GetCbInfoSync(env, info, input);
229     NAPI_ASSERT(env, ctxt->status == napi_ok, "Parameter error:Parameters type failed");
230 
231     auto fieldNode = reinterpret_cast<JsFieldNode*>(ctxt->native);
232     fieldNode->valueType_ = type;
233     return nullptr;
234 }
235 
ToString(const JSUtil::KvStoreVariant & value)236 std::string JsFieldNode::ToString(const JSUtil::KvStoreVariant &value)
237 {
238     auto strValue = std::get_if<std::string>(&value);
239     if (strValue != nullptr) {
240         return (*strValue);
241     }
242     auto intValue = std::get_if<int32_t>(&value);
243     if (intValue != nullptr) {
244         return std::to_string(*intValue);
245     }
246     auto fltValue = std::get_if<float>(&value);
247     if (fltValue != nullptr) {
248         return std::to_string(*fltValue);
249     }
250     auto boolValue = std::get_if<bool>(&value);
251     if (boolValue != nullptr) {
252         return std::to_string(*boolValue);
253     }
254     auto dblValue = std::get_if<double>(&value);
255     if (dblValue != nullptr) {
256         return std::to_string(*dblValue);
257     }
258     ZLOGE("ValueType is INVALID");
259     return std::string();
260 }
261 
ToString(uint32_t type)262 std::string JsFieldNode::ToString(uint32_t type)
263 {
264     // DistributedDB::FieldType
265     auto it = valueTypeToString_.find(type);
266     if (valueTypeToString_.find(type) != valueTypeToString_.end()) {
267         return it->second;
268     } else {
269         return std::string();
270     }
271 }
272 
Dump()273 std::string JsFieldNode::Dump()
274 {
275     json jsFields;
276     for (auto fld : fields_) {
277         jsFields.push_back(fld->Dump());
278     }
279 
280     json jsNode = {
281         { FIELD_NAME, fieldName_ },
282         { VALUE_TYPE, ToString(valueType_) },
283         { DEFAULT_VALUE, ToString(defaultValue_) },
284         { IS_DEFAULT_VALUE, isWithDefaultValue_ },
285         { IS_NULLABLE, isNullable_ },
286         { CHILDREN, jsFields.dump() }
287     };
288     return jsNode.dump();
289 }
290 } // namespace OHOS::DistributedKVStore
291