1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #define LOG_TAG "NapiRdbJsUtils"
16 #include "napi_rdb_js_utils.h"
17
18 #include <memory>
19 #include <tuple>
20
21 #include "js_ability.h"
22 #include "js_native_api_types.h"
23 #include "logger.h"
24 #include "rdb_errno.h"
25 #include "rdb_sql_statistic.h"
26 #include "rdb_sql_utils.h"
27 #include "rdb_types.h"
28 #include "result_set.h"
29 #include "transaction.h"
30
31 #define NAPI_CALL_RETURN_ERR(theCall, retVal) \
32 do { \
33 if ((theCall) != napi_ok) { \
34 return retVal; \
35 } \
36 } while (0)
37
38 #ifndef PATH_SPLIT
39 #define PATH_SPLIT '/'
40 #endif
41 namespace OHOS::AppDataMgrJsKit {
42 namespace JSUtils {
43 using namespace OHOS::Rdb;
44 using namespace NativeRdb;
45 using RelationalStoreJsKit::ParamError;
46 using namespace RelationalStoreJsKit;
47 template<>
Convert2Value(napi_env env,napi_value jsValue,Asset & output)48 int32_t Convert2Value(napi_env env, napi_value jsValue, Asset &output)
49 {
50 napi_valuetype type = napi_undefined;
51 napi_status status = napi_typeof(env, jsValue, &type);
52 bool isArray;
53 napi_status status_array = napi_is_array(env, jsValue, &isArray);
54 if (status != napi_ok || type != napi_object || status_array != napi_ok || isArray) {
55 LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type);
56 return napi_invalid_arg;
57 }
58
59 NAPI_CALL_RETURN_ERR(GetNamedProperty(env, jsValue, "name", output.name), napi_invalid_arg);
60 NAPI_CALL_RETURN_ERR(GetNamedProperty(env, jsValue, "uri", output.uri), napi_invalid_arg);
61 NAPI_CALL_RETURN_ERR(GetNamedProperty(env, jsValue, "createTime", output.createTime), napi_invalid_arg);
62 NAPI_CALL_RETURN_ERR(GetNamedProperty(env, jsValue, "modifyTime", output.modifyTime), napi_invalid_arg);
63 NAPI_CALL_RETURN_ERR(GetNamedProperty(env, jsValue, "size", output.size), napi_invalid_arg);
64 NAPI_CALL_RETURN_ERR(GetNamedProperty(env, jsValue, "path", output.path), napi_invalid_arg);
65 NAPI_CALL_RETURN_ERR(GetNamedProperty(env, jsValue, "status", output.status, true), napi_invalid_arg);
66 if (output.status != AssetValue::STATUS_DELETE) {
67 output.status = AssetValue::STATUS_UNKNOWN;
68 }
69 output.hash = output.modifyTime + "_" + output.size;
70 return napi_ok;
71 }
72
73 template<>
Convert2Value(napi_env env,napi_value input,DistributedRdb::Reference & output)74 int32_t Convert2Value(napi_env env, napi_value input, DistributedRdb::Reference &output)
75 {
76 napi_valuetype type = napi_undefined;
77 napi_status status = napi_typeof(env, input, &type);
78 if (status != napi_ok || type != napi_object) {
79 LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type);
80 return napi_invalid_arg;
81 }
82
83 NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "sourceTable", output.sourceTable), napi_invalid_arg);
84 NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "targetTable", output.targetTable), napi_invalid_arg);
85 NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "refFields", output.refFields), napi_invalid_arg);
86 return napi_ok;
87 }
88
89 template<>
Convert2Value(napi_env env,napi_value input,DistributedRdb::DistributedConfig & output)90 int32_t Convert2Value(napi_env env, napi_value input, DistributedRdb::DistributedConfig &output)
91 {
92 napi_valuetype type = napi_undefined;
93 napi_status status = napi_typeof(env, input, &type);
94 if (status != napi_ok || type != napi_object) {
95 LOG_DEBUG("napi_typeof failed status = %{public}d type = %{public}d", status, type);
96 return napi_invalid_arg;
97 }
98
99 NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "autoSync", output.autoSync), napi_invalid_arg);
100 NAPI_CALL_RETURN_ERR(GetNamedProperty(env, input, "references", output.references, true), napi_invalid_arg);
101 return napi_ok;
102 }
103
104 template<>
Convert2Value(napi_env env,napi_value jsValue,ValueObject & valueObject)105 int32_t Convert2Value(napi_env env, napi_value jsValue, ValueObject &valueObject)
106 {
107 auto status = Convert2Value(env, jsValue, valueObject.value);
108 if (status != napi_ok) {
109 return napi_invalid_arg;
110 }
111 return napi_ok;
112 }
113
114 template<>
Convert2JSValue(napi_env env,const Asset & value)115 napi_value Convert2JSValue(napi_env env, const Asset &value)
116 {
117 auto outputStatus = value.status & ~0xF0000000;
118 std::vector<napi_property_descriptor> descriptors = {
119 DECLARE_JS_PROPERTY(env, "name", value.name),
120 DECLARE_JS_PROPERTY(env, "uri", value.uri),
121 DECLARE_JS_PROPERTY(env, "createTime", value.createTime),
122 DECLARE_JS_PROPERTY(env, "modifyTime", value.modifyTime),
123 DECLARE_JS_PROPERTY(env, "size", value.size),
124 DECLARE_JS_PROPERTY(env, "path", value.path),
125 DECLARE_JS_PROPERTY(env, "status", outputStatus),
126 };
127
128 napi_value object = nullptr;
129 NAPI_CALL_RETURN_ERR(
130 napi_create_object_with_properties(env, &object, descriptors.size(), descriptors.data()), object);
131 return object;
132 }
133
134 template<>
Convert2JSValue(napi_env env,const RowEntity & rowEntity)135 napi_value Convert2JSValue(napi_env env, const RowEntity &rowEntity)
136 {
137 napi_value object = nullptr;
138 NAPI_CALL_RETURN_ERR(napi_create_object(env, &object), object);
139 auto &values = rowEntity.Get();
140 for (auto const &[key, value] : values) {
141 NAPI_CALL_RETURN_ERR(SetNamedProperty(env, object, key.c_str(), value), object);
142 }
143 return object;
144 }
145
146 template<>
Convert2JSValue(napi_env env,const ValueObject & value)147 napi_value Convert2JSValue(napi_env env, const ValueObject &value)
148 {
149 return Convert2JSValue(env, value.value);
150 }
151
152 template<>
Convert2JSValue(napi_env env,const DistributedRdb::Statistic & value)153 napi_value Convert2JSValue(napi_env env, const DistributedRdb::Statistic &value)
154 {
155 std::vector<napi_property_descriptor> descriptors = {
156 DECLARE_JS_PROPERTY(env, "total", value.total),
157 DECLARE_JS_PROPERTY(env, "success", value.success),
158 DECLARE_JS_PROPERTY(env, "successful", value.success),
159 DECLARE_JS_PROPERTY(env, "failed", value.failed),
160 DECLARE_JS_PROPERTY(env, "remained", value.untreated),
161 };
162
163 napi_value object = nullptr;
164 NAPI_CALL_RETURN_ERR(
165 napi_create_object_with_properties(env, &object, descriptors.size(), descriptors.data()), object);
166 return object;
167 }
168
169 template<>
Convert2JSValue(napi_env env,const DistributedRdb::TableDetail & value)170 napi_value Convert2JSValue(napi_env env, const DistributedRdb::TableDetail &value)
171 {
172 std::vector<napi_property_descriptor> descriptors = {
173 DECLARE_JS_PROPERTY(env, "upload", value.upload),
174 DECLARE_JS_PROPERTY(env, "download", value.download),
175 };
176
177 napi_value object = nullptr;
178 NAPI_CALL_RETURN_ERR(
179 napi_create_object_with_properties(env, &object, descriptors.size(), descriptors.data()), object);
180 return object;
181 }
182
183 template<>
Convert2JSValue(napi_env env,const DistributedRdb::ProgressDetail & value)184 napi_value Convert2JSValue(napi_env env, const DistributedRdb::ProgressDetail &value)
185 {
186 std::vector<napi_property_descriptor> descriptors = {
187 DECLARE_JS_PROPERTY(env, "schedule", value.progress),
188 DECLARE_JS_PROPERTY(env, "code", value.code),
189 DECLARE_JS_PROPERTY(env, "details", value.details),
190 };
191
192 napi_value object = nullptr;
193 NAPI_CALL_RETURN_ERR(
194 napi_create_object_with_properties(env, &object, descriptors.size(), descriptors.data()), object);
195 return object;
196 }
197
198 template<>
Convert2JSValue(napi_env env,const DistributedRdb::SqlObserver::SqlExecutionInfo & value)199 napi_value Convert2JSValue(napi_env env, const DistributedRdb::SqlObserver::SqlExecutionInfo &value)
200 {
201 std::vector<napi_property_descriptor> descriptors = {
202 DECLARE_JS_PROPERTY(env, "sql", value.sql_),
203 DECLARE_JS_PROPERTY(env, "totalTime", value.totalTime_),
204 DECLARE_JS_PROPERTY(env, "waitTime", value.waitTime_),
205 DECLARE_JS_PROPERTY(env, "prepareTime", value.prepareTime_),
206 DECLARE_JS_PROPERTY(env, "executeTime", value.executeTime_),
207 };
208
209 napi_value object = nullptr;
210 NAPI_CALL_RETURN_ERR(
211 napi_create_object_with_properties(env, &object, descriptors.size(), descriptors.data()), object);
212 return object;
213 }
214
215 template<>
Convert2JSValue(napi_env env,const DistributedRdb::Details & details)216 napi_value Convert2JSValue(napi_env env, const DistributedRdb::Details &details)
217 {
218 return nullptr;
219 }
220
221 template<>
Convert2JSValue(napi_env env,const JSChangeInfo & value)222 napi_value Convert2JSValue(napi_env env, const JSChangeInfo &value)
223 {
224 std::vector<napi_property_descriptor> descriptors = {
225 DECLARE_JS_PROPERTY(env, "table", value.table),
226 DECLARE_JS_PROPERTY(env, "type", value.type),
227 DECLARE_JS_PROPERTY(env, "inserted", value.inserted),
228 DECLARE_JS_PROPERTY(env, "updated", value.updated),
229 DECLARE_JS_PROPERTY(env, "deleted", value.deleted),
230 };
231
232 napi_value object = nullptr;
233 NAPI_CALL_RETURN_ERR(
234 napi_create_object_with_properties(env, &object, descriptors.size(), descriptors.data()), object);
235 return object;
236 }
237
238 template<>
Convert2JSValue(napi_env env,const Date & date)239 napi_value Convert2JSValue(napi_env env, const Date &date)
240 {
241 napi_value jsDeta = nullptr;
242 NAPI_CALL_RETURN_ERR(napi_create_date(env, date, &jsDeta), jsDeta);
243 return jsDeta;
244 }
245 template<>
Convert2JSValue(napi_env env,const BigInt & value)246 napi_value Convert2JSValue(napi_env env, const BigInt &value)
247 {
248 napi_value val = nullptr;
249 napi_status status = napi_create_bigint_words(env, value.Sign(), value.Size(), value.TrueForm(), &val);
250 if (status != napi_ok) {
251 return nullptr;
252 }
253 return val;
254 }
255
256 template<>
Convert2Value(napi_env env,napi_value jsValue,BigInt & value)257 int32_t Convert2Value(napi_env env, napi_value jsValue, BigInt &value)
258 {
259 napi_valuetype type = napi_undefined;
260 napi_status status = napi_typeof(env, jsValue, &type);
261 if (status != napi_ok || type != napi_bigint) {
262 return napi_invalid_arg;
263 }
264 int sign = 0;
265 size_t count = 0;
266 status = napi_get_value_bigint_words(env, jsValue, nullptr, &count, nullptr);
267 if (status != napi_ok) {
268 return napi_bigint_expected;
269 }
270 std::vector<uint64_t> words(count, 0);
271 status = napi_get_value_bigint_words(env, jsValue, &sign, &count, words.data());
272 if (status != napi_ok) {
273 return napi_bigint_expected;
274 }
275 value = BigInteger(sign, std::move(words));
276 return napi_ok;
277 }
278
279 template<>
ToString(const PRIKey & key)280 std::string ToString(const PRIKey &key)
281 {
282 auto strVal = std::get_if<std::string>(&key);
283 if (strVal != nullptr) {
284 return *strVal;
285 }
286 auto intVal = std::get_if<int64_t>(&key);
287 if (intVal != nullptr) {
288 return std::to_string(*intVal);
289 }
290 auto dbVal = std::get_if<double>(&key);
291 if (dbVal != nullptr) {
292 return std::to_string(static_cast<int64_t>(*dbVal));
293 }
294 return {};
295 }
296
IsNapiString(napi_env env,napi_value value)297 bool IsNapiString(napi_env env, napi_value value)
298 {
299 napi_valuetype type = napi_undefined;
300 NAPI_CALL_BASE(env, napi_typeof(env, value, &type), false);
301 return type == napi_string;
302 }
303
GetLevel(SecurityLevel level,SecurityLevel & out)304 int32_t GetLevel(SecurityLevel level, SecurityLevel &out)
305 {
306 switch (level) {
307 case SecurityLevel::S1:
308 case SecurityLevel::S2:
309 case SecurityLevel::S3:
310 case SecurityLevel::S4:
311 out = level;
312 return napi_ok;
313 default:
314 return napi_invalid_arg;
315 }
316 }
317
318 template<>
Convert2Value(napi_env env,napi_value jsValue,RdbConfig & rdbConfig)319 int32_t Convert2Value(napi_env env, napi_value jsValue, RdbConfig &rdbConfig)
320 {
321 int32_t status = GetNamedProperty(env, jsValue, "encrypt", rdbConfig.isEncrypt, true);
322 ASSERT(OK == status, "get encrypt failed.", napi_invalid_arg);
323
324 int32_t securityLevel;
325 status = GetNamedProperty(env, jsValue, "securityLevel", securityLevel);
326 ASSERT(OK == status, "get securityLevel failed.", napi_invalid_arg);
327 status = GetLevel(static_cast<SecurityLevel>(securityLevel), rdbConfig.securityLevel);
328 ASSERT(status == napi_ok, "get securityLevel failed", status);
329
330 status = GetNamedProperty(env, jsValue, "dataGroupId", rdbConfig.dataGroupId, true);
331 ASSERT(OK == status, "get dataGroupId failed.", napi_invalid_arg);
332
333 status = GetNamedProperty(env, jsValue, "autoCleanDirtyData", rdbConfig.isAutoClean, true);
334 ASSERT(OK == status, "get autoCleanDirtyData failed.", napi_invalid_arg);
335
336 status = GetNamedProperty(env, jsValue, "name", rdbConfig.name);
337 ASSERT(OK == status, "get name failed.", napi_invalid_arg);
338
339 status = GetNamedProperty(env, jsValue, "customDir", rdbConfig.customDir, true);
340 ASSERT(OK == status, "get customDir failed.", napi_invalid_arg);
341
342 GetNamedProperty(env, jsValue, "isSearchable", rdbConfig.isSearchable, true);
343 ASSERT(OK == status, "get isSearchable failed.", napi_invalid_arg);
344
345 GetNamedProperty(env, jsValue, "vector", rdbConfig.vector, true);
346 ASSERT(OK == status, "get vector failed.", napi_invalid_arg);
347
348 GetNamedProperty(env, jsValue, "allowRebuild", rdbConfig.allowRebuild, true);
349 ASSERT(OK == status, "get allowRebuild failed.", napi_invalid_arg);
350
351 GetNamedProperty(env, jsValue, "isReadOnly", rdbConfig.isReadOnly, true);
352 ASSERT(OK == status, "get isReadOnly failed.", napi_invalid_arg);
353
354 GetNamedProperty(env, jsValue, "pluginLibs", rdbConfig.pluginLibs, true);
355 ASSERT(OK == status, "get pluginLibs failed.", napi_invalid_arg);
356
357 status = GetNamedProperty(env, jsValue, "haMode", rdbConfig.haMode, true);
358 ASSERT(OK == status, "get haMode failed.", napi_invalid_arg);
359 return napi_ok;
360 }
361
362 template<>
Convert2Value(napi_env env,napi_value jsValue,TransactionOptions & transactionOptions)363 int32_t Convert2Value(napi_env env, napi_value jsValue, TransactionOptions &transactionOptions)
364 {
365 int32_t status = GetNamedProperty(env, jsValue, "transactionType", transactionOptions.transactionType, true);
366 bool checked = transactionOptions.transactionType >= Transaction::DEFERRED &&
367 transactionOptions.transactionType <= Transaction::EXCLUSIVE;
368 ASSERT(OK == status && checked, "get transactionType failed.", napi_invalid_arg);
369 return napi_ok;
370 }
371
GetCurrentAbilityParam(napi_env env,napi_value jsValue,ContextParam & param)372 int32_t GetCurrentAbilityParam(napi_env env, napi_value jsValue, ContextParam ¶m)
373 {
374 std::shared_ptr<Context> context = JSAbility::GetCurrentAbility(env, jsValue);
375 if (context == nullptr) {
376 return napi_invalid_arg;
377 }
378 param.baseDir = context->GetDatabaseDir();
379 param.moduleName = context->GetModuleName();
380 param.area = context->GetArea();
381 param.bundleName = context->GetBundleName();
382 param.isSystemApp = context->IsSystemAppCalled();
383 return napi_ok;
384 }
385
386 template<>
Convert2Value(napi_env env,napi_value jsValue,ContextParam & param)387 int32_t Convert2Value(napi_env env, napi_value jsValue, ContextParam ¶m)
388 {
389 if (jsValue == nullptr) {
390 LOG_INFO("hasProp is false -> fa stage");
391 param.isStageMode = false;
392 return GetCurrentAbilityParam(env, jsValue, param);
393 }
394
395 int32_t status = GetNamedProperty(env, jsValue, "stageMode", param.isStageMode);
396 ASSERT(status == napi_ok, "get stageMode param failed", napi_invalid_arg);
397 if (!param.isStageMode) {
398 LOG_WARN("isStageMode is false -> fa stage");
399 return GetCurrentAbilityParam(env, jsValue, param);
400 }
401 LOG_DEBUG("stage mode branch");
402 status = GetNamedProperty(env, jsValue, "databaseDir", param.baseDir);
403 ASSERT(status == napi_ok, "get databaseDir failed.", napi_invalid_arg);
404 status = GetNamedProperty(env, jsValue, "area", param.area, true);
405 ASSERT(status == napi_ok, "get area failed.", napi_invalid_arg);
406
407 napi_value hapInfo = nullptr;
408 GetNamedProperty(env, jsValue, "currentHapModuleInfo", hapInfo);
409 if (hapInfo != nullptr) {
410 status = GetNamedProperty(env, hapInfo, "name", param.moduleName);
411 ASSERT(status == napi_ok, "get currentHapModuleInfo.name failed.", napi_invalid_arg);
412 }
413
414 napi_value appInfo = nullptr;
415 GetNamedProperty(env, jsValue, "applicationInfo", appInfo);
416 if (appInfo != nullptr) {
417 status = GetNamedProperty(env, appInfo, "name", param.bundleName);
418 ASSERT(status == napi_ok, "get applicationInfo.name failed.", napi_invalid_arg);
419 status = GetNamedProperty(env, appInfo, "systemApp", param.isSystemApp, true);
420 ASSERT(status == napi_ok, "get applicationInfo.systemApp failed.", napi_invalid_arg);
421 int32_t hapVersion = JSAbility::GetHapVersion(env, jsValue);
422 JSUtils::SetHapVersion(hapVersion);
423 }
424 return napi_ok;
425 }
426
GetRealPath(napi_env env,napi_value jsValue,RdbConfig & rdbConfig,ContextParam & param)427 std::tuple<int32_t, std::shared_ptr<Error>> GetRealPath(
428 napi_env env, napi_value jsValue, RdbConfig &rdbConfig, ContextParam ¶m)
429 {
430 CHECK_RETURN_CORE(rdbConfig.name.find(PATH_SPLIT) == std::string::npos, RDB_DO_NOTHING,
431 std::make_tuple(ERR, std::make_shared<ParamError>("StoreConfig.name", "a file name without path.")));
432
433 if (!rdbConfig.customDir.empty()) {
434 // determine if the first character of customDir is '/'
435 CHECK_RETURN_CORE(rdbConfig.customDir.find_first_of(PATH_SPLIT) != 0, RDB_DO_NOTHING,
436 std::make_tuple(ERR, std::make_shared<ParamError>("customDir", "a relative directory.")));
437 // customDir length is limited to 128 bytes
438 CHECK_RETURN_CORE(rdbConfig.customDir.length() <= 128, RDB_DO_NOTHING,
439 std::make_tuple(ERR, std::make_shared<ParamError>("customDir length", "less than or equal to 128 "
440 "bytes.")));
441 }
442
443 std::string baseDir = param.baseDir;
444 if (!rdbConfig.dataGroupId.empty()) {
445 if (!param.isStageMode) {
446 return std::make_tuple(ERR, std::make_shared<InnerError>(E_NOT_STAGE_MODE));
447 }
448 auto stageContext = JSAbility::GetStageModeContext(env, jsValue);
449 if (stageContext == nullptr) {
450 return std::make_tuple(ERR, std::make_shared<ParamError>("Illegal context."));
451 }
452 std::string groupDir;
453 int errCode = stageContext->GetSystemDatabaseDir(rdbConfig.dataGroupId, groupDir);
454 CHECK_RETURN_CORE(errCode == E_OK || !groupDir.empty(), RDB_DO_NOTHING,
455 std::make_tuple(ERR, std::make_shared<InnerError>(E_DATA_GROUP_ID_INVALID)));
456 baseDir = groupDir;
457 }
458
459 auto [realPath, errorCode] = RdbSqlUtils::GetDefaultDatabasePath(baseDir, rdbConfig.name, rdbConfig.customDir);
460 // realPath length is limited to 1024 bytes
461 CHECK_RETURN_CORE(errorCode == E_OK && realPath.length() <= 1024, RDB_DO_NOTHING,
462 std::make_tuple(ERR, std::make_shared<ParamError>("database path", "a valid path.")));
463 rdbConfig.path = realPath;
464 return std::make_tuple(E_OK, nullptr);
465 }
466
GetRdbStoreConfig(const RdbConfig & rdbConfig,const ContextParam & param)467 RdbStoreConfig GetRdbStoreConfig(const RdbConfig &rdbConfig, const ContextParam ¶m)
468 {
469 RdbStoreConfig rdbStoreConfig(rdbConfig.path);
470 rdbStoreConfig.SetEncryptStatus(rdbConfig.isEncrypt);
471 rdbStoreConfig.SetSearchable(rdbConfig.isSearchable);
472 rdbStoreConfig.SetIsVector(rdbConfig.vector);
473 rdbConfig.vector ? rdbStoreConfig.SetDBType(DB_VECTOR) : rdbStoreConfig.SetDBType(DB_SQLITE);
474 rdbStoreConfig.SetAutoClean(rdbConfig.isAutoClean);
475 rdbStoreConfig.SetSecurityLevel(rdbConfig.securityLevel);
476 rdbStoreConfig.SetDataGroupId(rdbConfig.dataGroupId);
477 rdbStoreConfig.SetName(rdbConfig.name);
478 rdbStoreConfig.SetCustomDir(rdbConfig.customDir);
479 rdbStoreConfig.SetAllowRebuild(rdbConfig.allowRebuild);
480 rdbStoreConfig.SetReadOnly(rdbConfig.isReadOnly);
481 rdbStoreConfig.SetIntegrityCheck(IntegrityCheck::NONE);
482
483 if (!param.bundleName.empty()) {
484 rdbStoreConfig.SetBundleName(param.bundleName);
485 }
486 rdbStoreConfig.SetModuleName(param.moduleName);
487 rdbStoreConfig.SetArea(param.area);
488 rdbStoreConfig.SetPluginLibs(rdbConfig.pluginLibs);
489 rdbStoreConfig.SetHaMode(rdbConfig.haMode);
490 return rdbStoreConfig;
491 }
492
HasDuplicateAssets(const ValueObject & value)493 bool HasDuplicateAssets(const ValueObject &value)
494 {
495 auto *assets = std::get_if<ValueObject::Assets>(&value.value);
496 if (assets == nullptr) {
497 return false;
498 }
499 std::set<std::string> names;
500 auto item = assets->begin();
501 while (item != assets->end()) {
502 if (!names.insert(item->name).second) {
503 LOG_ERROR("duplicate assets! name = %{public}.6s", item->name.c_str());
504 return true;
505 }
506 item++;
507 }
508 return false;
509 }
510
HasDuplicateAssets(const std::vector<ValueObject> & values)511 bool HasDuplicateAssets(const std::vector<ValueObject> &values)
512 {
513 for (auto &val : values) {
514 if (HasDuplicateAssets(val)) {
515 return true;
516 }
517 }
518 return false;
519 }
520
HasDuplicateAssets(const ValuesBucket & value)521 bool HasDuplicateAssets(const ValuesBucket &value)
522 {
523 for (auto &[key, val] : value.values_) {
524 if (HasDuplicateAssets(val)) {
525 return true;
526 }
527 }
528 return false;
529 }
530
HasDuplicateAssets(const std::vector<ValuesBucket> & values)531 bool HasDuplicateAssets(const std::vector<ValuesBucket> &values)
532 {
533 for (auto &valueBucket : values) {
534 if (HasDuplicateAssets(valueBucket)) {
535 return true;
536 }
537 }
538 return false;
539 }
540
HasDuplicateAssets(const ValuesBuckets & values)541 bool HasDuplicateAssets(const ValuesBuckets &values)
542 {
543 const auto &[fields, vals] = values.GetFieldsAndValues();
544 for (const auto &valueObject : *vals) {
545 if (HasDuplicateAssets(valueObject)) {
546 return true;
547 }
548 }
549 return false;
550 }
551 }; // namespace JSUtils
552 } // namespace OHOS::AppDataMgrJsKit