mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-26 05:19:05 +01:00
fix tag count bug if names non-unique, set global as default scope if none entered
This commit is contained in:
parent
fe35313305
commit
beba7c8d2e
@ -688,6 +688,7 @@ func (api *RestApi) editMeta(rw http.ResponseWriter, r *http.Request) {
|
|||||||
// @summary Adds one or more tags to a job
|
// @summary Adds one or more tags to a job
|
||||||
// @tags Job add and modify
|
// @tags Job add and modify
|
||||||
// @description Adds tag(s) to a job specified by DB ID. Name and Type of Tag(s) can be chosen freely.
|
// @description Adds tag(s) to a job specified by DB ID. Name and Type of Tag(s) can be chosen freely.
|
||||||
|
// @description Tag Scope for frontend visibility will default to "global" if none entered, other options: "admin" or specific username.
|
||||||
// @description If tagged job is already finished: Tag will be written directly to respective archive files.
|
// @description If tagged job is already finished: Tag will be written directly to respective archive files.
|
||||||
// @accept json
|
// @accept json
|
||||||
// @produce json
|
// @produce json
|
||||||
|
@ -81,6 +81,12 @@ func (r *JobRepository) RemoveTag(ctx context.Context, job, tag int64) ([]*schem
|
|||||||
|
|
||||||
// CreateTag creates a new tag with the specified type and name and returns its database id.
|
// CreateTag creates a new tag with the specified type and name and returns its database id.
|
||||||
func (r *JobRepository) CreateTag(tagType string, tagName string, tagScope string) (tagId int64, err error) {
|
func (r *JobRepository) CreateTag(tagType string, tagName string, tagScope string) (tagId int64, err error) {
|
||||||
|
|
||||||
|
// Default to "Global" scope if none defined
|
||||||
|
if tagScope == "" {
|
||||||
|
tagScope = "global"
|
||||||
|
}
|
||||||
|
|
||||||
q := sq.Insert("tag").Columns("tag_type", "tag_name", "tag_scope").Values(tagType, tagName, tagScope)
|
q := sq.Insert("tag").Columns("tag_type", "tag_name", "tag_scope").Values(tagType, tagName, tagScope)
|
||||||
|
|
||||||
res, err := q.RunWith(r.stmtCache).Exec()
|
res, err := q.RunWith(r.stmtCache).Exec()
|
||||||
@ -120,7 +126,7 @@ func (r *JobRepository) CountTags(ctx context.Context) (tags []schema.Tag, count
|
|||||||
user := GetUserFromContext(ctx)
|
user := GetUserFromContext(ctx)
|
||||||
|
|
||||||
// Query and Count Jobs with attached Tags
|
// Query and Count Jobs with attached Tags
|
||||||
q := sq.Select("t.tag_name, count(jt.tag_id)").
|
q := sq.Select("t.tag_name, t.id, count(jt.tag_id)").
|
||||||
From("tag t").
|
From("tag t").
|
||||||
LeftJoin("jobtag jt ON t.id = jt.tag_id").
|
LeftJoin("jobtag jt ON t.id = jt.tag_id").
|
||||||
GroupBy("t.tag_name")
|
GroupBy("t.tag_name")
|
||||||
@ -137,7 +143,7 @@ func (r *JobRepository) CountTags(ctx context.Context) (tags []schema.Tag, count
|
|||||||
|
|
||||||
// Handle Job Ownership
|
// Handle Job Ownership
|
||||||
if user != nil && user.HasAnyRole([]schema.Role{schema.RoleAdmin, schema.RoleSupport}) { // ADMIN || SUPPORT: Count all jobs
|
if user != nil && user.HasAnyRole([]schema.Role{schema.RoleAdmin, schema.RoleSupport}) { // ADMIN || SUPPORT: Count all jobs
|
||||||
log.Debug("CountTags: User Admin or Support -> Count all Jobs for Tags")
|
// log.Debug("CountTags: User Admin or Support -> Count all Jobs for Tags")
|
||||||
// Unchanged: Needs to be own case still, due to UserRole/NoRole compatibility handling in else case
|
// Unchanged: Needs to be own case still, due to UserRole/NoRole compatibility handling in else case
|
||||||
} else if user != nil && user.HasRole(schema.RoleManager) { // MANAGER: Count own jobs plus project's jobs
|
} else if user != nil && user.HasRole(schema.RoleManager) { // MANAGER: Count own jobs plus project's jobs
|
||||||
// Build ("project1", "project2", ...) list of variable length directly in SQL string
|
// Build ("project1", "project2", ...) list of variable length directly in SQL string
|
||||||
@ -154,11 +160,13 @@ func (r *JobRepository) CountTags(ctx context.Context) (tags []schema.Tag, count
|
|||||||
counts = make(map[string]int)
|
counts = make(map[string]int)
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var tagName string
|
var tagName string
|
||||||
|
var tagId int
|
||||||
var count int
|
var count int
|
||||||
if err = rows.Scan(&tagName, &count); err != nil {
|
if err = rows.Scan(&tagName, &tagId, &count); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
counts[tagName] = count
|
// Use tagId as second Map-Key component to differentiate tags with identical names
|
||||||
|
counts[fmt.Sprint(tagName, tagId)] = count
|
||||||
}
|
}
|
||||||
err = rows.Err()
|
err = rows.Err()
|
||||||
|
|
||||||
@ -169,6 +177,11 @@ func (r *JobRepository) CountTags(ctx context.Context) (tags []schema.Tag, count
|
|||||||
// If such a tag does not yet exist, it is created.
|
// If such a tag does not yet exist, it is created.
|
||||||
func (r *JobRepository) AddTagOrCreate(ctx context.Context, jobId int64, tagType string, tagName string, tagScope string) (tagId int64, err error) {
|
func (r *JobRepository) AddTagOrCreate(ctx context.Context, jobId int64, tagType string, tagName string, tagScope string) (tagId int64, err error) {
|
||||||
|
|
||||||
|
// Default to "Global" scope if none defined
|
||||||
|
if tagScope == "" {
|
||||||
|
tagScope = "global"
|
||||||
|
}
|
||||||
|
|
||||||
writable, err := r.checkScopeAuth(ctx, "write", tagScope)
|
writable, err := r.checkScopeAuth(ctx, "write", tagScope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
@ -237,7 +250,7 @@ func (r *JobRepository) GetTags(ctx context.Context, job *int64) ([]*schema.Tag,
|
|||||||
return tags, nil
|
return tags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetArchiveTags returns a list of all tags *regardless of scope* if job is nil or of the tags that the job with that database ID has.
|
// GetArchiveTags returns a list of all tags *regardless of scope* for archiving if job is nil or of the tags that the job with that database ID has.
|
||||||
func (r *JobRepository) getArchiveTags(job *int64) ([]*schema.Tag, error) {
|
func (r *JobRepository) getArchiveTags(job *int64) ([]*schema.Tag, error) {
|
||||||
q := sq.Select("id", "tag_type", "tag_name", "tag_scope").From("tag")
|
q := sq.Select("id", "tag_type", "tag_name", "tag_scope").From("tag")
|
||||||
if job != nil {
|
if job != nil {
|
||||||
|
@ -133,12 +133,13 @@ func setupTaglistRoute(i InfoType, r *http.Request) InfoType {
|
|||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Uses tag.ID as second Map-Key component to differentiate tags with identical names
|
||||||
for _, tag := range tags {
|
for _, tag := range tags {
|
||||||
tagItem := map[string]interface{}{
|
tagItem := map[string]interface{}{
|
||||||
"id": tag.ID,
|
"id": tag.ID,
|
||||||
"name": tag.Name,
|
"name": tag.Name,
|
||||||
"scope": tag.Scope,
|
"scope": tag.Scope,
|
||||||
"count": counts[tag.Name],
|
"count": counts[fmt.Sprint(tag.Name, tag.ID)],
|
||||||
}
|
}
|
||||||
tagMap[tag.Type] = append(tagMap[tag.Type], tagItem)
|
tagMap[tag.Type] = append(tagMap[tag.Type], tagItem)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user