diff --git a/services/backup/docker-server/contents/server/src/DatabaseManager.cpp b/services/backup/docker-server/contents/server/src/DatabaseManager.cpp index ef280a445..f6fe0394b 100644 --- a/services/backup/docker-server/contents/server/src/DatabaseManager.cpp +++ b/services/backup/docker-server/contents/server/src/DatabaseManager.cpp @@ -1,188 +1,167 @@ #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) { +void DatabaseManager::innerRemoveItem(const Item &item) { Aws::DynamoDB::Model::DeleteItemRequest request; request.SetTableName(item.getTableName()); + PrimaryKey pk = item.getPrimaryKey(); + PrimaryKeyValue primaryKeyValue = item.getPrimaryKeyValue(); request.AddKey( - item.getPrimaryKey().partitionKey, - Aws::DynamoDB::Model::AttributeValue(key)); + pk.partitionKey, + Aws::DynamoDB::Model::AttributeValue(primaryKeyValue.partitionKey)); + if (pk.sortKey != nullptr && primaryKeyValue.sortKey != nullptr) { + request.AddKey( + *pk.sortKey, + Aws::DynamoDB::Model::AttributeValue(*primaryKeyValue.sortKey)); + } 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(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) { - 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()); - } + this->innerRemoveItem(*item); } void DatabaseManager::putLogItem(const LogItem &item) { Aws::DynamoDB::Model::PutItemRequest request; request.SetTableName(LogItem::tableName); 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())); request.AddItem( LogItem::FIELD_ATTACHMENT_HOLDERS, Aws::DynamoDB::Model::AttributeValue(item.getAttachmentHolders())); this->innerPutItem(std::make_shared(item), 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.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) { - Aws::DynamoDB::Model::DeleteItemRequest request; - request.SetTableName(item->getTableName()); - request.AddKey( - LogItem::FIELD_BACKUP_ID, - Aws::DynamoDB::Model::AttributeValue(item->getBackupID())); - request.AddKey( - LogItem::FIELD_LOG_ID, - Aws::DynamoDB::Model::AttributeValue(item->getLogID())); - - const Aws::DynamoDB::Model::DeleteItemOutcome &outcome = - getDynamoDBClient()->DeleteItem(request); - if (!outcome.IsSuccess()) { - throw std::runtime_error(outcome.GetError().GetMessage()); - } + this->innerRemoveItem(*item); } } // 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 ff4718b67..6b996e913 100644 --- a/services/backup/docker-server/contents/server/src/DatabaseManager.h +++ b/services/backup/docker-server/contents/server/src/DatabaseManager.h @@ -1,70 +1,70 @@ #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); + void innerRemoveItem(const Item &item); public: static DatabaseManager &getInstance(); void putBackupItem(const BackupItem &item); std::shared_ptr findLastBackupItem(const std::string &userID); void removeBackupItem(std::shared_ptr item); void putLogItem(const LogItem &item); std::vector> findLogItemsForBackup(const std::string &backupID); void removeLogItem(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