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 "RdbStoreHelper"
16 #include "napi_rdb_store_helper.h"
17
18 #include <functional>
19 #include <string>
20 #include <vector>
21
22 #include "js_ability.h"
23 #include "js_utils.h"
24 #include "logger.h"
25 #include "napi_async_call.h"
26 #include "napi_rdb_error.h"
27 #include "napi_rdb_store.h"
28 #include "napi_rdb_trace.h"
29 #include "rdb_errno.h"
30 #include "rdb_open_callback.h"
31 #include "rdb_sql_utils.h"
32 #include "rdb_store_config.h"
33 #include "unistd.h"
34
35 using namespace OHOS::Rdb;
36 using namespace OHOS::NativeRdb;
37 using namespace OHOS::AppDataMgrJsKit;
38
39 namespace OHOS {
40 namespace RdbJsKit {
41
42 class OpenCallback : public OHOS::NativeRdb::RdbOpenCallback {
43 public:
44 OpenCallback() = default;
45
OpenCallback(napi_env env,napi_value jsObj)46 OpenCallback(napi_env env, napi_value jsObj) : env_(env)
47 {
48 napi_create_reference(env, jsObj, 1, &ref_);
49 napi_value property = nullptr;
50 napi_get_named_property(env_, jsObj, "onOpen", &property);
51 napi_create_reference(env, property, 1, &onOpen_);
52 napi_get_named_property(env_, jsObj, "onCreate", &property);
53 napi_create_reference(env, property, 1, &onCreate_);
54 napi_get_named_property(env_, jsObj, "onUpgrade", &property);
55 napi_create_reference(env, property, 1, &onUpgrade_);
56 napi_get_named_property(env_, jsObj, "onDowngrade", &property);
57 napi_create_reference(env, property, 1, &onDowngrade_);
58 }
59
~OpenCallback()60 ~OpenCallback()
61 {
62 if (env_ != nullptr) {
63 napi_delete_reference(env_, ref_);
64 napi_delete_reference(env_, onOpen_);
65 napi_delete_reference(env_, onCreate_);
66 napi_delete_reference(env_, onUpgrade_);
67 napi_delete_reference(env_, onDowngrade_);
68 }
69 }
70
71 OpenCallback(const OpenCallback &obj) = delete;
72
73 OpenCallback &operator=(const OpenCallback &obj) = delete;
74
OpenCallback(OpenCallback && obj)75 OpenCallback(OpenCallback &&obj) noexcept
76 {
77 operator=(std::move(obj));
78 }
79
operator =(OpenCallback && obj)80 OpenCallback &operator=(OpenCallback &&obj) noexcept
81 {
82 if (this == &obj) {
83 return *this;
84 }
85 if (env_ != nullptr && ref_ != nullptr) {
86 napi_delete_reference(env_, ref_);
87 }
88 env_ = obj.env_;
89 ref_ = obj.ref_;
90 onOpen_ = obj.onOpen_;
91 onCreate_ = obj.onCreate_;
92 onDowngrade_ = obj.onDowngrade_;
93 onUpgrade_ = obj.onUpgrade_;
94 callbacks_ = std::move(obj.callbacks_);
95 obj.env_ = nullptr;
96 obj.ref_ = nullptr;
97 obj.onOpen_ = nullptr;
98 obj.onCreate_ = nullptr;
99 obj.onDowngrade_ = nullptr;
100 obj.onUpgrade_ = nullptr;
101 return *this;
102 }
103
OnCreate(OHOS::NativeRdb::RdbStore & rdbStore)104 int OnCreate(OHOS::NativeRdb::RdbStore &rdbStore) override
105 {
106 LOG_DEBUG("OnCreate Callback.");
107 callbacks_.emplace_back([this]() -> int {
108 napi_value self = nullptr;
109 napi_status status = napi_get_reference_value(env_, ref_, &self);
110 if (status != napi_ok) {
111 LOG_ERROR("OnCreate get self reference failed, code:%{public}d", status);
112 return E_ERROR;
113 }
114 napi_value method = nullptr;
115 status = napi_get_reference_value(env_, onCreate_, &method);
116 if (status != napi_ok) {
117 LOG_ERROR("OnCreate get method reference failed, code:%{public}d", status);
118 return E_ERROR;
119 }
120 napi_value retValue = nullptr;
121 status = napi_call_function(env_, self, method, 0, nullptr, &retValue);
122 if (status != napi_ok) {
123 LOG_ERROR("OnCreate call js method failed, code:%{public}d", status);
124 return E_ERROR;
125 }
126 return E_OK;
127 });
128 return E_OK;
129 }
130
OnUpgrade(OHOS::NativeRdb::RdbStore & rdbStore,int oldVersion,int newVersion)131 int OnUpgrade(OHOS::NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion) override
132 {
133 LOG_DEBUG("OnUpgrade Callback.");
134 callbacks_.emplace_back([this, oldVersion, newVersion]() -> int {
135 napi_value self = nullptr;
136 napi_status status = napi_get_reference_value(env_, ref_, &self);
137 if (status != napi_ok) {
138 LOG_ERROR("OnUpgrade get self reference failed, code:%{public}d", status);
139 return E_ERROR;
140 }
141 napi_value method = nullptr;
142 status = napi_get_reference_value(env_, onUpgrade_, &method);
143 if (status != napi_ok) {
144 LOG_ERROR("OnUpgrade get method reference failed, code:%{public}d", status);
145 return E_ERROR;
146 }
147 napi_value result[JSUtils::ASYNC_RST_SIZE] = { 0 };
148 napi_get_undefined(env_, &result[0]);
149 napi_create_object(env_, &result[1]);
150 napi_value version = nullptr;
151 napi_create_int32(env_, newVersion, &version);
152 napi_set_named_property(env_, result[1], "currentVersion", version);
153 napi_create_int32(env_, oldVersion, &version);
154 napi_set_named_property(env_, result[1], "targetVersion", version);
155 napi_value retValue = nullptr;
156 status = napi_call_function(env_, self, method, JSUtils::ASYNC_RST_SIZE, result, &retValue);
157 if (status != napi_ok) {
158 LOG_ERROR("OnUpgrade call js method failed, code:%{public}d", status);
159 return E_ERROR;
160 }
161 return E_OK;
162 });
163 return E_OK;
164 }
165
OnDowngrade(OHOS::NativeRdb::RdbStore & rdbStore,int oldVersion,int newVersion)166 int OnDowngrade(OHOS::NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion) override
167 {
168 LOG_DEBUG("OnDowngrade Callback.");
169 callbacks_.emplace_back([this, oldVersion, newVersion]() -> int {
170 napi_value self = nullptr;
171 napi_status status = napi_get_reference_value(env_, ref_, &self);
172 if (status != napi_ok) {
173 LOG_ERROR("OnDowngrade get self reference failed, code:%{public}d", status);
174 return E_ERROR;
175 }
176 napi_value method = nullptr;
177 status = napi_get_reference_value(env_, onDowngrade_, &method);
178 if (status != napi_ok) {
179 LOG_ERROR("OnDowngrade get method reference failed, code:%{public}d", status);
180 return E_ERROR;
181 }
182 napi_value result[JSUtils::ASYNC_RST_SIZE] = { 0 };
183 napi_get_undefined(env_, &result[0]);
184 napi_create_object(env_, &result[1]);
185 napi_value version = nullptr;
186 napi_create_int32(env_, newVersion, &version);
187 napi_set_named_property(env_, result[1], "currentVersion", version);
188 napi_create_int32(env_, oldVersion, &version);
189 napi_set_named_property(env_, result[1], "targetVersion", version);
190 napi_value retValue = nullptr;
191 status = napi_call_function(env_, self, method, JSUtils::ASYNC_RST_SIZE, result, &retValue);
192 if (status != napi_ok) {
193 LOG_ERROR("OnDowngrade call js method failed, code:%{public}d", status);
194 return E_ERROR;
195 }
196 return E_OK;
197 });
198 return E_OK;
199 }
200
OnOpen(OHOS::NativeRdb::RdbStore & rdbStore)201 int OnOpen(OHOS::NativeRdb::RdbStore &rdbStore) override
202 {
203 LOG_DEBUG("OnOpen Callback.");
204 callbacks_.emplace_back([this]() -> int {
205 napi_value self = nullptr;
206 napi_status status = napi_get_reference_value(env_, ref_, &self);
207 if (status != napi_ok) {
208 LOG_ERROR("OnOpen get self reference failed, code:%{public}d", status);
209 return E_ERROR;
210 }
211 napi_value method = nullptr;
212 status = napi_get_reference_value(env_, onOpen_, &method);
213 if (status != napi_ok) {
214 LOG_ERROR("OnOpen get method reference failed, code:%{public}d", status);
215 return E_ERROR;
216 }
217 napi_value retValue = nullptr;
218 status = napi_call_function(env_, self, method, 0, nullptr, &retValue);
219 if (status != napi_ok) {
220 LOG_ERROR("OnOpen call js method failed, code:%{public}d", status);
221 return E_ERROR;
222 }
223 return E_OK;
224 });
225 return E_OK;
226 }
227
DelayNotify()228 void DelayNotify()
229 {
230 for (auto &callback : callbacks_) {
231 callback();
232 }
233 }
234
235 private:
236 napi_env env_ = nullptr;
237 napi_ref ref_ = nullptr;
238 napi_ref onOpen_ = nullptr;
239 napi_ref onCreate_ = nullptr;
240 napi_ref onUpgrade_ = nullptr;
241 napi_ref onDowngrade_ = nullptr;
242 std::vector<std::function<int(void)>> callbacks_;
243 };
244
245 struct HelperRdbContext : public BaseContext {
246 RdbStoreConfig config;
247 int32_t version;
248 bool iscontext;
249 OpenCallback openCallback;
250 std::shared_ptr<RdbStore> proxy;
251 std::shared_ptr<OHOS::AppDataMgrJsKit::Context> abilitycontext;
252
HelperRdbContextOHOS::RdbJsKit::HelperRdbContext253 HelperRdbContext() : config(""), version(0), iscontext(false), openCallback(), proxy(nullptr)
254 {
255 }
~HelperRdbContextOHOS::RdbJsKit::HelperRdbContext256 virtual ~HelperRdbContext(){};
257 };
258
259 using ParseStoreConfigFunction = int (*)(
260 const napi_env &env, const napi_value &object, std::shared_ptr<HelperRdbContext> context);
261
ParserThis(const napi_env & env,const napi_value & self,std::shared_ptr<HelperRdbContext> context)262 void ParserThis(const napi_env &env, const napi_value &self, std::shared_ptr<HelperRdbContext> context)
263 {
264 napi_unwrap(env, self, &context->boundObj);
265 }
266
ParseContext(const napi_env & env,const napi_value & object,std::shared_ptr<HelperRdbContext> context)267 int ParseContext(const napi_env &env, const napi_value &object, std::shared_ptr<HelperRdbContext> context)
268 {
269 auto abilitycontext = JSAbility::GetContext(env, object);
270 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("context", "a Context.");
271 RDB_CHECK_RETURN_CALL_RESULT(abilitycontext != nullptr, context->SetError(paramError));
272 context->abilitycontext = abilitycontext;
273 return OK;
274 }
275
ParseDatabaseName(const napi_env & env,const napi_value & object,std::shared_ptr<HelperRdbContext> context)276 int ParseDatabaseName(const napi_env &env, const napi_value &object, std::shared_ptr<HelperRdbContext> context)
277 {
278 napi_value value = nullptr;
279 napi_get_named_property(env, object, "name", &value);
280 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("config", "a StoreConfig.");
281 RDB_CHECK_RETURN_CALL_RESULT(value != nullptr, context->SetError(paramError));
282
283 std::string name = JSUtils::Convert2String(env, value);
284 RDB_CHECK_RETURN_CALL_RESULT(!name.empty(), context->SetError(paramError));
285 if (name.find("/") != std::string::npos) {
286 paramError = std::make_shared<ParamTypeError>("StoreConfig.name", "a file name without path");
287 RDB_CHECK_RETURN_CALL_RESULT(false, context->SetError(paramError));
288 }
289
290 context->config.SetName(std::move(name));
291 return OK;
292 }
293
ParseIsEncrypt(const napi_env & env,const napi_value & object,std::shared_ptr<HelperRdbContext> context)294 int ParseIsEncrypt(const napi_env &env, const napi_value &object, std::shared_ptr<HelperRdbContext> context)
295 {
296 napi_value value = nullptr;
297 napi_status status = napi_get_named_property(env, object, "encrypt", &value);
298 if (status == napi_ok && value != nullptr) {
299 bool isEncrypt = false;
300 JSUtils::Convert2Value(env, value, isEncrypt);
301 context->config.SetEncryptStatus(isEncrypt);
302 }
303 return OK;
304 }
305
ParseContextProperty(const napi_env & env,std::shared_ptr<HelperRdbContext> context)306 int ParseContextProperty(const napi_env &env, std::shared_ptr<HelperRdbContext> context)
307 {
308 if (context->abilitycontext == nullptr) {
309 int status = ParseContext(env, nullptr, context); // when no context as arg got from application.
310 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("context", "a Context.");
311 RDB_CHECK_RETURN_CALL_RESULT(status == OK, context->SetError(paramError));
312 }
313 context->config.SetModuleName(context->abilitycontext->GetModuleName());
314 context->config.SetArea(context->abilitycontext->GetArea());
315 context->config.SetBundleName(context->abilitycontext->GetBundleName());
316 return OK;
317 }
318
ParseDatabaseDir(const napi_env & env,std::shared_ptr<HelperRdbContext> context)319 int ParseDatabaseDir(const napi_env &env, std::shared_ptr<HelperRdbContext> context)
320 {
321 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("context", "a Context.");
322 RDB_CHECK_RETURN_CALL_RESULT(context->abilitycontext != nullptr, context->SetError(paramError));
323 int errorCode = E_OK;
324 std::string databaseName = context->config.GetName();
325 std::string databaseDir = context->abilitycontext->GetDatabaseDir();
326 std::string realPath = RdbSqlUtils::GetDefaultDatabasePath(databaseDir, databaseName, errorCode);
327 paramError = std::make_shared<ParamTypeError>("config", "a StoreConfig.");
328 RDB_CHECK_RETURN_CALL_RESULT(errorCode == E_OK, context->SetError(paramError));
329 context->config.SetPath(std::move(realPath));
330 return OK;
331 }
332
ParseSecurityLevel(const napi_env & env,const napi_value & object,std::shared_ptr<HelperRdbContext> context)333 int ParseSecurityLevel(const napi_env &env, const napi_value &object, std::shared_ptr<HelperRdbContext> context)
334 {
335 napi_value value = nullptr;
336 bool hasProp = false;
337 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("config", "a StoreConfig.");
338 napi_status status = napi_has_named_property(env, object, "securityLevel", &hasProp);
339 if (status != napi_ok || !hasProp) {
340 LOG_ERROR("napi_has_named_property failed! code:%{public}d!, hasProp:%{public}d!", status, hasProp);
341 RDB_CHECK_RETURN_CALL_RESULT(false, context->SetError(paramError));
342 }
343 status = napi_get_named_property(env, object, "securityLevel", &value);
344 if (status != napi_ok) {
345 LOG_ERROR("napi_get_named_property failed! code:%{public}d!", status);
346 RDB_CHECK_RETURN_CALL_RESULT(false, context->SetError(paramError));
347 }
348
349 int32_t securityLevel;
350 napi_get_value_int32(env, value, &securityLevel);
351 SecurityLevel sl = static_cast<SecurityLevel>(securityLevel);
352 LOG_DEBUG("Get sl:%{public}d", securityLevel);
353
354 bool isValidSecurityLevel = sl >= SecurityLevel::S1 && sl < SecurityLevel::LAST;
355 if (!isValidSecurityLevel) {
356 LOG_ERROR("The securityLevel should be S1-S4!");
357 RDB_CHECK_RETURN_CALL_RESULT(false, context->SetError(paramError));
358 }
359 context->config.SetSecurityLevel(sl);
360
361 LOG_DEBUG("ParseSecurityLevel end.");
362 return OK;
363 }
364
ParseStoreConfig(const napi_env & env,const napi_value & object,std::shared_ptr<HelperRdbContext> context)365 int ParseStoreConfig(const napi_env &env, const napi_value &object, std::shared_ptr<HelperRdbContext> context)
366 {
367 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseDatabaseName(env, object, context));
368 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseIsEncrypt(env, object, context));
369 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseContextProperty(env, context));
370 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseDatabaseDir(env, context));
371 return OK;
372 }
373
ParseStoreConfigV9(const napi_env & env,const napi_value & object,std::shared_ptr<HelperRdbContext> context)374 int ParseStoreConfigV9(const napi_env &env, const napi_value &object, std::shared_ptr<HelperRdbContext> context)
375 {
376 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseDatabaseName(env, object, context));
377 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseIsEncrypt(env, object, context));
378 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseSecurityLevel(env, object, context));
379 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseContextProperty(env, context));
380 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseDatabaseDir(env, context));
381 return OK;
382 }
383
ParsePath(const napi_env env,const napi_value arg,std::shared_ptr<HelperRdbContext> context)384 int ParsePath(const napi_env env, const napi_value arg, std::shared_ptr<HelperRdbContext> context)
385 {
386 std::string path = JSUtils::Convert2String(env, arg);
387 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("name", "a without path non empty string.");
388 RDB_CHECK_RETURN_CALL_RESULT(!path.empty(), context->SetError(paramError));
389
390 size_t pos = path.find_first_of('/');
391 RDB_CHECK_RETURN_CALL_RESULT(pos == std::string::npos, context->SetError(paramError));
392
393 if (context->abilitycontext == nullptr) {
394 // when no context as arg got from application.
395 ParseContext(env, nullptr, context);
396 }
397 std::string databaseDir = context->abilitycontext->GetDatabaseDir();
398 int errorCode = E_OK;
399 std::string realPath = RdbSqlUtils::GetDefaultDatabasePath(databaseDir, path, errorCode);
400 RDB_CHECK_RETURN_CALL_RESULT(errorCode == E_OK, context->SetError(paramError));
401
402 context->config.SetPath(realPath);
403 return OK;
404 }
405
ParseVersion(const napi_env env,const napi_value arg,std::shared_ptr<HelperRdbContext> context)406 int ParseVersion(const napi_env env, const napi_value arg, std::shared_ptr<HelperRdbContext> context)
407 {
408 napi_get_value_int32(env, arg, &context->version);
409 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("version", "an integer greater than 0.");
410 RDB_CHECK_RETURN_CALL_RESULT(context->version > 0, context->SetError(paramError));
411 return OK;
412 }
413
414 class DefaultOpenCallback : public RdbOpenCallback {
415 public:
OnCreate(RdbStore & rdbStore)416 int OnCreate(RdbStore &rdbStore) override
417 {
418 return E_OK;
419 }
OnUpgrade(RdbStore & rdbStore,int oldVersion,int newVersion)420 int OnUpgrade(RdbStore &rdbStore, int oldVersion, int newVersion) override
421 {
422 return E_OK;
423 }
424 };
425
InnerGetRdbStore(napi_env env,napi_callback_info info,std::shared_ptr<HelperRdbContext> context,ParseStoreConfigFunction parseStoreConfig)426 napi_value InnerGetRdbStore(napi_env env, napi_callback_info info, std::shared_ptr<HelperRdbContext> context,
427 ParseStoreConfigFunction parseStoreConfig)
428 {
429 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
430 LOG_DEBUG("RdbJsKit::GetRdbStore start.");
431 context->iscontext = JSAbility::CheckContext(env, info);
432 // context: Context, config: StoreConfig, version: number
433 auto input = [context, parseStoreConfig](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
434 if (context->iscontext || context->apiversion > APIVERSION_8) {
435 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("3 or 4");
436 RDB_CHECK_RETURN_CALL_RESULT(argc == 3 || argc == 4, context->SetError(paramNumError));
437 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseContext(env, argv[0], context));
438 RDB_ASYNC_PARAM_CHECK_FUNCTION(parseStoreConfig(env, argv[1], context));
439 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseVersion(env, argv[2], context));
440 } else {
441 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("2 or 3");
442 RDB_CHECK_RETURN_CALL_RESULT(argc == 2 || argc == 3, context->SetError(paramNumError));
443 RDB_ASYNC_PARAM_CHECK_FUNCTION(parseStoreConfig(env, argv[0], context));
444 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseVersion(env, argv[1], context));
445 }
446 ParserThis(env, self, context);
447 return OK;
448 };
449 auto exec = [context]() -> int {
450 LOG_DEBUG("RdbJsKit::GetRdbStore Async.");
451 int errCode = OK;
452 DefaultOpenCallback callback;
453 context->proxy = RdbHelper::GetRdbStore(context->config, context->version, callback, errCode);
454 std::shared_ptr<Error> dbInvalidError = std::make_shared<DbInvalidError>();
455 RDB_CHECK_RETURN_CALL_RESULT(errCode == E_OK && context->proxy != nullptr, context->SetError(dbInvalidError));
456 return (errCode == E_OK) ? OK : ERR;
457 };
458 auto output = [context](napi_env env, napi_value &result) -> int {
459 result = RdbStoreProxy::NewInstance(env, context->proxy, context->apiversion);
460 context->openCallback.DelayNotify();
461 LOG_DEBUG("RdbJsKit::GetRdbStore end.");
462 return (result != nullptr) ? OK : ERR;
463 };
464 context->SetAction(env, info, input, exec, output);
465
466 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK,
467 "RdbJsKit::GetRdbStore end with err");
468 return AsyncCall::Call(env, context);
469 }
470
GetRdbStore(napi_env env,napi_callback_info info)471 napi_value GetRdbStore(napi_env env, napi_callback_info info)
472 {
473 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
474 auto context = std::make_shared<HelperRdbContext>();
475 context->apiversion = APIVERSION_8;
476 return InnerGetRdbStore(env, info, context, ParseStoreConfig);
477 }
478
GetRdbStoreV9(napi_env env,napi_callback_info info)479 napi_value GetRdbStoreV9(napi_env env, napi_callback_info info)
480 {
481 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
482 auto context = std::make_shared<HelperRdbContext>();
483 context->apiversion = APIVERSION_V9;
484 return InnerGetRdbStore(env, info, context, ParseStoreConfigV9);
485 }
486
InnerDeleteRdbStore(napi_env env,napi_callback_info info,std::shared_ptr<HelperRdbContext> context)487 napi_value InnerDeleteRdbStore(napi_env env, napi_callback_info info, std::shared_ptr<HelperRdbContext> context)
488 {
489 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
490 LOG_DEBUG("RdbJsKit::DeleteRdbStore start.");
491 context->iscontext = JSAbility::CheckContext(env, info);
492 // context: Context, config: StoreConfig, version: number
493 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
494 if (context->iscontext || context->apiversion > APIVERSION_8) {
495 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("2 or 3");
496 RDB_CHECK_RETURN_CALL_RESULT(argc == 2 || argc == 3, context->SetError(paramNumError));
497 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseContext(env, argv[0], context));
498 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParsePath(env, argv[1], context));
499 } else {
500 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("1 or 2");
501 RDB_CHECK_RETURN_CALL_RESULT(argc == 1 || argc == 2, context->SetError(paramNumError));
502 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParsePath(env, argv[0], context));
503 }
504 return OK;
505 };
506 auto exec = [context]() -> int {
507 int errCode = RdbHelper::DeleteRdbStore(context->config.GetPath());
508 LOG_DEBUG("RdbJsKit::DeleteRdbStore failed %{public}d", errCode);
509 std::shared_ptr<Error> dbInvalidError = std::make_shared<DbInvalidError>();
510 RDB_CHECK_RETURN_CALL_RESULT(errCode != E_INVALID_FILE_PATH, context->SetError(dbInvalidError));
511 return (errCode == E_OK) ? OK : ERR;
512 };
513 auto output = [context](napi_env env, napi_value &result) -> int {
514 napi_status status = napi_create_int64(env, OK, &result);
515 LOG_DEBUG("RdbJsKit::DeleteRdbStore end.");
516 return (status == napi_ok) ? OK : ERR;
517 };
518 context->SetAction(env, info, input, exec, output);
519
520 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK,
521 "RdbJsKit::DeleteRdbStore end with err");
522 return AsyncCall::Call(env, context);
523 }
524
DeleteRdbStore(napi_env env,napi_callback_info info)525 napi_value DeleteRdbStore(napi_env env, napi_callback_info info)
526 {
527 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
528 auto context = std::make_shared<HelperRdbContext>();
529 context->apiversion = APIVERSION_8;
530 return InnerDeleteRdbStore(env, info, context);
531 }
532
DeleteRdbStoreV9(napi_env env,napi_callback_info info)533 napi_value DeleteRdbStoreV9(napi_env env, napi_callback_info info)
534 {
535 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
536 auto context = std::make_shared<HelperRdbContext>();
537 context->apiversion = APIVERSION_V9;
538 return InnerDeleteRdbStore(env, info, context);
539 }
540
InitRdbHelper(napi_env env,napi_value exports)541 napi_value InitRdbHelper(napi_env env, napi_value exports)
542 {
543 napi_property_descriptor properties[] = {
544 DECLARE_NAPI_FUNCTION("getRdbStore", GetRdbStore),
545 DECLARE_NAPI_FUNCTION("deleteRdbStore", DeleteRdbStore),
546 DECLARE_NAPI_FUNCTION("getRdbStoreV9", GetRdbStoreV9),
547 DECLARE_NAPI_FUNCTION("deleteRdbStoreV9", DeleteRdbStoreV9),
548 };
549 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(*properties), properties));
550 return exports;
551 }
552 } // namespace RdbJsKit
553 } // namespace OHOS
554