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