diff --git a/services/backup/src/database.rs b/services/backup/src/database.rs --- a/services/backup/src/database.rs +++ b/services/backup/src/database.rs @@ -14,6 +14,9 @@ BACKUP_TABLE_FIELD_COMPACTION_HOLDER, BACKUP_TABLE_FIELD_CREATED, BACKUP_TABLE_FIELD_RECOVERY_DATA, BACKUP_TABLE_FIELD_USER_ID, BACKUP_TABLE_INDEX_USERID_CREATED, BACKUP_TABLE_NAME, + LOG_TABLE_FIELD_ATTACHMENT_HOLDERS, LOG_TABLE_FIELD_BACKUP_ID, + LOG_TABLE_FIELD_DATA_HASH, LOG_TABLE_FIELD_LOG_ID, + LOG_TABLE_FIELD_PERSISTED_IN_BLOB, LOG_TABLE_FIELD_VALUE, LOG_TABLE_NAME, }; #[derive(Clone, Debug)] @@ -186,7 +189,46 @@ // log item pub async fn put_log_item(&self, log_item: LogItem) -> Result<(), Error> { - unimplemented!() + let item = HashMap::from([ + ( + LOG_TABLE_FIELD_BACKUP_ID.to_string(), + AttributeValue::S(log_item.backup_id), + ), + ( + LOG_TABLE_FIELD_LOG_ID.to_string(), + AttributeValue::S(log_item.log_id), + ), + ( + LOG_TABLE_FIELD_PERSISTED_IN_BLOB.to_string(), + AttributeValue::Bool(log_item.persisted_in_blob), + ), + ( + LOG_TABLE_FIELD_VALUE.to_string(), + AttributeValue::S(log_item.value), + ), + ( + LOG_TABLE_FIELD_DATA_HASH.to_string(), + AttributeValue::S(log_item.data_hash), + ), + ( + LOG_TABLE_FIELD_ATTACHMENT_HOLDERS.to_string(), + AttributeValue::S(log_item.attachment_holders), + ), + ]); + + self + .client + .put_item() + .table_name(LOG_TABLE_NAME) + .set_item(Some(item)) + .send() + .await + .map_err(|e| { + error!("DynamoDB client failed to put log item"); + Error::AwsSdk(e.into()) + })?; + + Ok(()) } pub async fn find_log_item( @@ -194,18 +236,89 @@ backup_id: &str, log_id: &str, ) -> Result, Error> { - unimplemented!() + let item_key = HashMap::from([ + ( + LOG_TABLE_FIELD_BACKUP_ID.to_string(), + AttributeValue::S(backup_id.to_string()), + ), + ( + LOG_TABLE_FIELD_LOG_ID.to_string(), + AttributeValue::S(log_id.to_string()), + ), + ]); + + match self + .client + .get_item() + .table_name(LOG_TABLE_NAME) + .set_key(Some(item_key)) + .send() + .await + .map_err(|e| { + error!("DynamoDB client failed to find log item"); + Error::AwsSdk(e.into()) + })? { + GetItemOutput { + item: Some(item), .. + } => { + let log_item = parse_log_item(item)?; + Ok(Some(log_item)) + } + _ => Ok(None), + } } pub async fn find_log_items_for_backup( &self, backup_id: &str, ) -> Result, Error> { - unimplemented!() + let response = self + .client + .query() + .table_name(LOG_TABLE_NAME) + .key_condition_expression("#backupID = :valueToMatch") + .expression_attribute_names("#backupID", LOG_TABLE_FIELD_BACKUP_ID) + .expression_attribute_values( + ":valueToMatch", + AttributeValue::S(backup_id.to_string()), + ) + .send() + .await + .map_err(|e| { + error!("DynamoDB client failed to find log items for backup"); + Error::AwsSdk(e.into()) + })?; + + if response.count == 0 { + return Ok(Vec::new()); + } + + let mut results: Vec = + Vec::with_capacity(response.count() as usize); + for item in response.items.unwrap_or_default() { + let log_item = parse_log_item(item)?; + results.push(log_item); + } + Ok(results) } pub async fn remove_log_item(&self, log_id: &str) -> Result<(), Error> { - unimplemented!() + self + .client + .delete_item() + .table_name(LOG_TABLE_NAME) + .key( + LOG_TABLE_FIELD_LOG_ID, + AttributeValue::S(log_id.to_string()), + ) + .send() + .await + .map_err(|e| { + error!("DynamoDB client failed to remove log item"); + Error::AwsSdk(e.into()) + })?; + + Ok(()) } } @@ -352,3 +465,40 @@ attachment_holders, }) } + +fn parse_log_item( + mut item: HashMap, +) -> Result { + let backup_id = parse_string_attribute( + LOG_TABLE_FIELD_BACKUP_ID, + item.remove(LOG_TABLE_FIELD_BACKUP_ID), + )?; + let log_id = parse_string_attribute( + LOG_TABLE_FIELD_LOG_ID, + item.remove(LOG_TABLE_FIELD_LOG_ID), + )?; + let persisted_in_blob = parse_bool_attribute( + LOG_TABLE_FIELD_PERSISTED_IN_BLOB, + item.remove(LOG_TABLE_FIELD_PERSISTED_IN_BLOB), + )?; + let value = parse_string_attribute( + LOG_TABLE_FIELD_VALUE, + item.remove(LOG_TABLE_FIELD_VALUE), + )?; + let data_hash = parse_string_attribute( + LOG_TABLE_FIELD_DATA_HASH, + item.remove(LOG_TABLE_FIELD_DATA_HASH), + )?; + let attachment_holders = parse_string_attribute( + LOG_TABLE_FIELD_ATTACHMENT_HOLDERS, + item.remove(LOG_TABLE_FIELD_ATTACHMENT_HOLDERS), + )?; + Ok(LogItem { + log_id, + backup_id, + persisted_in_blob, + value, + data_hash, + attachment_holders, + }) +}