mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-26 13:29:05 +01:00
Better implementation for querying multiple users
This commit is contained in:
parent
bf6ec1bc98
commit
09bcf9f355
@ -201,7 +201,6 @@ input JobFilter {
|
|||||||
jobId: StringInput
|
jobId: StringInput
|
||||||
arrayJobId: Int
|
arrayJobId: Int
|
||||||
user: StringInput
|
user: StringInput
|
||||||
multiUser: [String]
|
|
||||||
project: StringInput
|
project: StringInput
|
||||||
jobName: StringInput
|
jobName: StringInput
|
||||||
cluster: StringInput
|
cluster: StringInput
|
||||||
@ -237,6 +236,7 @@ input StringInput {
|
|||||||
contains: String
|
contains: String
|
||||||
startsWith: String
|
startsWith: String
|
||||||
endsWith: String
|
endsWith: String
|
||||||
|
in: [String!]
|
||||||
}
|
}
|
||||||
|
|
||||||
input IntRange { from: Int!, to: Int! }
|
input IntRange { from: Int!, to: Int! }
|
||||||
|
@ -1592,7 +1592,6 @@ input JobFilter {
|
|||||||
jobId: StringInput
|
jobId: StringInput
|
||||||
arrayJobId: Int
|
arrayJobId: Int
|
||||||
user: StringInput
|
user: StringInput
|
||||||
multiUser: [String]
|
|
||||||
project: StringInput
|
project: StringInput
|
||||||
jobName: StringInput
|
jobName: StringInput
|
||||||
cluster: StringInput
|
cluster: StringInput
|
||||||
@ -1628,6 +1627,7 @@ input StringInput {
|
|||||||
contains: String
|
contains: String
|
||||||
startsWith: String
|
startsWith: String
|
||||||
endsWith: String
|
endsWith: String
|
||||||
|
in: [String!]
|
||||||
}
|
}
|
||||||
|
|
||||||
input IntRange { from: Int!, to: Int! }
|
input IntRange { from: Int!, to: Int! }
|
||||||
@ -10445,7 +10445,7 @@ func (ec *executionContext) unmarshalInputJobFilter(ctx context.Context, obj int
|
|||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"tags", "jobId", "arrayJobId", "user", "multiUser", "project", "jobName", "cluster", "partition", "duration", "minRunningFor", "numNodes", "numAccelerators", "numHWThreads", "startTime", "state", "flopsAnyAvg", "memBwAvg", "loadAvg", "memUsedMax"}
|
fieldsInOrder := [...]string{"tags", "jobId", "arrayJobId", "user", "project", "jobName", "cluster", "partition", "duration", "minRunningFor", "numNodes", "numAccelerators", "numHWThreads", "startTime", "state", "flopsAnyAvg", "memBwAvg", "loadAvg", "memUsedMax"}
|
||||||
for _, k := range fieldsInOrder {
|
for _, k := range fieldsInOrder {
|
||||||
v, ok := asMap[k]
|
v, ok := asMap[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -10484,14 +10484,6 @@ func (ec *executionContext) unmarshalInputJobFilter(ctx context.Context, obj int
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
case "multiUser":
|
|
||||||
var err error
|
|
||||||
|
|
||||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("multiUser"))
|
|
||||||
it.MultiUser, err = ec.unmarshalOString2ᚕᚖstring(ctx, v)
|
|
||||||
if err != nil {
|
|
||||||
return it, err
|
|
||||||
}
|
|
||||||
case "project":
|
case "project":
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -10701,7 +10693,7 @@ func (ec *executionContext) unmarshalInputStringInput(ctx context.Context, obj i
|
|||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"eq", "contains", "startsWith", "endsWith"}
|
fieldsInOrder := [...]string{"eq", "contains", "startsWith", "endsWith", "in"}
|
||||||
for _, k := range fieldsInOrder {
|
for _, k := range fieldsInOrder {
|
||||||
v, ok := asMap[k]
|
v, ok := asMap[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -10740,6 +10732,14 @@ func (ec *executionContext) unmarshalInputStringInput(ctx context.Context, obj i
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
|
case "in":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("in"))
|
||||||
|
it.In, err = ec.unmarshalOString2ᚕstringᚄ(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14671,38 +14671,6 @@ func (ec *executionContext) marshalOString2ᚕstringᚄ(ctx context.Context, sel
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalOString2ᚕᚖstring(ctx context.Context, v interface{}) ([]*string, error) {
|
|
||||||
if v == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
var vSlice []interface{}
|
|
||||||
if v != nil {
|
|
||||||
vSlice = graphql.CoerceList(v)
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
res := make([]*string, len(vSlice))
|
|
||||||
for i := range vSlice {
|
|
||||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i))
|
|
||||||
res[i], err = ec.unmarshalOString2ᚖstring(ctx, vSlice[i])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) marshalOString2ᚕᚖstring(ctx context.Context, sel ast.SelectionSet, v []*string) graphql.Marshaler {
|
|
||||||
if v == nil {
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
ret := make(graphql.Array, len(v))
|
|
||||||
for i := range v {
|
|
||||||
ret[i] = ec.marshalOString2ᚖstring(ctx, sel, v[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) {
|
func (ec *executionContext) unmarshalOString2ᚖstring(ctx context.Context, v interface{}) (*string, error) {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -41,7 +41,6 @@ type JobFilter struct {
|
|||||||
JobID *StringInput `json:"jobId"`
|
JobID *StringInput `json:"jobId"`
|
||||||
ArrayJobID *int `json:"arrayJobId"`
|
ArrayJobID *int `json:"arrayJobId"`
|
||||||
User *StringInput `json:"user"`
|
User *StringInput `json:"user"`
|
||||||
MultiUser []*string `json:"multiUser"`
|
|
||||||
Project *StringInput `json:"project"`
|
Project *StringInput `json:"project"`
|
||||||
JobName *StringInput `json:"jobName"`
|
JobName *StringInput `json:"jobName"`
|
||||||
Cluster *StringInput `json:"cluster"`
|
Cluster *StringInput `json:"cluster"`
|
||||||
@ -104,10 +103,11 @@ type PageRequest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type StringInput struct {
|
type StringInput struct {
|
||||||
Eq *string `json:"eq"`
|
Eq *string `json:"eq"`
|
||||||
Contains *string `json:"contains"`
|
Contains *string `json:"contains"`
|
||||||
StartsWith *string `json:"startsWith"`
|
StartsWith *string `json:"startsWith"`
|
||||||
EndsWith *string `json:"endsWith"`
|
EndsWith *string `json:"endsWith"`
|
||||||
|
In []string `json:"in"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TimeRangeOutput struct {
|
type TimeRangeOutput struct {
|
||||||
|
@ -118,13 +118,6 @@ func BuildWhereClause(filter *model.JobFilter, query sq.SelectBuilder) sq.Select
|
|||||||
if filter.User != nil {
|
if filter.User != nil {
|
||||||
query = buildStringCondition("job.user", filter.User, query)
|
query = buildStringCondition("job.user", filter.User, query)
|
||||||
}
|
}
|
||||||
if filter.MultiUser != nil {
|
|
||||||
queryUsers := make([]string, len(filter.MultiUser))
|
|
||||||
for i, val := range filter.MultiUser {
|
|
||||||
queryUsers[i] = *val
|
|
||||||
}
|
|
||||||
query = query.Where(sq.Or{sq.Eq{"job.user": queryUsers}})
|
|
||||||
}
|
|
||||||
if filter.Project != nil {
|
if filter.Project != nil {
|
||||||
query = buildStringCondition("job.project", filter.Project, query)
|
query = buildStringCondition("job.project", filter.Project, query)
|
||||||
}
|
}
|
||||||
@ -213,6 +206,13 @@ func buildStringCondition(field string, cond *model.StringInput, query sq.Select
|
|||||||
if cond.Contains != nil {
|
if cond.Contains != nil {
|
||||||
return query.Where(field+" LIKE ?", fmt.Sprint("%", *cond.Contains, "%"))
|
return query.Where(field+" LIKE ?", fmt.Sprint("%", *cond.Contains, "%"))
|
||||||
}
|
}
|
||||||
|
if cond.In != nil {
|
||||||
|
queryUsers := make([]string, len(cond.In))
|
||||||
|
for i, val := range cond.In {
|
||||||
|
queryUsers[i] = val
|
||||||
|
}
|
||||||
|
return query.Where(sq.Or{sq.Eq{"job.user": queryUsers}})
|
||||||
|
}
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,12 +184,14 @@ func buildFilterPresets(query url.Values) map[string]interface{} {
|
|||||||
if query.Get("jobName") != "" {
|
if query.Get("jobName") != "" {
|
||||||
filterPresets["jobName"] = query.Get("jobName")
|
filterPresets["jobName"] = query.Get("jobName")
|
||||||
}
|
}
|
||||||
if query.Get("user") != "" {
|
if len(query["user"]) != 0 {
|
||||||
filterPresets["user"] = query.Get("user")
|
if len(query["user"]) == 1 {
|
||||||
filterPresets["userMatch"] = "contains"
|
filterPresets["user"] = query.Get("user")
|
||||||
}
|
filterPresets["userMatch"] = "contains"
|
||||||
if len(query["multiUser"]) != 0 {
|
} else {
|
||||||
filterPresets["multiUser"] = query["multiUser"]
|
filterPresets["user"] = query["user"]
|
||||||
|
filterPresets["userMatch"] = "in"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if len(query["state"]) != 0 {
|
if len(query["state"]) != 0 {
|
||||||
filterPresets["state"] = query["state"]
|
filterPresets["state"] = query["state"]
|
||||||
@ -339,8 +341,8 @@ func HandleSearchBar(rw http.ResponseWriter, r *http.Request, api *api.RestApi)
|
|||||||
http.Redirect(rw, r, "/monitoring/user/"+usernames[0], http.StatusTemporaryRedirect)
|
http.Redirect(rw, r, "/monitoring/user/"+usernames[0], http.StatusTemporaryRedirect)
|
||||||
return
|
return
|
||||||
} else if len(usernames) > 1 {
|
} else if len(usernames) > 1 {
|
||||||
joinedNames := strings.Join(usernames, "&multiUser=")
|
joinedNames := strings.Join(usernames, "&user=")
|
||||||
http.Redirect(rw, r, "/monitoring/users/?multiUser="+joinedNames, http.StatusTemporaryRedirect) // > 1 Matches: Redirect to user table
|
http.Redirect(rw, r, "/monitoring/users/?user="+joinedNames, http.StatusTemporaryRedirect) // > 1 Matches: Redirect to user table
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
http.Redirect(rw, r, "/monitoring/users/?user=NotFound", http.StatusTemporaryRedirect) // Workaround to display correctly empty table
|
http.Redirect(rw, r, "/monitoring/users/?user=NotFound", http.StatusTemporaryRedirect) // Workaround to display correctly empty table
|
||||||
|
@ -46,7 +46,6 @@
|
|||||||
user: filterPresets.user || '',
|
user: filterPresets.user || '',
|
||||||
project: filterPresets.project || '',
|
project: filterPresets.project || '',
|
||||||
jobName: filterPresets.jobName || '',
|
jobName: filterPresets.jobName || '',
|
||||||
multiUser: filterPresets.multiUser || [],
|
|
||||||
|
|
||||||
numNodes: filterPresets.numNodes || { from: null, to: null },
|
numNodes: filterPresets.numNodes || { from: null, to: null },
|
||||||
numHWThreads: filterPresets.numHWThreads || { from: null, to: null },
|
numHWThreads: filterPresets.numHWThreads || { from: null, to: null },
|
||||||
@ -94,8 +93,6 @@
|
|||||||
items.push({ numAccelerators: { from: filters.numAccelerators.from, to: filters.numAccelerators.to } })
|
items.push({ numAccelerators: { from: filters.numAccelerators.from, to: filters.numAccelerators.to } })
|
||||||
if (filters.user)
|
if (filters.user)
|
||||||
items.push({ user: { [filters.userMatch]: filters.user } })
|
items.push({ user: { [filters.userMatch]: filters.user } })
|
||||||
if (filters.multiUser.length != 0)
|
|
||||||
items.push({ multiUser: filters.multiUser })
|
|
||||||
if (filters.project)
|
if (filters.project)
|
||||||
items.push({ project: { [filters.projectMatch]: filters.project } })
|
items.push({ project: { [filters.projectMatch]: filters.project } })
|
||||||
if (filters.jobName)
|
if (filters.jobName)
|
||||||
@ -129,11 +126,13 @@
|
|||||||
opts.push(`numNodes=${filters.numNodes.from}-${filters.numNodes.to}`)
|
opts.push(`numNodes=${filters.numNodes.from}-${filters.numNodes.to}`)
|
||||||
if (filters.numAccelerators.from && filters.numAccelerators.to)
|
if (filters.numAccelerators.from && filters.numAccelerators.to)
|
||||||
opts.push(`numAccelerators=${filters.numAccelerators.from}-${filters.numAccelerators.to}`)
|
opts.push(`numAccelerators=${filters.numAccelerators.from}-${filters.numAccelerators.to}`)
|
||||||
if (filters.user)
|
if (filters.user.length != 0)
|
||||||
opts.push(`user=${filters.user}`)
|
if (filters.userMatch != 'in') {
|
||||||
if (filters.multiUser.length != 0)
|
opts.push(`user=${filters.user}`)
|
||||||
for (let singleUser of filters.multiUser)
|
} else {
|
||||||
opts.push(`multiUser=${singleUser}`)
|
for (let singleUser of filters.user)
|
||||||
|
opts.push(`user=${singleUser}`)
|
||||||
|
}
|
||||||
if (filters.userMatch != 'contains')
|
if (filters.userMatch != 'contains')
|
||||||
opts.push(`userMatch=${filters.userMatch}`)
|
opts.push(`userMatch=${filters.userMatch}`)
|
||||||
if (filters.project)
|
if (filters.project)
|
||||||
|
Loading…
Reference in New Issue
Block a user