优化结构
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user