• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "napi_datashare_helper.h"
17 
18 #include "data_proxy_observer_stub.h"
19 #include "datashare_helper.h"
20 #include "datashare_log.h"
21 #include "datashare_predicates_proxy.h"
22 #include "datashare_result_set_proxy.h"
23 #include "napi_base_context.h"
24 #include "napi_common_util.h"
25 #include "napi_datashare_values_bucket.h"
26 
27 using namespace OHOS::AAFwk;
28 using namespace OHOS::AppExecFwk;
29 
30 namespace OHOS {
31 namespace DataShare {
32 static constexpr int MAX_ARGC = 6;
UnwrapDataSharePredicates(napi_env env,napi_value value)33 static DataSharePredicates UnwrapDataSharePredicates(napi_env env, napi_value value)
34 {
35     auto predicates = DataSharePredicatesProxy::GetNativePredicates(env, value);
36     if (predicates == nullptr) {
37         LOG_ERROR("GetNativePredicates is nullptr.");
38         return {};
39     }
40     return DataSharePredicates(predicates->GetOperationList());
41 }
42 
UnwrapValuesBucketArrayFromJS(napi_env env,napi_value param,std::vector<DataShareValuesBucket> & value)43 static bool UnwrapValuesBucketArrayFromJS(napi_env env, napi_value param, std::vector<DataShareValuesBucket> &value)
44 {
45     uint32_t arraySize = 0;
46     napi_value jsValue = nullptr;
47     std::string strValue = "";
48 
49     if (!IsArrayForNapiValue(env, param, arraySize)) {
50         LOG_ERROR("IsArrayForNapiValue is false");
51         return false;
52     }
53 
54     value.clear();
55     for (uint32_t i = 0; i < arraySize; i++) {
56         jsValue = nullptr;
57         if (napi_get_element(env, param, i, &jsValue) != napi_ok) {
58             LOG_ERROR("napi_get_element is false");
59             return false;
60         }
61 
62         DataShareValuesBucket valueBucket;
63         if (!GetValueBucketObject(valueBucket, env, jsValue)) {
64             return false;
65         }
66 
67         value.push_back(std::move(valueBucket));
68     }
69     return true;
70 }
71 
GetValuesBucketArray(napi_env env,napi_value param,bool & status)72 static std::vector<DataShareValuesBucket> GetValuesBucketArray(napi_env env, napi_value param, bool &status)
73 {
74     std::vector<DataShareValuesBucket> result;
75     status = UnwrapValuesBucketArrayFromJS(env, param, result);
76     return result;
77 }
78 
GetUri(napi_env env,napi_value jsValue,std::string & uri)79 static bool GetUri(napi_env env, napi_value jsValue, std::string &uri)
80 {
81     napi_valuetype valuetype = napi_undefined;
82     napi_typeof(env, jsValue, &valuetype);
83     if (valuetype != napi_string) {
84         return false;
85     }
86     uri = DataShareJSUtils::Convert2String(env, jsValue);
87     return true;
88 }
89 
GetOptions(napi_env env,napi_value jsValue,CreateOptions & options)90 bool NapiDataShareHelper::GetOptions(napi_env env, napi_value jsValue, CreateOptions &options)
91 {
92     napi_valuetype type = napi_undefined;
93     napi_typeof(env, jsValue, &type);
94     if (type != napi_object) {
95         LOG_ERROR("CreateOptions is not object");
96         return false;
97     }
98     napi_value isProxyJs = nullptr;
99     napi_status status = napi_get_named_property(env, jsValue, "isProxy", &isProxyJs);
100     if (status != napi_ok) {
101         LOG_ERROR("napi_get_named_property failed %{public}d", status);
102         return false;
103     }
104     napi_typeof(env, isProxyJs, &type);
105     if (type != napi_boolean) {
106         LOG_ERROR("CreateOptions.isProxy is not bool");
107         return false;
108     }
109     status = napi_get_value_bool(env, isProxyJs, &options.isProxy_);
110     if (status != napi_ok) {
111         LOG_ERROR("napi_get_value_bool failed %{public}d", status);
112         return false;
113     }
114     options.enabled_ = true;
115     return true;
116 }
117 
Napi_CreateDataShareHelper(napi_env env,napi_callback_info info)118 napi_value NapiDataShareHelper::Napi_CreateDataShareHelper(napi_env env, napi_callback_info info)
119 {
120     auto ctxInfo = std::make_shared<CreateContextInfo>();
121     auto input = [ctxInfo](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
122         NAPI_ASSERT_CALL_ERRCODE(env, argc == 2 || argc == 3 || argc == 4,
123             ctxInfo->error = std::make_shared<ParametersNumError>("2 or 3 or 4"), napi_invalid_arg);
124         ctxInfo->contextS = OHOS::AbilityRuntime::GetStageModeContext(env, argv[0]);
125         NAPI_ASSERT_CALL_ERRCODE(env, ctxInfo->contextS != nullptr,
126             ctxInfo->error = std::make_shared<ParametersTypeError>("contextS", "not nullptr"), napi_invalid_arg);
127         NAPI_ASSERT_CALL_ERRCODE(env, GetUri(env, argv[1], ctxInfo->strUri),
128             ctxInfo->error = std::make_shared<ParametersTypeError>("uri", "string"), napi_invalid_arg);
129         Uri uri(ctxInfo->strUri);
130         if (uri.GetScheme() == "datashareproxy") {
131             NAPI_ASSERT_CALL_ERRCODE(env, argc == 3 || argc == 4,
132                 ctxInfo->error = std::make_shared<ParametersNumError>("3 or 4"), napi_invalid_arg);
133             NAPI_ASSERT_CALL_ERRCODE(env, GetOptions(env, argv[2], ctxInfo->options),
134                 ctxInfo->error = std::make_shared<ParametersTypeError>("option", "CreateOption"), napi_invalid_arg);
135         }
136         napi_value helperProxy = nullptr;
137         napi_status status = napi_new_instance(env, GetConstructor(env), argc, argv, &helperProxy);
138         NAPI_ASSERT_CALL_ERRCODE(env, helperProxy != nullptr && status == napi_ok,
139             ctxInfo->error = std::make_shared<DataShareHelperInitError>(), napi_generic_failure);
140         napi_create_reference(env, helperProxy, 1, &(ctxInfo->ref));
141         ctxInfo->env = env;
142         return napi_ok;
143     };
144     auto output = [ctxInfo](napi_env env, napi_value *result) -> napi_status {
145         NAPI_ASSERT_CALL_ERRCODE(env, ctxInfo->dataShareHelper != nullptr,
146             ctxInfo->error = std::make_shared<DataShareHelperInitError>(), napi_generic_failure);
147         napi_status status = napi_get_reference_value(env, ctxInfo->ref, result);
148         NAPI_ASSERT_CALL_ERRCODE(env, result != nullptr,
149             ctxInfo->error = std::make_shared<DataShareHelperInitError>(), napi_generic_failure);
150         NapiDataShareHelper *proxy = nullptr;
151         status = napi_unwrap(env, *result, reinterpret_cast<void **>(&proxy));
152         NAPI_ASSERT_CALL_ERRCODE(env, proxy != nullptr, ctxInfo->error = std::make_shared<DataShareHelperInitError>(),
153             status);
154         proxy->jsRdbObsManager_ = std::make_shared<NapiRdbSubscriberManager>(ctxInfo->dataShareHelper);
155         proxy->jsPublishedObsManager_ = std::make_shared<NapiPublishedSubscriberManager>(ctxInfo->dataShareHelper);
156         proxy->datashareHelper_ = std::move(ctxInfo->dataShareHelper);
157         return status;
158     };
159     auto exec = [ctxInfo](AsyncCall::Context *ctx) {
160         if (ctxInfo->options.enabled_) {
161             ctxInfo->options.token_ = ctxInfo->contextS->GetToken();
162             ctxInfo->dataShareHelper = DataShareHelper::Creator(ctxInfo->strUri, ctxInfo->options);
163         } else {
164             ctxInfo->dataShareHelper = DataShareHelper::Creator(ctxInfo->contextS->GetToken(), ctxInfo->strUri);
165         }
166     };
167     ctxInfo->SetAction(std::move(input), std::move(output));
168     AsyncCall asyncCall(env, info, ctxInfo);
169     return asyncCall.Call(env, exec);
170 }
171 
GetConstructor(napi_env env)172 napi_value NapiDataShareHelper::GetConstructor(napi_env env)
173 {
174     napi_value cons = nullptr;
175     napi_property_descriptor clzDes[] = {
176         DECLARE_NAPI_FUNCTION("on", Napi_On),
177         DECLARE_NAPI_FUNCTION("off", Napi_Off),
178         DECLARE_NAPI_FUNCTION("insert", Napi_Insert),
179         DECLARE_NAPI_FUNCTION("delete", Napi_Delete),
180         DECLARE_NAPI_FUNCTION("query", Napi_Query),
181         DECLARE_NAPI_FUNCTION("update", Napi_Update),
182         DECLARE_NAPI_FUNCTION("batchInsert", Napi_BatchInsert),
183         DECLARE_NAPI_FUNCTION("normalizeUri", Napi_NormalizeUri),
184         DECLARE_NAPI_FUNCTION("denormalizeUri", Napi_DenormalizeUri),
185         DECLARE_NAPI_FUNCTION("notifyChange", Napi_NotifyChange),
186         DECLARE_NAPI_FUNCTION("addTemplate", Napi_AddTemplate),
187         DECLARE_NAPI_FUNCTION("delTemplate", Napi_DelTemplate),
188         DECLARE_NAPI_FUNCTION("publish", Napi_Publish),
189         DECLARE_NAPI_FUNCTION("getPublishedData", Napi_GetPublishedData),
190     };
191     NAPI_CALL(env, napi_define_class(env, "DataShareHelper", NAPI_AUTO_LENGTH, Initialize, nullptr,
192         sizeof(clzDes) / sizeof(napi_property_descriptor), clzDes, &cons));
193     return cons;
194 }
195 
Initialize(napi_env env,napi_callback_info info)196 napi_value NapiDataShareHelper::Initialize(napi_env env, napi_callback_info info)
197 {
198     LOG_DEBUG("Start");
199     napi_value self = nullptr;
200     size_t argc = ARGS_MAX_COUNT;
201     napi_value argv[ARGS_MAX_COUNT] = {nullptr};
202     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
203     if (argc <= 1) {
204         LOG_ERROR("Parameters error, need at least 2 parameters!");
205         return nullptr;
206     }
207     auto *proxy = new (std::nothrow) NapiDataShareHelper();
208     if (proxy == nullptr) {
209         return nullptr;
210     }
211     auto finalize = [](napi_env env, void *data, void *hint) {
212         NapiDataShareHelper *proxy = reinterpret_cast<NapiDataShareHelper *>(data);
213         delete proxy;
214     };
215     if (napi_wrap(env, self, proxy, finalize, nullptr, nullptr) != napi_ok) {
216         finalize(env, proxy, nullptr);
217         return nullptr;
218     }
219     return self;
220 }
221 
Napi_OpenFile(napi_env env,napi_callback_info info)222 napi_value NapiDataShareHelper::Napi_OpenFile(napi_env env, napi_callback_info info)
223 {
224     auto context = std::make_shared<ContextInfo>();
225     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
226         NAPI_ASSERT_BASE(env, argc == 2 || argc == 3, " should 2 or 3 parameters!", napi_invalid_arg);
227         LOG_DEBUG("argc : %{public}d", static_cast<int>(argc));
228 
229         GetUri(env, argv[0], context->uri);
230 
231         napi_valuetype valuetype = napi_undefined;
232         napi_typeof(env, argv[1], &valuetype);
233         if (valuetype == napi_string) {
234             context->mode = DataShareJSUtils::Convert2String(env, argv[1]);
235         } else {
236             LOG_ERROR("wrong type, should be napi_string");
237         }
238         return napi_ok;
239     };
240     auto output = [context](napi_env env, napi_value *result) -> napi_status {
241         napi_create_int32(env, context->resultNumber, result);
242         return napi_ok;
243     };
244     auto exec = [context](AsyncCall::Context *ctx) {
245         if (context->proxy->datashareHelper_ != nullptr && !context->uri.empty()) {
246             OHOS::Uri uri(context->uri);
247             context->resultNumber = context->proxy->datashareHelper_->OpenFile(uri, context->mode);
248             context->status = napi_ok;
249         } else {
250             LOG_ERROR("dataShareHelper_ is nullptr : %{public}d, context->uri is empty : %{public}d",
251                 context->proxy->datashareHelper_ == nullptr, context->uri.empty());
252         }
253     };
254     context->SetAction(std::move(input), std::move(output));
255     AsyncCall asyncCall(env, info, context);
256     return asyncCall.Call(env, exec);
257 }
258 
Napi_Insert(napi_env env,napi_callback_info info)259 napi_value NapiDataShareHelper::Napi_Insert(napi_env env, napi_callback_info info)
260 {
261     auto context = std::make_shared<ContextInfo>();
262     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
263         if (argc != 2 && argc != 3) {
264             context->error = std::make_shared<ParametersNumError>("2 or 3");
265             return napi_invalid_arg;
266         }
267 
268         if (!GetUri(env, argv[0], context->uri)) {
269             context->error = std::make_shared<ParametersTypeError>("uri", "string");
270             return napi_invalid_arg;
271         }
272 
273         context->valueBucket.Clear();
274         if (!GetValueBucketObject(context->valueBucket, env, argv[1])) {
275             context->error = std::make_shared<ParametersTypeError>("valueBucket",
276                 "[string|number|boolean|null|Uint8Array]");
277             return napi_invalid_arg;
278         }
279 
280         return napi_ok;
281     };
282     auto output = [context](napi_env env, napi_value *result) -> napi_status {
283         if (context->resultNumber < 0) {
284             context->error = std::make_shared<InnerError>();
285             return napi_generic_failure;
286         }
287         napi_create_int32(env, context->resultNumber, result);
288         return napi_ok;
289     };
290     auto exec = [context](AsyncCall::Context *ctx) {
291         if (context->proxy->datashareHelper_ != nullptr && !context->uri.empty()) {
292             OHOS::Uri uri(context->uri);
293             context->resultNumber = context->proxy->datashareHelper_->Insert(uri, context->valueBucket);
294             context->status = napi_ok;
295         } else {
296             LOG_ERROR("dataShareHelper_ is nullptr : %{public}d, context->uri is empty : %{public}d",
297                 context->proxy->datashareHelper_ == nullptr, context->uri.empty());
298         }
299     };
300     context->SetAction(std::move(input), std::move(output));
301     AsyncCall asyncCall(env, info, context);
302     return asyncCall.Call(env, exec);
303 }
304 
Napi_Delete(napi_env env,napi_callback_info info)305 napi_value NapiDataShareHelper::Napi_Delete(napi_env env, napi_callback_info info)
306 {
307     auto context = std::make_shared<ContextInfo>();
308     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
309         if (argc != 2 && argc != 3) {
310             context->error = std::make_shared<ParametersNumError>("2 or 3");
311             return napi_invalid_arg;
312         }
313 
314         if (!GetUri(env, argv[0], context->uri)) {
315             context->error = std::make_shared<ParametersTypeError>("uri", "string");
316             return napi_invalid_arg;
317         }
318 
319         context->predicates = UnwrapDataSharePredicates(env, argv[1]);
320         return napi_ok;
321     };
322     auto output = [context](napi_env env, napi_value *result) -> napi_status {
323         if (context->resultNumber < 0) {
324             context->error = std::make_shared<InnerError>();
325             return napi_generic_failure;
326         }
327         napi_create_int32(env, context->resultNumber, result);
328         return napi_ok;
329     };
330     auto exec = [context](AsyncCall::Context *ctx) {
331         if (context->proxy->datashareHelper_ != nullptr && !context->uri.empty()) {
332             OHOS::Uri uri(context->uri);
333             context->resultNumber = context->proxy->datashareHelper_->Delete(uri, context->predicates);
334             context->status = napi_ok;
335         } else {
336             LOG_ERROR("dataShareHelper_ is nullptr : %{public}d, context->uri is empty : %{public}d",
337                 context->proxy->datashareHelper_ == nullptr, context->uri.empty());
338         }
339     };
340     context->SetAction(std::move(input), std::move(output));
341     AsyncCall asyncCall(env, info, context);
342     return asyncCall.Call(env, exec);
343 }
344 
Napi_Query(napi_env env,napi_callback_info info)345 napi_value NapiDataShareHelper::Napi_Query(napi_env env, napi_callback_info info)
346 {
347     auto context = std::make_shared<ContextInfo>();
348     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
349         if (argc != 3 && argc != 4) {
350             context->error = std::make_shared<ParametersNumError>("3 or 4");
351             return napi_invalid_arg;
352         }
353 
354         if (!GetUri(env, argv[0], context->uri)) {
355             context->error = std::make_shared<ParametersTypeError>("uri", "string");
356             return napi_invalid_arg;
357         }
358 
359         context->predicates = UnwrapDataSharePredicates(env, argv[1]);
360 
361         context->columns = DataShareJSUtils::Convert2StrVector(env, argv[2], DataShareJSUtils::DEFAULT_BUF_SIZE);
362         return napi_ok;
363     };
364     auto output = [context](napi_env env, napi_value *result) -> napi_status {
365         if (context->businessError.GetCode() != 0) {
366             LOG_DEBUG("query failed, errorCode : %{public}d", context->businessError.GetCode());
367             context->error = std::make_shared<BusinessError>(context->businessError.GetCode(),
368                 context->businessError.GetMessage());
369             return napi_generic_failure;
370         }
371 
372         if (context->resultObject == nullptr) {
373             context->error = std::make_shared<InnerError>();
374             return napi_generic_failure;
375         }
376         *result = DataShareResultSetProxy::NewInstance(env, context->resultObject);
377         context->resultObject = nullptr;
378         return napi_ok;
379     };
380     auto exec = [context](AsyncCall::Context *ctx) {
381         if (context->proxy->datashareHelper_ != nullptr && !context->uri.empty()) {
382             OHOS::Uri uri(context->uri);
383             context->resultObject = context->proxy->datashareHelper_->Query(uri,
384                 context->predicates, context->columns, &(context->businessError));
385             context->status = napi_ok;
386         } else {
387             LOG_ERROR("dataShareHelper_ is nullptr : %{public}d, context->uri is empty : %{public}d",
388                 context->proxy->datashareHelper_ == nullptr, context->uri.empty());
389         }
390     };
391     context->SetAction(std::move(input), std::move(output));
392     AsyncCall asyncCall(env, info, context);
393     return asyncCall.Call(env, exec);
394 }
395 
Napi_Update(napi_env env,napi_callback_info info)396 napi_value NapiDataShareHelper::Napi_Update(napi_env env, napi_callback_info info)
397 {
398     auto context = std::make_shared<ContextInfo>();
399     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
400         if (argc != 3 && argc != 4) {
401             context->error = std::make_shared<ParametersNumError>("3 or 4");
402             return napi_invalid_arg;
403         }
404 
405         if (!GetUri(env, argv[0], context->uri)) {
406             context->error = std::make_shared<ParametersTypeError>("uri", "string");
407             return napi_invalid_arg;
408         }
409 
410         context->predicates = UnwrapDataSharePredicates(env, argv[1]);
411 
412         context->valueBucket.Clear();
413         if (!GetValueBucketObject(context->valueBucket, env, argv[2])) {
414             context->error = std::make_shared<ParametersTypeError>("valueBucket",
415                 "[string|number|boolean|null|Uint8Array]");
416             return napi_invalid_arg;
417         }
418         return napi_ok;
419     };
420     auto output = [context](napi_env env, napi_value *result) -> napi_status {
421         if (context->resultNumber < 0) {
422             context->error = std::make_shared<InnerError>();
423             return napi_generic_failure;
424         }
425         napi_create_int32(env, context->resultNumber, result);
426         return napi_ok;
427     };
428     auto exec = [context](AsyncCall::Context *ctx) {
429         if (context->proxy->datashareHelper_ != nullptr && !context->uri.empty()) {
430             OHOS::Uri uri(context->uri);
431             context->resultNumber =
432                 context->proxy->datashareHelper_->Update(uri, context->predicates, context->valueBucket);
433             context->status = napi_ok;
434         } else {
435             LOG_ERROR("dataShareHelper_ is nullptr : %{public}d, context->uri is empty : %{public}d",
436                 context->proxy->datashareHelper_ == nullptr, context->uri.empty());
437         }
438     };
439     context->SetAction(std::move(input), std::move(output));
440     AsyncCall asyncCall(env, info, context);
441     return asyncCall.Call(env, exec);
442 }
443 
Napi_BatchInsert(napi_env env,napi_callback_info info)444 napi_value NapiDataShareHelper::Napi_BatchInsert(napi_env env, napi_callback_info info)
445 {
446     auto context = std::make_shared<ContextInfo>();
447     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
448         if (argc != 2 && argc != 3) {
449             context->error = std::make_shared<ParametersNumError>("2 or 3");
450             return napi_invalid_arg;
451         }
452 
453         if (!GetUri(env, argv[0], context->uri)) {
454             context->error = std::make_shared<ParametersTypeError>("uri", "string");
455             return napi_invalid_arg;
456         }
457         bool status = false;
458         context->values = GetValuesBucketArray(env, argv[1], status);
459         if (!status) {
460             context->error = std::make_shared<ParametersTypeError>("valueBucket",
461                 "[string|number|boolean|null|Uint8Array]");
462             return napi_invalid_arg;
463         }
464         return napi_ok;
465     };
466     auto output = [context](napi_env env, napi_value *result) -> napi_status {
467         if (context->resultNumber < 0) {
468             context->error = std::make_shared<InnerError>();
469             return napi_generic_failure;
470         }
471         napi_create_int32(env, context->resultNumber, result);
472         return napi_ok;
473     };
474     auto exec = [context](AsyncCall::Context *ctx) {
475         if (context->proxy->datashareHelper_ != nullptr && !context->uri.empty()) {
476             OHOS::Uri uri(context->uri);
477             context->resultNumber = context->proxy->datashareHelper_->BatchInsert(uri, context->values);
478             context->status = napi_ok;
479         } else {
480             LOG_ERROR("dataShareHelper_ is nullptr : %{public}d, context->uri is empty : %{public}d",
481                 context->proxy->datashareHelper_ == nullptr, context->uri.empty());
482         }
483     };
484     context->SetAction(std::move(input), std::move(output));
485     AsyncCall asyncCall(env, info, context);
486     return asyncCall.Call(env, exec);
487 }
488 
Napi_GetType(napi_env env,napi_callback_info info)489 napi_value NapiDataShareHelper::Napi_GetType(napi_env env, napi_callback_info info)
490 {
491     auto context = std::make_shared<ContextInfo>();
492     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
493         NAPI_ASSERT_BASE(env, argc == 1 || argc == 2, " should 1 or 2 parameters!", napi_invalid_arg);
494 
495         GetUri(env, argv[0], context->uri);
496         return napi_ok;
497     };
498     auto output = [context](napi_env env, napi_value *result) -> napi_status {
499         napi_create_string_utf8(env, context->resultString.c_str(), NAPI_AUTO_LENGTH, result);
500         return napi_ok;
501     };
502     auto exec = [context](AsyncCall::Context *ctx) {
503         if (context->proxy->datashareHelper_ != nullptr && !context->uri.empty()) {
504             OHOS::Uri uri(context->uri);
505             context->resultString = context->proxy->datashareHelper_->GetType(uri);
506             context->status = napi_ok;
507         } else {
508             LOG_ERROR("dataShareHelper_ is nullptr : %{public}d, context->uri is empty : %{public}d",
509                 context->proxy->datashareHelper_ == nullptr, context->uri.empty());
510         }
511     };
512     context->SetAction(std::move(input), std::move(output));
513     AsyncCall asyncCall(env, info, context);
514     return asyncCall.Call(env, exec);
515 }
516 
Napi_GetFileTypes(napi_env env,napi_callback_info info)517 napi_value NapiDataShareHelper::Napi_GetFileTypes(napi_env env, napi_callback_info info)
518 {
519     auto context = std::make_shared<ContextInfo>();
520     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
521         NAPI_ASSERT_BASE(env, argc == 2 || argc == 3, " should 2 or 3 parameters!", napi_invalid_arg);
522 
523         GetUri(env, argv[0], context->uri);
524 
525         napi_valuetype valuetype = napi_undefined;
526         napi_typeof(env, argv[1], &valuetype);
527         if (valuetype == napi_string) {
528             context->mimeTypeFilter = DataShareJSUtils::Convert2String(env, argv[1]);
529         } else {
530             LOG_ERROR("wrong type, should be napi_string");
531         }
532         return napi_ok;
533     };
534     auto output = [context](napi_env env, napi_value *result) -> napi_status {
535         *result = DataShareJSUtils::Convert2JSValue(env, context->resultStrArr);
536         return napi_ok;
537     };
538     auto exec = [context](AsyncCall::Context *ctx) {
539         if (context->proxy->datashareHelper_ != nullptr && !context->uri.empty()) {
540             OHOS::Uri uri(context->uri);
541             context->resultStrArr = context->proxy->datashareHelper_->GetFileTypes(uri, context->mimeTypeFilter);
542             context->status = napi_ok;
543         } else {
544             LOG_ERROR("dataShareHelper_ is nullptr : %{public}d, context->uri is empty : %{public}d",
545                 context->proxy->datashareHelper_ == nullptr, context->uri.empty());
546         }
547     };
548     context->SetAction(std::move(input), std::move(output));
549     AsyncCall asyncCall(env, info, context);
550     return asyncCall.Call(env, exec);
551 }
552 
Napi_NormalizeUri(napi_env env,napi_callback_info info)553 napi_value NapiDataShareHelper::Napi_NormalizeUri(napi_env env, napi_callback_info info)
554 {
555     auto context = std::make_shared<ContextInfo>();
556     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
557         NAPI_ASSERT_BASE(env, argc == 1 || argc == 2, " should 1 or 2 parameters!", napi_invalid_arg);
558 
559         GetUri(env, argv[0], context->uri);
560         return napi_ok;
561     };
562     auto output = [context](napi_env env, napi_value *result) -> napi_status {
563         napi_create_string_utf8(env, context->resultString.c_str(), NAPI_AUTO_LENGTH, result);
564         return napi_ok;
565     };
566     auto exec = [context](AsyncCall::Context *ctx) {
567         if (context->proxy->datashareHelper_ != nullptr && !context->uri.empty()) {
568             OHOS::Uri uri(context->uri);
569             Uri uriValue = context->proxy->datashareHelper_->NormalizeUri(uri);
570             context->resultString = uriValue.ToString();
571             context->status = napi_ok;
572         } else {
573             LOG_ERROR("dataShareHelper_ is nullptr : %{public}d, context->uri is empty : %{public}d",
574                 context->proxy->datashareHelper_ == nullptr, context->uri.empty());
575         }
576     };
577     context->SetAction(std::move(input), std::move(output));
578     AsyncCall asyncCall(env, info, context);
579     return asyncCall.Call(env, exec);
580 }
581 
Napi_DenormalizeUri(napi_env env,napi_callback_info info)582 napi_value NapiDataShareHelper::Napi_DenormalizeUri(napi_env env, napi_callback_info info)
583 {
584     auto context = std::make_shared<ContextInfo>();
585     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
586         NAPI_ASSERT_BASE(env, argc == 1 || argc == 2, " should 1 or 2 parameters!", napi_invalid_arg);
587 
588         GetUri(env, argv[0], context->uri);
589         return napi_ok;
590     };
591     auto output = [context](napi_env env, napi_value *result) -> napi_status {
592         napi_create_string_utf8(env, context->resultString.c_str(), NAPI_AUTO_LENGTH, result);
593         return napi_ok;
594     };
595     auto exec = [context](AsyncCall::Context *ctx) {
596         if (context->proxy->datashareHelper_ != nullptr && !context->uri.empty()) {
597             OHOS::Uri uri(context->uri);
598             Uri uriValue = context->proxy->datashareHelper_->DenormalizeUri(uri);
599             context->resultString = uriValue.ToString();
600             context->status = napi_ok;
601         } else {
602             LOG_ERROR("dataShareHelper_ is nullptr : %{public}d, context->uri is empty : %{public}d",
603                 context->proxy->datashareHelper_ == nullptr, context->uri.empty());
604         }
605     };
606     context->SetAction(std::move(input), std::move(output));
607     AsyncCall asyncCall(env, info, context);
608     return asyncCall.Call(env, exec);
609 }
610 
Napi_NotifyChange(napi_env env,napi_callback_info info)611 napi_value NapiDataShareHelper::Napi_NotifyChange(napi_env env, napi_callback_info info)
612 {
613     auto context = std::make_shared<ContextInfo>();
614     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
615         NAPI_ASSERT_BASE(env, argc == 1 || argc == 2, " should 1 or 2 parameters!", napi_invalid_arg);
616 
617         GetUri(env, argv[0], context->uri);
618         return napi_ok;
619     };
620     auto output = [context](napi_env env, napi_value *result) -> napi_status {
621         napi_get_null(env, result);
622         return napi_ok;
623     };
624     auto exec = [context](AsyncCall::Context *ctx) {
625         if (context->proxy->datashareHelper_ != nullptr && !context->uri.empty()) {
626             OHOS::Uri uri(context->uri);
627             context->proxy->datashareHelper_->NotifyChange(uri);
628             context->status = napi_ok;
629         } else {
630             LOG_ERROR("dataShareHelper_ is nullptr : %{public}d, context->uri is empty : %{public}d",
631                 context->proxy->datashareHelper_ == nullptr, context->uri.empty());
632         }
633     };
634     context->SetAction(std::move(input), std::move(output));
635     AsyncCall asyncCall(env, info, context);
636     return asyncCall.Call(env, exec);
637 }
638 
Napi_AddTemplate(napi_env env,napi_callback_info info)639 napi_value NapiDataShareHelper::Napi_AddTemplate(napi_env env, napi_callback_info info)
640 {
641     napi_value self = nullptr;
642     size_t argc = MAX_ARGC;
643     napi_value argv[MAX_ARGC] = { nullptr };
644     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
645     std::shared_ptr<Error> error = nullptr;
646     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, argc == ARGS_THREE, error = std::make_shared<ParametersNumError>("3"), error,
647         nullptr);
648 
649     NapiDataShareHelper *proxy = nullptr;
650     NAPI_CALL_BASE(env, napi_unwrap(env, self, reinterpret_cast<void **>(&proxy)), nullptr);
651     NAPI_ASSERT_BASE(env, proxy != nullptr, "there is no NapiDataShareHelper instance", nullptr);
652     NAPI_ASSERT_BASE(env, proxy->datashareHelper_ != nullptr, "there is no DataShareHelper instance", nullptr);
653 
654     napi_valuetype valueType;
655     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
656     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_string,
657         error = std::make_shared<ParametersTypeError>("uri", "string"), error, nullptr);
658     std::string uri = DataShareJSUtils::Convert2String(env, argv[0]);
659     NAPI_ASSERT_BASE(env, !uri.empty(), "convert uri failed", nullptr);
660 
661     NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
662     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_string,
663         error = std::make_shared<ParametersTypeError>("subscriberId", "string"), error, nullptr);
664     std::string subscriberId = DataShareJSUtils::Convert2String(env, argv[1]);
665 
666     NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valueType));
667     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_object,
668         error = std::make_shared<ParametersTypeError>("template", "Template"), error, nullptr);
669     Template tpl = DataShareJSUtils::Convert2Template(env, argv[PARAM2]);
670 
671     auto res = proxy->datashareHelper_->AddQueryTemplate(uri, atoll(subscriberId.c_str()), tpl);
672     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, res != E_URI_NOT_EXIST && res != E_BUNDLE_NAME_NOT_EXIST,
673         error = std::make_shared<UriNotExistError>(), error, nullptr);
674     return DataShareJSUtils::Convert2JSValue(env, res);
675 }
676 
Napi_DelTemplate(napi_env env,napi_callback_info info)677 napi_value NapiDataShareHelper::Napi_DelTemplate(napi_env env, napi_callback_info info)
678 {
679     napi_value self = nullptr;
680     size_t argc = MAX_ARGC;
681     napi_value argv[MAX_ARGC] = { nullptr };
682     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
683     std::shared_ptr<Error> error = nullptr;
684     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, argc == ARGS_TWO, error = std::make_shared<ParametersNumError>("2"), error,
685         nullptr);
686 
687     NapiDataShareHelper *proxy = nullptr;
688     NAPI_CALL_BASE(env, napi_unwrap(env, self, reinterpret_cast<void **>(&proxy)), nullptr);
689     NAPI_ASSERT_BASE(env, proxy != nullptr, "there is no NapiDataShareHelper instance", nullptr);
690     NAPI_ASSERT_BASE(env, proxy->datashareHelper_ != nullptr, "there is no DataShareHelper instance", nullptr);
691 
692     napi_valuetype valueType;
693     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
694     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_string,
695         error = std::make_shared<ParametersTypeError>("uri", "string"), error, nullptr);
696     std::string uri = DataShareJSUtils::Convert2String(env, argv[0]);
697     NAPI_ASSERT_BASE(env, !uri.empty(), "convert uri failed", nullptr);
698 
699     NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
700     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_string,
701         error = std::make_shared<ParametersTypeError>("subscriberId", "string"), error, nullptr);
702     std::string subscriberId = DataShareJSUtils::Convert2String(env, argv[1]);
703 
704     auto res = proxy->datashareHelper_->DelQueryTemplate(uri, atoll(subscriberId.c_str()));
705     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, res != E_URI_NOT_EXIST && res != E_BUNDLE_NAME_NOT_EXIST,
706         error = std::make_shared<UriNotExistError>(), error, nullptr);
707     return DataShareJSUtils::Convert2JSValue(env, res);
708 }
709 
Napi_Publish(napi_env env,napi_callback_info info)710 napi_value NapiDataShareHelper::Napi_Publish(napi_env env, napi_callback_info info)
711 {
712     auto context = std::make_shared<ContextInfo>();
713     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
714         if (argc != 2 && argc != 3 && argc != 4) {
715             context->error = std::make_shared<ParametersNumError>("2 or 3 or 4");
716             return napi_invalid_arg;
717         }
718         napi_valuetype valueType;
719         NAPI_CALL_BASE(env, napi_typeof(env, argv[0], &valueType), napi_invalid_arg);
720         NAPI_ASSERT_CALL_ERRCODE(env, valueType == napi_object,
721             context->error = std::make_shared<ParametersTypeError>("data", "Data"), napi_invalid_arg);
722         NAPI_CALL_BASE(env, napi_typeof(env, argv[1], &valueType), napi_invalid_arg);
723         NAPI_ASSERT_CALL_ERRCODE(env, valueType == napi_string,
724             context->error = std::make_shared<ParametersTypeError>("bundleName", "string"), napi_invalid_arg);
725         context->publishData = DataShareJSUtils::Convert2PublishedData(env, argv[0]);
726         context->bundleName = DataShareJSUtils::Convert2String(env, argv[1]);
727         if (argc > 2) {
728             NAPI_CALL_BASE(env, napi_typeof(env, argv[PARAM2], &valueType), napi_invalid_arg);
729             if (valueType == napi_number) {
730                 napi_get_value_int32(env, argv[PARAM2], &(context->publishData.version_));
731             }
732         }
733         return napi_ok;
734     };
735     auto output = [context](napi_env env, napi_value *result) -> napi_status {
736         NAPI_ASSERT_BASE(env, context->status == napi_ok, "exec failed", napi_generic_failure);
737         for (auto &operationResult : context->results) {
738             if (operationResult.errCode_ == E_BUNDLE_NAME_NOT_EXIST) {
739                 context->error = std::make_shared<DataAreaNotExistError>();
740                 return napi_generic_failure;
741             }
742         }
743         *result = DataShareJSUtils::Convert2JSValue(env, context->results);
744         context->results.clear();
745         return napi_ok;
746     };
747     auto exec = [context](AsyncCall::Context *ctx) {
748         if (context->proxy->datashareHelper_ == nullptr) {
749             LOG_ERROR("dataShareHelper_ is nullptr");
750             return;
751         }
752         context->results =
753             context->proxy->datashareHelper_->Publish(context->publishData, context->bundleName);
754         context->status = napi_ok;
755     };
756     context->SetAction(std::move(input), std::move(output));
757     AsyncCall asyncCall(env, info, context);
758     return asyncCall.Call(env, exec);
759 }
760 
Napi_GetPublishedData(napi_env env,napi_callback_info info)761 napi_value NapiDataShareHelper::Napi_GetPublishedData(napi_env env, napi_callback_info info)
762 {
763     auto context = std::make_shared<ContextInfo>();
764     auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> napi_status {
765         if (argc != 1 && argc != 2) {
766             context->error = std::make_shared<ParametersNumError>("1 or 2");
767             return napi_invalid_arg;
768         }
769         napi_valuetype valueType;
770         NAPI_CALL_BASE(env, napi_typeof(env, argv[0], &valueType), napi_invalid_arg);
771         NAPI_ASSERT_CALL_ERRCODE(env, valueType == napi_string,
772             context->error = std::make_shared<ParametersTypeError>("bundleName", "string"), napi_invalid_arg);
773         context->bundleName = DataShareJSUtils::Convert2String(env, argv[0]);
774         return napi_ok;
775     };
776     auto output = [context](napi_env env, napi_value *result) -> napi_status {
777         NAPI_ASSERT_BASE(env, context->status == napi_ok, "exec failed", napi_generic_failure);
778         if (context->resultNumber == E_BUNDLE_NAME_NOT_EXIST) {
779             context->error = std::make_shared<DataAreaNotExistError>();
780             return napi_generic_failure;
781         }
782         *result = DataShareJSUtils::Convert2JSValue(env, context->publishData.datas_);
783         return napi_ok;
784     };
785     auto exec = [context](AsyncCall::Context *ctx) {
786         if (context->proxy->datashareHelper_ == nullptr) {
787             LOG_ERROR("dataShareHelper_ is nullptr");
788             return;
789         }
790         context->publishData = context->proxy->datashareHelper_->GetPublishedData(context->bundleName,
791             context->resultNumber);
792         context->status = napi_ok;
793     };
794     context->SetAction(std::move(input), std::move(output));
795     AsyncCall asyncCall(env, info, context);
796     return asyncCall.Call(env, exec);
797 }
798 
Napi_On(napi_env env,napi_callback_info info)799 napi_value NapiDataShareHelper::Napi_On(napi_env env, napi_callback_info info)
800 {
801     napi_value self = nullptr;
802     size_t argc = MAX_ARGC;
803     napi_value argv[MAX_ARGC] = { nullptr };
804     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
805     NAPI_ASSERT(env, argc == ARGS_THREE || argc == ARGS_FOUR, "wrong count of args");
806 
807     napi_valuetype valueType;
808     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
809     if (valueType != napi_string) {
810         LOG_ERROR("type is not string");
811         return nullptr;
812     }
813 
814     std::string type = DataShareJSUtils::Convert2String(env, argv[0]);
815     if (type == "rdbDataChange") {
816         return Napi_SubscribeRdbObserver(env, argc, argv, self);
817     } else if (type == "publishedDataChange") {
818         return Napi_SubscribePublishedObserver(env, argc, argv, self);
819     }
820     if (type != "dataChange") {
821         LOG_ERROR("wrong register type : %{public}s", type.c_str());
822         return nullptr;
823     }
824 
825     NapiDataShareHelper *proxy = nullptr;
826     NAPI_CALL_BASE(env, napi_unwrap(env, self, reinterpret_cast<void **>(&proxy)), nullptr);
827     NAPI_ASSERT_BASE(env, proxy != nullptr, "there is no NapiDataShareHelper instance", nullptr);
828     NAPI_ASSERT_BASE(env, proxy->datashareHelper_ != nullptr, "there is no DataShareHelper instance", nullptr);
829 
830     NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
831     NAPI_ASSERT_BASE(env, valueType == napi_string, "uri is not string", nullptr);
832     std::string uri = DataShareJSUtils::Convert2String(env, argv[1]);
833 
834     NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valueType));
835     NAPI_ASSERT_BASE(env, valueType == napi_function, "callback is not a function", nullptr);
836 
837     proxy->RegisteredObserver(env, uri, argv[PARAM2]);
838     return nullptr;
839 }
840 
Napi_Off(napi_env env,napi_callback_info info)841 napi_value NapiDataShareHelper::Napi_Off(napi_env env, napi_callback_info info)
842 {
843     napi_value self = nullptr;
844     size_t argc = MAX_ARGC;
845     napi_value argv[MAX_ARGC] = { nullptr };
846     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &self, nullptr));
847     NAPI_ASSERT(env, argc == ARGS_TWO || argc == ARGS_THREE || argc == ARGS_FOUR, "wrong count of args");
848 
849     napi_valuetype valueType;
850     NAPI_CALL(env, napi_typeof(env, argv[0], &valueType));
851     if (valueType != napi_string) {
852         LOG_ERROR("type is not string");
853         return nullptr;
854     }
855 
856     std::string type = DataShareJSUtils::Convert2String(env, argv[0]);
857     if (type == "rdbDataChange") {
858         return Napi_UnsubscribeRdbObserver(env, argc, argv, self);
859     } else if (type == "publishedDataChange") {
860         return Napi_UnsubscribePublishedObserver(env, argc, argv, self);
861     }
862     if (type != "dataChange") {
863         LOG_ERROR("wrong register type : %{public}s", type.c_str());
864         return nullptr;
865     }
866 
867     NapiDataShareHelper *proxy = nullptr;
868     NAPI_CALL_BASE(env, napi_unwrap(env, self, reinterpret_cast<void **>(&proxy)), nullptr);
869     NAPI_ASSERT_BASE(env, proxy != nullptr, "there is no NapiDataShareHelper instance", nullptr);
870     NAPI_ASSERT_BASE(env, proxy->datashareHelper_ != nullptr, "there is no DataShareHelper instance", nullptr);
871 
872     NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
873     NAPI_ASSERT_BASE(env, valueType == napi_string, "uri is not string", nullptr);
874     std::string uri = DataShareJSUtils::Convert2String(env, argv[1]);
875 
876     if (argc == ARGS_THREE) {
877         NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valueType));
878         NAPI_ASSERT_BASE(env, valueType == napi_function, "callback is not a function", nullptr);
879         proxy->UnRegisteredObserver(env, uri, argv[PARAM2]);
880         return nullptr;
881     }
882     proxy->UnRegisteredObserver(env, uri);
883     return nullptr;
884 }
885 
HasRegisteredObserver(napi_env env,std::list<sptr<NAPIDataShareObserver>> & list,napi_value callback)886 bool NapiDataShareHelper::HasRegisteredObserver(napi_env env, std::list<sptr<NAPIDataShareObserver>> &list,
887     napi_value callback)
888 {
889     for (auto &it : list) {
890         if (DataShareJSUtils::Equals(env, callback, it->observer_->GetCallback())) {
891             LOG_DEBUG("The observer has already subscribed.");
892             return true;
893         }
894     }
895     return false;
896 }
897 
RegisteredObserver(napi_env env,const std::string & uri,napi_value callback)898 void NapiDataShareHelper::RegisteredObserver(napi_env env, const std::string &uri, napi_value callback)
899 {
900     std::lock_guard<std::mutex> lck(listMutex_);
901     observerMap_.try_emplace(uri);
902 
903     auto &list = observerMap_.find(uri)->second;
904     if (HasRegisteredObserver(env, list, callback)) {
905         LOG_DEBUG("has registered observer");
906         return;
907     }
908     auto innerObserver = std::make_shared<NAPIInnerObserver>(env, callback);
909     sptr<NAPIDataShareObserver> observer(new (std::nothrow) NAPIDataShareObserver(innerObserver));
910     if (observer == nullptr) {
911         LOG_ERROR("observer is nullptr");
912         return;
913     }
914     datashareHelper_->RegisterObserver(Uri(uri), observer);
915     list.push_back(observer);
916 }
917 
UnRegisteredObserver(napi_env env,const std::string & uri,napi_value callback)918 void NapiDataShareHelper::UnRegisteredObserver(napi_env env, const std::string &uri, napi_value callback)
919 {
920     std::lock_guard<std::mutex> lck(listMutex_);
921     auto obs = observerMap_.find(uri);
922     if (obs == observerMap_.end()) {
923         LOG_DEBUG("this uri hasn't been registered");
924         return;
925     }
926     auto &list = obs->second;
927     auto it = list.begin();
928     while (it != list.end()) {
929         if (!DataShareJSUtils::Equals(env, callback, (*it)->observer_->GetCallback())) {
930             ++it;
931             continue;
932         }
933         datashareHelper_->UnregisterObserver(Uri(uri), *it);
934         (*it)->observer_->DeleteReference();
935         it = list.erase(it);
936         break;
937     }
938     if (list.empty()) {
939         observerMap_.erase(uri);
940     }
941 }
942 
UnRegisteredObserver(napi_env env,const std::string & uri)943 void NapiDataShareHelper::UnRegisteredObserver(napi_env env, const std::string &uri)
944 {
945     std::lock_guard<std::mutex> lck(listMutex_);
946     auto obs = observerMap_.find(uri);
947     if (obs == observerMap_.end()) {
948         LOG_DEBUG("this uri hasn't been registered");
949         return;
950     }
951     auto &list = obs->second;
952     auto it = list.begin();
953     while (it != list.end()) {
954         datashareHelper_->UnregisterObserver(Uri(uri), *it);
955         (*it)->observer_->DeleteReference();
956         it = list.erase(it);
957     }
958     observerMap_.erase(uri);
959 }
960 
Napi_SubscribeRdbObserver(napi_env env,size_t argc,napi_value * argv,napi_value self)961 napi_value NapiDataShareHelper::Napi_SubscribeRdbObserver(napi_env env, size_t argc, napi_value *argv, napi_value self)
962 {
963     std::vector<OperationResult> results;
964     napi_value jsResults = DataShareJSUtils::Convert2JSValue(env, results);
965     std::shared_ptr<Error> error = nullptr;
966     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, argc == ARGS_FOUR, error = std::make_shared<ParametersNumError>("4"), error,
967         jsResults);
968 
969     NapiDataShareHelper *proxy = nullptr;
970     NAPI_CALL_BASE(env, napi_unwrap(env, self, reinterpret_cast<void **>(&proxy)), jsResults);
971     NAPI_ASSERT_BASE(env, proxy != nullptr, "there is no NapiDataShareHelper instance", jsResults);
972     NAPI_ASSERT_BASE(env, proxy->datashareHelper_ != nullptr, "there is no DataShareHelper instance", jsResults);
973 
974     napi_valuetype valueType;
975     NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
976     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_object,
977         error = std::make_shared<ParametersTypeError>("uris", "Array<String>"), error, jsResults);
978     std::vector<std::string> uris =
979         DataShareJSUtils::Convert2StrVector(env, argv[1], DataShareJSUtils::DEFAULT_BUF_SIZE);
980 
981     NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valueType));
982     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_object,
983         error = std::make_shared<ParametersTypeError>("templateId", "TemplateId"), error, jsResults);
984     TemplateId templateId = DataShareJSUtils::Convert2TemplateId(env, argv[PARAM2]);
985 
986     NAPI_CALL(env, napi_typeof(env, argv[PARAM3], &valueType));
987     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_function,
988         error = std::make_shared<ParametersTypeError>("callback", "function"), error, jsResults);
989 
990     if (proxy->jsRdbObsManager_ == nullptr) {
991         LOG_ERROR("proxy->jsManager_ is nullptr");
992         return jsResults;
993     }
994     results = proxy->jsRdbObsManager_->AddObservers(env, argv[PARAM3], uris, templateId);
995     return DataShareJSUtils::Convert2JSValue(env, results);
996 }
997 
Napi_UnsubscribeRdbObserver(napi_env env,size_t argc,napi_value * argv,napi_value self)998 napi_value NapiDataShareHelper::Napi_UnsubscribeRdbObserver(napi_env env, size_t argc, napi_value *argv,
999     napi_value self)
1000 {
1001     std::vector<OperationResult> results;
1002     napi_value jsResults = DataShareJSUtils::Convert2JSValue(env, results);
1003     std::shared_ptr<Error> error = nullptr;
1004     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, argc == ARGS_THREE || argc == ARGS_FOUR,
1005         error = std::make_shared<ParametersNumError>("3 or 4"), error, jsResults);
1006 
1007     NapiDataShareHelper *proxy = nullptr;
1008     NAPI_CALL_BASE(env, napi_unwrap(env, self, reinterpret_cast<void **>(&proxy)), jsResults);
1009     NAPI_ASSERT_BASE(env, proxy != nullptr, "there is no NapiDataShareHelper instance", jsResults);
1010     NAPI_ASSERT_BASE(env, proxy->datashareHelper_ != nullptr, "there is no DataShareHelper instance", jsResults);
1011 
1012     napi_valuetype valueType;
1013     NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
1014     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_object,
1015         error = std::make_shared<ParametersTypeError>("uris", "Array<String>"), error, jsResults);
1016     std::vector<std::string> uris =
1017         DataShareJSUtils::Convert2StrVector(env, argv[1], DataShareJSUtils::DEFAULT_BUF_SIZE);
1018 
1019     NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valueType));
1020     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_object,
1021         error = std::make_shared<ParametersTypeError>("templateId", "TemplateId"), error, jsResults);
1022     TemplateId templateId = DataShareJSUtils::Convert2TemplateId(env, argv[2]);
1023 
1024     if (proxy->jsRdbObsManager_ == nullptr) {
1025         LOG_ERROR("proxy->jsManager_ is nullptr");
1026         return jsResults;
1027     }
1028 
1029     if (argc == ARGS_FOUR) {
1030         NAPI_CALL(env, napi_typeof(env, argv[PARAM3], &valueType));
1031         NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_function,
1032             error = std::make_shared<ParametersTypeError>("callback", "function"), error, jsResults);
1033         results = proxy->jsRdbObsManager_->DelObservers(env, argv[PARAM3], uris, templateId);
1034         return DataShareJSUtils::Convert2JSValue(env, results);
1035     }
1036     results = proxy->jsRdbObsManager_->DelObservers(env, nullptr, uris, templateId);
1037     return DataShareJSUtils::Convert2JSValue(env, results);
1038 }
1039 
Napi_SubscribePublishedObserver(napi_env env,size_t argc,napi_value * argv,napi_value self)1040 napi_value NapiDataShareHelper::Napi_SubscribePublishedObserver(napi_env env, size_t argc, napi_value *argv,
1041     napi_value self)
1042 {
1043     std::vector<OperationResult> results;
1044     napi_value jsResults = DataShareJSUtils::Convert2JSValue(env, results);
1045     std::shared_ptr<Error> error = nullptr;
1046     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, argc == ARGS_FOUR, error = std::make_shared<ParametersNumError>("4"), error,
1047         jsResults);
1048 
1049     NapiDataShareHelper *proxy = nullptr;
1050     NAPI_CALL_BASE(env, napi_unwrap(env, self, reinterpret_cast<void **>(&proxy)), jsResults);
1051     NAPI_ASSERT_BASE(env, proxy != nullptr, "there is no NapiDataShareHelper instance", jsResults);
1052     NAPI_ASSERT_BASE(env, proxy->datashareHelper_ != nullptr, "there is no DataShareHelper instance", jsResults);
1053 
1054     napi_valuetype valueType;
1055     NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
1056     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_object,
1057         error = std::make_shared<ParametersTypeError>("uris", "Array<String>"), error, jsResults);
1058     std::vector<std::string> uris =
1059         DataShareJSUtils::Convert2StrVector(env, argv[1], DataShareJSUtils::DEFAULT_BUF_SIZE);
1060 
1061     NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valueType));
1062     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_string,
1063         error = std::make_shared<ParametersTypeError>("subscriberId", "string"), error, jsResults);
1064     std::string subscriberId = DataShareJSUtils::Convert2String(env, argv[PARAM2]);
1065 
1066     NAPI_CALL(env, napi_typeof(env, argv[PARAM3], &valueType));
1067     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_function,
1068         error = std::make_shared<ParametersTypeError>("callback", "function"), error, jsResults);
1069 
1070     if (proxy->jsPublishedObsManager_ == nullptr) {
1071         LOG_ERROR("proxy->jsPublishedObsManager_ is nullptr");
1072         return jsResults;
1073     }
1074     results = proxy->jsPublishedObsManager_->AddObservers(env, argv[PARAM3], uris, atoll(subscriberId.c_str()));
1075     return DataShareJSUtils::Convert2JSValue(env, results);
1076 }
1077 
Napi_UnsubscribePublishedObserver(napi_env env,size_t argc,napi_value * argv,napi_value self)1078 napi_value NapiDataShareHelper::Napi_UnsubscribePublishedObserver(napi_env env, size_t argc, napi_value *argv,
1079     napi_value self)
1080 {
1081     std::vector<OperationResult> results;
1082     napi_value jsResults = DataShareJSUtils::Convert2JSValue(env, results);
1083     std::shared_ptr<Error> error = nullptr;
1084     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, argc == ARGS_THREE || argc == ARGS_FOUR,
1085         error = std::make_shared<ParametersNumError>("3 or 4"), error, jsResults);
1086 
1087     NapiDataShareHelper *proxy = nullptr;
1088     NAPI_CALL_BASE(env, napi_unwrap(env, self, reinterpret_cast<void **>(&proxy)), jsResults);
1089     NAPI_ASSERT_BASE(env, proxy != nullptr, "there is no NapiDataShareHelper instance", jsResults);
1090     NAPI_ASSERT_BASE(env, proxy->datashareHelper_ != nullptr, "there is no DataShareHelper instance", jsResults);
1091 
1092     napi_valuetype valueType;
1093     NAPI_CALL(env, napi_typeof(env, argv[1], &valueType));
1094     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_object,
1095         error = std::make_shared<ParametersTypeError>("uris", "Array<String>"), error, jsResults);
1096     std::vector<std::string> uris =
1097         DataShareJSUtils::Convert2StrVector(env, argv[1], DataShareJSUtils::DEFAULT_BUF_SIZE);
1098 
1099     NAPI_CALL(env, napi_typeof(env, argv[PARAM2], &valueType));
1100     NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_string,
1101         error = std::make_shared<ParametersTypeError>("subscriberId", "string"), error, jsResults);
1102     std::string subscriberId = DataShareJSUtils::Convert2String(env, argv[PARAM2]);
1103     if (proxy->jsPublishedObsManager_ == nullptr) {
1104         LOG_ERROR("proxy->jsPublishedObsManager_ is nullptr");
1105         return jsResults;
1106     }
1107 
1108     if (argc == ARGS_FOUR) {
1109         NAPI_CALL(env, napi_typeof(env, argv[PARAM3], &valueType));
1110         NAPI_ASSERT_CALL_ERRCODE_SYNC(env, valueType == napi_function,
1111             error = std::make_shared<ParametersTypeError>("callback", "function"), error, jsResults);
1112         results = proxy->jsPublishedObsManager_->DelObservers(env, argv[PARAM3], uris, atoll(subscriberId.c_str()));
1113         return DataShareJSUtils::Convert2JSValue(env, results);
1114     }
1115     results = proxy->jsPublishedObsManager_->DelObservers(env, nullptr, uris, atoll(subscriberId.c_str()));
1116     return DataShareJSUtils::Convert2JSValue(env, results);
1117 }
1118 } // namespace DataShare
1119 } // namespace OHOS
1120