github.com/benchkram/bob@v0.0.0-20240314204020-b7a57f2f9be9/pkg/store/sync.go (about)

     1  package store
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  
     7  	"github.com/benchkram/errz"
     8  )
     9  
    10  // Sync an item from the src store to the dst store.
    11  // In case the item exists in dst Sync does nothing and returns nil.
    12  func Sync(ctx context.Context, src, dst Store, id string, ignoreAlreadyExists bool) (err error) {
    13  	defer errz.Recover(&err)
    14  
    15  	found, err := exists(ctx, src, id)
    16  	errz.Fatal(err)
    17  	if !found {
    18  		return ErrArtifactNotFoundinSrc
    19  	}
    20  
    21  	if !ignoreAlreadyExists {
    22  		found, err = exists(ctx, dst, id)
    23  		errz.Fatal(err)
    24  		if found {
    25  			return ErrArtifactAlreadyExists
    26  		}
    27  	}
    28  
    29  	srcReader, size, err := src.GetArtifact(ctx, id)
    30  	errz.Fatal(err)
    31  
    32  	dstWriter, err := dst.NewArtifact(ctx, id, size)
    33  	errz.Fatal(err)
    34  
    35  	tr := io.TeeReader(srcReader, dstWriter)
    36  	buf := make([]byte, 256)
    37  	for {
    38  		_, err := tr.Read(buf)
    39  		if err == io.EOF {
    40  			_ = dstWriter.Close()
    41  			break
    42  		}
    43  		errz.Fatal(err)
    44  	}
    45  
    46  	return src.Done()
    47  }
    48  
    49  func exists(ctx context.Context, store Store, id string) (found bool, err error) {
    50  	defer errz.Recover(&err)
    51  
    52  	artifactIds, err := store.List(ctx)
    53  	errz.Fatal(err)
    54  
    55  	for _, i := range artifactIds {
    56  		if i == id {
    57  			found = true
    58  			break
    59  		}
    60  	}
    61  
    62  	return found, nil
    63  }