• 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 #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     GRD_DBApiInfo.DbGetConfigApi = (DBGetConfig)dlsym(PreferenceDbAdapter::gLibrary_, "GRD_GetConfig");
68 #endif
69 }
70 
71 const std::map<int, int> GRDErrnoMap = {
72     { GRD_OK, E_OK },
73     { GRD_NOT_SUPPORT, E_NOT_SUPPORTED },
74     { GRD_OVER_LIMIT, E_DEFAULT_EXCEED_LENGTH_LIMIT },
75     { GRD_INVALID_ARGS, E_INVALID_ARGS },
76     { GRD_FAILED_MEMORY_ALLOCATE, E_OUT_OF_MEMORY },
77     { GRD_FAILED_MEMORY_RELEASE, E_OUT_OF_MEMORY },
78     { GRD_PERMISSION_DENIED, PERMISSION_DENIED },
79     { GRD_NO_DATA, E_NO_DATA }
80 };
81 
TransferGrdErrno(int err)82 int TransferGrdErrno(int err)
83 {
84     if (err > 0) {
85         return err;
86     }
87 
88     auto iter = GRDErrnoMap.find(err);
89     if (iter != GRDErrnoMap.end()) {
90         return iter->second;
91     }
92 
93     return E_ERROR;
94 }
95 
IsEnhandceDbEnable()96 bool PreferenceDbAdapter::IsEnhandceDbEnable()
97 {
98     return PreferenceDbAdapter::gLibrary_ != nullptr;
99 }
100 
GetApiInstance()101 GRD_APIInfo& PreferenceDbAdapter::GetApiInstance()
102 {
103     if (PreferenceDbAdapter::isInit_) {
104         return PreferenceDbAdapter::api_;
105     }
106     ApiInit();
107     return PreferenceDbAdapter::api_;
108 }
109 
ApiInit()110 void PreferenceDbAdapter::ApiInit()
111 {
112     if (PreferenceDbAdapter::isInit_) {
113         return;
114     }
115     std::lock_guard<std::mutex> lck(PreferenceDbAdapter::apiMutex_);
116     if (PreferenceDbAdapter::isInit_) {
117         return;
118     }
119     PreferenceDbAdapter::gLibrary_ = DBDlOpen();
120     if (PreferenceDbAdapter::gLibrary_ != nullptr) {
121         GRDDBApiInitEnhance(PreferenceDbAdapter::api_);
122     } else {
123         LOG_DEBUG("use default db kernel");
124     }
125     PreferenceDbAdapter::isInit_ = true;
126     return;
127 }
128 
PreferencesDb()129 PreferencesDb::PreferencesDb()
130 {
131 }
132 
~PreferencesDb()133 PreferencesDb::~PreferencesDb()
134 {
135     if (db_ != nullptr || PreferenceDbAdapter::GetApiInstance().DbCloseApi != nullptr) {
136         PreferenceDbAdapter::GetApiInstance().DbCloseApi(db_, GRD_DB_CLOSE_IGNORE_ERROR);
137         db_ = nullptr;
138         LOG_DEBUG("destructor: calling close db.");
139     } else {
140         LOG_DEBUG("destructor: db closed before or dbClose api not loaded, db closed before ? %{public}d.",
141             db_ == nullptr);
142     }
143 }
144 
GetReportParam(const std::string & info,uint32_t errCode)145 ReportParam PreferencesDb::GetReportParam(const std::string &info, uint32_t errCode)
146 {
147     ReportParam reportParam = {
148         bundleName_,
149         ENHANCE_DB,
150         ExtractFileName(dbPath_),
151         errCode,
152         errno,
153         info};
154     return reportParam;
155 }
156 
CloseDb()157 int PreferencesDb::CloseDb()
158 {
159     if (db_ != nullptr) {
160         if (PreferenceDbAdapter::GetApiInstance().DbCloseApi == nullptr) {
161             LOG_ERROR("api load failed: DbCloseApi");
162             return E_ERROR;
163         }
164         int errCode = PreferenceDbAdapter::GetApiInstance().DbCloseApi(db_, GRD_DB_CLOSE_IGNORE_ERROR);
165         if (errCode != E_OK) {
166             LOG_ERROR("close db failed, errcode=%{public}d, file: %{public}s", errCode,
167                 ExtractFileName(dbPath_).c_str());
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     }
189     return TransferGrdErrno(errCode);
190 }
191 
OpenDb(bool isNeedRebuild)192 int PreferencesDb::OpenDb(bool isNeedRebuild)
193 {
194     if (PreferenceDbAdapter::GetApiInstance().DbOpenApi == nullptr) {
195         LOG_ERROR("api load failed: DbOpenApi");
196         return E_ERROR;
197     }
198     uint32_t flag = GRD_DB_OPEN_CREATE;
199     if (isNeedRebuild) {
200         flag |= GRD_DB_OPEN_CHECK;
201     }
202     int errCode = PreferenceDbAdapter::GetApiInstance().DbOpenApi(dbPath_.c_str(), CONFIG_STR, flag, &db_);
203     if (errCode != GRD_OK) {
204         // log outside
205         std::string errMsg = isNeedRebuild ? "open db failed with open_create | open_check" :
206                 "open db failed with open_create";
207         LOG_ERROR("%{public}s, errCode: %{public}d, isRebuild:%{public}d", errMsg.c_str(), errCode, isNeedRebuild);
208     }
209     return errCode;
210 }
211 
RepairDb()212 int PreferencesDb::RepairDb()
213 {
214     if (PreferenceDbAdapter::GetApiInstance().DbRepairApi == nullptr) {
215         LOG_ERROR("api load failed: DbRepairApi");
216         return E_ERROR;
217     }
218     int errCode = PreferenceDbAdapter::GetApiInstance().DbRepairApi(dbPath_.c_str(), CONFIG_STR);
219     if (errCode != GRD_OK) {
220         LOG_ERROR("repair db failed, errCode: %{public}d", errCode);
221     }
222     return errCode;
223 }
224 
TryRepairAndRebuild(int openCode)225 int PreferencesDb::TryRepairAndRebuild(int openCode)
226 {
227     LOG_ERROR("db corrupted, errCode: %{public}d, begin to rebuild, db: %{public}s", openCode,
228         ExtractFileName(dbPath_).c_str());
229     int retryTimes = DB_REPAIR_RETRY_TIMES;
230     int innerErr = GRD_OK;
231     do {
232         innerErr = RepairDb();
233         if (innerErr == GRD_OK) {
234             LOG_INFO("db repair success");
235             return innerErr;
236         } else if (innerErr == GRD_DB_BUSY) {
237             LOG_ERROR("db repair failed, busy, retry times : %{public}d, errCode: %{public}d",
238                 (DB_REPAIR_RETRY_TIMES - retryTimes + 1), innerErr);
239 #if !defined(WINDOWS_PLATFORM)
240             std::this_thread::sleep_for(WAIT_REPAIRE_TIMEOUT);
241 #endif
242         } else {
243             // other error, break to rebuild
244             LOG_ERROR("db repair failed: %{public}d, begin to rebuild", innerErr);
245             break;
246         }
247         retryTimes--;
248     } while (retryTimes > 0);
249 
250     innerErr = OpenDb(true);
251     if (innerErr == GRD_OK || innerErr == GRD_REBUILD_DATABASE) {
252         LOG_INFO("rebuild db success, errCode: %{public}d", innerErr);
253         return GRD_OK;
254     }
255     LOG_ERROR("rebuild db failed, errCode: %{public}d, file: %{public}s", innerErr, ExtractFileName(dbPath_).c_str());
256     return innerErr;
257 }
258 
Init(const std::string & dbPath,const std::string & bundleName)259 int PreferencesDb::Init(const std::string &dbPath, const std::string &bundleName)
260 {
261     if (db_ != nullptr) {
262         LOG_DEBUG("Init: already init.");
263         return E_OK;
264     }
265     if (PreferenceDbAdapter::GetApiInstance().DbIndexPreloadApi == nullptr) {
266         LOG_ERROR("api load failed: DbIndexPreloadApi");
267         return E_ERROR;
268     }
269     dbPath_ = dbPath + ".db";
270     bundleName_ = bundleName;
271     int errCode = OpenDb(false);
272     if (errCode == GRD_DATA_CORRUPTED) {
273         PreferencesDfxManager::Report(GetReportParam("db corrupted", errCode), EVENT_NAME_DB_CORRUPTED);
274         int innerErr = TryRepairAndRebuild(errCode);
275         if (innerErr != GRD_OK) {
276             // log inside
277             return TransferGrdErrno(innerErr);
278         }
279         ReportParam param = GetReportParam("db repair success", GRD_OK);
280         param.errnoCode = 0;
281         PreferencesDfxManager::Report(param, EVENT_NAME_DB_CORRUPTED);
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                 return TransferGrdErrno(ret);
327             }
328         }
329         retryTimes--;
330     } while (retryTimes > 0);
331 
332     LOG_ERROR("rd put over retry times, errcode: :%{public}d", ret);
333     return TransferGrdErrno(ret);
334 }
335 
Delete(const std::vector<uint8_t> & key)336 int PreferencesDb::Delete(const std::vector<uint8_t> &key)
337 {
338     if (db_ == nullptr) {
339         LOG_ERROR("Delete failed, db has been closed.");
340         return E_ALREADY_CLOSED;
341     } else if (PreferenceDbAdapter::GetApiInstance().DbKvDelApi == nullptr) {
342         LOG_ERROR("api load failed: DbKvDelApi");
343         return E_ERROR;
344     }
345 
346     GRD_KVItemT innerKey = BlobToKvItem(key);
347 
348     int retryTimes = CREATE_COLLECTION_RETRY_TIMES;
349     int ret = E_OK;
350     do {
351         ret = PreferenceDbAdapter::GetApiInstance().DbKvDelApi(db_, TABLENAME, &innerKey);
352         if (ret == GRD_UNDEFINED_TABLE) {
353             LOG_INFO("CreateCollection called when Delete, file: %{public}s", ExtractFileName(dbPath_).c_str());
354             (void)CreateCollection();
355         } else {
356             if (ret == E_OK) {
357                 return TransferGrdErrno(ret);
358             } else {
359                 LOG_ERROR("rd delete failed:%{public}d", ret);
360                 return TransferGrdErrno(ret);
361             }
362         }
363         retryTimes--;
364     } while (retryTimes > 0);
365 
366     LOG_ERROR("rd delete over retry times, errcode: :%{public}d", ret);
367     return TransferGrdErrno(ret);
368 }
369 
Get(const std::vector<uint8_t> & key,std::vector<uint8_t> & value)370 int PreferencesDb::Get(const std::vector<uint8_t> &key, std::vector<uint8_t> &value)
371 {
372     if (db_ == nullptr) {
373         LOG_ERROR("Get failed, db has been closed.");
374         return E_ALREADY_CLOSED;
375     } else if (PreferenceDbAdapter::GetApiInstance().DbKvGetApi == nullptr ||
376         PreferenceDbAdapter::GetApiInstance().FreeItemApi == nullptr) {
377         LOG_ERROR("api load failed: DbKvGetApi or FreeItemApi");
378         return E_ERROR;
379     }
380 
381     GRD_KVItemT innerKey = BlobToKvItem(key);
382     GRD_KVItemT innerVal = { NULL, 0 };
383 
384     int retryTimes = CREATE_COLLECTION_RETRY_TIMES;
385     int ret = GRD_OK;
386     do {
387         ret = PreferenceDbAdapter::GetApiInstance().DbKvGetApi(db_, TABLENAME, &innerKey, &innerVal);
388         if (ret == GRD_UNDEFINED_TABLE) {
389             LOG_INFO("CreateCollection called when Get, file: %{public}s", ExtractFileName(dbPath_).c_str());
390             (void)CreateCollection();
391         } else {
392             if (ret == GRD_OK) {
393                 break;
394             }
395             if (ret != GRD_NO_DATA) {
396                 LOG_ERROR("rd get failed:%{public}d", ret);
397             }
398             return TransferGrdErrno(ret);
399         }
400         retryTimes--;
401     } while (retryTimes > 0);
402 
403     if (retryTimes == 0) {
404         LOG_ERROR("rd get over retry times, errcode: :%{public}d", ret);
405         return TransferGrdErrno(ret);
406     }
407     value.resize(innerVal.dataLen);
408     value = KvItemToBlob(innerVal);
409     (void)PreferenceDbAdapter::GetApiInstance().FreeItemApi(&innerVal);
410     return TransferGrdErrno(ret);
411 }
412 
GetAllInner(std::list<std::pair<std::vector<uint8_t>,std::vector<uint8_t>>> & data,GRD_ResultSet * resultSet)413 int PreferencesDb::GetAllInner(std::list<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>> &data,
414     GRD_ResultSet *resultSet)
415 {
416     int ret = E_OK;
417     while (TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().NextApi(resultSet)) == E_OK) {
418         std::pair<std::vector<uint8_t>, std::vector<uint8_t>> dataItem;
419         uint32_t keySize = 0;
420         uint32_t valueSize = 0;
421         ret = PreferenceDbAdapter::GetApiInstance().GetItemSizeApi(resultSet, &keySize, &valueSize);
422         if (ret != GRD_OK) {
423             LOG_ERROR("ger reulstSet kv size failed %{public}d", ret);
424             return TransferGrdErrno(ret);
425         }
426         dataItem.first.resize(keySize);
427         dataItem.second.resize(valueSize);
428         ret = PreferenceDbAdapter::GetApiInstance().GetItemApi(resultSet, dataItem.first.data(),
429             dataItem.second.data());
430         if (ret != E_OK) {
431             LOG_ERROR("ger reulstSet failed %{public}d", ret);
432             return TransferGrdErrno(ret);
433         }
434         data.emplace_back(std::move(dataItem));
435     }
436     return TransferGrdErrno(ret);
437 }
438 
IsApiValid()439 static inline bool IsApiValid()
440 {
441     auto& apiInstance = PreferenceDbAdapter::GetApiInstance();
442     return (apiInstance.DbKvFilterApi != nullptr && apiInstance.NextApi != nullptr &&
443         apiInstance.GetItemSizeApi != nullptr && apiInstance.GetItemApi != nullptr &&
444         apiInstance.FreeResultSetApi != nullptr);
445 }
446 
GetAll(std::list<std::pair<std::vector<uint8_t>,std::vector<uint8_t>>> & data)447 int PreferencesDb::GetAll(std::list<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>> &data)
448 {
449     if (db_ == nullptr) {
450         LOG_ERROR("GetAll failed, db has been closed.");
451         return E_ALREADY_CLOSED;
452     }
453     if (!IsApiValid()) {
454         LOG_ERROR("api load failed when get all");
455         return E_ERROR;
456     }
457 
458     GRD_FilterOptionT param;
459     param.mode = KV_SCAN_ALL;
460     GRD_ResultSet *resultSet = nullptr;
461 
462     int retryTimes = CREATE_COLLECTION_RETRY_TIMES;
463     int ret = E_OK;
464 
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 if (ret == GRD_OK) {
471             int innerErr = GetAllInner(data, resultSet); // log inside when failed
472             PreferenceDbAdapter::GetApiInstance().FreeResultSetApi(resultSet);
473             return innerErr;
474         } else {
475             LOG_ERROR("rd kv filter failed:%{public}d", ret);
476             return TransferGrdErrno(ret);
477         }
478         retryTimes--;
479     } while (retryTimes > 0);
480 
481     LOG_ERROR("rd get over retry times, errcode: :%{public}d", ret);
482     return TransferGrdErrno(ret);
483 }
484 
DropCollection()485 int PreferencesDb::DropCollection()
486 {
487     if (db_ == nullptr) {
488         LOG_ERROR("DropCollection failed, db has been closed.");
489         return E_ALREADY_CLOSED;
490     } else if (PreferenceDbAdapter::GetApiInstance().DbDropCollectionApi == nullptr) {
491         LOG_ERROR("api load failed: DbDropCollectionApi");
492         return E_ERROR;
493     }
494 
495     int errCode = PreferenceDbAdapter::GetApiInstance().DbDropCollectionApi(db_, TABLENAME, 0);
496     if (errCode != E_OK) {
497         LOG_ERROR("rd drop collection failed:%{public}d", errCode);
498     }
499     return TransferGrdErrno(errCode);
500 }
501 
BlobToKvItem(const std::vector<uint8_t> & blob)502 GRD_KVItemT PreferencesDb::BlobToKvItem(const std::vector<uint8_t> &blob)
503 {
504     return {
505         .data = (void *)&blob[0],
506         .dataLen = (uint32_t)blob.size()
507     };
508 }
509 
KvItemToBlob(GRD_KVItemT & item)510 std::vector<uint8_t> PreferencesDb::KvItemToBlob(GRD_KVItemT &item)
511 {
512     return std::vector<uint8_t>(static_cast<uint8_t *>(item.data),
513         static_cast<uint8_t *>(item.data) + item.dataLen);
514 }
515 
GetKernelDataVersion(int64_t & dataVersion)516 int PreferencesDb::GetKernelDataVersion(int64_t &dataVersion)
517 {
518     if (db_ == nullptr) {
519         LOG_ERROR("Get kernel data version failed, db has been closed.");
520         return E_ALREADY_CLOSED;
521     } else if (PreferenceDbAdapter::GetApiInstance().DbGetConfigApi == nullptr) {
522         LOG_ERROR("api load failed: DbGetConfigApi");
523         return E_ERROR;
524     }
525 
526     GRD_DbValueT kernelDataVersion = PreferenceDbAdapter::GetApiInstance().DbGetConfigApi(db_,
527         GRD_ConfigTypeE::GRD_CONFIG_DATA_VERSION);
528     if (kernelDataVersion.type != GRD_DbDataTypeE::GRD_DB_DATATYPE_INTEGER) {
529         LOG_ERROR("get wrong data version type: %d", kernelDataVersion.type);
530         return E_ERROR;
531     }
532 
533     dataVersion = kernelDataVersion.value.longValue;
534     return E_OK;
535 }
536 } // End of namespace NativePreferences
537 } // End of namespace OHOS