• 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 
16 #include "meta_data.h"
17 
18 #include <openssl/rand.h>
19 
20 #include "db_common.h"
21 #include "db_constant.h"
22 #include "db_errno.h"
23 #include "hash.h"
24 #include "log_print.h"
25 #include "platform_specific.h"
26 #include "securec.h"
27 #include "sync_types.h"
28 #include "time_helper.h"
29 #include "version.h"
30 
31 namespace DistributedDB {
32 namespace {
33     // store local timeoffset;this is a special key;
34     constexpr const char *CLIENT_ID_PREFIX_KEY = "clientId";
35     constexpr const char *LOCAL_META_DATA_KEY = "localMetaData";
36 }
37 
Metadata()38 Metadata::Metadata()
39     : localTimeOffset_(0),
40       naturalStoragePtr_(nullptr),
41       lastLocalTime_(0)
42 {}
43 
~Metadata()44 Metadata::~Metadata()
45 {
46     naturalStoragePtr_ = nullptr;
47 }
48 
Initialize(ISyncInterface * storage)49 int Metadata::Initialize(ISyncInterface* storage)
50 {
51     naturalStoragePtr_ = storage;
52     std::vector<uint8_t> key;
53     std::vector<uint8_t> timeOffset;
54     DBCommon::StringToVector(std::string(DBConstant::LOCALTIME_OFFSET_KEY), key);
55 
56     int errCode = GetMetadataFromDb(key, timeOffset);
57     if (errCode == -E_NOT_FOUND) {
58         int err = SaveLocalTimeOffset(TimeHelper::BASE_OFFSET);
59         if (err != E_OK) {
60             LOGD("[Metadata][Initialize]SaveLocalTimeOffset failed errCode:%d", err);
61             return err;
62         }
63     } else if (errCode == E_OK) {
64         localTimeOffset_ = StringToLong(timeOffset);
65     } else {
66         LOGE("Metadata::Initialize get meatadata from db failed,err=%d", errCode);
67         return errCode;
68     }
69     (void)querySyncWaterMarkHelper_.Initialize(storage);
70     return LoadAllMetadata();
71 }
72 
SaveTimeOffset(const DeviceID & deviceId,const DeviceID & userId,TimeOffset inValue)73 int Metadata::SaveTimeOffset(const DeviceID &deviceId, const DeviceID &userId, TimeOffset inValue)
74 {
75     MetaDataValue metadata;
76     std::lock_guard<std::mutex> lockGuard(metadataLock_);
77     GetMetaDataValue(deviceId, userId, metadata, true);
78     metadata.timeOffset = inValue;
79     metadata.lastUpdateTime = TimeHelper::GetSysCurrentTime();
80     LOGD("Metadata::SaveTimeOffset = %" PRId64 " dev %s", inValue, STR_MASK(deviceId));
81     return SaveMetaDataValue(deviceId, userId, metadata);
82 }
83 
GetTimeOffset(const DeviceID & deviceId,const DeviceID & userId,TimeOffset & outValue)84 void Metadata::GetTimeOffset(const DeviceID &deviceId, const DeviceID &userId, TimeOffset &outValue)
85 {
86     MetaDataValue metadata;
87     std::lock_guard<std::mutex> lockGuard(metadataLock_);
88     GetMetaDataValue(deviceId, userId, metadata, true);
89     outValue = metadata.timeOffset;
90 }
91 
GetLocalWaterMark(const DeviceID & deviceId,const DeviceID & userId,uint64_t & outValue)92 void Metadata::GetLocalWaterMark(const DeviceID &deviceId, const DeviceID &userId, uint64_t &outValue)
93 {
94     MetaDataValue metadata;
95     std::lock_guard<std::mutex> lockGuard(metadataLock_);
96     GetMetaDataValue(deviceId, userId, metadata, true);
97     outValue = metadata.localWaterMark;
98 }
99 
SaveLocalWaterMark(const DeviceID & deviceId,const DeviceID & userId,uint64_t inValue)100 int Metadata::SaveLocalWaterMark(const DeviceID &deviceId, const DeviceID &userId, uint64_t inValue)
101 {
102     MetaDataValue metadata;
103     std::lock_guard<std::mutex> lockGuard(metadataLock_);
104     GetMetaDataValue(deviceId, userId, metadata, true);
105     metadata.localWaterMark = inValue;
106     LOGD("Metadata::SaveLocalWaterMark = %" PRIu64, inValue);
107     return SaveMetaDataValue(deviceId, userId, metadata);
108 }
109 
GetPeerWaterMark(const DeviceID & deviceId,const DeviceID & userId,uint64_t & outValue,bool isNeedHash)110 void Metadata::GetPeerWaterMark(const DeviceID &deviceId, const DeviceID &userId, uint64_t &outValue, bool isNeedHash)
111 {
112     MetaDataValue metadata;
113     std::lock_guard<std::mutex> lockGuard(metadataLock_);
114     GetMetaDataValue(deviceId, userId, metadata, isNeedHash);
115     outValue = metadata.peerWaterMark;
116 }
117 
SavePeerWaterMark(const DeviceID & deviceId,const DeviceID & userId,uint64_t inValue,bool isNeedHash)118 int Metadata::SavePeerWaterMark(const DeviceID &deviceId, const DeviceID &userId, uint64_t inValue, bool isNeedHash)
119 {
120     std::map<Key, MetaDataValue> metadata;
121     std::lock_guard<std::mutex> lockGuard(metadataLock_);
122     int errCode = E_OK;
123     if (!userId.empty()) {
124         MetaDataValue oneMetadata;
125         GetMetaDataValue(deviceId, userId, oneMetadata, isNeedHash);
126         DeviceID hashId;
127         Key key;
128         GetHashDeviceId(deviceId, userId, hashId, isNeedHash);
129         DBCommon::StringToVector(hashId, key);
130         metadata[key] = oneMetadata;
131     } else {
132         errCode = GetMetaDataFromDBByPrefixKey(deviceId, isNeedHash, metadata);
133         if (errCode != E_OK) {
134             return errCode;
135         }
136     }
137 
138     for (auto &oneMetadata : metadata) {
139         oneMetadata.second.peerWaterMark = inValue;
140         LOGD("Metadata::SavePeerWaterMark = %" PRIu64, inValue);
141         Value metadataValue;
142         errCode = SerializeMetaData(oneMetadata.second, metadataValue);
143         if (errCode != E_OK) {
144             return errCode;
145         }
146         errCode = SetMetadataToDb(oneMetadata.first, metadataValue);
147         if (errCode != E_OK) {
148             return errCode;
149         }
150     }
151     return E_OK;
152 }
153 
SaveLocalTimeOffset(TimeOffset timeOffset,bool saveIntoDb)154 int Metadata::SaveLocalTimeOffset(TimeOffset timeOffset, bool saveIntoDb)
155 {
156     std::string timeOffsetString = std::to_string(timeOffset);
157     std::vector<uint8_t> timeOffsetValue(timeOffsetString.begin(), timeOffsetString.end());
158     std::string keyStr(DBConstant::LOCALTIME_OFFSET_KEY);
159     std::vector<uint8_t> localTimeOffsetValue(keyStr.begin(), keyStr.end());
160 
161     std::lock_guard<std::mutex> lockGuard(localTimeOffsetLock_);
162     localTimeOffset_ = timeOffset;
163     LOGI("Metadata::SaveLocalTimeOffset offset = %" PRId64 " save db %d", timeOffset, static_cast<int>(saveIntoDb));
164     if (!saveIntoDb) {
165         return E_OK;
166     }
167     int errCode = SetMetadataToDb(localTimeOffsetValue, timeOffsetValue);
168     if (errCode != E_OK) {
169         LOGE("Metadata::SaveLocalTimeOffset SetMetadataToDb failed errCode:%d", errCode);
170     }
171     return errCode;
172 }
173 
GetLocalTimeOffset() const174 TimeOffset Metadata::GetLocalTimeOffset() const
175 {
176     TimeOffset localTimeOffset = localTimeOffset_.load(std::memory_order_seq_cst);
177     return localTimeOffset;
178 }
179 
EraseDeviceWaterMark(const std::string & deviceId,bool isNeedHash)180 int Metadata::EraseDeviceWaterMark(const std::string &deviceId, bool isNeedHash)
181 {
182     return EraseDeviceWaterMark(deviceId, "", isNeedHash, "");
183 }
184 
EraseDeviceWaterMark(const std::string & deviceId,const std::string & userId,bool isNeedHash,const std::string & tableName)185 int Metadata::EraseDeviceWaterMark(const std::string &deviceId, const std::string &userId, bool isNeedHash,
186     const std::string &tableName)
187 {
188     // reload meta data again
189     (void)LoadAllMetadata();
190     std::lock_guard<std::recursive_mutex> autoLock(waterMarkMutex_);
191     // try to erase all the waterMark
192     // erase deleteSync recv waterMark
193     WaterMark waterMark = 0;
194     int errCodeDeleteSync = SetRecvDeleteSyncWaterMark(deviceId, userId, waterMark, isNeedHash);
195     if (errCodeDeleteSync != E_OK) {
196         LOGE("[Metadata] erase deleteWaterMark failed errCode:%d", errCodeDeleteSync);
197         return errCodeDeleteSync;
198     }
199     // erase querySync recv waterMark
200     int errCodeQuerySync = ResetRecvQueryWaterMark(deviceId, userId, tableName, isNeedHash);
201     if (errCodeQuerySync != E_OK) {
202         LOGE("[Metadata] erase queryWaterMark failed errCode:%d", errCodeQuerySync);
203         return errCodeQuerySync;
204     }
205     // peerWaterMark must be erased at last
206     int errCode = SavePeerWaterMark(deviceId, userId, 0, isNeedHash);
207     if (errCode != E_OK) {
208         LOGE("[Metadata] erase peerWaterMark failed errCode:%d", errCode);
209         return errCode;
210     }
211     return E_OK;
212 }
213 
SetLastLocalTime(Timestamp lastLocalTime)214 void Metadata::SetLastLocalTime(Timestamp lastLocalTime)
215 {
216     std::lock_guard<std::mutex> lock(lastLocalTimeLock_);
217     if (lastLocalTime > lastLocalTime_) {
218         lastLocalTime_ = lastLocalTime;
219     }
220 }
221 
GetLastLocalTime() const222 Timestamp Metadata::GetLastLocalTime() const
223 {
224     std::lock_guard<std::mutex> lock(lastLocalTimeLock_);
225     return lastLocalTime_;
226 }
227 
SaveMetaDataValue(const DeviceID & deviceId,const DeviceID & userId,const MetaDataValue & inValue,bool isNeedHash)228 int Metadata::SaveMetaDataValue(const DeviceID &deviceId, const DeviceID &userId, const MetaDataValue &inValue,
229     bool isNeedHash)
230 {
231     std::vector<uint8_t> value;
232     int errCode = SerializeMetaData(inValue, value);
233     if (errCode != E_OK) {
234         return errCode;
235     }
236 
237     DeviceID hashDeviceId;
238     GetHashDeviceId(deviceId, userId, hashDeviceId, isNeedHash);
239     std::vector<uint8_t> key;
240     DBCommon::StringToVector(hashDeviceId, key);
241     errCode = SetMetadataToDb(key, value);
242     if (errCode != E_OK) {
243         LOGE("Metadata::SetMetadataToDb failed errCode:%d", errCode);
244     }
245     return errCode;
246 }
247 
GetMetaDataValue(const DeviceID & deviceId,const DeviceID & userId,MetaDataValue & outValue,bool isNeedHash)248 int Metadata::GetMetaDataValue(const DeviceID &deviceId, const DeviceID &userId, MetaDataValue &outValue,
249     bool isNeedHash)
250 {
251     int errCode = GetMetaDataValueFromDB(deviceId, userId, isNeedHash, outValue);
252     if (errCode == -E_NOT_FOUND && RuntimeContext::GetInstance()->IsTimeChanged()) {
253         outValue = {};
254         outValue.syncMark = static_cast<uint64_t>(SyncMark::SYNC_MARK_TIME_CHANGE);
255     }
256     return errCode;
257 }
258 
SerializeMetaData(const MetaDataValue & inValue,std::vector<uint8_t> & outValue)259 int Metadata::SerializeMetaData(const MetaDataValue &inValue, std::vector<uint8_t> &outValue)
260 {
261     outValue.resize(sizeof(MetaDataValue));
262     errno_t err = memcpy_s(outValue.data(), outValue.size(), &inValue, sizeof(MetaDataValue));
263     if (err != EOK) {
264         return -E_SECUREC_ERROR;
265     }
266     return E_OK;
267 }
268 
DeSerializeMetaData(const std::vector<uint8_t> & inValue,MetaDataValue & outValue)269 int Metadata::DeSerializeMetaData(const std::vector<uint8_t> &inValue, MetaDataValue &outValue)
270 {
271     if (inValue.empty()) {
272         return -E_INVALID_ARGS;
273     }
274     errno_t err = memcpy_s(&outValue, sizeof(MetaDataValue), inValue.data(), inValue.size());
275     if (err != EOK) {
276         return -E_SECUREC_ERROR;
277     }
278     return E_OK;
279 }
280 
GetMetadataFromDb(const std::vector<uint8_t> & key,std::vector<uint8_t> & outValue) const281 int Metadata::GetMetadataFromDb(const std::vector<uint8_t> &key, std::vector<uint8_t> &outValue) const
282 {
283     if (naturalStoragePtr_ == nullptr) {
284         return -E_INVALID_DB;
285     }
286     return naturalStoragePtr_->GetMetaData(key, outValue);
287 }
288 
GetMetadataFromDbByPrefixKey(const Key & keyPrefix,std::map<Key,Value> & data) const289 int Metadata::GetMetadataFromDbByPrefixKey(const Key &keyPrefix, std::map<Key, Value> &data) const
290 {
291     if (naturalStoragePtr_ == nullptr) {
292         return -E_INVALID_DB;
293     }
294     return naturalStoragePtr_->GetMetaDataByPrefixKey(keyPrefix, data);
295 }
296 
SetMetadataToDb(const std::vector<uint8_t> & key,const std::vector<uint8_t> & inValue)297 int Metadata::SetMetadataToDb(const std::vector<uint8_t> &key, const std::vector<uint8_t> &inValue)
298 {
299     if (naturalStoragePtr_ == nullptr) {
300         return -E_INVALID_DB;
301     }
302     return naturalStoragePtr_->PutMetaData(key, inValue, false);
303 }
304 
StringToLong(const std::vector<uint8_t> & value) const305 int64_t Metadata::StringToLong(const std::vector<uint8_t> &value) const
306 {
307     std::string valueString(value.begin(), value.end());
308     int64_t longData = std::strtoll(valueString.c_str(), nullptr, DBConstant::STR_TO_LL_BY_DEVALUE);
309     if (errno == ERANGE && (longData == LLONG_MAX || longData == LLONG_MIN)) {
310         LOGW("[Metadata][StringToLong] convert string '%s' to number failed, longData = %" PRId64,
311             valueString.c_str(), longData);
312     }
313     LOGD("Metadata::StringToLong longData = %" PRId64, longData);
314     return longData;
315 }
316 
GetAllMetadataKey(std::vector<std::vector<uint8_t>> & keys)317 int Metadata::GetAllMetadataKey(std::vector<std::vector<uint8_t>> &keys)
318 {
319     if (naturalStoragePtr_ == nullptr) {
320         return -E_INVALID_DB;
321     }
322     return naturalStoragePtr_->GetAllMetaKeys(keys);
323 }
324 
325 namespace {
IsMetaDataKey(const Key & inKey,const std::string & expectPrefix)326 bool IsMetaDataKey(const Key &inKey, const std::string &expectPrefix)
327 {
328     if (inKey.size() < expectPrefix.size()) {
329         return false;
330     }
331     std::string prefixInKey(inKey.begin(), inKey.begin() + expectPrefix.size());
332     if (prefixInKey != expectPrefix) {
333         return false;
334     }
335     return true;
336 }
337 }
338 
LoadAllMetadata()339 int Metadata::LoadAllMetadata()
340 {
341     std::vector<std::vector<uint8_t>> metaDataKeys;
342     int errCode = GetAllMetadataKey(metaDataKeys);
343     if (errCode != E_OK) {
344         LOGE("[Metadata] get all metadata key failed err=%d", errCode);
345         return errCode;
346     }
347 
348     std::vector<std::vector<uint8_t>> querySyncIds;
349     for (const auto &deviceId : metaDataKeys) {
350         if (IsMetaDataKey(deviceId, QuerySyncWaterMarkHelper::GetQuerySyncPrefixKey())) {
351             querySyncIds.push_back(deviceId);
352         } else if (IsMetaDataKey(deviceId, QuerySyncWaterMarkHelper::GetDeleteSyncPrefixKey())) {
353             errCode = querySyncWaterMarkHelper_.LoadDeleteSyncDataToCache(deviceId);
354             if (errCode != E_OK) {
355                 return errCode;
356             }
357         }
358     }
359     errCode = querySyncWaterMarkHelper_.RemoveLeastUsedQuerySyncItems(querySyncIds);
360     if (errCode != E_OK) {
361         return errCode;
362     }
363     return InitLocalMetaData();
364 }
365 
GetHashDeviceId(const DeviceID & deviceId,const DeviceID & userId,DeviceID & hashDeviceId,bool isNeedHash)366 void Metadata::GetHashDeviceId(const DeviceID &deviceId, const DeviceID &userId, DeviceID &hashDeviceId,
367     bool isNeedHash)
368 {
369     if (!isNeedHash) {
370         hashDeviceId = DBConstant::DEVICEID_PREFIX_KEY + deviceId + DBConstant::USERID_PREFIX_KEY + userId;
371         return;
372     }
373     DeviceSyncTarget deviceInfo(deviceId, userId);
374     if (deviceIdToHashDeviceIdMap_.count(deviceInfo) == 0) {
375         hashDeviceId = DBConstant::DEVICEID_PREFIX_KEY + DBCommon::TransferHashString(deviceId) +
376             DBConstant::USERID_PREFIX_KEY + userId;
377         deviceIdToHashDeviceIdMap_.insert(std::pair<DeviceSyncTarget, DeviceID>(deviceInfo, hashDeviceId));
378     } else {
379         hashDeviceId = deviceIdToHashDeviceIdMap_[deviceInfo];
380     }
381 }
382 
GetRecvQueryWaterMark(const std::string & queryIdentify,const std::string & deviceId,const std::string & userId,WaterMark & waterMark)383 int Metadata::GetRecvQueryWaterMark(const std::string &queryIdentify,
384     const std::string &deviceId, const std::string &userId, WaterMark &waterMark)
385 {
386     QueryWaterMark queryWaterMark;
387     int errCode = querySyncWaterMarkHelper_.GetQueryWaterMark(queryIdentify, deviceId, userId, queryWaterMark);
388     if (errCode != E_OK) {
389         return errCode;
390     }
391     WaterMark peerWaterMark;
392     GetPeerWaterMark(deviceId, userId, peerWaterMark);
393     waterMark = std::max(queryWaterMark.recvWaterMark, peerWaterMark);
394     return E_OK;
395 }
396 
SetRecvQueryWaterMark(const std::string & queryIdentify,const std::string & deviceId,const std::string & userId,const WaterMark & waterMark)397 int Metadata::SetRecvQueryWaterMark(const std::string &queryIdentify,
398     const std::string &deviceId, const std::string &userId, const WaterMark &waterMark)
399 {
400     return querySyncWaterMarkHelper_.SetRecvQueryWaterMark(queryIdentify, deviceId, userId, waterMark);
401 }
402 
GetSendQueryWaterMark(const std::string & queryIdentify,const std::string & deviceId,const std::string & userId,WaterMark & waterMark,bool isAutoLift)403 int Metadata::GetSendQueryWaterMark(const std::string &queryIdentify,
404     const std::string &deviceId, const std::string &userId, WaterMark &waterMark, bool isAutoLift)
405 {
406     QueryWaterMark queryWaterMark;
407     int errCode = querySyncWaterMarkHelper_.GetQueryWaterMark(queryIdentify, deviceId, userId, queryWaterMark);
408     if (errCode != E_OK) {
409         return errCode;
410     }
411     if (isAutoLift) {
412         WaterMark localWaterMark;
413         GetLocalWaterMark(deviceId, userId, localWaterMark);
414         waterMark = std::max(queryWaterMark.sendWaterMark, localWaterMark);
415     } else {
416         waterMark = queryWaterMark.sendWaterMark;
417     }
418     return E_OK;
419 }
420 
SetSendQueryWaterMark(const std::string & queryIdentify,const std::string & deviceId,const std::string & userId,const WaterMark & waterMark)421 int Metadata::SetSendQueryWaterMark(const std::string &queryIdentify,
422     const std::string &deviceId, const std::string &userId, const WaterMark &waterMark)
423 {
424     return querySyncWaterMarkHelper_.SetSendQueryWaterMark(queryIdentify, deviceId, userId, waterMark);
425 }
426 
GetLastQueryTime(const std::string & queryIdentify,const std::string & deviceId,const std::string & userId,Timestamp & timestamp)427 int Metadata::GetLastQueryTime(const std::string &queryIdentify, const std::string &deviceId, const std::string &userId,
428     Timestamp &timestamp)
429 {
430     QueryWaterMark queryWaterMark;
431     int errCode = querySyncWaterMarkHelper_.GetQueryWaterMark(queryIdentify, deviceId, userId, queryWaterMark);
432     if (errCode != E_OK) {
433         return errCode;
434     }
435     timestamp = queryWaterMark.lastQueryTime;
436     return E_OK;
437 }
438 
SetLastQueryTime(const std::string & queryIdentify,const std::string & deviceId,const std::string & userId,const Timestamp & timestamp)439 int Metadata::SetLastQueryTime(const std::string &queryIdentify, const std::string &deviceId, const std::string &userId,
440     const Timestamp &timestamp)
441 {
442     return querySyncWaterMarkHelper_.SetLastQueryTime(queryIdentify, deviceId, userId, timestamp);
443 }
444 
GetSendDeleteSyncWaterMark(const DeviceID & deviceId,const DeviceID & userId,WaterMark & waterMark,bool isAutoLift)445 int Metadata::GetSendDeleteSyncWaterMark(const DeviceID &deviceId, const DeviceID &userId, WaterMark &waterMark,
446     bool isAutoLift)
447 {
448     DeleteWaterMark deleteWaterMark;
449     int errCode = querySyncWaterMarkHelper_.GetDeleteSyncWaterMark(deviceId, userId, deleteWaterMark);
450     if (errCode != E_OK) {
451         return errCode;
452     }
453     if (isAutoLift) {
454         WaterMark localWaterMark;
455         GetLocalWaterMark(deviceId, userId, localWaterMark);
456         waterMark = std::max(deleteWaterMark.sendWaterMark, localWaterMark);
457     } else {
458         waterMark = deleteWaterMark.sendWaterMark;
459     }
460     return E_OK;
461 }
462 
SetSendDeleteSyncWaterMark(const DeviceID & deviceId,const DeviceID & userId,const WaterMark & waterMark)463 int Metadata::SetSendDeleteSyncWaterMark(const DeviceID &deviceId, const DeviceID &userId, const WaterMark &waterMark)
464 {
465     return querySyncWaterMarkHelper_.SetSendDeleteSyncWaterMark(deviceId, userId, waterMark);
466 }
467 
GetRecvDeleteSyncWaterMark(const DeviceID & deviceId,const DeviceID & userId,WaterMark & waterMark)468 int Metadata::GetRecvDeleteSyncWaterMark(const DeviceID &deviceId, const DeviceID &userId, WaterMark &waterMark)
469 {
470     DeleteWaterMark deleteWaterMark;
471     int errCode = querySyncWaterMarkHelper_.GetDeleteSyncWaterMark(deviceId, userId, deleteWaterMark);
472     if (errCode != E_OK) {
473         return errCode;
474     }
475     WaterMark peerWaterMark;
476     GetPeerWaterMark(deviceId, userId, peerWaterMark);
477     waterMark = std::max(deleteWaterMark.recvWaterMark, peerWaterMark);
478     return E_OK;
479 }
480 
SetRecvDeleteSyncWaterMark(const DeviceID & deviceId,const DeviceID & userId,const WaterMark & waterMark,bool isNeedHash)481 int Metadata::SetRecvDeleteSyncWaterMark(const DeviceID &deviceId, const DeviceID &userId, const WaterMark &waterMark,
482     bool isNeedHash)
483 {
484     return querySyncWaterMarkHelper_.SetRecvDeleteSyncWaterMark(deviceId, userId, waterMark, isNeedHash);
485 }
486 
ResetRecvQueryWaterMark(const DeviceID & deviceId,const DeviceID & userId,const std::string & tableName,bool isNeedHash)487 int Metadata::ResetRecvQueryWaterMark(const DeviceID &deviceId, const DeviceID &userId, const std::string &tableName,
488     bool isNeedHash)
489 {
490     return querySyncWaterMarkHelper_.ResetRecvQueryWaterMark(deviceId, userId, tableName, isNeedHash);
491 }
492 
GetDbCreateTime(const DeviceID & deviceId,const DeviceID & userId,uint64_t & outValue)493 void Metadata::GetDbCreateTime(const DeviceID &deviceId, const DeviceID &userId, uint64_t &outValue)
494 {
495     std::lock_guard<std::mutex> lockGuard(metadataLock_);
496     MetaDataValue metadata;
497     int errCode = GetMetaDataValue(deviceId, userId, metadata, true);
498     if (errCode == E_OK) {
499         outValue = metadata.dbCreateTime;
500         return;
501     }
502     outValue = 0;
503     LOGI("Metadata::GetDbCreateTime, not found dev = %s dbCreateTime", STR_MASK(deviceId));
504 }
505 
SetDbCreateTime(const DeviceID & deviceId,const DeviceID & userId,uint64_t inValue,bool isNeedHash)506 int Metadata::SetDbCreateTime(const DeviceID &deviceId, const DeviceID &userId, uint64_t inValue, bool isNeedHash)
507 {
508     std::lock_guard<std::mutex> lockGuard(metadataLock_);
509     MetaDataValue metadata;
510     int errCode = GetMetaDataValue(deviceId, userId, metadata, isNeedHash);
511     if (errCode == E_OK) {
512         if (metadata.dbCreateTime != 0 && metadata.dbCreateTime != inValue) {
513             metadata.clearDeviceDataMark = REMOVE_DEVICE_DATA_MARK;
514             LOGI("Metadata::SetDbCreateTime,set clear data mark,dev=%s,dbCreateTime=%" PRIu64,
515                 STR_MASK(deviceId), inValue);
516         }
517         if (metadata.dbCreateTime == 0) {
518             LOGI("Metadata::SetDbCreateTime,update dev=%s,dbCreateTime=%" PRIu64, STR_MASK(deviceId), inValue);
519         }
520     } else if (errCode != -E_NOT_FOUND) {
521         return errCode;
522     }
523 
524     metadata.dbCreateTime = inValue;
525     return SaveMetaDataValue(deviceId, userId, metadata, isNeedHash);
526 }
527 
ResetMetaDataAfterRemoveData(const DeviceID & deviceId,const DeviceID & userId)528 int Metadata::ResetMetaDataAfterRemoveData(const DeviceID &deviceId, const DeviceID &userId)
529 {
530     std::lock_guard<std::mutex> lockGuard(metadataLock_);
531     MetaDataValue metadata;
532     int errCode = GetMetaDataValue(deviceId, userId, metadata, true);
533     if (errCode == E_OK) {
534         metadata.clearDeviceDataMark = 0;
535         return SaveMetaDataValue(deviceId, userId, metadata, true);
536     }
537     return errCode;
538 }
539 
GetRemoveDataMark(const DeviceID & deviceId,const DeviceID & userId,uint64_t & outValue)540 void Metadata::GetRemoveDataMark(const DeviceID &deviceId, const DeviceID &userId, uint64_t &outValue)
541 {
542     std::lock_guard<std::mutex> lockGuard(metadataLock_);
543     MetaDataValue metadata;
544     int errCode = GetMetaDataValue(deviceId, userId, metadata, true);
545     if (errCode == E_OK) {
546         outValue = metadata.clearDeviceDataMark;
547         return;
548     }
549     outValue = 0;
550 }
551 
GetQueryLastTimestamp(const DeviceID & deviceId,const std::string & queryId) const552 uint64_t Metadata::GetQueryLastTimestamp(const DeviceID &deviceId, const std::string &queryId) const
553 {
554     std::vector<uint8_t> key;
555     std::vector<uint8_t> value;
556     std::string hashqueryId = DBConstant::SUBSCRIBE_QUERY_PREFIX + DBCommon::TransferHashString(queryId);
557     DBCommon::StringToVector(hashqueryId, key);
558     int errCode = GetMetadataFromDb(key, value);
559     std::lock_guard<std::mutex> lockGuard(metadataLock_);
560     if (errCode == -E_NOT_FOUND) {
561         auto iter = queryIdMap_.find(deviceId);
562         if (iter != queryIdMap_.end()) {
563             if (iter->second.find(hashqueryId) == iter->second.end()) {
564                 iter->second.insert(hashqueryId);
565                 return INT64_MAX;
566             }
567             return 0;
568         } else {
569             queryIdMap_[deviceId] = { hashqueryId };
570             return INT64_MAX;
571         }
572     }
573     auto iter = queryIdMap_.find(deviceId);
574     // while value is found in db, it can be found in db later when db is not closed
575     // so no need to record the hashqueryId in map
576     if (errCode == E_OK && iter != queryIdMap_.end()) {
577         iter->second.erase(hashqueryId);
578     }
579     return static_cast<uint64_t>(StringToLong(value));
580 }
581 
RemoveQueryFromRecordSet(const DeviceID & deviceId,const std::string & queryId)582 void Metadata::RemoveQueryFromRecordSet(const DeviceID &deviceId, const std::string &queryId)
583 {
584     std::lock_guard<std::mutex> lockGuard(metadataLock_);
585     std::string hashqueryId = DBConstant::SUBSCRIBE_QUERY_PREFIX + DBCommon::TransferHashString(queryId);
586     auto iter = queryIdMap_.find(deviceId);
587     if (iter != queryIdMap_.end() && iter->second.find(hashqueryId) != iter->second.end()) {
588         iter->second.erase(hashqueryId);
589     }
590 }
591 
SaveClientId(const std::string & deviceId,const std::string & clientId)592 int Metadata::SaveClientId(const std::string &deviceId, const std::string &clientId)
593 {
594     {
595         // already save in cache
596         std::lock_guard<std::mutex> autoLock(clientIdLock_);
597         if (clientIdCache_[deviceId] == clientId) {
598             return E_OK;
599         }
600     }
601     std::string keyStr;
602     keyStr.append(CLIENT_ID_PREFIX_KEY).append(clientId);
603     std::string valueStr = DBCommon::TransferHashString(deviceId);
604     Key key;
605     DBCommon::StringToVector(keyStr, key);
606     Value value;
607     DBCommon::StringToVector(valueStr, value);
608     int errCode = SetMetadataToDb(key, value);
609     if (errCode != E_OK) {
610         return errCode;
611     }
612     std::lock_guard<std::mutex> autoLock(clientIdLock_);
613     clientIdCache_[deviceId] = clientId;
614     return E_OK;
615 }
616 
GetHashDeviceId(const std::string & clientId,std::string & hashDevId) const617 int Metadata::GetHashDeviceId(const std::string &clientId, std::string &hashDevId) const
618 {
619     // don't use cache here avoid invalid cache
620     std::string keyStr;
621     keyStr.append(CLIENT_ID_PREFIX_KEY).append(clientId);
622     Key key;
623     DBCommon::StringToVector(keyStr, key);
624     Value value;
625     int errCode = GetMetadataFromDb(key, value);
626     if (errCode == -E_NOT_FOUND) {
627         LOGD("[Metadata] not found clientId by %.3s", clientId.c_str());
628         return -E_NOT_SUPPORT;
629     }
630     if (errCode != E_OK) {
631         LOGE("[Metadata] reload clientId failed %d", errCode);
632         return errCode;
633     }
634     DBCommon::VectorToString(value, hashDevId);
635     return E_OK;
636 }
637 
LockWaterMark() const638 void Metadata::LockWaterMark() const
639 {
640     waterMarkMutex_.lock();
641 }
642 
UnlockWaterMark() const643 void Metadata::UnlockWaterMark() const
644 {
645     waterMarkMutex_.unlock();
646 }
647 
GetWaterMarkInfoFromDB(const std::string & dev,const std::string & userId,bool isNeedHash,WatermarkInfo & info)648 int Metadata::GetWaterMarkInfoFromDB(const std::string &dev, const std::string &userId, bool isNeedHash,
649     WatermarkInfo &info)
650 {
651     // read from db avoid watermark update in diff process
652     std::lock_guard<std::mutex> lockGuard(metadataLock_);
653     MetaDataValue metadata;
654     int errCode = GetMetaDataValue(dev, userId, metadata, isNeedHash);
655     if (errCode == -E_NOT_FOUND) {
656         LOGD("[Metadata] not found meta value");
657         return E_OK;
658     }
659     if (errCode != E_OK) {
660         LOGE("[Metadata] reload meta value failed %d", errCode);
661         return errCode;
662     }
663 
664     info.sendMark = metadata.localWaterMark;
665     info.receiveMark = metadata.peerWaterMark;
666     return E_OK;
667 }
668 
ClearAllAbilitySyncFinishMark()669 int Metadata::ClearAllAbilitySyncFinishMark()
670 {
671     return ClearAllMetaDataValue(static_cast<uint32_t>(MetaValueAction::CLEAR_ABILITY_SYNC_MARK) |
672         static_cast<uint32_t>(MetaValueAction::CLEAR_REMOTE_SCHEMA_VERSION));
673 }
674 
ClearAllTimeSyncFinishMark()675 int Metadata::ClearAllTimeSyncFinishMark()
676 {
677     return ClearAllMetaDataValue(static_cast<uint32_t>(MetaValueAction::CLEAR_TIME_SYNC_MARK) |
678         static_cast<uint32_t>(MetaValueAction::CLEAR_SYSTEM_TIME_OFFSET) |
679         static_cast<uint32_t>(MetaValueAction::SET_TIME_CHANGE_MARK));
680 }
681 
ClearAllMetaDataValue(uint32_t innerClearAction)682 int Metadata::ClearAllMetaDataValue(uint32_t innerClearAction)
683 {
684     std::vector<std::vector<uint8_t>> metaDataKeys;
685     int errCode = GetAllMetadataKey(metaDataKeys);
686     if (errCode != E_OK) {
687         LOGE("[Metadata][ClearAllMetaDataValue] get all metadata key failed err=%d", errCode);
688         return errCode;
689     }
690 
691     std::lock_guard<std::mutex> lockGuard(metadataLock_);
692     for (const auto &deviceId : metaDataKeys) {
693         if (!IsMetaDataKey(deviceId, DBConstant::DEVICEID_PREFIX_KEY)) {
694             continue;
695         }
696         MetaDataValue metaData;
697         int innerErrCode = GetMetaDataValueFromDB(deviceId, metaData);
698         if (innerErrCode != E_OK) {
699             LOGW("[Metadata][ClearAllMetaDataValue] action %" PRIu32 " get meta data failed %d", innerClearAction,
700                 innerErrCode);
701             errCode = errCode == E_OK ? innerErrCode : errCode;
702             continue;
703         }
704         ClearMetaDataValue(innerClearAction, metaData);
705         std::vector<uint8_t> value;
706         innerErrCode = SerializeMetaData(metaData, value);
707         // clear sync mark without transaction here
708         // just ignore error metadata value
709         if (innerErrCode != E_OK) {
710             LOGW("[Metadata][ClearAllMetaDataValue] action %" PRIu32 " serialize meta data failed %d", innerClearAction,
711                 innerErrCode);
712             errCode = errCode == E_OK ? innerErrCode : errCode;
713             continue;
714         }
715 
716         innerErrCode = SetMetadataToDb(deviceId, value);
717         if (innerErrCode != E_OK) {
718             LOGW("[Metadata][ClearAllMetaDataValue] action %" PRIu32 " save meta data failed %d", innerClearAction,
719                 innerErrCode);
720             errCode = errCode == E_OK ? innerErrCode : errCode;
721         }
722     }
723     if (errCode == E_OK) {
724         LOGD("[Metadata][ClearAllMetaDataValue] success clear action %" PRIu32, innerClearAction);
725     }
726     return errCode;
727 }
728 
ClearMetaDataValue(uint32_t innerClearAction,MetaDataValue & metaDataValue)729 void Metadata::ClearMetaDataValue(uint32_t innerClearAction, MetaDataValue &metaDataValue)
730 {
731     auto mark = static_cast<uint32_t>(MetaValueAction::CLEAR_ABILITY_SYNC_MARK);
732     if ((innerClearAction & mark) == mark) {
733         metaDataValue.syncMark =
734             DBCommon::EraseBit(metaDataValue.syncMark, static_cast<uint64_t>(SyncMark::SYNC_MARK_ABILITY_SYNC));
735     }
736     mark = static_cast<uint32_t>(MetaValueAction::CLEAR_TIME_SYNC_MARK);
737     if ((innerClearAction & mark) == mark) {
738         metaDataValue.syncMark =
739             DBCommon::EraseBit(metaDataValue.syncMark, static_cast<uint64_t>(SyncMark::SYNC_MARK_TIME_SYNC));
740     }
741     mark = static_cast<uint32_t>(MetaValueAction::CLEAR_REMOTE_SCHEMA_VERSION);
742     if ((innerClearAction & mark) == mark) {
743         metaDataValue.remoteSchemaVersion = 0;
744     }
745     mark = static_cast<uint32_t>(MetaValueAction::CLEAR_SYSTEM_TIME_OFFSET);
746     if ((innerClearAction & mark) == mark) {
747         metaDataValue.systemTimeOffset = 0;
748     }
749     mark = static_cast<uint32_t>(MetaValueAction::SET_TIME_CHANGE_MARK);
750     if ((innerClearAction & mark) == mark) {
751         metaDataValue.syncMark |= static_cast<uint64_t>(SyncMark::SYNC_MARK_TIME_CHANGE);
752     }
753 }
754 
SetAbilitySyncFinishMark(const std::string & deviceId,const std::string & userId,bool finish)755 int Metadata::SetAbilitySyncFinishMark(const std::string &deviceId, const std::string &userId, bool finish)
756 {
757     return SetSyncMark(deviceId, userId, SyncMark::SYNC_MARK_ABILITY_SYNC, finish);
758 }
759 
IsAbilitySyncFinish(const std::string & deviceId,const std::string & userId)760 bool Metadata::IsAbilitySyncFinish(const std::string &deviceId, const std::string &userId)
761 {
762     return IsContainSyncMark(deviceId, userId, SyncMark::SYNC_MARK_ABILITY_SYNC);
763 }
764 
SetTimeSyncFinishMark(const std::string & deviceId,const std::string & userId,bool finish)765 int Metadata::SetTimeSyncFinishMark(const std::string &deviceId, const std::string &userId, bool finish)
766 {
767     return SetSyncMark(deviceId, userId, SyncMark::SYNC_MARK_TIME_SYNC, finish);
768 }
769 
SetTimeChangeMark(const std::string & deviceId,const std::string & userId,bool change)770 int Metadata::SetTimeChangeMark(const std::string &deviceId, const std::string &userId, bool change)
771 {
772     return SetSyncMark(deviceId, userId, SyncMark::SYNC_MARK_TIME_CHANGE, change);
773 }
774 
IsTimeSyncFinish(const std::string & deviceId,const std::string & userId)775 bool Metadata::IsTimeSyncFinish(const std::string &deviceId, const std::string &userId)
776 {
777     return IsContainSyncMark(deviceId, userId, SyncMark::SYNC_MARK_TIME_SYNC);
778 }
779 
IsTimeChange(const std::string & deviceId,const std::string & userId)780 bool Metadata::IsTimeChange(const std::string &deviceId, const std::string &userId)
781 {
782     return IsContainSyncMark(deviceId, userId, SyncMark::SYNC_MARK_TIME_CHANGE);
783 }
784 
SetSyncMark(const std::string & deviceId,const std::string & userId,SyncMark syncMark,bool finish)785 int Metadata::SetSyncMark(const std::string &deviceId, const std::string &userId, SyncMark syncMark, bool finish)
786 {
787     MetaDataValue metadata;
788     std::lock_guard<std::mutex> lockGuard(metadataLock_);
789     GetMetaDataValue(deviceId, userId, metadata, true);
790     auto mark = static_cast<uint64_t>(syncMark);
791     if (finish) {
792         metadata.syncMark |= mark;
793     } else {
794         metadata.syncMark = DBCommon::EraseBit(metadata.syncMark, mark);
795     }
796     LOGD("[Metadata] Mark:%" PRIx64 " sync finish:%d sync mark:%" PRIu64, mark, static_cast<int>(finish),
797         metadata.syncMark);
798     return SaveMetaDataValue(deviceId, userId, metadata);
799 }
800 
IsContainSyncMark(const std::string & deviceId,const std::string & userId,SyncMark syncMark)801 bool Metadata::IsContainSyncMark(const std::string &deviceId, const std::string &userId, SyncMark syncMark)
802 {
803     MetaDataValue metadata;
804     std::lock_guard<std::mutex> lockGuard(metadataLock_);
805     GetMetaDataValue(deviceId, userId, metadata, true);
806     auto mark = static_cast<uint64_t>(syncMark);
807     return (metadata.syncMark & mark) == mark;
808 }
809 
SetRemoteSchemaVersion(const std::string & deviceId,const std::string & userId,uint64_t schemaVersion)810 int Metadata::SetRemoteSchemaVersion(const std::string &deviceId, const std::string &userId, uint64_t schemaVersion)
811 {
812     MetaDataValue metadata;
813     std::lock_guard<std::mutex> lockGuard(metadataLock_);
814     GetMetaDataValue(deviceId, userId, metadata, true);
815     metadata.remoteSchemaVersion = schemaVersion;
816     LOGI("[Metadata] Set %.3s schema version %" PRIu64, deviceId.c_str(), schemaVersion);
817     int errCode = SaveMetaDataValue(deviceId, userId, metadata);
818     if (errCode != E_OK) {
819         LOGW("[Metadata] Set remote schema version failed");
820     }
821     return errCode;
822 }
823 
GetRemoteSchemaVersion(const std::string & deviceId,const std::string & userId)824 uint64_t Metadata::GetRemoteSchemaVersion(const std::string &deviceId, const std::string &userId)
825 {
826     MetaDataValue metadata;
827     std::lock_guard<std::mutex> lockGuard(metadataLock_);
828     GetMetaDataValue(deviceId, userId, metadata, true);
829     LOGI("[Metadata] Get %.3s schema version %" PRIu64, deviceId.c_str(), metadata.remoteSchemaVersion);
830     return metadata.remoteSchemaVersion;
831 }
832 
SetSystemTimeOffset(const std::string & deviceId,const std::string & userId,int64_t systemTimeOffset)833 int Metadata::SetSystemTimeOffset(const std::string &deviceId, const std::string &userId, int64_t systemTimeOffset)
834 {
835     MetaDataValue metadata;
836     std::lock_guard<std::mutex> lockGuard(metadataLock_);
837     GetMetaDataValue(deviceId, userId, metadata, true);
838     metadata.systemTimeOffset = systemTimeOffset;
839     LOGI("[Metadata] Set %.3s systemTimeOffset %" PRId64, deviceId.c_str(), systemTimeOffset);
840     return SaveMetaDataValue(deviceId, userId, metadata);
841 }
842 
GetSystemTimeOffset(const std::string & deviceId,const std::string & userId)843 int64_t Metadata::GetSystemTimeOffset(const std::string &deviceId, const std::string &userId)
844 {
845     MetaDataValue metadata;
846     std::lock_guard<std::mutex> lockGuard(metadataLock_);
847     GetMetaDataValue(deviceId, userId, metadata, true);
848     LOGI("[Metadata] Get %.3s systemTimeOffset %" PRId64, deviceId.c_str(), metadata.systemTimeOffset);
849     return metadata.systemTimeOffset;
850 }
851 
GetLocalSchemaVersion()852 std::pair<int, uint64_t> Metadata::GetLocalSchemaVersion()
853 {
854     std::lock_guard<std::mutex> autoLock(localMetaDataMutex_);
855     auto [errCode, localMetaData] = GetLocalMetaData();
856     if (errCode != E_OK) {
857         return {errCode, 0};
858     }
859     LOGI("[Metadata] Get local schema version %" PRIu64, localMetaData.localSchemaVersion);
860     return {errCode, localMetaData.localSchemaVersion};
861 }
862 
SetLocalSchemaVersion(uint64_t schemaVersion)863 int Metadata::SetLocalSchemaVersion(uint64_t schemaVersion)
864 {
865     std::lock_guard<std::mutex> autoLock(localMetaDataMutex_);
866     auto [errCode, localMetaData] = GetLocalMetaData();
867     if (errCode != E_OK) {
868         return errCode;
869     }
870     localMetaData.localSchemaVersion = schemaVersion;
871     LOGI("[Metadata] Set local schema version %" PRIu64, schemaVersion);
872     return SaveLocalMetaData(localMetaData);
873 }
874 
SaveLocalMetaData(const LocalMetaData & localMetaData)875 int Metadata::SaveLocalMetaData(const LocalMetaData &localMetaData)
876 {
877     auto [errCode, value] = SerializeLocalMetaData(localMetaData);
878     if (errCode != E_OK) {
879         LOGE("[Metadata] Serialize local meta data failed %d", errCode);
880         return errCode;
881     }
882     std::string k(LOCAL_META_DATA_KEY);
883     Key key(k.begin(), k.end());
884     return SetMetadataToDb(key, value);
885 }
886 
GetLocalMetaData()887 std::pair<int, LocalMetaData> Metadata::GetLocalMetaData()
888 {
889     std::string k(LOCAL_META_DATA_KEY);
890     Key key(k.begin(), k.end());
891     Value value;
892     int errCode = GetMetadataFromDb(key, value);
893     if (errCode != E_OK && errCode != -E_NOT_FOUND) {
894         return {errCode, {}};
895     }
896     return DeSerializeLocalMetaData(value);
897 }
898 
SerializeLocalMetaData(const LocalMetaData & localMetaData)899 std::pair<int, Value> Metadata::SerializeLocalMetaData(const LocalMetaData &localMetaData)
900 {
901     std::pair<int, Value> res = {E_OK, {}};
902     auto &[errCode, value] = res;
903     value.resize(CalculateLocalMetaDataLength());
904     Parcel parcel(value.data(), value.size());
905     (void)parcel.WriteUInt32(localMetaData.version);
906     parcel.EightByteAlign();
907     (void)parcel.WriteUInt64(localMetaData.localSchemaVersion);
908     if (parcel.IsError()) {
909         LOGE("[Metadata] Serialize localMetaData failed");
910         errCode = -E_SERIALIZE_ERROR;
911         value.clear();
912         return res;
913     }
914     return res;
915 }
916 
DeSerializeLocalMetaData(const Value & value)917 std::pair<int, LocalMetaData> Metadata::DeSerializeLocalMetaData(const Value &value)
918 {
919     std::pair<int, LocalMetaData> res;
920     auto &[errCode, meta] = res;
921     if (value.empty()) {
922         errCode = E_OK;
923         return res;
924     }
925     Parcel parcel(const_cast<uint8_t *>(value.data()), value.size());
926     parcel.ReadUInt32(meta.version);
927     if (meta.version >= LOCAL_META_DATA_VERSION_V2) {
928         parcel.EightByteAlign();
929     }
930     parcel.ReadUInt64(meta.localSchemaVersion);
931     if (parcel.IsError()) {
932         LOGE("[Metadata] DeSerialize localMetaData failed");
933         errCode = -E_SERIALIZE_ERROR;
934         return res;
935     }
936     return res;
937 }
938 
CalculateLocalMetaDataLength()939 uint64_t Metadata::CalculateLocalMetaDataLength()
940 {
941     uint64_t length = Parcel::GetUInt32Len(); // version
942     length = Parcel::GetEightByteAlign(length);
943     length += Parcel::GetUInt64Len(); // local schema version
944     return length;
945 }
946 
MetaWaterMarkAutoLock(std::shared_ptr<Metadata> metadata)947 Metadata::MetaWaterMarkAutoLock::MetaWaterMarkAutoLock(std::shared_ptr<Metadata> metadata)
948     : metadataPtr_(std::move(metadata))
949 {
950     if (metadataPtr_ != nullptr) {
951         metadataPtr_->LockWaterMark();
952     }
953 }
954 
~MetaWaterMarkAutoLock()955 Metadata::MetaWaterMarkAutoLock::~MetaWaterMarkAutoLock()
956 {
957     if (metadataPtr_ != nullptr) {
958         metadataPtr_->UnlockWaterMark();
959     }
960 }
961 
InitLocalMetaData()962 int Metadata::InitLocalMetaData()
963 {
964     std::lock_guard<std::mutex> autoLock(localMetaDataMutex_);
965     auto [errCode, localMetaData] = GetLocalMetaData();
966     if (errCode != E_OK) {
967         return errCode;
968     }
969     if (localMetaData.localSchemaVersion != 0) {
970         return E_OK;
971     }
972     uint64_t curTime = 0u;
973     errCode = OS::GetCurrentSysTimeInMicrosecond(curTime);
974     if (errCode != E_OK) {
975         LOGW("[Metadata] get system time failed when init schema version!");
976         localMetaData.localSchemaVersion += 1;
977     } else {
978         localMetaData.localSchemaVersion = curTime;
979     }
980     errCode = SaveLocalMetaData(localMetaData);
981     if (errCode != E_OK) {
982         LOGE("[Metadata] init local schema version failed:%d", errCode);
983     }
984     return errCode;
985 }
986 
GetMetaDataValueFromDB(const std::string & deviceId,const std::string & userId,bool isNeedHash,MetaDataValue & metaDataValue)987 int Metadata::GetMetaDataValueFromDB(const std::string &deviceId, const std::string &userId, bool isNeedHash,
988     MetaDataValue &metaDataValue)
989 {
990     DeviceID hashDeviceId;
991     Key devKey;
992     GetHashDeviceId(deviceId, userId, hashDeviceId, isNeedHash);
993     DBCommon::StringToVector(hashDeviceId, devKey);
994 
995     return GetMetaDataValueFromDB(devKey, metaDataValue);
996 }
997 
GetMetaDataValueFromDB(const Key & key,MetaDataValue & metaDataValue)998 int Metadata::GetMetaDataValueFromDB(const Key &key, MetaDataValue &metaDataValue)
999 {
1000     std::vector<uint8_t> value;
1001     int errCode = GetMetadataFromDb(key, value);
1002     if (errCode != E_OK) {
1003         LOGE("[Metadata] Get metadata from db failed %d", errCode);
1004         return errCode;
1005     }
1006     return DeSerializeMetaData(value, metaDataValue);
1007 }
1008 
GetMetaDataFromDBByPrefixKey(const std::string & deviceId,bool isNeedHash,std::map<Key,MetaDataValue> & metaData)1009 int Metadata::GetMetaDataFromDBByPrefixKey(const std::string &deviceId, bool isNeedHash,
1010     std::map<Key, MetaDataValue> &metaData)
1011 {
1012     DeviceID hashId;
1013     Key keyPrefix;
1014     GetHashDeviceId(deviceId, "", hashId, isNeedHash);
1015     DBCommon::StringToVector(hashId, keyPrefix);
1016 
1017     std::map<Key, Value> data;
1018     int errCode = GetMetadataFromDbByPrefixKey(keyPrefix, data);
1019     if (errCode != E_OK) {
1020         if (errCode == -E_NOT_FOUND) {
1021             MetaDataValue oneMetaData;
1022             metaData[keyPrefix] = oneMetaData;
1023             return E_OK;
1024         }
1025         LOGE("[Metadata] Get metadata from db by prefix key failed %d", errCode);
1026         return errCode;
1027     }
1028     for (const auto &oneData : data) {
1029         MetaDataValue metaDataValue;
1030         errCode = DeSerializeMetaData(oneData.second, metaDataValue);
1031         if (errCode != E_OK) {
1032             LOGE("[Metadata] DeSerialize meta data failed %d", errCode);
1033             return errCode;
1034         }
1035         metaData[oneData.first] = metaDataValue;
1036     }
1037     return E_OK;
1038 }
1039 
GetRemoteSoftwareVersion(const std::string & deviceId,const std::string & userId)1040 uint64_t Metadata::GetRemoteSoftwareVersion(const std::string &deviceId, const std::string &userId)
1041 {
1042     MetaDataValue metadata;
1043     std::lock_guard<std::mutex> lockGuard(metadataLock_);
1044     GetMetaDataValue(deviceId, userId, metadata, true);
1045     return metadata.remoteSoftwareVersion;
1046 }
1047 
SetRemoteSoftwareVersion(const std::string & deviceId,const std::string & userId,uint64_t version)1048 int Metadata::SetRemoteSoftwareVersion(const std::string &deviceId, const std::string &userId, uint64_t version)
1049 {
1050     MetaDataValue metadata;
1051     std::lock_guard<std::mutex> lockGuard(metadataLock_);
1052     GetMetaDataValue(deviceId, userId, metadata, true);
1053     metadata.remoteSoftwareVersion = version;
1054     LOGI("[Metadata] Set %.3s version %" PRId64, deviceId.c_str(), version);
1055     return SaveMetaDataValue(deviceId, userId, metadata);
1056 }
1057 }  // namespace DistributedDB