diff --git a/services/backup/docker-server/contents/server/src/DatabaseManager.cpp b/services/backup/docker-server/contents/server/src/DatabaseManager.cpp index ec6bd9ff0..bf5d11f63 100644 --- a/services/backup/docker-server/contents/server/src/DatabaseManager.cpp +++ b/services/backup/docker-server/contents/server/src/DatabaseManager.cpp @@ -1,47 +1,120 @@ #include "DatabaseManager.h" #include "Constants.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::innerPutItem( std::shared_ptr item, const Aws::DynamoDB::Model::PutItemRequest &request) { const Aws::DynamoDB::Model::PutItemOutcome outcome = getDynamoDBClient()->PutItem(request); if (!outcome.IsSuccess()) { throw std::runtime_error(outcome.GetError().GetMessage()); } } void DatabaseManager::innerRemoveItem( const Item &item, const std::string &key) { Aws::DynamoDB::Model::DeleteItemRequest request; request.SetTableName(item.getTableName()); request.AddKey( item.getPrimaryKey(), Aws::DynamoDB::Model::AttributeValue(key)); const Aws::DynamoDB::Model::DeleteItemOutcome &outcome = getDynamoDBClient()->DeleteItem(request); if (!outcome.IsSuccess()) { throw std::runtime_error(outcome.GetError().GetMessage()); } } +void DatabaseManager::putBackupItem(const BackupItem &item) { + Aws::DynamoDB::Model::PutItemRequest request; + request.SetTableName(BackupItem::tableName); + request.AddItem( + BackupItem::FIELD_USER_ID, + Aws::DynamoDB::Model::AttributeValue(item.getUserID())); + request.AddItem( + BackupItem::FIELD_CREATED, + Aws::DynamoDB::Model::AttributeValue( + std::to_string(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())); + request.AddItem( + BackupItem::FIELD_ATTACHMENT_HOLDERS, + Aws::DynamoDB::Model::AttributeValue(item.getAttachmentHolders())); + + this->innerPutItem(std::make_shared(item), 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.SetKeyConditionExpression(item->getPrimaryKey() + " = :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) { + Aws::DynamoDB::Model::DeleteItemRequest request; + request.SetTableName(item->getTableName()); + request.AddKey( + BackupItem::FIELD_USER_ID, + Aws::DynamoDB::Model::AttributeValue(item->getUserID())); + request.AddKey( + BackupItem::FIELD_BACKUP_ID, + Aws::DynamoDB::Model::AttributeValue(item->getBackupID())); + + const Aws::DynamoDB::Model::DeleteItemOutcome &outcome = + comm::network::getDynamoDBClient()->DeleteItem(request); + if (!outcome.IsSuccess()) { + throw std::runtime_error(outcome.GetError().GetMessage()); + } +} + } // namespace database } // namespace network } // namespace comm diff --git a/services/backup/docker-server/contents/server/src/DatabaseManager.h b/services/backup/docker-server/contents/server/src/DatabaseManager.h index f21774fa4..04cc4c771 100644 --- a/services/backup/docker-server/contents/server/src/DatabaseManager.h +++ b/services/backup/docker-server/contents/server/src/DatabaseManager.h @@ -1,61 +1,65 @@ #pragma once #include "AwsTools.h" #include "DatabaseEntitiesTools.h" #include #include #include #include #include #include #ifdef COMM_SERVICES_DEV_MODE #include "DatabaseSimulator.h" #endif namespace comm { namespace network { namespace database { // this class should be thread-safe in case any shared resources appear class DatabaseManager { #ifdef COMM_SERVICES_DEV_MODE DatabaseSimulator dbSimulator; #endif void innerPutItem( std::shared_ptr item, const Aws::DynamoDB::Model::PutItemRequest &request); template std::shared_ptr innerFindItem(Aws::DynamoDB::Model::GetItemRequest &request); void innerRemoveItem(const Item &item, const std::string &key); public: static DatabaseManager &getInstance(); + + void putBackupItem(const BackupItem &item); + std::shared_ptr findLastBackupItem(const std::string &userID); + void removeBackupItem(std::shared_ptr item); }; template std::shared_ptr DatabaseManager::innerFindItem(Aws::DynamoDB::Model::GetItemRequest &request) { std::shared_ptr item = createItemByType(); request.SetTableName(item->getTableName()); const Aws::DynamoDB::Model::GetItemOutcome &outcome = getDynamoDBClient()->GetItem(request); if (!outcome.IsSuccess()) { throw std::runtime_error(outcome.GetError().GetMessage()); } const AttributeValues &outcomeItem = outcome.GetResult().GetItem(); if (!outcomeItem.size()) { return nullptr; } item->assignItemFromDatabase(outcomeItem); return item; } } // namespace database } // namespace network } // namespace comm