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)> ¬ifier)
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 ¬ifier : 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 ¬ifier)
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 ¬ifier)
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