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