MCPcopy
hub / github.com/minio/minio-go / ComposeObject

Method ComposeObject

api-compose-object.go:435–590  ·  view source on GitHub ↗

ComposeObject - creates an object using server-side copying of existing objects. It takes a list of source objects (with optional offsets) and concatenates them into a new object using only server-side copying operations. Optionally takes progress reader hook for applications to look at current prog

(ctx context.Context, dst CopyDestOptions, srcs ...CopySrcOptions)

Source from the content-addressed store, hash-verified

433// operations. Optionally takes progress reader hook for applications to
434// look at current progress.
435func (c *Client) ComposeObject(ctx context.Context, dst CopyDestOptions, srcs ...CopySrcOptions) (UploadInfo, error) {
436 if len(srcs) < 1 || len(srcs) > maxPartsCount {
437 return UploadInfo{}, errInvalidArgument("There must be as least one and up to 10000 source objects.")
438 }
439
440 for _, src := range srcs {
441 if err := src.validate(); err != nil {
442 return UploadInfo{}, err
443 }
444 }
445
446 if err := dst.validate(); err != nil {
447 return UploadInfo{}, err
448 }
449
450 srcObjectInfos := make([]ObjectInfo, len(srcs))
451 srcObjectSizes := make([]int64, len(srcs))
452 var totalSize, totalParts int64
453 var err error
454 for i, src := range srcs {
455 opts := StatObjectOptions{ServerSideEncryption: encrypt.SSE(src.Encryption), VersionID: src.VersionID}
456 srcObjectInfos[i], err = c.StatObject(context.Background(), src.Bucket, src.Object, opts)
457 if err != nil {
458 return UploadInfo{}, err
459 }
460
461 srcCopySize := srcObjectInfos[i].Size
462 // Check if a segment is specified, and if so, is the
463 // segment within object bounds?
464 if src.MatchRange {
465 // Since range is specified,
466 // 0 <= src.start <= src.end
467 // so only invalid case to check is:
468 if src.End >= srcCopySize || src.Start < 0 {
469 return UploadInfo{}, errInvalidArgument(
470 fmt.Sprintf("CopySrcOptions %d has invalid segment-to-copy [%d, %d] (size is %d)",
471 i, src.Start, src.End, srcCopySize))
472 }
473 srcCopySize = src.End - src.Start + 1
474 }
475
476 // Only the last source may be less than `absMinPartSize`
477 if srcCopySize < absMinPartSize && i < len(srcs)-1 {
478 return UploadInfo{}, errInvalidArgument(
479 fmt.Sprintf("CopySrcOptions %d is too small (%d) and it is not the last part", i, srcCopySize))
480 }
481
482 // Is data to copy too large?
483 totalSize += srcCopySize
484 if totalSize > maxObjectSize {
485 return UploadInfo{}, errInvalidArgument(fmt.Sprintf("Cannot compose an object of size %d (> 5GiB * 10000)", totalSize))
486 }
487
488 // record source size
489 srcObjectSizes[i] = srcCopySize
490
491 // calculate parts needed for current source
492 totalParts += partsRequired(srcCopySize, int64(dst.PartSize))

Callers 5

mainFunction · 0.80

Calls 13

StatObjectMethod · 0.95
CopyObjectMethod · 0.95
newUploadIDMethod · 0.95
uploadPartCopyMethod · 0.95
SSEFunction · 0.92
errInvalidArgumentFunction · 0.85
partsRequiredFunction · 0.85
calculateEvenSplitsFunction · 0.85
MarshalMethod · 0.65
TypeMethod · 0.65
validateMethod · 0.45

Tested by

no test coverage detected