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 "RdbStoreProxy"
16 #include "napi_rdb_store.h"
17
18 #include <cinttypes>
19 #include <string>
20 #include <vector>
21
22 #include "js_utils.h"
23 #include "logger.h"
24 #include "napi_async_call.h"
25 #include "napi_rdb_error.h"
26 #include "napi_rdb_predicates.h"
27 #include "napi_rdb_trace.h"
28 #include "napi_result_set.h"
29 #include "rdb_errno.h"
30
31 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM)
32 #include "rdb_utils.h"
33 using namespace OHOS::DataShare;
34 #endif
35
36 using namespace OHOS::Rdb;
37 using namespace OHOS::NativeRdb;
38 using namespace OHOS::AppDataMgrJsKit;
39
40 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM)
41 using OHOS::DistributedRdb::SubscribeMode;
42 using OHOS::DistributedRdb::SubscribeOption;
43 using OHOS::DistributedRdb::SyncOption;
44 using OHOS::DistributedRdb::SyncResult;
45 #endif
46
47 namespace OHOS {
48 namespace RdbJsKit {
49 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM)
50 struct PredicatesProxy {
51 std::shared_ptr<DataShareAbsPredicates> predicates_;
52 };
53 #endif
54 struct RdbStoreContext : public BaseContext {
55 bool isNapiString = false;
56 std::string device;
57 std::string tableName;
58 std::vector<std::string> tablesName;
59 std::string whereClause;
60 std::vector<std::string> whereArgs;
61 std::vector<std::string> selectionArgs;
62 std::string sql;
63 RdbPredicatesProxy *predicatesProxy;
64 std::vector<std::string> columns;
65 ValuesBucket valuesBucket;
66 std::vector<ValuesBucket> valuesBuckets;
67 std::map<std::string, ValueObject> numberMaps;
68 std::vector<ValueObject> bindArgs;
69 uint64_t rowId;
70 uint64_t insertNum;
71 std::vector<uint8_t> newKey;
72 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM)
73 std::shared_ptr<AbsSharedResultSet> resultSet;
74 #else
75 std::shared_ptr<ResultSet> resultSet;
76 #endif
77 std::shared_ptr<ResultSet> stepResultSet;
78 std::string aliasName;
79 std::string pathName;
80 std::string srcName;
81 int32_t enumArg;
82 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM)
83 DistributedRdb::SyncResult syncResult;
84 #endif
85 std::shared_ptr<RdbPredicates> rdbPredicates = nullptr;
86
RdbStoreContextOHOS::RdbJsKit::RdbStoreContext87 RdbStoreContext() : predicatesProxy(nullptr), rowId(0), insertNum(0), enumArg(0)
88 {
89 }
~RdbStoreContextOHOS::RdbJsKit::RdbStoreContext90 virtual ~RdbStoreContext()
91 {
92 }
93 };
94
95 static __thread napi_ref constructor_ = nullptr;
96 static __thread napi_ref constructorV9_ = nullptr;
97
RdbStoreProxy()98 RdbStoreProxy::RdbStoreProxy()
99 {
100 }
101
~RdbStoreProxy()102 RdbStoreProxy::~RdbStoreProxy()
103 {
104 LOG_DEBUG("RdbStoreProxy destructor.");
105 }
106
Init(napi_env env,napi_value exports)107 void RdbStoreProxy::Init(napi_env env, napi_value exports)
108 {
109 napi_property_descriptor descriptors[] = {
110 DECLARE_NAPI_FUNCTION("delete", Delete),
111 DECLARE_NAPI_FUNCTION("update", Update),
112 DECLARE_NAPI_FUNCTION("insert", Insert),
113 DECLARE_NAPI_FUNCTION("batchInsert", BatchInsert),
114 DECLARE_NAPI_FUNCTION("querySql", QuerySql),
115 DECLARE_NAPI_FUNCTION("query", Query),
116 DECLARE_NAPI_FUNCTION("executeSql", ExecuteSql),
117 DECLARE_NAPI_FUNCTION("replace", Replace),
118 DECLARE_NAPI_FUNCTION("count", Count),
119 DECLARE_NAPI_FUNCTION("addAttach", Attach),
120 DECLARE_NAPI_FUNCTION("beginTransaction", BeginTransaction),
121 DECLARE_NAPI_FUNCTION("rollBack", RollBack),
122 DECLARE_NAPI_FUNCTION("commit", Commit),
123 DECLARE_NAPI_FUNCTION("queryByStep", QueryByStep),
124 DECLARE_NAPI_FUNCTION("getVersion", GetVersion),
125 DECLARE_NAPI_FUNCTION("setVersion", SetVersion),
126 DECLARE_NAPI_GETTER("isInTransaction", IsInTransaction),
127 DECLARE_NAPI_GETTER("isOpen", IsOpen),
128 DECLARE_NAPI_GETTER("path", GetPath),
129 DECLARE_NAPI_GETTER("isHoldingConnection", IsHoldingConnection),
130 DECLARE_NAPI_GETTER("isReadOnly", IsReadOnly),
131 DECLARE_NAPI_GETTER("isMemoryRdb", IsMemoryRdb),
132 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM)
133 DECLARE_NAPI_FUNCTION("setDistributedTables", SetDistributedTables),
134 DECLARE_NAPI_FUNCTION("obtainDistributedTableName", ObtainDistributedTableName),
135 DECLARE_NAPI_FUNCTION("sync", Sync),
136 DECLARE_NAPI_FUNCTION("on", OnEvent),
137 DECLARE_NAPI_FUNCTION("off", OffEvent),
138 #endif
139 };
140 napi_value cons = nullptr;
141 NAPI_CALL_RETURN_VOID(env, napi_define_class(env, "RdbStore", NAPI_AUTO_LENGTH, Initialize, nullptr,
142 sizeof(descriptors) / sizeof(napi_property_descriptor), descriptors, &cons));
143 NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, cons, 1, &constructor_));
144
145 NAPI_CALL_RETURN_VOID(env, napi_define_class(env, "RdbStoreV9", NAPI_AUTO_LENGTH, InitializeV9, nullptr,
146 sizeof(descriptors) / sizeof(napi_property_descriptor), descriptors, &cons));
147 NAPI_CALL_RETURN_VOID(env, napi_create_reference(env, cons, 1, &constructorV9_));
148 }
149
InnerInitialize(napi_env env,napi_callback_info info,int version)150 napi_value RdbStoreProxy::InnerInitialize(napi_env env, napi_callback_info info, int version)
151 {
152 napi_value self = nullptr;
153 NAPI_CALL(env, napi_get_cb_info(env, info, NULL, NULL, &self, nullptr));
154 auto finalize = [](napi_env env, void *data, void *hint) {
155 RdbStoreProxy *proxy = reinterpret_cast<RdbStoreProxy *>(data);
156 delete proxy;
157 };
158 auto *proxy = new (std::nothrow) RdbStoreProxy();
159 if (proxy == nullptr) {
160 return nullptr;
161 }
162 proxy->apiversion = version;
163 napi_status status = napi_wrap(env, self, proxy, finalize, nullptr, nullptr);
164 if (status != napi_ok) {
165 LOG_ERROR("RdbStoreProxy::Initialize napi_wrap failed! code:%{public}d!", status);
166 delete proxy;
167 return nullptr;
168 }
169 return self;
170 }
171
Initialize(napi_env env,napi_callback_info info)172 napi_value RdbStoreProxy::Initialize(napi_env env, napi_callback_info info)
173 {
174 return InnerInitialize(env, info, APIVERSION_8);
175 }
176
InitializeV9(napi_env env,napi_callback_info info)177 napi_value RdbStoreProxy::InitializeV9(napi_env env, napi_callback_info info)
178 {
179 return InnerInitialize(env, info, APIVERSION_V9);
180 }
181
NewInstance(napi_env env,std::shared_ptr<OHOS::NativeRdb::RdbStore> value,int version)182 napi_value RdbStoreProxy::NewInstance(napi_env env, std::shared_ptr<OHOS::NativeRdb::RdbStore> value, int version)
183 {
184 if (value == nullptr) {
185 LOG_ERROR("RdbStoreProxy::NewInstance get native rdb is null.");
186 return nullptr;
187 }
188 napi_value cons = nullptr;
189 napi_status status;
190 if (version > APIVERSION_8) {
191 status = napi_get_reference_value(env, constructorV9_, &cons);
192 } else {
193 status = napi_get_reference_value(env, constructor_, &cons);
194 }
195
196 if (status != napi_ok) {
197 LOG_ERROR("RdbStoreProxy::NewInstance get constructor failed! code:%{public}d!", status);
198 return nullptr;
199 }
200
201 napi_value instance = nullptr;
202 status = napi_new_instance(env, cons, 0, nullptr, &instance);
203 if (status != napi_ok) {
204 LOG_ERROR("RdbStoreProxy::NewInstance napi_new_instance failed! code:%{public}d!", status);
205 return nullptr;
206 }
207
208 RdbStoreProxy *proxy = nullptr;
209 status = napi_unwrap(env, instance, reinterpret_cast<void **>(&proxy));
210 if (proxy == nullptr) {
211 LOG_ERROR("RdbStoreProxy::NewInstance native instance is nullptr! code:%{public}d!", status);
212 return instance;
213 }
214 proxy->rdbStore_ = std::move(value);
215 proxy->apiversion = version;
216 return instance;
217 }
218
GetNativeInstance(napi_env env,napi_value self)219 RdbStoreProxy *RdbStoreProxy::GetNativeInstance(napi_env env, napi_value self)
220 {
221 RdbStoreProxy *proxy = nullptr;
222 napi_status status = napi_unwrap(env, self, reinterpret_cast<void **>(&proxy));
223 if (proxy == nullptr) {
224 LOG_ERROR("RdbStoreProxy::GetNativePredicates native instance is nullptr! code:%{public}d!", status);
225 return nullptr;
226 }
227 return proxy;
228 }
229
ParserThis(const napi_env & env,const napi_value & self,std::shared_ptr<RdbStoreContext> context)230 int ParserThis(const napi_env &env, const napi_value &self, std::shared_ptr<RdbStoreContext> context)
231 {
232 RdbStoreProxy *obj = RdbStoreProxy::GetNativeInstance(env, self);
233 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("RdbStore", "not nullptr.");
234 RDB_CHECK_RETURN_CALL_RESULT(obj, context->SetError(paramError));
235 context->apiversion = obj->apiversion;
236 context->boundObj = obj;
237 LOG_DEBUG("ParserThis RdbStoreProxy is v%{public}d.", obj->apiversion);
238 return OK;
239 }
240
ParseTableName(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)241 int ParseTableName(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
242 {
243 context->tableName = JSUtils::Convert2String(env, arg);
244 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("table", "a non empty string.");
245 RDB_CHECK_RETURN_CALL_RESULT(!context->tableName.empty(), context->SetError(paramError));
246
247 LOG_DEBUG("ParseTableName end.");
248 return OK;
249 }
250
ParseDevice(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)251 int ParseDevice(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
252 {
253 context->device = JSUtils::Convert2String(env, arg);
254 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("device", "a non empty string.");
255 RDB_CHECK_RETURN_CALL_RESULT(!context->device.empty(), context->SetError(paramError));
256
257 LOG_DEBUG("ParseDevice end.");
258 return OK;
259 }
260
ParseTablesName(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)261 int ParseTablesName(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
262 {
263 uint32_t arrLen = 0;
264 napi_get_array_length(env, arg, &arrLen);
265 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("tables", "a string array.");
266 RDB_CHECK_RETURN_CALL_RESULT(arrLen >= 0, context->SetError(paramError));
267
268 for (uint32_t i = 0; i < arrLen; ++i) {
269 napi_value element = nullptr;
270 napi_get_element(env, arg, i, &element);
271 napi_valuetype type = napi_undefined;
272 napi_typeof(env, element, &type);
273 if (type == napi_string) {
274 std::string table = JSUtils::Convert2String(env, element);
275 context->tablesName.push_back(table);
276 }
277 }
278 LOG_DEBUG("ParseTablesName end.");
279 return OK;
280 }
281
ParseSyncModeArg(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)282 int ParseSyncModeArg(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
283 {
284 napi_get_value_int32(env, arg, &context->enumArg);
285 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("mode", "a SyncMode.");
286 RDB_CHECK_RETURN_CALL_RESULT(context->enumArg == 0 || context->enumArg == 1, context->SetError(paramError));
287
288 LOG_DEBUG("ParseSyncModeArg end.");
289 return OK;
290 }
291
CheckGlobalProperty(const napi_env env,const napi_value arg,const std::string & propertyName)292 bool CheckGlobalProperty(const napi_env env, const napi_value arg, const std::string &propertyName)
293 {
294 LOG_DEBUG("CheckGlobalProperty start: %{public}s.", propertyName.c_str());
295 napi_value global = nullptr;
296 napi_status status = napi_get_global(env, &global);
297 if (status != napi_ok) {
298 return false;
299 }
300 napi_value constructor = nullptr;
301 status = napi_get_named_property(env, global, propertyName.c_str(), &constructor);
302 if (status != napi_ok) {
303 return false;
304 }
305 bool result = false;
306 status = napi_instanceof(env, arg, constructor, &result);
307 return (status == napi_ok ? result : false);
308 }
309
ParsePredicates(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)310 int ParsePredicates(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
311 {
312 LOG_DEBUG("ParsePredicates start.");
313 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("predicates", "an RdbPredicates.");
314 if (CheckGlobalProperty(env, arg, "RdbPredicatesConstructor")
315 || CheckGlobalProperty(env, arg, "RdbPredicatesConstructorV9")) {
316 LOG_DEBUG("Parse RDB Predicates.");
317 napi_unwrap(env, arg, reinterpret_cast<void **>(&context->predicatesProxy));
318 RDB_CHECK_RETURN_CALL_RESULT(context->predicatesProxy != nullptr &&
319 context->predicatesProxy->GetPredicates() != nullptr, context->SetError(paramError));
320 context->tableName = context->predicatesProxy->GetPredicates()->GetTableName();
321 context->rdbPredicates = context->predicatesProxy->GetPredicates();
322 LOG_DEBUG("ParsePredicates end.");
323 return OK;
324 }
325
326 LOG_DEBUG("Isn't RdbPredicates, maybe DataShare Predicates.");
327 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM)
328 paramError = std::make_shared<ParamTypeError>("predicates", "an RdbPredicates or DataShare Predicates.");
329 PredicatesProxy *proxy = nullptr;
330 napi_unwrap(env, arg, reinterpret_cast<void **>(&proxy));
331 // proxy is nullptr, it isn't rdb predicates or datashare predicates
332 RDB_CHECK_RETURN_CALL_RESULT(proxy != nullptr, context->SetError(paramError));
333 // proxy is not nullptr, it's a datashare predicates.
334 LOG_DEBUG("Parse DataShare Predicates.");
335 paramError = std::make_shared<ParamTypeError>("predicates", "an DataShare Predicates.");
336 LOG_ERROR("dsPredicates is null ? %{public}d.", (proxy->predicates_ == nullptr));
337 RDB_CHECK_RETURN_CALL_RESULT(proxy->predicates_ != nullptr, context->SetError(paramError));
338 std::shared_ptr<DataShareAbsPredicates> dsPredicates = proxy->predicates_;
339 context->rdbPredicates = std::make_shared<RdbPredicates>(
340 RdbDataShareAdapter::RdbUtils::ToPredicates(*dsPredicates, context->tableName));
341 #endif
342 LOG_DEBUG("ParsePredicates end.");
343 return OK;
344 }
345
ParseSrcName(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)346 int ParseSrcName(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
347 {
348 context->srcName = JSUtils::Convert2String(env, arg);
349 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("srcName", "a non empty string.");
350 RDB_CHECK_RETURN_CALL_RESULT(!context->srcName.empty(), context->SetError(paramError));
351
352 LOG_DEBUG("ParseSrcName end.");
353 return OK;
354 }
355
ParseColumns(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)356 int ParseColumns(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
357 {
358 napi_valuetype type = napi_undefined;
359 napi_typeof(env, arg, &type);
360 if (type == napi_undefined || type == napi_null) {
361 return OK;
362 }
363 int32_t ret = JSUtils::Convert2Value(env, arg, context->columns);
364 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("columns", "a non empty string.");
365 RDB_CHECK_RETURN_CALL_RESULT(ret == napi_ok, context->SetError(paramError));
366 return OK;
367 }
368
ParseWhereClause(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)369 int ParseWhereClause(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
370 {
371 context->whereClause = JSUtils::Convert2String(env, arg);
372 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("whereClause", "a non empty string.");
373 RDB_CHECK_RETURN_CALL_RESULT(!context->whereClause.empty(), context->SetError(paramError));
374
375 LOG_DEBUG("ParseWhereClause end.");
376 return OK;
377 }
378
ParseAlias(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)379 int ParseAlias(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
380 {
381 context->aliasName = JSUtils::Convert2String(env, arg);
382 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("aliasName", "a non empty string.");
383 RDB_CHECK_RETURN_CALL_RESULT(!context->aliasName.empty(), context->SetError(paramError));
384
385 LOG_DEBUG("ParseAlias end.");
386 return OK;
387 }
388
ParsePath(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)389 int ParsePath(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
390 {
391 context->pathName = JSUtils::Convert2String(env, arg);
392 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("pathName", "a non empty string.");
393 RDB_CHECK_RETURN_CALL_RESULT(!context->pathName.empty(), context->SetError(paramError));
394
395 LOG_DEBUG("ParsePath end.");
396 return OK;
397 }
398
ParseWhereArgs(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)399 int ParseWhereArgs(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
400 {
401 napi_valuetype type = napi_undefined;
402 napi_typeof(env, arg, &type);
403 if (type == napi_undefined || type == napi_null) {
404 return OK;
405 }
406 int32_t ret = JSUtils::Convert2Value(env, arg, context->whereArgs);
407 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("columns", "a non empty string.");
408 RDB_CHECK_RETURN_CALL_RESULT(ret == napi_ok, context->SetError(paramError));
409 return OK;
410 }
411
ParseSelectionArgs(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)412 int ParseSelectionArgs(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
413 {
414 napi_valuetype type = napi_undefined;
415 napi_typeof(env, arg, &type);
416 if (type == napi_undefined || type == napi_null) {
417 return OK;
418 }
419 int32_t ret = JSUtils::Convert2Value(env, arg, context->selectionArgs);
420 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("columns", "a non empty string.");
421 RDB_CHECK_RETURN_CALL_RESULT(ret == napi_ok, context->SetError(paramError));
422 return OK;
423 }
424
ParseSql(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)425 int ParseSql(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
426 {
427 context->sql = JSUtils::Convert2String(env, arg);
428 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("sql", "a non empty string.");
429 RDB_CHECK_RETURN_CALL_RESULT(!context->sql.empty(), context->SetError(paramError));
430
431 LOG_DEBUG("ParseSql end.");
432 return OK;
433 }
434
ParseValuesBucket(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)435 int ParseValuesBucket(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
436 {
437 napi_value keys = nullptr;
438 napi_get_all_property_names(env, arg, napi_key_own_only,
439 static_cast<napi_key_filter>(napi_key_enumerable | napi_key_skip_symbols),
440 napi_key_numbers_to_strings, &keys);
441 uint32_t arrLen = 0;
442 napi_status status = napi_get_array_length(env, keys, &arrLen);
443 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("values", "a ValuesBucket.");
444 RDB_CHECK_RETURN_CALL_RESULT(status == napi_ok, context->SetError(paramError));
445
446 for (size_t i = 0; i < arrLen; ++i) {
447 napi_value key = nullptr;
448 status = napi_get_element(env, keys, i, &key);
449 if (status != napi_ok) {
450 LOG_DEBUG("ValuesBucket get_element errr.");
451 }
452 RDB_CHECK_RETURN_CALL_RESULT(status == napi_ok, context->SetError(paramError));
453
454 std::string keyStr = JSUtils::Convert2String(env, key);
455 napi_value value = nullptr;
456 napi_get_property(env, arg, key, &value);
457
458 ValueObject valueObject;
459 int32_t ret = JSUtils::Convert2Value(env, value, valueObject.value);
460 if (ret == napi_ok && valueObject.GetType() == ValueObject::TYPE_BLOB) {
461 std::vector<uint8_t> tmpValue;
462 valueObject.GetBlob(tmpValue);
463 if (tmpValue.empty()) {
464 valueObject = ValueObject();
465 }
466 }
467 if (ret == napi_ok) {
468 context->valuesBucket.Put(keyStr, std::move(valueObject));
469 } else if (ret != napi_generic_failure) {
470 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>(
471 "The value type of " + keyStr, "valid.");
472 RDB_CHECK_RETURN_CALL_RESULT(false, context->SetError(paramError));
473 }
474 }
475 LOG_DEBUG("ParseValuesBucket end.");
476 return OK;
477 }
478
ParseValuesBuckets(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)479 int ParseValuesBuckets(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
480 {
481 bool isArray = false;
482 napi_is_array(env, arg, &isArray);
483 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("values", "a ValuesBucket array.");
484 if (!isArray) {
485 context->insertNum = -1;
486 RDB_CHECK_RETURN_CALL_RESULT(isArray, context->SetError(paramError));
487 }
488 uint32_t arrLen = 0;
489 napi_status status = napi_get_array_length(env, arg, &arrLen);
490 RDB_CHECK_RETURN_CALL_RESULT(status == napi_ok || arrLen >= 0, context->SetError(paramError));
491
492 for (uint32_t i = 0; i < arrLen; ++i) {
493 napi_value obj = nullptr;
494 status = napi_get_element(env, arg, i, &obj);
495 RDB_CHECK_RETURN_CALL_RESULT(status == napi_ok || arrLen >= 0, context->SetError(paramError));
496
497 ParseValuesBucket(env, obj, context);
498 context->valuesBuckets.push_back(context->valuesBucket);
499 context->valuesBucket.Clear();
500 }
501 return OK;
502 }
503
IsNapiString(napi_env env,napi_callback_info info)504 bool IsNapiString(napi_env env, napi_callback_info info)
505 {
506 constexpr size_t MIN_ARGC = 1;
507 size_t argc = MIN_ARGC;
508 napi_value args[1] = { 0 };
509 napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
510 if (argc < MIN_ARGC) {
511 return false;
512 }
513 napi_valuetype type = napi_undefined;
514 napi_typeof(env, args[0], &type);
515 if (type == napi_string) {
516 return true;
517 }
518 return false;
519 }
520
Insert(napi_env env,napi_callback_info info)521 napi_value RdbStoreProxy::Insert(napi_env env, napi_callback_info info)
522 {
523 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
524 LOG_DEBUG("RdbStoreProxy::Insert start.");
525 auto context = std::make_shared<RdbStoreContext>();
526 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
527 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("2 or 3");
528 RDB_CHECK_RETURN_CALL_RESULT(argc == 2 || argc == 3, context->SetError(paramNumError));
529 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseTableName(env, argv[0], context));
530 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseValuesBucket(env, argv[1], context));
531 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParserThis(env, self, context));
532 return OK;
533 };
534 auto exec = [context]() {
535 RdbStoreProxy *obj = reinterpret_cast<RdbStoreProxy *>(context->boundObj);
536 int64_t rowId = 0;
537 LOG_DEBUG("RdbStoreProxy::Insert Async.");
538 CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr);
539 int errCode = obj->rdbStore_->Insert(rowId, context->tableName, context->valuesBucket);
540 context->rowId = rowId;
541 LOG_DEBUG("RdbStoreProxy::Insert errCode is: %{public}d.", errCode);
542 return (errCode == E_OK) ? OK : ERR;
543 };
544 auto output = [context](napi_env env, napi_value &result) -> int {
545 napi_status status = napi_create_int64(env, context->rowId, &result);
546 LOG_DEBUG("RdbStoreProxy::Insert end.");
547 return (status == napi_ok) ? OK : ERR;
548 };
549 context->SetAction(env, info, input, exec, output);
550
551 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, "");
552 return AsyncCall::Call(env, context);
553 }
554
BatchInsert(napi_env env,napi_callback_info info)555 napi_value RdbStoreProxy::BatchInsert(napi_env env, napi_callback_info info)
556 {
557 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
558 LOG_DEBUG("RdbStoreProxy::BatchInsert start.");
559 auto context = std::make_shared<RdbStoreContext>();
560 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
561 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("2 or 3");
562 RDB_CHECK_RETURN_CALL_RESULT(argc == 2 || argc == 3, context->SetError(paramNumError));
563 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseTableName(env, argv[0], context));
564 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseValuesBuckets(env, argv[1], context));
565 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParserThis(env, self, context));
566 return OK;
567 };
568 auto exec = [context]() {
569 LOG_INFO("RdbStoreProxy::BatchInsert Async.");
570 RdbStoreProxy *obj = reinterpret_cast<RdbStoreProxy *>(context->boundObj);
571 if (context->insertNum == -1UL) {
572 return E_OK;
573 }
574 int64_t outInsertNum = 0;
575 CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr);
576 int errCode = obj->rdbStore_->BatchInsert(outInsertNum, context->tableName, context->valuesBuckets);
577 context->insertNum = outInsertNum;
578 return (errCode == E_OK) ? OK : ERR;
579 };
580 auto output = [context](napi_env env, napi_value &result) -> int {
581 napi_status status = napi_create_int64(env, context->insertNum, &result);
582 LOG_DEBUG("RdbStoreProxy::BatchInsert end. tableName is: %{public}s.",
583 context->tableName.c_str());
584 return (status == napi_ok) ? OK : ERR;
585 };
586 context->SetAction(env, info, input, exec, output);
587
588 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, "");
589 return AsyncCall::Call(env, context);
590 }
591
Delete(napi_env env,napi_callback_info info)592 napi_value RdbStoreProxy::Delete(napi_env env, napi_callback_info info)
593 {
594 LOG_DEBUG("RdbStoreProxy::Delete start.");
595 auto context = std::make_shared<RdbStoreContext>();
596 context->isNapiString = IsNapiString(env, info);
597 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
598 if (context->isNapiString) {
599 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("2 or 3");
600 RDB_CHECK_RETURN_CALL_RESULT(argc == 2 || argc == 3, context->SetError(paramNumError));
601 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseTableName(env, argv[0], context));
602 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParsePredicates(env, argv[1], context));
603 } else {
604 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("1 or 2");
605 RDB_CHECK_RETURN_CALL_RESULT(argc == 1 || argc == 2, context->SetError(paramNumError));
606 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParsePredicates(env, argv[0], context));
607 }
608 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParserThis(env, self, context));
609 return OK;
610 };
611 auto exec = [context]() {
612 LOG_DEBUG("RdbStoreProxy::Delete Async.");
613 RdbStoreProxy *obj = reinterpret_cast<RdbStoreProxy *>(context->boundObj);
614 int deletedRows = 0;
615 CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr);
616 int errCode = obj->rdbStore_->Delete(deletedRows, *(context->rdbPredicates));
617 context->rowId = deletedRows;
618 LOG_DEBUG("RdbStoreProxy::Delete errCode is: %{public}d.", errCode);
619 return (errCode == E_OK) ? OK : ERR;
620 };
621 auto output = [context](napi_env env, napi_value &result) -> int {
622 napi_status status = napi_create_int64(env, context->rowId, &result);
623 LOG_DEBUG("RdbStoreProxy::Delete end.");
624 return (status == napi_ok) ? OK : ERR;
625 };
626 context->SetAction(env, info, input, exec, output);
627
628 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, "");
629 return AsyncCall::Call(env, context);
630 }
631
Update(napi_env env,napi_callback_info info)632 napi_value RdbStoreProxy::Update(napi_env env, napi_callback_info info)
633 {
634 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
635 LOG_DEBUG("RdbStoreProxy::Update start.");
636 auto context = std::make_shared<RdbStoreContext>();
637 context->isNapiString = IsNapiString(env, info);
638 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
639 if (context->isNapiString) {
640 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("3 or 4");
641 RDB_CHECK_RETURN_CALL_RESULT(argc == 3 || argc == 4, context->SetError(paramNumError));
642 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseTableName(env, argv[0], context));
643 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseValuesBucket(env, argv[1], context));
644 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParsePredicates(env, argv[2], context));
645 } else {
646 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("2 or 3");
647 RDB_CHECK_RETURN_CALL_RESULT(argc == 2 || argc == 3, context->SetError(paramNumError));
648 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseValuesBucket(env, argv[0], context));
649 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParsePredicates(env, argv[1], context));
650 }
651 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParserThis(env, self, context));
652 return OK;
653 };
654 auto exec = [context]() {
655 LOG_DEBUG("RdbStoreProxy::Update Async.");
656 RdbStoreProxy *obj = reinterpret_cast<RdbStoreProxy *>(context->boundObj);
657 int changedRows = 0;
658 CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr);
659 int errCode = obj->rdbStore_->Update(changedRows, context->valuesBucket, *(context->rdbPredicates));
660 context->rowId = changedRows;
661 LOG_DEBUG("RdbStoreProxy::Update errCode is: %{public}d.", errCode);
662 return (errCode == E_OK) ? OK : ERR;
663 };
664 auto output = [context](napi_env env, napi_value &result) -> int {
665 napi_status status = napi_create_int64(env, context->rowId, &result);
666 LOG_DEBUG("RdbStoreProxy::Update end.");
667 return (status == napi_ok) ? OK : ERR;
668 };
669 context->SetAction(env, info, input, exec, output);
670
671 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, "");
672 return AsyncCall::Call(env, context);
673 }
674
Query(napi_env env,napi_callback_info info)675 napi_value RdbStoreProxy::Query(napi_env env, napi_callback_info info)
676 {
677 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
678 auto context = std::make_shared<RdbStoreContext>();
679 context->isNapiString = IsNapiString(env, info);
680 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
681 if (context->isNapiString) {
682 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("1, 2 or 3");
683 RDB_CHECK_RETURN_CALL_RESULT(argc == 1 || argc == 2 || argc == 3, context->SetError(paramNumError));
684 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseTableName(env, argv[0], context));
685 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParsePredicates(env, argv[1], context));
686 if (argc > 2) {
687 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseColumns(env, argv[2], context));
688 }
689 } else {
690 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("1 or 2");
691 RDB_CHECK_RETURN_CALL_RESULT(argc == 1 || argc == 2, context->SetError(paramNumError));
692 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParsePredicates(env, argv[0], context));
693 if (argc > 1) {
694 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseColumns(env, argv[1], context));
695 }
696 }
697 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParserThis(env, self, context));
698 return OK;
699 };
700 auto exec = [context]() {
701 RdbStoreProxy *obj = reinterpret_cast<RdbStoreProxy *>(context->boundObj);
702 CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr);
703 #if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM) || defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
704 context->resultSet = obj->rdbStore_->QueryByStep(*(context->rdbPredicates), context->columns);
705 #else
706 context->resultSet = obj->rdbStore_->Query(*(context->rdbPredicates), context->columns);
707 #endif
708 LOG_DEBUG("RdbStoreProxy::Query result is nullptr ? %{public}d.", (context->resultSet == nullptr));
709 return (context->resultSet != nullptr) ? OK : ERR;
710 };
711 auto output = [context](napi_env env, napi_value &result) -> int {
712 result = ResultSetProxy::NewInstance(
713 env, context->resultSet, context->apiversion);
714 return (result != nullptr) ? OK : ERR;
715 };
716 context->SetAction(env, info, input, exec, output);
717
718 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, "");
719 return AsyncCall::Call(env, context);
720 }
721
QuerySql(napi_env env,napi_callback_info info)722 napi_value RdbStoreProxy::QuerySql(napi_env env, napi_callback_info info)
723 {
724 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
725 auto context = std::make_shared<RdbStoreContext>();
726 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
727 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("1, 2 or 3");
728 RDB_CHECK_RETURN_CALL_RESULT(argc == 1 || argc == 2 || argc == 3, context->SetError(paramNumError));
729 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseSql(env, argv[0], context));
730 if (argc > 1) {
731 #if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM)
732 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseColumns(env, argv[1], context));
733 #else
734 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseSelectionArgs(env, argv[1], context));
735 #endif
736 }
737 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParserThis(env, self, context));
738 return OK;
739 };
740 auto exec = [context]() {
741 RdbStoreProxy *obj = reinterpret_cast<RdbStoreProxy *>(context->boundObj);
742 #if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM)
743 CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr);
744 context->resultSet = obj->rdbStore_->QueryByStep(context->sql, context->columns);
745 LOG_ERROR("RdbStoreProxy::QuerySql is nullptr ? %{public}d ", context->resultSet == nullptr);
746 return (context->resultSet != nullptr) ? OK : ERR;
747 #else
748 std::string selectionArgs = ",";
749 for (size_t i = 0; i < context->selectionArgs.size(); i++) {
750 selectionArgs += context->selectionArgs[i];
751 }
752 context->resultSet = obj->rdbStore_->QuerySql(context->sql, context->selectionArgs);
753 return (context->resultSet != nullptr) ? OK : ERR;
754 #endif
755 };
756 auto output = [context](napi_env env, napi_value &result) -> int {
757 result = ResultSetProxy::NewInstance(
758 env, context->resultSet, context->apiversion);
759 return (result != nullptr) ? OK : ERR;
760 };
761 context->SetAction(env, info, input, exec, output);
762
763 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, "");
764 return AsyncCall::Call(env, context);
765 }
766
ParseBindArgs(const napi_env env,const napi_value arg,std::shared_ptr<RdbStoreContext> context)767 int ParseBindArgs(const napi_env env, const napi_value arg, std::shared_ptr<RdbStoreContext> context)
768 {
769 context->bindArgs.clear();
770 uint32_t arrLen = 0;
771 napi_get_array_length(env, arg, &arrLen);
772 if (arrLen == 0) {
773 return OK;
774 }
775 for (uint32_t i = 0; i < arrLen; ++i) {
776 napi_value element = nullptr;
777 napi_get_element(env, arg, i, &element);
778
779 ValueObject valueObject;
780 int32_t ret = JSUtils::Convert2Value(env, element, valueObject.value);
781 std::shared_ptr<Error> paramError = std::make_shared<ParamTypeError>("tables", "a string array.");
782 RDB_CHECK_RETURN_CALL_RESULT(ret == napi_ok, context->SetError(paramError));
783 if (valueObject.GetType() == ValueObject::TYPE_BLOB) {
784 std::vector<uint8_t> tmpValue;
785 valueObject.GetBlob(tmpValue);
786 if (tmpValue.empty()) {
787 valueObject = ValueObject();
788 }
789 }
790 context->bindArgs.push_back(valueObject);
791 }
792 return OK;
793 }
794
ExecuteSql(napi_env env,napi_callback_info info)795 napi_value RdbStoreProxy::ExecuteSql(napi_env env, napi_callback_info info)
796 {
797 LOG_DEBUG("RdbStoreProxy::ExecuteSql start.");
798 auto context = std::make_shared<RdbStoreContext>();
799 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
800 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("1, 2 or 3");
801 RDB_CHECK_RETURN_CALL_RESULT(argc == 1 || argc == 2 || argc == 3, context->SetError(paramNumError));
802 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseSql(env, argv[0], context));
803 if (argc > 1) {
804 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseBindArgs(env, argv[1], context));
805 }
806 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParserThis(env, self, context));
807 return OK;
808 };
809 auto exec = [context]() {
810 LOG_DEBUG("RdbStoreProxy::ExecuteSql Async.");
811 RdbStoreProxy *obj = reinterpret_cast<RdbStoreProxy *>(context->boundObj);
812 CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr);
813 int errCode = obj->rdbStore_->ExecuteSql(context->sql, context->bindArgs);
814 LOG_DEBUG("RdbStoreProxy::ExecuteSql errCode is: %{public}d.", errCode);
815 return (errCode == E_OK) ? OK : ERR;
816 };
817 auto output = [context](napi_env env, napi_value &result) -> int {
818 napi_status status = napi_get_undefined(env, &result);
819 LOG_DEBUG("RdbStoreProxy::ExecuteSql end.");
820 return (status == napi_ok) ? OK : ERR;
821 };
822 context->SetAction(env, info, input, exec, output);
823
824 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, "");
825 return AsyncCall::Call(env, context);
826 }
827
Count(napi_env env,napi_callback_info info)828 napi_value RdbStoreProxy::Count(napi_env env, napi_callback_info info)
829 {
830 LOG_DEBUG("RdbStoreProxy::Count start.");
831 auto context = std::make_shared<RdbStoreContext>();
832 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
833 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("1 or 2");
834 RDB_CHECK_RETURN_CALL_RESULT(argc == 1 || argc == 2, context->SetError(paramNumError));
835 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParsePredicates(env, argv[0], context));
836 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParserThis(env, self, context));
837 return OK;
838 };
839 auto exec = [context]() {
840 LOG_DEBUG("RdbStoreProxy::Count Async.");
841 RdbStoreProxy *obj = reinterpret_cast<RdbStoreProxy *>(context->boundObj);
842 std::int64_t temp = 0;
843 CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr);
844 CHECK_RETURN_ERR(context->predicatesProxy != nullptr &&
845 context->predicatesProxy->GetPredicates() != nullptr);
846 int errCode = obj->rdbStore_->Count(temp, *(context->predicatesProxy->GetPredicates()));
847 context->rowId = temp;
848 LOG_DEBUG("RdbStoreProxy::Count errCode is: %{public}d.", errCode);
849 return (errCode == E_OK) ? OK : ERR;
850 };
851 auto output = [context](napi_env env, napi_value &result) -> int {
852 napi_status status = napi_create_int64(env, context->rowId, &result);
853 LOG_DEBUG("RdbStoreProxy::Count end.");
854 return (status == napi_ok) ? OK : ERR;
855 };
856 context->SetAction(env, info, input, exec, output);
857
858 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, "");
859 return AsyncCall::Call(env, context);
860 }
861
Replace(napi_env env,napi_callback_info info)862 napi_value RdbStoreProxy::Replace(napi_env env, napi_callback_info info)
863 {
864 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
865 LOG_DEBUG("RdbStoreProxy::Replace start.");
866 auto context = std::make_shared<RdbStoreContext>();
867 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
868 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("2 or 3");
869 RDB_CHECK_RETURN_CALL_RESULT(argc == 2 || argc == 3, context->SetError(paramNumError));
870 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseTableName(env, argv[0], context));
871 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseValuesBucket(env, argv[1], context));
872 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParserThis(env, self, context));
873 return OK;
874 };
875 auto exec = [context]() {
876 LOG_DEBUG("RdbStoreProxy::Replace Async.");
877 RdbStoreProxy *obj = reinterpret_cast<RdbStoreProxy *>(context->boundObj);
878 int64_t rowId = 0;
879 CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr);
880 int errCode = obj->rdbStore_->Replace(rowId, context->tableName, context->valuesBucket);
881 context->rowId = rowId;
882 LOG_DEBUG("RdbStoreProxy::Replace errCode is:%{public}d.", errCode);
883 return (errCode == E_OK) ? OK : ERR;
884 };
885 auto output = [context](napi_env env, napi_value &result) -> int {
886 napi_status status = napi_create_int64(env, context->rowId, &result);
887 LOG_DEBUG("RdbStoreProxy::Replace end.");
888 return (status == napi_ok) ? OK : ERR;
889 };
890 context->SetAction(env, info, input, exec, output);
891
892 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, "");
893 return AsyncCall::Call(env, context);
894 }
895
Attach(napi_env env,napi_callback_info info)896 napi_value RdbStoreProxy::Attach(napi_env env, napi_callback_info info)
897 {
898 LOG_DEBUG("RdbStoreProxy::Attach start.");
899 auto context = std::make_shared<RdbStoreContext>();
900 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
901 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("3 or 4");
902 RDB_CHECK_RETURN_CALL_RESULT(argc == 3 || argc == 4, context->SetError(paramNumError));
903 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseAlias(env, argv[0], context));
904 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParsePath(env, argv[1], context));
905 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParserThis(env, self, context));
906 return OK;
907 };
908 auto exec = [context]() {
909 LOG_DEBUG("RdbStoreProxy::Attach Async.");
910 RdbStoreProxy *obj = reinterpret_cast<RdbStoreProxy *>(context->boundObj);
911 CHECK_RETURN_ERR(obj != nullptr && obj->rdbStore_ != nullptr);
912 int errCode = obj->rdbStore_->Attach(context->aliasName, context->pathName, context->newKey);
913 LOG_ERROR("RdbStoreProxy::Attach errCode is:%{public}d.", errCode);
914 return (errCode != E_OK) ? OK : ERR;
915 };
916 auto output = [context](napi_env env, napi_value &result) -> int {
917 napi_status status = napi_get_undefined(env, &result);
918 LOG_DEBUG("RdbStoreProxy::Attach end.");
919 return (status == napi_ok) ? OK : ERR;
920 };
921 context->SetAction(env, info, input, exec, output);
922
923 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, "");
924 return AsyncCall::Call(env, context);
925 }
926
IsHoldingConnection(napi_env env,napi_callback_info info)927 napi_value RdbStoreProxy::IsHoldingConnection(napi_env env, napi_callback_info info)
928 {
929 napi_value thisObj = nullptr;
930 napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr);
931 RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj);
932 NAPI_ASSERT(env, rdbStoreProxy != nullptr &&
933 rdbStoreProxy->rdbStore_ != nullptr, "RdbStoreProxy or rdbStore_ is nullptr");
934 bool out = rdbStoreProxy->rdbStore_->IsHoldingConnection();
935 LOG_DEBUG("RdbStoreProxy::IsHoldingConnection out is : %{public}d.", out);
936 return JSUtils::Convert2JSValue(env, out);
937 }
938
IsReadOnly(napi_env env,napi_callback_info info)939 napi_value RdbStoreProxy::IsReadOnly(napi_env env, napi_callback_info info)
940 {
941 napi_value thisObj = nullptr;
942 napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr);
943 RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj);
944 NAPI_ASSERT(env, rdbStoreProxy != nullptr
945 && rdbStoreProxy->rdbStore_ != nullptr, "RdbStoreProxy or rdbStore_ is nullptr");
946 bool out = rdbStoreProxy->rdbStore_->IsReadOnly();
947 LOG_DEBUG("RdbStoreProxy::IsReadOnly out is : %{public}d.", out);
948 return JSUtils::Convert2JSValue(env, out);
949 }
950
IsMemoryRdb(napi_env env,napi_callback_info info)951 napi_value RdbStoreProxy::IsMemoryRdb(napi_env env, napi_callback_info info)
952 {
953 napi_value thisObj = nullptr;
954 napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr);
955 RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj);
956 NAPI_ASSERT(env, rdbStoreProxy != nullptr
957 && rdbStoreProxy->rdbStore_ != nullptr, "RdbStoreProxy or rdbStore_ is nullptr");
958 bool out = rdbStoreProxy->rdbStore_->IsMemoryRdb();
959 LOG_DEBUG("RdbStoreProxy::IsMemoryRdb out is : %{public}d.", out);
960 return JSUtils::Convert2JSValue(env, out);
961 }
962
GetPath(napi_env env,napi_callback_info info)963 napi_value RdbStoreProxy::GetPath(napi_env env, napi_callback_info info)
964 {
965 napi_value thisObj = nullptr;
966 napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr);
967 RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj);
968 NAPI_ASSERT(env, rdbStoreProxy != nullptr
969 && rdbStoreProxy->rdbStore_ != nullptr, "RdbStoreProxy or rdbStore_ is nullptr");
970 std::string path = rdbStoreProxy->rdbStore_->GetPath();
971 LOG_DEBUG("RdbStoreProxy::GetPath path is empty ? %{public}d.", path.empty());
972 return JSUtils::Convert2JSValue(env, path);
973 }
974
BeginTransaction(napi_env env,napi_callback_info info)975 napi_value RdbStoreProxy::BeginTransaction(napi_env env, napi_callback_info info)
976 {
977 napi_value thisObj = nullptr;
978 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr));
979 RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj);
980 NAPI_ASSERT(env, rdbStoreProxy != nullptr
981 && rdbStoreProxy->rdbStore_ != nullptr, "RdbStoreProxy or rdbStore_ is nullptr");
982 int errCode = rdbStoreProxy->rdbStore_->BeginTransaction();
983 NAPI_ASSERT(env, errCode == E_OK, "call BeginTransaction failed");
984 LOG_DEBUG("RdbStoreProxy::BeginTransaction end, errCode is:%{public}d.", errCode);
985 return nullptr;
986 }
987
RollBack(napi_env env,napi_callback_info info)988 napi_value RdbStoreProxy::RollBack(napi_env env, napi_callback_info info)
989 {
990 napi_value thisObj = nullptr;
991 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr));
992 RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj);
993 NAPI_ASSERT(env, rdbStoreProxy != nullptr, "RdbStoreProxy is nullptr");
994 int errCode = rdbStoreProxy->rdbStore_->RollBack();
995 NAPI_ASSERT(env, errCode == E_OK, "call RollBack failed");
996 LOG_DEBUG("RdbStoreProxy::RollBack end, errCode is:%{public}d.", errCode);
997 return nullptr;
998 }
999
Commit(napi_env env,napi_callback_info info)1000 napi_value RdbStoreProxy::Commit(napi_env env, napi_callback_info info)
1001 {
1002 napi_value thisObj = nullptr;
1003 NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr));
1004 RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj);
1005 NAPI_ASSERT(env, rdbStoreProxy != nullptr, "RdbStoreProxy is nullptr");
1006 int errCode = rdbStoreProxy->rdbStore_->Commit();
1007 NAPI_ASSERT(env, errCode == E_OK, "call Commit failed");
1008 LOG_DEBUG("RdbStoreProxy::Commit end, errCode is:%{public}d.", errCode);
1009 return nullptr;
1010 }
1011
QueryByStep(napi_env env,napi_callback_info info)1012 napi_value RdbStoreProxy::QueryByStep(napi_env env, napi_callback_info info)
1013 {
1014 DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
1015 LOG_DEBUG("RdbStoreProxy::QueryByStep start.");
1016 auto context = std::make_shared<RdbStoreContext>();
1017 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
1018 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("2 or 3");
1019 RDB_CHECK_RETURN_CALL_RESULT(argc == 2 || argc == 3, context->SetError(paramNumError));
1020 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseSql(env, argv[0], context));
1021 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseColumns(env, argv[1], context));
1022 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParserThis(env, self, context));
1023 return OK;
1024 };
1025 auto exec = [context]() {
1026 LOG_DEBUG("RdbStoreProxy::QueryByStep Async.");
1027 RdbStoreProxy *obj = reinterpret_cast<RdbStoreProxy *>(context->boundObj);
1028 if (obj == nullptr || obj->rdbStore_ == nullptr) {
1029 return ERR;
1030 }
1031 context->stepResultSet = obj->rdbStore_->QueryByStep(context->sql, context->columns);
1032 LOG_ERROR("RdbStoreProxy::QueryByStep is nullptr ? %{public}d.", context->stepResultSet == nullptr);
1033 return (context->stepResultSet != nullptr) ? OK : ERR;
1034 };
1035 auto output = [context](napi_env env, napi_value &result) -> int {
1036 if (context->stepResultSet != nullptr) {
1037 result = ResultSetProxy::NewInstance(env, context->stepResultSet, context->apiversion);
1038 }
1039 LOG_DEBUG("RdbStoreProxy::QueryByStep end.");
1040 return (result != nullptr) ? OK : ERR;
1041 };
1042 context->SetAction(env, info, input, exec, output);
1043
1044 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, "");
1045 return AsyncCall::Call(env, context);
1046 }
1047
IsInTransaction(napi_env env,napi_callback_info info)1048 napi_value RdbStoreProxy::IsInTransaction(napi_env env, napi_callback_info info)
1049 {
1050 napi_value thisObj = nullptr;
1051 napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr);
1052 RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj);
1053 NAPI_ASSERT(env, rdbStoreProxy != nullptr, "RdbStoreProxy is nullptr");
1054 bool out = rdbStoreProxy->rdbStore_->IsInTransaction();
1055 LOG_DEBUG("RdbStoreProxy::IsInTransaction out is : %{public}d.", out);
1056 return JSUtils::Convert2JSValue(env, out);
1057 }
1058
IsOpen(napi_env env,napi_callback_info info)1059 napi_value RdbStoreProxy::IsOpen(napi_env env, napi_callback_info info)
1060 {
1061 napi_value thisObj = nullptr;
1062 napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr);
1063 RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj);
1064 NAPI_ASSERT(env, (rdbStoreProxy != nullptr) && (rdbStoreProxy->rdbStore_ != nullptr), "RdbStoreProxy is nullptr");
1065 bool out = rdbStoreProxy->rdbStore_->IsOpen();
1066 LOG_DEBUG("RdbStoreProxy::IsOpen out is : %{public}d.", out);
1067 return JSUtils::Convert2JSValue(env, out);
1068 }
1069
GetVersion(napi_env env,napi_callback_info info)1070 napi_value RdbStoreProxy::GetVersion(napi_env env, napi_callback_info info)
1071 {
1072 napi_value thisObj = nullptr;
1073 napi_get_cb_info(env, info, nullptr, nullptr, &thisObj, nullptr);
1074 RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thisObj);
1075 NAPI_ASSERT(env, (rdbStoreProxy != nullptr) && (rdbStoreProxy->rdbStore_ != nullptr), "RdbStoreProxy is nullptr");
1076 int32_t version = 0;
1077 int out = rdbStoreProxy->rdbStore_->GetVersion(version);
1078 LOG_DEBUG("RdbStoreProxy::GetVersion out is : %{public}d.", out);
1079 return JSUtils::Convert2JSValue(env, version);
1080 }
1081
SetVersion(napi_env env,napi_callback_info info)1082 napi_value RdbStoreProxy::SetVersion(napi_env env, napi_callback_info info)
1083 {
1084 napi_value thiz = nullptr;
1085 size_t argc = 1;
1086 napi_value args[1] = { 0 };
1087 napi_get_cb_info(env, info, &argc, args, &thiz, nullptr);
1088 NAPI_ASSERT(env, argc == 1, "RdbStoreProxy::SetVersion Invalid argvs!");
1089 RdbStoreProxy *rdbStoreProxy = GetNativeInstance(env, thiz);
1090 NAPI_ASSERT(env, (rdbStoreProxy != nullptr) && (rdbStoreProxy->rdbStore_ != nullptr), "RdbStoreProxy is nullptr");
1091 int32_t version = 0;
1092 napi_get_value_int32(env, args[0], &version);
1093 int out = rdbStoreProxy->rdbStore_->SetVersion(version);
1094 LOG_DEBUG("RdbStoreProxy::SetVersion out is : %{public}d.", out);
1095 return nullptr;
1096 }
1097
1098 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM)
SetDistributedTables(napi_env env,napi_callback_info info)1099 napi_value RdbStoreProxy::SetDistributedTables(napi_env env, napi_callback_info info)
1100 {
1101 LOG_DEBUG("RdbStoreProxy::SetDistributedTables start.");
1102 auto context = std::make_shared<RdbStoreContext>();
1103 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
1104 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("1 or 2");
1105 RDB_CHECK_RETURN_CALL_RESULT(argc == 1 || argc == 2, context->SetError(paramNumError));
1106 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseTablesName(env, argv[0], context));
1107 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParserThis(env, self, context));
1108 return OK;
1109 };
1110 auto exec = [context]() {
1111 LOG_DEBUG("RdbStoreProxy::SetDistributedTables Async.");
1112 RdbStoreProxy *obj = reinterpret_cast<RdbStoreProxy *>(context->boundObj);
1113 if (obj == nullptr || obj->rdbStore_.get() == nullptr) {
1114 return ERR;
1115 }
1116 int res = obj->rdbStore_->SetDistributedTables(context->tablesName);
1117 LOG_DEBUG("RdbStoreProxy::SetDistributedTables res is : %{public}d.", res);
1118 return (res == E_OK || res == E_NOT_SUPPORT) ? OK : ERR;
1119 };
1120 auto output = [context](napi_env env, napi_value &result) -> int {
1121 napi_status status = napi_get_undefined(env, &result);
1122 LOG_DEBUG("RdbStoreProxy::SetDistributedTables end.");
1123 return (status == napi_ok) ? OK : ERR;
1124 };
1125 context->SetAction(env, info, input, exec, output);
1126
1127 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, "");
1128 return AsyncCall::Call(env, context);
1129 }
1130
ObtainDistributedTableName(napi_env env,napi_callback_info info)1131 napi_value RdbStoreProxy::ObtainDistributedTableName(napi_env env, napi_callback_info info)
1132 {
1133 LOG_DEBUG("RdbStoreProxy::ObtainDistributedTableName start.");
1134 auto context = std::make_shared<RdbStoreContext>();
1135 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
1136 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("2 or 3");
1137 RDB_CHECK_RETURN_CALL_RESULT(argc == 2 || argc == 3, context->SetError(paramNumError));
1138 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseDevice(env, argv[0], context));
1139 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseTableName(env, argv[1], context));
1140 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParserThis(env, self, context));
1141 return OK;
1142 };
1143 auto exec = [context]() {
1144 LOG_DEBUG("RdbStoreProxy::ObtainDistributedTableName Async.");
1145 RdbStoreProxy *obj = reinterpret_cast<RdbStoreProxy *>(context->boundObj);
1146 int errCode = E_ERROR;
1147 if (obj == nullptr || obj->rdbStore_.get() == nullptr) {
1148 return ERR;
1149 }
1150 auto name = obj->rdbStore_->ObtainDistributedTableName(context->device, context->tableName, errCode);
1151 LOG_INFO("RdbStoreProxy::ObtainDistributedTableName name is empty ? : %{public}d, errCode is %{public}d",
1152 name.empty(), errCode);
1153 context->tableName = name;
1154 return name.empty() ? ERR : OK;
1155 };
1156 auto output = [context](napi_env env, napi_value &result) -> int {
1157 napi_status status =
1158 napi_create_string_utf8(env, context->tableName.c_str(), context->tableName.length(), &result);
1159 LOG_DEBUG("RdbStoreProxy::ObtainDistributedTableName end.");
1160 return (status == napi_ok) ? OK : ERR;
1161 };
1162 context->SetAction(env, info, input, exec, output);
1163
1164 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, "");
1165 return AsyncCall::Call(env, context);
1166 }
1167
Sync(napi_env env,napi_callback_info info)1168 napi_value RdbStoreProxy::Sync(napi_env env, napi_callback_info info)
1169 {
1170 LOG_DEBUG("RdbStoreProxy::Sync start.");
1171 auto context = std::make_shared<RdbStoreContext>();
1172 auto input = [context](napi_env env, size_t argc, napi_value *argv, napi_value self) -> int {
1173 std::shared_ptr<Error> paramNumError = std::make_shared<ParamNumError>("2 or 3");
1174 RDB_CHECK_RETURN_CALL_RESULT(argc == 2 || argc == 3, context->SetError(paramNumError));
1175 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParseSyncModeArg(env, argv[0], context));
1176 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParsePredicates(env, argv[1], context));
1177 RDB_ASYNC_PARAM_CHECK_FUNCTION(ParserThis(env, self, context));
1178 return OK;
1179 };
1180 auto exec = [context]() {
1181 LOG_DEBUG("RdbStoreProxy::Sync Async.");
1182 auto *obj = reinterpret_cast<RdbStoreProxy *>(context->boundObj);
1183 SyncOption option;
1184 option.mode = static_cast<DistributedRdb::SyncMode>(context->enumArg);
1185 option.isBlock = true;
1186 if (obj == nullptr || obj->rdbStore_.get() == nullptr) {
1187 return ERR;
1188 }
1189 int res = obj->rdbStore_->Sync(option, *context->predicatesProxy->GetPredicates(),
1190 [context](const SyncResult &result) { context->syncResult = result; });
1191 LOG_INFO("RdbStoreProxy::Sync res is : %{public}d.", res);
1192 return res == E_OK ? OK : ERR;
1193 };
1194 auto output = [context](napi_env env, napi_value &result) -> int {
1195 result = JSUtils::Convert2JSValue(env, context->syncResult);
1196 LOG_DEBUG("RdbStoreProxy::Sync end.");
1197 return (result != nullptr) ? OK : ERR;
1198 };
1199 context->SetAction(env, info, input, exec, output);
1200
1201 RDB_CHECK_RETURN_NULLPTR(context->error == nullptr || context->error->GetCode() == OK, "");
1202 return AsyncCall::Call(env, context);
1203 }
1204
OnDataChangeEvent(napi_env env,size_t argc,napi_value * argv)1205 void RdbStoreProxy::OnDataChangeEvent(napi_env env, size_t argc, napi_value *argv)
1206 {
1207 napi_valuetype type = napi_undefined;
1208 napi_typeof(env, argv[0], &type);
1209 if (type != napi_number) {
1210 LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: first argument is not number.");
1211 return;
1212 }
1213 int32_t mode = SubscribeMode::SUBSCRIBE_MODE_MAX;
1214 napi_get_value_int32(env, argv[0], &mode);
1215 if (mode < 0 || mode >= SubscribeMode::SUBSCRIBE_MODE_MAX) {
1216 LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: first argument value is invalid.");
1217 return;
1218 }
1219 LOG_INFO("RdbStoreProxy::OnDataChangeEvent: mode=%{public}d.", mode);
1220
1221 napi_typeof(env, argv[1], &type);
1222 if (type != napi_function) {
1223 LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: second argument is not function.");
1224 return;
1225 }
1226
1227 std::lock_guard<std::mutex> lockGuard(mutex_);
1228 for (const auto &observer : observers_[mode]) {
1229 if (observer != nullptr && *observer == argv[1]) {
1230 LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: duplicate subscribe.");
1231 return;
1232 }
1233 }
1234 SubscribeOption option;
1235 option.mode = static_cast<SubscribeMode>(mode);
1236 auto observer = std::make_shared<NapiRdbStoreObserver>(env, argv[1]);
1237 int errCode = rdbStore_->Subscribe(option, observer.get());
1238 if (errCode != E_OK) {
1239 LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: subscribe failed.");
1240 return;
1241 }
1242 observers_[mode].push_back(observer);
1243 LOG_INFO("RdbStoreProxy::OnDataChangeEvent: subscribe success, mode is: %{public}d.", mode);
1244 }
1245
OffDataChangeEvent(napi_env env,size_t argc,napi_value * argv)1246 void RdbStoreProxy::OffDataChangeEvent(napi_env env, size_t argc, napi_value *argv)
1247 {
1248 napi_valuetype type = napi_undefined;
1249 napi_typeof(env, argv[0], &type);
1250 if (type != napi_number) {
1251 LOG_ERROR("RdbStoreProxy::OffDataChangeEvent: first argument is not number.");
1252 return;
1253 }
1254 int32_t mode = SubscribeMode::SUBSCRIBE_MODE_MAX;
1255 napi_get_value_int32(env, argv[0], &mode);
1256 if (mode < 0 || mode >= SubscribeMode::SUBSCRIBE_MODE_MAX) {
1257 LOG_ERROR("RdbStoreProxy::OffDataChangeEvent: first argument value is invalid.");
1258 return;
1259 }
1260 LOG_INFO("RdbStoreProxy::OffDataChangeEvent: mode=%{public}d.", mode);
1261
1262 napi_typeof(env, argv[1], &type);
1263 if (type != napi_function) {
1264 LOG_ERROR("RdbStoreProxy::OffDataChangeEvent: second argument is not function.");
1265 return;
1266 }
1267
1268 SubscribeOption option;
1269 option.mode = static_cast<SubscribeMode>(mode);
1270 std::lock_guard<std::mutex> lockGuard(mutex_);
1271 for (auto it = observers_[mode].begin(); it != observers_[mode].end(); it++) {
1272 if (*it != nullptr && **it == argv[1]) {
1273 if (rdbStore_.get() == nullptr) {
1274 LOG_ERROR("RdbStoreProxy::OnDataChangeEvent: rdbStore_ invalid.");
1275 return;
1276 }
1277 rdbStore_->UnSubscribe(option, it->get());
1278 observers_[mode].erase(it);
1279 LOG_INFO("RdbStoreProxy::OffDataChangeEvent: unsubscribe success.");
1280 return;
1281 }
1282 }
1283 LOG_INFO("RdbStoreProxy::OffDataChangeEvent: not found.");
1284 }
1285
OnEvent(napi_env env,napi_callback_info info)1286 napi_value RdbStoreProxy::OnEvent(napi_env env, napi_callback_info info)
1287 {
1288 size_t argc = MAX_ON_EVENT_ARG_NUM;
1289 napi_value argv[MAX_ON_EVENT_ARG_NUM]{};
1290 napi_value self = nullptr;
1291 if (napi_get_cb_info(env, info, &argc, argv, &self, nullptr) != napi_ok) {
1292 LOG_ERROR("RdbStoreProxy::OnEvent: get args failed.");
1293 return nullptr;
1294 }
1295 bool invalid_condition = argc < MIN_ON_EVENT_ARG_NUM || argc > MAX_ON_EVENT_ARG_NUM || self == nullptr;
1296 NAPI_ASSERT(env, !invalid_condition, "RdbStoreProxy::OnEvent: invalid args");
1297
1298 auto proxy = RdbStoreProxy::GetNativeInstance(env, self);
1299 NAPI_ASSERT(env, proxy != nullptr, "RdbStoreProxy::OnEvent: invalid args");
1300
1301 std::string event = JSUtils::Convert2String(env, argv[0]);
1302 if (event == "dataChange") {
1303 proxy->OnDataChangeEvent(env, argc - 1, argv + 1);
1304 }
1305
1306 LOG_INFO("RdbStoreProxy::OnEvent end.");
1307 return nullptr;
1308 }
1309
OffEvent(napi_env env,napi_callback_info info)1310 napi_value RdbStoreProxy::OffEvent(napi_env env, napi_callback_info info)
1311 {
1312 size_t argc = MAX_ON_EVENT_ARG_NUM;
1313 napi_value argv[MAX_ON_EVENT_ARG_NUM]{};
1314 napi_value self = nullptr;
1315 if (napi_get_cb_info(env, info, &argc, argv, &self, nullptr) != napi_ok) {
1316 LOG_ERROR("RdbStoreProxy::OffEvent: get args failed.");
1317 return nullptr;
1318 }
1319 bool invalid_condition = argc < MIN_ON_EVENT_ARG_NUM || argc > MAX_ON_EVENT_ARG_NUM || self == nullptr;
1320 NAPI_ASSERT(env, !invalid_condition, "RdbStoreProxy::OffEvent: invalid args");
1321
1322 auto proxy = RdbStoreProxy::GetNativeInstance(env, self);
1323 NAPI_ASSERT(env, proxy != nullptr, "RdbStoreProxy::OffEvent: invalid args");
1324
1325 std::string event = JSUtils::Convert2String(env, argv[0]);
1326 if (event == "dataChange") {
1327 proxy->OffDataChangeEvent(env, argc - 1, argv + 1);
1328 }
1329
1330 LOG_INFO("RdbStoreProxy::OffEvent end.");
1331 return nullptr;
1332 }
1333 #endif
1334 } // namespace RdbJsKit
1335 } // namespace OHOS
1336