github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/formation/repository.go (about) 1 package formation 2 3 import ( 4 "context" 5 6 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 7 "github.com/pkg/errors" 8 9 "github.com/kyma-incubator/compass/components/director/internal/model" 10 "github.com/kyma-incubator/compass/components/director/internal/repo" 11 "github.com/kyma-incubator/compass/components/director/pkg/log" 12 "github.com/kyma-incubator/compass/components/director/pkg/resource" 13 ) 14 15 const tableName string = `public.formations` 16 17 var ( 18 updatableTableColumns = []string{"name", "state", "error"} 19 idTableColumns = []string{"id"} 20 tableColumns = []string{"id", "tenant_id", "formation_template_id", "name", "state", "error"} 21 tenantColumn = "tenant_id" 22 formationNameColumn = "name" 23 ) 24 25 // EntityConverter converts between the internal model and entity 26 // 27 //go:generate mockery --name=EntityConverter --output=automock --outpkg=automock --case=underscore --disable-version-string 28 type EntityConverter interface { 29 ToEntity(in *model.Formation) *Entity 30 FromEntity(entity *Entity) *model.Formation 31 } 32 33 type repository struct { 34 creator repo.CreatorGlobal 35 getter repo.SingleGetter 36 globalGetter repo.SingleGetterGlobal 37 pageableQuerier repo.PageableQuerier 38 lister repo.Lister 39 updater repo.UpdaterGlobal 40 deleter repo.Deleter 41 existQuerier repo.ExistQuerier 42 conv EntityConverter 43 } 44 45 // NewRepository creates a new Formation repository 46 func NewRepository(conv EntityConverter) *repository { 47 return &repository{ 48 creator: repo.NewCreatorGlobal(resource.Formations, tableName, tableColumns), 49 getter: repo.NewSingleGetterWithEmbeddedTenant(tableName, tenantColumn, tableColumns), 50 globalGetter: repo.NewSingleGetterGlobal(resource.Formations, tableName, tableColumns), 51 pageableQuerier: repo.NewPageableQuerierWithEmbeddedTenant(tableName, tenantColumn, tableColumns), 52 lister: repo.NewListerWithEmbeddedTenant(tableName, tenantColumn, tableColumns), 53 updater: repo.NewUpdaterWithEmbeddedTenant(resource.Formations, tableName, updatableTableColumns, tenantColumn, idTableColumns), 54 deleter: repo.NewDeleterWithEmbeddedTenant(tableName, tenantColumn), 55 existQuerier: repo.NewExistQuerierWithEmbeddedTenant(tableName, tenantColumn), 56 conv: conv, 57 } 58 } 59 60 // Create creates a Formation with a given input 61 func (r *repository) Create(ctx context.Context, item *model.Formation) error { 62 if item == nil { 63 return apperrors.NewInternalError("model can not be empty") 64 } 65 66 log.C(ctx).Debugf("Converting Formation with name: %q to entity", item.Name) 67 entity := r.conv.ToEntity(item) 68 69 log.C(ctx).Debugf("Persisting Formation entity with name: %q to the DB", item.Name) 70 return r.creator.Create(ctx, entity) 71 } 72 73 // Get returns a Formation by a given id 74 func (r *repository) Get(ctx context.Context, id, tenantID string) (*model.Formation, error) { 75 var entity Entity 76 if err := r.getter.Get(ctx, resource.Formations, tenantID, repo.Conditions{repo.NewEqualCondition("id", id)}, repo.NoOrderBy, &entity); err != nil { 77 log.C(ctx).Errorf("An error occurred while getting formation with id: %q", id) 78 return nil, errors.Wrapf(err, "An error occurred while getting formation with id: %q", id) 79 } 80 81 return r.conv.FromEntity(&entity), nil 82 } 83 84 // GetGlobalByID retrieves formation matching ID `id` globally without tenant parameter 85 func (r *repository) GetGlobalByID(ctx context.Context, id string) (*model.Formation, error) { 86 log.C(ctx).Debugf("Getting formation with ID: %q globally", id) 87 var entity Entity 88 if err := r.globalGetter.GetGlobal(ctx, repo.Conditions{repo.NewEqualCondition("id", id)}, repo.NoOrderBy, &entity); err != nil { 89 return nil, err 90 } 91 92 return r.conv.FromEntity(&entity), nil 93 } 94 95 // GetByName returns a Formations by a given name 96 func (r *repository) GetByName(ctx context.Context, name, tenantID string) (*model.Formation, error) { 97 var entity Entity 98 if err := r.getter.Get(ctx, resource.Formations, tenantID, repo.Conditions{repo.NewEqualCondition("name", name)}, repo.NoOrderBy, &entity); err != nil { 99 log.C(ctx).Errorf("An error occurred while getting formation with name: %q", name) 100 return nil, errors.Wrapf(err, "An error occurred while getting formation with name: %q", name) 101 } 102 103 return r.conv.FromEntity(&entity), nil 104 } 105 106 // List returns all Formations sorted by id and paginated by the pageSize and cursor parameters 107 func (r *repository) List(ctx context.Context, tenant string, pageSize int, cursor string) (*model.FormationPage, error) { 108 var entityCollection EntityCollection 109 page, totalCount, err := r.pageableQuerier.List(ctx, resource.Formations, tenant, pageSize, cursor, "id", &entityCollection) 110 if err != nil { 111 return nil, err 112 } 113 114 items := make([]*model.Formation, 0, entityCollection.Len()) 115 116 for _, entity := range entityCollection { 117 formationModel := r.conv.FromEntity(entity) 118 119 items = append(items, formationModel) 120 } 121 return &model.FormationPage{ 122 Data: items, 123 TotalCount: totalCount, 124 PageInfo: page, 125 }, nil 126 } 127 128 // ListByFormationNames returns all Formations with name in formationNames 129 func (r *repository) ListByFormationNames(ctx context.Context, formationNames []string, tenantID string) ([]*model.Formation, error) { 130 var entityCollection EntityCollection 131 if err := r.lister.List(ctx, resource.Formations, tenantID, &entityCollection, repo.NewInConditionForStringValues(formationNameColumn, formationNames)); err != nil { 132 return nil, err 133 } 134 135 items := make([]*model.Formation, 0, entityCollection.Len()) 136 137 for _, entity := range entityCollection { 138 formationModel := r.conv.FromEntity(entity) 139 140 items = append(items, formationModel) 141 } 142 return items, nil 143 } 144 145 // Update updates a Formation with the given input 146 func (r *repository) Update(ctx context.Context, model *model.Formation) error { 147 if model == nil { 148 return apperrors.NewInternalError("model can not be empty") 149 } 150 log.C(ctx).Debugf("Updating formation with ID: %q and name: %q...", model.ID, model.Name) 151 return r.updater.UpdateSingleGlobal(ctx, r.conv.ToEntity(model)) 152 } 153 154 // DeleteByName deletes a Formation with given name 155 func (r *repository) DeleteByName(ctx context.Context, tenantID, name string) error { 156 log.C(ctx).Debugf("Deleting formation with name: %q...", name) 157 return r.deleter.DeleteOne(ctx, resource.Formations, tenantID, repo.Conditions{repo.NewEqualCondition("name", name)}) 158 } 159 160 // Exists check if a Formation with given ID exists 161 func (r *repository) Exists(ctx context.Context, id, tenantID string) (bool, error) { 162 log.C(ctx).Debugf("Cheking if formation with ID: %q exists...", id) 163 return r.existQuerier.Exists(ctx, resource.Formations, tenantID, repo.Conditions{repo.NewEqualCondition("id", id)}) 164 }