func()

in internal/storage/fake/bucket.go [728:796]


func (b *bucket) CopyObject(
	ctx context.Context,
	req *gcs.CopyObjectRequest) (o *gcs.Object, err error) {
	b.mu.Lock()
	defer b.mu.Unlock()

	// Check that the destination name is legal.
	err = checkName(req.DstName)
	if err != nil {
		return
	}

	// Does the object exist?
	srcIndex := b.objects.find(req.SrcName)
	if srcIndex == len(b.objects) {
		err = &gcs.NotFoundError{
			Err: fmt.Errorf("object %q not found", req.SrcName),
		}

		return
	}

	// Does it have the correct generation?
	if req.SrcGeneration != 0 &&
		b.objects[srcIndex].metadata.Generation != req.SrcGeneration {
		err = &gcs.NotFoundError{
			Err: fmt.Errorf(
				"object %s generation %d not found", req.SrcName, req.SrcGeneration),
		}

		return
	}

	// Does it have the correct meta-generation?
	if req.SrcMetaGenerationPrecondition != nil {
		p := *req.SrcMetaGenerationPrecondition
		if b.objects[srcIndex].metadata.MetaGeneration != p {
			err = &gcs.PreconditionError{
				Err: fmt.Errorf(
					"object %q has meta-generation %d",
					req.SrcName,
					b.objects[srcIndex].metadata.MetaGeneration),
			}

			return
		}
	}

	// Copy it and assign a new generation number, to ensure that the generation
	// number for the destination name is strictly increasing.
	dst := b.objects[srcIndex]
	dst.metadata.Name = req.DstName
	dst.metadata.MediaLink = "http://localhost/download/storage/fake/" + req.DstName

	b.prevGeneration++
	dst.metadata.Generation = b.prevGeneration

	// Insert into our array.
	existingIndex := b.objects.find(req.DstName)
	if existingIndex < len(b.objects) {
		b.objects[existingIndex] = dst
	} else {
		b.objects = append(b.objects, dst)
		sort.Sort(b.objects)
	}

	o = copyObject(&dst.metadata)
	return
}