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_delegate_impl.h"
17
18 #include "cloud/cloud_db_constant.h"
19 #include "db_common.h"
20 #include "db_errno.h"
21 #include "cloud/cloud_db_constant.h"
22 #include "kv_store_errno.h"
23 #include "log_print.h"
24 #include "param_check_utils.h"
25 #include "relational_store_changed_data_impl.h"
26 #include "relational_store_instance.h"
27 #include "sync_operation.h"
28
29 namespace DistributedDB {
RelationalStoreDelegateImpl(RelationalStoreConnection * conn,const std::string & path)30 RelationalStoreDelegateImpl::RelationalStoreDelegateImpl(RelationalStoreConnection *conn, const std::string &path)
31 : conn_(conn),
32 storePath_(path)
33 {}
34
~RelationalStoreDelegateImpl()35 RelationalStoreDelegateImpl::~RelationalStoreDelegateImpl()
36 {
37 if (!releaseFlag_) {
38 LOGF("[RelationalStore Delegate] Can't release directly");
39 return;
40 }
41
42 conn_ = nullptr;
43 }
44
RemoveDeviceDataInner(const std::string & device,ClearMode mode)45 DBStatus RelationalStoreDelegateImpl::RemoveDeviceDataInner(const std::string &device, ClearMode mode)
46 {
47 if (mode >= BUTT || mode < 0) {
48 LOGE("Invalid mode for Remove device data, %d.", INVALID_ARGS);
49 return INVALID_ARGS;
50 }
51 if (mode == FLAG_ONLY || mode == FLAG_AND_DATA) {
52 if (conn_ == nullptr) {
53 LOGE("[RelationalStore Delegate] Invalid connection for operation!");
54 return DB_ERROR;
55 }
56
57 int errCode = conn_->DoClean(mode);
58 if (errCode != E_OK) {
59 LOGE("[RelationalStore Delegate] remove device cloud data failed:%d", errCode);
60 return TransferDBErrno(errCode);
61 }
62 return OK;
63 }
64 return RemoveDeviceData(device, "");
65 }
66
GetCloudSyncTaskCount()67 int32_t RelationalStoreDelegateImpl::GetCloudSyncTaskCount()
68 {
69 if (conn_ == nullptr) {
70 LOGE("[RelationalStore Delegate] Invalid connection for operation!");
71 return -1;
72 }
73 int32_t count = conn_->GetCloudSyncTaskCount();
74 if (count == -1) {
75 LOGE("[RelationalStore Delegate] Failed to get cloud sync task count.");
76 }
77 return count;
78 }
79
CreateDistributedTableInner(const std::string & tableName,TableSyncType type)80 DBStatus RelationalStoreDelegateImpl::CreateDistributedTableInner(const std::string &tableName, TableSyncType type)
81 {
82 if (!ParamCheckUtils::CheckRelationalTableName(tableName)) {
83 LOGE("[RelationalStore Delegate] Invalid table name.");
84 return INVALID_ARGS;
85 }
86
87 if (!(type == DEVICE_COOPERATION || type == CLOUD_COOPERATION)) {
88 LOGE("[RelationalStore Delegate] Invalid table sync type.");
89 return INVALID_ARGS;
90 }
91
92 if (conn_ == nullptr) {
93 LOGE("[RelationalStore Delegate] Invalid connection for operation!");
94 return DB_ERROR;
95 }
96
97 int errCode = conn_->CreateDistributedTable(tableName, type);
98 if (errCode != E_OK) {
99 LOGE("[RelationalStore Delegate] Create Distributed table failed:%d", errCode);
100 return TransferDBErrno(errCode);
101 }
102 return OK;
103 }
104
Sync(const std::vector<std::string> & devices,SyncMode mode,const Query & query,const SyncStatusCallback & onComplete,bool wait)105 DBStatus RelationalStoreDelegateImpl::Sync(const std::vector<std::string> &devices, SyncMode mode,
106 const Query &query, const SyncStatusCallback &onComplete, bool wait)
107 {
108 if (conn_ == nullptr) {
109 LOGE("Invalid connection for operation!");
110 return DB_ERROR;
111 }
112
113 if (mode > SYNC_MODE_PUSH_PULL) {
114 LOGE("not support other mode");
115 return NOT_SUPPORT;
116 }
117
118 RelationalStoreConnection::SyncInfo syncInfo{devices, mode,
119 std::bind(&RelationalStoreDelegateImpl::OnSyncComplete, std::placeholders::_1, onComplete), query, wait};
120 int errCode = conn_->SyncToDevice(syncInfo);
121 if (errCode != E_OK) {
122 LOGW("[RelationalStore Delegate] sync data to device failed:%d", errCode);
123 return TransferDBErrno(errCode);
124 }
125 return OK;
126 }
127
RemoveDeviceData(const std::string & device,const std::string & tableName)128 DBStatus RelationalStoreDelegateImpl::RemoveDeviceData(const std::string &device, const std::string &tableName)
129 {
130 if (conn_ == nullptr) {
131 LOGE("Invalid connection for operation!");
132 return DB_ERROR;
133 }
134
135 if (device.empty() || device.length() > DBConstant::MAX_DEV_LENGTH ||
136 !ParamCheckUtils::CheckRelationalTableName(tableName)) {
137 LOGE("[RelationalStore Delegate] Remove device data with invalid device name or table name.");
138 return INVALID_ARGS;
139 }
140
141 int errCode = conn_->RemoveDeviceData(device, tableName);
142 if (errCode != E_OK) {
143 LOGW("[RelationalStore Delegate] remove device data failed:%d", errCode);
144 return TransferDBErrno(errCode);
145 }
146 return OK;
147 }
148
Close()149 DBStatus RelationalStoreDelegateImpl::Close()
150 {
151 if (conn_ == nullptr) {
152 return OK;
153 }
154
155 int errCode = RelationalStoreInstance::ReleaseDataBaseConnection(conn_);
156 if (errCode == -E_BUSY) {
157 LOGW("[RelationalStore Delegate] busy for close");
158 return BUSY;
159 }
160 if (errCode != E_OK) {
161 LOGE("Release db connection error:%d", errCode);
162 return TransferDBErrno(errCode);
163 }
164
165 LOGI("[RelationalStore Delegate] Close");
166 conn_ = nullptr;
167 return OK;
168 }
169
SetReleaseFlag(bool flag)170 void RelationalStoreDelegateImpl::SetReleaseFlag(bool flag)
171 {
172 releaseFlag_ = flag;
173 }
174
OnSyncComplete(const std::map<std::string,std::vector<TableStatus>> & devicesStatus,const SyncStatusCallback & onComplete)175 void RelationalStoreDelegateImpl::OnSyncComplete(const std::map<std::string, std::vector<TableStatus>> &devicesStatus,
176 const SyncStatusCallback &onComplete)
177 {
178 std::map<std::string, std::vector<TableStatus>> res;
179 for (const auto &[device, tablesStatus] : devicesStatus) {
180 for (const auto &tableStatus : tablesStatus) {
181 TableStatus table;
182 table.tableName = tableStatus.tableName;
183 table.status = SyncOperation::DBStatusTrans(tableStatus.status);
184 res[device].push_back(table);
185 }
186 }
187 if (onComplete) {
188 onComplete(res);
189 }
190 }
191
RemoteQuery(const std::string & device,const RemoteCondition & condition,uint64_t timeout,std::shared_ptr<ResultSet> & result)192 DBStatus RelationalStoreDelegateImpl::RemoteQuery(const std::string &device, const RemoteCondition &condition,
193 uint64_t timeout, std::shared_ptr<ResultSet> &result)
194 {
195 if (conn_ == nullptr) {
196 LOGE("Invalid connection for operation!");
197 return DB_ERROR;
198 }
199 int errCode = conn_->RemoteQuery(device, condition, timeout, result);
200 if (errCode != E_OK) {
201 LOGW("[RelationalStore Delegate] remote query failed:%d", errCode);
202 result = nullptr;
203 return TransferDBErrno(errCode);
204 }
205 return OK;
206 }
207
RemoveDeviceData()208 DBStatus RelationalStoreDelegateImpl::RemoveDeviceData()
209 {
210 if (conn_ == nullptr) {
211 LOGE("Invalid connection for operation!");
212 return DB_ERROR;
213 }
214
215 int errCode = conn_->RemoveDeviceData();
216 if (errCode != E_OK) {
217 LOGW("[RelationalStore Delegate] remove device data failed:%d", errCode);
218 return TransferDBErrno(errCode);
219 }
220 return OK;
221 }
222
Sync(const std::vector<std::string> & devices,SyncMode mode,const Query & query,const SyncProcessCallback & onProcess,int64_t waitTime)223 DBStatus RelationalStoreDelegateImpl::Sync(const std::vector<std::string> &devices, SyncMode mode, const Query &query,
224 const SyncProcessCallback &onProcess, int64_t waitTime)
225 {
226 if (conn_ == nullptr) {
227 return DB_ERROR;
228 }
229 int errCode = conn_->Sync(devices, mode, query, onProcess, waitTime);
230 if (errCode != E_OK) {
231 LOGW("[RelationalStore Delegate] cloud sync failed:%d", errCode);
232 return TransferDBErrno(errCode);
233 }
234 return OK;
235 }
236
SetCloudDB(const std::shared_ptr<ICloudDb> & cloudDb)237 DBStatus RelationalStoreDelegateImpl::SetCloudDB(const std::shared_ptr<ICloudDb> &cloudDb)
238 {
239 if (conn_ == nullptr || conn_->SetCloudDB(cloudDb) != E_OK) {
240 return DB_ERROR;
241 }
242 return OK;
243 }
244
SetCloudDbSchema(const DataBaseSchema & schema)245 DBStatus RelationalStoreDelegateImpl::SetCloudDbSchema(const DataBaseSchema &schema)
246 {
247 if (conn_ == nullptr || conn_->SetCloudDbSchema(schema) != E_OK) {
248 return DB_ERROR;
249 }
250 return OK;
251 }
252
RegisterObserver(StoreObserver * observer)253 DBStatus RelationalStoreDelegateImpl::RegisterObserver(StoreObserver *observer)
254 {
255 if (conn_ == nullptr) {
256 return DB_ERROR;
257 }
258 std::string userId;
259 std::string appId;
260 std::string storeId;
261 int errCode = conn_->GetStoreInfo(userId, appId, storeId);
262 if (errCode != E_OK) {
263 return DB_ERROR;
264 }
265 conn_->RegisterObserverAction([observer, userId, appId, storeId](const std::string &changedDevice,
266 ChangedData &&changedData, bool isChangedData) {
267 if (isChangedData && observer != nullptr) {
268 observer->OnChange(Origin::ORIGIN_CLOUD, changedDevice, std::move(changedData));
269 LOGD("begin to observer on changed data");
270 return;
271 }
272 RelationalStoreChangedDataImpl data(changedDevice);
273 data.SetStoreProperty({userId, appId, storeId});
274 if (observer != nullptr) {
275 LOGD("begin to observer on changed, changedDevice=%s", STR_MASK(changedDevice));
276 observer->OnChange(data);
277 }
278 });
279 return OK;
280 }
281
SetIAssetLoader(const std::shared_ptr<IAssetLoader> & loader)282 DBStatus RelationalStoreDelegateImpl::SetIAssetLoader(const std::shared_ptr<IAssetLoader> &loader)
283 {
284 if (conn_ == nullptr || conn_->SetIAssetLoader(loader) != E_OK) {
285 return DB_ERROR;
286 }
287 return OK;
288 }
289
UnRegisterObserver()290 DBStatus RelationalStoreDelegateImpl::UnRegisterObserver()
291 {
292 return RegisterObserver(nullptr);
293 }
294 } // namespace DistributedDB
295 #endif