diff --git a/go.mod b/go.mod index 9b5ce0064..4f1b33ed7 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/Masterminds/squirrel v1.2.0 github.com/astaxie/beego v1.12.1 github.com/bradleyjkemp/cupaloy v2.3.0+incompatible - github.com/deluan/rest v0.0.0-20200114062534-0653ffe9eab4 + github.com/deluan/rest v0.0.0-20200327222046-b71e558c45d0 github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dhowden/tag v0.0.0-20191122115059-7e5c04feccd8 github.com/djherbis/fscache v0.10.0 diff --git a/go.sum b/go.sum index 0be3b6581..fb65180b4 100644 --- a/go.sum +++ b/go.sum @@ -22,8 +22,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deluan/rest v0.0.0-20200114062534-0653ffe9eab4 h1:VSoAcWJvj656TSyWbJ5KuGsi/J8dO5+iO9+5/7I8wao= -github.com/deluan/rest v0.0.0-20200114062534-0653ffe9eab4/go.mod h1:tSgDythFsl0QgS/PFWfIZqcJKnkADWneY80jaVRlqK8= +github.com/deluan/rest v0.0.0-20200327222046-b71e558c45d0 h1:qHX6TTBIsrpg0JkYNkoePIpstV37lhRVLj23bHUDNwk= +github.com/deluan/rest v0.0.0-20200327222046-b71e558c45d0/go.mod h1:tSgDythFsl0QgS/PFWfIZqcJKnkADWneY80jaVRlqK8= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dhowden/tag v0.0.0-20191122115059-7e5c04feccd8 h1:nmFnmD8VZXkjDHIb1Gnfz50cgzUvGN72zLjPRXBW/hU= @@ -41,8 +41,6 @@ github.com/fatih/structs v1.0.0 h1:BrX964Rv5uQ3wwS+KRUAJCBBw5PQmgJfJ6v4yly5QwU= github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/go-chi/chi v4.0.3+incompatible h1:gakN3pDJnzZN5jqFV2TEdF66rTfKeITyR8qu6ekICEY= -github.com/go-chi/chi v4.0.3+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-chi/chi v4.0.4+incompatible h1:7fVnpr0gAXG15uDbtH+LwSeMztvIvlHrBNRkTzgphS0= github.com/go-chi/chi v4.0.4+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-chi/cors v1.0.1 h1:56TT/uWGoLWZpnMI/AwAmCneikXr5eLsiIq27wrKecw= diff --git a/persistence/sql_restful.go b/persistence/sql_restful.go index 3b2335ff2..eb56b5cfe 100644 --- a/persistence/sql_restful.go +++ b/persistence/sql_restful.go @@ -16,6 +16,23 @@ type sqlRestful struct { filterMappings map[string]filterFunc } +func (r sqlRestful) parseRestFilters(options rest.QueryOptions) Sqlizer { + if len(options.Filters) == 0 { + return nil + } + filters := And{} + for f, v := range options.Filters { + if ff, ok := r.filterMappings[f]; ok { + filters = append(filters, ff(f, v)) + } else if f == "id" { + filters = append(filters, eqFilter(f, v)) + } else { + filters = append(filters, startsWithFilter(f, v)) + } + } + return filters +} + func (r sqlRestful) parseRestOptions(options ...rest.QueryOptions) model.QueryOptions { qo := model.QueryOptions{} if len(options) > 0 { @@ -23,22 +40,16 @@ func (r sqlRestful) parseRestOptions(options ...rest.QueryOptions) model.QueryOp qo.Order = strings.ToLower(options[0].Order) qo.Max = options[0].Max qo.Offset = options[0].Offset - if len(options[0].Filters) > 0 { - filters := And{} - for f, v := range options[0].Filters { - if ff, ok := r.filterMappings[f]; ok { - filters = append(filters, ff(f, v)) - } else { - filters = append(filters, startsWithFilter(f, v)) - } - } - qo.Filters = filters - } + qo.Filters = r.parseRestFilters(options[0]) } return qo } -func startsWithFilter(field string, value interface{}) Like { +func eqFilter(field string, value interface{}) Sqlizer { + return Eq{field: value} +} + +func startsWithFilter(field string, value interface{}) Sqlizer { return Like{field: fmt.Sprintf("%s%%", value)} } diff --git a/persistence/sql_restful_test.go b/persistence/sql_restful_test.go new file mode 100644 index 000000000..429813b08 --- /dev/null +++ b/persistence/sql_restful_test.go @@ -0,0 +1,49 @@ +package persistence + +import ( + "github.com/Masterminds/squirrel" + "github.com/deluan/rest" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("sqlRestful", func() { + Describe("parseRestFilters", func() { + var r sqlRestful + var options rest.QueryOptions + + BeforeEach(func() { + r = sqlRestful{} + }) + + It("returns nil if filters is empty", func() { + options.Filters = nil + Expect(r.parseRestFilters(options)).To(BeNil()) + }) + + It("returns a '=' condition for 'id' filter", func() { + options.Filters = map[string]interface{}{"id": "123"} + Expect(r.parseRestFilters(options)).To(Equal(squirrel.And{squirrel.Eq{"id": "123"}})) + }) + + It("returns a 'in' condition for multiples 'id' filters", func() { + options.Filters = map[string]interface{}{"id": []string{"123", "456"}} + Expect(r.parseRestFilters(options)).To(Equal(squirrel.And{squirrel.Eq{"id": []string{"123", "456"}}})) + }) + + It("returns a 'like' condition for other filters", func() { + options.Filters = map[string]interface{}{"name": "joe"} + Expect(r.parseRestFilters(options)).To(Equal(squirrel.And{squirrel.Like{"name": "joe%"}})) + }) + + It("uses the custom filter", func() { + r.filterMappings = map[string]filterFunc{ + "test": func(field string, value interface{}) squirrel.Sqlizer { + return squirrel.Gt{field: value} + }, + } + options.Filters = map[string]interface{}{"test": 100} + Expect(r.parseRestFilters(options)).To(Equal(squirrel.And{squirrel.Gt{"test": 100}})) + }) + }) +})