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 std::string errMsg = "db repair failed";
221 LOG_ERROR("repair db failed, errCode: %{public}d", errCode);
222 }
223 return errCode;
224 }
225
TryRepairAndRebuild(int openCode)226 int PreferencesDb::TryRepairAndRebuild(int openCode)
227 {
228 LOG_ERROR("db corrupted, errCode: %{public}d, begin to rebuild, db: %{public}s", openCode,
229 ExtractFileName(dbPath_).c_str());
230 int retryTimes = DB_REPAIR_RETRY_TIMES;
231 int innerErr = GRD_OK;
232 do {
233 innerErr = RepairDb();
234 if (innerErr == GRD_OK) {
235 LOG_INFO("db repair success");
236 return innerErr;
237 } else if (innerErr == GRD_DB_BUSY) {
238 LOG_ERROR("db repair failed, busy, retry times : %{public}d, errCode: %{public}d",
239 (DB_REPAIR_RETRY_TIMES - retryTimes + 1), innerErr);
240 #if !defined(WINDOWS_PLATFORM)
241 std::this_thread::sleep_for(WAIT_REPAIRE_TIMEOUT);
242 #endif
243 } else {
244 // other error, break to rebuild
245 LOG_ERROR("db repair failed: %{public}d, begin to rebuild", innerErr);
246 break;
247 }
248 retryTimes--;
249 } while (retryTimes > 0);
250
251 innerErr = OpenDb(true);
252 if (innerErr == GRD_OK || innerErr == GRD_REBUILD_DATABASE) {
253 LOG_INFO("rebuild db success, errCode: %{public}d", innerErr);
254 return GRD_OK;
255 }
256 LOG_ERROR("rebuild db failed, errCode: %{public}d, file: %{public}s", innerErr, ExtractFileName(dbPath_).c_str());
257 return innerErr;
258 }
259
Init(const std::string &dbPath, const std::string &bundleName)260 int PreferencesDb::Init(const std::string &dbPath, const std::string &bundleName)
261 {
262 if (db_ != nullptr) {
263 LOG_DEBUG("Init: already init.");
264 return E_OK;
265 }
266 if (PreferenceDbAdapter::GetApiInstance().DbIndexPreloadApi == nullptr) {
267 LOG_ERROR("api load failed: DbIndexPreloadApi");
268 return E_ERROR;
269 }
270 dbPath_ = dbPath + ".db";
271 bundleName_ = bundleName;
272 int errCode = OpenDb(false);
273 if (errCode == GRD_DATA_CORRUPTED) {
274 PreferencesDfxManager::ReportDbFault(GetReportParam("db corrupted", errCode));
275 }
276 if (errCode == GRD_DATA_CORRUPTED || errCode == GRD_INNER_ERR) {
277 int innerErr = TryRepairAndRebuild(errCode);
278 if (innerErr != GRD_OK) {
279 // log inside
280 return TransferGrdErrno(innerErr);
281 }
282 if (errCode == GRD_DATA_CORRUPTED) {
283 ReportParam param = GetReportParam("db repair success", GRD_OK);
284 param.errnoCode = 0;
285 PreferencesDfxManager::ReportDbFault(param);
286 }
287 } else if (errCode != GRD_OK) {
288 LOG_ERROR("db open failed, errCode: %{public}d", errCode);
289 return TransferGrdErrno(errCode);
290 }
291
292 errCode = CreateCollection();
293 if (errCode != E_OK) {
294 LOG_ERROR("create collection failed when init: %{public}d, but ignored.", errCode);
295 // ignore create collection error
296 }
297
298 errCode = TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().DbIndexPreloadApi(db_, TABLENAME));
299 if (errCode != E_OK) {
300 LOG_ERROR("Init: Index preload FAILED %{public}d", errCode);
301 return errCode;
302 }
303 return errCode;
304 }
305
Put(const std::vector<uint8_t> &key, const std::vector<uint8_t> &value)306 int PreferencesDb::Put(const std::vector<uint8_t> &key, const std::vector<uint8_t> &value)
307 {
308 if (db_ == nullptr) {
309 LOG_ERROR("Put failed, db has been closed.");
310 return E_ALREADY_CLOSED;
311 } else if (PreferenceDbAdapter::GetApiInstance().DbKvPutApi == nullptr) {
312 LOG_ERROR("api load failed: DbKvPutApi");
313 return E_ERROR;
314 }
315
316 GRD_KVItemT innerKey = BlobToKvItem(key);
317 GRD_KVItemT innerVal = BlobToKvItem(value);
318
319 int retryTimes = CREATE_COLLECTION_RETRY_TIMES;
320 int ret = E_OK;
321 do {
322 ret = PreferenceDbAdapter::GetApiInstance().DbKvPutApi(db_, TABLENAME, &innerKey, &innerVal);
323 if (ret == GRD_UNDEFINED_TABLE) {
324 LOG_INFO("CreateCollection called when Put, file: %{public}s", ExtractFileName(dbPath_).c_str());
325 (void)CreateCollection();
326 } else {
327 if (ret == GRD_OK) {
328 return TransferGrdErrno(ret);
329 } else {
330 LOG_ERROR("rd put failed:%{public}d", ret);
331 return TransferGrdErrno(ret);
332 }
333 }
334 retryTimes--;
335 } while (retryTimes > 0);
336
337 LOG_ERROR("rd put over retry times, errcode: :%{public}d", ret);
338 return TransferGrdErrno(ret);
339 }
340
Delete(const std::vector<uint8_t> &key)341 int PreferencesDb::Delete(const std::vector<uint8_t> &key)
342 {
343 if (db_ == nullptr) {
344 LOG_ERROR("Delete failed, db has been closed.");
345 return E_ALREADY_CLOSED;
346 } else if (PreferenceDbAdapter::GetApiInstance().DbKvDelApi == nullptr) {
347 LOG_ERROR("api load failed: DbKvDelApi");
348 return E_ERROR;
349 }
350
351 GRD_KVItemT innerKey = BlobToKvItem(key);
352
353 int retryTimes = CREATE_COLLECTION_RETRY_TIMES;
354 int ret = E_OK;
355 do {
356 ret = PreferenceDbAdapter::GetApiInstance().DbKvDelApi(db_, TABLENAME, &innerKey);
357 if (ret == GRD_UNDEFINED_TABLE) {
358 LOG_INFO("CreateCollection called when Delete, file: %{public}s", ExtractFileName(dbPath_).c_str());
359 (void)CreateCollection();
360 } else {
361 if (ret == E_OK) {
362 return TransferGrdErrno(ret);
363 } else {
364 LOG_ERROR("rd delete failed:%{public}d", ret);
365 return TransferGrdErrno(ret);
366 }
367 }
368 retryTimes--;
369 } while (retryTimes > 0);
370
371 LOG_ERROR("rd delete over retry times, errcode: :%{public}d", ret);
372 return TransferGrdErrno(ret);
373 }
374
Get(const std::vector<uint8_t> &key, std::vector<uint8_t> &value)375 int PreferencesDb::Get(const std::vector<uint8_t> &key, std::vector<uint8_t> &value)
376 {
377 if (db_ == nullptr) {
378 LOG_ERROR("Get failed, db has been closed.");
379 return E_ALREADY_CLOSED;
380 } else if (PreferenceDbAdapter::GetApiInstance().DbKvGetApi == nullptr ||
381 PreferenceDbAdapter::GetApiInstance().FreeItemApi == nullptr) {
382 LOG_ERROR("api load failed: DbKvGetApi or FreeItemApi");
383 return E_ERROR;
384 }
385
386 GRD_KVItemT innerKey = BlobToKvItem(key);
387 GRD_KVItemT innerVal = { NULL, 0 };
388
389 int retryTimes = CREATE_COLLECTION_RETRY_TIMES;
390 int ret = E_OK;
391 do {
392 ret = PreferenceDbAdapter::GetApiInstance().DbKvGetApi(db_, TABLENAME, &innerKey, &innerVal);
393 if (ret == GRD_UNDEFINED_TABLE) {
394 LOG_INFO("CreateCollection called when Get, file: %{public}s", ExtractFileName(dbPath_).c_str());
395 (void)CreateCollection();
396 } else {
397 if (ret == E_OK) {
398 break;
399 } else {
400 LOG_ERROR("rd get failed:%{public}d", ret);
401 return TransferGrdErrno(ret);
402 }
403 }
404 retryTimes--;
405 } while (retryTimes > 0);
406
407 if (retryTimes == 0) {
408 LOG_ERROR("rd get over retry times, errcode: :%{public}d", ret);
409 return TransferGrdErrno(ret);
410 }
411 value.resize(innerVal.dataLen);
412 value = KvItemToBlob(innerVal);
413 (void)PreferenceDbAdapter::GetApiInstance().FreeItemApi(&innerVal);
414 return TransferGrdErrno(ret);
415 }
416
GetAllInner(std::list<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>> &data, GRD_ResultSet *resultSet)417 int PreferencesDb::GetAllInner(std::list<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>> &data,
418 GRD_ResultSet *resultSet)
419 {
420 int ret = E_OK;
421 while (TransferGrdErrno(PreferenceDbAdapter::GetApiInstance().NextApi(resultSet)) == E_OK) {
422 std::pair<std::vector<uint8_t>, std::vector<uint8_t>> dataItem;
423 uint32_t keySize = 0;
424 uint32_t valueSize = 0;
425 ret = PreferenceDbAdapter::GetApiInstance().GetItemSizeApi(resultSet, &keySize, &valueSize);
426 if (ret != GRD_OK) {
427 LOG_ERROR("ger reulstSet kv size failed %{public}d", ret);
428 return TransferGrdErrno(ret);
429 }
430 dataItem.first.resize(keySize);
431 dataItem.second.resize(valueSize);
432 ret = PreferenceDbAdapter::GetApiInstance().GetItemApi(resultSet, dataItem.first.data(),
433 dataItem.second.data());
434 if (ret != E_OK) {
435 LOG_ERROR("ger reulstSet failed %{public}d", ret);
436 return TransferGrdErrno(ret);
437 }
438 data.emplace_back(std::move(dataItem));
439 }
440 return TransferGrdErrno(ret);
441 }
442
IsApiValid()443 static inline bool IsApiValid()
444 {
445 auto& apiInstance = PreferenceDbAdapter::GetApiInstance();
446 return (apiInstance.DbKvFilterApi != nullptr && apiInstance.NextApi != nullptr &&
447 apiInstance.GetItemSizeApi != nullptr && apiInstance.GetItemApi != nullptr &&
448 apiInstance.FreeResultSetApi != nullptr);
449 }
450
GetAll(std::list<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>> &data)451 int PreferencesDb::GetAll(std::list<std::pair<std::vector<uint8_t>, std::vector<uint8_t>>> &data)
452 {
453 if (db_ == nullptr) {
454 LOG_ERROR("GetAll failed, db has been closed.");
455 return E_ALREADY_CLOSED;
456 }
457 if (!IsApiValid()) {
458 LOG_ERROR("api load failed when get all");
459 return E_ERROR;
460 }
461
462 GRD_FilterOptionT param;
463 param.mode = KV_SCAN_ALL;
464 GRD_ResultSet *resultSet = nullptr;
465
466 int retryTimes = CREATE_COLLECTION_RETRY_TIMES;
467 int ret = E_OK;
468
469 do {
470 ret = PreferenceDbAdapter::GetApiInstance().DbKvFilterApi(db_, TABLENAME, ¶m, &resultSet);
471 if (ret == GRD_UNDEFINED_TABLE) {
472 LOG_INFO("CreateCollection called when GetAll, file: %{public}s", ExtractFileName(dbPath_).c_str());
473 (void)CreateCollection();
474 } else if (ret == GRD_OK) {
475 int innerErr = GetAllInner(data, resultSet); // log inside when failed
476 PreferenceDbAdapter::GetApiInstance().FreeResultSetApi(resultSet);
477 return innerErr;
478 } else {
479 LOG_ERROR("rd kv filter failed:%{public}d", ret);
480 return TransferGrdErrno(ret);
481 }
482 retryTimes--;
483 } while (retryTimes > 0);
484
485 LOG_ERROR("rd get over retry times, errcode: :%{public}d", ret);
486 return TransferGrdErrno(ret);
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 }
503 return TransferGrdErrno(errCode);
504 }
505
BlobToKvItem(const std::vector<uint8_t> &blob)506 GRD_KVItemT PreferencesDb::BlobToKvItem(const std::vector<uint8_t> &blob)
507 {
508 return {
509 .data = (void *)&blob[0],
510 .dataLen = (uint32_t)blob.size()
511 };
512 }
513
KvItemToBlob(GRD_KVItemT &item)514 std::vector<uint8_t> PreferencesDb::KvItemToBlob(GRD_KVItemT &item)
515 {
516 return std::vector<uint8_t>(static_cast<uint8_t *>(item.data),
517 static_cast<uint8_t *>(item.data) + item.dataLen);
518 }
519
GetKernelDataVersion(int64_t &dataVersion)520 int PreferencesDb::GetKernelDataVersion(int64_t &dataVersion)
521 {
522 if (db_ == nullptr) {
523 LOG_ERROR("Get kernel data version failed, db has been closed.");
524 return E_ALREADY_CLOSED;
525 } else if (PreferenceDbAdapter::GetApiInstance().DbGetConfigApi == nullptr) {
526 LOG_ERROR("api load failed: DbGetConfigApi");
527 return E_ERROR;
528 }
529
530 GRD_DbValueT kernelDataVersion = PreferenceDbAdapter::GetApiInstance().DbGetConfigApi(db_,
531 GRD_ConfigTypeE::GRD_CONFIG_DATA_VERSION);
532 if (kernelDataVersion.type != GRD_DbDataTypeE::GRD_DB_DATATYPE_INTEGER) {
533 LOG_ERROR("get wrong data version type: %d", kernelDataVersion.type);
534 return E_ERROR;
535 }
536
537 dataVersion = kernelDataVersion.value.longValue;
538 return E_OK;
539 }
540 } // End of namespace NativePreferences
541 } // End of namespace OHOS