diff --git a/docs/api_docs/bundle.yaml b/docs/api_docs/bundle.yaml index c40ef6efb..aaa0b69be 100644 --- a/docs/api_docs/bundle.yaml +++ b/docs/api_docs/bundle.yaml @@ -961,6 +961,50 @@ paths: description: Export JSON format of the eval cache dump produces: - application/json + parameters: + - in: query + name: ids + description: >- + "query optimized" flagIDs parameter. Has precedence over `enabled`, + `keys` and `tags` parameters. + required: false + type: array + collectionFormat: csv + minItems: 1 + items: + type: integer + format: int64 + minimum: 1 + - in: query + name: keys + description: >- + "query optimized" flagKeys parameter. Has precedence over `enabled` + and `tags` parameter. + required: false + type: array + items: + type: string + minLength: 1 + - in: query + name: enabled + description: return flags having given enabled status + required: false + type: boolean + - in: query + name: tags + description: '"query optimized" flagTags parameter' + required: false + type: array + items: + type: string + minLength: 1 + - in: query + name: all + type: boolean + description: >- + whether to use ALL (tags) semantics (ANY by default): + `?tags=foo,bar&all=true` is equivalent to postEvaluation's + `flagTagsOperator: "ALL"` responses: '200': description: OK diff --git a/pkg/entity/fixture.go b/pkg/entity/fixture.go index 476aa781a..63449e7d7 100644 --- a/pkg/entity/fixture.go +++ b/pkg/entity/fixture.go @@ -42,6 +42,20 @@ func GenFixtureFlag() Flag { return f } +func GenFixtureFlagWithTags(id uint, key string, enabled bool, tags []string) Flag { + f := Flag{ + Model: gorm.Model{ID: id}, + Key: key, + Description: "", + Enabled: enabled, + Tags: []Tag{}, + } + for _, tag := range tags { + f.Tags = append(f.Tags, Tag{Value: tag}) + } + return f +} + // GenFixtureSegment is a fixture func GenFixtureSegment() Segment { s := Segment{ diff --git a/pkg/handler/eval_cache_fetcher.go b/pkg/handler/eval_cache_fetcher.go index 907916635..b59ab01d5 100644 --- a/pkg/handler/eval_cache_fetcher.go +++ b/pkg/handler/eval_cache_fetcher.go @@ -1,16 +1,17 @@ package handler import ( + "encoding/json" "fmt" "io" "net/http" "os" - - "encoding/json" + "slices" "github.com/openflagr/flagr/pkg/config" "github.com/openflagr/flagr/pkg/entity" "github.com/openflagr/flagr/pkg/util" + "github.com/openflagr/flagr/swagger_gen/restapi/operations/export" "gorm.io/gorm" ) @@ -19,13 +20,78 @@ type EvalCacheJSON struct { Flags []entity.Flag } -func (ec *EvalCache) export() EvalCacheJSON { +func (ec *EvalCache) export(query export.GetExportEvalCacheJSONParams) EvalCacheJSON { + var targetIDs map[uint]struct{} + if len(query.Ids) > 0 { + targetIDs = make(map[uint]struct{}, len(query.Ids)) + for _, id := range query.Ids { + targetIDs[uint(id)] = struct{}{} + } + } + + var targetKeys map[string]struct{} + if len(query.Keys) > 0 { + targetKeys = make(map[string]struct{}, len(query.Keys)) + for _, key := range query.Keys { + targetKeys[key] = struct{}{} + } + } + + var hasTags func(*entity.Flag) bool + if len(query.Tags) > 0 { + if query.All != nil && *query.All { + hasTags = func(f *entity.Flag) bool { + for _, tag := range query.Tags { + if !slices.ContainsFunc(f.Tags, func(t entity.Tag) bool { return t.Value == tag }) { + return false + } + } + return true + } + } else { + hasTags = func(f *entity.Flag) bool { + for _, tag := range query.Tags { + if slices.ContainsFunc(f.Tags, func(t entity.Tag) bool { return t.Value == tag }) { + return true + } + } + return false + } + } + } + ec.cacheMutex.RLock() defer ec.cacheMutex.RUnlock() idCache := ec.cache.idCache fs := make([]entity.Flag, 0, len(idCache)) for _, f := range idCache { + if targetIDs != nil { + if _, ok := targetIDs[f.ID]; ok { + ff := *f + fs = append(fs, ff) + } + continue + } + + if targetKeys != nil { + if _, ok := targetKeys[f.Key]; ok { + ff := *f + fs = append(fs, ff) + } + continue + } + + if query.Enabled != nil && *query.Enabled != f.Enabled { + continue + } + + if hasTags != nil { + if !hasTags(f) { + continue + } + } + ff := *f fs = append(fs, ff) } diff --git a/pkg/handler/eval_cache_test.go b/pkg/handler/eval_cache_test.go index 610131a5d..a3b0b3cad 100644 --- a/pkg/handler/eval_cache_test.go +++ b/pkg/handler/eval_cache_test.go @@ -1,9 +1,12 @@ package handler import ( - "github.com/openflagr/flagr/swagger_gen/models" + "slices" "testing" + "github.com/openflagr/flagr/swagger_gen/models" + "github.com/openflagr/flagr/swagger_gen/restapi/operations/export" + "github.com/openflagr/flagr/pkg/entity" "github.com/prashantv/gostub" @@ -71,3 +74,108 @@ func TestGetByTags(t *testing.T) { f = ec.GetByTags(tags, &all) assert.Len(t, f, 0) } + +func TestEvalCacheExport(t *testing.T) { + ec := GenFixtureEvalCacheWithFlags([]entity.Flag{ + entity.GenFixtureFlagWithTags(1, "first", true, []string{"tag1", "tag2"}), + entity.GenFixtureFlagWithTags(2, "second", true, []string{"tag2", "tag3"}), + entity.GenFixtureFlagWithTags(3, "third", false, []string{"tag2", "tag3"}), + entity.GenFixtureFlagWithTags(4, "fourth", true, []string{}), + }) + + t.Run("should be able to query cache via flag ids", func(t *testing.T) { + exportedFlags := ec.export(export.GetExportEvalCacheJSONParams{Ids: []int64{1, 3}}).Flags + assert.Len(t, exportedFlags, 2) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(1))) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(1))) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(3))) + }) + + t.Run("should be able to query cache via flag keys", func(t *testing.T) { + exportedFlags := ec.export(export.GetExportEvalCacheJSONParams{Keys: []string{"second", "fourth"}}).Flags + assert.Len(t, exportedFlags, 2) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(2))) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(4))) + }) + + t.Run("should be able to query cache via enabled property", func(t *testing.T) { + tru := true + exportedFlags := ec.export(export.GetExportEvalCacheJSONParams{Enabled: &tru}).Flags + assert.Len(t, exportedFlags, 3) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(1))) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(2))) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(4))) + + fals := false + exportedFlags = ec.export(export.GetExportEvalCacheJSONParams{Enabled: &fals}).Flags + assert.Len(t, exportedFlags, 1) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(3))) + }) + + t.Run("should be able to query cache via tags with default ANY semantics", func(t *testing.T) { + exportedFlags := ec.export(export.GetExportEvalCacheJSONParams{Tags: []string{"tag1", "tag2"}}).Flags + assert.Len(t, exportedFlags, 3) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(1))) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(2))) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(3))) + + fals := false + exportedFlags = ec.export(export.GetExportEvalCacheJSONParams{All: &fals, Tags: []string{"tag1", "tag2"}}).Flags + assert.Len(t, exportedFlags, 3) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(1))) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(2))) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(3))) + }) + + t.Run("should be able to query cache via tags with ALL semantics", func(t *testing.T) { + tru := true + exportedFlags := ec.export(export.GetExportEvalCacheJSONParams{All: &tru, Tags: []string{"tag1", "tag2"}}).Flags + assert.Len(t, exportedFlags, 1) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(1))) + }) + + t.Run("flag ids query should have precedence over other queries", func(t *testing.T) { + exportedFlags := ec.export(export.GetExportEvalCacheJSONParams{Ids: []int64{4}, Keys: []string{"first", "second"}}).Flags + assert.Len(t, exportedFlags, 1) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(4))) + + fals := false + exportedFlags = ec.export(export.GetExportEvalCacheJSONParams{Ids: []int64{4}, Enabled: &fals}).Flags + assert.Len(t, exportedFlags, 1) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(4))) + + exportedFlags = ec.export(export.GetExportEvalCacheJSONParams{Ids: []int64{4}, Tags: []string{"tag1"}}).Flags + assert.Len(t, exportedFlags, 1) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(4))) + }) + + t.Run("flag keys query should have precedence over enabled and tags queries", func(t *testing.T) { + fals := false + exportedFlags := ec.export(export.GetExportEvalCacheJSONParams{Keys: []string{"fourth"}, Enabled: &fals}).Flags + assert.Len(t, exportedFlags, 1) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(4))) + + exportedFlags = ec.export(export.GetExportEvalCacheJSONParams{Keys: []string{"fourth"}, Tags: []string{"tag1"}}).Flags + assert.Len(t, exportedFlags, 1) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(4))) + }) + + t.Run("should be able to combine enabled and tags queries", func(t *testing.T) { + tru := true + exportedFlags := ec.export(export.GetExportEvalCacheJSONParams{Enabled: &tru, Tags: []string{"tag2"}}).Flags + assert.Len(t, exportedFlags, 2) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(1))) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(2))) + + fals := false + exportedFlags = ec.export(export.GetExportEvalCacheJSONParams{Enabled: &fals, Tags: []string{"tag2"}}).Flags + assert.Len(t, exportedFlags, 1) + assert.True(t, slices.ContainsFunc(exportedFlags, withID(3))) + }) +} + +func withID(id uint) func(entity.Flag) bool { + return func(f entity.Flag) bool { + return f.ID == id + } +} diff --git a/pkg/handler/export.go b/pkg/handler/export.go index 2a236225f..cd1751dd9 100644 --- a/pkg/handler/export.go +++ b/pkg/handler/export.go @@ -100,8 +100,8 @@ var exportFlagEntityTypes = func(tmpDB *gorm.DB) error { return nil } -var exportEvalCacheJSONHandler = func(export.GetExportEvalCacheJSONParams) middleware.Responder { +var exportEvalCacheJSONHandler = func(query export.GetExportEvalCacheJSONParams) middleware.Responder { return export.NewGetExportEvalCacheJSONOK().WithPayload( - GetEvalCache().export(), + GetEvalCache().export(query), ) } diff --git a/pkg/handler/fixture.go b/pkg/handler/fixture.go index ad84e5915..56791a59f 100644 --- a/pkg/handler/fixture.go +++ b/pkg/handler/fixture.go @@ -24,3 +24,29 @@ func GenFixtureEvalCache() *EvalCache { return ec } + +func GenFixtureEvalCacheWithFlags(flags []entity.Flag) *EvalCache { + idCache := make(map[string]*entity.Flag) + keyCache := make(map[string]*entity.Flag) + tagCache := make(map[string]map[uint]*entity.Flag) + for _, f := range flags { + idCache[util.SafeString(f.Model.ID)] = &f + keyCache[f.Key] = &f + for _, tag := range f.Tags { + if tagCache[tag.Value] == nil { + tagCache[tag.Value] = make(map[uint]*entity.Flag) + } + tagCache[tag.Value][f.ID] = &f + } + } + + ec := &EvalCache{ + cache: &cacheContainer{ + idCache: idCache, + keyCache: keyCache, + tagCache: tagCache, + }, + } + + return ec +} diff --git a/swagger/export_eval_cache_json.yaml b/swagger/export_eval_cache_json.yaml index 120cbf486..377fbafd3 100644 --- a/swagger/export_eval_cache_json.yaml +++ b/swagger/export_eval_cache_json.yaml @@ -5,6 +5,52 @@ get: description: Export JSON format of the eval cache dump produces: - application/json + parameters: + - in: query + name: ids + description: >- + "query optimized" flagIDs parameter. + Has precedence over `enabled`, `keys` and `tags` parameters. + required: false + type: array + collectionFormat: csv + minItems: 1 + items: + type: integer + format: int64 + minimum: 1 + - in: query + name: keys + description: >- + "query optimized" flagKeys parameter. + Has precedence over `enabled` and `tags` parameter. + required: false + type: array + items: + type: string + minLength: 1 + - in: query + name: enabled + description: >- + return flags having given enabled status + required: false + type: boolean + - in: query + name: tags + description: >- + "query optimized" flagTags parameter + required: false + type: array + items: + type: string + minLength: 1 + - in: query + name: all + type: boolean + description: >- + whether to use ALL (tags) semantics (ANY by default): + `?tags=foo,bar&all=true` is equivalent to postEvaluation's + `flagTagsOperator: "ALL"` responses: 200: description: OK diff --git a/swagger_gen/restapi/embedded_spec.go b/swagger_gen/restapi/embedded_spec.go index 5051dc3a8..e5d91d59a 100644 --- a/swagger_gen/restapi/embedded_spec.go +++ b/swagger_gen/restapi/embedded_spec.go @@ -111,6 +111,53 @@ func init() { "export" ], "operationId": "getExportEvalCacheJSON", + "parameters": [ + { + "minItems": 1, + "type": "array", + "items": { + "minimum": 1, + "type": "integer", + "format": "int64" + }, + "collectionFormat": "csv", + "description": "\"query optimized\" flagIDs parameter. Has precedence over ` + "`" + `enabled` + "`" + `, ` + "`" + `keys` + "`" + ` and ` + "`" + `tags` + "`" + ` parameters.", + "name": "ids", + "in": "query" + }, + { + "type": "array", + "items": { + "minLength": 1, + "type": "string" + }, + "description": "\"query optimized\" flagKeys parameter. Has precedence over ` + "`" + `enabled` + "`" + ` and ` + "`" + `tags` + "`" + ` parameter.", + "name": "keys", + "in": "query" + }, + { + "type": "boolean", + "description": "return flags having given enabled status", + "name": "enabled", + "in": "query" + }, + { + "type": "array", + "items": { + "minLength": 1, + "type": "string" + }, + "description": "\"query optimized\" flagTags parameter", + "name": "tags", + "in": "query" + }, + { + "type": "boolean", + "description": "whether to use ALL (tags) semantics (ANY by default): ` + "`" + `?tags=foo,bar\u0026all=true` + "`" + ` is equivalent to postEvaluation's ` + "`" + `flagTagsOperator: \"ALL\"` + "`" + `", + "name": "all", + "in": "query" + } + ], "responses": { "200": { "description": "OK", @@ -2208,6 +2255,53 @@ func init() { "export" ], "operationId": "getExportEvalCacheJSON", + "parameters": [ + { + "minItems": 1, + "type": "array", + "items": { + "minimum": 1, + "type": "integer", + "format": "int64" + }, + "collectionFormat": "csv", + "description": "\"query optimized\" flagIDs parameter. Has precedence over ` + "`" + `enabled` + "`" + `, ` + "`" + `keys` + "`" + ` and ` + "`" + `tags` + "`" + ` parameters.", + "name": "ids", + "in": "query" + }, + { + "type": "array", + "items": { + "minLength": 1, + "type": "string" + }, + "description": "\"query optimized\" flagKeys parameter. Has precedence over ` + "`" + `enabled` + "`" + ` and ` + "`" + `tags` + "`" + ` parameter.", + "name": "keys", + "in": "query" + }, + { + "type": "boolean", + "description": "return flags having given enabled status", + "name": "enabled", + "in": "query" + }, + { + "type": "array", + "items": { + "minLength": 1, + "type": "string" + }, + "description": "\"query optimized\" flagTags parameter", + "name": "tags", + "in": "query" + }, + { + "type": "boolean", + "description": "whether to use ALL (tags) semantics (ANY by default): ` + "`" + `?tags=foo,bar\u0026all=true` + "`" + ` is equivalent to postEvaluation's ` + "`" + `flagTagsOperator: \"ALL\"` + "`" + `", + "name": "all", + "in": "query" + } + ], "responses": { "200": { "description": "OK", diff --git a/swagger_gen/restapi/operations/export/get_export_eval_cache_json_parameters.go b/swagger_gen/restapi/operations/export/get_export_eval_cache_json_parameters.go index e0ccb9bd6..937edde83 100644 --- a/swagger_gen/restapi/operations/export/get_export_eval_cache_json_parameters.go +++ b/swagger_gen/restapi/operations/export/get_export_eval_cache_json_parameters.go @@ -6,10 +6,15 @@ package export // Editing this file might prove futile when you re-run the swagger generate command import ( + "fmt" "net/http" "github.com/go-openapi/errors" + "github.com/go-openapi/runtime" "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" ) // NewGetExportEvalCacheJSONParams creates a new GetExportEvalCacheJSONParams object @@ -28,6 +33,29 @@ type GetExportEvalCacheJSONParams struct { // HTTP Request Object HTTPRequest *http.Request `json:"-"` + + /*whether to use ALL (tags) semantics (ANY by default): `?tags=foo,bar&all=true` is equivalent to postEvaluation's `flagTagsOperator: "ALL"` + In: query + */ + All *bool + /*return flags having given enabled status + In: query + */ + Enabled *bool + /*"query optimized" flagIDs parameter. Has precedence over `enabled`, `keys` and `tags` parameters. + Min Items: 1 + In: query + Collection Format: csv + */ + Ids []int64 + /*"query optimized" flagKeys parameter. Has precedence over `enabled` and `tags` parameter. + In: query + */ + Keys []string + /*"query optimized" flagTags parameter + In: query + */ + Tags []string } // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface @@ -39,8 +67,192 @@ func (o *GetExportEvalCacheJSONParams) BindRequest(r *http.Request, route *middl o.HTTPRequest = r + qs := runtime.Values(r.URL.Query()) + + qAll, qhkAll, _ := qs.GetOK("all") + if err := o.bindAll(qAll, qhkAll, route.Formats); err != nil { + res = append(res, err) + } + + qEnabled, qhkEnabled, _ := qs.GetOK("enabled") + if err := o.bindEnabled(qEnabled, qhkEnabled, route.Formats); err != nil { + res = append(res, err) + } + + qIds, qhkIds, _ := qs.GetOK("ids") + if err := o.bindIds(qIds, qhkIds, route.Formats); err != nil { + res = append(res, err) + } + + qKeys, qhkKeys, _ := qs.GetOK("keys") + if err := o.bindKeys(qKeys, qhkKeys, route.Formats); err != nil { + res = append(res, err) + } + + qTags, qhkTags, _ := qs.GetOK("tags") + if err := o.bindTags(qTags, qhkTags, route.Formats); err != nil { + res = append(res, err) + } if len(res) > 0 { return errors.CompositeValidationError(res...) } return nil } + +// bindAll binds and validates parameter All from query. +func (o *GetExportEvalCacheJSONParams) bindAll(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: false + // AllowEmptyValue: false + + if raw == "" { // empty values pass all other validations + return nil + } + + value, err := swag.ConvertBool(raw) + if err != nil { + return errors.InvalidType("all", "query", "bool", raw) + } + o.All = &value + + return nil +} + +// bindEnabled binds and validates parameter Enabled from query. +func (o *GetExportEvalCacheJSONParams) bindEnabled(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: false + // AllowEmptyValue: false + + if raw == "" { // empty values pass all other validations + return nil + } + + value, err := swag.ConvertBool(raw) + if err != nil { + return errors.InvalidType("enabled", "query", "bool", raw) + } + o.Enabled = &value + + return nil +} + +// bindIds binds and validates array parameter Ids from query. +// +// Arrays are parsed according to CollectionFormat: "csv" (defaults to "csv" when empty). +func (o *GetExportEvalCacheJSONParams) bindIds(rawData []string, hasKey bool, formats strfmt.Registry) error { + var qvIds string + if len(rawData) > 0 { + qvIds = rawData[len(rawData)-1] + } + + // CollectionFormat: csv + idsIC := swag.SplitByFormat(qvIds, "csv") + if len(idsIC) == 0 { + return nil + } + + var idsIR []int64 + for i, idsIV := range idsIC { + // items.Format: "int64" + idsI, err := swag.ConvertInt64(idsIV) + if err != nil { + return errors.InvalidType(fmt.Sprintf("%s.%v", "ids", i), "query", "int64", idsI) + } + + if err := validate.MinimumInt(fmt.Sprintf("%s.%v", "ids", i), "query", idsI, 1, false); err != nil { + return err + } + + idsIR = append(idsIR, idsI) + } + + o.Ids = idsIR + if err := o.validateIds(formats); err != nil { + return err + } + + return nil +} + +// validateIds carries on validations for parameter Ids +func (o *GetExportEvalCacheJSONParams) validateIds(formats strfmt.Registry) error { + + idsSize := int64(len(o.Ids)) + + // minItems: 1 + if err := validate.MinItems("ids", "query", idsSize, 1); err != nil { + return err + } + return nil +} + +// bindKeys binds and validates array parameter Keys from query. +// +// Arrays are parsed according to CollectionFormat: "" (defaults to "csv" when empty). +func (o *GetExportEvalCacheJSONParams) bindKeys(rawData []string, hasKey bool, formats strfmt.Registry) error { + var qvKeys string + if len(rawData) > 0 { + qvKeys = rawData[len(rawData)-1] + } + + // CollectionFormat: + keysIC := swag.SplitByFormat(qvKeys, "") + if len(keysIC) == 0 { + return nil + } + + var keysIR []string + for i, keysIV := range keysIC { + keysI := keysIV + + if err := validate.MinLength(fmt.Sprintf("%s.%v", "keys", i), "query", keysI, 1); err != nil { + return err + } + + keysIR = append(keysIR, keysI) + } + + o.Keys = keysIR + + return nil +} + +// bindTags binds and validates array parameter Tags from query. +// +// Arrays are parsed according to CollectionFormat: "" (defaults to "csv" when empty). +func (o *GetExportEvalCacheJSONParams) bindTags(rawData []string, hasKey bool, formats strfmt.Registry) error { + var qvTags string + if len(rawData) > 0 { + qvTags = rawData[len(rawData)-1] + } + + // CollectionFormat: + tagsIC := swag.SplitByFormat(qvTags, "") + if len(tagsIC) == 0 { + return nil + } + + var tagsIR []string + for i, tagsIV := range tagsIC { + tagsI := tagsIV + + if err := validate.MinLength(fmt.Sprintf("%s.%v", "tags", i), "query", tagsI, 1); err != nil { + return err + } + + tagsIR = append(tagsIR, tagsI) + } + + o.Tags = tagsIR + + return nil +} diff --git a/swagger_gen/restapi/operations/export/get_export_eval_cache_json_urlbuilder.go b/swagger_gen/restapi/operations/export/get_export_eval_cache_json_urlbuilder.go index 6528f58bd..e0a10f215 100644 --- a/swagger_gen/restapi/operations/export/get_export_eval_cache_json_urlbuilder.go +++ b/swagger_gen/restapi/operations/export/get_export_eval_cache_json_urlbuilder.go @@ -9,11 +9,21 @@ import ( "errors" "net/url" golangswaggerpaths "path" + + "github.com/go-openapi/swag" ) // GetExportEvalCacheJSONURL generates an URL for the get export eval cache JSON operation type GetExportEvalCacheJSONURL struct { + All *bool + Enabled *bool + Ids []int64 + Keys []string + Tags []string + _basePath string + // avoid unkeyed usage + _ struct{} } // WithBasePath sets the base path for this url builder, only required when it's different from the @@ -43,6 +53,77 @@ func (o *GetExportEvalCacheJSONURL) Build() (*url.URL, error) { } _result.Path = golangswaggerpaths.Join(_basePath, _path) + qs := make(url.Values) + + var allQ string + if o.All != nil { + allQ = swag.FormatBool(*o.All) + } + if allQ != "" { + qs.Set("all", allQ) + } + + var enabledQ string + if o.Enabled != nil { + enabledQ = swag.FormatBool(*o.Enabled) + } + if enabledQ != "" { + qs.Set("enabled", enabledQ) + } + + var idsIR []string + for _, idsI := range o.Ids { + idsIS := swag.FormatInt64(idsI) + if idsIS != "" { + idsIR = append(idsIR, idsIS) + } + } + + ids := swag.JoinByFormat(idsIR, "csv") + + if len(ids) > 0 { + qsv := ids[0] + if qsv != "" { + qs.Set("ids", qsv) + } + } + + var keysIR []string + for _, keysI := range o.Keys { + keysIS := keysI + if keysIS != "" { + keysIR = append(keysIR, keysIS) + } + } + + keys := swag.JoinByFormat(keysIR, "") + + if len(keys) > 0 { + qsv := keys[0] + if qsv != "" { + qs.Set("keys", qsv) + } + } + + var tagsIR []string + for _, tagsI := range o.Tags { + tagsIS := tagsI + if tagsIS != "" { + tagsIR = append(tagsIR, tagsIS) + } + } + + tags := swag.JoinByFormat(tagsIR, "") + + if len(tags) > 0 { + qsv := tags[0] + if qsv != "" { + qs.Set("tags", qsv) + } + } + + _result.RawQuery = qs.Encode() + return &_result, nil }