2020-10-29 18:10:46 +00:00
|
|
|
// Copyright (C) 2020 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package metabase
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2020-11-17 14:05:41 +00:00
|
|
|
"time"
|
2020-10-29 18:10:46 +00:00
|
|
|
|
2020-11-17 14:05:41 +00:00
|
|
|
"storj.io/common/storj"
|
2020-10-29 18:10:46 +00:00
|
|
|
"storj.io/common/uuid"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ObjectEntry contains information about an item in a bucket.
|
2020-11-17 14:05:41 +00:00
|
|
|
type ObjectEntry struct {
|
|
|
|
IsPrefix bool
|
|
|
|
|
|
|
|
ObjectKey ObjectKey
|
|
|
|
Version Version
|
|
|
|
StreamID uuid.UUID
|
|
|
|
|
|
|
|
CreatedAt time.Time
|
|
|
|
ExpiresAt *time.Time
|
|
|
|
|
|
|
|
Status ObjectStatus
|
|
|
|
SegmentCount int32
|
|
|
|
|
|
|
|
EncryptedMetadataNonce []byte
|
|
|
|
EncryptedMetadata []byte
|
|
|
|
EncryptedMetadataEncryptedKey []byte
|
|
|
|
|
2020-11-24 12:29:16 +00:00
|
|
|
TotalPlainSize int64
|
2020-11-17 14:05:41 +00:00
|
|
|
TotalEncryptedSize int64
|
|
|
|
FixedSegmentSize int32
|
|
|
|
|
|
|
|
Encryption storj.EncryptionParameters
|
|
|
|
}
|
2020-10-29 18:10:46 +00:00
|
|
|
|
|
|
|
// ObjectsIterator iterates over a sequence of ObjectEntry items.
|
|
|
|
type ObjectsIterator interface {
|
|
|
|
Next(ctx context.Context, item *ObjectEntry) bool
|
|
|
|
}
|
|
|
|
|
2021-01-11 12:06:04 +00:00
|
|
|
// IterateCursor is a cursor used during iteration through objects.
|
2021-06-25 15:01:12 +01:00
|
|
|
//
|
|
|
|
// The cursor is exclusive.
|
2020-10-29 18:10:46 +00:00
|
|
|
type IterateCursor struct {
|
|
|
|
Key ObjectKey
|
|
|
|
Version Version
|
|
|
|
}
|
|
|
|
|
2021-01-11 12:06:04 +00:00
|
|
|
// StreamIDCursor is a cursor used during iteration through streamIDs of a pending object.
|
|
|
|
type StreamIDCursor struct {
|
|
|
|
StreamID uuid.UUID
|
|
|
|
}
|
|
|
|
|
2020-12-21 16:43:08 +00:00
|
|
|
// IterateObjects contains arguments necessary for listing objects in a bucket.
|
|
|
|
type IterateObjects struct {
|
|
|
|
ProjectID uuid.UUID
|
|
|
|
BucketName string
|
|
|
|
BatchSize int
|
|
|
|
Prefix ObjectKey
|
|
|
|
Cursor IterateCursor
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify verifies get object request fields.
|
|
|
|
func (opts *IterateObjects) Verify() error {
|
|
|
|
switch {
|
|
|
|
case opts.ProjectID.IsZero():
|
|
|
|
return ErrInvalidRequest.New("ProjectID missing")
|
|
|
|
case opts.BucketName == "":
|
|
|
|
return ErrInvalidRequest.New("BucketName missing")
|
|
|
|
case opts.BatchSize < 0:
|
|
|
|
return ErrInvalidRequest.New("BatchSize is negative")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// IterateObjectsAllVersions iterates through all versions of all objects.
|
|
|
|
func (db *DB) IterateObjectsAllVersions(ctx context.Context, opts IterateObjects, fn func(context.Context, ObjectsIterator) error) (err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
if err = opts.Verify(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return iterateAllVersions(ctx, db, opts, fn)
|
|
|
|
}
|
|
|
|
|
2021-01-11 12:06:04 +00:00
|
|
|
// IteratePendingObjectsByKey contains arguments necessary for listing pending objects by ObjectKey.
|
|
|
|
type IteratePendingObjectsByKey struct {
|
|
|
|
ObjectLocation
|
|
|
|
BatchSize int
|
|
|
|
Cursor StreamIDCursor
|
|
|
|
}
|
|
|
|
|
2020-12-21 15:07:00 +00:00
|
|
|
// IterateObjectsWithStatus contains arguments necessary for listing objects in a bucket.
|
|
|
|
type IterateObjectsWithStatus struct {
|
2021-08-03 02:26:19 +01:00
|
|
|
ProjectID uuid.UUID
|
|
|
|
BucketName string
|
|
|
|
Recursive bool
|
|
|
|
BatchSize int
|
|
|
|
Prefix ObjectKey
|
|
|
|
Cursor IterateCursor
|
|
|
|
Status ObjectStatus
|
|
|
|
IncludeMetadata bool
|
2020-10-29 18:10:46 +00:00
|
|
|
}
|
|
|
|
|
2020-12-21 15:07:00 +00:00
|
|
|
// IterateObjectsAllVersionsWithStatus iterates through all versions of all objects with specified status.
|
|
|
|
func (db *DB) IterateObjectsAllVersionsWithStatus(ctx context.Context, opts IterateObjectsWithStatus, fn func(context.Context, ObjectsIterator) error) (err error) {
|
2020-10-29 18:10:46 +00:00
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
if err = opts.Verify(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-12-21 15:07:00 +00:00
|
|
|
return iterateAllVersionsWithStatus(ctx, db, opts, fn)
|
2020-10-29 18:10:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Verify verifies get object request fields.
|
2020-12-21 15:07:00 +00:00
|
|
|
func (opts *IterateObjectsWithStatus) Verify() error {
|
2020-10-29 18:10:46 +00:00
|
|
|
switch {
|
|
|
|
case opts.ProjectID.IsZero():
|
|
|
|
return ErrInvalidRequest.New("ProjectID missing")
|
2020-11-16 14:02:11 +00:00
|
|
|
case opts.BucketName == "":
|
|
|
|
return ErrInvalidRequest.New("BucketName missing")
|
2020-10-29 18:10:46 +00:00
|
|
|
case opts.BatchSize < 0:
|
|
|
|
return ErrInvalidRequest.New("BatchSize is negative")
|
2020-11-16 13:08:22 +00:00
|
|
|
case !(opts.Status == Pending || opts.Status == Committed):
|
|
|
|
return ErrInvalidRequest.New("Status %v is not supported", opts.Status)
|
2020-10-29 18:10:46 +00:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
2021-01-11 12:06:04 +00:00
|
|
|
|
|
|
|
// IteratePendingObjectsByKey iterates through all streams of pending objects with the same ObjectKey.
|
|
|
|
func (db *DB) IteratePendingObjectsByKey(ctx context.Context, opts IteratePendingObjectsByKey, fn func(context.Context, ObjectsIterator) error) (err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
|
|
|
|
if err := opts.Verify(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return iteratePendingObjectsByKey(ctx, db, opts, fn)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify verifies get object request fields.
|
|
|
|
func (opts *IteratePendingObjectsByKey) Verify() error {
|
|
|
|
if err := opts.ObjectLocation.Verify(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if opts.BatchSize < 0 {
|
|
|
|
return ErrInvalidRequest.New("BatchSize is negative")
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|