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 
16 #include "kv_store_delegate_manager.h"
17 
18 #include <algorithm>
19 #include <cctype>
20 #include <cstdlib>
21 #include <map>
22 #include <thread>
23 
24 #include "auto_launch.h"
25 #include "db_common.h"
26 #include "db_constant.h"
27 #include "db_dfx_adapter.h"
28 #include "kv_store_delegate_impl.h"
29 #include "kv_store_errno.h"
30 #include "kv_store_nb_delegate_impl.h"
31 #include "kvdb_manager.h"
32 #include "kvdb_pragma.h"
33 #include "kvdb_properties.h"
34 #include "log_print.h"
35 #include "network_adapter.h"
36 #include "param_check_utils.h"
37 #include "platform_specific.h"
38 #include "rd_utils.h"
39 #include "runtime_config.h"
40 #include "runtime_context.h"
41 
42 namespace DistributedDB {
43 const std::string KvStoreDelegateManager::DEFAULT_PROCESS_APP_ID = "default";
44 std::mutex KvStoreDelegateManager::communicatorMutex_;
45 std::shared_ptr<IProcessCommunicator> KvStoreDelegateManager::processCommunicator_ = nullptr;
46 std::mutex KvStoreDelegateManager::multiUserMutex_;
47 
48 namespace {
49     const int GET_CONNECT_RETRY = 3;
50     const int RETRY_GET_CONN_INTER = 30;
51 
GetOneConnectionWithRetry(const KvDBProperties & properties,int & errCode)52     IKvDBConnection *GetOneConnectionWithRetry(const KvDBProperties &properties, int &errCode)
53     {
54         for (int i = 0; i < GET_CONNECT_RETRY; i++) {
55             auto conn = KvDBManager::GetDatabaseConnection(properties, errCode);
56             if (conn != nullptr) {
57                 return conn;
58             }
59             if (errCode == -E_STALE) {
60                 std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_GET_CONN_INTER));
61             } else {
62                 return nullptr;
63             }
64         }
65         return nullptr;
66     }
67 
CheckAndGetSchema(bool isMemoryDb,const std::string & schema,SchemaObject & schemaObj)68     DBStatus CheckAndGetSchema(bool isMemoryDb, const std::string &schema, SchemaObject &schemaObj)
69     {
70         if (isMemoryDb && !schema.empty()) {
71             LOGW("[KvStoreDelegateManager] memory database doesn't support the schema.");
72             return NOT_SUPPORT;
73         }
74         if (schema.empty()) {
75             return OK;
76         }
77         schemaObj.ParseFromSchemaString(schema);
78         if (!schemaObj.IsSchemaValid()) {
79             return INVALID_SCHEMA;
80         }
81         return OK;
82     }
83 
InitPropWithNbOption(KvDBProperties & properties,const std::string & storePath,const SchemaObject & schema,const KvStoreNbDelegate::Option & option)84     void InitPropWithNbOption(KvDBProperties &properties,  const std::string &storePath,
85         const SchemaObject &schema, const KvStoreNbDelegate::Option &option)
86     {
87         properties.SetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, option.createIfNecessary);
88         properties.SetIntProp(KvDBProperties::DATABASE_TYPE, option.storageEngineType == GAUSSDB_RD ?
89             KvDBProperties::SINGLE_VER_TYPE_RD_KERNAL : KvDBProperties::SINGLE_VER_TYPE_SQLITE);
90         properties.SetBoolProp(KvDBProperties::MEMORY_MODE, option.isMemoryDb);
91         properties.SetBoolProp(KvDBProperties::ENCRYPTED_MODE, option.isEncryptedDb);
92         if (!option.isMemoryDb) { // memory db ignore store path
93             properties.SetStringProp(KvDBProperties::DATA_DIR, storePath);
94         }
95         properties.SetBoolProp(KvDBProperties::CREATE_DIR_BY_STORE_ID_ONLY, option.createDirByStoreIdOnly);
96         properties.SetSchema(schema);
97         properties.SetBoolProp(KvDBProperties::CHECK_INTEGRITY, option.isNeedIntegrityCheck);
98         properties.SetBoolProp(KvDBProperties::RM_CORRUPTED_DB, option.isNeedRmCorruptedDb);
99         if (RuntimeContext::GetInstance()->IsProcessSystemApiAdapterValid()) {
100             properties.SetIntProp(KvDBProperties::SECURITY_LABEL, option.secOption.securityLabel);
101             properties.SetIntProp(KvDBProperties::SECURITY_FLAG, option.secOption.securityFlag);
102         }
103         properties.SetIntProp(KvDBProperties::CONFLICT_RESOLVE_POLICY, option.conflictResolvePolicy);
104 
105         if (option.isEncryptedDb) {
106             properties.SetPassword(option.cipher, option.passwd);
107         }
108         properties.SetBoolProp(KvDBProperties::COMPRESS_ON_SYNC, option.isNeedCompressOnSync);
109         if (option.isNeedCompressOnSync) {
110             properties.SetIntProp(KvDBProperties::COMPRESSION_RATE,
111                 ParamCheckUtils::GetValidCompressionRate(option.compressionRate));
112         }
113         properties.SetBoolProp(KvDBProperties::SYNC_DUAL_TUPLE_MODE, option.syncDualTupleMode);
114         properties.SetBoolProp(KvDBProperties::LOCAL_ONLY, option.localOnly);
115         properties.SetBoolProp(KvDBProperties::READ_ONLY_MODE, option.rdconfig.readOnly);
116         bool sharedMode = (option.storageEngineType == GAUSSDB_RD);
117         properties.SetBoolProp(KvDBProperties::SHARED_MODE, sharedMode);
118         properties.SetUIntProp(KvDBProperties::PAGE_SIZE, option.rdconfig.pageSize);
119         properties.SetUIntProp(KvDBProperties::CACHE_SIZE, option.rdconfig.cacheSize);
120         properties.SetIntProp(KvDBProperties::INDEX_TYPE, option.rdconfig.type);
121     }
122 
CheckObserverConflictParam(const KvStoreNbDelegate::Option & option)123     bool CheckObserverConflictParam(const KvStoreNbDelegate::Option &option)
124     {
125         if ((option.notifier && !ParamCheckUtils::CheckConflictNotifierType(option.conflictType)) ||
126             (!option.notifier && option.conflictType != 0)) {
127             LOGE("Invalid conflict type, conflict type is [%d]", option.conflictType);
128             return false;
129         }
130         if ((option.observer != nullptr && !ParamCheckUtils::CheckObserver(option.key, option.mode)) ||
131             (option.observer == nullptr && (!option.key.empty() || option.mode != 0))) {
132             LOGE("Invalid observer param, observer mode is [%u]", option.mode);
133             return false;
134         }
135         return true;
136     }
137 
138 #ifndef OMIT_MULTI_VER
InitPropWithOption(KvDBProperties & properties,const std::string & storePath,const KvStoreDelegate::Option & option)139     void InitPropWithOption(KvDBProperties &properties, const std::string &storePath,
140         const KvStoreDelegate::Option &option)
141     {
142         properties.SetBoolProp(KvDBProperties::CREATE_IF_NECESSARY, option.createIfNecessary);
143         properties.SetBoolProp(KvDBProperties::CREATE_DIR_BY_STORE_ID_ONLY, option.createDirByStoreIdOnly);
144         properties.SetIntProp(KvDBProperties::DATABASE_TYPE,
145             ((option.localOnly == true) ? KvDBProperties::LOCAL_TYPE_SQLITE : KvDBProperties::MULTI_VER_TYPE_SQLITE));
146         properties.SetBoolProp(KvDBProperties::MEMORY_MODE, false);
147         properties.SetBoolProp(KvDBProperties::ENCRYPTED_MODE, option.isEncryptedDb);
148         properties.SetStringProp(KvDBProperties::DATA_DIR, storePath);
149         if (option.isEncryptedDb) {
150             properties.SetPassword(option.cipher, option.passwd);
151         }
152     }
153 #endif
154 }
155 
KvStoreDelegateManager(const std::string & appId,const std::string & userId,int32_t instanceId)156 KvStoreDelegateManager::KvStoreDelegateManager(const std::string &appId, const std::string &userId, int32_t instanceId)
157     : appId_(appId),
158       userId_(userId),
159       instanceId_(instanceId)
160 {}
161 
KvStoreDelegateManager(const std::string & appId,const std::string & userId,const std::string & subUser,int32_t instanceId)162 KvStoreDelegateManager::KvStoreDelegateManager(const std::string &appId, const std::string &userId,
163     const std::string &subUser, int32_t instanceId)
164     : appId_(appId),
165       userId_(userId),
166       subUser_(subUser),
167       instanceId_(instanceId)
168 {}
169 
~KvStoreDelegateManager()170 KvStoreDelegateManager::~KvStoreDelegateManager() {}
171 
SetKvStoreConfig(const KvStoreConfig & kvStoreConfig)172 DBStatus KvStoreDelegateManager::SetKvStoreConfig(const KvStoreConfig &kvStoreConfig)
173 {
174     std::string canonicalDir;
175     if (!IsDataDirSafe(kvStoreConfig.dataDir, canonicalDir)) {
176         return INVALID_ARGS;
177     }
178     if (!OS::CheckPathExistence(canonicalDir)) {
179         LOGE("[KvStoreMgr] Data dir doesn't exist or no perm");
180         return INVALID_ARGS;
181     }
182     {
183         std::lock_guard<std::mutex> lock(mutex_);
184         kvStoreConfig_ = kvStoreConfig;
185         kvStoreConfig_.dataDir = canonicalDir;
186     }
187     return OK;
188 }
189 
GetKvStore(const std::string & storeId,const KvStoreDelegate::Option & option,const std::function<void (DBStatus,KvStoreDelegate *)> & callback)190 void KvStoreDelegateManager::GetKvStore(const std::string &storeId, const KvStoreDelegate::Option &option,
191     const std::function<void(DBStatus, KvStoreDelegate *)> &callback)
192 {
193     if (!callback) {
194         LOGE("[KvStoreMgr] Invalid callback for kv store!");
195         return;
196     }
197 #ifndef OMIT_MULTI_VER
198     // Multi version and local database mode not allow the creation of a memory database
199     if (!ParamCheckUtils::CheckStoreParameter(storeId, appId_, userId_, false, subUser_) || GetKvStorePath().empty()) {
200         callback(INVALID_ARGS, nullptr);
201         return;
202     }
203 
204     if (option.isEncryptedDb) {
205         if (!ParamCheckUtils::CheckEncryptedParameter(option.cipher, option.passwd)) {
206             callback(INVALID_ARGS, nullptr);
207             return;
208         }
209     }
210 
211     KvDBProperties properties;
212     InitPropWithOption(properties, GetKvStorePath(), option);
213     DbIdParam dbIdParam = { appId_, userId_, storeId };
214     DBCommon::SetDatabaseIds(properties, dbIdParam);
215 
216     int errCode;
217     IKvDBConnection *conn = GetOneConnectionWithRetry(properties, errCode);
218     if (conn == nullptr) {
219         DBStatus status = TransferDBErrno(errCode);
220         callback(status, nullptr);
221         return;
222     }
223 
224     auto kvStore = new (std::nothrow) KvStoreDelegateImpl(conn, storeId);
225     if (kvStore == nullptr) {
226         LOGE("[KvStoreMgr] Failed to alloc the delegate");
227         conn->Close();
228         conn = nullptr;
229         callback(DB_ERROR, nullptr);
230         return;
231     }
232     callback(OK, kvStore);
233 #else
234     callback(NOT_SUPPORT, nullptr);
235     return;
236 #endif
237 }
238 
SetObserverNotifier(KvStoreNbDelegate * kvStore,const KvStoreNbDelegate::Option & option)239 DBStatus KvStoreDelegateManager::SetObserverNotifier(KvStoreNbDelegate *kvStore,
240     const KvStoreNbDelegate::Option &option)
241 {
242     DBStatus status;
243     if (option.observer != nullptr) {
244         status = kvStore->RegisterObserver(option.key, option.mode, option.observer);
245         if (status != OK) {
246             LOGE("[KvStoreMgr] RegisterObserver failed.");
247             return status;
248         }
249     }
250     if (option.notifier != nullptr) {
251         status = kvStore->SetConflictNotifier(option.conflictType, option.notifier);
252         if (status != OK) {
253             LOGE("[KvStoreMgr] SetConflictNotifier failed.");
254             return status;
255         }
256     }
257     return OK;
258 }
259 
GetKvStoreParamCheck(const std::string & storeId,const KvStoreNbDelegate::Option & option,const std::function<void (DBStatus,KvStoreNbDelegate *)> & callback) const260 bool KvStoreDelegateManager::GetKvStoreParamCheck(const std::string &storeId, const KvStoreNbDelegate::Option &option,
261     const std::function<void(DBStatus, KvStoreNbDelegate *)> &callback) const
262 {
263     if (!callback) {
264         LOGE("[KvStoreMgr] Invalid callback for kv store");
265         return false;
266     }
267     if (!CheckParaOption(option, callback)) {
268         LOGE("[KvStoreMgr] Unsupport option for RD mode");
269         return false;
270     }
271     if (!ParamCheckUtils::CheckStoreParameter(storeId, appId_, userId_, false, subUser_) ||
272         (GetKvStorePath().empty() && !option.isMemoryDb)) {
273         LOGE("[KvStoreMgr] Invalid id or path info for the store");
274         callback(INVALID_ARGS, nullptr);
275         return false;
276     }
277 
278     // check if want an encrypted db
279     if (option.isEncryptedDb) {
280         if (option.isMemoryDb) {
281             LOGE("Memory db not support encrypt!");
282             callback(NOT_SUPPORT, nullptr);
283             return false;
284         }
285         if (!ParamCheckUtils::CheckEncryptedParameter(option.cipher, option.passwd)) {
286             callback(INVALID_ARGS, nullptr);
287             return false;
288         }
289     }
290     // check secOption
291     if (!option.isMemoryDb) {
292         if (!ParamCheckUtils::CheckSecOption(option.secOption)) {
293             callback(INVALID_ARGS, nullptr);
294             return false;
295         }
296     } else {
297         if (option.secOption.securityLabel != SecurityLabel::NOT_SET ||
298             option.secOption.securityFlag != 0) {
299             LOGE("Memory db has no physical files, Is not controlled by security labels, so not support set labels");
300             callback(INVALID_ARGS, nullptr);
301             return false;
302         }
303     }
304 
305     if (!CheckObserverConflictParam(option)) {
306         callback(INVALID_ARGS, nullptr);
307         return false;
308     }
309     return true;
310 }
311 
GetKvStore(const std::string & storeId,const KvStoreNbDelegate::Option & option,const std::function<void (DBStatus,KvStoreNbDelegate *)> & callback)312 void KvStoreDelegateManager::GetKvStore(const std::string &storeId, const KvStoreNbDelegate::Option &option,
313     const std::function<void(DBStatus, KvStoreNbDelegate *)> &callback)
314 {
315     if (!GetKvStoreParamCheck(storeId, option, callback)) {
316         return;
317     }
318     auto tmpOption = option;
319     if (tmpOption.storageEngineType == std::string(GAUSSDB_RD)) {
320         DBCommon::LoadGrdLib();
321         if (!DBCommon::IsGrdLibLoaded()) {
322             tmpOption.storageEngineType = std::string(SQLITE);
323         }
324     }
325     // check if schema is supported and valid
326     SchemaObject schema;
327     DBStatus retCode = CheckAndGetSchema(tmpOption.isMemoryDb, tmpOption.schema, schema);
328     if (retCode != OK) {
329         callback(retCode, nullptr);
330         return;
331     }
332     KvDBProperties properties;
333     InitPropWithNbOption(properties, GetKvStorePath(), schema, tmpOption);
334     DbIdParam dbIdParam = { appId_, userId_, storeId, subUser_, instanceId_ };
335     DBCommon::SetDatabaseIds(properties, dbIdParam);
336 
337     int errCode;
338     IKvDBConnection *conn = GetOneConnectionWithRetry(properties, errCode);
339     DBStatus status = TransferDBErrno(errCode);
340     if (conn == nullptr) {
341         callback(status, nullptr);
342         return;
343     }
344 
345     auto kvStore = new (std::nothrow) KvStoreNbDelegateImpl(conn, storeId);
346     if (kvStore == nullptr) {
347         conn->Close();
348         conn = nullptr;
349         callback(DB_ERROR, nullptr);
350         return;
351     }
352 
353     status = SetObserverNotifier(kvStore, tmpOption);
354     if (status != OK) {
355         CloseKvStore(kvStore);
356         callback(status, nullptr);
357         return;
358     }
359 
360     bool enAutoSync = false;
361     (void)conn->Pragma(PRAGMA_AUTO_SYNC, static_cast<void *>(&enAutoSync));
362 
363     SecurityOption secOption = tmpOption.secOption;
364     (void)conn->Pragma(PRAGMA_TRIGGER_TO_MIGRATE_DATA, &secOption);
365 
366     callback(OK, kvStore);
367 }
368 
CloseKvStore(KvStoreDelegate * kvStore)369 DBStatus KvStoreDelegateManager::CloseKvStore(KvStoreDelegate *kvStore)
370 {
371 #ifndef OMIT_MULTI_VER
372     if (kvStore == nullptr) {
373         return INVALID_ARGS;
374     }
375 
376     auto kvStoreImpl = static_cast<KvStoreDelegateImpl *>(kvStore);
377     DBStatus status = kvStoreImpl->Close();
378     if (status == BUSY) {
379         LOGD("DelegateImpl is busy now.");
380         return BUSY;
381     }
382 
383     kvStoreImpl->SetReleaseFlag(true);
384     delete kvStore;
385     kvStore = nullptr;
386     return OK;
387 #else
388     return NOT_SUPPORT;
389 #endif
390 }
391 
CloseKvStore(KvStoreNbDelegate * kvStore)392 DBStatus KvStoreDelegateManager::CloseKvStore(KvStoreNbDelegate *kvStore)
393 {
394     if (kvStore == nullptr) {
395         return INVALID_ARGS;
396     }
397 
398     auto kvStoreImpl = static_cast<KvStoreNbDelegateImpl *>(kvStore);
399     DBStatus status = kvStoreImpl->Close();
400     if (status == BUSY) {
401         LOGD("NbDelegateImpl is busy now.");
402         return BUSY;
403     }
404     kvStoreImpl->SetReleaseFlag(true);
405     delete kvStore;
406     kvStore = nullptr;
407     return OK;
408 }
409 
DeleteKvStore(const std::string & storeId)410 DBStatus KvStoreDelegateManager::DeleteKvStore(const std::string &storeId)
411 {
412     if (!ParamCheckUtils::IsStoreIdSafe(storeId) || GetKvStorePath().empty()) {
413         LOGE("Invalid store info for deleting");
414         return INVALID_ARGS;
415     }
416 
417     KvDBProperties properties;
418     properties.SetStringProp(KvDBProperties::DATA_DIR, GetKvStorePath());
419     DbIdParam dbIdParam = { appId_, userId_, storeId, subUser_ };
420     DBCommon::SetDatabaseIds(properties, dbIdParam);
421     int errCode = KvDBManager::RemoveDatabase(properties);
422     if (errCode == E_OK) {
423         LOGI("Database deleted successfully!");
424         DBInfo dbInfo;
425         dbInfo.userId = userId_;
426         dbInfo.appId = appId_;
427         dbInfo.storeId = storeId;
428         RuntimeContext::GetInstance()->RemoveRemoteSubscribe(dbInfo);
429         return OK;
430     }
431     LOGE("Delete the kv store error:%d", errCode);
432     return TransferDBErrno(errCode);
433 }
434 
SetProcessLabel(const std::string & appId,const std::string & userId)435 DBStatus KvStoreDelegateManager::SetProcessLabel(const std::string &appId, const std::string &userId)
436 {
437     if (appId.size() > DBConstant::MAX_APP_ID_LENGTH || appId.empty() ||
438         userId.size() > DBConstant::MAX_USER_ID_LENGTH || userId.empty()) {
439         LOGE("Invalid app or user info[%zu]-[%zu]", appId.length(), userId.length());
440         return INVALID_ARGS;
441     }
442 
443     int errCode = KvDBManager::SetProcessLabel(appId, userId);
444     if (errCode != E_OK) {
445         LOGE("Failed to set the process label:%d", errCode);
446         return DB_ERROR;
447     }
448     return OK;
449 }
450 
SetProcessCommunicator(const std::shared_ptr<IProcessCommunicator> & inCommunicator)451 DBStatus KvStoreDelegateManager::SetProcessCommunicator(const std::shared_ptr<IProcessCommunicator> &inCommunicator)
452 {
453     std::lock_guard<std::mutex> lock(communicatorMutex_);
454     if (processCommunicator_ != nullptr) {
455         LOGE("processCommunicator_ is not null!");
456         return DB_ERROR;
457     }
458 
459     std::string processLabel = RuntimeContext::GetInstance()->GetProcessLabel();
460     if (processLabel.empty()) {
461         LOGE("ProcessLabel is not set!");
462         return DB_ERROR;
463     }
464 
465     NetworkAdapter *adapter = new (std::nothrow) NetworkAdapter(processLabel, inCommunicator);
466     if (adapter == nullptr) {
467         LOGE("New NetworkAdapter failed!");
468         return DB_ERROR;
469     }
470     processCommunicator_ = inCommunicator;
471     if (RuntimeContext::GetInstance()->SetCommunicatorAdapter(adapter) != E_OK) {
472         LOGE("SetProcessCommunicator not support!");
473         delete adapter;
474         return DB_ERROR;
475     }
476     KvDBManager::RestoreSyncableKvStore();
477     return OK;
478 }
479 
GetKvStoreDiskSize(const std::string & storeId,uint64_t & size)480 DBStatus KvStoreDelegateManager::GetKvStoreDiskSize(const std::string &storeId, uint64_t &size)
481 {
482     std::string dataDir = GetKvStorePath();
483     if (!ParamCheckUtils::CheckStoreParameter(storeId, appId_, userId_)) {
484         LOGE("[KvStoreMgr] Invalid store info for size");
485         return INVALID_ARGS;
486     }
487     KvDBProperties properties;
488     properties.SetStringProp(KvDBProperties::DATA_DIR, dataDir);
489     DbIdParam dbIdParam = { appId_, userId_, storeId, subUser_ };
490     DBCommon::SetDatabaseIds(properties, dbIdParam);
491     int errCode = KvDBManager::CalculateKvStoreSize(properties, size);
492     if (errCode != E_OK) {
493         if (errCode == -E_NOT_FOUND) {
494             return NOT_FOUND;
495         }
496 
497         LOGE("[KvStoreMgr] Get the file size failed[%d]", errCode);
498         return DB_ERROR;
499     }
500     return OK;
501 }
502 
SetKvStoreCorruptionHandler(const KvStoreCorruptionHandler & handler)503 void KvStoreDelegateManager::SetKvStoreCorruptionHandler(const KvStoreCorruptionHandler &handler)
504 {
505     KvDBManager::SetDatabaseCorruptionHandler(handler);
506 }
507 
GetDatabaseDir(const std::string & storeId,const std::string & appId,const std::string & userId,std::string & directory)508 DBStatus KvStoreDelegateManager::GetDatabaseDir(const std::string &storeId, const std::string &appId,
509     const std::string &userId, std::string &directory)
510 {
511     if (!ParamCheckUtils::CheckStoreParameter(storeId, appId, userId)) {
512         return INVALID_ARGS;
513     }
514 
515     std::string identifier = DBCommon::GenerateIdentifierId(storeId, appId, userId);
516     std::string dir = DBCommon::TransferHashString(identifier);
517     if (dir.empty()) {
518         return DB_ERROR;
519     }
520     directory = DBCommon::TransferStringToHex(dir);
521     return OK;
522 }
523 
GetDatabaseDir(const std::string & storeId,std::string & directory)524 DBStatus KvStoreDelegateManager::GetDatabaseDir(const std::string &storeId, std::string &directory)
525 {
526     if (!ParamCheckUtils::IsStoreIdSafe(storeId)) {
527         return INVALID_ARGS;
528     }
529 
530     if (storeId.find(DBConstant::ID_CONNECTOR) != std::string::npos) {
531         return INVALID_ARGS;
532     }
533 
534     std::string dir = DBCommon::TransferHashString(storeId);
535     if (dir.empty()) {
536         return DB_ERROR;
537     }
538     directory = DBCommon::TransferStringToHex(dir);
539     return OK;
540 }
541 
542 // private
IsDataDirSafe(const std::string & dataDir,std::string & canonicalDir) const543 bool KvStoreDelegateManager::IsDataDirSafe(const std::string &dataDir, std::string &canonicalDir) const
544 {
545     return ParamCheckUtils::CheckDataDir(dataDir, canonicalDir);
546 }
547 
GetKvStorePath() const548 const std::string &KvStoreDelegateManager::GetKvStorePath() const
549 {
550     std::lock_guard<std::mutex> lock(mutex_);
551     return kvStoreConfig_.dataDir;
552 }
553 
SetPermissionCheckCallback(const PermissionCheckCallback & callback)554 DBStatus KvStoreDelegateManager::SetPermissionCheckCallback(const PermissionCheckCallback &callback)
555 {
556     int errCode = RuntimeContext::GetInstance()->SetPermissionCheckCallback(callback);
557     return TransferDBErrno(errCode);
558 }
559 
SetPermissionCheckCallback(const PermissionCheckCallbackV2 & callback)560 DBStatus KvStoreDelegateManager::SetPermissionCheckCallback(const PermissionCheckCallbackV2 &callback)
561 {
562     int errCode = RuntimeContext::GetInstance()->SetPermissionCheckCallback(callback);
563     return TransferDBErrno(errCode);
564 }
565 
EnableKvStoreAutoLaunch(const std::string & userId,const std::string & appId,const std::string & storeId,const AutoLaunchOption & option,const AutoLaunchNotifier & notifier)566 DBStatus KvStoreDelegateManager::EnableKvStoreAutoLaunch(const std::string &userId, const std::string &appId,
567     const std::string &storeId, const AutoLaunchOption &option, const AutoLaunchNotifier &notifier)
568 {
569     if (RuntimeContext::GetInstance() == nullptr) {
570         return DB_ERROR;
571     }
572     AutoLaunchParam param{ userId, appId, storeId, option, notifier, {} };
573     std::shared_ptr<DBProperties> ptr;
574     int errCode = AutoLaunch::GetAutoLaunchProperties(param, DBTypeInner::DB_KV, true, ptr);
575     if (errCode != E_OK) {
576         LOGE("[KvStoreManager] Enable auto launch, get properties failed:%d", errCode);
577         return TransferDBErrno(errCode);
578     }
579 
580     std::shared_ptr<KvDBProperties> kvPtr = std::static_pointer_cast<KvDBProperties>(ptr);
581     errCode = RuntimeContext::GetInstance()->EnableKvStoreAutoLaunch(*kvPtr, notifier, option);
582     if (errCode != E_OK) {
583         LOGE("[KvStoreManager] Enable auto launch failed:%d", errCode);
584         return TransferDBErrno(errCode, true);
585     }
586     LOGI("[KvStoreManager] Enable auto launch");
587     return OK;
588 }
589 
DisableKvStoreAutoLaunch(const std::string & userId,const std::string & appId,const std::string & storeId)590 DBStatus KvStoreDelegateManager::DisableKvStoreAutoLaunch(const std::string &userId, const std::string &appId,
591     const std::string &storeId)
592 {
593     if (RuntimeContext::GetInstance() == nullptr) {
594         return DB_ERROR;
595     }
596 
597     std::string syncIdentifier = DBCommon::GenerateIdentifierId(storeId, appId, userId, "", 0);
598     std::string hashIdentifier = DBCommon::TransferHashString(syncIdentifier);
599     std::string dualIdentifier = DBCommon::TransferHashString(DBCommon::GenerateDualTupleIdentifierId(storeId, appId));
600     int errCode = RuntimeContext::GetInstance()->DisableKvStoreAutoLaunch(hashIdentifier, dualIdentifier, userId);
601     if (errCode != E_OK) {
602         LOGE("[KvStoreManager] Disable auto launch failed:%d", errCode);
603         return TransferDBErrno(errCode);
604     }
605     LOGI("[KvStoreManager] Disable auto launch");
606     return OK;
607 }
608 
SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback & callback)609 void KvStoreDelegateManager::SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &callback)
610 {
611     RuntimeContext::GetInstance()->SetAutoLaunchRequestCallback(callback, DBTypeInner::DB_KV);
612 }
613 
GetKvStoreIdentifier(const std::string & userId,const std::string & appId,const std::string & storeId,bool syncDualTupleMode)614 std::string KvStoreDelegateManager::GetKvStoreIdentifier(const std::string &userId, const std::string &appId,
615     const std::string &storeId, bool syncDualTupleMode)
616 {
617     return RuntimeConfig::GetStoreIdentifier(userId, appId, storeId, syncDualTupleMode);
618 }
619 
SetProcessSystemAPIAdapter(const std::shared_ptr<IProcessSystemApiAdapter> & adapter)620 DBStatus KvStoreDelegateManager::SetProcessSystemAPIAdapter(const std::shared_ptr<IProcessSystemApiAdapter> &adapter)
621 {
622     return TransferDBErrno(RuntimeContext::GetInstance()->SetProcessSystemApiAdapter(adapter));
623 }
624 
SetStoreStatusNotifier(const StoreStatusNotifier & notifier)625 void KvStoreDelegateManager::SetStoreStatusNotifier(const StoreStatusNotifier &notifier)
626 {
627     RuntimeContext::GetInstance()->SetStoreStatusNotifier(notifier);
628 }
629 
SetSyncActivationCheckCallback(const SyncActivationCheckCallback & callback)630 DBStatus KvStoreDelegateManager::SetSyncActivationCheckCallback(const SyncActivationCheckCallback &callback)
631 {
632     std::lock_guard<std::mutex> lock(multiUserMutex_);
633     int errCode = RuntimeContext::GetInstance()->SetSyncActivationCheckCallback(callback);
634     return TransferDBErrno(errCode);
635 }
636 
NotifyUserChanged()637 DBStatus KvStoreDelegateManager::NotifyUserChanged()
638 {
639     std::lock_guard<std::mutex> lock(multiUserMutex_);
640     int errCode = RuntimeContext::GetInstance()->NotifyUserChanged();
641     return TransferDBErrno(errCode);
642 }
643 
IsProcessSystemApiAdapterValid()644 bool KvStoreDelegateManager::IsProcessSystemApiAdapterValid()
645 {
646     return RuntimeContext::GetInstance()->IsProcessSystemApiAdapterValid();
647 }
648 } // namespace DistributedDB
649