From 9d44fa867927ffdf958db36c7526fb6d9ac4250f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toma=C5=BE=20Jerman?= Date: Wed, 27 Jul 2022 15:13:36 +0200 Subject: [PATCH] Fix RDBMS filter construction for applications and flags * Add a new byFlag resource filter feature to support filtering using flags. False by default since only system applications use it. * Add filter definitions to flag pkg resource. * Add support for using []string inside byValue filters. --- app/resources.cue | 12 +++++++ .../gocode/store/rdbms/filters.go.tpl | 21 ++++++++++++ codegen/schema/resource.cue | 3 ++ codegen/server.store.cue | 1 + store/adapters/rdbms/filters.gen.go | 33 ++++++++++++++++++- system/apigw_filter.cue | 2 +- system/application.cue | 4 +++ 7 files changed, 74 insertions(+), 2 deletions(-) diff --git a/app/resources.cue b/app/resources.cue index ff71a12c4..3e9884fef 100644 --- a/app/resources.cue +++ b/app/resources.cue @@ -131,6 +131,18 @@ resources: { active: { goType: "bool"} } + filter: { + expIdent: "FlagFilter" + struct: { + kind: {} + resource_id: { goType: "[]uint64", ident: "resourceID", storeIdent: "rel_resource" } + owned_by: { goType: "[]uint64", ident: "ownedBy" } + name: { goType: "[]string", ident: "name" } + } + + byValue: ["kind", "resource_id", "owned_by", "name", ] + } + store: { api: { lookups: [ diff --git a/codegen/assets/templates/gocode/store/rdbms/filters.go.tpl b/codegen/assets/templates/gocode/store/rdbms/filters.go.tpl index 10d7849d0..755896eb5 100644 --- a/codegen/assets/templates/gocode/store/rdbms/filters.go.tpl +++ b/codegen/assets/templates/gocode/store/rdbms/filters.go.tpl @@ -52,6 +52,10 @@ func {{ .expIdent }}Filter(f {{ .goFilterType }})(ee []goqu.Expression, _ {{ .go if val := strings.TrimSpace(f.{{ .expIdent }}); len(val) > 0 { ee = append(ee, goqu.C({{ printf "%q" .storeIdent }}).Eq(f.{{ .expIdent }})) } + {{ else if eq .goType "[]string" }} + if ss := trimStringSlice(f.{{ .expIdent }}); len(ss) > 0 { + ee = append(ee, goqu.C({{ printf "%q" .storeIdent }}).In(ss)) + } {{ else if eq .goType "bool" }} if f.{{ .expIdent }} { ee = append(ee, goqu.C({{ printf "%q" .storeIdent }}).IsTrue()) @@ -76,6 +80,12 @@ func {{ .expIdent }}Filter(f {{ .goFilterType }})(ee []goqu.Expression, _ {{ .go } {{ end }} + {{ if .filter.byFlag }} + if len(f.FlaggedIDs) > 0 { + ee = append(ee, goqu.I("id").In(f.FlaggedIDs)) + } + {{ end }} + {{ if .filter.query }} if f.Query != "" { ee = append(ee, goqu.Or( @@ -89,3 +99,14 @@ func {{ .expIdent }}Filter(f {{ .goFilterType }})(ee []goqu.Expression, _ {{ .go return ee, f, err } {{ end }} + +// trimStringSlice is a utility to trim all of the string slice elements and omit empty ones +func trimStringSlice(in []string) []string { + out := make([]string, 0, len(in)) + for _, s := range in { + if t := strings.TrimSpace(s); len(t) > 0 { + out = append(out, t) + } + } + return out +} diff --git a/codegen/schema/resource.cue b/codegen/schema/resource.cue index ed05765d9..50a210f15 100644 --- a/codegen/schema/resource.cue +++ b/codegen/schema/resource.cue @@ -42,6 +42,9 @@ import ( // filtering by label labels: bool | *true + // filtering by flag + flags: bool | *false + // support pagination paging: bool | *true diff --git a/codegen/server.store.cue b/codegen/server.store.cue index 8ae2c89ee..44c008f3b 100644 --- a/codegen/server.store.cue +++ b/codegen/server.store.cue @@ -44,6 +44,7 @@ _StoreResource: { // @todo this should be pulled from the struct "byValue": [ for name in res.filter.byValue {res.filter.struct[name]}] "byLabel": res.features.labels + "byFlag": res.features.flags } auxIdent: "aux\(expIdent)" diff --git a/store/adapters/rdbms/filters.gen.go b/store/adapters/rdbms/filters.gen.go index ae0e78f1b..2a3b45a0d 100644 --- a/store/adapters/rdbms/filters.gen.go +++ b/store/adapters/rdbms/filters.gen.go @@ -203,7 +203,7 @@ func ApigwFilterFilter(f systemType.ApigwFilterFilter) (ee []goqu.Expression, _ } if f.RouteID > 0 { - ee = append(ee, goqu.C("route_id").Eq(f.RouteID)) + ee = append(ee, goqu.C("rel_route").Eq(f.RouteID)) } return ee, f, err @@ -256,6 +256,10 @@ func ApplicationFilter(f systemType.ApplicationFilter) (ee []goqu.Expression, _ ee = append(ee, goqu.I("id").In(f.LabeledIDs)) } + if len(f.FlaggedIDs) > 0 { + ee = append(ee, goqu.I("id").In(f.FlaggedIDs)) + } + if f.Query != "" { ee = append(ee, goqu.Or( goqu.C("name").ILike("%"+f.Query+"%"), @@ -919,6 +923,22 @@ func FederationSharedModuleFilter(f federationType.SharedModuleFilter) (ee []goq // This function is auto-generated func FlagFilter(f flagType.FlagFilter) (ee []goqu.Expression, _ flagType.FlagFilter, err error) { + if val := strings.TrimSpace(f.Kind); len(val) > 0 { + ee = append(ee, goqu.C("kind").Eq(f.Kind)) + } + + if len(f.ResourceID) > 0 { + ee = append(ee, goqu.C("rel_resource").In(f.ResourceID)) + } + + if len(f.OwnedBy) > 0 { + ee = append(ee, goqu.C("owned_by").In(f.OwnedBy)) + } + + if ss := trimStringSlice(f.Name); len(ss) > 0 { + ee = append(ee, goqu.C("name").In(ss)) + } + return ee, f, err } @@ -1252,3 +1272,14 @@ func UserFilter(f systemType.UserFilter) (ee []goqu.Expression, _ systemType.Use return ee, f, err } + +// trimStringSlice is a utility to trim all of the string slice elements and omit empty ones +func trimStringSlice(in []string) []string { + out := make([]string, 0, len(in)) + for _, s := range in { + if t := strings.TrimSpace(s); len(t) > 0 { + out = append(out, t) + } + } + return out +} diff --git a/system/apigw_filter.cue b/system/apigw_filter.cue index 592ca2231..5d90eefe2 100644 --- a/system/apigw_filter.cue +++ b/system/apigw_filter.cue @@ -28,7 +28,7 @@ apigw_filter: schema.#Resource & { filter: { struct: { - route_id: {goType: "uint64", ident: "routeID"} + route_id: {goType: "uint64", ident: "routeID", storeIdent: "rel_route"} deleted: {goType: "filter.State", storeIdent: "deleted_at"} disabled: {goType: "filter.State", storeIdent: "enabled"} } diff --git a/system/application.cue b/system/application.cue index ef1bff554..2d4bf42be 100644 --- a/system/application.cue +++ b/system/application.cue @@ -32,6 +32,10 @@ application: schema.#Resource & { byNilState: ["deleted"] } + features: { + flags: true + } + rbac: { operations: { read: