github.com/Azure/draft-classic@v0.16.0/pkg/storage/inprocess/store.go (about)

     1  package inprocess
     2  
     3  import (
     4  	"context"
     5  	"github.com/Azure/draft/pkg/storage"
     6  	"github.com/golang/protobuf/ptypes"
     7  	"time"
     8  )
     9  
    10  // Store is an inprocess storage engine for draft.
    11  type Store struct {
    12  	// builds is mapping of app name to storage objects.
    13  	builds map[string][]*storage.Object
    14  }
    15  
    16  // compile-time guarantee that *Store implements storage.Store
    17  var _ storage.Store = (*Store)(nil)
    18  
    19  // NewStore returns a new inprocess memory Store for storing draft application context.
    20  func NewStore() *Store {
    21  	return &Store{builds: make(map[string][]*storage.Object)}
    22  }
    23  
    24  // DeleteBuilds deletes all draft builds for the application specified by appName.
    25  //
    26  // DeleteBuilds implements storage.Deleter.
    27  func (s *Store) DeleteBuilds(ctx context.Context, appName string) ([]*storage.Object, error) {
    28  	h, ok := s.builds[appName]
    29  	if !ok {
    30  		return nil, storage.NewErrAppStorageNotFound(appName)
    31  	}
    32  	delete(s.builds, appName)
    33  	return h, nil
    34  }
    35  
    36  // DeleteBuild deletes the draft build given by buildID for the application specified by appName.
    37  //
    38  // DeleteBuild implements storage.Deleter.
    39  func (s *Store) DeleteBuild(ctx context.Context, appName, buildID string) (*storage.Object, error) {
    40  	h, ok := s.builds[appName]
    41  	if !ok {
    42  		return nil, storage.NewErrAppStorageNotFound(appName)
    43  	}
    44  	for i, o := range h {
    45  		if buildID == o.BuildID {
    46  			s.builds[appName] = append(h[:i], h[i+1:]...)
    47  			return o, nil
    48  		}
    49  	}
    50  	return nil, storage.NewErrAppBuildNotFound(appName, buildID)
    51  }
    52  
    53  // CreateBuild creates new storage for the application specified by appName to include build.
    54  //
    55  // If storage already exists for the application, ErrAppStorageExists is returned.
    56  //
    57  // CreateBuild implements storage.Creater.
    58  func (s *Store) CreateBuild(ctx context.Context, appName string, build *storage.Object) error {
    59  	if _, ok := s.builds[appName]; ok {
    60  		return storage.NewErrAppStorageExists(appName)
    61  	}
    62  	now, err := ptypes.TimestampProto(time.Now())
    63  	if err != nil {
    64  		return err
    65  	}
    66  	build.CreatedAt = now
    67  	s.builds[appName] = []*storage.Object{build}
    68  	return nil
    69  }
    70  
    71  // UpdateBuild updates the application storage specified by appName to include build.
    72  //
    73  // If build does not exist, a new storage entry is created. Otherwise the existing storage
    74  // is updated.
    75  //
    76  // UpdateBuild implements storage.Updater.
    77  func (s *Store) UpdateBuild(ctx context.Context, appName string, build *storage.Object) (err error) {
    78  	if _, ok := s.builds[appName]; !ok {
    79  		return s.CreateBuild(ctx, appName, build)
    80  	}
    81  	if build.CreatedAt, err = ptypes.TimestampProto(time.Now()); err != nil {
    82  		return err
    83  	}
    84  	s.builds[appName] = append(s.builds[appName], build)
    85  	// TODO(fibonacci1729): deduplication of builds.
    86  	return nil
    87  }
    88  
    89  // GetBuilds returns a slice of builds for the given app name.
    90  //
    91  // GetBuilds implements storage.Getter.
    92  func (s *Store) GetBuilds(ctx context.Context, appName string) ([]*storage.Object, error) {
    93  	h, ok := s.builds[appName]
    94  	if !ok {
    95  		return nil, storage.NewErrAppStorageNotFound(appName)
    96  	}
    97  	return h, nil
    98  }
    99  
   100  // GetBuild returns the build associated with buildID for the specified app name.
   101  //
   102  // GetBuild implements storage.Getter.
   103  func (s *Store) GetBuild(ctx context.Context, appName, buildID string) (*storage.Object, error) {
   104  	h, ok := s.builds[appName]
   105  	if !ok {
   106  		return nil, storage.NewErrAppStorageNotFound(appName)
   107  	}
   108  	for _, o := range h {
   109  		if buildID == o.BuildID {
   110  			return o, nil
   111  		}
   112  	}
   113  	return nil, storage.NewErrAppBuildNotFound(appName, buildID)
   114  }