1 /*
2 * Copyright (c) 2021 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 "RdbStoreConfig"
16 #include "rdb_store_config.h"
17
18 #include <sstream>
19
20 #include "logger.h"
21 #include "rdb_errno.h"
22 #include "rdb_security_manager.h"
23 #include "string_utils.h"
24
25 namespace OHOS::NativeRdb {
26 using namespace OHOS::Rdb;
27
RdbStoreConfig(const std::string & name,StorageMode storageMode,bool isReadOnly,const std::vector<uint8_t> & encryptKey,const std::string & journalMode,const std::string & syncMode,const std::string & databaseFileType,SecurityLevel securityLevel,bool isCreateNecessary,bool autoCheck,int journalSize,int pageSize,const std::string & encryptAlgo)28 RdbStoreConfig::RdbStoreConfig(const std::string &name, StorageMode storageMode, bool isReadOnly,
29 const std::vector<uint8_t> &encryptKey, const std::string &journalMode, const std::string &syncMode,
30 const std::string &databaseFileType, SecurityLevel securityLevel, bool isCreateNecessary, bool autoCheck,
31 int journalSize, int pageSize, const std::string &encryptAlgo)
32 : readOnly_(isReadOnly), isCreateNecessary_(isCreateNecessary), autoCheck_(autoCheck), journalSize_(journalSize),
33 pageSize_(pageSize), securityLevel_(securityLevel), storageMode_(storageMode), path_(name),
34 journalMode_(journalMode), syncMode_(syncMode), databaseFileType(databaseFileType), encryptAlgo_(encryptAlgo),
35 encryptKey_(encryptKey)
36 {
37 name_ = StringUtils::ExtractFileName(name);
38 }
39
~RdbStoreConfig()40 RdbStoreConfig::~RdbStoreConfig()
41 {
42 ClearEncryptKey();
43 }
44
45 /**
46 * Obtains the database name.
47 */
GetName() const48 std::string RdbStoreConfig::GetName() const
49 {
50 return name_;
51 }
52
53 /**
54 * Obtains the database path.
55 */
GetPath() const56 std::string RdbStoreConfig::GetPath() const
57 {
58 return path_;
59 }
60
61 /**
62 * Obtains the storage mode.
63 */
GetStorageMode() const64 StorageMode RdbStoreConfig::GetStorageMode() const
65 {
66 return storageMode_;
67 }
68
69 /**
70 * Obtains the journal mode in this {@code StoreConfig} object.
71 */
GetJournalMode() const72 std::string RdbStoreConfig::GetJournalMode() const
73 {
74 return journalMode_;
75 }
76
77 /**
78 * Obtains the synchronization mode in this {@code StoreConfig} object.
79 */
GetSyncMode() const80 std::string RdbStoreConfig::GetSyncMode() const
81 {
82 return syncMode_;
83 }
84
85 /**
86 * Checks whether the database is read-only.
87 */
IsReadOnly() const88 bool RdbStoreConfig::IsReadOnly() const
89 {
90 return readOnly_;
91 }
92
93 /**
94 * Checks whether the database is memory.
95 */
IsMemoryRdb() const96 bool RdbStoreConfig::IsMemoryRdb() const
97 {
98 return GetStorageMode() == StorageMode::MODE_MEMORY;
99 }
100
101 /**
102 * Obtains the database file type in this {@code StoreConfig} object.
103 */
GetDatabaseFileType() const104 std::string RdbStoreConfig::GetDatabaseFileType() const
105 {
106 return databaseFileType;
107 }
108
SetName(std::string name)109 void RdbStoreConfig::SetName(std::string name)
110 {
111 this->name_ = std::move(name);
112 }
113
114 /**
115 * Sets the journal mode for the object.
116 */
SetJournalMode(JournalMode journalMode)117 void RdbStoreConfig::SetJournalMode(JournalMode journalMode)
118 {
119 this->journalMode_ = GetJournalModeValue(journalMode);
120 }
121
SetJournalMode(const std::string & journalMode)122 void RdbStoreConfig::SetJournalMode(const std::string &journalMode)
123 {
124 this->journalMode_ = journalMode;
125 }
126
SetDatabaseFileType(DatabaseFileType type)127 void RdbStoreConfig::SetDatabaseFileType(DatabaseFileType type)
128 {
129 this->databaseFileType = GetDatabaseFileTypeValue(type);
130 }
131
132 /**
133 * Sets the path for the object.
134 */
SetPath(std::string path)135 void RdbStoreConfig::SetPath(std::string path)
136 {
137 this->path_ = std::move(path);
138 }
139
SetStorageMode(StorageMode storageMode)140 void RdbStoreConfig::SetStorageMode(StorageMode storageMode)
141 {
142 this->storageMode_ = storageMode;
143 }
144
IsAutoCheck() const145 bool RdbStoreConfig::IsAutoCheck() const
146 {
147 return autoCheck_;
148 }
SetAutoCheck(bool autoCheck)149 void RdbStoreConfig::SetAutoCheck(bool autoCheck)
150 {
151 this->autoCheck_ = autoCheck;
152 }
GetJournalSize() const153 int RdbStoreConfig::GetJournalSize() const
154 {
155 return journalSize_;
156 }
SetJournalSize(int journalSize)157 void RdbStoreConfig::SetJournalSize(int journalSize)
158 {
159 this->journalSize_ = journalSize;
160 }
GetPageSize() const161 int RdbStoreConfig::GetPageSize() const
162 {
163 return pageSize_;
164 }
SetPageSize(int pageSize)165 void RdbStoreConfig::SetPageSize(int pageSize)
166 {
167 this->pageSize_ = pageSize;
168 }
GetEncryptAlgo() const169 const std::string RdbStoreConfig::GetEncryptAlgo() const
170 {
171 return encryptAlgo_;
172 }
SetEncryptAlgo(const std::string & encryptAlgo)173 void RdbStoreConfig::SetEncryptAlgo(const std::string &encryptAlgo)
174 {
175 this->encryptAlgo_ = encryptAlgo;
176 }
177
SetReadOnly(bool readOnly)178 void RdbStoreConfig::SetReadOnly(bool readOnly)
179 {
180 this->readOnly_ = readOnly;
181 }
182
SetDistributedType(DistributedType type)183 int RdbStoreConfig::SetDistributedType(DistributedType type)
184 {
185 if (type != DistributedType::RDB_DEVICE_COLLABORATION) {
186 LOG_ERROR("type is invalid.");
187 return E_ERROR;
188 }
189 distributedType_ = type;
190 return E_OK;
191 }
192
GetDistributedType() const193 DistributedType RdbStoreConfig::GetDistributedType() const
194 {
195 return distributedType_;
196 }
197
SetBundleName(const std::string & bundleName)198 int RdbStoreConfig::SetBundleName(const std::string &bundleName)
199 {
200 if (bundleName.empty()) {
201 LOG_ERROR("bundleName is empty.");
202 return E_ERROR;
203 }
204 bundleName_ = bundleName;
205 return E_OK;
206 }
207
GetBundleName() const208 std::string RdbStoreConfig::GetBundleName() const
209 {
210 return bundleName_;
211 }
212
SetModuleName(const std::string & moduleName)213 void RdbStoreConfig::SetModuleName(const std::string &moduleName)
214 {
215 moduleName_ = moduleName;
216 }
217
GetModuleName() const218 std::string RdbStoreConfig::GetModuleName() const
219 {
220 return moduleName_;
221 }
222
SetServiceName(const std::string & serviceName)223 void RdbStoreConfig::SetServiceName(const std::string &serviceName)
224 {
225 SetBundleName(serviceName);
226 }
227
SetArea(int32_t area)228 void RdbStoreConfig::SetArea(int32_t area)
229 {
230 area_ = area + 1;
231 }
232
GetArea() const233 int32_t RdbStoreConfig::GetArea() const
234 {
235 return area_;
236 }
237
GetJournalModeValue(JournalMode journalMode)238 std::string RdbStoreConfig::GetJournalModeValue(JournalMode journalMode)
239 {
240 std::string value = "";
241
242 switch (journalMode) {
243 case JournalMode::MODE_DELETE:
244 return "DELETE";
245 case JournalMode::MODE_TRUNCATE:
246 return "TRUNCATE";
247 case JournalMode::MODE_PERSIST:
248 return "PERSIST";
249 case JournalMode::MODE_MEMORY:
250 return "MEMORY";
251 case JournalMode::MODE_WAL:
252 return "WAL";
253 case JournalMode::MODE_OFF:
254 return "OFF";
255 default:
256 break;
257 }
258 return value;
259 }
260
GetSyncModeValue(SyncMode syncMode)261 std::string RdbStoreConfig::GetSyncModeValue(SyncMode syncMode)
262 {
263 std::string value = "";
264 switch (syncMode) {
265 case SyncMode::MODE_OFF:
266 return "MODE_OFF";
267 case SyncMode::MODE_NORMAL:
268 return "MODE_NORMAL";
269 case SyncMode::MODE_FULL:
270 return "MODE_FULL";
271 case SyncMode::MODE_EXTRA:
272 return "MODE_EXTRA";
273 default:
274 break;
275 }
276
277 return value;
278 }
279
GetDatabaseFileTypeValue(DatabaseFileType databaseFileType)280 std::string RdbStoreConfig::GetDatabaseFileTypeValue(DatabaseFileType databaseFileType)
281 {
282 std::string value = "";
283 switch (databaseFileType) {
284 case DatabaseFileType::NORMAL:
285 return "db";
286 case DatabaseFileType::BACKUP:
287 return "backup";
288 case DatabaseFileType::CORRUPT:
289 return "corrupt";
290 default:
291 break;
292 }
293
294 return value;
295 }
296
SetSecurityLevel(SecurityLevel sl)297 void RdbStoreConfig::SetSecurityLevel(SecurityLevel sl)
298 {
299 securityLevel_ = sl;
300 }
301
GetSecurityLevel() const302 SecurityLevel RdbStoreConfig::GetSecurityLevel() const
303 {
304 return securityLevel_;
305 }
306
SetEncryptStatus(const bool status)307 void RdbStoreConfig::SetEncryptStatus(const bool status)
308 {
309 this->isEncrypt_ = status;
310 }
311
IsEncrypt() const312 bool RdbStoreConfig::IsEncrypt() const
313 {
314 return isEncrypt_ || !encryptKey_.empty();
315 }
316
IsCreateNecessary() const317 bool RdbStoreConfig::IsCreateNecessary() const
318 {
319 return isCreateNecessary_;
320 }
321
SetCreateNecessary(bool isCreateNecessary)322 void RdbStoreConfig::SetCreateNecessary(bool isCreateNecessary)
323 {
324 isCreateNecessary_ = isCreateNecessary;
325 }
326
GetReadConSize() const327 int RdbStoreConfig::GetReadConSize() const
328 {
329 return readConSize_;
330 }
331
SetReadConSize(int readConSize)332 void RdbStoreConfig::SetReadConSize(int readConSize)
333 {
334 readConSize_= readConSize;
335 }
336
SetEncryptKey(const std::vector<uint8_t> & encryptKey)337 void RdbStoreConfig::SetEncryptKey(const std::vector<uint8_t> &encryptKey)
338 {
339 encryptKey_ = encryptKey;
340 }
341
RestoreEncryptKey(const std::vector<uint8_t> & encryptKey) const342 void RdbStoreConfig::RestoreEncryptKey(const std::vector<uint8_t> &encryptKey) const
343 {
344 RdbSecurityManager::GetInstance().RestoreKeyFile(GetPath(), encryptKey);
345 encryptKey_.assign(encryptKey_.size(), 0);
346 newEncryptKey_.assign(newEncryptKey_.size(), 0);
347 encryptKey_ = encryptKey;
348 }
349
SetNewEncryptKey(const std::vector<uint8_t> newEncryptKey)350 void RdbStoreConfig::SetNewEncryptKey(const std::vector<uint8_t> newEncryptKey)
351 {
352 newEncryptKey_ = newEncryptKey;
353 }
354
GetEncryptKey() const355 std::vector<uint8_t> RdbStoreConfig::GetEncryptKey() const
356 {
357 return encryptKey_;
358 }
359
ChangeEncryptKey() const360 void RdbStoreConfig::ChangeEncryptKey() const
361 {
362 RdbSecurityManager::GetInstance().ChangeKeyFile(GetPath());
363 if (newEncryptKey_.empty()) {
364 return;
365 }
366 encryptKey_.assign(encryptKey_.size(), 0);
367 encryptKey_.assign(newEncryptKey_.data(), newEncryptKey_.data() + newEncryptKey_.size());
368 newEncryptKey_.assign(newEncryptKey_.size(), 0);
369 newEncryptKey_.resize(0);
370 }
371
GetNewEncryptKey() const372 std::vector<uint8_t> RdbStoreConfig::GetNewEncryptKey() const
373 {
374 return newEncryptKey_;
375 }
376
Initialize() const377 int32_t RdbStoreConfig::Initialize() const
378 {
379 return GenerateEncryptedKey();
380 }
381
GenerateEncryptedKey() const382 int32_t RdbStoreConfig::GenerateEncryptedKey() const
383 {
384 if (!isEncrypt_) {
385 return E_OK;
386 }
387
388 auto name = bundleName_;
389 if (name.empty()) {
390 name = std::string(path_).substr(0, path_.rfind("/") + 1);
391 }
392 using KeyFileType = RdbSecurityManager::KeyFileType;
393 auto errCode = RdbSecurityManager::GetInstance().Init(name);
394 if (errCode != E_OK) {
395 LOG_ERROR("generate root encrypt key failed, bundleName_:%{public}s", bundleName_.c_str());
396 return errCode;
397 }
398 auto rdbPwd = RdbSecurityManager::GetInstance().GetRdbPassword(path_, KeyFileType::PUB_KEY_FILE);
399 if (rdbPwd.IsValid()) {
400 encryptKey_ = std::vector<uint8_t>(rdbPwd.GetData(), rdbPwd.GetData() + rdbPwd.GetSize());
401 }
402 rdbPwd.Clear();
403 if ((rdbPwd.isKeyExpired && autoRekey_) ||
404 RdbSecurityManager::GetInstance().IsKeyFileExists(path_, KeyFileType::PUB_KEY_FILE_NEW_KEY)) {
405 auto rdbNewPwd = RdbSecurityManager::GetInstance().GetRdbPassword(path_, KeyFileType::PUB_KEY_FILE_NEW_KEY);
406 if (rdbNewPwd.IsValid()) {
407 newEncryptKey_ = std::vector<uint8_t>(rdbNewPwd.GetData(), rdbNewPwd.GetData() + rdbNewPwd.GetSize());
408 }
409 rdbPwd.Clear();
410 }
411 if (encryptKey_.empty() && newEncryptKey_.empty()) {
412 LOG_WARN("key is inValid, bundleName_:%{public}s", bundleName_.c_str());
413 }
414 return E_OK;
415 }
416
ClearEncryptKey()417 void RdbStoreConfig::ClearEncryptKey()
418 {
419 encryptKey_.assign(encryptKey_.size(), 0);
420 newEncryptKey_.assign(newEncryptKey_.size(), 0);
421 }
422
SetScalarFunction(const std::string & functionName,int argc,ScalarFunction function)423 void RdbStoreConfig::SetScalarFunction(const std::string &functionName, int argc, ScalarFunction function)
424 {
425 customScalarFunctions.try_emplace(functionName, ScalarFunctionInfo(function, argc));
426 }
427
SetScalarFunctions(const std::map<std::string,ScalarFunctionInfo> functions)428 void RdbStoreConfig::SetScalarFunctions(const std::map<std::string, ScalarFunctionInfo> functions)
429 {
430 customScalarFunctions = functions;
431 }
432
GetScalarFunctions() const433 std::map<std::string, ScalarFunctionInfo> RdbStoreConfig::GetScalarFunctions() const
434 {
435 return customScalarFunctions;
436 }
437
SetDataGroupId(const std::string & DataGroupId)438 void RdbStoreConfig::SetDataGroupId(const std::string &DataGroupId)
439 {
440 dataGroupId_ = DataGroupId;
441 }
442
GetDataGroupId() const443 std::string RdbStoreConfig::GetDataGroupId() const
444 {
445 return dataGroupId_;
446 }
447
SetAutoClean(bool isAutoClean)448 void RdbStoreConfig::SetAutoClean(bool isAutoClean)
449 {
450 isAutoClean_ = isAutoClean;
451 }
452
GetAutoClean() const453 bool RdbStoreConfig::GetAutoClean() const
454 {
455 return isAutoClean_;
456 }
457
SetIsVector(bool isVector)458 void RdbStoreConfig::SetIsVector(bool isVector)
459 {
460 isVector_ = isVector;
461 isVector ? SetDBType(DB_VECTOR) : SetDBType(DB_SQLITE);
462 }
463
IsVector() const464 bool RdbStoreConfig::IsVector() const
465 {
466 return isVector_;
467 }
468
SetCustomDir(const std::string & customDir)469 void RdbStoreConfig::SetCustomDir(const std::string &customDir)
470 {
471 customDir_ = customDir;
472 }
473
GetCustomDir() const474 std::string RdbStoreConfig::GetCustomDir() const
475 {
476 return customDir_;
477 }
478
SetVisitorDir(const std::string & visitorDir)479 void RdbStoreConfig::SetVisitorDir(const std::string &visitorDir)
480 {
481 visitorDir_ = visitorDir;
482 }
483
GetVisitorDir() const484 std::string RdbStoreConfig::GetVisitorDir() const
485 {
486 return visitorDir_;
487 }
488
IsSearchable() const489 bool RdbStoreConfig::IsSearchable() const
490 {
491 return isSearchable_;
492 }
493
SetSearchable(bool isSearchable)494 void RdbStoreConfig::SetSearchable(bool isSearchable)
495 {
496 isSearchable_ = isSearchable;
497 }
498
GetWriteTime() const499 int RdbStoreConfig::GetWriteTime() const
500 {
501 return writeTimeout_;
502 }
503
SetWriteTime(int timeout)504 void RdbStoreConfig::SetWriteTime(int timeout)
505 {
506 writeTimeout_ = std::max(MIN_TIMEOUT, std::min(MAX_TIMEOUT, timeout));
507 }
508
GetReadTime() const509 int RdbStoreConfig::GetReadTime() const
510 {
511 return readTimeout_;
512 }
513
SetReadTime(int timeout)514 void RdbStoreConfig::SetReadTime(int timeout)
515 {
516 readTimeout_ = std::max(MIN_TIMEOUT, std::min(MAX_TIMEOUT, timeout));
517 }
518
SetRoleType(RoleType role)519 void RdbStoreConfig::SetRoleType(RoleType role)
520 {
521 role_ = role;
522 }
523
GetRoleType() const524 uint32_t RdbStoreConfig::GetRoleType() const
525 {
526 return role_;
527 }
528
SetDBType(int32_t dbType)529 void RdbStoreConfig::SetDBType(int32_t dbType)
530 {
531 dbType_ = dbType;
532 }
533
GetDBType() const534 int32_t RdbStoreConfig::GetDBType() const
535 {
536 return dbType_;
537 }
538
SetAllowRebuild(bool allowRebuild)539 void RdbStoreConfig::SetAllowRebuild(bool allowRebuild)
540 {
541 this->allowRebuilt_ = allowRebuild;
542 }
543
GetAllowRebuild() const544 bool RdbStoreConfig::GetAllowRebuild() const
545 {
546 return allowRebuilt_;
547 }
548
SetIntegrityCheck(IntegrityCheck checkType)549 void RdbStoreConfig::SetIntegrityCheck(IntegrityCheck checkType)
550 {
551 checkType_ = checkType;
552 }
553
GetIntegrityCheck() const554 IntegrityCheck RdbStoreConfig::GetIntegrityCheck() const
555 {
556 return checkType_;
557 }
558
GetIter() const559 int32_t RdbStoreConfig::GetIter() const
560 {
561 return iter_;
562 }
563
SetIter(int32_t iter) const564 void RdbStoreConfig::SetIter(int32_t iter) const
565 {
566 iter_ = iter;
567 }
568
SetPluginLibs(const std::vector<std::string> & pluginLibs)569 void RdbStoreConfig::SetPluginLibs(const std::vector<std::string> &pluginLibs)
570 {
571 pluginLibs_ = pluginLibs;
572 }
573
GetPluginLibs() const574 std::vector<std::string> RdbStoreConfig::GetPluginLibs() const
575 {
576 return pluginLibs_;
577 }
578
GetHaMode() const579 int32_t RdbStoreConfig::GetHaMode() const
580 {
581 return haMode_;
582 }
583
SetHaMode(int32_t haMode)584 void RdbStoreConfig::SetHaMode(int32_t haMode)
585 {
586 haMode_ = haMode;
587 }
588
EnableRekey(bool enable)589 void RdbStoreConfig::EnableRekey(bool enable)
590 {
591 autoRekey_ = enable;
592 }
Format(const RdbStoreConfig & cacheConfig,const RdbStoreConfig & incomingConfig)593 std::string RdbStoreConfig::Format(const RdbStoreConfig &cacheConfig, const RdbStoreConfig &incomingConfig)
594 {
595 std::stringstream oss;
596 oss << " isEncrypt:" << static_cast<int32_t>(cacheConfig.IsEncrypt()) << "->"
597 << static_cast<int32_t>(incomingConfig.IsEncrypt()) << ",";
598 oss << " securityLevel:" << static_cast<int32_t>(cacheConfig.securityLevel_) << "->"
599 << static_cast<int32_t>(incomingConfig.securityLevel_) << ",";
600 oss << " area:" << cacheConfig.area_ << "->" << incomingConfig.area_ << ",";
601 oss << " storageMode:" << static_cast<int32_t>(cacheConfig.storageMode_) << "->"
602 << static_cast<int32_t>(incomingConfig.storageMode_) << ",";
603 oss << " journalMode:" << cacheConfig.journalMode_ << "->" << incomingConfig.journalMode_ << ",";
604 oss << " syncMode:" << cacheConfig.syncMode_ << "->" << incomingConfig.syncMode_ << ",";
605 oss << " databaseFileType:" << cacheConfig.databaseFileType << "->" << incomingConfig.databaseFileType << ",";
606 oss << " journalSize:" << cacheConfig.journalSize_ << "->" << incomingConfig.journalSize_ << ",";
607 oss << " pageSize:" << cacheConfig.pageSize_ << "->" << incomingConfig.pageSize_ << ",";
608 oss << " customDir:" << cacheConfig.customDir_ << "->" << incomingConfig.customDir_ << ",";
609 oss << " haMode:" << cacheConfig.haMode_ << "->" << incomingConfig.haMode_ << ",";
610 oss << " dbType:" << cacheConfig.dbType_ << "->" << incomingConfig.dbType_ << ",";
611
612 return oss.str();
613 }
614 } // namespace OHOS::NativeRdb
615