// ConvertWorkItemLinkTypeFromModel converts a work item link type from model to REST representation
512435
func ConvertWorkItemLinkTypeFromModel(request *http.Request, modelLinkType link.WorkItemLinkType) app.WorkItemLinkTypeSingle {
	spaceTemplateRelatedURL := rest.AbsoluteURL(request, app.SpaceTemplateHref(modelLinkType.SpaceTemplateID.String()))
	spaceRelatedURL := rest.AbsoluteURL(request, app.SpaceHref(space.SystemSpace.String()))

	topologyStr := modelLinkType.Topology.String()
	var converted = app.WorkItemLinkTypeSingle{
		Data: &app.WorkItemLinkTypeData{
			Type: link.EndpointWorkItemLinkTypes,
			ID:   &modelLinkType.ID,
			Attributes: &app.WorkItemLinkTypeAttributes{
				Name:               &modelLinkType.Name,
				Description:        modelLinkType.Description,
				Version:            &modelLinkType.Version,
				CreatedAt:          &modelLinkType.CreatedAt,
				UpdatedAt:          &modelLinkType.UpdatedAt,
				ForwardName:        &modelLinkType.ForwardName,
				ForwardDescription: modelLinkType.ForwardDescription,
				ReverseName:        &modelLinkType.ReverseName,
				ReverseDescription: modelLinkType.ReverseDescription,
				Topology:           &topologyStr,
			},
			Relationships: &app.WorkItemLinkTypeRelationships{
				Space:         app.NewSpaceRelation(space.SystemSpace, spaceRelatedURL),
				SpaceTemplate: app.NewSpaceTemplateRelation(modelLinkType.SpaceTemplateID, spaceTemplateRelatedURL),
			},
		},
	}
	return converted
}
1002609
func enrichLinkTypeList(ctx *workItemLinkContext, list *app.WorkItemLinkTypeList) error {
	// Add "links" element
	for _, data := range list.Data {
		relatedURL := rest.AbsoluteURL(ctx.Request, ctx.LinkFunc(*data.ID))
		data.Links = &app.GenericLinks{
			Self:    &relatedURL,
			Related: &relatedURL,
		}
	}
	return nil
}
397768
func (list WorkItemLinkList) GetDistinctListOfTargetIDs(linkTypeID uuid.UUID) id.Slice {
	m := id.Map{}
	for _, l := range list {
		if l.LinkTypeID == linkTypeID {
			m[l.TargetID] = struct{}{}
		}
	}
	return m.ToSlice()
}
3597
func getWorkItemsByFilterExpression(ctx context.Context, db application.DB, filterExpression string, filterParentexists *bool, offset *int, limit *int) ([]workitem.WorkItem, link.WorkItemLinkList, link.AncestorList, error) {
	var result []workitem.WorkItem
	var childLinks link.WorkItemLinkList
	var parents link.AncestorList
	err := application.Transactional(db, func(appl application.Application) error {
		var err error
		// add tree option to query if not already present
		var reqMap map[string]interface{}
		err = json.Unmarshal([]byte(filterExpression), &reqMap)
		if err != nil {
			return errs.Errorf("error unmarshalling query expression for CSV filtering: %s", filterExpression)
		}
		if _, ok := reqMap["$OPTS"]; !ok {
			reqMap["$OPTS"] = make(map[string]interface{})
		}
		// Set "tree-view" to true. We always want tree-view to be enabled
		(reqMap["$OPTS"].(map[string]interface{}))["tree-view"] = true
		updatedFilterExpression, err := json.Marshal(reqMap)
		if err != nil {
			return errs.Errorf("error adding tree opt to query expression for CSV filtering: %s", filterExpression)
		}
		// execute query
		result, _, parents, childLinks, err = appl.SearchItems().Filter(ctx, string(updatedFilterExpression), filterParentexists, offset, limit)
		if err != nil {
			log.Error(ctx, map[string]interface{}{
				"err":               err,
				"filter_expression": filterExpression,
			}, "unable to list the work items")
			return errs.Wrapf(err, "error executing filter expression for CSV filtering: %s", filterExpression)
		}
		return nil
	})
	return result, childLinks, parents, err
}
557540
func extractWorkItemTypeFields(wit workitem.WorkItemType) ([]string, []string, error) {
	fieldLabels := []string{}
	fieldKeys := []string{}
	for fieldKey, fieldDefinition := range wit.Fields {
		// extract the label and key
		fieldLabels = append(fieldLabels, fieldDefinition.Label)
		fieldKeys = append(fieldKeys, fieldKey)
	}
	return fieldLabels, fieldKeys, nil
}
1273663
func ConvertBoardFromModel(request *http.Request, b workitem.Board) *app.WorkItemBoardData {
	res := &app.WorkItemBoardData{
		ID:   &b.ID,
		Type: APIWorkItemBoards,
		Links: &app.GenericLinks{
			Related: ptr.String(rest.AbsoluteURL(request, app.WorkItemBoardHref(b.ID))),
		},
		Attributes: &app.WorkItemBoardAttributes{
			Context:     b.Context,
			ContextType: b.ContextType,
			Name:        b.Name,
			CreatedAt:   ptr.Time(b.CreatedAt.UTC()),
			UpdatedAt:   ptr.Time(b.UpdatedAt.UTC()),
		},
		Relationships: &app.WorkItemBoardRelationships{
			Columns: &app.RelationGenericList{
				Data: make([]*app.GenericData, len(b.Columns)),
			},
			SpaceTemplate: &app.RelationGeneric{
				Data: &app.GenericData{
					ID:   ptr.String(b.SpaceTemplateID.String()),
					Type: &APISpaceTemplates,
				},
			},
		},
	}

	// iterate over the columns and attach them as an
	// included relationship
	for i, column := range b.Columns {
		res.Relationships.Columns.Data[i] = &app.GenericData{
			ID:   ptr.String(column.ID.String()),
			Type: ptr.String(APIBoardColumns),
		}
	}

	return res
}
280787
func (c *SearchController) enrichWorkItemList(ctx *app.ShowSearchContext, ancestors link.AncestorList, matchingIDs id.Slice, childLinks link.WorkItemLinkList, res *app.SearchWorkItemList, hasChildren WorkItemConvertFunc) error {
	parentIDs := id.Slice{}
	for _, wi := range res.Data {
		if wi.Relationships != nil && wi.Relationships.Parent != nil && wi.Relationships.Parent.Data != nil {
			parentIDs = append(parentIDs, wi.Relationships.Parent.Data.ID)
		}
	}

	// Also append the ancestors not already included in the parent list
	fetchInBatch := parentIDs
	fetchInBatch.Add(ancestors.GetDistinctAncestorIDs().Diff(parentIDs))

	// Append direct children of matching work items that have a child that is
	// also a match and are not yet in the list.
	nonMatchingChildItems := childLinks.GetDistinctListOfTargetIDs(link.SystemWorkItemLinkTypeParentChildID)
	fetchInBatch.Add(fetchInBatch.Diff(nonMatchingChildItems))

	// Eliminate work items already in the search
	fetchInBatch = fetchInBatch.Sub(matchingIDs)

	wis := []*workitem.WorkItem{}
	err := application.Transactional(c.db, func(appl application.Application) error {
		var err error
		wis, err = appl.WorkItems().LoadBatchByID(ctx, fetchInBatch)
		return err
	})
	if err != nil {
		log.Error(ctx, map[string]interface{}{
			"wis": wis,
			"err": err,
		}, "unable to load parent work items in batch: %s", fetchInBatch)
		return errs.Wrapf(err, "unable to load work item items in batch: %s", fetchInBatch)
	}

	for _, ele := range wis {
		wit, err := c.db.WorkItemTypes().Load(ctx.Context, ele.Type)
		if err != nil {
			return errs.Wrapf(err, "failed to load work item type: %s", ele.Type)
		}
		convertedWI, err := ConvertWorkItem(ctx.Request, *wit, *ele, hasChildren, includeParentWorkItem(ctx, ancestors, childLinks))
		if err != nil {
			return errs.WithStack(err)
		}
		res.Included = append(res.Included, *convertedWI)
	}
	return nil
}
767722
func (f FieldDefinition) ConvertFromModel(name string, value interface{}) (interface{}, error) {
	if f.Required && value == nil {
		return nil, fmt.Errorf("Value %s is required", name)
	}
	return f.Type.ConvertFromModel(value)
}
80159
func (c *DiscoveryController) processNextWorkItem() bool {
	key, quit := c.queue.Get()
	if quit {
		return false
	}
	defer c.queue.Done(key)

	err := c.syncFn(key.(schema.GroupVersion))
	if err == nil {
		c.queue.Forget(key)
		return true
	}

	utilruntime.HandleError(fmt.Errorf("%v failed with: %v", key, err))
	c.queue.AddRateLimited(key)

	return true
}
1068720
func ConvertTracker(request *http.Request, tracker remoteworkitem.Tracker) *app.Tracker {
	trackerStringType := remoteworkitem.APIStringTypeTrackers
	selfURL := rest.AbsoluteURL(request, app.TrackerHref(tracker.ID))
	t := &app.Tracker{
		Type: trackerStringType,
		ID:   &tracker.ID,
		Attributes: &app.TrackerAttributes{
			URL:  tracker.URL,
			Type: tracker.Type,
		},
		Links: &app.GenericLinks{
			Self: &selfURL,
		},
	}
	return t
}
1266220
func (c *Client) RegisterWorkflowType(request RegisterWorkflowType) error {
	err := c.swfReqNoResponse("RegisterWorkflowType", request)
	return err
}
565583
func NewWorkItemRelationshipsLinksController(service *goa.Service, db application.DB, config WorkItemRelationshipsLinksControllerConfig) *WorkItemRelationshipsLinksController {
	return &WorkItemRelationshipsLinksController{
		Controller: service.NewController("WorkItemRelationshipsLinksController"),
		db:         db,
		config:     config,
	}
}
401833
func IsLinkMetadataFromJSON(data []byte) (IsLinkMetadata, error) {
	var t linkMetadataUnion
	if err := json.Unmarshal(data, &t); err != nil {
		return nil, err
	}
	switch t.Tag {
	case "path":
		return t.Path, nil

	case "collection":
		return t.Collection, nil

	}
	return nil, nil
}
868619
func ConvertWorkItems(request *http.Request, wits []workitem.WorkItemType, wis []workitem.WorkItem, additional ...WorkItemConvertFunc) ([]*app.WorkItem, error) {
	ops := []*app.WorkItem{}
	if len(wits) != len(wis) {
		return nil, errs.Errorf("length mismatch of work items (%d) and work item types (%d)", len(wis), len(wits))
	}
	for i := 0; i < len(wis); i++ {
		wi, err := ConvertWorkItem(request, wits[i], wis[i], additional...)
		if err != nil {
			return nil, errs.Wrapf(err, "failed to convert work item: %s", wis[i].ID)
		}
		ops = append(ops, wi)
	}
	return ops, nil
}
386374
func (c *WorkItemLinkController) Create(ctx *app.CreateWorkItemLinkContext) error {
	currentUserIdentityID, err := login.ContextIdentity(ctx)
	if err != nil {
		return jsonapi.JSONErrorResponse(ctx, errors.NewUnauthorizedError(err.Error()))
	}
	modelLink, err := ConvertLinkToModel(app.WorkItemLinkSingle{
		Data: ctx.Payload.Data,
	})
	if err != nil {
		return jsonapi.JSONErrorResponse(ctx, err)
	}
	var createdModelLink *link.WorkItemLink
	err = application.Transactional(c.db, func(appl application.Application) error {
		var err error
		createdModelLink, err = appl.WorkItemLinks().Create(ctx.Context, modelLink.SourceID, modelLink.TargetID, modelLink.LinkTypeID, *currentUserIdentityID)
		return err
	})
	if err != nil {
		return jsonapi.JSONErrorResponse(ctx, err)
	}
	// convert from model to rest representation
	createdAppLink := ConvertLinkFromModel(ctx.Request, *createdModelLink)
	if err := enrichLinkSingle(ctx.Context, c.db, ctx.Request, &createdAppLink); err != nil {
		return jsonapi.JSONErrorResponse(ctx, err)
	}
	ctx.ResponseWriter.Header().Set("Location", app.WorkItemLinkHref(createdAppLink.Data.ID))
	return ctx.Created(&createdAppLink)
}
10865
func (r *GormWorkItemLinkRepository) ListWorkItemChildren(ctx context.Context, parentID uuid.UUID, start *int, limit *int) ([]workitem.WorkItem, int, error) {
	defer goa.MeasureSince([]string{"goa", "db", "workitemlink", "children", "query"}, time.Now())
	where := fmt.Sprintf(`
	id in (
		SELECT target_id FROM %s
		WHERE source_id = $1 AND link_type_id = $2 AND deleted_at IS NULL
	)`, WorkItemLink{}.TableName())
	baseDB := r.db.Model(&workitem.WorkItemStorage{}).Where(where, parentID.String(), SystemWorkItemLinkTypeParentChildID.String())
	if start != nil {
		if *start < 0 {
			return nil, 0, errors.NewBadParameterError("start", *start)
		}
		baseDB = baseDB.Offset(*start)
	}
	if limit != nil {
		if *limit <= 0 {
			return nil, 0, errors.NewBadParameterError("limit", *limit)
		}
		baseDB = baseDB.Limit(*limit)
	}
	db := baseDB.Select("count(*) over () as cnt2 , *").Order("execution_order desc")
	// To sort by title do this:
	// db = db.Select("count(*) over () as cnt2 , *").Order(fmt.Sprintf("fields->>'%s'", workitem.SystemTitle))
	rows, err := db.Rows()
	defer closeable.Close(ctx, rows)
	if err != nil {
		return nil, 0, err
	}
	result := []workitem.WorkItemStorage{}

	columns, err := rows.Columns()
	if err != nil {
		return nil, 0, errors.NewInternalError(ctx, err)
	}

	var count int
	var ignore interface{}
	columnValues := make([]interface{}, len(columns))

	for index := range columnValues {
		columnValues[index] = &ignore
	}
	columnValues[0] = &count
	first := true

	for rows.Next() {
		value := workitem.WorkItemStorage{}
		db.ScanRows(rows, &value)

		if first {
			first = false
			if err = rows.Scan(columnValues...); err != nil {
				return nil, 0, errors.NewInternalError(ctx, err)
			}
		}
		result = append(result, value)
	}

	if first {
		// means 0 rows were returned from the first query (maybe because of
		// offset outside of total count), need to do a count(*) to find out
		// total
		db := baseDB.Select("count(*)")
		if db.Error != nil {
			return nil, 0, errs.WithStack(db.Error)
		}
		rows2, err := db.Rows()
		defer closeable.Close(ctx, rows2)
		if err != nil {
			return nil, 0, errs.WithStack(err)
		}
		rows2.Next() // count(*) will always return a row
		rows2.Scan(&count)
	}

	res := make([]workitem.WorkItem, len(result))
	for index, value := range result {
		wiType, err := r.workItemTypeRepo.Load(ctx, value.Type)
		if err != nil {
			return nil, 0, errors.NewInternalError(ctx, err)
		}
		modelWI, err := workitem.ConvertWorkItemStorageToModel(wiType, &value)
		if err != nil {
			return nil, 0, errors.NewInternalError(ctx, err)
		}
		res[index] = *modelWI
	}

	return res, count, nil
}
1081547
func (c *SearchController) WorkitemsCSV(ctx *app.WorkitemsCSVSearchContext) error {
	if ctx.FilterExpression == nil {
		return goa.ErrBadRequest(fmt.Sprintf("bad parameter error exporting work items as CSV: param 'filter[expression]' missing"))
	}
	if ctx.PageLimit != nil && *(ctx.PageLimit) > 1000 {
		// the window size is too large
		return goa.ErrBadRequest("maximum limit value is 1000")
	}
	// set page size from query or use default
	limit := 100
	if ctx.PageLimit != nil {
		// we add an overflow indicator element
		limit = *(ctx.PageLimit) + 1
	}
	offset := 0
	if ctx.PageOffset != nil {
		offset = *(ctx.PageOffset)
	}
	// retrieve the first work item window to get a reference for the WITs
	wiResult, childsResult, parentsResult, err := getWorkItemsByFilterExpression(*ctx, c.db, *ctx.FilterExpression, ctx.FilterParentexists, &offset, &limit)
	if err != nil {
		return goa.ErrBadRequest(fmt.Sprintf("error searching work items for expression '%s': %s", *ctx.FilterExpression, err))
	}
	// set header data, adding timestamp to the filename
	currentTime := time.Now().UTC()
	timeStr := currentTime.Format(time.RFC3339)
	ctx.ResponseData.Header().Set("Content-Disposition", "attachment; filename='workitems-"+timeStr+".csv'")
	// see if we have a non-empty result set
	if len(wiResult) == 0 {
		// empty result, nothing matched the filter expression, we're done
		return ctx.OK([]byte(""))
	}
	// retrieve the spaceID from the returned first result entry
	spaceID := wiResult[0].SpaceID
	// retieve all WITs for this space
	var wits []workitem.WorkItemType
	err = application.Transactional(c.db, func(appl application.Application) error {
		var err error
		thisSpace, err := appl.Spaces().Load(ctx.Context, spaceID)
		if err != nil {
			log.Error(ctx, map[string]interface{}{
				"err":     err,
				"spaceID": spaceID,
			}, "unable to retrieve space")
			return errs.Wrapf(err, "error retrieving space for spaceID: %s", spaceID.String())
		}
		spaceTemplateID := thisSpace.SpaceTemplateID
		wits, err = appl.WorkItemTypes().List(ctx.Context, spaceTemplateID)
		if err != nil {
			log.Error(ctx, map[string]interface{}{
				"err":     err,
				"spaceID": spaceID,
			}, "unable to retrieve work item types")
			return errs.Wrapf(err, "error retrieving work item types for spaceID: %s", spaceID.String())
		}
		return nil
	})
	if err != nil {
		return goa.ErrBadRequest(fmt.Sprintf("error retrieving work item types for expression '%s': %s", *ctx.FilterExpression, err))
	}
	// the cache used for caching id to number resolve results
	idNumberCache := make(map[string]string)
	if ctx.PageLimit != nil {
		// if the overflow entry is in the result set, then there is more than this window, add a note to the bottom of the returned list
		moreMessage := ""
		if len(wiResult) >= limit {
			// there is an overflow, slice off the overflow item and add the message
			wiResult = wiResult[:len(wiResult)-1]
			moreMessage = "\nWIT_NOTE_MORE: There are more result entries. You may want to narrow down your query or use paging to retrieve more results."
		}
		// Convert them to CSV format the return value contains the final CSV
		wisCSV, _, err := ConvertWorkItemsToCSV(ctx.Context, c.db, wits, wiResult, childsResult, parentsResult, idNumberCache, true)
		if err != nil {
			return goa.ErrBadRequest(fmt.Sprintf("error converting work items to output format for expression '%s': %s", *ctx.FilterExpression, err))
		}
		// add the note to the bottom of the result csv (if there is a note)
		wisCSV = wisCSV + moreMessage
		// return to client
		return ctx.OK([]byte(wisCSV))
	}
	// we want to retrieve everything, first serialize the work items we already got
	wisCSV, _, err := ConvertWorkItemsToCSV(ctx.Context, c.db, wits, wiResult, childsResult, parentsResult, idNumberCache, true)
	if err != nil {
		return goa.ErrBadRequest(fmt.Sprintf("error converting work items to output format for expression '%s': %s", *ctx.FilterExpression, err))
	}
	// write them out to the client
	ctx.ResponseWriter.Write([]byte(wisCSV))
	// page over the database, convert and send in chunks to the client
	var wiResultWindow []workitem.WorkItem
	var childLinksWindow link.WorkItemLinkList
	var parentWindow link.AncestorList
	// we already fetched limit entries, so set offset
	offset = offset + limit
	// now iterate as long as the returned item count reaches the limit
	for {
		wiResultWindow, childLinksWindow, parentWindow, err = getWorkItemsByFilterExpression(ctx.Context, c.db, *ctx.FilterExpression, ctx.FilterParentexists, ptr.Int(offset), ptr.Int(limit))
		if err != nil {
			return goa.ErrBadRequest(fmt.Sprintf("error retrieving work item types for expression '%s': %s", *ctx.FilterExpression, err))
		}
		wisCSV, _, err = ConvertWorkItemsToCSV(ctx.Context, c.db, wits, wiResultWindow, childLinksWindow, parentWindow, idNumberCache, false)
		if err != nil {
			return goa.ErrBadRequest(fmt.Sprintf("error converting work items to output format for expression '%s': %s", *ctx.FilterExpression, err))
		}
		ctx.ResponseWriter.Write([]byte(wisCSV))
		if len(wiResultWindow) < limit {
			break
		}
		offset = offset + len(wiResultWindow)
	}
	// finally, return the result
	return ctx.OK(nil)
}