• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #include <map>
16 #include <thread>
17 #include "preferences_db_adapter.h"
18 #include "log_print.h"
19 #include "preferences_errno.h"
20 #include "preferences_file_operation.h"
21 
22 namespace OHOS {
23 namespace NativePreferences {
24 
25 void *PreferenceDbAdapter::gLibrary_ = NULL;
26 
27 std::mutex PreferenceDbAdapter::apiMutex_;
28 
29 GRD_APIInfo PreferenceDbAdapter::api_;
30 
31 std::atomic<bool> PreferenceDbAdapter::isInit_ = false;
32 
33 thread_local std::string PreferenceDbAdapter::eventInfo_;
34 
35 #if !defined(WINDOWS_PLATFORM)
36 static const std::chrono::milliseconds WAIT_REPAIRE_TIMEOUT(5);
37 #endif
38 
39 const char * const TABLENAME = "preferences_data";
40 const char * const TABLE_MODE = "{\"mode\" : \"kv\", \"indextype\" : \"hash\"}";
41 const char * const CONFIG_STR =
42     "{\"pageSize\": 4, \"redoFlushByTrx\": 2, \"redoPubBufSize\": 256, \"maxConnNum\": 100, "
43     "\"bufferPoolSize\": 1024, \"crcCheckEnable\": 0, \"bufferPoolPolicy\" : \"BUF_PRIORITY_INDEX\", "
44     "\"sharedModeEnable\" : 1, \"MetaInfoBak\": 1}";
45 const int CREATE_COLLECTION_RETRY_TIMES = 2;
46 const int DB_REPAIR_RETRY_TIMES = 3;
47 
GRDDBApiInitEnhance(GRD_APIInfo & GRD_DBApiInfo)48 void GRDDBApiInitEnhance(GRD_APIInfo &GRD_DBApiInfo)
49 {
50 #ifndef _WIN32
51     GRD_DBApiInfo.DbOpenApi = (DBOpen)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_DBOpen");
52     GRD_DBApiInfo.DbCloseApi = (DBClose)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_DBClose");
53     GRD_DBApiInfo.DbCreateCollectionApi = (DBCreateCollection)dlsym(PreferenceDbAdapter::gLibrary_,
54         "GRD_CreateCollection");
55     GRD_DBApiInfo.DbDropCollectionApi = (DBDropCollection)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_DropCollection");
56     GRD_DBApiInfo.DbIndexPreloadApi = (DBIndexPreload)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_IndexPreload");
57     GRD_DBApiInfo.DbKvPutApi = (DBKvPut)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_KVPut");
58     GRD_DBApiInfo.DbKvGetApi = (DBKvGet)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_KVGet");
59     GRD_DBApiInfo.DbKvDelApi = (DBKvDel)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_KVDel");
60     GRD_DBApiInfo.DbKvFilterApi = (DBKvFilter)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_KVFilter");
61     GRD_DBApiInfo.NextApi = (ResultNext)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_Next");
62     GRD_DBApiInfo.GetValueApi = (GetValue)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_GetValue");
63     GRD_DBApiInfo.GetItemApi = (GetItem)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_GetItem");
64     GRD_DBApiInfo.GetItemSizeApi = (GetItemSize)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_KVGetSize");
65     GRD_DBApiInfo.FetchApi = (Fetch)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_Fetch");
66     GRD_DBApiInfo.FreeItemApi = (KVFreeItem)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_KVFreeItem");
67     GRD_DBApiInfo.FreeResultSetApi = (FreeResultSet)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_FreeResultSet");
68     GRD_DBApiInfo.DbRepairApi = (DBRepair)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_DBRepair");
69     GRD_DBApiInfo.DbGetConfigApi = (DBGetConfig)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_GetConfig");
70     GRD_DBApiInfo.DbSetEventCallbackApi = (DBSetEventCallback)dlsym(PreferenceDbAdapter::gLibrary_,
71         "GRD_SetEventCallback");
72 #endif
73 }
74 
75 const std::map<int, int> GRDErrnoMap = {
76     { GRD_OK, E_OK },
77     { GRD_NOT_SUPPORT, E_NOT_SUPPORTED },
78     { GRD_OVER_LIMIT, E_DEFAULT_EXCEED_LENGTH_LIMIT },
79     { GRD_INVALID_ARGS, E_INVALID_ARGS },
80     { GRD_FAILED_MEMORY_ALLOCATE, E_OUT_OF_MEMORY },
81     { GRD_FAILED_MEMORY_RELEASE, E_OUT_OF_MEMORY },
82     { GRD_PERMISSION_DENIED, PERMISSION_DENIED },
83     { GRD_NO_DATA, E_NO_DATA }
84 };
85 
TransferGrdErrno(int err)86 int TransferGrdErrno(int err)
87 {
88     if (err > 0) {
89         return err;
90     }
91 
92     auto iter = GRDErrnoMap.find(err);
93     if (iter != GRDErrnoMap.end()) {
94         return iter->second;
95     }
96 
97     return E_ERROR;
98 }
99 
IsEnhandceDbEnable()100 bool PreferenceDbAdapter::IsEnhandceDbEnable()
101 {
102     return PreferenceDbAdapter::gLibrary_ != nullptr;
103 }
104 
GetApiInstance()105 GRD_APIInfo& PreferenceDbAdapter::GetApiInstance()
106 {
107     if (PreferenceDbAdapter::isInit_) {
108         return PreferenceDbAdapter::api_;
109     }
110     ApiInit();
111     return PreferenceDbAdapter::api_;
112 }
113 
ApiInit()114 void PreferenceDbAdapter::ApiInit()
115 {
116     if (PreferenceDbAdapter::isInit_) {
117         return;
118     }
119     std::lock_guard<std::mutex> lck(PreferenceDbAdapter::apiMutex_);
120     if (PreferenceDbAdapter::isInit_) {
121         return;
122     }
123     PreferenceDbAdapter::gLibrary_ = DBDlOpen();
124     if (PreferenceDbAdapter::gLibrary_ != nullptr) {
125         GRDDBApiInitEnhance(PreferenceDbAdapter::api_);
126     } else {
127         LOG_DEBUG("use default db kernel");
128     }
129     PreferenceDbAdapter::isInit_ = true;
130     PreferenceDbAdapter::RegisterDbEventCallback();
131     return;
132 }
133 
GetDbEventInfo()134 std::string PreferenceDbAdapter::GetDbEventInfo()
135 {
136     std::string info = PreferenceDbAdapter::eventInfo_;
137     eventInfo_ = "";
138     return info;
139 }
140 
DbEventCallback(void * callbackContext,const char * eventInfo)141 void PreferenceDbAdapter::DbEventCallback(void *callbackContext, const char *eventInfo)
142 {
143     (void)callbackContext;
144     if (eventInfo != NULL) {
145         PreferenceDbAdapter::eventInfo_ = eventInfo;
146     }
147 }
148 
RegisterDbEventCallback()149 void PreferenceDbAdapter::RegisterDbEventCallback()
150 {
151     if (PreferenceDbAdapter::GetApiInstance().DbSetEventCallbackApi == nullptr) { // LCOV_EXCL_BR_LINE
152         LOG_ERROR("api load failed:DbSetEventCallbackApi");
153         return;
154     }
155     int errCode = PreferenceDbAdapter::GetApiInstance().DbSetEventCallbackApi(nullptr, GRD_EVENT_CORRUPTION,
156         &PreferenceDbAdapter::DbEventCallback);
157     if (errCode != GRD_OK) { // LCOV_EXCL_BR_LINE
158         LOG_ERROR("set event callback failed, errCode: %{public}d", errCode);
159     }
160 }
161 
PreferencesDb()162 PreferencesDb::PreferencesDb()
163 {
164 }
165 
~PreferencesDb()166 PreferencesDb::~PreferencesDb()
167 {
168     if (db_ != nullptr || PreferenceDbAdapter::GetApiInstance().DbCloseApi != nullptr) {
169         PreferenceDbAdapter::GetApiInstance().DbCloseApi(db_, GRD_DB_CLOSE_IGNORE_ERROR);
170         db_ = nullptr;
171         LOG_DEBUG("destructor: calling close db.");
172     } else {
173         LOG_DEBUG("destructor: db closed before or dbClose api not loaded, db closed before ? %{public}d.",
174             db_ == nullptr);
175     }
176 }
177 
GetReportParam(const std::string & info,uint32_t errCode)178 ReportParam PreferencesDb::GetReportParam(const std::string &info, uint32_t errCode)
179 {
180     ReportParam reportParam = {
181         bundleName_,
182         ENHANCE_DB,
183         ExtractFileName(dbPath_),
184         errCode,
185         errno,
186         info};
187     return reportParam;
188 }
189 
CloseDb()190 int PreferencesDb::CloseDb()
191 {
192     if (db_ != nullptr) {
193         if (PreferenceDbAdapter::GetApiInstance().DbCloseApi == nullptr) {
194             LOG_ERROR("api load failed: DbCloseApi");
195             return E_ERROR;
196         }
197         int errCode = PreferenceDbAdapter::GetApiInstance().DbCloseApi(db_, GRD_DB_CLOSE_IGNORE_ERROR);
198         if (errCode != E_OK) {
199             LOG_ERROR("close db failed, errcode=%{public}d, file: %{public}s", errCode,
200                 ExtractFileName(dbPath_).c_str());
201             return TransferGrdErrno(errCode);
202         }
203         LOG_INFO("db has been closed.");
204         db_ = nullptr;
205         return E_OK;
206     }
207     LOG_INFO("CloseDb: DB closed before.");
208     return E_OK;
209 }
210 
CreateCollection()211 int PreferencesDb::CreateCollection()
212 {
213     if (PreferenceDbAdapter::GetApiInstance().DbCreateCollectionApi == nullptr) {
214         LOG_ERROR("api load failed: DbCreateCollectionApi");
215         return E_ERROR;
216     }
217     int errCode = PreferenceDbAdapter::GetApiInstance().DbCreateCollectionApi(db_, TABLENAME,
218         TABLE_MODE, 0);
219     if (errCode != GRD_OK) {
220         LOG_ERROR("rd create table failed:%{public}d", errCode);
221     }
222     return TransferGrdErrno(errCode);
223 }
224 
OpenDb(bool isNeedRebuild)225 int PreferencesDb::OpenDb(bool isNeedRebuild)
226 {
227     if (PreferenceDbAdapter::GetApiInstance().DbOpenApi == nullptr) {
228         LOG_ERROR("api load failed: DbOpenApi");
229         return E_ERROR;
230     }
231     uint32_t flag = GRD_DB_OPEN_CREATE;
232     if (isNeedRebuild) {
233         flag |= GRD_DB_OPEN_CHECK;
234     }
235     int errCode = PreferenceDbAdapter::GetApiInstance().DbOpenApi(dbPath_.c_str(), CONFIG_STR, flag, &db_);
236     if (errCode != GRD_OK) {
237         // log outside
238         std::string errMsg = isNeedRebuild ? "open db failed with open_create | open_check" :
239                 "open db failed with open_create";
240         LOG_ERROR("%{public}s, errCode: %{public}d, isRebuild:%{public}d", errMsg.c_str(), errCode, isNeedRebuild);
241     }
242     return errCode;
243 }
244 
RepairDb()245 int PreferencesDb::RepairDb()
246 {
247     if (PreferenceDbAdapter::GetApiInstance().DbRepairApi == nullptr) {
248         LOG_ERROR("api load failed: DbRepairApi");
249         return E_ERROR;
250     }
251     int errCode = PreferenceDbAdapter::GetApiInstance().DbRepairApi(dbPath_.c_str(), CONFIG_STR);
252     if (errCode != GRD_OK) {
253         LOG_ERROR("repair db failed, errCode: %{public}d", errCode);
254     }
255     return errCode;
256 }
257 
TryRepairAndRebuild(int openCode)258 int PreferencesDb::TryRepairAndRebuild(int openCode)
259 {
260     LOG_ERROR("db corrupted, errCode: %{public}d, begin to rebuild, db: %{public}s", openCode,
261         ExtractFileName(dbPath_).c_str());
262     int retryTimes = DB_REPAIR_RETRY_TIMES;
263     int innerErr = GRD_OK;
264     do {
265         innerErr = RepairDb();
266         if (innerErr == GRD_OK) {
267             LOG_INFO("db repair success");
268             return innerErr;
269         } else if (innerErr == GRD_DB_BUSY) {
270             LOG_ERROR("db repair failed, busy, retry times : %{public}d, errCode: %{public}d",
271                 (DB_REPAIR_RETRY_TIMES - retryTimes + 1), innerErr);
272 #if !defined(WINDOWS_PLATFORM)
273             std::this_thread::sleep_for(WAIT_REPAIRE_TIMEOUT);
274 #endif
275         } else {
276             // other error, break to rebuild
277             LOG_ERROR("db repair failed: %{public}d, begin to rebuild", innerErr);
278             break;
279         }
280         retryTimes--;
281     } while (retryTimes > 0);
282 
283     innerErr = OpenDb(true);
284     if (innerErr == GRD_OK || innerErr == GRD_REBUILD_DATABASE) {
285         LOG_INFO("rebuild db success, errCode: %{public}d", innerErr);
286         return GRD_OK;
287     }
288     LOG_ERROR("rebuild db failed, errCode: %{public}d, file: %{public}s", innerErr, ExtractFileName(dbPath_).c_str());
289     return innerErr;
290 }
291 
Init(const std::string & dbPath,const std::string & bundleName)292 int PreferencesDb::Init(const std::string &dbPath, const std::string &bundleName)
293 {
294     if (db_ != nullptr) {
295         LOG_DEBUG("Init: already init.");
296         return E_OK;
297     }
298     if (PreferenceDbAdapter::GetApiInstance().DbIndexPreloadApi == nullptr) {
299         LOG_ERROR("api load failed: DbIndexPreloadApi");
300         return E_ERROR;
301     }
302     dbPath_ = dbPath + ".db";
303     bundleName_ = bundleName;
304     int errCode = OpenDb(false);
305     if (errCode == GRD_DATA_CORRUPTED) {
306         std::string info = PreferenceDbAdapter::GetDbEventInfo();
307         PreferencesDfxManager::Report(GetReportParam((info.empty() ? "db corrupted" : info), errCode),
308             EVENT_NAME_DB_CORRUPTED);
309         int innerErr = TryRepairAndRebuild(errCode);
310         if (innerErr != GRD_OK) {
311             // log inside
312             return TransferGrdErrno(innerErr);
313         }
314         ReportParam param = GetReportParam("db repair success", GRD_OK);
315         param.errnoCode = 0;
316         PreferencesDfxManager::Report(param, EVENT_NAME_DB_CORRUPTED);
317     } else if (errCode != GRD_OK) {
318         LOG_ERROR("db open failed, errCode: %{public}d", errCode);
319         return TransferGrdErrno(errCode);
320     }
321 
322     errCode = CreateCollection();
323     if (errCode != E_OK) {
324         LOG_ERROR("create collection failed when init: %{public}d, but ignored.", errCode);
325         // ignore create collection error
326     }
327 
328     errCode = TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().DbIndexPreloadApi(db_, TABLENAME));
329     if (errCode != E_OK) {
330         LOG_ERROR("Init: Index preload FAILED %{public}d", errCode);
331         return errCode;
332     }
333     return errCode;
334 }
335 
Put(const std::vector<uint8_t> & key,const std::vector<uint8_t> & value)336 int PreferencesDb::Put(const std::vector<uint8_t> &key, const std::vector<uint8_t> &value)
337 {
338     if (db_ == nullptr) {
339         LOG_ERROR("Put failed, db has been closed.");
340         return E_ALREADY_CLOSED;
341     } else if (PreferenceDbAdapter::GetApiInstance().DbKvPutApi == nullptr) {
342         LOG_ERROR("api load failed: DbKvPutApi");
343         return E_ERROR;
344     }
345 
346     GRD_KVItemT innerKey = BlobToKvItem(key);
347     GRD_KVItemT innerVal = BlobToKvItem(value);
348 
349     int retryTimes = CREATE_COLLECTION_RETRY_TIMES;
350     int ret = E_OK;
351     do {
352         ret = PreferenceDbAdapter::GetApiInstance().DbKvPutApi(db_, TABLENAME, &innerKey, &innerVal);
353         if (ret == GRD_UNDEFINED_TABLE) {
354             LOG_INFO("CreateCollection called when Put, file: %{public}s", ExtractFileName(dbPath_).c_str());
355             (void)CreateCollection();
356         } else {
357             if (ret == GRD_OK) {
358                 return TransferGrdErrno(ret);
359             } else {
360                 LOG_ERROR("rd put failed:%{public}d", ret);
361                 return TransferGrdErrno(ret);
362             }
363         }
364         retryTimes--;
365     } while (retryTimes > 0);
366 
367     return TransferGrdErrno(ret);
368 }
369 
Delete(const std::vector<uint8_t> & key)370 int PreferencesDb::Delete(const std::vector<uint8_t> &key)
371 {
372     if (db_ == nullptr) {
373         LOG_ERROR("Delete failed, db has been closed.");
374         return E_ALREADY_CLOSED;
375     } else if (PreferenceDbAdapter::GetApiInstance().DbKvDelApi == nullptr) {
376         LOG_ERROR("api load failed: DbKvDelApi");
377         return E_ERROR;
378     }
379 
380     GRD_KVItemT innerKey = BlobToKvItem(key);
381 
382     int retryTimes = CREATE_COLLECTION_RETRY_TIMES;
383     int ret = E_OK;
384     do {
385         ret = PreferenceDbAdapter::GetApiInstance().DbKvDelApi(db_, TABLENAME, &innerKey);
386         if (ret == GRD_UNDEFINED_TABLE) {
387             LOG_INFO("CreateCollection called when Delete, file: %{public}s", ExtractFileName(dbPath_).c_str());
388             (void)CreateCollection();
389         } else {
390             if (ret == E_OK) {
391                 return TransferGrdErrno(ret);
392             } else {
393                 LOG_ERROR("rd delete failed:%{public}d", ret);
394                 return TransferGrdErrno(ret);
395             }
396         }
397         retryTimes--;
398     } while (retryTimes > 0);
399 
400     return TransferGrdErrno(ret);
401 }
402 
Get(const std::vector<uint8_t> & key,std::vector<uint8_t> & value)403 int PreferencesDb::Get(const std::vector<uint8_t> &key, std::vector<uint8_t> &value)
404 {
405     if (db_ == nullptr) {
406         LOG_ERROR("Get failed, db has been closed.");
407         return E_ALREADY_CLOSED;
408     } else if (PreferenceDbAdapter::GetApiInstance().DbKvGetApi == nullptr ||
409         PreferenceDbAdapter::GetApiInstance().FreeItemApi == nullptr) {
410         LOG_ERROR("api load failed: DbKvGetApi or FreeItemApi");
411         return E_ERROR;
412     }
413 
414     GRD_KVItemT innerKey = BlobToKvItem(key);
415     GRD_KVItemT innerVal = { NULL, 0 };
416 
417     int retryTimes = CREATE_COLLECTION_RETRY_TIMES;
418     int ret = GRD_OK;
419     do {
420         ret = PreferenceDbAdapter::GetApiInstance().DbKvGetApi(db_, TABLENAME, &innerKey, &innerVal);
421         if (ret == GRD_UNDEFINED_TABLE) {
422             LOG_INFO("CreateCollection called when Get, file: %{public}s", ExtractFileName(dbPath_).c_str());
423             (void)CreateCollection();
424         } else {
425             if (ret == GRD_OK) {
426                 break;
427             }
428             if (ret != GRD_NO_DATA) {
429                 LOG_ERROR("rd get failed:%{public}d", ret);
430             }
431             return TransferGrdErrno(ret);
432         }
433         retryTimes--;
434     } while (retryTimes > 0);
435 
436     if (retryTimes == 0) {
437         return TransferGrdErrno(ret);
438     }
439     value.resize(innerVal.dataLen);
440     value = KvItemToBlob(innerVal);
441     (void)PreferenceDbAdapter::GetApiInstance().FreeItemApi(&innerVal);
442     return TransferGrdErrno(ret);
443 }
444 
GetAllInner(std::list<std::pair<std::vector<uint8_t>,std::vector<uint8_t>>> & data,GRD_ResultSet * resultSet)445 int PreferencesDb::GetAllInner(std::list<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>> &data,
446     GRD_ResultSet *resultSet)
447 {
448     int ret = E_OK;
449     while (TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().NextApi(resultSet)) == E_OK) {
450         std::pair<std::vector<uint8_t>, std::vector<uint8_t>> dataItem;
451         uint32_t keySize = 0;
452         uint32_t valueSize = 0;
453         ret = PreferenceDbAdapter::GetApiInstance().GetItemSizeApi(resultSet, &keySize, &valueSize);
454         if (ret != GRD_OK) {
455             LOG_ERROR("ger reulstSet kv size failed %{public}d", ret);
456             return TransferGrdErrno(ret);
457         }
458         dataItem.first.resize(keySize);
459         dataItem.second.resize(valueSize);
460         ret = PreferenceDbAdapter::GetApiInstance().GetItemApi(resultSet, dataItem.first.data(),
461             dataItem.second.data());
462         if (ret != E_OK) {
463             LOG_ERROR("ger reulstSet failed %{public}d", ret);
464             return TransferGrdErrno(ret);
465         }
466         data.emplace_back(std::move(dataItem));
467     }
468     return TransferGrdErrno(ret);
469 }
470 
IsApiValid()471 static inline bool IsApiValid()
472 {
473     auto& apiInstance = PreferenceDbAdapter::GetApiInstance();
474     return (apiInstance.DbKvFilterApi != nullptr && apiInstance.NextApi != nullptr &&
475         apiInstance.GetItemSizeApi != nullptr && apiInstance.GetItemApi != nullptr &&
476         apiInstance.FreeResultSetApi != nullptr);
477 }
478 
GetAll(std::list<std::pair<std::vector<uint8_t>,std::vector<uint8_t>>> & data)479 int PreferencesDb::GetAll(std::list<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>> &data)
480 {
481     if (db_ == nullptr) {
482         LOG_ERROR("GetAll failed, db has been closed.");
483         return E_ALREADY_CLOSED;
484     }
485     if (!IsApiValid()) {
486         LOG_ERROR("api load failed when get all");
487         return E_ERROR;
488     }
489 
490     GRD_FilterOptionT param;
491     param.mode = KV_SCAN_ALL;
492     GRD_ResultSet *resultSet = nullptr;
493 
494     int retryTimes = CREATE_COLLECTION_RETRY_TIMES;
495     int ret = E_OK;
496 
497     do {
498         ret = PreferenceDbAdapter::GetApiInstance().DbKvFilterApi(db_, TABLENAME, &param, &resultSet);
499         if (ret == GRD_UNDEFINED_TABLE) {
500             LOG_INFO("CreateCollection called when GetAll, file: %{public}s", ExtractFileName(dbPath_).c_str());
501             (void)CreateCollection();
502         } else if (ret == GRD_OK) {
503             int innerErr = GetAllInner(data, resultSet); // log inside when failed
504             PreferenceDbAdapter::GetApiInstance().FreeResultSetApi(resultSet);
505             return innerErr;
506         } else {
507             LOG_ERROR("rd kv filter failed:%{public}d", ret);
508             return TransferGrdErrno(ret);
509         }
510         retryTimes--;
511     } while (retryTimes > 0);
512 
513     return TransferGrdErrno(ret);
514 }
515 
DropCollection()516 int PreferencesDb::DropCollection()
517 {
518     if (db_ == nullptr) {
519         LOG_ERROR("DropCollection failed, db has been closed.");
520         return E_ALREADY_CLOSED;
521     } else if (PreferenceDbAdapter::GetApiInstance().DbDropCollectionApi == nullptr) {
522         LOG_ERROR("api load failed: DbDropCollectionApi");
523         return E_ERROR;
524     }
525 
526     int errCode = PreferenceDbAdapter::GetApiInstance().DbDropCollectionApi(db_, TABLENAME, 0);
527     if (errCode != E_OK) {
528         LOG_ERROR("rd drop collection failed:%{public}d", errCode);
529     }
530     return TransferGrdErrno(errCode);
531 }
532 
BlobToKvItem(const std::vector<uint8_t> & blob)533 GRD_KVItemT PreferencesDb::BlobToKvItem(const std::vector<uint8_t> &blob)
534 {
535     return {
536         .data = (void *)&blob[0],
537         .dataLen = (uint32_t)blob.size()
538     };
539 }
540 
KvItemToBlob(GRD_KVItemT & item)541 std::vector<uint8_t> PreferencesDb::KvItemToBlob(GRD_KVItemT &item)
542 {
543     return std::vector<uint8_t>(static_cast<uint8_t *>(item.data),
544         static_cast<uint8_t *>(item.data) + item.dataLen);
545 }
546 
GetKernelDataVersion(int64_t & dataVersion)547 int PreferencesDb::GetKernelDataVersion(int64_t &dataVersion)
548 {
549     if (db_ == nullptr) {
550         LOG_ERROR("Get kernel data version failed, db has been closed.");
551         return E_ALREADY_CLOSED;
552     } else if (PreferenceDbAdapter::GetApiInstance().DbGetConfigApi == nullptr) {
553         LOG_ERROR("api load failed: DbGetConfigApi");
554         return E_ERROR;
555     }
556 
557     GRD_DbValueT kernelDataVersion = PreferenceDbAdapter::GetApiInstance().DbGetConfigApi(db_,
558         GRD_ConfigTypeE::GRD_CONFIG_DATA_VERSION);
559     if (kernelDataVersion.type != GRD_DbDataTypeE::GRD_DB_DATATYPE_INTEGER) {
560         LOG_ERROR("get wrong data version type: %d", kernelDataVersion.type);
561         return E_ERROR;
562     }
563 
564     dataVersion = kernelDataVersion.value.longValue;
565     return E_OK;
566 }
567 } // End of namespace NativePreferences
568 } // End of namespace OHOS