优化结构

This commit is contained in:
Yvan
2026-08-28 09:19:54 +08:00
parent 03a4131f6e
commit 279692375b
57 changed files with 778 additions and 799 deletions
+1 -23
View File
@@ -69,29 +69,7 @@ func (s *aliyunStorage) Compose(ctx context.Context, names []string, destination
return composeFiles(ctx, s, names, destination)
}
func (s *aliyunStorage) DeletePrefix(ctx context.Context, prefix string) error {
prefix, err := normalizeDeletePrefix(prefix)
if err != nil {
return err
}
cursor := ""
for {
items, next, more, err := s.List(ctx, prefix+"/", cursor, 1000)
if err != nil {
return err
}
for _, item := range items {
if err = s.Delete(ctx, item.Path); err != nil {
return err
}
}
if !more {
return nil
}
cursor, err = advanceDeletePrefixCursor(cursor, next, more)
if err != nil {
return err
}
}
return deletePrefixViaList(ctx, prefix, s.List, s.Delete)
}
func (s *aliyunStorage) List(_ context.Context, prefix, cursor string, limit int) ([]*system.StoredFile, string, bool, error) {
if limit <= 0 {
+1 -23
View File
@@ -106,29 +106,7 @@ func (s *awsStorage) Compose(ctx context.Context, names []string, destination st
return composeFiles(ctx, s, names, destination)
}
func (s *awsStorage) DeletePrefix(ctx context.Context, prefix string) error {
prefix, err := normalizeDeletePrefix(prefix)
if err != nil {
return err
}
cursor := ""
for {
items, next, more, err := s.List(ctx, prefix+"/", cursor, 1000)
if err != nil {
return err
}
for _, item := range items {
if err = s.Delete(ctx, item.Path); err != nil {
return err
}
}
if !more {
return nil
}
cursor, err = advanceDeletePrefixCursor(cursor, next, more)
if err != nil {
return err
}
}
return deletePrefixViaList(ctx, prefix, s.List, s.Delete)
}
func (s *awsStorage) List(ctx context.Context, prefix, cursor string, limit int) ([]*system.StoredFile, string, bool, error) {
if limit <= 0 {
@@ -6,6 +6,7 @@ import (
"encoding/hex"
"errors"
"io"
"kra/internal/biz/system"
"strings"
"testing"
"time"
@@ -117,3 +118,38 @@ func TestAdvanceDeletePrefixCursor(t *testing.T) {
t.Fatalf("advance cursor = %q, %v", next, err)
}
}
func TestDeletePrefixViaListDeletesAllPages(t *testing.T) {
pages := map[string][]*system.StoredFile{
"": {{Path: "uploads/a"}, {Path: "uploads/b"}},
"next": {{Path: "uploads/c"}},
}
removed := []string{}
if err := deletePrefixViaList(context.Background(), "uploads", func(_ context.Context, prefix, cursor string, limit int) ([]*system.StoredFile, string, bool, error) {
if prefix != "uploads/" || limit != 1000 {
t.Fatalf("list arguments = %q, %q, %d", prefix, cursor, limit)
}
items := pages[cursor]
if cursor == "" {
return items, "next", true, nil
}
return items, "", false, nil
}, func(_ context.Context, path string) error {
removed = append(removed, path)
return nil
}); err != nil {
t.Fatal(err)
}
if len(removed) != 3 || removed[2] != "uploads/c" {
t.Fatalf("removed paths = %#v", removed)
}
}
func TestDeletePrefixViaListRejectsStalledCursor(t *testing.T) {
err := deletePrefixViaList(context.Background(), "uploads", func(_ context.Context, _, _ string, _ int) ([]*system.StoredFile, string, bool, error) {
return nil, "", true, nil
}, func(context.Context, string) error { return nil })
if err == nil || !strings.Contains(err.Error(), "no progress") {
t.Fatalf("stalled pagination error = %v", err)
}
}
+1 -23
View File
@@ -68,29 +68,7 @@ func (s *huaweiStorage) Compose(ctx context.Context, names []string, destination
return composeFiles(ctx, s, names, destination)
}
func (s *huaweiStorage) DeletePrefix(ctx context.Context, prefix string) error {
prefix, err := normalizeDeletePrefix(prefix)
if err != nil {
return err
}
cursor := ""
for {
items, next, more, err := s.List(ctx, prefix+"/", cursor, 1000)
if err != nil {
return err
}
for _, item := range items {
if err = s.Delete(ctx, item.Path); err != nil {
return err
}
}
if !more {
return nil
}
cursor, err = advanceDeletePrefixCursor(cursor, next, more)
if err != nil {
return err
}
}
return deletePrefixViaList(ctx, prefix, s.List, s.Delete)
}
func (s *huaweiStorage) List(_ context.Context, prefix, cursor string, limit int) ([]*system.StoredFile, string, bool, error) {
if limit <= 0 {
+28
View File
@@ -1,11 +1,39 @@
package storage
import (
"context"
"errors"
"kra/internal/biz/system"
"path"
"strings"
)
func deletePrefixViaList(ctx context.Context, prefix string, list func(context.Context, string, string, int) ([]*system.StoredFile, string, bool, error), remove func(context.Context, string) error) error {
prefix, err := normalizeDeletePrefix(prefix)
if err != nil {
return err
}
cursor := ""
for {
items, next, more, err := list(ctx, prefix+"/", cursor, 1000)
if err != nil {
return err
}
for _, item := range items {
if err := remove(ctx, item.Path); err != nil {
return err
}
}
if !more {
return nil
}
cursor, err = advanceDeletePrefixCursor(cursor, next, more)
if err != nil {
return err
}
}
}
// normalizeDeletePrefix rejects requests that could accidentally target the
// storage root and returns the canonical key form used by all backends.
func normalizeDeletePrefix(prefix string) (string, error) {
+1 -23
View File
@@ -99,29 +99,7 @@ func (s *qiniuStorage) Compose(ctx context.Context, names []string, destination
return composeFiles(ctx, s, names, destination)
}
func (s *qiniuStorage) DeletePrefix(ctx context.Context, prefix string) error {
prefix, err := normalizeDeletePrefix(prefix)
if err != nil {
return err
}
cursor := ""
for {
items, next, more, err := s.List(ctx, prefix+"/", cursor, 1000)
if err != nil {
return err
}
for _, item := range items {
if err = s.Delete(ctx, item.Path); err != nil {
return err
}
}
if !more {
return nil
}
cursor, err = advanceDeletePrefixCursor(cursor, next, more)
if err != nil {
return err
}
}
return deletePrefixViaList(ctx, prefix, s.List, s.Delete)
}
func (s *qiniuStorage) List(ctx context.Context, prefix, cursor string, limit int) ([]*system.StoredFile, string, bool, error) {
if limit <= 0 {
@@ -82,29 +82,7 @@ func (s *tencentStorage) Compose(ctx context.Context, names []string, destinatio
return composeFiles(ctx, s, names, destination)
}
func (s *tencentStorage) DeletePrefix(ctx context.Context, prefix string) error {
prefix, err := normalizeDeletePrefix(prefix)
if err != nil {
return err
}
cursor := ""
for {
items, next, more, err := s.List(ctx, prefix+"/", cursor, 1000)
if err != nil {
return err
}
for _, item := range items {
if err = s.Delete(ctx, item.Path); err != nil {
return err
}
}
if !more {
return nil
}
cursor, err = advanceDeletePrefixCursor(cursor, next, more)
if err != nil {
return err
}
}
return deletePrefixViaList(ctx, prefix, s.List, s.Delete)
}
func (s *tencentStorage) List(ctx context.Context, prefix, cursor string, limit int) ([]*system.StoredFile, string, bool, error) {
if limit <= 0 {