• 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 "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 &notifier)
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