// Save updates the given space in the db. Version must be the same as the one in the stored version // returns NotFoundError, BadParameterError, VersionConflictError or InternalError func (r *GormRepository) Save(ctx context.Context, p *Space) (*Space, error) { pr := Space{} tx := r.db.Where("id=?", p.ID).First(&pr) oldVersion := p.Version p.Version++ if tx.RecordNotFound() { // treating this as a not found error: the fact that we're using number internal is implementation detail return nil, errors.NewNotFoundError("space", p.ID.String()) } if err := tx.Error; err != nil { return nil, errors.NewInternalError(err.Error()) } tx = tx.Where("Version = ?", oldVersion).Save(p) if err := tx.Error; err != nil { if gormsupport.IsCheckViolation(tx.Error, "spaces_name_check") { return nil, errors.NewBadParameterError("Name", p.Name).Expected("not empty") } if gormsupport.IsUniqueViolation(tx.Error, "spaces_name_idx") { return nil, errors.NewBadParameterError("Name", p.Name).Expected("unique") } return nil, errors.NewInternalError(err.Error()) } if tx.RowsAffected == 0 { return nil, errors.NewVersionConflictError("version conflict") } log.Info(ctx, map[string]interface{}{ "pkg": "space", "spaceID": p.ID, }, "space updated successfully") return p, nil }
// Save updates the given work item link in storage. Version must be the same as the one int the stored version. // returns NotFoundError, VersionConflictError, ConversionError or InternalError func (r *GormWorkItemLinkRepository) Save(ctx context.Context, lt app.WorkItemLinkSingle) (*app.WorkItemLinkSingle, error) { res := WorkItemLink{} if lt.Data.ID == nil { return nil, errors.NewBadParameterError("work item link", nil) } db := r.db.Model(&res).Where("id=?", *lt.Data.ID).First(&res) if db.RecordNotFound() { log.Error(ctx, map[string]interface{}{ "wilID": *lt.Data.ID, }, "work item link not found") return nil, errors.NewNotFoundError("work item link", *lt.Data.ID) } if db.Error != nil { log.Error(ctx, map[string]interface{}{ "wilID": *lt.Data.ID, "err": db.Error, }, "unable to find work item link") return nil, errors.NewInternalError(db.Error.Error()) } if lt.Data.Attributes.Version == nil || res.Version != *lt.Data.Attributes.Version { return nil, errors.NewVersionConflictError("version conflict") } if err := ConvertLinkToModel(lt, &res); err != nil { return nil, errs.WithStack(err) } res.Version = res.Version + 1 if err := r.ValidateCorrectSourceAndTargetType(ctx, res.SourceID, res.TargetID, res.LinkTypeID); err != nil { return nil, errs.WithStack(err) } db = r.db.Save(&res) if db.Error != nil { log.Error(ctx, map[string]interface{}{ "wilID": res.ID, "err": db.Error, }, "unable to save work item link") return nil, errors.NewInternalError(db.Error.Error()) } log.Info(ctx, map[string]interface{}{ "pkg": "link", "wilID": res.ID, }, "Work item link updated") result := ConvertLinkFromModel(res) return &result, nil }
// Save updates the given work item in storage. Version must be the same as the one int the stored version // returns NotFoundError, VersionConflictError, ConversionError or InternalError func (r *GormWorkItemRepository) Save(ctx context.Context, wi app.WorkItem) (*app.WorkItem, error) { res := WorkItem{} id, err := strconv.ParseUint(wi.ID, 10, 64) if err != nil || id == 0 { return nil, errors.NewNotFoundError("work item", wi.ID) } log.Info(ctx, map[string]interface{}{ "pkg": "workitem", "wiID": wi.ID, }, "Looking for id for the work item repository") tx := r.db.First(&res, id) if tx.RecordNotFound() { log.Error(ctx, map[string]interface{}{ "wiID": wi.ID, }, "work item repository not found") return nil, errors.NewNotFoundError("work item", wi.ID) } if tx.Error != nil { return nil, errors.NewInternalError(err.Error()) } if res.Version != wi.Version { return nil, errors.NewVersionConflictError("version conflict") } wiType, err := r.wir.LoadTypeFromDB(ctx, wi.Type) if err != nil { return nil, errors.NewBadParameterError("Type", wi.Type) } res.Version = res.Version + 1 res.Type = wi.Type res.Fields = Fields{} for fieldName, fieldDef := range wiType.Fields { if fieldName == SystemCreatedAt { continue } fieldValue := wi.Fields[fieldName] var err error res.Fields[fieldName], err = fieldDef.ConvertToModel(fieldName, fieldValue) if err != nil { return nil, errors.NewBadParameterError(fieldName, fieldValue) } } tx = tx.Where("Version = ?", wi.Version).Save(&res) if err := tx.Error; err != nil { log.Error(ctx, map[string]interface{}{ "wiID": wi.ID, "err": err, }, "unable to save the work item repository") return nil, errors.NewInternalError(err.Error()) } if tx.RowsAffected == 0 { return nil, errors.NewVersionConflictError("version conflict") } log.Info(ctx, map[string]interface{}{ "pkg": "workitem", "wiID": wi.ID, }, "Updated work item repository") return convertWorkItemModelToApp(wiType, &res) }
// Save updates the given work item link category in storage. Version must be the same as the one int the stored version. // returns NotFoundError, VersionConflictError, ConversionError or InternalError func (r *GormWorkItemLinkCategoryRepository) Save(ctx context.Context, linkCat app.WorkItemLinkCategorySingle) (*app.WorkItemLinkCategorySingle, error) { res := WorkItemLinkCategory{} if linkCat.Data.ID == nil { return nil, errors.NewBadParameterError("data.id", linkCat.Data.ID) } id, err := satoriuuid.FromString(*linkCat.Data.ID) if err != nil { log.Error(ctx, map[string]interface{}{ "wilcID": *linkCat.Data.ID, "err": err, }, "error when converting %s to UUID: %s", *linkCat.Data.ID, err.Error()) // treat as not found: clients don't know it must be a UUID return nil, errors.NewNotFoundError("work item link category", id.String()) } if linkCat.Data.Type != EndpointWorkItemLinkCategories { return nil, errors.NewBadParameterError("data.type", linkCat.Data.Type).Expected(EndpointWorkItemLinkCategories) } // If the name is not nil, it MUST NOT be empty if linkCat.Data.Attributes.Name != nil && *linkCat.Data.Attributes.Name == "" { return nil, errors.NewBadParameterError("data.attributes.name", *linkCat.Data.Attributes.Name) } db := r.db.Model(&res).Where("id=?", *linkCat.Data.ID).First(&res) if db.RecordNotFound() { log.Error(ctx, map[string]interface{}{ "wilcID": *linkCat.Data.ID, }, "work item link category not found") return nil, errors.NewNotFoundError("work item link category", id.String()) } if db.Error != nil { log.Error(ctx, map[string]interface{}{ "wilcID": *linkCat.Data.ID, "err": db.Error, }, "unable to find work item link category") return nil, errors.NewInternalError(db.Error.Error()) } if linkCat.Data.Attributes.Version == nil || res.Version != *linkCat.Data.Attributes.Version { return nil, errors.NewVersionConflictError("version conflict") } newLinkCat := WorkItemLinkCategory{ ID: id, Version: *linkCat.Data.Attributes.Version + 1, } if linkCat.Data.Attributes.Name != nil { newLinkCat.Name = *linkCat.Data.Attributes.Name } if linkCat.Data.Attributes.Description != nil { newLinkCat.Description = linkCat.Data.Attributes.Description } db = db.Save(&newLinkCat) if db.Error != nil { log.Error(ctx, map[string]interface{}{ "wilcID": newLinkCat.ID, "err": db.Error, }, "unable to save work item link category repository") return nil, errors.NewInternalError(db.Error.Error()) } log.Info(ctx, map[string]interface{}{ "pkg": "link", "wilcID": newLinkCat.ID, "newLinkCategory": newLinkCat, }, "Work item link category updated") result := ConvertLinkCategoryFromModel(newLinkCat) return &result, nil }