|
7 | 7 |
|
8 | 8 | "github.com/aws/aws-sdk-go-v2/service/dynamodb"
|
9 | 9 | "github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
|
| 10 | + "github.com/aws/aws-sdk-go/aws" |
10 | 11 | "github.com/cloudopsy/dynamodb-encryption-go/pkg/provider"
|
11 | 12 | "github.com/cloudopsy/dynamodb-encryption-go/pkg/utils"
|
12 | 13 | )
|
@@ -152,6 +153,62 @@ func (ec *EncryptedClient) BatchGetItem(ctx context.Context, input *dynamodb.Bat
|
152 | 153 | return encryptedOutput, nil
|
153 | 154 | }
|
154 | 155 |
|
| 156 | +// DeleteItem deletes an item and its associated metadata from a DynamoDB table. |
| 157 | +func (ec *EncryptedClient) DeleteItem(ctx context.Context, input *dynamodb.DeleteItemInput) (*dynamodb.DeleteItemOutput, error) { |
| 158 | + // First, delete the item from DynamoDB |
| 159 | + deleteOutput, err := ec.client.DeleteItem(ctx, input) |
| 160 | + if err != nil { |
| 161 | + return nil, fmt.Errorf("error deleting encrypted item: %v", err) |
| 162 | + } |
| 163 | + |
| 164 | + // Determine the material name or metadata identifier |
| 165 | + pkInfo, err := ec.getPrimaryKeyInfo(ctx, *input.TableName) |
| 166 | + if err != nil { |
| 167 | + return nil, fmt.Errorf("error fetching primary key info: %v", err) |
| 168 | + } |
| 169 | + |
| 170 | + // Construct material name based on the primary key of the item being deleted |
| 171 | + materialName := ec.constructMaterialName(input.Key, pkInfo) |
| 172 | + |
| 173 | + // Delete the associated metadata |
| 174 | + tableName := ec.materialsProvider.TableName() |
| 175 | + queryInput := &dynamodb.QueryInput{ |
| 176 | + TableName: aws.String(tableName), |
| 177 | + KeyConditionExpression: aws.String("MaterialName = :materialName"), |
| 178 | + ExpressionAttributeValues: map[string]types.AttributeValue{ |
| 179 | + ":materialName": &types.AttributeValueMemberS{Value: materialName}, |
| 180 | + }, |
| 181 | + } |
| 182 | + |
| 183 | + queryOutput, err := ec.client.Query(ctx, queryInput) |
| 184 | + if err != nil { |
| 185 | + return nil, fmt.Errorf("error querying for versions: %v", err) |
| 186 | + } |
| 187 | + |
| 188 | + for _, item := range queryOutput.Items { |
| 189 | + deleteRequest := map[string][]types.WriteRequest{ |
| 190 | + tableName: { |
| 191 | + { |
| 192 | + DeleteRequest: &types.DeleteRequest{ |
| 193 | + Key: map[string]types.AttributeValue{ |
| 194 | + "MaterialName": item["MaterialName"], |
| 195 | + "Version": item["Version"], |
| 196 | + }, |
| 197 | + }, |
| 198 | + }, |
| 199 | + }, |
| 200 | + } |
| 201 | + |
| 202 | + batchWriteInput := &dynamodb.BatchWriteItemInput{RequestItems: deleteRequest} |
| 203 | + _, err = ec.client.BatchWriteItem(ctx, batchWriteInput) |
| 204 | + if err != nil { |
| 205 | + return nil, fmt.Errorf("error deleting a version: %v", err) |
| 206 | + } |
| 207 | + } |
| 208 | + |
| 209 | + return deleteOutput, nil |
| 210 | +} |
| 211 | + |
155 | 212 | // getPrimaryKeyInfo lazily loads and caches primary key information in a thread-safe manner.
|
156 | 213 | func (ec *EncryptedClient) getPrimaryKeyInfo(ctx context.Context, tableName string) (*utils.PrimaryKeyInfo, error) {
|
157 | 214 | ec.lock.RLock()
|
@@ -221,7 +278,6 @@ func (ec *EncryptedClient) encryptItem(ctx context.Context, tableName string, it
|
221 | 278 |
|
222 | 279 | // decryptItem decrypts a DynamoDB item's attributes, excluding primary keys.
|
223 | 280 | func (ec *EncryptedClient) decryptItem(ctx context.Context, tableName string, item map[string]types.AttributeValue) (map[string]types.AttributeValue, error) {
|
224 |
| - // Fetch primary key info to identify these attributes |
225 | 281 | pkInfo, err := ec.getPrimaryKeyInfo(ctx, tableName)
|
226 | 282 | if err != nil {
|
227 | 283 | return nil, err
|
|
0 commit comments