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