Add idempotent object deletion

This commit is contained in:
2026-09-05 12:22:44 +00:00
parent 7f84fc5d1e
commit 14b4fee214
10 changed files with 143 additions and 9 deletions

View File

@@ -23,6 +23,7 @@ type s3API interface {
ListObjectsV2(ctx context.Context, params *s3.ListObjectsV2Input, optFns ...func(*s3.Options)) (*s3.ListObjectsV2Output, error)
GetObject(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error)
PutObject(ctx context.Context, params *s3.PutObjectInput, optFns ...func(*s3.Options)) (*s3.PutObjectOutput, error)
DeleteObject(ctx context.Context, params *s3.DeleteObjectInput, optFns ...func(*s3.Options)) (*s3.DeleteObjectOutput, error)
HeadObject(ctx context.Context, params *s3.HeadObjectInput, optFns ...func(*s3.Options)) (*s3.HeadObjectOutput, error)
}
@@ -300,6 +301,25 @@ func (b *S3Backend) uploadReader(ctx context.Context, source io.Reader, key stri
return info, nil
}
// Delete removes one object. S3 deletion is idempotent when the key is absent.
func (b *S3Backend) Delete(ctx context.Context, key string) error {
if err := ctx.Err(); err != nil {
return err
}
normalizedKey := normalizeObjectKey(key)
if normalizedKey == "" {
return fmt.Errorf("delete object: key is required")
}
_, err := b.client.DeleteObject(ctx, &s3.DeleteObjectInput{
Bucket: &b.bucket,
Key: &normalizedKey,
})
if err != nil {
return fmt.Errorf("delete object %q: %w", normalizedKey, err)
}
return nil
}
// Exists checks whether one object key exists.
func (b *S3Backend) Exists(ctx context.Context, key string) (bool, error) {
normalizedKey := normalizeObjectKey(key)