diff --git a/services/backup/src/DatabaseEntities/BackupItem.cpp b/services/backup/src/DatabaseEntities/BackupItem.cpp index 8dad9fb8e..c7401b029 100644 --- a/services/backup/src/DatabaseEntities/BackupItem.cpp +++ b/services/backup/src/DatabaseEntities/BackupItem.cpp @@ -1,122 +1,122 @@ #include "BackupItem.h" #include "Constants.h" #include "Tools.h" namespace comm { namespace network { namespace database { const std::string BackupItem::FIELD_USER_ID = "userID"; const std::string BackupItem::FIELD_BACKUP_ID = "backupID"; const std::string BackupItem::FIELD_CREATED = "created"; const std::string BackupItem::FIELD_RECOVERY_DATA = "recoveryData"; const std::string BackupItem::FIELD_COMPACTION_HOLDER = "compactionHolder"; const std::string BackupItem::FIELD_ATTACHMENT_HOLDERS = "attachmentHolders"; -std::string BackupItem::tableName = BACKUP_TABLE_NAME; +const std::string BackupItem::TABLE_NAME = BACKUP_TABLE_NAME; BackupItem::BackupItem( std::string userID, std::string backupID, uint64_t created, std::string recoveryData, std::string compactionHolder, std::string attachmentHolders) : userID(userID), backupID(backupID), created(created), recoveryData(recoveryData), compactionHolder(compactionHolder), attachmentHolders(attachmentHolders) { this->validate(); } BackupItem::BackupItem(const AttributeValues &itemFromDB) { this->assignItemFromDatabase(itemFromDB); } void BackupItem::validate() const { if (!this->userID.size()) { throw std::runtime_error("userID empty"); } if (!this->backupID.size()) { throw std::runtime_error("backupID empty"); } if (!this->created) { throw std::runtime_error("created not provided"); } if (!this->recoveryData.size()) { throw std::runtime_error("recoveryData empty"); } } void BackupItem::assignItemFromDatabase(const AttributeValues &itemFromDB) { try { this->userID = itemFromDB.at(BackupItem::FIELD_USER_ID).GetS(); this->backupID = itemFromDB.at(BackupItem::FIELD_BACKUP_ID).GetS(); this->created = std::stoll( std::string(itemFromDB.at(BackupItem::FIELD_CREATED).GetS()).c_str()); this->recoveryData = itemFromDB.at(BackupItem::FIELD_RECOVERY_DATA).GetS(); auto compactionHolder = itemFromDB.find(BackupItem::FIELD_COMPACTION_HOLDER); if (compactionHolder != itemFromDB.end()) { this->compactionHolder = compactionHolder->second.GetS(); } auto attachmentsHolders = itemFromDB.find(BackupItem::FIELD_ATTACHMENT_HOLDERS); if (attachmentsHolders != itemFromDB.end()) { this->attachmentHolders = attachmentsHolders->second.GetS(); } } catch (std::logic_error &e) { throw std::runtime_error( "invalid backup item provided, " + std::string(e.what())); } this->validate(); } std::string BackupItem::getTableName() const { - return BackupItem::tableName; + return BackupItem::TABLE_NAME; } PrimaryKeyDescriptor BackupItem::getPrimaryKeyDescriptor() const { return PrimaryKeyDescriptor( BackupItem::FIELD_USER_ID, BackupItem::FIELD_BACKUP_ID); } PrimaryKeyValue BackupItem::getPrimaryKeyValue() const { return PrimaryKeyValue(this->userID, this->backupID); } std::string BackupItem::getUserID() const { return this->userID; } std::string BackupItem::getBackupID() const { return this->backupID; } uint64_t BackupItem::getCreated() const { return this->created; } std::string BackupItem::getRecoveryData() const { return this->recoveryData; } std::string BackupItem::getCompactionHolder() const { return this->compactionHolder; } std::string BackupItem::getAttachmentHolders() const { return this->attachmentHolders; } void BackupItem::addAttachmentHolders(const std::string &attachmentHolders) { this->attachmentHolders += tools::validateAttachmentHolders(attachmentHolders); } } // namespace database } // namespace network } // namespace comm diff --git a/services/backup/src/DatabaseEntities/BackupItem.h b/services/backup/src/DatabaseEntities/BackupItem.h index cb0a95578..0da325231 100644 --- a/services/backup/src/DatabaseEntities/BackupItem.h +++ b/services/backup/src/DatabaseEntities/BackupItem.h @@ -1,81 +1,81 @@ #pragma once #include "Item.h" #include namespace comm { namespace network { namespace database { /** * backup - backups assigned to users along with the data necessary to * decrypt * `created` - when the backup was created. This is a search key because * we want to be able to perform effective queries based on this info * (for example get me the latest backup, get me backup from some day) * `attachmentHolders` - this is a list of attachment references * `recoveryData` - data serialized with protobuf which is described by * one of the following structures: * { authType: 'password', pakePasswordCiphertext: string, nonce: string } * { authType: 'wallet', walletAddress: string, rawMessage: string } * * this class is used for representing two things: the rows in the main table, * and also the rows in the secondary index * * Needs userID(pk)-created(sk)-index that projects: * userID * backupID * created * recoveryData */ class BackupItem : public Item { std::string userID; std::string backupID; uint64_t created; std::string recoveryData; std::string compactionHolder; std::string attachmentHolders; void validate() const override; public: - static std::string tableName; + static const std::string TABLE_NAME; static const std::string FIELD_USER_ID; static const std::string FIELD_BACKUP_ID; static const std::string FIELD_CREATED; static const std::string FIELD_RECOVERY_DATA; static const std::string FIELD_COMPACTION_HOLDER; static const std::string FIELD_ATTACHMENT_HOLDERS; BackupItem() { } BackupItem( std::string userID, std::string backupID, uint64_t created, std::string recoveryData, std::string compactionHolder, std::string attachmentHolders); BackupItem(const AttributeValues &itemFromDB); void assignItemFromDatabase(const AttributeValues &itemFromDB) override; std::string getTableName() const override; PrimaryKeyDescriptor getPrimaryKeyDescriptor() const override; PrimaryKeyValue getPrimaryKeyValue() const override; std::string getUserID() const; std::string getBackupID() const; uint64_t getCreated() const; std::string getRecoveryData() const; std::string getCompactionHolder() const; std::string getAttachmentHolders() const; void addAttachmentHolders(const std::string &attachmentHolders); }; } // namespace database } // namespace network } // namespace comm diff --git a/services/backup/src/DatabaseEntities/LogItem.cpp b/services/backup/src/DatabaseEntities/LogItem.cpp index e9b59e58e..2a3f281ae 100644 --- a/services/backup/src/DatabaseEntities/LogItem.cpp +++ b/services/backup/src/DatabaseEntities/LogItem.cpp @@ -1,148 +1,148 @@ #include "LogItem.h" #include "Constants.h" #include "Tools.h" #include namespace comm { namespace network { namespace database { const std::string LogItem::FIELD_BACKUP_ID = "backupID"; const std::string LogItem::FIELD_LOG_ID = "logID"; const std::string LogItem::FIELD_PERSISTED_IN_BLOB = "persistedInBlob"; const std::string LogItem::FIELD_VALUE = "value"; const std::string LogItem::FIELD_ATTACHMENT_HOLDERS = "attachmentHolders"; const std::string LogItem::FIELD_DATA_HASH = "dataHash"; -std::string LogItem::tableName = LOG_TABLE_NAME; +const std::string LogItem::TABLE_NAME = LOG_TABLE_NAME; LogItem::LogItem( const std::string backupID, const std::string logID, const bool persistedInBlob, const std::string value, std::string attachmentHolders, const std::string dataHash) : backupID(backupID), logID(logID), persistedInBlob(persistedInBlob), value(value), attachmentHolders(attachmentHolders), dataHash(dataHash) { this->validate(); } LogItem::LogItem(const AttributeValues &itemFromDB) { this->assignItemFromDatabase(itemFromDB); } void LogItem::validate() const { if (!this->backupID.size()) { throw std::runtime_error("backupID empty"); } if (!this->logID.size()) { throw std::runtime_error("logID empty"); } if (!this->value.size()) { throw std::runtime_error("value empty"); } const size_t itemSize = LogItem::getItemSize(this); if (!this->persistedInBlob && itemSize > LOG_DATA_SIZE_DATABASE_LIMIT) { throw std::runtime_error( "the value of this log is too big to be stored in the database, it " "should be stored in the blob instead (" + std::to_string(itemSize) + "/" + std::to_string(LOG_DATA_SIZE_DATABASE_LIMIT) + ")"); } if (!this->dataHash.size()) { throw std::runtime_error("data hash empty"); } } void LogItem::assignItemFromDatabase(const AttributeValues &itemFromDB) { try { this->backupID = itemFromDB.at(LogItem::FIELD_BACKUP_ID).GetS(); this->logID = itemFromDB.at(LogItem::FIELD_LOG_ID).GetS(); this->persistedInBlob = std::stoi( std::string(itemFromDB.at(LogItem::FIELD_PERSISTED_IN_BLOB).GetS()) .c_str()); this->value = itemFromDB.at(LogItem::FIELD_VALUE).GetS(); auto attachmentsHolders = itemFromDB.find(LogItem::FIELD_ATTACHMENT_HOLDERS); if (attachmentsHolders != itemFromDB.end()) { this->attachmentHolders = attachmentsHolders->second.GetS(); } this->dataHash = itemFromDB.at(LogItem::FIELD_DATA_HASH).GetS(); } catch (std::logic_error &e) { throw std::runtime_error( "invalid log item provided, " + std::string(e.what())); } this->validate(); } std::string LogItem::getTableName() const { - return LogItem::tableName; + return LogItem::TABLE_NAME; } PrimaryKeyDescriptor LogItem::getPrimaryKeyDescriptor() const { return PrimaryKeyDescriptor(LogItem::FIELD_BACKUP_ID, LogItem::FIELD_LOG_ID); } PrimaryKeyValue LogItem::getPrimaryKeyValue() const { return PrimaryKeyValue(this->backupID, this->logID); } std::string LogItem::getBackupID() const { return this->backupID; } std::string LogItem::getLogID() const { return this->logID; } bool LogItem::getPersistedInBlob() const { return this->persistedInBlob; } std::string LogItem::getValue() const { return this->value; } std::string LogItem::getAttachmentHolders() const { return this->attachmentHolders; } std::string LogItem::getDataHash() const { return this->dataHash; } void LogItem::addAttachmentHolders(const std::string &attachmentHolders) { this->attachmentHolders += tools::validateAttachmentHolders(attachmentHolders); } size_t LogItem::getItemSize(const LogItem *item) { size_t size = 0; size += LogItem::FIELD_BACKUP_ID.size(); size += LogItem::FIELD_LOG_ID.size(); size += LogItem::FIELD_PERSISTED_IN_BLOB.size(); size += LogItem::FIELD_VALUE.size(); size += LogItem::FIELD_ATTACHMENT_HOLDERS.size(); size += LogItem::FIELD_DATA_HASH.size(); size += item->getBackupID().size(); size += item->getLogID().size(); size += std::to_string(item->getPersistedInBlob()).size(); size += item->getValue().size(); size += item->getAttachmentHolders().size(); size += item->getDataHash().size(); return size; } } // namespace database } // namespace network } // namespace comm diff --git a/services/backup/src/DatabaseEntities/LogItem.h b/services/backup/src/DatabaseEntities/LogItem.h index 4f489ba6f..ec76eff68 100644 --- a/services/backup/src/DatabaseEntities/LogItem.h +++ b/services/backup/src/DatabaseEntities/LogItem.h @@ -1,70 +1,70 @@ #pragma once #include "Item.h" #include namespace comm { namespace network { namespace database { /* * log - a single log record * `backupID` - id of the backup that this log is assigned to * `value` - either the value itself which is a dump of a single operation (if * `persistedInBlob` is false) or the holder to blob (if `persistedInBlob` is * true) * `attachmentHolders` - this is a list of attachment references */ class LogItem : public Item { std::string backupID; std::string logID; bool persistedInBlob; std::string value; std::string attachmentHolders; std::string dataHash; void validate() const override; public: - static std::string tableName; + static const std::string TABLE_NAME; static const std::string FIELD_BACKUP_ID; static const std::string FIELD_LOG_ID; static const std::string FIELD_PERSISTED_IN_BLOB; static const std::string FIELD_VALUE; static const std::string FIELD_ATTACHMENT_HOLDERS; static const std::string FIELD_DATA_HASH; LogItem() { } LogItem( const std::string backupID, const std::string logID, const bool persistedInBlob, const std::string value, std::string attachmentHolders, const std::string dataHash); LogItem(const AttributeValues &itemFromDB); void assignItemFromDatabase(const AttributeValues &itemFromDB) override; std::string getTableName() const override; PrimaryKeyDescriptor getPrimaryKeyDescriptor() const override; PrimaryKeyValue getPrimaryKeyValue() const override; std::string getBackupID() const; std::string getLogID() const; bool getPersistedInBlob() const; std::string getValue() const; std::string getAttachmentHolders() const; std::string getDataHash() const; void addAttachmentHolders(const std::string &attachmentHolders); static size_t getItemSize(const LogItem *item); }; } // namespace database } // namespace network } // namespace comm diff --git a/services/backup/src/DatabaseManager.cpp b/services/backup/src/DatabaseManager.cpp index 5481ac32c..06ce84e3a 100644 --- a/services/backup/src/DatabaseManager.cpp +++ b/services/backup/src/DatabaseManager.cpp @@ -1,173 +1,173 @@ #include "DatabaseManager.h" #include "Constants.h" #include "GlobalTools.h" #include "Tools.h" #include #include #include #include #include namespace comm { namespace network { namespace database { DatabaseManager &DatabaseManager::getInstance() { static DatabaseManager instance; return instance; } void DatabaseManager::putBackupItem(const BackupItem &item) { Aws::DynamoDB::Model::PutItemRequest request; - request.SetTableName(BackupItem::tableName); + request.SetTableName(BackupItem::TABLE_NAME); request.AddItem( BackupItem::FIELD_USER_ID, Aws::DynamoDB::Model::AttributeValue(item.getUserID())); request.AddItem( BackupItem::FIELD_CREATED, Aws::DynamoDB::Model::AttributeValue( std::to_string(tools::getCurrentTimestamp()))); request.AddItem( BackupItem::FIELD_BACKUP_ID, Aws::DynamoDB::Model::AttributeValue(item.getBackupID())); request.AddItem( BackupItem::FIELD_RECOVERY_DATA, Aws::DynamoDB::Model::AttributeValue(item.getRecoveryData())); request.AddItem( BackupItem::FIELD_COMPACTION_HOLDER, Aws::DynamoDB::Model::AttributeValue(item.getCompactionHolder())); if (!item.getAttachmentHolders().empty()) { request.AddItem( BackupItem::FIELD_ATTACHMENT_HOLDERS, Aws::DynamoDB::Model::AttributeValue(item.getAttachmentHolders())); } this->innerPutItem(std::make_shared(item), request); } std::shared_ptr DatabaseManager::findBackupItem( const std::string &userID, const std::string &backupID) { Aws::DynamoDB::Model::GetItemRequest request; request.AddKey( BackupItem::FIELD_USER_ID, Aws::DynamoDB::Model::AttributeValue(userID)); request.AddKey( BackupItem::FIELD_BACKUP_ID, Aws::DynamoDB::Model::AttributeValue(backupID)); return this->innerFindItem(request); } std::shared_ptr DatabaseManager::findLastBackupItem(const std::string &userID) { std::shared_ptr item = createItemByType(); Aws::DynamoDB::Model::QueryRequest req; - req.SetTableName(BackupItem::tableName); + req.SetTableName(BackupItem::TABLE_NAME); req.SetKeyConditionExpression(BackupItem::FIELD_USER_ID + " = :valueToMatch"); AttributeValues attributeValues; attributeValues.emplace(":valueToMatch", userID); req.SetExpressionAttributeValues(attributeValues); req.SetIndexName("userID-created-index"); req.SetLimit(1); req.SetScanIndexForward(false); const Aws::DynamoDB::Model::QueryOutcome &outcome = getDynamoDBClient()->Query(req); if (!outcome.IsSuccess()) { throw std::runtime_error(outcome.GetError().GetMessage()); } const Aws::Vector &items = outcome.GetResult().GetItems(); if (items.empty()) { return nullptr; } return std::make_shared(items[0]); } void DatabaseManager::removeBackupItem(std::shared_ptr item) { if (item == nullptr) { return; } this->innerRemoveItem(*item); } void DatabaseManager::putLogItem(const LogItem &item) { Aws::DynamoDB::Model::PutItemRequest request; - request.SetTableName(LogItem::tableName); + request.SetTableName(LogItem::TABLE_NAME); request.AddItem( LogItem::FIELD_BACKUP_ID, Aws::DynamoDB::Model::AttributeValue(item.getBackupID())); request.AddItem( LogItem::FIELD_LOG_ID, Aws::DynamoDB::Model::AttributeValue(item.getLogID())); request.AddItem( LogItem::FIELD_PERSISTED_IN_BLOB, Aws::DynamoDB::Model::AttributeValue( std::to_string(item.getPersistedInBlob()))); request.AddItem( LogItem::FIELD_VALUE, Aws::DynamoDB::Model::AttributeValue(item.getValue())); if (!item.getAttachmentHolders().empty()) { request.AddItem( LogItem::FIELD_ATTACHMENT_HOLDERS, Aws::DynamoDB::Model::AttributeValue(item.getAttachmentHolders())); } request.AddItem( LogItem::FIELD_DATA_HASH, Aws::DynamoDB::Model::AttributeValue(item.getDataHash())); this->innerPutItem(std::make_shared(item), request); } std::shared_ptr DatabaseManager::findLogItem( const std::string &backupID, const std::string &logID) { Aws::DynamoDB::Model::GetItemRequest request; request.AddKey( LogItem::FIELD_BACKUP_ID, Aws::DynamoDB::Model::AttributeValue(backupID)); request.AddKey( LogItem::FIELD_LOG_ID, Aws::DynamoDB::Model::AttributeValue(logID)); return this->innerFindItem(request); } std::vector> DatabaseManager::findLogItemsForBackup(const std::string &backupID) { std::vector> result; std::shared_ptr item = createItemByType(); Aws::DynamoDB::Model::QueryRequest req; - req.SetTableName(LogItem::tableName); + req.SetTableName(LogItem::TABLE_NAME); req.SetKeyConditionExpression(LogItem::FIELD_BACKUP_ID + " = :valueToMatch"); AttributeValues attributeValues; attributeValues.emplace(":valueToMatch", backupID); req.SetExpressionAttributeValues(attributeValues); const Aws::DynamoDB::Model::QueryOutcome &outcome = getDynamoDBClient()->Query(req); if (!outcome.IsSuccess()) { throw std::runtime_error(outcome.GetError().GetMessage()); } const Aws::Vector &items = outcome.GetResult().GetItems(); for (auto &item : items) { result.push_back(std::make_shared(item)); } return result; } void DatabaseManager::removeLogItem(std::shared_ptr item) { if (item == nullptr) { return; } this->innerRemoveItem(*item); } } // namespace database } // namespace network } // namespace comm diff --git a/services/blob/src/DatabaseEntities/BlobItem.cpp b/services/blob/src/DatabaseEntities/BlobItem.cpp index 849cbadac..c3881414a 100644 --- a/services/blob/src/DatabaseEntities/BlobItem.cpp +++ b/services/blob/src/DatabaseEntities/BlobItem.cpp @@ -1,73 +1,73 @@ #include "BlobItem.h" #include "Constants.h" namespace comm { namespace network { namespace database { const std::string BlobItem::FIELD_BLOB_HASH = "blobHash"; const std::string BlobItem::FIELD_S3_PATH = "s3Path"; const std::string BlobItem::FIELD_CREATED = "created"; -std::string BlobItem::tableName = BLOB_TABLE_NAME; +const std::string BlobItem::TABLE_NAME = BLOB_TABLE_NAME; BlobItem::BlobItem( const std::string blobHash, const S3Path s3Path, uint64_t created) : blobHash(blobHash), s3Path(s3Path), created(created) { this->validate(); } BlobItem::BlobItem(const AttributeValues &itemFromDB) { this->assignItemFromDatabase(itemFromDB); } void BlobItem::validate() const { if (!this->blobHash.size()) { throw std::runtime_error("blobHash empty"); } this->s3Path.validate(); } void BlobItem::assignItemFromDatabase(const AttributeValues &itemFromDB) { try { this->blobHash = itemFromDB.at(BlobItem::FIELD_BLOB_HASH).GetS(); this->s3Path = S3Path(itemFromDB.at(BlobItem::FIELD_S3_PATH).GetS()); this->created = std::stoll( std::string(itemFromDB.at(BlobItem::FIELD_CREATED).GetS()).c_str()); } catch (std::logic_error &e) { throw std::runtime_error( "invalid blob item provided, " + std::string(e.what())); } this->validate(); } std::string BlobItem::getTableName() const { - return BlobItem::tableName; + return BlobItem::TABLE_NAME; } PrimaryKeyDescriptor BlobItem::getPrimaryKeyDescriptor() const { return PrimaryKeyDescriptor(BlobItem::FIELD_BLOB_HASH); } PrimaryKeyValue BlobItem::getPrimaryKeyValue() const { return PrimaryKeyValue(this->blobHash); } std::string BlobItem::getBlobHash() const { return this->blobHash; } S3Path BlobItem::getS3Path() const { return this->s3Path; } uint64_t BlobItem::getCreated() const { return this->created; } } // namespace database } // namespace network } // namespace comm diff --git a/services/blob/src/DatabaseEntities/BlobItem.h b/services/blob/src/DatabaseEntities/BlobItem.h index 74fe713f6..693645b9b 100644 --- a/services/blob/src/DatabaseEntities/BlobItem.h +++ b/services/blob/src/DatabaseEntities/BlobItem.h @@ -1,47 +1,47 @@ #pragma once #include "Item.h" #include "S3Path.h" #include namespace comm { namespace network { namespace database { class BlobItem : public Item { std::string blobHash; S3Path s3Path; uint64_t created = 0; void validate() const override; public: - static std::string tableName; + static const std::string TABLE_NAME; static const std::string FIELD_BLOB_HASH; static const std::string FIELD_S3_PATH; static const std::string FIELD_CREATED; BlobItem() { } BlobItem( const std::string blobHash, const S3Path s3Path, uint64_t created = 0); BlobItem(const AttributeValues &itemFromDB); void assignItemFromDatabase(const AttributeValues &itemFromDB) override; std::string getTableName() const override; PrimaryKeyDescriptor getPrimaryKeyDescriptor() const override; PrimaryKeyValue getPrimaryKeyValue() const override; std::string getBlobHash() const; S3Path getS3Path() const; uint64_t getCreated() const; }; } // namespace database } // namespace network } // namespace comm diff --git a/services/blob/src/DatabaseEntities/ReverseIndexItem.cpp b/services/blob/src/DatabaseEntities/ReverseIndexItem.cpp index 265c3aaab..4d9322d40 100644 --- a/services/blob/src/DatabaseEntities/ReverseIndexItem.cpp +++ b/services/blob/src/DatabaseEntities/ReverseIndexItem.cpp @@ -1,62 +1,62 @@ #include "ReverseIndexItem.h" #include "Constants.h" namespace comm { namespace network { namespace database { const std::string ReverseIndexItem::FIELD_HOLDER = "holder"; const std::string ReverseIndexItem::FIELD_BLOB_HASH = "blobHash"; -std::string ReverseIndexItem::tableName = REVERSE_INDEX_TABLE_NAME; +const std::string ReverseIndexItem::TABLE_NAME = REVERSE_INDEX_TABLE_NAME; ReverseIndexItem::ReverseIndexItem( const std::string holder, const std::string blobHash) : holder(holder), blobHash(blobHash) { this->validate(); } ReverseIndexItem::ReverseIndexItem(const AttributeValues &itemFromDB) { this->assignItemFromDatabase(itemFromDB); } void ReverseIndexItem::validate() const { if (!this->holder.size()) { throw std::runtime_error("reverse index empty"); } if (!this->blobHash.size()) { throw std::runtime_error("blobHash empty"); } } void ReverseIndexItem::assignItemFromDatabase( const AttributeValues &itemFromDB) { this->holder = itemFromDB.at(ReverseIndexItem::FIELD_HOLDER).GetS(); this->blobHash = itemFromDB.at(ReverseIndexItem::FIELD_BLOB_HASH).GetS(); this->validate(); } std::string ReverseIndexItem::getTableName() const { - return ReverseIndexItem::tableName; + return ReverseIndexItem::TABLE_NAME; } PrimaryKeyDescriptor ReverseIndexItem::getPrimaryKeyDescriptor() const { return PrimaryKeyDescriptor(ReverseIndexItem::FIELD_HOLDER); } PrimaryKeyValue ReverseIndexItem::getPrimaryKeyValue() const { return PrimaryKeyValue(this->holder); } std::string ReverseIndexItem::getHolder() const { return this->holder; } std::string ReverseIndexItem::getBlobHash() const { return this->blobHash; } } // namespace database } // namespace network } // namespace comm diff --git a/services/blob/src/DatabaseEntities/ReverseIndexItem.h b/services/blob/src/DatabaseEntities/ReverseIndexItem.h index d7888c3c7..df42eda86 100644 --- a/services/blob/src/DatabaseEntities/ReverseIndexItem.h +++ b/services/blob/src/DatabaseEntities/ReverseIndexItem.h @@ -1,45 +1,45 @@ #pragma once #include "Item.h" #include namespace comm { namespace network { namespace database { /** * Needs blobHash(pk)-index that projects: * blobHash * holder */ class ReverseIndexItem : public Item { std::string holder; std::string blobHash; void validate() const override; public: - static std::string tableName; + static const std::string TABLE_NAME; static const std::string FIELD_HOLDER; static const std::string FIELD_BLOB_HASH; ReverseIndexItem() { } ReverseIndexItem(const std::string holder, const std::string blobHash); ReverseIndexItem(const AttributeValues &itemFromDB); void assignItemFromDatabase(const AttributeValues &itemFromDB) override; std::string getTableName() const override; PrimaryKeyDescriptor getPrimaryKeyDescriptor() const override; PrimaryKeyValue getPrimaryKeyValue() const override; std::string getHolder() const; std::string getBlobHash() const; }; } // namespace database } // namespace network } // namespace comm diff --git a/services/blob/src/DatabaseManager.cpp b/services/blob/src/DatabaseManager.cpp index 9766b1a5d..a0c420bcf 100644 --- a/services/blob/src/DatabaseManager.cpp +++ b/services/blob/src/DatabaseManager.cpp @@ -1,120 +1,120 @@ #include "DatabaseManager.h" #include "GlobalTools.h" #include "Tools.h" #include #include #include #include namespace comm { namespace network { namespace database { DatabaseManager &DatabaseManager::getInstance() { static DatabaseManager instance; return instance; } void DatabaseManager::putBlobItem(const BlobItem &item) { Aws::DynamoDB::Model::PutItemRequest request; - request.SetTableName(BlobItem::tableName); + request.SetTableName(BlobItem::TABLE_NAME); request.AddItem( BlobItem::FIELD_BLOB_HASH, Aws::DynamoDB::Model::AttributeValue(item.getBlobHash())); request.AddItem( BlobItem::FIELD_S3_PATH, Aws::DynamoDB::Model::AttributeValue(item.getS3Path().getFullPath())); request.AddItem( BlobItem::FIELD_CREATED, Aws::DynamoDB::Model::AttributeValue( std::to_string(tools::getCurrentTimestamp()))); this->innerPutItem(std::make_shared(item), request); } std::shared_ptr DatabaseManager::findBlobItem(const std::string &blobHash) { Aws::DynamoDB::Model::GetItemRequest request; request.AddKey( BlobItem::FIELD_BLOB_HASH, Aws::DynamoDB::Model::AttributeValue(blobHash)); return std::move(this->innerFindItem(request)); } void DatabaseManager::removeBlobItem(const std::string &blobHash) { std::shared_ptr item = this->findBlobItem(blobHash); if (item == nullptr) { return; } this->innerRemoveItem(*item); } void DatabaseManager::putReverseIndexItem(const ReverseIndexItem &item) { if (this->findReverseIndexItemByHolder(item.getHolder()) != nullptr) { throw std::runtime_error( "An item for the given holder [" + item.getHolder() + "] already exists"); } Aws::DynamoDB::Model::PutItemRequest request; - request.SetTableName(ReverseIndexItem::tableName); + request.SetTableName(ReverseIndexItem::TABLE_NAME); request.AddItem( ReverseIndexItem::FIELD_HOLDER, Aws::DynamoDB::Model::AttributeValue(item.getHolder())); request.AddItem( ReverseIndexItem::FIELD_BLOB_HASH, Aws::DynamoDB::Model::AttributeValue(item.getBlobHash())); this->innerPutItem(std::make_shared(item), request); } std::shared_ptr DatabaseManager::findReverseIndexItemByHolder(const std::string &holder) { Aws::DynamoDB::Model::GetItemRequest request; request.AddKey( ReverseIndexItem::FIELD_HOLDER, Aws::DynamoDB::Model::AttributeValue(holder)); return std::move(this->innerFindItem(request)); } std::vector> DatabaseManager::findReverseIndexItemsByHash(const std::string &blobHash) { std::vector> result; Aws::DynamoDB::Model::QueryRequest req; - req.SetTableName(ReverseIndexItem::tableName); + req.SetTableName(ReverseIndexItem::TABLE_NAME); req.SetKeyConditionExpression("blobHash = :valueToMatch"); AttributeValues attributeValues; attributeValues.emplace(":valueToMatch", blobHash); req.SetExpressionAttributeValues(attributeValues); req.SetIndexName("blobHash-index"); const Aws::DynamoDB::Model::QueryOutcome &outcome = getDynamoDBClient()->Query(req); if (!outcome.IsSuccess()) { throw std::runtime_error(outcome.GetError().GetMessage()); } const Aws::Vector &items = outcome.GetResult().GetItems(); for (auto &item : items) { result.push_back(std::make_shared(item)); } return result; } void DatabaseManager::removeReverseIndexItem(const std::string &holder) { std::shared_ptr item = findReverseIndexItemByHolder(holder); if (item == nullptr) { return; } this->innerRemoveItem(*item); } } // namespace database } // namespace network } // namespace comm