package model import ( "context" "encoding/json" "errors" "github.com/jinzhu/gorm" "github.com/jinzhu/gorm/dialects/postgres" errs "github.com/pkg/errors" ) var ( ErrMissingWorkgroup = errs.New("missing workgroup") ErrInvalidWorkgroup = errs.New("invalid workgroup") ErrDecisionSupportFileDoesNotExist = errs.New("decision support file does not exist") ) type DSFRepository struct { db *gorm.DB } func (r *DSFRepository) Create(ctx context.Context, changes *DecisionSupportFileChanges) (*DecisionSupportFile, error) { dsf := &DecisionSupportFile{} if err := r.updateFromChanges(dsf, changes); err != nil { return nil, errs.WithStack(err) } if err := r.db.Save(&dsf).Error; err != nil { return nil, errs.WithStack(err) } return dsf, nil } func (r *DSFRepository) Update(ctx context.Context, id string, changes *DecisionSupportFileChanges) (*DecisionSupportFile, error) { dsf := &DecisionSupportFile{} if err := r.db.Find(dsf, "id = ?", id).Error; err != nil { return nil, errs.WithStack(err) } if err := r.updateFromChanges(dsf, changes); err != nil { return nil, errs.WithStack(err) } if err := r.db.Save(dsf).Error; err != nil { return nil, errs.WithStack(err) } return dsf, nil } func (r *DSFRepository) updateFromChanges(dsf *DecisionSupportFile, changes *DecisionSupportFileChanges) error { if changes.WorkgroupID == nil { return errs.WithStack(ErrMissingWorkgroup) } wg := &Workgroup{} if err := r.db.Model(wg).First(wg, "id = ?", changes.WorkgroupID).Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return errs.WithStack(ErrInvalidWorkgroup) } return errs.WithStack(err) } dsf.Workgroup = wg if changes.Sections != nil { rawSections, err := json.Marshal(changes.Sections) if err != nil { return errs.WithStack(err) } dsf.Sections = postgres.Jsonb{RawMessage: rawSections} } if changes.Title != nil { dsf.Title = *changes.Title } if changes.Status != nil { dsf.Status = *changes.Status } return nil } func (r *DSFRepository) Find(ctx context.Context, id string) (*DecisionSupportFile, error) { dsf := &DecisionSupportFile{} query := r.db.Model(dsf).Preload("Workgroup").Where("id = ?", id) if err := query.First(&dsf).Error; err != nil { return nil, errs.WithStack(err) } return dsf, nil } func (r *DSFRepository) Search(ctx context.Context, filter *DecisionSupportFileFilter) ([]*DecisionSupportFile, error) { query := r.db.Model(&DecisionSupportFile{}).Preload("Workgroup") if filter != nil { if filter.Ids != nil { query = query.Where("id in (?)", filter.Ids) } } dsfs := make([]*DecisionSupportFile, 0) if err := query.Find(&dsfs).Error; err != nil { return nil, errs.WithStack(err) } return dsfs, nil } func NewDSFRepository(db *gorm.DB) *DSFRepository { return &DSFRepository{db} }