diff --git a/frameworks/libs/distributeddb/BUILD.gn b/frameworks/libs/distributeddb/BUILD.gn index 3d61737f1e0c1bebf4171e69d99b117e3a53c79c..c3255f415b28a2b55e3b8581d6f91a15e995c6e0 100644 --- a/frameworks/libs/distributeddb/BUILD.gn +++ b/frameworks/libs/distributeddb/BUILD.gn @@ -215,6 +215,7 @@ config("distributeddbforrdbclient_config") { "storage/src/sqlite", "storage/src", "storage/src/kv", + "syncer/src", "syncer/src/device", "storage/src/sqlite/relational", diff --git a/frameworks/libs/distributeddb/distributeddb.gni b/frameworks/libs/distributeddb/distributeddb.gni index c204b31c2241fde774f46943f9c6399dcb61672f..a2bc292fc9a3fb5b2baf6fb1f38c4a7c423d588e 100755 --- a/frameworks/libs/distributeddb/distributeddb.gni +++ b/frameworks/libs/distributeddb/distributeddb.gni @@ -261,6 +261,7 @@ distributeddb_src = [ "${distributeddb_path}/syncer/src/sync_config.cpp", "${distributeddb_path}/syncer/src/sync_operation.cpp", "${distributeddb_path}/syncer/src/time_helper.cpp", + "${distributeddb_path}/syncer/src/time_helper_client.cpp", ] distributeddb_cloud_src = [ @@ -336,4 +337,5 @@ distributeddbforrdbclient_src = [ "${distributeddb_path}/storage/src/sqlite/relational/sqlite_relational_utils_client.cpp", "${distributeddb_path}/storage/src/sqlite/sqlite_log_table_manager.cpp", "${distributeddb_path}/storage/src/sqlite/sqlite_utils_client.cpp", + "${distributeddb_path}/syncer/src/time_helper_client.cpp", ] diff --git a/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp b/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp index 766bef40318c86ef6cc52309bd2efa3a832c7105..c94ec912b4b0df3fc679a8f42f74c156bc48e0e6 100644 --- a/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp +++ b/frameworks/libs/distributeddb/interfaces/src/relational/relational_store_sqlite_ext.cpp @@ -1415,7 +1415,7 @@ void ClearTheLogAfterDropTable(sqlite3 *db, const char *tableName, const char *s if (tableType == DEVICE_TYPE) { RegisterGetSysTime(db); RegisterGetLastTime(db); - std::string targetFlag = "flag|0x01"; + std::string targetFlag = "flag|0x03"; std::string originalFlag = "flag&0x01=0x0"; auto tableMode = DistributedTableMode::COLLABORATION; (void)GetTableModeFromMeta(db, tableMode); diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.cpp index 22f7f18dc6841053922a0a77127c86ced54d00b9..99a981751e4ca69f2899581d7c7dba3bee0bc9c1 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.cpp @@ -822,44 +822,4 @@ int SQLiteRelationalUtils::UpdateLocalDataModifyTime(sqlite3 *db, const std::str } return errCode; } - -int SQLiteRelationalUtils::GetMetaLocalTimeOffset(sqlite3 *db, int64_t &timeOffset) -{ - std::string sql = "SELECT value FROM " + DBCommon::GetMetaTableName() + " WHERE key=x'" + - DBCommon::TransferStringToHex(std::string(DBConstant::LOCALTIME_OFFSET_KEY)) + "';"; - sqlite3_stmt *stmt = nullptr; - int errCode = SQLiteUtils::GetStatement(db, sql, stmt); - if (errCode != E_OK) { - return errCode; - } - int ret = E_OK; - errCode = SQLiteUtils::StepWithRetry(stmt); - if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { - timeOffset = static_cast(sqlite3_column_int64(stmt, 0)); - if (timeOffset < 0) { - LOGE("[SQLiteRDBUtils] TimeOffset %" PRId64 "is invalid.", timeOffset); - SQLiteUtils::ResetStatement(stmt, true, ret); - return -E_INTERNAL_ERROR; - } - errCode = E_OK; - } - SQLiteUtils::ResetStatement(stmt, true, ret); - return errCode != E_OK ? errCode : ret; -} - -std::pair SQLiteRelationalUtils::GetCurrentVirtualTime(sqlite3 *db) -{ - int64_t localTimeOffset = 0; - std::pair res; - auto &[errCode, time] = res; - errCode = GetMetaLocalTimeOffset(db, localTimeOffset); - if (errCode != E_OK) { - LOGE("[SQLiteRDBUtils] Failed to get local timeOffset.%d", errCode); - return res; - } - Timestamp currentSysTime = TimeHelper::GetSysCurrentTime(); - Timestamp currentLocalTime = currentSysTime + static_cast(localTimeOffset); - time = std::to_string(currentLocalTime); - return res; -} } // namespace DistributedDB \ No newline at end of file diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.h b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.h index b2bf0f957a4293f613c98f3e69b115b35625f443..b017c2cb35e749860685109e664f1ddf06343068 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.h +++ b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils.h @@ -82,6 +82,9 @@ public: bool isMemory = false; bool isTrackerTable = false; }; + + static int GeneTimeStrForLog(const TableInfo &tableInfo, GenLogParam ¶m, std::string &timeStr); + static int GeneLogInfoForExistedData(const std::string &identity, const TableInfo &tableInfo, std::unique_ptr &logMgrPtr, GenLogParam ¶m); diff --git a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils_client.cpp b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils_client.cpp index 34fd0bb40a13a3d6eb69edb481fcb692a4d2828a..4e9db0e8ff28fdea6172d0331f08e8bbf52e872a 100644 --- a/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils_client.cpp +++ b/frameworks/libs/distributeddb/storage/src/sqlite/relational/sqlite_relational_utils_client.cpp @@ -15,6 +15,7 @@ #include "sqlite_relational_utils.h" #include "db_common.h" +#include "time_helper.h" namespace DistributedDB { int SQLiteRelationalUtils::CreateRelationalMetaTable(sqlite3 *db) @@ -122,8 +123,8 @@ int SQLiteRelationalUtils::GeneLogInfoForExistedData(const std::string &identity std::unique_ptr &logMgrPtr, GenLogParam ¶m) { std::string tableName = tableInfo.GetTableName(); - int64_t timeOffset = 0; - int errCode = GetExistedDataTimeOffset(param.db, tableName, param.isMemory, timeOffset); + std::string timeStr; + int errCode = GeneTimeStrForLog(tableInfo, param, timeStr); if (errCode != E_OK) { return errCode; } @@ -131,7 +132,6 @@ int SQLiteRelationalUtils::GeneLogInfoForExistedData(const std::string &identity if (errCode != E_OK) { return errCode; } - std::string timeOffsetStr = std::to_string(timeOffset); std::string logTable = DBConstant::RELATIONAL_PREFIX + tableName + "_log"; std::string rowid = std::string(DBConstant::SQLITE_INNER_ROWID); std::string flag = std::to_string(static_cast(LogInfoFlag::FLAG_LOCAL) | @@ -140,9 +140,8 @@ int SQLiteRelationalUtils::GeneLogInfoForExistedData(const std::string &identity trackerTable.SetTableName(tableName); const std::string prefix = "a."; std::string calPrimaryKeyHash = logMgrPtr->CalcPrimaryKeyHash(prefix, tableInfo, identity); - std::string sql = "INSERT OR REPLACE INTO " + logTable + " SELECT " + rowid + - ", '', '', " + timeOffsetStr + " + " + rowid + ", " + - timeOffsetStr + " + " + rowid + ", " + flag + ", " + calPrimaryKeyHash + ", '', "; + std::string sql = "INSERT OR REPLACE INTO " + logTable + " SELECT " + rowid + ", '', '', " + timeStr + " + " + + rowid + ", " + timeStr + " + " + rowid + ", " + flag + ", " + calPrimaryKeyHash + ", '', "; sql += GetExtendValue(tableInfo.GetTrackerTable()); sql += ", 0, '', '', 0 FROM '" + tableName + "' AS a "; if (param.isTrackerTable) { @@ -245,4 +244,68 @@ int SQLiteRelationalUtils::AnalysisTrackerTable(sqlite3 *db, const TrackerTable } return errCode; } + +int SQLiteRelationalUtils::GetMetaLocalTimeOffset(sqlite3 *db, int64_t &timeOffset) +{ + std::string sql = "SELECT value FROM " + DBCommon::GetMetaTableName() + " WHERE key=x'" + + DBCommon::TransferStringToHex(std::string(DBConstant::LOCALTIME_OFFSET_KEY)) + "';"; + sqlite3_stmt *stmt = nullptr; + int errCode = SQLiteUtils::GetStatement(db, sql, stmt); + if (errCode != E_OK) { + return errCode; + } + int ret = E_OK; + errCode = SQLiteUtils::StepWithRetry(stmt); + if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_ROW)) { + timeOffset = static_cast(sqlite3_column_int64(stmt, 0)); + if (timeOffset < 0) { + LOGE("[SQLiteRDBUtils] TimeOffset %" PRId64 "is invalid.", timeOffset); + SQLiteUtils::ResetStatement(stmt, true, ret); + return -E_INTERNAL_ERROR; + } + errCode = E_OK; + } else if (errCode == SQLiteUtils::MapSQLiteErrno(SQLITE_DONE)) { + timeOffset = 0; + errCode = E_OK; + } + SQLiteUtils::ResetStatement(stmt, true, ret); + return errCode != E_OK ? errCode : ret; +} + +std::pair SQLiteRelationalUtils::GetCurrentVirtualTime(sqlite3 *db) +{ + int64_t localTimeOffset = 0; + std::pair res; + auto &[errCode, time] = res; + errCode = GetMetaLocalTimeOffset(db, localTimeOffset); + if (errCode != E_OK) { + LOGE("[SQLiteRDBUtils] Failed to get local timeOffset.%d", errCode); + return res; + } + Timestamp currentSysTime = TimeHelper::GetSysCurrentTime(); + Timestamp currentLocalTime = currentSysTime + static_cast(localTimeOffset); + time = std::to_string(currentLocalTime); + return res; +} + +int SQLiteRelationalUtils::GeneTimeStrForLog(const TableInfo &tableInfo, GenLogParam ¶m, std::string &timeStr) +{ + if (tableInfo.GetTableSyncType() == TableSyncType::DEVICE_COOPERATION) { + auto [errCode, time] = GetCurrentVirtualTime(param.db); + if (errCode != E_OK) { + LOGE("Failed to get current virtual time.%d", errCode); + return errCode; + } + timeStr = time; + } else { + int64_t timeOffset = 0; + std::string tableName = tableInfo.GetTableName(); + int errCode = GetExistedDataTimeOffset(param.db, tableName, param.isMemory, timeOffset); + if (errCode != E_OK) { + return errCode; + } + timeStr = std::to_string(timeOffset); + } + return E_OK; +} } // namespace DistributedDB \ No newline at end of file diff --git a/frameworks/libs/distributeddb/syncer/src/time_helper.cpp b/frameworks/libs/distributeddb/syncer/src/time_helper.cpp index f82841dcc5064ed6c07b4849a50a32b1872a59d7..1984d1f2730329e74300d5956fa7746619b579bb 100644 --- a/frameworks/libs/distributeddb/syncer/src/time_helper.cpp +++ b/frameworks/libs/distributeddb/syncer/src/time_helper.cpp @@ -20,33 +20,8 @@ #include "platform_specific.h" namespace DistributedDB { -std::mutex TimeHelper::systemTimeLock_; -Timestamp TimeHelper::lastSystemTimeUs_ = 0; -Timestamp TimeHelper::currentIncCount_ = 0; std::atomic TimeHelper::lastMonotonicTime_ = 0; -Timestamp TimeHelper::GetSysCurrentTime() -{ - uint64_t curTime = 0; - std::lock_guard lock(systemTimeLock_); - int errCode = OS::GetCurrentSysTimeInMicrosecond(curTime); - if (errCode != E_OK) { - return INVALID_TIMESTAMP; - } - - // If GetSysCurrentTime in 1us, we need increase the currentIncCount_ - if (curTime == lastSystemTimeUs_) { - // if the currentIncCount_ has been increased MAX_INC_COUNT, keep the currentIncCount_ - if (currentIncCount_ < MAX_INC_COUNT) { - currentIncCount_++; - } - } else { - lastSystemTimeUs_ = curTime; - currentIncCount_ = 0; - } - return (curTime * TO_100_NS) + currentIncCount_; // Currently Timestamp is uint64_t -} - int TimeHelper::GetSysCurrentRawTime(uint64_t &curTime) { int errCode = OS::GetCurrentSysTimeInMicrosecond(curTime); diff --git a/frameworks/libs/distributeddb/syncer/src/time_helper_client.cpp b/frameworks/libs/distributeddb/syncer/src/time_helper_client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a28246ab4d810de88e49924a97a023e029bad54a --- /dev/null +++ b/frameworks/libs/distributeddb/syncer/src/time_helper_client.cpp @@ -0,0 +1,47 @@ + +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "time_helper.h" + +#include "platform_specific.h" + +namespace DistributedDB { +std::mutex TimeHelper::systemTimeLock_; +Timestamp TimeHelper::lastSystemTimeUs_ = 0; +Timestamp TimeHelper::currentIncCount_ = 0; + +Timestamp TimeHelper::GetSysCurrentTime() +{ + uint64_t curTime = 0; + std::lock_guard lock(systemTimeLock_); + int errCode = OS::GetCurrentSysTimeInMicrosecond(curTime); + if (errCode != E_OK) { + return INVALID_TIMESTAMP; + } + + // If GetSysCurrentTime in 1us, we need increase the currentIncCount_ + if (curTime == lastSystemTimeUs_) { + // if the currentIncCount_ has been increased MAX_INC_COUNT, keep the currentIncCount_ + if (currentIncCount_ < MAX_INC_COUNT) { + currentIncCount_++; + } + } else { + lastSystemTimeUs_ = curTime; + currentIncCount_ = 0; + } + return (curTime * TO_100_NS) + currentIncCount_; // Currently Timestamp is uint64_t +} +} // namespace DistributedDB \ No newline at end of file