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 "sqlite_relational_store_connection.h"
17 #include "db_errno.h"
18 #include "log_print.h"
19
20 namespace DistributedDB {
SQLiteRelationalStoreConnection(SQLiteRelationalStore * store)21 SQLiteRelationalStoreConnection::SQLiteRelationalStoreConnection(SQLiteRelationalStore *store)
22 : RelationalStoreConnection(store)
23 {
24 OnKill([this]() {
25 auto *store = GetDB<SQLiteRelationalStore>();
26 if (store == nullptr) {
27 return;
28 }
29 UnlockObj();
30 store->StopSync(GetConnectionId());
31 LockObj();
32 });
33 }
34 // Close and release the connection.
Close()35 int SQLiteRelationalStoreConnection::Close()
36 {
37 if (store_ == nullptr) {
38 return -E_INVALID_CONNECTION;
39 }
40
41 if (isExclusive_.load()) {
42 return -E_BUSY;
43 }
44
45 // check if transaction closed
46 {
47 std::lock_guard<std::mutex> transactionLock(transactionMutex_);
48 if (writeHandle_ != nullptr) {
49 LOGW("Transaction started, need to rollback before close.");
50 int errCode = RollBack();
51 if (errCode != E_OK) {
52 LOGE("Rollback transaction failed, %d.", errCode);
53 }
54 ReleaseExecutor(writeHandle_);
55 }
56 }
57
58 static_cast<SQLiteRelationalStore *>(store_)->ReleaseDBConnection(GetConnectionId(), this);
59 return E_OK;
60 }
61
GetIdentifier()62 std::string SQLiteRelationalStoreConnection::GetIdentifier()
63 {
64 if (store_ == nullptr) {
65 return {};
66 }
67 return store_->GetProperties().GetStringProp(RelationalDBProperties::IDENTIFIER_DATA, "");
68 }
69
GetExecutor(bool isWrite,int & errCode) const70 SQLiteSingleVerRelationalStorageExecutor *SQLiteRelationalStoreConnection::GetExecutor(bool isWrite, int &errCode) const
71 {
72 auto *store = GetDB<SQLiteRelationalStore>();
73 if (store == nullptr) { // LCOV_EXCL_BR_LINE
74 errCode = -E_NOT_INIT;
75 LOGE("[RelationalConnection] store is null, get executor failed! errCode = [%d]", errCode);
76 return nullptr;
77 }
78
79 return store->GetHandle(isWrite, errCode);
80 }
81
ReleaseExecutor(SQLiteSingleVerRelationalStorageExecutor * & executor) const82 void SQLiteRelationalStoreConnection::ReleaseExecutor(SQLiteSingleVerRelationalStorageExecutor *&executor) const
83 {
84 auto *store = GetDB<SQLiteRelationalStore>();
85 if (store != nullptr) { // LCOV_EXCL_BR_LINE
86 store->ReleaseHandle(executor);
87 }
88 }
89
StartTransaction()90 int SQLiteRelationalStoreConnection::StartTransaction()
91 {
92 std::lock_guard<std::mutex> lock(transactionMutex_);
93 if (writeHandle_ != nullptr) { // LCOV_EXCL_BR_LINE
94 LOGD("Transaction started already.");
95 return -E_TRANSACT_STATE;
96 }
97
98 int errCode = E_OK;
99 auto *handle = GetExecutor(true, errCode);
100 if (handle == nullptr) { // LCOV_EXCL_BR_LINE
101 return errCode;
102 }
103
104 errCode = handle->StartTransaction(TransactType::DEFERRED);
105 if (errCode != E_OK) { // LCOV_EXCL_BR_LINE
106 ReleaseExecutor(handle);
107 return errCode;
108 }
109
110 writeHandle_ = handle;
111 return E_OK;
112 }
113
114 // Commit the transaction
Commit()115 int SQLiteRelationalStoreConnection::Commit()
116 {
117 std::lock_guard<std::mutex> lock(transactionMutex_);
118 if (writeHandle_ == nullptr) { // LCOV_EXCL_BR_LINE
119 LOGE("single version database is null or the transaction has not been started");
120 return -E_INVALID_DB;
121 }
122
123 int errCode = writeHandle_->Commit();
124 ReleaseExecutor(writeHandle_);
125 LOGD("connection commit transaction!");
126 return errCode;
127 }
128
129 // Roll back the transaction
RollBack()130 int SQLiteRelationalStoreConnection::RollBack()
131 {
132 std::lock_guard<std::mutex> lock(transactionMutex_);
133 if (writeHandle_ == nullptr) { // LCOV_EXCL_BR_LINE
134 LOGE("Invalid handle for rollback or the transaction has not been started.");
135 return -E_INVALID_DB;
136 }
137
138 int errCode = writeHandle_->Rollback();
139 ReleaseExecutor(writeHandle_);
140 LOGI("connection rollback transaction!");
141 return errCode;
142 }
143
CreateDistributedTable(const std::string & tableName,TableSyncType syncType)144 int SQLiteRelationalStoreConnection::CreateDistributedTable(const std::string &tableName, TableSyncType syncType)
145 {
146 auto *store = GetDB<SQLiteRelationalStore>();
147 if (store == nullptr) {
148 LOGE("[RelationalConnection] store is null, get DB failed!");
149 return -E_INVALID_CONNECTION;
150 }
151
152 int errCode = store->CreateDistributedTable(tableName, syncType);
153 if (errCode != E_OK) {
154 LOGE("[RelationalConnection] create distributed table failed. %d", errCode);
155 }
156 return errCode;
157 }
158
RemoveDeviceData()159 int SQLiteRelationalStoreConnection::RemoveDeviceData()
160 {
161 auto *store = GetDB<SQLiteRelationalStore>();
162 if (store == nullptr) {
163 LOGE("[RelationalConnection] store is null, get DB failed!");
164 return -E_INVALID_CONNECTION;
165 }
166
167 int errCode = store->RemoveDeviceData();
168 if (errCode != E_OK) {
169 LOGE("[RelationalConnection] remove device data failed. %d", errCode);
170 }
171 return errCode;
172 }
173
GetCloudSyncTaskCount()174 int32_t SQLiteRelationalStoreConnection::GetCloudSyncTaskCount()
175 {
176 auto *store = GetDB<SQLiteRelationalStore>();
177 if (store == nullptr) {
178 LOGE("[RelationalConnection] store is null, get DB failed!");
179 return -1;
180 }
181 int32_t count = store->GetCloudSyncTaskCount();
182 if (count == -1) {
183 LOGE("[RelationalConnection] failed to get cloud sync task count");
184 }
185 return count;
186 }
187
DoClean(ClearMode mode)188 int SQLiteRelationalStoreConnection::DoClean(ClearMode mode)
189 {
190 auto *store = GetDB<SQLiteRelationalStore>();
191 if (store == nullptr) {
192 LOGE("[RelationalConnection] store is null, get DB failed!");
193 return -E_INVALID_CONNECTION;
194 }
195
196 int errCode = store->CleanCloudData(mode);
197 if (errCode != E_OK) {
198 LOGE("[RelationalConnection] failed to clean cloud data, %d.", errCode);
199 }
200 return errCode;
201 }
202
RemoveDeviceData(const std::string & device)203 int SQLiteRelationalStoreConnection::RemoveDeviceData(const std::string &device)
204 {
205 return RemoveDeviceData(device, {});
206 }
207
RemoveDeviceData(const std::string & device,const std::string & tableName)208 int SQLiteRelationalStoreConnection::RemoveDeviceData(const std::string &device, const std::string &tableName)
209 {
210 auto *store = GetDB<SQLiteRelationalStore>();
211 if (store == nullptr) {
212 LOGE("[RelationalConnection] store is null, get DB failed!");
213 return -E_INVALID_CONNECTION;
214 }
215
216 int errCode = store->RemoveDeviceData(device, tableName);
217 if (errCode != E_OK) {
218 LOGE("[RelationalConnection] remove device data failed. %d", errCode);
219 }
220 return errCode;
221 }
222
Pragma(int cmd,void * parameter)223 int SQLiteRelationalStoreConnection::Pragma(int cmd, void *parameter) // reserve for interface function fix
224 {
225 (void)cmd;
226 (void)parameter;
227 return E_OK;
228 }
229
SyncToDevice(SyncInfo & info)230 int SQLiteRelationalStoreConnection::SyncToDevice(SyncInfo &info)
231 {
232 auto *store = GetDB<SQLiteRelationalStore>();
233 if (store == nullptr) {
234 LOGE("[RelationalConnection] store is null, get executor failed!");
235 return -E_INVALID_CONNECTION;
236 }
237
238 {
239 AutoLock lockGuard(this);
240 if (IsKilled()) {
241 // If this happens, users are using a closed connection.
242 LOGE("Sync on a closed connection.");
243 return -E_STALE;
244 }
245 IncObjRef(this);
246 }
247 ISyncer::SyncParma syncParam;
248 syncParam.devices = info.devices;
249 syncParam.mode = info.mode;
250 syncParam.wait = info.wait;
251 syncParam.isQuerySync = true;
252 syncParam.relationOnComplete = info.onComplete;
253 syncParam.syncQuery = QuerySyncObject(info.query);
254 syncParam.onFinalize = [this]() {
255 DecObjRef(this);
256 };
257 if (syncParam.syncQuery.GetSortType() != SortType::NONE) {
258 LOGE("not support order by timestamp");
259 DecObjRef(this);
260 return -E_NOT_SUPPORT;
261 }
262 int errCode = store->Sync(syncParam, GetConnectionId());
263 if (errCode != E_OK) {
264 DecObjRef(this);
265 return errCode;
266 }
267 return E_OK;
268 }
269
RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier & notifier)270 int SQLiteRelationalStoreConnection::RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier ¬ifier)
271 {
272 auto *store = GetDB<SQLiteRelationalStore>();
273 if (store == nullptr) {
274 LOGE("[RelationalConnection] store is null, get executor failed!");
275 return -E_INVALID_CONNECTION;
276 }
277
278 return store->RegisterLifeCycleCallback(notifier);
279 }
280
RegisterObserverAction(const StoreObserver * observer,const RelationalObserverAction & action)281 int SQLiteRelationalStoreConnection::RegisterObserverAction(const StoreObserver *observer,
282 const RelationalObserverAction &action)
283 {
284 return static_cast<SQLiteRelationalStore *>(store_)->RegisterObserverAction(GetConnectionId(), observer, action);
285 }
286
UnRegisterObserverAction(const StoreObserver * observer)287 int SQLiteRelationalStoreConnection::UnRegisterObserverAction(const StoreObserver *observer)
288 {
289 return static_cast<SQLiteRelationalStore *>(store_)->UnRegisterObserverAction(GetConnectionId(), observer);
290 }
291
RemoteQuery(const std::string & device,const RemoteCondition & condition,uint64_t timeout,std::shared_ptr<ResultSet> & result)292 int SQLiteRelationalStoreConnection::RemoteQuery(const std::string &device, const RemoteCondition &condition,
293 uint64_t timeout, std::shared_ptr<ResultSet> &result)
294 {
295 auto *store = GetDB<SQLiteRelationalStore>();
296 if (store == nullptr) {
297 LOGE("[RelationalConnection] store is null, get executor failed!");
298 return -E_INVALID_CONNECTION;
299 }
300 return store->RemoteQuery(device, condition, timeout, GetConnectionId(), result);
301 }
302
SetCloudDB(const std::shared_ptr<ICloudDb> & cloudDb)303 int SQLiteRelationalStoreConnection::SetCloudDB(const std::shared_ptr<ICloudDb> &cloudDb)
304 {
305 auto *store = GetDB<SQLiteRelationalStore>();
306 if (store == nullptr) {
307 LOGE("[RelationalConnection] store is null, get DB failed!");
308 return -E_INVALID_CONNECTION;
309 }
310
311 return store->SetCloudDB(cloudDb);
312 }
313
PrepareAndSetCloudDbSchema(const DataBaseSchema & schema)314 int SQLiteRelationalStoreConnection::PrepareAndSetCloudDbSchema(const DataBaseSchema &schema)
315 {
316 auto *store = GetDB<SQLiteRelationalStore>();
317 if (store == nullptr) {
318 LOGE("[RelationalConnection] store is null, get DB failed!");
319 return -E_INVALID_CONNECTION;
320 }
321
322 int ret = store->PrepareAndSetCloudDbSchema(schema);
323 if (ret != E_OK) {
324 LOGE("[RelationalConnection] PrepareAndSetCloudDbSchema failed. %d", ret);
325 }
326 return ret;
327 }
328
SetIAssetLoader(const std::shared_ptr<IAssetLoader> & loader)329 int SQLiteRelationalStoreConnection::SetIAssetLoader(const std::shared_ptr<IAssetLoader> &loader)
330 {
331 auto *store = GetDB<SQLiteRelationalStore>();
332 if (store == nullptr) {
333 LOGE("[RelationalConnection] store is null, get DB failed!");
334 return -E_INVALID_CONNECTION;
335 }
336
337 int ret = store->SetIAssetLoader(loader);
338 if (ret != E_OK) {
339 LOGE("[RelationalConnection] Set asset loader failed. %d", ret);
340 }
341 return ret;
342 }
343
GetStoreInfo(std::string & userId,std::string & appId,std::string & storeId)344 int SQLiteRelationalStoreConnection::GetStoreInfo(std::string &userId, std::string &appId, std::string &storeId)
345 {
346 auto *store = GetDB<SQLiteRelationalStore>();
347 if (store == nullptr) {
348 LOGE("[RelationalConnection] store is null, get storeInfo failed!");
349 return -E_INVALID_CONNECTION;
350 }
351 auto properties = store->GetProperties();
352 userId = properties.GetStringProp(RelationalDBProperties::USER_ID, "");
353 appId = properties.GetStringProp(RelationalDBProperties::APP_ID, "");
354 storeId = properties.GetStringProp(RelationalDBProperties::STORE_ID, "");
355 return E_OK;
356 }
357
SetTrackerTable(const TrackerSchema & schema)358 int SQLiteRelationalStoreConnection::SetTrackerTable(const TrackerSchema &schema)
359 {
360 auto *store = GetDB<SQLiteRelationalStore>();
361 if (store == nullptr) {
362 LOGE("[RelationalConnection] store is null, get DB failed!");
363 return -E_INVALID_CONNECTION;
364 }
365 int errCode = store->SetTrackerTable(schema);
366 if (errCode != E_OK && errCode != -E_WITH_INVENTORY_DATA) {
367 LOGE("[RelationalConnection] set tracker table failed. %d", errCode);
368 }
369 return errCode;
370 }
371
ExecuteSql(const SqlCondition & condition,std::vector<VBucket> & records)372 int SQLiteRelationalStoreConnection::ExecuteSql(const SqlCondition &condition, std::vector<VBucket> &records)
373 {
374 auto *store = GetDB<SQLiteRelationalStore>();
375 if (store == nullptr) {
376 LOGE("[RelationalConnection] store is null, get executor failed!");
377 return -E_INVALID_CONNECTION;
378 }
379 return store->ExecuteSql(condition, records);
380 }
381
SetReference(const std::vector<TableReferenceProperty> & tableReferenceProperty)382 int SQLiteRelationalStoreConnection::SetReference(const std::vector<TableReferenceProperty> &tableReferenceProperty)
383 {
384 auto *store = GetDB<SQLiteRelationalStore>();
385 if (store == nullptr) {
386 LOGE("[SetReference] store is null, get DB failed!");
387 return -E_INVALID_CONNECTION;
388 }
389 return store->SetReference(tableReferenceProperty);
390 }
391
CleanTrackerData(const std::string & tableName,int64_t cursor)392 int SQLiteRelationalStoreConnection::CleanTrackerData(const std::string &tableName, int64_t cursor)
393 {
394 auto *store = GetDB<SQLiteRelationalStore>();
395 if (store == nullptr) { // LCOV_EXCL_BR_LINE
396 LOGE("[RelationalConnection] store is null, get executor failed!");
397 return -E_INVALID_CONNECTION;
398 }
399 return store->CleanTrackerData(tableName, cursor);
400 }
401
Pragma(PragmaCmd cmd,PragmaData & pragmaData)402 int SQLiteRelationalStoreConnection::Pragma(PragmaCmd cmd, PragmaData &pragmaData)
403 {
404 auto *store = GetDB<SQLiteRelationalStore>();
405 if (store == nullptr) {
406 LOGE("[RelationalConnection] store is null, get executor failed!");
407 return -E_INVALID_CONNECTION;
408 }
409 return store->Pragma(cmd, pragmaData);
410 }
411
UpsertData(RecordStatus status,const std::string & tableName,const std::vector<VBucket> & records)412 int SQLiteRelationalStoreConnection::UpsertData(RecordStatus status, const std::string &tableName,
413 const std::vector<VBucket> &records)
414 {
415 auto *store = GetDB<SQLiteRelationalStore>();
416 if (store == nullptr) {
417 LOGE("[RelationalConnection] store is null, upsert dara failed!");
418 return -E_INVALID_CONNECTION;
419 }
420 return store->UpsertData(status, tableName, records);
421 }
422
SetCloudSyncConfig(const CloudSyncConfig & config)423 int SQLiteRelationalStoreConnection::SetCloudSyncConfig(const CloudSyncConfig &config)
424 {
425 auto *store = GetDB<SQLiteRelationalStore>();
426 if (store == nullptr) { // LCOV_EXCL_BR_LINE
427 LOGE("[RelationalConnection] store is null, set cloud sync config failed!");
428 return -E_INVALID_CONNECTION;
429 }
430 return store->SetCloudSyncConfig(config);
431 }
432
Sync(const CloudSyncOption & option,const SyncProcessCallback & onProcess,uint64_t taskId)433 int SQLiteRelationalStoreConnection::Sync(const CloudSyncOption &option, const SyncProcessCallback &onProcess,
434 uint64_t taskId)
435 {
436 auto *store = GetDB<SQLiteRelationalStore>();
437 if (store == nullptr) {
438 LOGE("[RelationalConnection] store is null, get executor failed!");
439 return -E_INVALID_CONNECTION;
440 }
441 {
442 AutoLock lockGuard(this);
443 if (IsKilled()) {
444 // If this happens, users are using a closed connection.
445 LOGE("[RelationalConnection] Sync on a closed connection.");
446 return -E_STALE;
447 }
448 IncObjRef(this);
449 }
450 int errCode = store->Sync(option, onProcess, taskId);
451 DecObjRef(this);
452 return errCode;
453 }
454
GetCloudTaskStatus(uint64_t taskId)455 SyncProcess SQLiteRelationalStoreConnection::GetCloudTaskStatus(uint64_t taskId)
456 {
457 auto *store = GetDB<SQLiteRelationalStore>();
458 if (store == nullptr) {
459 LOGE("[RelationalConnection] store is null, get executor failed!");
460 SyncProcess process;
461 process.errCode = DB_ERROR;
462 return process;
463 }
464 {
465 AutoLock lockGuard(this);
466 if (IsKilled()) {
467 // If this happens, users are using a closed connection.
468 LOGE("[RelationalConnection] Get sync task on a closed connection.");
469 SyncProcess process;
470 process.errCode = DB_ERROR;
471 return process;
472 }
473 IncObjRef(this);
474 }
475 SyncProcess process = store->GetCloudTaskStatus(taskId);
476 DecObjRef(this);
477 return process;
478 }
479 }
480 #endif