Skip to content

Commit c34f06b

Browse files
authored
feat: add reverse version for listObjectVersions (#2072)
1 parent a9f9671 commit c34f06b

File tree

2 files changed

+57
-12
lines changed

2 files changed

+57
-12
lines changed

api-datatypes.go

+2
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ type ObjectInfo struct {
212212
// not to be confused with `Expires` HTTP header.
213213
Expiration time.Time
214214
ExpirationRuleID string
215+
// NumVersions is the number of versions of the object.
216+
NumVersions int
215217

216218
Restore *RestoreInfo
217219

api-list.go

+55-12
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"fmt"
2323
"net/http"
2424
"net/url"
25+
"slices"
2526
"time"
2627

2728
"github.com/minio/minio-go/v7/pkg/s3utils"
@@ -421,20 +422,17 @@ func (c *Client) listObjectVersions(ctx context.Context, bucketName string, opts
421422
var (
422423
keyMarker = ""
423424
versionIDMarker = ""
425+
preName = ""
426+
preKey = ""
427+
perVersions []Version
428+
numVersions int
424429
)
425-
426-
for {
427-
// Get list of objects a maximum of 1000 per request.
428-
result, err := c.listObjectVersionsQuery(ctx, bucketName, opts, keyMarker, versionIDMarker, delimiter)
429-
if err != nil {
430-
sendObjectInfo(ObjectInfo{
431-
Err: err,
432-
})
433-
return
430+
send := func(vers []Version) {
431+
if opts.WithVersions && opts.ReverseVersions {
432+
slices.Reverse(vers)
433+
numVersions = len(vers)
434434
}
435-
436-
// If contents are available loop through and send over channel.
437-
for _, version := range result.Versions {
435+
for _, version := range vers {
438436
info := ObjectInfo{
439437
ETag: trimEtag(version.ETag),
440438
Key: version.Key,
@@ -448,6 +446,7 @@ func (c *Client) listObjectVersions(ctx context.Context, bucketName string, opts
448446
UserTags: version.UserTags,
449447
UserMetadata: version.UserMetadata,
450448
Internal: version.Internal,
449+
NumVersions: numVersions,
451450
}
452451
select {
453452
// Send object version info.
@@ -457,6 +456,38 @@ func (c *Client) listObjectVersions(ctx context.Context, bucketName string, opts
457456
return
458457
}
459458
}
459+
}
460+
for {
461+
// Get list of objects a maximum of 1000 per request.
462+
result, err := c.listObjectVersionsQuery(ctx, bucketName, opts, keyMarker, versionIDMarker, delimiter)
463+
if err != nil {
464+
sendObjectInfo(ObjectInfo{
465+
Err: err,
466+
})
467+
return
468+
}
469+
if opts.WithVersions && opts.ReverseVersions {
470+
for _, version := range result.Versions {
471+
if preName == "" {
472+
preName = result.Name
473+
preKey = version.Key
474+
}
475+
if result.Name == preName && preKey == version.Key {
476+
// If the current name is same as previous name,
477+
// we need to append the version to the previous version.
478+
perVersions = append(perVersions, version)
479+
continue
480+
}
481+
// Send the file versions.
482+
send(perVersions)
483+
perVersions = perVersions[:0]
484+
perVersions = append(perVersions, version)
485+
preName = result.Name
486+
preKey = version.Key
487+
}
488+
} else {
489+
send(result.Versions)
490+
}
460491

461492
// Send all common prefixes if any.
462493
// NOTE: prefixes are only present if the request is delimited.
@@ -480,10 +511,20 @@ func (c *Client) listObjectVersions(ctx context.Context, bucketName string, opts
480511
versionIDMarker = result.NextVersionIDMarker
481512
}
482513

514+
// If context is canceled, return here.
515+
if contextCanceled(ctx) {
516+
return
517+
}
518+
483519
// Listing ends result is not truncated, return right here.
484520
if !result.IsTruncated {
521+
// sent the lasted file with versions
522+
if opts.ReverseVersions && len(perVersions) > 0 {
523+
send(perVersions)
524+
}
485525
return
486526
}
527+
487528
}
488529
}(resultCh)
489530
return resultCh
@@ -683,6 +724,8 @@ func (c *Client) listObjectsQuery(ctx context.Context, bucketName, objectPrefix,
683724

684725
// ListObjectsOptions holds all options of a list object request
685726
type ListObjectsOptions struct {
727+
// ReverseVersions - reverse the order of the object versions
728+
ReverseVersions bool
686729
// Include objects versions in the listing
687730
WithVersions bool
688731
// Include objects metadata in the listing

0 commit comments

Comments
 (0)