github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/fetchrequest/repository.go (about)

     1  package fetchrequest
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/kyma-incubator/compass/components/director/pkg/resource"
     7  
     8  	"github.com/kyma-incubator/compass/components/director/pkg/apperrors"
     9  
    10  	"github.com/kyma-incubator/compass/components/director/internal/model"
    11  	"github.com/kyma-incubator/compass/components/director/internal/repo"
    12  	"github.com/pkg/errors"
    13  )
    14  
    15  const fetchRequestTable string = `public.fetch_requests`
    16  
    17  const documentIDColumn = "document_id"
    18  const specIDColumn = "spec_id"
    19  
    20  var (
    21  	fetchRequestColumns = []string{"id", documentIDColumn, "url", "auth", "mode", "filter", "status_condition", "status_message", "status_timestamp", specIDColumn}
    22  )
    23  
    24  // Converter missing godoc
    25  //
    26  //go:generate mockery --name=Converter --output=automock --outpkg=automock --case=underscore --disable-version-string
    27  type Converter interface {
    28  	ToEntity(in *model.FetchRequest) (*Entity, error)
    29  	FromEntity(in *Entity, objectType model.FetchRequestReferenceObjectType) (*model.FetchRequest, error)
    30  }
    31  
    32  type repository struct {
    33  	creator       repo.Creator
    34  	creatorGlobal repo.CreatorGlobal
    35  	singleGetter  repo.SingleGetter
    36  	lister        repo.Lister
    37  	listerGlobal  repo.ListerGlobal
    38  	deleter       repo.Deleter
    39  	deleterGlobal repo.DeleterGlobal
    40  	updater       repo.Updater
    41  	updaterGlobal repo.UpdaterGlobal
    42  	conv          Converter
    43  }
    44  
    45  // NewRepository missing godoc
    46  func NewRepository(conv Converter) *repository {
    47  	return &repository{
    48  		creator:       repo.NewCreator(fetchRequestTable, fetchRequestColumns),
    49  		creatorGlobal: repo.NewCreatorGlobal(resource.FetchRequest, fetchRequestTable, fetchRequestColumns),
    50  		singleGetter:  repo.NewSingleGetter(fetchRequestTable, fetchRequestColumns),
    51  		lister:        repo.NewLister(fetchRequestTable, fetchRequestColumns),
    52  		listerGlobal:  repo.NewListerGlobal(resource.FetchRequest, fetchRequestTable, fetchRequestColumns),
    53  		deleter:       repo.NewDeleter(fetchRequestTable),
    54  		deleterGlobal: repo.NewDeleterGlobal(resource.FetchRequest, fetchRequestTable),
    55  		updater:       repo.NewUpdater(fetchRequestTable, []string{"status_condition", "status_message", "status_timestamp"}, []string{"id"}),
    56  		updaterGlobal: repo.NewUpdaterGlobal(resource.FetchRequest, fetchRequestTable, []string{"status_condition", "status_message", "status_timestamp"}, []string{"id"}),
    57  		conv:          conv,
    58  	}
    59  }
    60  
    61  // Create missing godoc
    62  func (r *repository) Create(ctx context.Context, tenant string, item *model.FetchRequest) error {
    63  	if item == nil {
    64  		return apperrors.NewInternalError("item can not be empty")
    65  	}
    66  
    67  	entity, err := r.conv.ToEntity(item)
    68  	if err != nil {
    69  		return errors.Wrap(err, "while creating FetchRequest entity from model")
    70  	}
    71  
    72  	return r.creator.Create(ctx, item.ObjectType.GetResourceType(), tenant, entity)
    73  }
    74  
    75  // CreateGlobal creates a fetch request without tenant isolation
    76  func (r *repository) CreateGlobal(ctx context.Context, item *model.FetchRequest) error {
    77  	if item == nil {
    78  		return apperrors.NewInternalError("item can not be empty")
    79  	}
    80  
    81  	entity, err := r.conv.ToEntity(item)
    82  	if err != nil {
    83  		return errors.Wrap(err, "while creating FetchRequest entity from model")
    84  	}
    85  
    86  	return r.creatorGlobal.Create(ctx, entity)
    87  }
    88  
    89  // GetByReferenceObjectID missing godoc
    90  func (r *repository) GetByReferenceObjectID(ctx context.Context, tenant string, objectType model.FetchRequestReferenceObjectType, objectID string) (*model.FetchRequest, error) {
    91  	fieldName, err := r.referenceObjectFieldName(objectType)
    92  	if err != nil {
    93  		return nil, err
    94  	}
    95  
    96  	var entity Entity
    97  	if err := r.singleGetter.Get(ctx, objectType.GetResourceType(), tenant, repo.Conditions{repo.NewEqualCondition(fieldName, objectID)}, repo.NoOrderBy, &entity); err != nil {
    98  		return nil, err
    99  	}
   100  
   101  	frModel, err := r.conv.FromEntity(&entity, objectType)
   102  	if err != nil {
   103  		return nil, errors.Wrap(err, "while getting FetchRequest model from entity")
   104  	}
   105  
   106  	return frModel, nil
   107  }
   108  
   109  // Delete missing godoc
   110  func (r *repository) Delete(ctx context.Context, tenant, id string, objectType model.FetchRequestReferenceObjectType) error {
   111  	return r.deleter.DeleteOne(ctx, objectType.GetResourceType(), tenant, repo.Conditions{repo.NewEqualCondition("id", id)})
   112  }
   113  
   114  // DeleteByReferenceObjectID missing godoc
   115  func (r *repository) DeleteByReferenceObjectID(ctx context.Context, tenant string, objectType model.FetchRequestReferenceObjectType, objectID string) error {
   116  	fieldName, err := r.referenceObjectFieldName(objectType)
   117  	if err != nil {
   118  		return err
   119  	}
   120  
   121  	return r.deleter.DeleteMany(ctx, objectType.GetResourceType(), tenant, repo.Conditions{repo.NewEqualCondition(fieldName, objectID)})
   122  }
   123  
   124  // DeleteByReferenceObjectIDGlobal deletes fetch request by model.FetchRequestReferenceObjectType without tenant isolation
   125  func (r *repository) DeleteByReferenceObjectIDGlobal(ctx context.Context, objectType model.FetchRequestReferenceObjectType, objectID string) error {
   126  	fieldName, err := r.referenceObjectFieldName(objectType)
   127  	if err != nil {
   128  		return err
   129  	}
   130  
   131  	return r.deleterGlobal.DeleteManyGlobal(ctx, repo.Conditions{repo.NewEqualCondition(fieldName, objectID)})
   132  }
   133  
   134  // Update missing godoc
   135  func (r *repository) Update(ctx context.Context, tenant string, item *model.FetchRequest) error {
   136  	if item == nil {
   137  		return apperrors.NewInternalError("item cannot be nil")
   138  	}
   139  	entity, err := r.conv.ToEntity(item)
   140  	if err != nil {
   141  		return err
   142  	}
   143  	return r.updater.UpdateSingle(ctx, item.ObjectType.GetResourceType(), tenant, entity)
   144  }
   145  
   146  // UpdateGlobal updates a fetch request globally without tenant isolation
   147  func (r *repository) UpdateGlobal(ctx context.Context, item *model.FetchRequest) error {
   148  	if item == nil {
   149  		return apperrors.NewInternalError("item cannot be nil")
   150  	}
   151  	entity, err := r.conv.ToEntity(item)
   152  	if err != nil {
   153  		return err
   154  	}
   155  	return r.updaterGlobal.UpdateSingleGlobal(ctx, entity)
   156  }
   157  
   158  func (r *repository) ListByReferenceObjectIDs(ctx context.Context, tenant string, objectType model.FetchRequestReferenceObjectType, objectIDs []string) ([]*model.FetchRequest, error) {
   159  	fieldName, err := r.referenceObjectFieldName(objectType)
   160  	if err != nil {
   161  		return nil, err
   162  	}
   163  
   164  	conditions := r.buildConditionsForReferenceObjectIDs(objectIDs, fieldName)
   165  
   166  	var fetchRequestCollection FetchRequestsCollection
   167  	if err = r.lister.List(ctx, objectType.GetResourceType(), tenant, &fetchRequestCollection, conditions...); err != nil {
   168  		return nil, err
   169  	}
   170  
   171  	return r.enrichFetchRequestModel(fetchRequestCollection, fieldName, objectType, objectIDs)
   172  }
   173  
   174  // ListByReferenceObjectIDsGlobal lists fetch requests by reference objects IDs without tenant isolation
   175  func (r *repository) ListByReferenceObjectIDsGlobal(ctx context.Context, objectType model.FetchRequestReferenceObjectType, objectIDs []string) ([]*model.FetchRequest, error) {
   176  	fieldName, err := r.referenceObjectFieldName(objectType)
   177  	if err != nil {
   178  		return nil, err
   179  	}
   180  
   181  	conditions := r.buildConditionsForReferenceObjectIDs(objectIDs, fieldName)
   182  
   183  	var fetchRequestCollection FetchRequestsCollection
   184  	if err = r.listerGlobal.ListGlobal(ctx, &fetchRequestCollection, conditions...); err != nil {
   185  		return nil, err
   186  	}
   187  
   188  	return r.enrichFetchRequestModel(fetchRequestCollection, fieldName, objectType, objectIDs)
   189  }
   190  
   191  func (r *repository) referenceObjectFieldName(objectType model.FetchRequestReferenceObjectType) (string, error) {
   192  	switch objectType {
   193  	case model.DocumentFetchRequestReference:
   194  		return documentIDColumn, nil
   195  	case model.EventSpecFetchRequestReference:
   196  		fallthrough
   197  	case model.APISpecFetchRequestReference:
   198  		return specIDColumn, nil
   199  	}
   200  
   201  	return "", apperrors.NewInternalError("Invalid type of the Fetch Request reference object")
   202  }
   203  
   204  func (r *repository) buildConditionsForReferenceObjectIDs(objectIDs []string, fieldName string) repo.Conditions {
   205  	var conditions repo.Conditions
   206  	if len(objectIDs) > 0 {
   207  		conditions = repo.Conditions{
   208  			repo.NewInConditionForStringValues(fieldName, objectIDs),
   209  		}
   210  	}
   211  
   212  	return conditions
   213  }
   214  
   215  func (r *repository) enrichFetchRequestModel(fetchRequestCollection FetchRequestsCollection, fieldName string, objectType model.FetchRequestReferenceObjectType, objectIDs []string) ([]*model.FetchRequest, error) {
   216  	fetchRequestsByID := map[string]*model.FetchRequest{}
   217  	for _, fetchRequestEnt := range fetchRequestCollection {
   218  		m, err := r.conv.FromEntity(&fetchRequestEnt, objectType)
   219  		if err != nil {
   220  			return nil, errors.Wrap(err, "while creating FetchRequest model from entity")
   221  		}
   222  
   223  		if fieldName == specIDColumn {
   224  			fetchRequestsByID[fetchRequestEnt.SpecID.String] = m
   225  		} else if fieldName == documentIDColumn {
   226  			fetchRequestsByID[fetchRequestEnt.DocumentID.String] = m
   227  		}
   228  	}
   229  
   230  	fetchRequests := make([]*model.FetchRequest, 0, len(objectIDs))
   231  	for _, objectID := range objectIDs {
   232  		fetchRequests = append(fetchRequests, fetchRequestsByID[objectID])
   233  	}
   234  
   235  	return fetchRequests, nil
   236  }
   237  
   238  // FetchRequestsCollection missing godoc
   239  type FetchRequestsCollection []Entity
   240  
   241  // Len missing godoc
   242  func (r FetchRequestsCollection) Len() int {
   243  	return len(r)
   244  }