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 #define LOG_TAG "JSCloudUtils"
16 #include "js_cloud_utils.h"
17 #include "js_proxy.h"
18 #include "result_set.h"
19 #include "result_set_bridge.h"
20 #include "logger.h"
21 
22 #define NAPI_CALL_RETURN_ERR(call, ret)  \
23     ASSERT_RETURN((call) == napi_ok, ret)
24 
25 #define ASSERT_RETURN(call, ret) \
26     do {                         \
27         if (!(call)) {           \
28             return ret;          \
29         }                        \
30     } while (0)
31 
32 namespace OHOS::AppDataMgrJsKit {
33 namespace JSUtils {
34 using namespace OHOS::Rdb;
35 
36 template<>
Convert2Value(napi_env env,napi_value input,ExtraData & output)37 int32_t Convert2Value(napi_env env, napi_value input, ExtraData &output)
38 {
39     napi_valuetype type = napi_undefined;
40     napi_status status = napi_typeof(env, input, &type);
41     if (status != napi_ok || type != napi_object) {
42         return napi_invalid_arg;
43     }
44     int32_t result = GetNamedProperty(env, input, "eventId", output.eventId);
45     if (result != napi_ok) {
46         return napi_invalid_arg;
47     }
48     return GetNamedProperty(env, input, "extraData", output.extraData);
49 }
50 
51 template<>
Convert2Value(napi_env env,napi_value input,Participant & output)52 int32_t Convert2Value(napi_env env, napi_value input, Participant &output)
53 {
54     napi_valuetype type = napi_undefined;
55     napi_status status = napi_typeof(env, input, &type);
56     if (status != napi_ok || type != napi_object) {
57         LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type);
58         return napi_invalid_arg;
59     }
60     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "identity", output.identity), napi_invalid_arg);
61     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "role", output.role, true), napi_invalid_arg);
62     if (output.role < CloudData::Role::ROLE_NIL || output.role >= CloudData::Role::ROLE_BUTT) {
63         return napi_invalid_arg;
64     }
65     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "state", output.state, true), napi_invalid_arg);
66     if (output.state < CloudData::Confirmation::CFM_NIL ||
67         output.state >= CloudData::Confirmation::CFM_BUTT) {
68         return napi_invalid_arg;
69     }
70     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "privilege", output.privilege, true), napi_invalid_arg);
71     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "attachInfo", output.attachInfo, true), napi_invalid_arg);
72     return napi_ok;
73 }
74 
75 template<>
Convert2Value(napi_env env,napi_value input,Privilege & output)76 int32_t Convert2Value(napi_env env, napi_value input, Privilege &output)
77 {
78     napi_valuetype type = napi_undefined;
79     napi_status status = napi_typeof(env, input, &type);
80     if (status != napi_ok || type != napi_object) {
81         LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type);
82         return napi_invalid_arg;
83     }
84     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "writable", output.writable, true), napi_invalid_arg);
85     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "readable", output.readable, true), napi_invalid_arg);
86     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "creatable", output.creatable, true), napi_invalid_arg);
87     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "deletable", output.deletable, true), napi_invalid_arg);
88     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "shareable", output.shareable, true), napi_invalid_arg);
89     return napi_ok;
90 }
91 
92 template<>
Convert2Value(napi_env env,napi_value jsValue,Asset & output)93 int32_t Convert2Value(napi_env env, napi_value jsValue, Asset &output)
94 {
95     napi_valuetype type = napi_undefined;
96     napi_status status = napi_typeof(env, jsValue, &type);
97     bool isArray;
98     napi_status status_array = napi_is_array(env, jsValue, &isArray);
99     if (status != napi_ok || type != napi_object || status_array != napi_ok || isArray) {
100         LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type);
101         return napi_invalid_arg;
102     }
103 
104     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, jsValue, "name", output.name), napi_invalid_arg);
105     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, jsValue, "uri", output.uri), napi_invalid_arg);
106     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, jsValue, "createTime", output.createTime), napi_invalid_arg);
107     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, jsValue, "modifyTime", output.modifyTime), napi_invalid_arg);
108     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, jsValue, "modifyTime", output.size), napi_invalid_arg);
109     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, jsValue, "path", output.path), napi_invalid_arg);
110     NAPI_CALL_RETURN_ERR(GetNamedProperty(env, jsValue, "status", output.status, true), napi_invalid_arg);
111     output.hash = output.modifyTime + "_" + output.size;
112     if (output.status != Asset::STATUS_DELETE) {
113         output.status = Asset::STATUS_UNKNOWN;
114     }
115     return napi_ok;
116 }
117 
118 template<>
Convert2Value(napi_env env,napi_value input,std::shared_ptr<RdbPredicates> & output)119 int32_t Convert2Value(napi_env env, napi_value input, std::shared_ptr<RdbPredicates> &output)
120 {
121     napi_valuetype type = napi_undefined;
122     napi_status status = napi_typeof(env, input, &type);
123     if (status != napi_ok || type != napi_object) {
124         LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type);
125         return napi_invalid_arg;
126     }
127     JSProxy::JSProxy<NativeRdb::RdbPredicates> *jsProxy = nullptr;
128     status = napi_unwrap(env, input, reinterpret_cast<void **>(&jsProxy));
129     ASSERT_RETURN(status == napi_ok && jsProxy != nullptr && jsProxy->GetInstance() != nullptr, napi_invalid_arg);
130     output = jsProxy->GetInstance();
131     return napi_ok;
132 }
133 
134 template<>
Convert2JSValue(napi_env env,const Participant & value)135 napi_value Convert2JSValue(napi_env env, const Participant &value)
136 {
137     napi_value jsValue = nullptr;
138     napi_status status = napi_create_object(env, &jsValue);
139     if (status != napi_ok) {
140         return nullptr;
141     }
142     napi_value identity = Convert2JSValue(env, value.identity);
143     napi_value role = nullptr;
144     if (value.role == CloudData::Role::ROLE_NIL) {
145         napi_get_undefined(env, &role);
146     } else {
147         role = Convert2JSValue(env, value.role);
148     }
149     napi_value state = nullptr;
150     if (value.state == CloudData::Confirmation::CFM_NIL) {
151         napi_get_undefined(env, &state);
152     } else {
153         state = Convert2JSValue(env, value.state);
154     }
155     napi_value privilege = Convert2JSValue(env, value.privilege);
156     if (privilege == nullptr) {
157         return nullptr;
158     }
159     napi_value attachInfo = Convert2JSValue(env, value.attachInfo);
160     napi_set_named_property(env, jsValue, "identity", identity);
161     napi_set_named_property(env, jsValue, "role", role);
162     napi_set_named_property(env, jsValue, "state", state);
163     napi_set_named_property(env, jsValue, "privilege", privilege);
164     napi_set_named_property(env, jsValue, "attachInfo", attachInfo);
165     return jsValue;
166 }
167 
168 template<>
Convert2JSValue(napi_env env,const Privilege & value)169 napi_value Convert2JSValue(napi_env env, const Privilege &value)
170 {
171     napi_value jsValue = nullptr;
172     napi_status status = napi_create_object(env, &jsValue);
173     if (status != napi_ok) {
174         return nullptr;
175     }
176 
177     napi_set_named_property(env, jsValue, "writable", Convert2JSValue(env, value.writable));
178     napi_set_named_property(env, jsValue, "readable", Convert2JSValue(env, value.readable));
179     napi_set_named_property(env, jsValue, "creatable", Convert2JSValue(env, value.creatable));
180     napi_set_named_property(env, jsValue, "deletable", Convert2JSValue(env, value.deletable));
181     napi_set_named_property(env, jsValue, "shareable", Convert2JSValue(env, value.shareable));
182     return jsValue;
183 }
184 
185 template<>
Convert2JSValue(napi_env env,const std::shared_ptr<ResultSet> & value)186 napi_value Convert2JSValue(napi_env env, const std::shared_ptr<ResultSet> &value)
187 {
188     auto constructor = JSUtils::GetClass(env, "ohos.data.relationalStore", "ResultSet");
189     if (constructor == nullptr) {
190         LOG_ERROR("Constructor of ResultSet is nullptr!");
191         return nullptr;
192     }
193     napi_value instance = nullptr;
194     napi_status status = napi_new_instance(env, constructor, 0, nullptr, &instance);
195     if (status != napi_ok) {
196         LOG_ERROR("NewInstance ResultSet failed! status:%{public}d!", status);
197         return nullptr;
198     }
199     JSProxy::JSEntity<NativeRdb::ResultSet, DataShare::ResultSetBridge> *proxy = nullptr;
200     status = napi_unwrap(env, instance, reinterpret_cast<void **>(&proxy));
201     if (status != napi_ok || proxy == nullptr) {
202         LOG_ERROR("napi_unwrap failed! status:%{public}d!", status);
203         return nullptr;
204     }
205     proxy->SetInstance(value);
206     return instance;
207 }
208 
209 template<>
Convert2JSValue(napi_env env,const std::pair<int32_t,std::string> & value)210 napi_value Convert2JSValue(napi_env env, const std::pair<int32_t, std::string> &value)
211 {
212     napi_value jsValue;
213     napi_status status = napi_create_object(env, &jsValue);
214     if (status != napi_ok) {
215         return nullptr;
216     }
217     napi_value code = Convert2JSValue(env, value.first);
218     napi_value description = Convert2JSValue(env, value.second);
219     napi_value val;
220     napi_get_undefined(env, &val);
221     napi_set_named_property(env, jsValue, "code", code);
222     napi_set_named_property(env, jsValue, "description", description);
223     napi_set_named_property(env, jsValue, "value", val);
224     return jsValue;
225 }
226 
227 template<>
Convert2JSValue(napi_env env,const StatisticInfo & value)228 napi_value Convert2JSValue(napi_env env, const StatisticInfo &value)
229 {
230     napi_value jsValue = nullptr;
231     napi_status status = napi_create_object(env, &jsValue);
232     if (status != napi_ok) {
233         return nullptr;
234     }
235     napi_value table = Convert2JSValue(env, value.table);
236     napi_value inserted = Convert2JSValue(env, value.inserted);
237     napi_value updated = Convert2JSValue(env, value.updated);
238     napi_value normal = Convert2JSValue(env, value.normal);
239     napi_set_named_property(env, jsValue, "table", table);
240     napi_set_named_property(env, jsValue, "inserted", inserted);
241     napi_set_named_property(env, jsValue, "updated", updated);
242     napi_set_named_property(env, jsValue, "normal", normal);
243     return jsValue;
244 }
245 
246 template<>
Convert2JSValue(napi_env env,const CloudSyncInfo & value)247 napi_value Convert2JSValue(napi_env env, const CloudSyncInfo &value)
248 {
249     napi_value jsValue = nullptr;
250     napi_status status = napi_create_object(env, &jsValue);
251     if (status != napi_ok) {
252         return nullptr;
253     }
254 
255     napi_value startTime = nullptr;
256     status = napi_create_date(env, static_cast<double>(value.startTime), &startTime);
257     if (status != napi_ok) {
258         return nullptr;
259     }
260 
261     napi_value finishTime = nullptr;
262     status = napi_create_date(env, static_cast<double>(value.finishTime), &finishTime);
263     if (status != napi_ok) {
264         return nullptr;
265     }
266     napi_set_named_property(env, jsValue, "startTime", startTime);
267     napi_set_named_property(env, jsValue, "finishTime", finishTime);
268     napi_set_named_property(env, jsValue, "code", Convert2JSValue(env, value.code));
269     return jsValue;
270 }
271 }; // namespace JSUtils
272 } // namespace OHOS::AppDataMgrJsKit