• 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 "JS_FieldNode"
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("FLOAT") },
36     { JSUtil::BYTE_ARRAY, std::string("BYTE_ARRAY") },
37     { JSUtil::BOOLEAN, std::string("BOOLEAN") },
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         return ValueTypeToString(valueType) + "," + (isNullable ? "NULL" : "NOT NULL");
55     }
56 
57     json jsFields;
58     for (auto fld : fields) {
59         jsFields[fld->fieldName] = fld->GetValueForJson();
60     }
61     return jsFields;
62 }
63 
Constructor(napi_env env)64 napi_value JsFieldNode::Constructor(napi_env env)
65 {
66     const napi_property_descriptor properties[] = {
67         DECLARE_NAPI_FUNCTION("appendChild", JsFieldNode::AppendChild),
68         DECLARE_NAPI_GETTER_SETTER("default", JsFieldNode::GetDefaultValue, JsFieldNode::SetDefaultValue),
69         DECLARE_NAPI_GETTER_SETTER("nullable", JsFieldNode::GetNullable, JsFieldNode::SetNullable),
70         DECLARE_NAPI_GETTER_SETTER("type", JsFieldNode::GetValueType, JsFieldNode::SetValueType)
71     };
72     size_t count = sizeof(properties) / sizeof(properties[0]);
73     return JSUtil::DefineClass(env, "FieldNode", properties, count, JsFieldNode::New);
74 }
75 
New(napi_env env,napi_callback_info info)76 napi_value JsFieldNode::New(napi_env env, napi_callback_info info)
77 {
78     ZLOGD("FieldNode::New");
79     std::string fieldName;
80     auto ctxt = std::make_shared<ContextBase>();
81     auto input = [env, ctxt, &fieldName](size_t argc, napi_value* argv) {
82         // required 1 arguments :: <fieldName>
83         ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
84         ctxt->status = JSUtil::GetValue(env, argv[0], fieldName);
85         ASSERT_BUSINESS_ERR(ctxt, ((ctxt->status == napi_ok) && !fieldName.empty()), Status::INVALID_ARGUMENT,
86             "The parameters of fieldName is incorrect.");
87     };
88     ctxt->GetCbInfoSync(env, info, input);
89     ASSERT_NULL(!ctxt->isThrowError, "JsFieldNode New exit");
90 
91     JsFieldNode* fieldNode = new (std::nothrow) JsFieldNode(fieldName);
92     ASSERT_ERR(env, fieldNode != nullptr, Status::INVALID_ARGUMENT, "no memory for fieldNode.");
93 
94     auto finalize = [](napi_env env, void* data, void* hint) {
95         ZLOGD("fieldNode finalize.");
96         auto* field = reinterpret_cast<JsFieldNode*>(data);
97         ASSERT_VOID(field != nullptr, "finalize null!");
98         delete field;
99     };
100     ASSERT_CALL(env, napi_wrap(env, ctxt->self, fieldNode, finalize, nullptr, nullptr), fieldNode);
101     return ctxt->self;
102 }
103 
AppendChild(napi_env env,napi_callback_info info)104 napi_value JsFieldNode::AppendChild(napi_env env, napi_callback_info info)
105 {
106     ZLOGD("FieldNode::AppendChild");
107     JsFieldNode* child = nullptr;
108     auto ctxt = std::make_shared<ContextBase>();
109     auto input = [env, ctxt, &child](size_t argc, napi_value* argv) {
110         // required 1 arguments :: <child>
111         ASSERT_BUSINESS_ERR(ctxt, argc >= 1, Status::INVALID_ARGUMENT, "The number of parameters is incorrect.");
112         ctxt->status = JSUtil::Unwrap(env, argv[0], reinterpret_cast<void**>(&child), JsFieldNode::Constructor(env));
113         ASSERT_BUSINESS_ERR(ctxt, ((ctxt->status == napi_ok) && (child != nullptr)), Status::INVALID_ARGUMENT,
114             "The parameters JsFieldNode is incorrect.");
115     };
116     ctxt->GetCbInfoSync(env, info, input);
117     ASSERT_NULL(!ctxt->isThrowError, "AppendChild exit");
118 
119     auto fieldNode = reinterpret_cast<JsFieldNode*>(ctxt->native);
120     fieldNode->fields.push_back(child);
121 
122     napi_get_boolean(env, true, &ctxt->output);
123     return ctxt->output;
124 }
125 
GetFieldNode(napi_env env,napi_callback_info info,std::shared_ptr<ContextBase> & ctxt)126 JsFieldNode* JsFieldNode::GetFieldNode(napi_env env, napi_callback_info info, std::shared_ptr<ContextBase>& ctxt)
127 {
128     ctxt->GetCbInfoSync(env, info);
129     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
130     return reinterpret_cast<JsFieldNode*>(ctxt->native);
131 }
132 
133 template <typename T>
GetContextValue(napi_env env,std::shared_ptr<ContextBase> & ctxt,T & value)134 napi_value JsFieldNode::GetContextValue(napi_env env, std::shared_ptr<ContextBase> &ctxt, T &value)
135 {
136     JSUtil::SetValue(env, value, ctxt->output);
137     return ctxt->output;
138 }
139 
GetDefaultValue(napi_env env,napi_callback_info info)140 napi_value JsFieldNode::GetDefaultValue(napi_env env, napi_callback_info info)
141 {
142     ZLOGD("FieldNode::GetDefaultValue");
143     auto ctxt = std::make_shared<ContextBase>();
144     auto fieldNode = GetFieldNode(env, info, ctxt);
145     ASSERT(fieldNode != nullptr, "getFieldNode nullptr!", nullptr);
146     return GetContextValue(env, ctxt, fieldNode->defaultValue);
147 }
148 
SetDefaultValue(napi_env env,napi_callback_info info)149 napi_value JsFieldNode::SetDefaultValue(napi_env env, napi_callback_info info)
150 {
151     ZLOGD("FieldNode::SetDefaultValue");
152     auto ctxt = std::make_shared<ContextBase>();
153     JSUtil::KvStoreVariant vv;
154     auto input = [env, ctxt, &vv](size_t argc, napi_value* argv) {
155         // required 1 arguments :: <defaultValue>
156         ASSERT_ARGS(ctxt, argc == 1, "invalid arguments!");
157         ctxt->status = JSUtil::GetValue(env, argv[0], vv);
158         ASSERT_STATUS(ctxt, "invalid arg[0], i.e. invalid defaultValue!");
159     };
160     ctxt->GetCbInfoSync(env, info, input);
161     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
162 
163     auto fieldNode = reinterpret_cast<JsFieldNode*>(ctxt->native);
164     fieldNode->defaultValue = vv;
165     return nullptr;
166 }
167 
GetNullable(napi_env env,napi_callback_info info)168 napi_value JsFieldNode::GetNullable(napi_env env, napi_callback_info info)
169 {
170     ZLOGD("FieldNode::GetNullable");
171     auto ctxt = std::make_shared<ContextBase>();
172     auto fieldNode = GetFieldNode(env, info, ctxt);
173     ASSERT(fieldNode != nullptr, "getFieldNode nullptr!", nullptr);
174     return GetContextValue(env, ctxt, fieldNode->isNullable);
175 }
176 
SetNullable(napi_env env,napi_callback_info info)177 napi_value JsFieldNode::SetNullable(napi_env env, napi_callback_info info)
178 {
179     ZLOGD("FieldNode::SetNullable");
180     auto ctxt = std::make_shared<ContextBase>();
181     bool isNullable = false;
182     auto input = [env, ctxt, &isNullable](size_t argc, napi_value* argv) {
183         // required 1 arguments :: <isNullable>
184         ASSERT_ARGS(ctxt, argc == 1, "invalid arguments!");
185         ctxt->status = JSUtil::GetValue(env, argv[0], isNullable);
186         ASSERT_STATUS(ctxt, "invalid arg[0], i.e. invalid isNullable!");
187     };
188     ctxt->GetCbInfoSync(env, info, input);
189     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
190 
191     auto fieldNode = reinterpret_cast<JsFieldNode*>(ctxt->native);
192     fieldNode->isNullable = isNullable;
193     return nullptr;
194 }
195 
GetValueType(napi_env env,napi_callback_info info)196 napi_value JsFieldNode::GetValueType(napi_env env, napi_callback_info info)
197 {
198     ZLOGD("FieldNode::GetValueType");
199     auto ctxt = std::make_shared<ContextBase>();
200     auto fieldNode = GetFieldNode(env, info, ctxt);
201     ASSERT(fieldNode != nullptr, "getFieldNode nullptr!", nullptr);
202     return GetContextValue(env, ctxt, fieldNode->valueType);
203 }
204 
SetValueType(napi_env env,napi_callback_info info)205 napi_value JsFieldNode::SetValueType(napi_env env, napi_callback_info info)
206 {
207     ZLOGD("FieldNode::SetValueType");
208     auto ctxt = std::make_shared<ContextBase>();
209     uint32_t type = 0;
210     auto input = [env, ctxt, &type](size_t argc, napi_value* argv) {
211         // required 1 arguments :: <valueType>
212         ASSERT_ARGS(ctxt, argc == 1, "invalid arguments!");
213         ctxt->status = JSUtil::GetValue(env, argv[0], type);
214         ASSERT_STATUS(ctxt, "invalid arg[0], i.e. invalid valueType!");
215         ASSERT_ARGS(ctxt, (JSUtil::STRING <= type) && (type <= JSUtil::DOUBLE),
216             "invalid arg[0], i.e. invalid valueType!");
217     };
218     ctxt->GetCbInfoSync(env, info, input);
219     NAPI_ASSERT(env, ctxt->status == napi_ok, "invalid arguments!");
220 
221     auto fieldNode = reinterpret_cast<JsFieldNode*>(ctxt->native);
222     fieldNode->valueType = type;
223     return nullptr;
224 }
225 
ValueToString(JSUtil::KvStoreVariant value)226 std::string JsFieldNode::ValueToString(JSUtil::KvStoreVariant value)
227 {
228     auto strValue = std::get_if<std::string>(&value);
229     if (strValue != nullptr) {
230         return (*strValue);
231     }
232     auto intValue = std::get_if<int32_t>(&value);
233     if (intValue != nullptr) {
234         return std::to_string(*intValue);
235     }
236     auto fltValue = std::get_if<float>(&value);
237     if (fltValue != nullptr) {
238         return std::to_string(*fltValue);
239     }
240     auto boolValue = std::get_if<bool>(&value);
241     if (boolValue != nullptr) {
242         return std::to_string(*boolValue);
243     }
244     auto dblValue = std::get_if<double>(&value);
245     if (dblValue != nullptr) {
246         return std::to_string(*dblValue);
247     }
248     ZLOGE("ValueType is INVALID");
249     return std::string();
250 }
251 
ValueTypeToString(uint32_t type)252 std::string JsFieldNode::ValueTypeToString(uint32_t type)
253 {
254     // DistributedDB::FieldType
255     auto it = valueTypeToString_.find(type);
256     if (valueTypeToString_.find(type) != valueTypeToString_.end()) {
257         return it->second;
258     } else {
259         return std::string();
260     }
261 }
262 
Dump()263 std::string JsFieldNode::Dump()
264 {
265     json jsFields;
266     for (auto fld : fields) {
267         jsFields.push_back(fld->Dump());
268     }
269 
270     json jsNode = {
271         { FIELD_NAME, fieldName },
272         { VALUE_TYPE, ValueTypeToString(valueType) },
273         { DEFAULT_VALUE, ValueToString(defaultValue) },
274         { IS_DEFAULT_VALUE, isWithDefaultValue },
275         { IS_NULLABLE, isNullable },
276         { CHILDREN, jsFields.dump() }
277     };
278     return jsNode.dump();
279 }
280 } // namespace OHOS::DistributedKVStore
281