• 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.h"
17 
18 #include "db_common.h"
19 #include "db_constant.h"
20 #include "db_dump_helper.h"
21 #include "db_errno.h"
22 #include "log_print.h"
23 #include "db_types.h"
24 #include "sqlite_log_table_manager.h"
25 #include "sqlite_relational_store_connection.h"
26 #include "storage_engine_manager.h"
27 
28 namespace DistributedDB {
29 namespace {
30     constexpr const char *DISTRIBUTED_TABLE_MODE = "distributed_table_mode";
31 }
32 
~SQLiteRelationalStore()33 SQLiteRelationalStore::~SQLiteRelationalStore()
34 {
35     sqliteStorageEngine_ = nullptr;
36 }
37 
38 // Called when a new connection created.
IncreaseConnectionCounter()39 void SQLiteRelationalStore::IncreaseConnectionCounter()
40 {
41     connectionCount_.fetch_add(1, std::memory_order_seq_cst);
42     if (connectionCount_.load() > 0) {
43         sqliteStorageEngine_->SetConnectionFlag(true);
44     }
45 }
46 
GetDBConnection(int & errCode)47 RelationalStoreConnection *SQLiteRelationalStore::GetDBConnection(int &errCode)
48 {
49     std::lock_guard<std::mutex> lock(connectMutex_);
50     RelationalStoreConnection* connection = new (std::nothrow) SQLiteRelationalStoreConnection(this);
51     if (connection == nullptr) {
52         errCode = -E_OUT_OF_MEMORY;
53         return nullptr;
54     }
55     IncObjRef(this);
56     IncreaseConnectionCounter();
57     return connection;
58 }
59 
InitDataBaseOption(const RelationalDBProperties & properties,OpenDbProperties & option)60 static void InitDataBaseOption(const RelationalDBProperties &properties, OpenDbProperties &option)
61 {
62     option.uri = properties.GetStringProp(DBProperties::DATA_DIR, "");
63     option.createIfNecessary = properties.GetBoolProp(DBProperties::CREATE_IF_NECESSARY, false);
64     if (properties.IsEncrypted()) {
65         option.cipherType = properties.GetCipherType();
66         option.passwd = properties.GetPasswd();
67         option.iterTimes = properties.GetIterTimes();
68     }
69 }
70 
InitStorageEngine(const RelationalDBProperties & properties)71 int SQLiteRelationalStore::InitStorageEngine(const RelationalDBProperties &properties)
72 {
73     OpenDbProperties option;
74     InitDataBaseOption(properties, option);
75     std::string identifier = properties.GetStringProp(DBProperties::IDENTIFIER_DATA, "");
76 
77     StorageEngineAttr poolSize = {1, 1, 0, 16}; // at most 1 write 16 read.
78     int errCode = sqliteStorageEngine_->InitSQLiteStorageEngine(poolSize, option, identifier);
79     if (errCode != E_OK) {
80         LOGE("Init the sqlite storage engine failed:%d", errCode);
81     }
82     return errCode;
83 }
84 
ReleaseResources()85 void SQLiteRelationalStore::ReleaseResources()
86 {
87     if (sqliteStorageEngine_ != nullptr) {
88         sqliteStorageEngine_->ClearEnginePasswd();
89         sqliteStorageEngine_ = nullptr;
90     }
91     RefObject::DecObjRef(storageEngine_);
92 }
93 
CheckDBMode()94 int SQLiteRelationalStore::CheckDBMode()
95 {
96     int errCode = E_OK;
97     auto *handle = GetHandle(false, errCode);
98     if (handle == nullptr) {
99         return errCode;
100     }
101     errCode = handle->CheckDBModeForRelational();
102     if (errCode != E_OK) {
103         LOGE("check relational DB mode failed. %d", errCode);
104     }
105 
106     ReleaseHandle(handle);
107     return errCode;
108 }
109 
GetSchemaFromMeta(RelationalSchemaObject & schema)110 int SQLiteRelationalStore::GetSchemaFromMeta(RelationalSchemaObject &schema)
111 {
112     Key schemaKey;
113     DBCommon::StringToVector(DBConstant::RELATIONAL_SCHEMA_KEY, schemaKey);
114     Value schemaVal;
115     int errCode = storageEngine_->GetMetaData(schemaKey, schemaVal);
116     if (errCode != E_OK && errCode != -E_NOT_FOUND) {
117         LOGE("Get relational schema from meta table failed. %d", errCode);
118         return errCode;
119     } else if (errCode == -E_NOT_FOUND || schemaVal.empty()) {
120         LOGW("No relational schema info was found.");
121         return -E_NOT_FOUND;
122     }
123 
124     std::string schemaStr;
125     DBCommon::VectorToString(schemaVal, schemaStr);
126     errCode = schema.ParseFromSchemaString(schemaStr);
127     if (errCode != E_OK) {
128         LOGE("Parse schema string from meta table failed.");
129         return errCode;
130     }
131 
132     sqliteStorageEngine_->SetSchema(schema);
133     return E_OK;
134 }
135 
CheckTableModeFromMeta(DistributedTableMode mode,bool isUnSet)136 int SQLiteRelationalStore::CheckTableModeFromMeta(DistributedTableMode mode, bool isUnSet)
137 {
138     const Key modeKey(DISTRIBUTED_TABLE_MODE, DISTRIBUTED_TABLE_MODE + strlen(DISTRIBUTED_TABLE_MODE));
139     Value modeVal;
140     int errCode = storageEngine_->GetMetaData(modeKey, modeVal);
141     if (errCode != E_OK && errCode != -E_NOT_FOUND) {
142         LOGE("Get distributed table mode from meta table failed. errCode=%d", errCode);
143         return errCode;
144     }
145 
146     DistributedTableMode orgMode = DistributedTableMode::SPLIT_BY_DEVICE;
147     if (!modeVal.empty()) {
148         std::string value(modeVal.begin(), modeVal.end());
149         orgMode = static_cast<DistributedTableMode>(strtoll(value.c_str(), nullptr, 10)); // 10: decimal
150     } else if (isUnSet) {
151         return E_OK; // First set table mode.
152     }
153 
154     if (orgMode != mode) {
155         LOGE("Check distributed table mode mismatch, orgMode=%d, openMode=%d", orgMode, mode);
156         return -E_INVALID_ARGS;
157     }
158     return E_OK;
159 }
160 
CheckProperties(RelationalDBProperties properties)161 int SQLiteRelationalStore::CheckProperties(RelationalDBProperties properties)
162 {
163     RelationalSchemaObject schema;
164     int errCode = GetSchemaFromMeta(schema);
165     if (errCode != E_OK && errCode != -E_NOT_FOUND) {
166         LOGE("Get relational schema from meta failed. errcode=%d", errCode);
167         return errCode;
168     }
169     properties.SetSchema(schema);
170 
171     // Empty schema means no distributed table has been used, we may set DB to any table mode
172     // If there is a schema but no table mode, it is the 'SPLIT_BY_DEVICE' mode of old version
173     bool isSchemaEmpty = (errCode == -E_NOT_FOUND);
174     auto mode = static_cast<DistributedTableMode>(properties.GetIntProp(RelationalDBProperties::DISTRIBUTED_TABLE_MODE,
175         DistributedTableMode::SPLIT_BY_DEVICE));
176     errCode = CheckTableModeFromMeta(mode, isSchemaEmpty);
177     if (errCode != E_OK) {
178         LOGE("Get distributed table mode from meta failed. errcode=%d", errCode);
179         return errCode;
180     }
181 
182     errCode = SaveTableModeToMeta(mode);
183     if (errCode != E_OK) {
184         LOGE("Save table mode to meta failed. errCode=%d", errCode);
185         return errCode;
186     }
187 
188     return E_OK;
189 }
190 
SaveSchemaToMeta()191 int SQLiteRelationalStore::SaveSchemaToMeta()
192 {
193     Key schemaKey;
194     DBCommon::StringToVector(DBConstant::RELATIONAL_SCHEMA_KEY, schemaKey);
195     Value schemaVal;
196     DBCommon::StringToVector(sqliteStorageEngine_->GetSchema().ToSchemaString(), schemaVal);
197     int errCode = storageEngine_->PutMetaData(schemaKey, schemaVal);
198     if (errCode != E_OK) {
199         LOGE("Save relational schema to meta table failed. %d", errCode);
200     }
201     return errCode;
202 }
203 
SaveTableModeToMeta(DistributedTableMode mode)204 int SQLiteRelationalStore::SaveTableModeToMeta(DistributedTableMode mode)
205 {
206     const Key modeKey(DISTRIBUTED_TABLE_MODE, DISTRIBUTED_TABLE_MODE + strlen(DISTRIBUTED_TABLE_MODE));
207     Value modeVal;
208     DBCommon::StringToVector(std::to_string(mode), modeVal);
209     int errCode = storageEngine_->PutMetaData(modeKey, modeVal);
210     if (errCode != E_OK) {
211         LOGE("Save relational schema to meta table failed. %d", errCode);
212     }
213     return errCode;
214 }
215 
SaveLogTableVersionToMeta()216 int SQLiteRelationalStore::SaveLogTableVersionToMeta()
217 {
218     LOGD("save log table version to meta table, key: %s, val: %s", DBConstant::LOG_TABLE_VERSION_KEY.c_str(),
219         DBConstant::LOG_TABLE_VERSION_CURRENT.c_str());
220     const Key logVersionKey(DBConstant::LOG_TABLE_VERSION_KEY.begin(), DBConstant::LOG_TABLE_VERSION_KEY.end());
221     Value logVersionVal(DBConstant::LOG_TABLE_VERSION_CURRENT.begin(), DBConstant::LOG_TABLE_VERSION_CURRENT.end());
222     int errCode = storageEngine_->PutMetaData(logVersionKey, logVersionVal);
223     if (errCode != E_OK) {
224         LOGE("save log table version to meta table failed. %d", errCode);
225     }
226     return errCode;
227 }
228 
CleanDistributedDeviceTable()229 int SQLiteRelationalStore::CleanDistributedDeviceTable()
230 {
231     std::vector<std::string> missingTables;
232     int errCode = sqliteStorageEngine_->CleanDistributedDeviceTable(missingTables);
233     if (errCode != E_OK) {
234         LOGE("Clean distributed device table failed. %d", errCode);
235     }
236     for (const auto &deviceTableName : missingTables) {
237         std::string deviceHash;
238         std::string tableName;
239         DBCommon::GetDeviceFromName(deviceTableName, deviceHash, tableName);
240         syncAbleEngine_->EraseDeviceWaterMark(deviceHash, false, tableName);
241         if (errCode != E_OK) {
242             LOGE("Erase water mark failed:%d", errCode);
243             return errCode;
244         }
245     }
246     return errCode;
247 }
248 
Open(const RelationalDBProperties & properties)249 int SQLiteRelationalStore::Open(const RelationalDBProperties &properties)
250 {
251     std::lock_guard<std::mutex> lock(initalMutex_);
252     if (isInitialized_) {
253         LOGD("[RelationalStore][Open] relational db was already initialized.");
254         return E_OK;
255     }
256 
257     sqliteStorageEngine_ = std::make_shared<SQLiteSingleRelationalStorageEngine>(properties);
258     if (sqliteStorageEngine_ == nullptr) {
259         LOGE("[RelationalStore][Open] Create storage engine failed");
260         return -E_OUT_OF_MEMORY;
261     }
262 
263     int errCode = E_OK;
264     do {
265         errCode = InitStorageEngine(properties);
266         if (errCode != E_OK) {
267             LOGE("[RelationalStore][Open] Init database context fail! errCode = [%d]", errCode);
268             break;
269         }
270 
271         storageEngine_ = new (std::nothrow) RelationalSyncAbleStorage(sqliteStorageEngine_);
272         if (storageEngine_ == nullptr) {
273             LOGE("[RelationalStore][Open] Create syncable storage failed");
274             errCode = -E_OUT_OF_MEMORY;
275             break;
276         }
277 
278         syncAbleEngine_ = std::make_unique<SyncAbleEngine>(storageEngine_);
279 
280         errCode = CheckDBMode();
281         if (errCode != E_OK) {
282             break;
283         }
284 
285         errCode = CheckProperties(properties);
286         if (errCode != E_OK) {
287             break;
288         }
289 
290         errCode = SaveLogTableVersionToMeta();
291         if (errCode != E_OK) {
292             break;
293         }
294 
295         errCode = CleanDistributedDeviceTable();
296         if (errCode != E_OK) {
297             break;
298         }
299 
300         isInitialized_ = true;
301         return E_OK;
302     } while (false);
303 
304     ReleaseResources();
305     return errCode;
306 }
307 
OnClose(const std::function<void (void)> & notifier)308 void SQLiteRelationalStore::OnClose(const std::function<void(void)> &notifier)
309 {
310     AutoLock lockGuard(this);
311     if (notifier) {
312         closeNotifiers_.push_back(notifier);
313     } else {
314         LOGW("Register 'Close()' notifier failed, notifier is null.");
315     }
316 }
317 
GetHandle(bool isWrite,int & errCode) const318 SQLiteSingleVerRelationalStorageExecutor *SQLiteRelationalStore::GetHandle(bool isWrite, int &errCode) const
319 {
320     if (sqliteStorageEngine_ == nullptr) {
321         errCode = -E_INVALID_DB;
322         return nullptr;
323     }
324 
325     return static_cast<SQLiteSingleVerRelationalStorageExecutor *>(sqliteStorageEngine_->FindExecutor(isWrite,
326         OperatePerm::NORMAL_PERM, errCode));
327 }
ReleaseHandle(SQLiteSingleVerRelationalStorageExecutor * & handle) const328 void SQLiteRelationalStore::ReleaseHandle(SQLiteSingleVerRelationalStorageExecutor *&handle) const
329 {
330     if (handle == nullptr) {
331         return;
332     }
333 
334     if (sqliteStorageEngine_ != nullptr) {
335         StorageExecutor *databaseHandle = handle;
336         sqliteStorageEngine_->Recycle(databaseHandle);
337         handle = nullptr;
338     }
339 }
340 
Sync(const ISyncer::SyncParma & syncParam,uint64_t connectionId)341 int SQLiteRelationalStore::Sync(const ISyncer::SyncParma &syncParam, uint64_t connectionId)
342 {
343     return syncAbleEngine_->Sync(syncParam, connectionId);
344 }
345 
346 // Called when a connection released.
DecreaseConnectionCounter()347 void SQLiteRelationalStore::DecreaseConnectionCounter()
348 {
349     int count = connectionCount_.fetch_sub(1, std::memory_order_seq_cst);
350     if (count <= 0) {
351         LOGF("Decrease db connection counter failed, count <= 0.");
352         return;
353     }
354     if (count != 1) {
355         return;
356     }
357 
358     LockObj();
359     auto notifiers = std::move(closeNotifiers_);
360     UnlockObj();
361 
362     for (const auto &notifier : notifiers) {
363         if (notifier) {
364             notifier();
365         }
366     }
367 
368     // Sync Close
369     syncAbleEngine_->Close();
370 
371     if (sqliteStorageEngine_ != nullptr) {
372         sqliteStorageEngine_ = nullptr;
373     }
374     // close will dec sync ref of storageEngine_
375     DecObjRef(storageEngine_);
376 }
377 
ReleaseDBConnection(RelationalStoreConnection * connection)378 void SQLiteRelationalStore::ReleaseDBConnection(RelationalStoreConnection *connection)
379 {
380     if (connectionCount_.load() == 1) {
381         sqliteStorageEngine_->SetConnectionFlag(false);
382     }
383 
384     connectMutex_.lock();
385     if (connection != nullptr) {
386         KillAndDecObjRef(connection);
387         DecreaseConnectionCounter();
388         connectMutex_.unlock();
389         KillAndDecObjRef(this);
390     } else {
391         connectMutex_.unlock();
392     }
393 }
394 
WakeUpSyncer()395 void SQLiteRelationalStore::WakeUpSyncer()
396 {
397     syncAbleEngine_->WakeUpSyncer();
398 }
399 
CreateDistributedTable(const std::string & tableName)400 int SQLiteRelationalStore::CreateDistributedTable(const std::string &tableName)
401 {
402     auto mode = static_cast<DistributedTableMode>(sqliteStorageEngine_->GetProperties().GetIntProp(
403         RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE));
404 
405     std::string localIdentity; // collaboration mode need local identify
406     if (mode == DistributedTableMode::COLLABORATION) {
407         int errCode = syncAbleEngine_->GetLocalIdentity(localIdentity);
408         if (errCode != E_OK || localIdentity.empty()) {
409             LOGD("Get local identity failed, can not create.");
410             return -E_NOT_SUPPORT;
411         }
412     }
413 
414     bool schemaChanged = false;
415     int errCode = sqliteStorageEngine_->CreateDistributedTable(tableName, DBCommon::TransferStringToHex(localIdentity),
416         schemaChanged);
417     if (errCode != E_OK) {
418         LOGE("Create distributed table failed. %d", errCode);
419     }
420     if (schemaChanged) {
421         LOGD("Notify schema changed.");
422         storageEngine_->NotifySchemaChanged();
423     }
424     return errCode;
425 }
426 
RemoveDeviceData()427 int SQLiteRelationalStore::RemoveDeviceData()
428 {
429     auto mode = static_cast<DistributedTableMode>(sqliteStorageEngine_->GetProperties().GetIntProp(
430         RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE));
431     if (mode == DistributedTableMode::COLLABORATION) {
432         LOGE("Not support remove device data in collaboration mode.");
433         return -E_NOT_SUPPORT;
434     }
435 
436     std::map<std::string, TableInfo> tables = sqliteStorageEngine_->GetSchema().GetTables();
437     if (tables.empty()) {
438         return E_OK;
439     }
440 
441     int errCode = E_OK;
442     auto *handle = GetHandleAndStartTransaction(errCode);
443     if (handle == nullptr) {
444         return errCode;
445     }
446 
447     std::vector<std::string> tableNameList;
448     for (const auto &table: tables) {
449         errCode = handle->DeleteDistributedDeviceTable("", table.second.GetTableName());
450         if (errCode != E_OK) {
451             LOGE("delete device data failed. %d", errCode);
452             break;
453         }
454         errCode = handle->DeleteDistributedAllDeviceTableLog(table.second.GetTableName());
455         if (errCode != E_OK) {
456             LOGE("delete device data failed. %d", errCode);
457             break;
458         }
459         tableNameList.push_back(table.second.GetTableName());
460     }
461 
462     if (errCode != E_OK) {
463         (void)handle->Rollback();
464         ReleaseHandle(handle);
465         return errCode;
466     }
467     errCode = handle->Commit();
468     ReleaseHandle(handle);
469     storageEngine_->NotifySchemaChanged();
470     return (errCode != E_OK) ? errCode : EraseAllDeviceWatermark(tableNameList);
471 }
472 
RemoveDeviceData(const std::string & device,const std::string & tableName)473 int SQLiteRelationalStore::RemoveDeviceData(const std::string &device, const std::string &tableName)
474 {
475     auto mode = static_cast<DistributedTableMode>(sqliteStorageEngine_->GetProperties().GetIntProp(
476         RelationalDBProperties::DISTRIBUTED_TABLE_MODE, DistributedTableMode::SPLIT_BY_DEVICE));
477     if (mode == DistributedTableMode::COLLABORATION) {
478         LOGE("Not support remove device data in collaboration mode.");
479         return -E_NOT_SUPPORT;
480     }
481 
482     auto tables = sqliteStorageEngine_->GetSchema().GetTables(); // TableInfoMap
483     if (tables.empty() || (!tableName.empty() && tables.find(tableName) == tables.end())) {
484         LOGE("Remove device data with table name which is not a distributed table or no distributed table found.");
485         return -E_DISTRIBUTED_SCHEMA_NOT_FOUND;
486     }
487 
488     bool isNeedHash = false;
489     std::string hashDeviceId;
490     int errCode = syncAbleEngine_->GetHashDeviceId(device, hashDeviceId);
491     if (errCode == -E_NOT_SUPPORT) {
492         isNeedHash = true;
493         hashDeviceId = device;
494         errCode = E_OK;
495     }
496     if (errCode != E_OK) {
497         return errCode;
498     }
499     if (isNeedHash) {
500         // check device is uuid in meta
501         std::set<std::string> hashDevices;
502         errCode = GetExistDevices(hashDevices);
503         if (errCode != E_OK) {
504             return errCode;
505         }
506         if (hashDevices.find(DBCommon::TransferHashString(device)) == hashDevices.end()) {
507             LOGD("[SQLiteRelationalStore] not match device, just return");
508             return E_OK;
509         }
510     }
511     return RemoveDeviceDataInner(hashDeviceId, device, tableName, isNeedHash);
512 }
513 
RegisterObserverAction(const RelationalObserverAction & action)514 void SQLiteRelationalStore::RegisterObserverAction(const RelationalObserverAction &action)
515 {
516     storageEngine_->RegisterObserverAction(action);
517 }
518 
StopLifeCycleTimer()519 int SQLiteRelationalStore::StopLifeCycleTimer()
520 {
521     auto runtimeCxt = RuntimeContext::GetInstance();
522     if (runtimeCxt == nullptr) {
523         return -E_INVALID_ARGS;
524     }
525     if (lifeTimerId_ != 0) {
526         TimerId timerId = lifeTimerId_;
527         lifeTimerId_ = 0;
528         runtimeCxt->RemoveTimer(timerId, false);
529     }
530     return E_OK;
531 }
532 
StartLifeCycleTimer(const DatabaseLifeCycleNotifier & notifier)533 int SQLiteRelationalStore::StartLifeCycleTimer(const DatabaseLifeCycleNotifier &notifier)
534 {
535     auto runtimeCxt = RuntimeContext::GetInstance();
536     if (runtimeCxt == nullptr) {
537         return -E_INVALID_ARGS;
538     }
539     RefObject::IncObjRef(this);
540     TimerId timerId = 0;
541     int errCode = runtimeCxt->SetTimer(DBConstant::DEF_LIFE_CYCLE_TIME,
542         [this](TimerId id) -> int {
543             std::lock_guard<std::mutex> lock(lifeCycleMutex_);
544             if (lifeCycleNotifier_) {
545                 // normal identifier mode
546                 std::string identifier;
547                 if (sqliteStorageEngine_->GetProperties().GetBoolProp(DBProperties::SYNC_DUAL_TUPLE_MODE, false)) {
548                     identifier = sqliteStorageEngine_->GetProperties().GetStringProp(
549                         DBProperties::DUAL_TUPLE_IDENTIFIER_DATA, "");
550                 } else {
551                     identifier = sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::IDENTIFIER_DATA, "");
552                 }
553                 auto userId = sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::USER_ID, "");
554                 lifeCycleNotifier_(identifier, userId);
555             }
556             return 0;
557         },
558         [this]() {
559             int ret = RuntimeContext::GetInstance()->ScheduleTask([this]() {
560                 RefObject::DecObjRef(this);
561             });
562             if (ret != E_OK) {
563                 LOGE("SQLiteSingleVerNaturalStore timer finalizer ScheduleTask, errCode %d", ret);
564             }
565         },
566         timerId);
567     if (errCode != E_OK) {
568         lifeTimerId_ = 0;
569         LOGE("SetTimer failed:%d", errCode);
570         RefObject::DecObjRef(this);
571         return errCode;
572     }
573 
574     lifeCycleNotifier_ = notifier;
575     lifeTimerId_ = timerId;
576     return E_OK;
577 }
578 
RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier & notifier)579 int SQLiteRelationalStore::RegisterLifeCycleCallback(const DatabaseLifeCycleNotifier &notifier)
580 {
581     int errCode;
582     {
583         std::lock_guard<std::mutex> lock(lifeCycleMutex_);
584         if (lifeTimerId_ != 0) {
585             errCode = StopLifeCycleTimer();
586             if (errCode != E_OK) {
587                 LOGE("Stop the life cycle timer failed:%d", errCode);
588                 return errCode;
589             }
590         }
591 
592         if (!notifier) {
593             return E_OK;
594         }
595         errCode = StartLifeCycleTimer(notifier);
596         if (errCode != E_OK) {
597             LOGE("Register life cycle timer failed:%d", errCode);
598             return errCode;
599         }
600     }
601     auto listener = std::bind(&SQLiteRelationalStore::HeartBeat, this);
602     storageEngine_->RegisterHeartBeatListener(listener);
603     return errCode;
604 }
605 
HeartBeat()606 void SQLiteRelationalStore::HeartBeat()
607 {
608     std::lock_guard<std::mutex> lock(lifeCycleMutex_);
609     int errCode = ResetLifeCycleTimer();
610     if (errCode != E_OK) {
611         LOGE("Heart beat for life cycle failed:%d", errCode);
612     }
613 }
614 
ResetLifeCycleTimer()615 int SQLiteRelationalStore::ResetLifeCycleTimer()
616 {
617     if (lifeTimerId_ == 0) {
618         return E_OK;
619     }
620     auto lifeNotifier = lifeCycleNotifier_;
621     lifeCycleNotifier_ = nullptr;
622     int errCode = StopLifeCycleTimer();
623     if (errCode != E_OK) {
624         LOGE("[Reset timer]Stop the life cycle timer failed:%d", errCode);
625     }
626     return StartLifeCycleTimer(lifeNotifier);
627 }
628 
GetStorePath() const629 std::string SQLiteRelationalStore::GetStorePath() const
630 {
631     return sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::DATA_DIR, "");
632 }
633 
GetProperties() const634 RelationalDBProperties SQLiteRelationalStore::GetProperties() const
635 {
636     return sqliteStorageEngine_->GetProperties();
637 }
638 
StopSync(uint64_t connectionId)639 void SQLiteRelationalStore::StopSync(uint64_t connectionId)
640 {
641     return syncAbleEngine_->StopSync(connectionId);
642 }
643 
Dump(int fd)644 void SQLiteRelationalStore::Dump(int fd)
645 {
646     std::string userId = "";
647     std::string appId = "";
648     std::string storeId = "";
649     std::string label = "";
650     if (sqliteStorageEngine_ != nullptr) {
651         userId = sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::USER_ID, "");
652         appId = sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::APP_ID, "");
653         storeId = sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::STORE_ID, "");
654         label = sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::IDENTIFIER_DATA, "");
655     }
656     label = DBCommon::TransferStringToHex(label);
657     DBDumpHelper::Dump(fd, "\tdb userId = %s, appId = %s, storeId = %s, label = %s\n",
658         userId.c_str(), appId.c_str(), storeId.c_str(), label.c_str());
659     if (syncAbleEngine_ != nullptr) {
660         syncAbleEngine_->Dump(fd);
661     }
662 }
663 
RemoteQuery(const std::string & device,const RemoteCondition & condition,uint64_t timeout,uint64_t connectionId,std::shared_ptr<ResultSet> & result)664 int SQLiteRelationalStore::RemoteQuery(const std::string &device, const RemoteCondition &condition, uint64_t timeout,
665     uint64_t connectionId, std::shared_ptr<ResultSet> &result)
666 {
667     if (sqliteStorageEngine_ == nullptr) {
668         return -E_INVALID_DB;
669     }
670 
671     if (!sqliteStorageEngine_->GetSchema().IsSchemaValid()) {
672         LOGW("not a distributed relational store.");
673         return -E_NOT_SUPPORT;
674     }
675     const auto &properties = sqliteStorageEngine_->GetProperties();
676     int tableMode = properties.GetIntProp(RelationalDBProperties::DISTRIBUTED_TABLE_MODE,
677         DistributedTableMode::SPLIT_BY_DEVICE);
678     if (tableMode != DistributedTableMode::SPLIT_BY_DEVICE) {
679         LOGW("only support split mode.");
680         return -E_NOT_SUPPORT;
681     }
682 
683     // Check whether to be able to operate the db.
684     int errCode = E_OK;
685     auto *handle = GetHandle(false, errCode);
686     if (handle == nullptr) {
687         return errCode;
688     }
689     errCode = handle->CheckEncryptedOrCorrupted();
690     ReleaseHandle(handle);
691     if (errCode != E_OK) {
692         return errCode;
693     }
694 
695     return syncAbleEngine_->RemoteQuery(device, condition, timeout, connectionId, result);
696 }
697 
EraseAllDeviceWatermark(const std::vector<std::string> & tableNameList)698 int SQLiteRelationalStore::EraseAllDeviceWatermark(const std::vector<std::string> &tableNameList)
699 {
700     std::set<std::string> devices;
701     int errCode = GetExistDevices(devices);
702     if (errCode != E_OK) {
703         return errCode;
704     }
705     for (const auto &tableName: tableNameList) {
706         for (const auto &device: devices) {
707             errCode = syncAbleEngine_->EraseDeviceWaterMark(device, false, tableName);
708             if (errCode != E_OK) {
709                 return errCode;
710             }
711         }
712     }
713     return errCode;
714 }
715 
GetDevTableName(const std::string & device,const std::string & hashDev) const716 std::string SQLiteRelationalStore::GetDevTableName(const std::string &device, const std::string &hashDev) const
717 {
718     std::string devTableName;
719     StoreInfo info = {
720         sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::USER_ID, ""),
721         sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::APP_ID, ""),
722         sqliteStorageEngine_->GetProperties().GetStringProp(DBProperties::STORE_ID, "")
723     };
724     if (RuntimeContext::GetInstance()->TranslateDeviceId(device, info, devTableName) != E_OK) {
725         devTableName = hashDev;
726     }
727     return devTableName;
728 }
729 
GetHandleAndStartTransaction(int & errCode) const730 SQLiteSingleVerRelationalStorageExecutor *SQLiteRelationalStore::GetHandleAndStartTransaction(int &errCode) const
731 {
732     auto *handle = GetHandle(true, errCode);
733     if (handle == nullptr) {
734         return nullptr;
735     }
736 
737     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
738     if (errCode != E_OK) {
739         ReleaseHandle(handle);
740         return nullptr;
741     }
742     return handle;
743 }
744 
RemoveDeviceDataInner(const std::string & mappingDev,const std::string & device,const std::string & tableName,bool isNeedHash)745 int SQLiteRelationalStore::RemoveDeviceDataInner(const std::string &mappingDev, const std::string &device,
746     const std::string &tableName, bool isNeedHash)
747 {
748     int errCode = E_OK;
749     auto *handle = GetHandle(true, errCode);
750     if (handle == nullptr) {
751         return errCode;
752     }
753 
754     errCode = handle->StartTransaction(TransactType::IMMEDIATE);
755     if (errCode != E_OK) {
756         ReleaseHandle(handle);
757         return errCode;
758     }
759 
760     std::string hashHexDev;
761     std::string hashDev;
762     std::string devTableName;
763     if (!isNeedHash) {
764         // if is not need hash mappingDev mean hash(uuid) device is param device
765         hashHexDev = DBCommon::TransferStringToHex(mappingDev);
766         hashDev = mappingDev;
767         devTableName = device;
768     } else {
769         // if is need hash mappingDev mean uuid
770         hashDev = DBCommon::TransferHashString(mappingDev);
771         hashHexDev = DBCommon::TransferStringToHex(hashDev);
772         devTableName = GetDevTableName(mappingDev, hashHexDev);
773     }
774     errCode = handle->DeleteDistributedDeviceTable(devTableName, tableName);
775     auto tables = sqliteStorageEngine_->GetSchema().GetTables(); // TableInfoMap
776     if (errCode != E_OK) {
777         LOGE("delete device data failed. %d", errCode);
778         goto END;
779     }
780 
781     for (const auto &it : tables) {
782         if (tableName.empty() || it.second.GetTableName() == tableName) {
783             errCode = handle->DeleteDistributedDeviceTableLog(hashHexDev, it.second.GetTableName());
784             if (errCode != E_OK) {
785                 LOGE("delete device data failed. %d", errCode);
786                 break;
787             }
788         }
789     }
790 
791 END:
792     if (errCode != E_OK) {
793         (void)handle->Rollback();
794         ReleaseHandle(handle);
795         return errCode;
796     }
797     errCode = handle->Commit();
798     ReleaseHandle(handle);
799     storageEngine_->NotifySchemaChanged();
800     return (errCode != E_OK) ? errCode : syncAbleEngine_->EraseDeviceWaterMark(hashDev, false, tableName);
801 }
802 
GetExistDevices(std::set<std::string> & hashDevices)803 int SQLiteRelationalStore::GetExistDevices(std::set<std::string> &hashDevices)
804 {
805     int errCode = E_OK;
806     auto *handle = GetHandle(true, errCode);
807     if (handle == nullptr) {
808         LOGE("[SingleVerRDBStore] GetExistsDeviceList get handle failed:%d", errCode);
809         return errCode;
810     }
811     errCode = handle->GetExistsDeviceList(hashDevices);
812     if (errCode != E_OK) {
813         LOGE("[SingleVerRDBStore] Get remove device list from meta failed. err=%d", errCode);
814     }
815     ReleaseHandle(handle);
816     return errCode;
817 }
818 }
819 #endif