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  }