• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef RELATIONAL_STORE
16 #include "relational_store_manager.h"
17 
18 #include <thread>
19 
20 #include "auto_launch.h"
21 #include "relational_store_instance.h"
22 #include "db_common.h"
23 #include "db_dfx_adapter.h"
24 #include "param_check_utils.h"
25 #include "log_print.h"
26 #include "db_errno.h"
27 #include "kv_store_errno.h"
28 #include "relational_store_changed_data_impl.h"
29 #include "relational_store_delegate_impl.h"
30 #include "runtime_context.h"
31 #include "platform_specific.h"
32 
33 namespace DistributedDB {
34 namespace {
35 const int GET_CONNECT_RETRY = 3;
36 const int RETRY_GET_CONN_INTER = 30;
37 }
38 
RelationalStoreManager(const std::string & appId,const std::string & userId,int32_t instanceId)39 RelationalStoreManager::RelationalStoreManager(const std::string &appId, const std::string &userId, int32_t instanceId)
40     : appId_(appId),
41       userId_(userId),
42       instanceId_(instanceId)
43 {}
44 
GetOneConnectionWithRetry(const RelationalDBProperties & properties,int & errCode)45 static RelationalStoreConnection *GetOneConnectionWithRetry(const RelationalDBProperties &properties, int &errCode)
46 {
47     for (int i = 0; i < GET_CONNECT_RETRY; i++) {
48         auto conn = RelationalStoreInstance::GetDatabaseConnection(properties, errCode);
49         if (conn != nullptr) {
50             return conn;
51         }
52         if (errCode == -E_STALE) {
53             std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_GET_CONN_INTER));
54         } else {
55             return nullptr;
56         }
57     }
58     return nullptr;
59 }
60 
OpenStore(const std::string & path,const std::string & storeId,const RelationalStoreDelegate::Option & option,RelationalStoreDelegate * & delegate)61 DB_API DBStatus RelationalStoreManager::OpenStore(const std::string &path, const std::string &storeId,
62     const RelationalStoreDelegate::Option &option, RelationalStoreDelegate *&delegate)
63 {
64     if (delegate != nullptr) {
65         LOGE("[RelationalStoreMgr] Invalid delegate!");
66         return INVALID_ARGS;
67     }
68 
69     std::string canonicalDir;
70     if (!ParamCheckUtils::CheckDataDir(path, canonicalDir)) {
71         return INVALID_ARGS;
72     }
73 
74     if (!ParamCheckUtils::CheckStoreParameter(storeId, appId_, userId_) || path.empty()) {
75         return INVALID_ARGS;
76     }
77 
78     RelationalDBProperties properties;
79     properties.SetStringProp(RelationalDBProperties::DATA_DIR, canonicalDir);
80     properties.SetIdentifier(userId_, appId_, storeId, instanceId_);
81     properties.SetBoolProp(RelationalDBProperties::SYNC_DUAL_TUPLE_MODE, option.syncDualTupleMode);
82     if (option.isEncryptedDb) {
83         if (!ParamCheckUtils::CheckEncryptedParameter(option.cipher, option.passwd) || option.iterateTimes == 0) {
84             return INVALID_ARGS;
85         }
86         properties.SetCipherArgs(option.cipher, option.passwd, option.iterateTimes);
87     }
88 
89     int errCode = E_OK;
90     auto *conn = GetOneConnectionWithRetry(properties, errCode);
91     if (errCode == -E_INVALID_PASSWD_OR_CORRUPTED_DB) {
92         DBDfxAdapter::ReportFault( { DBDfxAdapter::EVENT_OPEN_DATABASE_FAILED, userId_, appId_, storeId, errCode } );
93     }
94     if (conn == nullptr) {
95         return TransferDBErrno(errCode);
96     }
97 
98     delegate = new (std::nothrow) RelationalStoreDelegateImpl(conn, path);
99     if (delegate == nullptr) {
100         conn->Close();
101         return DB_ERROR;
102     }
103     conn->RegisterObserverAction([option, storeId, this](const std::string &changedDevice) {
104         RelationalStoreChangedDataImpl data(changedDevice);
105         data.SetStoreProperty({userId_, appId_, storeId});
106         if (option.observer) {
107             LOGD("begin to observer on changed, changedDevice=%s", STR_MASK(changedDevice));
108             option.observer->OnChange(data);
109         }
110     });
111     return OK;
112 }
113 
CloseStore(RelationalStoreDelegate * store)114 DBStatus RelationalStoreManager::CloseStore(RelationalStoreDelegate *store)
115 {
116     if (store == nullptr) {
117         return INVALID_ARGS;
118     }
119 
120     auto storeImpl = static_cast<RelationalStoreDelegateImpl *>(store);
121     DBStatus status = storeImpl->Close();
122     if (status == BUSY) {
123         LOGD("NbDelegateImpl is busy now.");
124         return BUSY;
125     }
126     storeImpl->SetReleaseFlag(true);
127     delete store;
128     store = nullptr;
129     return OK;
130 }
131 
GetDistributedTableName(const std::string & device,const std::string & tableName)132 std::string RelationalStoreManager::GetDistributedTableName(const std::string &device, const std::string &tableName)
133 {
134     if ((!RuntimeContext::GetInstance()->ExistTranslateDevIdCallback() && device.empty()) || tableName.empty()) {
135         return {};
136     }
137     return DBCommon::GetDistributedTableName(device, tableName);
138 }
139 
SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback & callback)140 void RelationalStoreManager::SetAutoLaunchRequestCallback(const AutoLaunchRequestCallback &callback)
141 {
142     RuntimeContext::GetInstance()->SetAutoLaunchRequestCallback(callback, DBType::DB_RELATION);
143 }
144 
GetRelationalStoreIdentifier(const std::string & userId,const std::string & appId,const std::string & storeId,bool syncDualTupleMode)145 std::string RelationalStoreManager::GetRelationalStoreIdentifier(const std::string &userId, const std::string &appId,
146     const std::string &storeId, bool syncDualTupleMode)
147 {
148     if (!ParamCheckUtils::CheckStoreParameter(storeId, appId, userId, syncDualTupleMode)) {
149         return "";
150     }
151     if (syncDualTupleMode) {
152         return DBCommon::TransferHashString(appId + "-" + storeId);
153     }
154     return DBCommon::TransferHashString(DBCommon::GenerateIdentifierId(storeId, appId, userId));
155 }
156 } // namespace DistributedDB
157 #endif