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 "RelationalStore"
16 #include "relational_store.h"
17
18 #include "convertor_error_code.h"
19 #include "grd_api_manager.h"
20 #include "logger.h"
21 #include "modify_time_cursor.h"
22 #include "oh_data_define.h"
23 #include "oh_data_utils.h"
24 #include "raw_data_parser.h"
25 #include "rdb_errno.h"
26 #include "rdb_helper.h"
27 #include "rdb_ndk_utils.h"
28 #include "rdb_predicates.h"
29 #include "rdb_sql_utils.h"
30 #include "rdb_store_config.h"
31 #include "relational_cursor.h"
32 #include "relational_predicates.h"
33 #include "relational_predicates_objects.h"
34 #include "relational_store_error_code.h"
35 #include "relational_store_impl.h"
36 #include "relational_store_inner_types.h"
37 #include "relational_types_v0.h"
38 #include "relational_values_bucket.h"
39 #include "securec.h"
40 #include "sqlite_global_config.h"
41 #include "values_buckets.h"
42 #include "sqlite_utils.h"
43
44 using namespace OHOS::RdbNdk;
45 using namespace OHOS::DistributedRdb;
46 constexpr int RDB_STORE_CID = 1234560; // The class id used to uniquely identify the OH_Rdb_Store class.
47 constexpr int RDB_CONFIG_SIZE_V0 = 41;
48 constexpr int RDB_CONFIG_SIZE_V1 = 45;
49 constexpr int RDB_ATTACH_WAIT_TIME_MIN = 1;
50 constexpr int RDB_ATTACH_WAIT_TIME_MAX = 300;
51 constexpr int RDB_CONFIG_PLUGINS_MAX = 16;
52 constexpr int RDB_CONFIG_CUST_DIR_MAX_LEN = 128;
53
54 static int g_supportDbTypes[] = { RDB_SQLITE, RDB_CAYLEY };
55
OH_Rdb_CreateConfig()56 OH_Rdb_ConfigV2 *OH_Rdb_CreateConfig()
57 {
58 return new (std::nothrow) OH_Rdb_ConfigV2();
59 }
60
OH_Rdb_DestroyConfig(OH_Rdb_ConfigV2 * config)61 int OH_Rdb_DestroyConfig(OH_Rdb_ConfigV2 *config)
62 {
63 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) {
64 LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when destroy.", (config == nullptr),
65 (config == nullptr ? 0 : config->magicNum));
66 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
67 }
68 delete config;
69 config = nullptr;
70 return OH_Rdb_ErrCode::RDB_OK;
71 }
72
OH_Rdb_SetDatabaseDir(OH_Rdb_ConfigV2 * config,const char * dataBaseDir)73 int OH_Rdb_SetDatabaseDir(OH_Rdb_ConfigV2 *config, const char *dataBaseDir)
74 {
75 if (config == nullptr || dataBaseDir == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) {
76 LOG_ERROR("config is null %{public}d or dataBaseDir %{public}d magic num not valid %{public}x "
77 "when Set DataBaseDir.",
78 (config == nullptr), (dataBaseDir == nullptr), (config == nullptr ? 0 : config->magicNum));
79 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
80 }
81 config->dataBaseDir = std::string(dataBaseDir);
82 return OH_Rdb_ErrCode::RDB_OK;
83 }
84
OH_Rdb_SetStoreName(OH_Rdb_ConfigV2 * config,const char * storeName)85 int OH_Rdb_SetStoreName(OH_Rdb_ConfigV2 *config, const char *storeName)
86 {
87 if (config == nullptr || storeName == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) {
88 LOG_ERROR("config is null %{public}d or storeName %{public}d or magic num not ok"
89 "%{public}x When set storeName.",
90 (config == nullptr), (storeName == nullptr), (config == nullptr ? 0 : config->magicNum));
91 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
92 }
93 config->storeName = std::string(storeName);
94 return OH_Rdb_ErrCode::RDB_OK;
95 }
96
OH_Rdb_SetBundleName(OH_Rdb_ConfigV2 * config,const char * bundleName)97 int OH_Rdb_SetBundleName(OH_Rdb_ConfigV2 *config, const char *bundleName)
98 {
99 if (config == nullptr || bundleName == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) {
100 LOG_ERROR("config is null %{public}d or bundleName %{public}d magic num no ok %{public}x when set bundleName.",
101 (config == nullptr), (bundleName == nullptr), (config == nullptr ? 0 : config->magicNum));
102 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
103 }
104 config->bundleName = std::string(bundleName);
105 return OH_Rdb_ErrCode::RDB_OK;
106 }
107
OH_Rdb_SetModuleName(OH_Rdb_ConfigV2 * config,const char * moduleName)108 int OH_Rdb_SetModuleName(OH_Rdb_ConfigV2 *config, const char *moduleName)
109 {
110 if (config == nullptr || moduleName == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) {
111 LOG_ERROR("config is null %{public}d or moduleName %{public}d magic num no ok %{public}x when set moduleName.",
112 (config == nullptr), (moduleName == nullptr), (config == nullptr ? 0 : config->magicNum));
113 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
114 }
115 config->moduleName = std::string(moduleName);
116 return OH_Rdb_ErrCode::RDB_OK;
117 }
118
OH_Rdb_SetEncrypted(OH_Rdb_ConfigV2 * config,bool isEncrypted)119 int OH_Rdb_SetEncrypted(OH_Rdb_ConfigV2 *config, bool isEncrypted)
120 {
121 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) {
122 LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when set encrypt.", (config == nullptr),
123 (config == nullptr ? 0 : config->magicNum));
124 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
125 }
126 config->isEncrypt = isEncrypted;
127 return OH_Rdb_ErrCode::RDB_OK;
128 }
129
OH_Rdb_SetSecurityLevel(OH_Rdb_ConfigV2 * config,int securityLevel)130 int OH_Rdb_SetSecurityLevel(OH_Rdb_ConfigV2 *config, int securityLevel)
131 {
132 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) {
133 LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when set security level.",
134 (config == nullptr), (config == nullptr ? 0 : config->magicNum));
135 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
136 }
137 if (securityLevel < S1 || securityLevel > S4) {
138 LOG_ERROR("securityLevel value is out of range %{public}d", securityLevel);
139 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
140 }
141 config->securityLevel = securityLevel;
142 return OH_Rdb_ErrCode::RDB_OK;
143 }
144
OH_Rdb_SetArea(OH_Rdb_ConfigV2 * config,int area)145 int OH_Rdb_SetArea(OH_Rdb_ConfigV2 *config, int area)
146 {
147 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) {
148 LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when set area.", (config == nullptr),
149 (config == nullptr ? 0 : config->magicNum));
150 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
151 }
152 if (area < RDB_SECURITY_AREA_EL1 || area > RDB_SECURITY_AREA_EL5) {
153 LOG_ERROR("area value is out of range %{public}d", area);
154 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
155 }
156 config->area = area;
157 return OH_Rdb_ErrCode::RDB_OK;
158 }
159
OH_Rdb_SetSemanticIndex(OH_Rdb_ConfigV2 * config,bool isEnable)160 int OH_Rdb_SetSemanticIndex(OH_Rdb_ConfigV2 *config, bool isEnable)
161 {
162 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) {
163 LOG_ERROR("config is null %{public}d or magic num not valid %{public}x when set SemanticIndex.",
164 (config == nullptr), (config == nullptr ? 0 : config->magicNum));
165 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
166 }
167 config->enableSemanticIndex = isEnable;
168 return OH_Rdb_ErrCode::RDB_OK;
169 }
170
OH_Rdb_SetDbType(OH_Rdb_ConfigV2 * config,int dbType)171 int OH_Rdb_SetDbType(OH_Rdb_ConfigV2 *config, int dbType)
172 {
173 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE) ||
174 (dbType < RDB_SQLITE || dbType > RDB_CAYLEY)) {
175 LOG_ERROR("config is null %{public}d or magicNum not valid %{public}d or dbType is out of range %{public}d",
176 (config == nullptr), (config == nullptr ? 0 : config->magicNum), dbType);
177 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
178 }
179 if (dbType == RDB_CAYLEY && !(OHOS::NativeRdb::IsUsingArkData())) {
180 return OH_Rdb_ErrCode::RDB_E_NOT_SUPPORTED;
181 }
182 config->dbType = dbType;
183 return OH_Rdb_ErrCode::RDB_OK;
184 }
185
OH_Rdb_SetCustomDir(OH_Rdb_ConfigV2 * config,const char * customDir)186 int OH_Rdb_SetCustomDir(OH_Rdb_ConfigV2 *config, const char *customDir)
187 {
188 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE) || customDir == nullptr ||
189 strlen(customDir) > RDB_CONFIG_CUST_DIR_MAX_LEN) {
190 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
191 }
192 config->customDir = customDir;
193 return OH_Rdb_ErrCode::RDB_OK;
194 }
195
OH_Rdb_SetReadOnly(OH_Rdb_ConfigV2 * config,bool readOnly)196 int OH_Rdb_SetReadOnly(OH_Rdb_ConfigV2 *config, bool readOnly)
197 {
198 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) {
199 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
200 }
201 config->readOnly = readOnly;
202 return OH_Rdb_ErrCode::RDB_OK;
203 }
204
OH_Rdb_SetPlugins(OH_Rdb_ConfigV2 * config,const char ** plugins,int32_t length)205 int OH_Rdb_SetPlugins(OH_Rdb_ConfigV2 *config, const char **plugins, int32_t length)
206 {
207 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE) || plugins == nullptr ||
208 length > RDB_CONFIG_PLUGINS_MAX) {
209 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
210 }
211 for (int i = 0; i < length; i++) {
212 config->pluginLibs.push_back(plugins[i]);
213 }
214 return OH_Rdb_ErrCode::RDB_OK;
215 }
216
OH_Rdb_SetCryptoParam(OH_Rdb_ConfigV2 * config,const OH_Rdb_CryptoParam * cryptoParam)217 int OH_Rdb_SetCryptoParam(OH_Rdb_ConfigV2 *config, const OH_Rdb_CryptoParam *cryptoParam)
218 {
219 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE) ||
220 cryptoParam == nullptr || !cryptoParam->IsValid()) {
221 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
222 }
223 config->cryptoParam = cryptoParam->cryptoParam;
224 return OH_Rdb_ErrCode::RDB_OK;
225 }
226
OH_Rdb_IsTokenizerSupported(Rdb_Tokenizer tokenizer,bool * isSupported)227 int OH_Rdb_IsTokenizerSupported(Rdb_Tokenizer tokenizer, bool *isSupported)
228 {
229 if (tokenizer < RDB_NONE_TOKENIZER || tokenizer > RDB_CUSTOM_TOKENIZER) {
230 LOG_ERROR("token is out of range %{public}d", tokenizer);
231 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
232 }
233 if (isSupported == nullptr) {
234 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
235 }
236 *isSupported = OHOS::NativeRdb::RdbHelper::IsSupportedTokenizer(static_cast<OHOS::NativeRdb::Tokenizer>(tokenizer));
237 return OH_Rdb_ErrCode::RDB_OK;
238 }
239
OH_Rdb_SetTokenizer(OH_Rdb_ConfigV2 * config,Rdb_Tokenizer tokenizer)240 int OH_Rdb_SetTokenizer(OH_Rdb_ConfigV2 *config, Rdb_Tokenizer tokenizer)
241 {
242 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE) ||
243 (tokenizer < RDB_NONE_TOKENIZER || tokenizer > RDB_CUSTOM_TOKENIZER)) {
244 LOG_ERROR("config is null %{public}d or magicNum not valid %{public}d or token is out of range %{public}d",
245 (config == nullptr), (config == nullptr ? 0 : config->magicNum), tokenizer);
246 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
247 }
248 if (config->dbType != Rdb_DBType::RDB_SQLITE) {
249 LOG_ERROR("ICU Tokenizer only support sqlite db type.");
250 return OH_Rdb_ErrCode::RDB_E_NOT_SUPPORTED;
251 }
252 config->token = tokenizer;
253 return OH_Rdb_ErrCode::RDB_OK;
254 }
255
OH_Rdb_SetPersistent(OH_Rdb_ConfigV2 * config,bool isPersistent)256 int OH_Rdb_SetPersistent(OH_Rdb_ConfigV2 *config, bool isPersistent)
257 {
258 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) {
259 LOG_ERROR("config is null %{public}d or magicNum not valid %{public}d. isPersistent %{public}d",
260 (config == nullptr), (config == nullptr ? 0 : config->magicNum), isPersistent);
261 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
262 }
263 config->persist = isPersistent;
264 return OH_Rdb_ErrCode::RDB_OK;
265 }
266
OH_Rdb_GetSupportedDbType(int * numType)267 const int *OH_Rdb_GetSupportedDbType(int *numType)
268 {
269 if (numType == nullptr) {
270 return nullptr;
271 }
272 // if use arkData, then numType will be 2 {RDB_SQLITE and RDB_CAYLEY}, otherwise only 1 {RDB_SQLITE}
273 *numType = OHOS::NativeRdb::IsUsingArkData() ? 2 : 1;
274 return g_supportDbTypes;
275 }
276
OH_Rdb_CreateValueObject()277 OH_VObject *OH_Rdb_CreateValueObject()
278 {
279 return new (std::nothrow) RelationalPredicatesObjects();
280 }
281
OH_Rdb_CreateValuesBucket()282 OH_VBucket *OH_Rdb_CreateValuesBucket()
283 {
284 return new (std::nothrow) RelationalValuesBucket();
285 }
286
OH_Rdb_CreatePredicates(const char * table)287 OH_Predicates *OH_Rdb_CreatePredicates(const char *table)
288 {
289 if (table == nullptr) {
290 return nullptr;
291 }
292 return new (std::nothrow) RelationalPredicate(table);
293 }
294
RelationalStore(std::shared_ptr<OHOS::NativeRdb::RdbStore> store)295 OHOS::RdbNdk::RelationalStore::RelationalStore(std::shared_ptr<OHOS::NativeRdb::RdbStore> store) : store_(store)
296 {
297 id = RDB_STORE_CID;
298 }
299
SubscribeAutoSyncProgress(const Rdb_ProgressObserver * callback)300 int RelationalStore::SubscribeAutoSyncProgress(const Rdb_ProgressObserver *callback)
301 {
302 std::lock_guard<decltype(mutex_)> lock(mutex_);
303 bool result = std::any_of(
304 callbacks_.begin(), callbacks_.end(), [callback](const auto &observer) { return *observer == callback; });
305 if (result) {
306 LOG_INFO("duplicate subscribe.");
307 return OH_Rdb_ErrCode::RDB_OK;
308 }
309 auto obs = std::make_shared<NDKDetailProgressObserver>(callback);
310 if (store_ == nullptr) {
311 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
312 }
313 int errCode = store_->RegisterAutoSyncCallback(obs);
314 if (errCode == NativeRdb::E_OK) {
315 LOG_ERROR("subscribe failed.");
316 return ConvertorErrorCode::NativeToNdk(errCode);
317 }
318 callbacks_.push_back(std::move(obs));
319 return OH_Rdb_ErrCode::RDB_OK;
320 }
321
UnsubscribeAutoSyncProgress(const Rdb_ProgressObserver * callback)322 int RelationalStore::UnsubscribeAutoSyncProgress(const Rdb_ProgressObserver *callback)
323 {
324 std::lock_guard<decltype(mutex_)> lock(mutex_);
325 if (store_ == nullptr) {
326 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
327 }
328 for (auto it = callbacks_.begin(); it != callbacks_.end();) {
329 if (callback != nullptr && !(**it == callback)) {
330 ++it;
331 continue;
332 }
333
334 int errCode = store_->UnregisterAutoSyncCallback(*it);
335 if (errCode != NativeRdb::E_OK) {
336 LOG_ERROR("unsubscribe failed.");
337 return ConvertorErrorCode::NativeToNdk(errCode);
338 }
339 it = callbacks_.erase(it);
340 LOG_DEBUG("progress unsubscribe success.");
341 }
342 return OH_Rdb_ErrCode::RDB_OK;
343 }
344
~RelationalStore()345 RelationalStore::~RelationalStore()
346 {
347 if (store_ == nullptr || callbacks_.empty()) {
348 return;
349 }
350 for (auto &callback : callbacks_) {
351 store_->UnregisterAutoSyncCallback(callback);
352 }
353 }
354
TransformMode(Rdb_SyncMode & mode)355 SyncMode NDKUtils::TransformMode(Rdb_SyncMode &mode)
356 {
357 switch (mode) {
358 case RDB_SYNC_MODE_TIME_FIRST:
359 return TIME_FIRST;
360 case RDB_SYNC_MODE_NATIVE_FIRST:
361 return NATIVE_FIRST;
362 case RDB_SYNC_MODE_CLOUD_FIRST:
363 return CLOUD_FIRST;
364 default:
365 return static_cast<SyncMode>(-1);
366 }
367 }
368
GetSubscribeType(Rdb_SubscribeType & type)369 OHOS::DistributedRdb::SubscribeMode NDKUtils::GetSubscribeType(Rdb_SubscribeType &type)
370 {
371 switch (type) {
372 case Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD:
373 return SubscribeMode::CLOUD;
374 case Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD_DETAILS:
375 return SubscribeMode::CLOUD_DETAIL;
376 case Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS:
377 return SubscribeMode::LOCAL_DETAIL;
378 default:
379 return SubscribeMode::SUBSCRIBE_MODE_MAX;
380 }
381 }
382
383 class MainOpenCallback : public OHOS::NativeRdb::RdbOpenCallback {
384 public:
385 int OnCreate(OHOS::NativeRdb::RdbStore &rdbStore) override;
386 int OnUpgrade(OHOS::NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion) override;
387 };
388
OnCreate(OHOS::NativeRdb::RdbStore & rdbStore)389 int MainOpenCallback::OnCreate(OHOS::NativeRdb::RdbStore &rdbStore)
390 {
391 return OH_Rdb_ErrCode::RDB_OK;
392 }
393
OnUpgrade(OHOS::NativeRdb::RdbStore & rdbStore,int oldVersion,int newVersion)394 int MainOpenCallback::OnUpgrade(OHOS::NativeRdb::RdbStore &rdbStore, int oldVersion, int newVersion)
395 {
396 return OH_Rdb_ErrCode::RDB_OK;
397 }
398
GetRelationalStore(OH_Rdb_Store * store)399 RelationalStore *GetRelationalStore(OH_Rdb_Store *store)
400 {
401 if (store == nullptr || store->id != RDB_STORE_CID) {
402 LOG_ERROR("store is invalid. is null %{public}d", (store == nullptr));
403 return nullptr;
404 }
405 return static_cast<RelationalStore *>(store);
406 }
407
OH_Rdb_GetOrOpen(const OH_Rdb_Config * config,int * errCode)408 OH_Rdb_Store *OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode)
409 {
410 if (config == nullptr || config->selfSize > RDB_CONFIG_SIZE_V1 || errCode == nullptr) {
411 LOG_ERROR("Parameters set error:config is NULL ? %{public}d and config size is %{public}zu or "
412 "errCode is NULL ? %{public}d ",
413 (config == nullptr), sizeof(OH_Rdb_Config), (errCode == nullptr));
414 return nullptr;
415 }
416
417 std::string realPath =
418 OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, config->storeName, *errCode);
419 if (*errCode != 0) {
420 *errCode = ConvertorErrorCode::NativeToNdk(*errCode);
421 LOG_ERROR("Get database path failed, ret %{public}d ", *errCode);
422 return nullptr;
423 }
424 OHOS::NativeRdb::RdbStoreConfig rdbStoreConfig(realPath);
425 rdbStoreConfig.SetSecurityLevel(OHOS::NativeRdb::SecurityLevel(config->securityLevel));
426 rdbStoreConfig.SetEncryptStatus(config->isEncrypt);
427 if (config->selfSize > RDB_CONFIG_SIZE_V0) {
428 rdbStoreConfig.SetArea(config->area - 1);
429 }
430 if (config->bundleName != nullptr) {
431 rdbStoreConfig.SetBundleName(config->bundleName);
432 }
433 rdbStoreConfig.SetName(config->storeName);
434
435 MainOpenCallback callback;
436 std::shared_ptr<OHOS::NativeRdb::RdbStore> store =
437 OHOS::NativeRdb::RdbHelper::GetRdbStore(rdbStoreConfig, -1, callback, *errCode);
438 *errCode = ConvertorErrorCode::NativeToNdk(*errCode);
439 if (store == nullptr) {
440 LOG_ERROR("Get RDB Store fail %{public}s", OHOS::NativeRdb::SqliteUtils::Anonymous(realPath).c_str());
441 return nullptr;
442 }
443 return new (std::nothrow) RelationalStore(store);
444 }
445
OH_Rdb_CreateOrOpen(const OH_Rdb_ConfigV2 * config,int * errCode)446 OH_Rdb_Store *OH_Rdb_CreateOrOpen(const OH_Rdb_ConfigV2 *config, int *errCode)
447 {
448 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE) || errCode == nullptr) {
449 LOG_ERROR("Parameters set error:config is NULL ? %{public}d or magicNum is not valid %{public}d or"
450 " errCode is NULL ? %{public}d ",
451 (config == nullptr), (config == nullptr ? 0 : config->magicNum), (errCode == nullptr));
452 return nullptr;
453 }
454
455 auto [ret, rdbStoreConfig] = RdbNdkUtils::GetRdbStoreConfig(config);
456 if (ret != OHOS::NativeRdb::E_OK) {
457 *errCode = ConvertorErrorCode::NativeToNdk(ret);
458 return nullptr;
459 }
460 MainOpenCallback callback;
461 std::shared_ptr<OHOS::NativeRdb::RdbStore> store =
462 OHOS::NativeRdb::RdbHelper::GetRdbStore(rdbStoreConfig, -1, callback, *errCode);
463 *errCode = ConvertorErrorCode::NativeToNdk(*errCode);
464 if (store == nullptr) {
465 LOG_ERROR("Get RDB Store fail %{public}s",
466 OHOS::NativeRdb::SqliteUtils::Anonymous(rdbStoreConfig.GetPath()).c_str());
467 return nullptr;
468 }
469 return new (std::nothrow) RelationalStore(store);
470 }
471
OH_Rdb_CloseStore(OH_Rdb_Store * store)472 int OH_Rdb_CloseStore(OH_Rdb_Store *store)
473 {
474 auto rdbStore = GetRelationalStore(store);
475 if (rdbStore == nullptr) {
476 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
477 }
478 delete rdbStore;
479 return OH_Rdb_ErrCode::RDB_OK;
480 }
481
OH_Rdb_DeleteStore(const OH_Rdb_Config * config)482 int OH_Rdb_DeleteStore(const OH_Rdb_Config *config)
483 {
484 if (config == nullptr || config->dataBaseDir == nullptr || config->storeName == nullptr) {
485 LOG_ERROR("Parameters set error:path is NULL ? %{public}d", (config == nullptr));
486 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
487 }
488 int errCode = OHOS::NativeRdb::E_OK;
489 std::string realPath =
490 OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, config->storeName, errCode);
491 if (errCode != OHOS::NativeRdb::E_OK) {
492 return ConvertorErrorCode::NativeToNdk(errCode);
493 }
494 return ConvertorErrorCode::NativeToNdk(OHOS::NativeRdb::RdbHelper::DeleteRdbStore(realPath));
495 }
496
OH_Rdb_DeleteStoreV2(const OH_Rdb_ConfigV2 * config)497 int OH_Rdb_DeleteStoreV2(const OH_Rdb_ConfigV2 *config)
498 {
499 if (config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE)) {
500 LOG_ERROR("config is NULL ? %{public}d, config is invalid ? %{public}d", (config == nullptr),
501 (config == nullptr ? 0 : config->magicNum));
502 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
503 }
504 int errCode = OHOS::NativeRdb::E_OK;
505 std::string realPath =
506 OHOS::NativeRdb::RdbSqlUtils::GetDefaultDatabasePath(config->dataBaseDir, config->storeName, errCode);
507 if (errCode != OHOS::NativeRdb::E_OK) {
508 return ConvertorErrorCode::NativeToNdk(errCode);
509 }
510 return ConvertorErrorCode::NativeToNdk(OHOS::NativeRdb::RdbHelper::DeleteRdbStore(realPath));
511 }
512
OH_Rdb_Insert(OH_Rdb_Store * store,const char * table,OH_VBucket * valuesBucket)513 int OH_Rdb_Insert(OH_Rdb_Store *store, const char *table, OH_VBucket *valuesBucket)
514 {
515 auto rdbStore = GetRelationalStore(store);
516 auto bucket = RelationalValuesBucket::GetSelf(valuesBucket);
517 if (rdbStore == nullptr || table == nullptr || bucket == nullptr) {
518 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
519 }
520 int64_t rowId = -1;
521 rdbStore->GetStore()->Insert(rowId, table, bucket->Get());
522 return rowId >= 0 ? rowId : OH_Rdb_ErrCode::RDB_ERR;
523 }
524
OH_Rdb_BatchInsert(OH_Rdb_Store * store,const char * table,const OH_Data_VBuckets * rows,Rdb_ConflictResolution resolution,int64_t * changes)525 int OH_Rdb_BatchInsert(OH_Rdb_Store *store, const char *table,
526 const OH_Data_VBuckets *rows, Rdb_ConflictResolution resolution, int64_t *changes)
527 {
528 auto rdbStore = GetRelationalStore(store);
529 if (rdbStore == nullptr || table == nullptr || rows == nullptr || changes == nullptr ||
530 resolution < RDB_CONFLICT_NONE || resolution > RDB_CONFLICT_REPLACE) {
531 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
532 }
533 OHOS::NativeRdb::ValuesBuckets datas;
534 for (size_t i = 0; i < rows->rows_.size(); i++) {
535 auto valuesBucket = RelationalValuesBucket::GetSelf(const_cast<OH_VBucket *>(rows->rows_[i]));
536 if (valuesBucket == nullptr) {
537 continue;
538 }
539 datas.Put(valuesBucket->Get());
540 }
541 auto [errCode, count] = rdbStore->GetStore()->BatchInsert(table,
542 datas, Utils::ConvertConflictResolution(resolution));
543 *changes = count;
544 if (errCode != OHOS::NativeRdb::E_OK) {
545 LOG_ERROR("batch insert fail, errCode=%{public}d count=%{public}" PRId64, errCode, count);
546 }
547 return ConvertorErrorCode::GetInterfaceCode(errCode);
548 }
549
OH_Rdb_Update(OH_Rdb_Store * store,OH_VBucket * valueBucket,OH_Predicates * predicates)550 int OH_Rdb_Update(OH_Rdb_Store *store, OH_VBucket *valueBucket, OH_Predicates *predicates)
551 {
552 auto rdbStore = GetRelationalStore(store);
553 auto predicate = RelationalPredicate::GetSelf(predicates);
554 auto bucket = RelationalValuesBucket::GetSelf(valueBucket);
555 if (rdbStore == nullptr || predicate == nullptr || bucket == nullptr) {
556 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
557 }
558 int updatedRows = -1;
559 rdbStore->GetStore()->Update(updatedRows, bucket->Get(), predicate->Get());
560 return updatedRows >= 0 ? updatedRows : OH_Rdb_ErrCode::RDB_ERR;
561 }
562
OH_Rdb_Delete(OH_Rdb_Store * store,OH_Predicates * predicates)563 int OH_Rdb_Delete(OH_Rdb_Store *store, OH_Predicates *predicates)
564 {
565 auto rdbStore = GetRelationalStore(store);
566 auto predicate = RelationalPredicate::GetSelf(predicates);
567 if (rdbStore == nullptr || predicate == nullptr) {
568 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
569 }
570 int deletedRows = -1;
571 rdbStore->GetStore()->Delete(deletedRows, predicate->Get());
572 return deletedRows >= 0 ? deletedRows : OH_Rdb_ErrCode::RDB_ERR;
573 }
574
OH_Rdb_Query(OH_Rdb_Store * store,OH_Predicates * predicates,const char * const * columnNames,int length)575 OH_Cursor *OH_Rdb_Query(OH_Rdb_Store *store, OH_Predicates *predicates, const char *const *columnNames, int length)
576 {
577 auto rdbStore = GetRelationalStore(store);
578 auto predicate = RelationalPredicate::GetSelf(predicates);
579 if (rdbStore == nullptr || predicate == nullptr) {
580 return nullptr;
581 }
582 std::vector<std::string> columns;
583 if (columnNames != nullptr && length > 0) {
584 columns.reserve(length);
585 for (int i = 0; i < length; i++) {
586 columns.push_back(columnNames[i]);
587 }
588 }
589
590 std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet =
591 rdbStore->GetStore()->QueryByStep(predicate->Get(), columns);
592 if (resultSet == nullptr) {
593 return nullptr;
594 }
595 return new (std::nothrow) RelationalCursor(std::move(resultSet));
596 }
597
OH_Rdb_ExecuteQuery(OH_Rdb_Store * store,const char * sql)598 OH_Cursor *OH_Rdb_ExecuteQuery(OH_Rdb_Store *store, const char *sql)
599 {
600 auto rdbStore = GetRelationalStore(store);
601 if (rdbStore == nullptr || sql == nullptr) {
602 return nullptr;
603 }
604 std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet =
605 rdbStore->GetStore()->GetDbType() == OHOS::NativeRdb::DB_VECTOR
606 ? rdbStore->GetStore()->QueryByStep(sql, std::vector<std::string>{})
607 : rdbStore->GetStore()->QuerySql(sql, std::vector<std::string>{});
608 if (resultSet == nullptr) {
609 return nullptr;
610 }
611 return new OHOS::RdbNdk::RelationalCursor(std::move(resultSet));
612 }
613
OH_Rdb_Execute(OH_Rdb_Store * store,const char * sql)614 int OH_Rdb_Execute(OH_Rdb_Store *store, const char *sql)
615 {
616 auto rdbStore = GetRelationalStore(store);
617 if (rdbStore == nullptr || sql == nullptr) {
618 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
619 }
620 return ConvertorErrorCode::NativeToNdk(
621 rdbStore->GetStore()->ExecuteSql(sql, std::vector<OHOS::NativeRdb::ValueObject>{}));
622 }
623
OH_Rdb_ExecuteByTrxId(OH_Rdb_Store * store,int64_t trxId,const char * sql)624 int OH_Rdb_ExecuteByTrxId(OH_Rdb_Store *store, int64_t trxId, const char *sql)
625 {
626 auto rdbStore = GetRelationalStore(store);
627 if (rdbStore == nullptr || sql == nullptr) {
628 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
629 }
630 return ConvertorErrorCode::NativeToNdk(
631 (rdbStore->GetStore()->Execute(sql, std::vector<OHOS::NativeRdb::ValueObject>{}, trxId)).first);
632 }
633
OH_Rdb_BeginTransaction(OH_Rdb_Store * store)634 int OH_Rdb_BeginTransaction(OH_Rdb_Store *store)
635 {
636 auto rdbStore = GetRelationalStore(store);
637 if (rdbStore == nullptr) {
638 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
639 }
640 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->BeginTransaction());
641 }
642
OH_Rdb_RollBack(OH_Rdb_Store * store)643 int OH_Rdb_RollBack(OH_Rdb_Store *store)
644 {
645 auto rdbStore = GetRelationalStore(store);
646 if (rdbStore == nullptr) {
647 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
648 }
649 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->RollBack());
650 }
651
OH_Rdb_Commit(OH_Rdb_Store * store)652 int OH_Rdb_Commit(OH_Rdb_Store *store)
653 {
654 auto rdbStore = GetRelationalStore(store);
655 if (rdbStore == nullptr) {
656 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
657 }
658 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Commit());
659 }
660
OH_Rdb_BeginTransWithTrxId(OH_Rdb_Store * store,int64_t * trxId)661 int OH_Rdb_BeginTransWithTrxId(OH_Rdb_Store *store, int64_t *trxId)
662 {
663 auto rdbStore = GetRelationalStore(store);
664 if (rdbStore == nullptr || trxId == nullptr) {
665 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
666 }
667 std::pair<int, int64_t> res = rdbStore->GetStore()->BeginTrans();
668 *trxId = res.second;
669 return ConvertorErrorCode::NativeToNdk(res.first);
670 }
671
OH_Rdb_RollBackByTrxId(OH_Rdb_Store * store,int64_t trxId)672 int OH_Rdb_RollBackByTrxId(OH_Rdb_Store *store, int64_t trxId)
673 {
674 auto rdbStore = GetRelationalStore(store);
675 if (rdbStore == nullptr) {
676 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
677 }
678 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->RollBack(trxId));
679 }
680
OH_Rdb_CommitByTrxId(OH_Rdb_Store * store,int64_t trxId)681 int OH_Rdb_CommitByTrxId(OH_Rdb_Store *store, int64_t trxId)
682 {
683 auto rdbStore = GetRelationalStore(store);
684 if (rdbStore == nullptr) {
685 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
686 }
687 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Commit(trxId));
688 }
689
OH_Rdb_Backup(OH_Rdb_Store * store,const char * databasePath)690 int OH_Rdb_Backup(OH_Rdb_Store *store, const char *databasePath)
691 {
692 auto rdbStore = GetRelationalStore(store);
693 if (rdbStore == nullptr || databasePath == nullptr) {
694 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
695 }
696 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Backup(databasePath));
697 }
698
OH_Rdb_Restore(OH_Rdb_Store * store,const char * databasePath)699 int OH_Rdb_Restore(OH_Rdb_Store *store, const char *databasePath)
700 {
701 auto rdbStore = GetRelationalStore(store);
702 if (rdbStore == nullptr || databasePath == nullptr) {
703 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
704 }
705 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Restore(databasePath));
706 }
707
OH_Rdb_GetVersion(OH_Rdb_Store * store,int * version)708 int OH_Rdb_GetVersion(OH_Rdb_Store *store, int *version)
709 {
710 auto rdbStore = GetRelationalStore(store);
711 if (rdbStore == nullptr || version == nullptr) {
712 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
713 }
714 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->GetVersion(*version));
715 }
716
OH_Rdb_SetVersion(OH_Rdb_Store * store,int version)717 int OH_Rdb_SetVersion(OH_Rdb_Store *store, int version)
718 {
719 auto rdbStore = GetRelationalStore(store);
720 if (rdbStore == nullptr) {
721 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
722 }
723 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->SetVersion(version));
724 }
725
Convert(const Rdb_DistributedConfig * config)726 static std::pair<int32_t, Rdb_DistributedConfig> Convert(const Rdb_DistributedConfig *config)
727 {
728 std::pair<int32_t, Rdb_DistributedConfig> result = { OH_Rdb_ErrCode::RDB_E_INVALID_ARGS, {} };
729 auto &[errCode, cfg] = result;
730 switch (config->version) {
731 case DISTRIBUTED_CONFIG_V0: {
732 const auto *realCfg = reinterpret_cast<const DistributedConfigV0 *>(config);
733 cfg.version = realCfg->version;
734 cfg.isAutoSync = realCfg->isAutoSync;
735 errCode = OH_Rdb_ErrCode::RDB_OK;
736 break;
737 }
738 default:
739 break;
740 }
741 return result;
742 }
743
OH_Rdb_SetDistributedTables(OH_Rdb_Store * store,const char * tables[],uint32_t count,Rdb_DistributedType type,const Rdb_DistributedConfig * config)744 int OH_Rdb_SetDistributedTables(OH_Rdb_Store *store, const char *tables[], uint32_t count, Rdb_DistributedType type,
745 const Rdb_DistributedConfig *config)
746 {
747 auto rdbStore = GetRelationalStore(store);
748 if (rdbStore == nullptr || type != Rdb_DistributedType::RDB_DISTRIBUTED_CLOUD || (count > 0 && tables == nullptr)) {
749 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
750 }
751
752 auto [errCode, cfg] = Convert(config);
753 if (errCode != OH_Rdb_ErrCode::RDB_OK) {
754 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
755 }
756 std::vector<std::string> tableNames;
757 tableNames.reserve(count);
758 for (uint32_t i = 0; i < count; i++) {
759 if (tables[i] == nullptr) {
760 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
761 }
762 tableNames.emplace_back(tables[i]);
763 }
764 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->SetDistributedTables(
765 tableNames, DistributedTableType::DISTRIBUTED_CLOUD, { cfg.isAutoSync }));
766 }
767
OH_Rdb_FindModifyTime(OH_Rdb_Store * store,const char * tableName,const char * columnName,OH_VObject * values)768 OH_Cursor *OH_Rdb_FindModifyTime(OH_Rdb_Store *store, const char *tableName, const char *columnName, OH_VObject *values)
769 {
770 auto rdbStore = GetRelationalStore(store);
771 auto selfObjects = RelationalPredicatesObjects::GetSelf(values);
772 if (rdbStore == nullptr || selfObjects == nullptr || tableName == nullptr) {
773 return nullptr;
774 }
775 std::vector<ValueObject> objects = selfObjects->Get();
776 std::vector<OHOS::NativeRdb::RdbStore::PRIKey> keys;
777 keys.reserve(objects.size());
778 for (auto &object : objects) {
779 OHOS::NativeRdb::RdbStore::PRIKey priKey;
780 OHOS::NativeRdb::RawDataParser::Convert(std::move(object.value), priKey);
781 keys.push_back(std::move(priKey));
782 }
783 auto results = rdbStore->GetStore()->GetModifyTime(tableName, columnName, keys);
784 return new (std::nothrow) ModifyTimeCursor(std::move(results));
785 }
786
OH_Rdb_Subscribe(OH_Rdb_Store * store,Rdb_SubscribeType type,const Rdb_DataObserver * observer)787 int OH_Rdb_Subscribe(OH_Rdb_Store *store, Rdb_SubscribeType type, const Rdb_DataObserver *observer)
788 {
789 auto rdbStore = GetRelationalStore(store);
790 if (rdbStore == nullptr || observer == nullptr) {
791 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
792 }
793 return rdbStore->DoSubScribe(type, observer);
794 }
795
OH_Rdb_Unsubscribe(OH_Rdb_Store * store,Rdb_SubscribeType type,const Rdb_DataObserver * observer)796 int OH_Rdb_Unsubscribe(OH_Rdb_Store *store, Rdb_SubscribeType type, const Rdb_DataObserver *observer)
797 {
798 auto rdbStore = GetRelationalStore(store);
799 if (rdbStore == nullptr) {
800 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
801 }
802 return rdbStore->DoUnsubScribe(type, observer);
803 }
804
DoSubScribe(Rdb_SubscribeType type,const Rdb_DataObserver * observer)805 int RelationalStore::DoSubScribe(Rdb_SubscribeType type, const Rdb_DataObserver *observer)
806 {
807 if (store_ == nullptr || type < RDB_SUBSCRIBE_TYPE_CLOUD || type > RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS ||
808 observer == nullptr || observer->callback.briefObserver == nullptr ||
809 observer->callback.detailsObserver == nullptr) {
810 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
811 }
812
813 std::lock_guard<decltype(mutex_)> lock(mutex_);
814 auto result = std::any_of(dataObservers_[type].begin(), dataObservers_[type].end(),
815 [observer](const std::shared_ptr<NDKStoreObserver> &item) { return *item.get() == observer; });
816 if (result) {
817 LOG_INFO("duplicate subscribe.");
818 return OH_Rdb_ErrCode::RDB_OK;
819 }
820 auto subscribeOption = SubscribeOption{ .mode = NDKUtils::GetSubscribeType(type), .event = "data_change" };
821 auto ndkObserver = std::make_shared<NDKStoreObserver>(observer, type);
822 int subscribeResult = (type == RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS)
823 ? store_->SubscribeObserver(subscribeOption, ndkObserver)
824 : store_->Subscribe(subscribeOption, ndkObserver);
825 if (subscribeResult != OHOS::NativeRdb::E_OK) {
826 LOG_ERROR("subscribe failed.");
827 } else {
828 dataObservers_[type].emplace_back(std::move(ndkObserver));
829 }
830 return ConvertorErrorCode::NativeToNdk(subscribeResult);
831 }
832
DoUnsubScribe(Rdb_SubscribeType type,const Rdb_DataObserver * observer)833 int RelationalStore::DoUnsubScribe(Rdb_SubscribeType type, const Rdb_DataObserver *observer)
834 {
835 if (store_ == nullptr || type < RDB_SUBSCRIBE_TYPE_CLOUD || type > RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS) {
836 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
837 }
838 std::lock_guard<decltype(mutex_)> lock(mutex_);
839 for (auto it = dataObservers_[type].begin(); it != dataObservers_[type].end();) {
840 if (observer != nullptr && !(**it == observer)) {
841 ++it;
842 continue;
843 }
844 auto subscribeOption = SubscribeOption{ .mode = NDKUtils::GetSubscribeType(type), .event = "data_change" };
845 int errCode = (type == RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS) ? store_->UnsubscribeObserver(subscribeOption, *it)
846 : store_->UnSubscribe(subscribeOption, *it);
847 if (errCode != NativeRdb::E_OK) {
848 LOG_ERROR("unsubscribe failed.");
849 return ConvertorErrorCode::NativeToNdk(errCode);
850 }
851 it = dataObservers_[type].erase(it);
852 LOG_DEBUG("data observer unsubscribe success.");
853 }
854 return OH_Rdb_ErrCode::RDB_OK;
855 }
856
857 namespace {
858 struct RelationalProgressDetails : public Rdb_ProgressDetails {
859 Rdb_TableDetails *details_ = nullptr;
860 explicit RelationalProgressDetails(const ProgressDetail &detail);
861 ~RelationalProgressDetails();
862
863 Rdb_TableDetails *GetTableDetails(int paraVersion);
864 void DestroyTableDetails();
865
866 private:
867 uint8_t *ResizeBuff(size_t size);
868
869 TableDetails tableDetails_;
870 size_t size_ = 0;
871 uint8_t *buffer_ = nullptr;
872 };
873
DestroyTableDetails()874 void RelationalProgressDetails::DestroyTableDetails()
875 {
876 delete[] details_;
877 details_ = nullptr;
878 }
879
RelationalProgressDetails(const ProgressDetail & detail)880 RelationalProgressDetails::RelationalProgressDetails(const ProgressDetail &detail)
881 {
882 version = DISTRIBUTED_PROGRESS_DETAIL_VERSION;
883 schedule = detail.progress;
884 code = detail.code;
885 tableLength = (int32_t)detail.details.size();
886 tableDetails_ = detail.details;
887 }
888
~RelationalProgressDetails()889 RelationalProgressDetails::~RelationalProgressDetails()
890 {
891 if (buffer_ != nullptr) {
892 free(buffer_);
893 }
894 buffer_ = nullptr;
895 }
896
GetTableDetails(int paraVersion)897 Rdb_TableDetails *RelationalProgressDetails::GetTableDetails(int paraVersion)
898 {
899 switch (paraVersion) {
900 case TABLE_DETAIL_V0: {
901 auto length = sizeof(TableDetailsV0) * (tableLength + 1);
902 auto *detailsV0 = (TableDetailsV0 *)ResizeBuff(length);
903 if (detailsV0 == nullptr) {
904 return nullptr;
905 }
906 auto result = memset_s(detailsV0, length, 0, length);
907 if (result != EOK) {
908 LOG_ERROR("memset_s failed, error code is %{public}d", result);
909 }
910 int index = 0;
911 for (const auto &pair : tableDetails_) {
912 detailsV0[index].table = pair.first.c_str();
913 detailsV0[index].upload = StatisticV0{
914 .total = (int)pair.second.upload.total,
915 .successful = (int)pair.second.upload.success,
916 .failed = (int)pair.second.upload.failed,
917 .remained = (int)pair.second.upload.untreated,
918 };
919 detailsV0[index].download = StatisticV0{
920 .total = (int)pair.second.download.total,
921 .successful = (int)pair.second.download.success,
922 .failed = (int)pair.second.download.failed,
923 .remained = (int)pair.second.download.untreated,
924 };
925 index++;
926 }
927 return reinterpret_cast<Rdb_TableDetails *>(reinterpret_cast<uint8_t *>(detailsV0));
928 }
929 default:
930 return nullptr;
931 }
932 }
933
ResizeBuff(size_t size)934 uint8_t *RelationalProgressDetails::ResizeBuff(size_t size)
935 {
936 if (size_ >= size) {
937 return buffer_;
938 }
939 if (buffer_ != nullptr) {
940 free(buffer_);
941 }
942 buffer_ = (uint8_t *)malloc(size);
943 return buffer_;
944 }
945 } // namespace
946
GetDetails(Rdb_ProgressDetails * progress)947 static std::pair<int, RelationalProgressDetails *> GetDetails(Rdb_ProgressDetails *progress)
948 {
949 if (progress->version != DISTRIBUTED_PROGRESS_DETAIL_VERSION) {
950 return { -1, nullptr };
951 }
952 return { 0, (RelationalProgressDetails *)progress };
953 }
954
OH_Rdb_GetTableDetails(Rdb_ProgressDetails * progress,int32_t version)955 Rdb_TableDetails *OH_Rdb_GetTableDetails(Rdb_ProgressDetails *progress, int32_t version)
956 {
957 auto [errCode, details] = GetDetails(progress);
958 if (errCode == -1 || details == nullptr) {
959 return nullptr;
960 }
961 return details->GetTableDetails(version);
962 }
963
OH_Rdb_CloudSync(OH_Rdb_Store * store,Rdb_SyncMode mode,const char * tables[],uint32_t count,const Rdb_ProgressObserver * observer)964 int OH_Rdb_CloudSync(
965 OH_Rdb_Store *store, Rdb_SyncMode mode, const char *tables[], uint32_t count, const Rdb_ProgressObserver *observer)
966 {
967 auto rdbStore = GetRelationalStore(store);
968 if (rdbStore == nullptr || mode < RDB_SYNC_MODE_TIME_FIRST || mode > RDB_SYNC_MODE_CLOUD_FIRST ||
969 observer == nullptr || observer->callback == nullptr || (count > 0 && tables == nullptr)) {
970 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
971 }
972 SyncOption syncOption{ .mode = NDKUtils::TransformMode(mode), .isBlock = false };
973 std::vector<std::string> tableNames;
974 for (uint32_t i = 0; i < count; ++i) {
975 if (tables[i] == nullptr) {
976 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
977 }
978 tableNames.emplace_back(tables[i]);
979 }
980
981 auto progressCallback = [cxt = (*observer).context, cb = (*observer).callback](Details &&details) {
982 if (details.size() > 1) {
983 LOG_ERROR("Not support edge to edge detail notify.");
984 return;
985 }
986 if (details.empty()) {
987 LOG_ERROR("No device or cloud synced.");
988 return;
989 }
990 for (auto &[device, detail] : details) {
991 RelationalProgressDetails cloudDetail(detail);
992 cb(cxt, &cloudDetail);
993 break;
994 }
995 };
996 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->Sync(syncOption, tableNames, progressCallback));
997 }
998
OH_Rdb_SubscribeAutoSyncProgress(OH_Rdb_Store * store,const Rdb_ProgressObserver * callback)999 int OH_Rdb_SubscribeAutoSyncProgress(OH_Rdb_Store *store, const Rdb_ProgressObserver *callback)
1000 {
1001 auto rdbStore = GetRelationalStore(store);
1002 if (rdbStore == nullptr || callback == nullptr) {
1003 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
1004 }
1005 return ConvertorErrorCode::NativeToNdk(rdbStore->SubscribeAutoSyncProgress(callback));
1006 }
1007
OH_Rdb_UnsubscribeAutoSyncProgress(OH_Rdb_Store * store,const Rdb_ProgressObserver * callback)1008 int OH_Rdb_UnsubscribeAutoSyncProgress(OH_Rdb_Store *store, const Rdb_ProgressObserver *callback)
1009 {
1010 auto rdbStore = GetRelationalStore(store);
1011 if (rdbStore == nullptr) {
1012 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
1013 }
1014 return ConvertorErrorCode::NativeToNdk(rdbStore->UnsubscribeAutoSyncProgress(callback));
1015 }
1016
OH_Rdb_LockRow(OH_Rdb_Store * store,OH_Predicates * predicates)1017 int OH_Rdb_LockRow(OH_Rdb_Store *store, OH_Predicates *predicates)
1018 {
1019 auto rdbStore = GetRelationalStore(store);
1020 auto predicate = RelationalPredicate::GetSelf(predicates);
1021 if (rdbStore == nullptr || predicate == nullptr) {
1022 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
1023 }
1024 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->ModifyLockStatus(predicate->Get(), true));
1025 }
1026
OH_Rdb_UnlockRow(OH_Rdb_Store * store,OH_Predicates * predicates)1027 int OH_Rdb_UnlockRow(OH_Rdb_Store *store, OH_Predicates *predicates)
1028 {
1029 auto rdbStore = GetRelationalStore(store);
1030 auto predicate = RelationalPredicate::GetSelf(predicates);
1031 if (rdbStore == nullptr || predicate == nullptr) {
1032 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
1033 }
1034 return ConvertorErrorCode::NativeToNdk(rdbStore->GetStore()->ModifyLockStatus(predicate->Get(), false));
1035 }
1036
OH_Rdb_QueryLockedRow(OH_Rdb_Store * store,OH_Predicates * predicates,const char * const * columnNames,int length)1037 OH_Cursor *OH_Rdb_QueryLockedRow(
1038 OH_Rdb_Store *store, OH_Predicates *predicates, const char *const *columnNames, int length)
1039 {
1040 auto rdbStore = GetRelationalStore(store);
1041 auto predicate = RelationalPredicate::GetSelf(predicates);
1042 if (rdbStore == nullptr || predicate == nullptr) {
1043 return nullptr;
1044 }
1045 std::vector<std::string> columns;
1046 if (columnNames != nullptr && length > 0) {
1047 columns.reserve(length);
1048 for (int i = 0; i < length; i++) {
1049 columns.push_back(columnNames[i]);
1050 }
1051 }
1052 predicate->Get().BeginWrap();
1053 predicate->Get().EqualTo(OHOS::NativeRdb::AbsRdbPredicates::LOCK_STATUS, OHOS::NativeRdb::AbsRdbPredicates::LOCKED);
1054 predicate->Get().Or();
1055 predicate->Get().EqualTo(
1056 OHOS::NativeRdb::AbsRdbPredicates::LOCK_STATUS, OHOS::NativeRdb::AbsRdbPredicates::LOCK_CHANGED);
1057 predicate->Get().EndWrap();
1058 std::shared_ptr<OHOS::NativeRdb::ResultSet> resultSet =
1059 rdbStore->GetStore()->QueryByStep(predicate->Get(), columns);
1060 if (resultSet == nullptr) {
1061 return nullptr;
1062 }
1063 return new OHOS::RdbNdk::RelationalCursor(std::move(resultSet));
1064 }
1065
OH_Rdb_CreateTransaction(OH_Rdb_Store * store,const OH_RDB_TransOptions * options,OH_Rdb_Transaction ** trans)1066 int OH_Rdb_CreateTransaction(OH_Rdb_Store *store, const OH_RDB_TransOptions *options, OH_Rdb_Transaction **trans)
1067 {
1068 auto rdbStore = GetRelationalStore(store);
1069 if (rdbStore == nullptr || trans == nullptr || options == nullptr || !options->IsValid()) {
1070 LOG_ERROR("params exist nullptr or invalid options.");
1071 return RDB_E_INVALID_ARGS;
1072 }
1073 OH_Rdb_Transaction *transaction = new (std::nothrow) OH_Rdb_Transaction();
1074 if (transaction == nullptr) {
1075 LOG_ERROR("new OH_Rdb_Transaction failed.");
1076 return RDB_E_ERROR;
1077 }
1078 auto [ret, tmpTrans] = rdbStore->GetStore()->CreateTransaction(static_cast<int>(options->type_));
1079 transaction->trans_ = tmpTrans;
1080 *trans = transaction;
1081 return ConvertorErrorCode::NativeToNdk(ret);
1082 }
1083
OH_Rdb_ExecuteV2(OH_Rdb_Store * store,const char * sql,const OH_Data_Values * args,OH_Data_Value ** result)1084 int OH_Rdb_ExecuteV2(OH_Rdb_Store *store, const char *sql, const OH_Data_Values *args, OH_Data_Value **result)
1085 {
1086 auto rdbStore = GetRelationalStore(store);
1087 if (rdbStore == nullptr || sql == nullptr || (args != nullptr && !args->IsValid())) {
1088 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
1089 }
1090 std::vector<ValueObject> datas;
1091 if (args != nullptr) {
1092 for (auto arg : args->values_) {
1093 if (!arg.IsValid()) {
1094 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
1095 }
1096 datas.push_back(arg.value_);
1097 }
1098 }
1099 auto innerStore = rdbStore->GetStore();
1100 if (innerStore == nullptr) {
1101 LOG_ERROR("store is nullptr");
1102 return OH_Rdb_ErrCode::RDB_E_ALREADY_CLOSED;
1103 }
1104 auto [errCode, valueObj] = innerStore->Execute(sql, datas);
1105 if (errCode != OHOS::NativeRdb::E_OK) {
1106 LOG_ERROR("execute fail, errCode=%{public}d", errCode);
1107 return ConvertorErrorCode::GetInterfaceCode(errCode);
1108 }
1109 if (result != nullptr) {
1110 OH_Data_Value *value = OH_Value_Create();
1111 if (value == nullptr) {
1112 return RDB_E_ERROR;
1113 }
1114 value->value_ = valueObj;
1115 *result = value;
1116 }
1117 return OH_Rdb_ErrCode::RDB_OK;
1118 }
1119
OH_Rdb_ExecuteQueryV2(OH_Rdb_Store * store,const char * sql,const OH_Data_Values * args)1120 OH_Cursor *OH_Rdb_ExecuteQueryV2(OH_Rdb_Store *store, const char *sql, const OH_Data_Values *args)
1121 {
1122 auto rdbStore = GetRelationalStore(store);
1123 if (rdbStore == nullptr || sql == nullptr || (args != nullptr && !args->IsValid())) {
1124 return nullptr;
1125 }
1126 std::vector<ValueObject> datas;
1127 if (args != nullptr) {
1128 for (auto arg : args->values_) {
1129 if (!arg.IsValid()) {
1130 LOG_ERROR("args is invalid");
1131 return nullptr;
1132 }
1133 datas.push_back(arg.value_);
1134 }
1135 }
1136 auto innerStore = rdbStore->GetStore();
1137 if (innerStore == nullptr) {
1138 LOG_ERROR("store is nullptr");
1139 return nullptr;
1140 }
1141 auto resultSet = innerStore->QueryByStep(sql, datas);
1142 if (resultSet == nullptr) {
1143 return nullptr;
1144 }
1145 return new (std::nothrow) RelationalCursor(std::move(resultSet));
1146 }
1147
NDKDetailProgressObserver(const Rdb_ProgressObserver * callback)1148 NDKDetailProgressObserver::NDKDetailProgressObserver(const Rdb_ProgressObserver *callback) : callback_(callback)
1149 {
1150 }
1151
ProgressNotification(const Details & details)1152 void NDKDetailProgressObserver::ProgressNotification(const Details &details)
1153 {
1154 if (callback_ == nullptr || details.empty()) {
1155 return;
1156 }
1157 RelationalProgressDetails progressDetails = RelationalProgressDetails(details.begin()->second);
1158 (*(callback_->callback))(callback_->context, &progressDetails);
1159 progressDetails.DestroyTableDetails();
1160 }
1161
operator ==(const Rdb_ProgressObserver * callback)1162 bool NDKDetailProgressObserver::operator==(const Rdb_ProgressObserver *callback)
1163 {
1164 return callback == callback_;
1165 }
1166
NDKStoreObserver(const Rdb_DataObserver * observer,int mode)1167 NDKStoreObserver::NDKStoreObserver(const Rdb_DataObserver *observer, int mode) : mode_(mode), observer_(observer)
1168 {
1169 }
1170
OnChange(const std::vector<std::string> & devices)1171 void NDKStoreObserver::OnChange(const std::vector<std::string> &devices)
1172 {
1173 if (mode_ == Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD) {
1174 auto count = devices.size();
1175 std::unique_ptr<const char *[]> deviceIds = std::make_unique<const char *[]>(count);
1176 for (uint32_t i = 0; i < count; ++i) {
1177 deviceIds[i] = devices[i].c_str();
1178 }
1179 (*observer_->callback.briefObserver)(observer_->context, deviceIds.get(), count);
1180 }
1181 }
1182
GetKeyInfoSize(RdbStoreObserver::ChangeInfo && changeInfo)1183 size_t NDKStoreObserver::GetKeyInfoSize(RdbStoreObserver::ChangeInfo &&changeInfo)
1184 {
1185 size_t size = 0;
1186 for (auto it = changeInfo.begin(); it != changeInfo.end(); ++it) {
1187 size += it->second[RdbStoreObserver::CHG_TYPE_INSERT].size() * sizeof(Rdb_KeyInfo::Rdb_KeyData);
1188 size += it->second[RdbStoreObserver::CHG_TYPE_UPDATE].size() * sizeof(Rdb_KeyInfo::Rdb_KeyData);
1189 size += it->second[RdbStoreObserver::CHG_TYPE_DELETE].size() * sizeof(Rdb_KeyInfo::Rdb_KeyData);
1190 }
1191 return size;
1192 }
1193
GetKeyDataType(std::vector<RdbStoreObserver::PrimaryKey> & primaryKey)1194 int32_t NDKStoreObserver::GetKeyDataType(std::vector<RdbStoreObserver::PrimaryKey> &primaryKey)
1195 {
1196 if (primaryKey.size() == 0) {
1197 return OH_ColumnType::TYPE_NULL;
1198 }
1199 if (std::holds_alternative<int64_t>(primaryKey[0]) || std::holds_alternative<double>(primaryKey[0])) {
1200 return OH_ColumnType::TYPE_INT64;
1201 }
1202 if (std::holds_alternative<std::string>(primaryKey[0])) {
1203 return OH_ColumnType::TYPE_TEXT;
1204 }
1205 return OH_ColumnType::TYPE_NULL;
1206 }
1207
OnChange(const Origin & origin,const RdbStoreObserver::PrimaryFields & fields,RdbStoreObserver::ChangeInfo && changeInfo)1208 void NDKStoreObserver::OnChange(
1209 const Origin &origin, const RdbStoreObserver::PrimaryFields &fields, RdbStoreObserver::ChangeInfo &&changeInfo)
1210 {
1211 uint32_t count = changeInfo.size();
1212 if (count == 0) {
1213 LOG_ERROR("No any infos.");
1214 return;
1215 }
1216
1217 if (mode_ == Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_CLOUD_DETAILS ||
1218 mode_ == Rdb_SubscribeType::RDB_SUBSCRIBE_TYPE_LOCAL_DETAILS) {
1219 size_t size = count * (sizeof(Rdb_ChangeInfo *) + sizeof(Rdb_ChangeInfo)) +
1220 GetKeyInfoSize(std::forward<RdbStoreObserver::ChangeInfo &&>(changeInfo));
1221 std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
1222 Rdb_ChangeInfo **infos = (Rdb_ChangeInfo **)(buffer.get());
1223 if (infos == nullptr) {
1224 LOG_ERROR("Failed to allocate memory for Rdb_ChangeInfo.");
1225 return;
1226 }
1227
1228 Rdb_ChangeInfo *details = (Rdb_ChangeInfo *)(infos + count);
1229 Rdb_KeyInfo::Rdb_KeyData *data = (Rdb_KeyInfo::Rdb_KeyData *)(details + count);
1230
1231 int index = 0;
1232 for (auto it = changeInfo.begin(); it != changeInfo.end(); ++it) {
1233 infos[index] = &details[index];
1234 infos[index]->version = DISTRIBUTED_CHANGE_INFO_VERSION;
1235 infos[index]->tableName = it->first.c_str();
1236 infos[index]->ChangeType = origin.dataType;
1237 infos[index]->inserted.count = static_cast<int>(it->second[RdbStoreObserver::CHG_TYPE_INSERT].size());
1238 infos[index]->inserted.type = GetKeyDataType(it->second[RdbStoreObserver::CHG_TYPE_INSERT]);
1239 infos[index]->updated.count = static_cast<int>(it->second[RdbStoreObserver::CHG_TYPE_UPDATE].size());
1240 infos[index]->updated.type = GetKeyDataType(it->second[RdbStoreObserver::CHG_TYPE_UPDATE]);
1241 infos[index]->deleted.count = static_cast<int>(it->second[RdbStoreObserver::CHG_TYPE_DELETE].size());
1242 infos[index]->deleted.type = GetKeyDataType(it->second[RdbStoreObserver::CHG_TYPE_DELETE]);
1243 ConvertKeyInfoData(data, it->second[RdbStoreObserver::CHG_TYPE_INSERT]);
1244 infos[index]->inserted.data = data;
1245 ConvertKeyInfoData(data + infos[index]->inserted.count, it->second[RdbStoreObserver::CHG_TYPE_UPDATE]);
1246 infos[index]->updated.data = data + infos[index]->inserted.count;
1247 ConvertKeyInfoData(data + infos[index]->inserted.count + infos[index]->updated.count,
1248 it->second[RdbStoreObserver::CHG_TYPE_DELETE]);
1249 infos[index]->deleted.data = data + infos[index]->inserted.count + infos[index]->updated.count;
1250 index++;
1251 }
1252
1253 (*observer_->callback.detailsObserver)(observer_->context, const_cast<const Rdb_ChangeInfo **>(infos), count);
1254 }
1255 }
1256
OnChange()1257 void NDKStoreObserver::OnChange()
1258 {
1259 RdbStoreObserver::OnChange();
1260 }
1261
ConvertKeyInfoData(Rdb_KeyInfo::Rdb_KeyData * keyInfoData,std::vector<RdbStoreObserver::PrimaryKey> & primaryKey)1262 void NDKStoreObserver::ConvertKeyInfoData(
1263 Rdb_KeyInfo::Rdb_KeyData *keyInfoData, std::vector<RdbStoreObserver::PrimaryKey> &primaryKey)
1264 {
1265 if (keyInfoData == nullptr || primaryKey.empty()) {
1266 LOG_WARN("no data, keyInfoData is nullptr:%{public}d", keyInfoData == nullptr);
1267 return;
1268 }
1269
1270 for (size_t i = 0; i < primaryKey.size(); ++i) {
1271 const auto &key = primaryKey[i];
1272 if (auto val = std::get_if<double>(&key)) {
1273 keyInfoData[i].real = *val;
1274 } else if (auto val = std::get_if<int64_t>(&key)) {
1275 keyInfoData[i].integer = *val;
1276 } else if (auto val = std::get_if<std::string>(&key)) {
1277 keyInfoData[i].text = val->c_str();
1278 } else {
1279 LOG_ERROR("Not support the data type.");
1280 return;
1281 }
1282 }
1283 }
1284
operator ==(const Rdb_DataObserver * other)1285 bool NDKStoreObserver::operator==(const Rdb_DataObserver *other)
1286 {
1287 if (other == nullptr || observer_ == nullptr) {
1288 return false;
1289 }
1290 return other->context == observer_->context && &(other->callback) == &(observer_->callback);
1291 }
1292
OH_Rdb_InsertWithConflictResolution(OH_Rdb_Store * store,const char * table,OH_VBucket * row,Rdb_ConflictResolution resolution,int64_t * rowId)1293 int OH_Rdb_InsertWithConflictResolution(OH_Rdb_Store *store, const char *table, OH_VBucket *row,
1294 Rdb_ConflictResolution resolution, int64_t *rowId)
1295 {
1296 auto rdbStore = GetRelationalStore(store);
1297 auto bucket = RelationalValuesBucket::GetSelf(row);
1298 if (rdbStore == nullptr || table == nullptr || bucket == nullptr || rowId == nullptr ||
1299 resolution < RDB_CONFLICT_NONE || resolution > RDB_CONFLICT_REPLACE) {
1300 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
1301 }
1302 auto [errCode, count] = rdbStore->GetStore()->Insert(table, bucket->Get(),
1303 Utils::ConvertConflictResolution(resolution));
1304 *rowId = count;
1305 return ConvertorErrorCode::GetInterfaceCode(errCode);
1306 }
1307
OH_Rdb_UpdateWithConflictResolution(OH_Rdb_Store * store,OH_VBucket * row,OH_Predicates * predicates,Rdb_ConflictResolution resolution,int64_t * changes)1308 int OH_Rdb_UpdateWithConflictResolution(OH_Rdb_Store *store, OH_VBucket *row, OH_Predicates *predicates,
1309 Rdb_ConflictResolution resolution, int64_t *changes)
1310 {
1311 auto rdbStore = GetRelationalStore(store);
1312 auto bucket = RelationalValuesBucket::GetSelf(row);
1313 auto predicate = RelationalPredicate::GetSelf(predicates);
1314 if (rdbStore == nullptr || bucket == nullptr || predicate == nullptr || changes == nullptr ||
1315 resolution < RDB_CONFLICT_NONE || resolution > RDB_CONFLICT_REPLACE) {
1316 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
1317 }
1318 int changedRows = 0;
1319 auto errCode = rdbStore->GetStore()->UpdateWithConflictResolution(changedRows,
1320 predicate->Get().GetTableName(), bucket->Get(), predicate->Get().GetWhereClause(),
1321 predicate->Get().GetBindArgs(), Utils::ConvertConflictResolution(resolution));
1322 *changes = changedRows;
1323 return ConvertorErrorCode::GetInterfaceCode(errCode);
1324 }
1325
OH_Rdb_Attach(OH_Rdb_Store * store,const OH_Rdb_ConfigV2 * config,const char * attachName,int64_t waitTime,size_t * attachedNumber)1326 int OH_Rdb_Attach(OH_Rdb_Store *store, const OH_Rdb_ConfigV2 *config, const char *attachName, int64_t waitTime,
1327 size_t *attachedNumber)
1328 {
1329 auto rdbStore = GetRelationalStore(store);
1330 if (rdbStore == nullptr || config == nullptr || (config->magicNum != RDB_CONFIG_V2_MAGIC_CODE) ||
1331 attachName == nullptr || waitTime < RDB_ATTACH_WAIT_TIME_MIN || waitTime > RDB_ATTACH_WAIT_TIME_MAX ||
1332 attachedNumber == nullptr) {
1333 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
1334 }
1335 auto [ret, rdbStoreConfig] = RdbNdkUtils::GetRdbStoreConfig(config);
1336 if (ret != OHOS::NativeRdb::E_OK) {
1337 return ConvertorErrorCode::NativeToNdk(ret);
1338 }
1339 auto [errCode, size] = rdbStore->GetStore()->Attach(rdbStoreConfig, attachName, static_cast<int32_t>(waitTime));
1340 *attachedNumber = size;
1341 return ConvertorErrorCode::GetInterfaceCode(errCode);
1342 }
1343
OH_Rdb_Detach(OH_Rdb_Store * store,const char * attachName,int64_t waitTime,size_t * attachedNumber)1344 int OH_Rdb_Detach(OH_Rdb_Store *store, const char *attachName, int64_t waitTime, size_t *attachedNumber)
1345 {
1346 auto rdbStore = GetRelationalStore(store);
1347 if (rdbStore == nullptr || attachName == nullptr ||
1348 waitTime < RDB_ATTACH_WAIT_TIME_MIN || waitTime > RDB_ATTACH_WAIT_TIME_MAX || attachedNumber == nullptr) {
1349 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
1350 }
1351 auto [errCode, size] = rdbStore->GetStore()->Detach(attachName, static_cast<int32_t>(waitTime));
1352 *attachedNumber = size;
1353 return ConvertorErrorCode::GetInterfaceCode(errCode);
1354 }
1355
OH_Rdb_SetLocale(OH_Rdb_Store * store,const char * locale)1356 int OH_Rdb_SetLocale(OH_Rdb_Store *store, const char *locale)
1357 {
1358 auto rdbStore = GetRelationalStore(store);
1359 if (rdbStore == nullptr || locale == nullptr) {
1360 return OH_Rdb_ErrCode::RDB_E_INVALID_ARGS;
1361 }
1362 auto errCode = rdbStore->GetStore()->ConfigLocale(locale);
1363 return ConvertorErrorCode::GetInterfaceCode(errCode);
1364 }
1365