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 }