Skip to content

Commit

Permalink
Merge pull request #42 from geoffreybauduin/dev/gbauduin/raw-filter
Browse files Browse the repository at this point in the history
feat: added raw filter
  • Loading branch information
geoffreybauduin authored Sep 22, 2020
2 parents 9289993 + b939792 commit aa0bf5e
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 119 deletions.
3 changes: 1 addition & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
language: go
go:
- 1.12.x
- 1.13.x
- 1.15.x
services:
- mysql
- postgres
Expand Down
39 changes: 39 additions & 0 deletions filterapply_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package yaorm_test

import (
"context"
"fmt"
"testing"

"github.com/geoffreybauduin/yaorm"
Expand Down Expand Up @@ -211,3 +212,41 @@ func TestFilterApplier_ApplyNotIn(t *testing.T) {
assert.Len(t, models, 1)
assert.Equal(t, models[0].(*testdata.Category).ID, category.ID)
}

func TestFilterApplier_ApplyRaw(t *testing.T) {
killDb, err := testdata.SetupTestDatabase("test")
defer killDb()
assert.Nil(t, err)
dbp, err := yaorm.NewDBProvider(context.TODO(), "test")
assert.Nil(t, err)
category := &testdata.Category{Name: "category"}
saveModel(t, dbp, category)
category2 := &testdata.Category{Name: "category2"}
saveModel(t, dbp, category2)

models, err := yaorm.GenericSelectAll(dbp, testdata.NewCategoryFilter().ID(yaormfilter.Raw(func(field string) interface{} {
return fmt.Sprintf("%s >= %d AND %s < %d", field, category.ID, field, category2.ID)
})))
assert.Nil(t, err)
assert.Len(t, models, 1)
assert.Equal(t, models[0].(*testdata.Category).ID, category.ID)
}

func TestFilterApplier_ApplyRaw_EscapedFields(t *testing.T) {
killDb, err := testdata.SetupTestDatabase("test")
defer killDb()
assert.Nil(t, err)
dbp, err := yaorm.NewDBProvider(context.TODO(), "test")
assert.Nil(t, err)
category := &testdata.TwoI{Name: "category"}
saveModel(t, dbp, category)
category2 := &testdata.TwoI{Name: "category2"}
saveModel(t, dbp, category2)

models, err := yaorm.GenericSelectAll(dbp, testdata.NewTwoIFilter().ID(yaormfilter.Raw(func(field string) interface{} {
return fmt.Sprintf("%s >= %d AND %s < %d", field, category.ID, field, category2.ID)
})))
assert.Nil(t, err)
assert.Len(t, models, 1)
assert.Equal(t, models[0].(*testdata.TwoI).ID, category.ID)
}
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1 h1:oL4IBbcqwhhNWh31bjOX8C/OCy0zs9906d/VUru+bqg=
github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1/go.mod h1:nSbFQvMj97ZyhFRSJYtut+msi4sOY6zJDGCdSc+/rZU=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
Expand Down
6 changes: 6 additions & 0 deletions yaormfilter/boolfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,9 @@ func (f *BoolFilter) Gt(v interface{}) ValueFilter {
func (f *BoolFilter) Gte(v interface{}) ValueFilter {
return f
}

// Raw performs a Raw filter
func (f *BoolFilter) Raw(s RawFilterFunc) ValueFilter {
f.raw(s)
return f
}
6 changes: 6 additions & 0 deletions yaormfilter/datefilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,9 @@ func (f *DateFilter) Gte(v interface{}) ValueFilter {
f.gte(f.getValue(v))
return f
}

// Raw performs a Raw filter
func (f *DateFilter) Raw(s RawFilterFunc) ValueFilter {
f.raw(s)
return f
}
6 changes: 6 additions & 0 deletions yaormfilter/int64filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,9 @@ func (f *Int64Filter) Gte(v interface{}) ValueFilter {
f.gte(f.getValue(v))
return f
}

// Raw performs a Raw filter
func (f *Int64Filter) Raw(s RawFilterFunc) ValueFilter {
f.raw(s)
return f
}
6 changes: 6 additions & 0 deletions yaormfilter/nilfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,9 @@ func (f *NilFilter) Gt(v interface{}) ValueFilter {
func (f *NilFilter) Gte(v interface{}) ValueFilter {
return f
}

// Raw performs a Raw filter
func (f *NilFilter) Raw(s RawFilterFunc) ValueFilter {
f.raw(s)
return f
}
6 changes: 6 additions & 0 deletions yaormfilter/stringfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,3 +103,9 @@ func (f *StringFilter) Gt(v interface{}) ValueFilter {
func (f *StringFilter) Gte(v interface{}) ValueFilter {
return f
}

// Raw performs a Raw filter
func (f *StringFilter) Raw(s RawFilterFunc) ValueFilter {
f.raw(s)
return f
}
5 changes: 5 additions & 0 deletions yaormfilter/stringfilter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,8 @@ func TestStringFilter_In(t *testing.T) {
str := "bla"
assert.Equal(t, filter, filter.In(str))
}

func TestStringFilter_Raw(t *testing.T) {
filter := yaormfilter.NewStringFilter()
assert.Equal(t, filter, filter.Raw(func(s string) interface{} { return s }))
}
5 changes: 5 additions & 0 deletions yaormfilter/tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,8 @@ func NotIn(values ...interface{}) ValueFilter {
}
panic(fmt.Errorf("Unknown type: %v inside In filter", t.Kind()))
}

// Raw returns the correct filter according the value sent
func Raw(v RawFilterFunc) ValueFilter {
return NewStringFilter().Raw(v)
}
156 changes: 39 additions & 117 deletions yaormfilter/valuefilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"github.com/geoffreybauduin/yaorm/_vendor/github.com/lann/squirrel"
)

type RawFilterFunc func(string) interface{}

type ValueFilter interface {
Apply(statement squirrel.SelectBuilder, tableName, fieldName string) squirrel.SelectBuilder
Equals(v interface{}) ValueFilter
Expand All @@ -16,165 +18,85 @@ type ValueFilter interface {
Gt(v interface{}) ValueFilter
Gte(v interface{}) ValueFilter
Nil(v bool) ValueFilter
IsEquality() bool
GetEquality() interface{}
In(v ...interface{}) ValueFilter
NotIn(v ...interface{}) ValueFilter
Raw(fn RawFilterFunc) ValueFilter
}

type valuefilterimpl struct {
equals_ interface{}
nil_ *bool
shouldEqual bool
like_ interface{}
shouldLike bool
in_ []interface{}
shouldIn bool
notIn_ []interface{}
shouldNotIn bool
lt_ interface{}
shouldLt bool
lte_ interface{}
shouldLte bool
gt_ interface{}
shouldGt bool
gte_ interface{}
shouldGte bool
notEquals_ interface{}
shouldNotEqual bool
}

func (f valuefilterimpl) IsEquality() bool {
return f.shouldEqual
}

func (f valuefilterimpl) IsInequality() bool {
return f.shouldNotEqual
}

func (f valuefilterimpl) GetEquality() interface{} {
return f.equals_
}

func (f valuefilterimpl) GetInequality() interface{} {
return f.notEquals_
filterFn RawFilterFunc
}

func (f *valuefilterimpl) nil(v bool) *valuefilterimpl {
f.nil_ = &v
f.raw(func(field string) interface{} {
if v {
return squirrel.Eq{field: nil}
}
return squirrel.NotEq{field: nil}
})
return f
}

func (f *valuefilterimpl) equals(e interface{}) *valuefilterimpl {
f.equals_ = e
f.shouldEqual = true
return f
return f.raw(func(field string) interface{} {
return squirrel.Eq{field: e}
})
}

func (f *valuefilterimpl) notEquals(e interface{}) *valuefilterimpl {
f.notEquals_ = e
f.shouldNotEqual = true
return f
return f.raw(func(field string) interface{} {
return squirrel.NotEq{field: e}
})
}

func (f *valuefilterimpl) like(e interface{}) *valuefilterimpl {
f.like_ = e
f.shouldLike = true
return f
return f.raw(func(field string) interface{} {
return fmt.Sprintf("%s LIKE %s", field, e)
})
}

func (f *valuefilterimpl) in(e []interface{}) *valuefilterimpl {
f.in_ = e
f.shouldIn = true
return f
return f.equals(e)
}

func (f *valuefilterimpl) notIn(e []interface{}) *valuefilterimpl {
f.notIn_ = e
f.shouldNotIn = true
return f
return f.notEquals(e)
}

func (f *valuefilterimpl) lte(e interface{}) *valuefilterimpl {
f.lte_ = e
f.shouldLte = true
return f
return f.raw(func(field string) interface{} {
return squirrel.LtOrEq{field: e}
})
}

func (f *valuefilterimpl) gte(e interface{}) *valuefilterimpl {
f.gte_ = e
f.shouldGte = true
return f
return f.raw(func(field string) interface{} {
return squirrel.GtOrEq{field: e}
})
}

func (f *valuefilterimpl) lt(e interface{}) *valuefilterimpl {
f.lt_ = e
f.shouldLt = true
return f
return f.raw(func(field string) interface{} {
return squirrel.Lt{field: e}
})
}

func (f *valuefilterimpl) gt(e interface{}) *valuefilterimpl {
f.gt_ = e
f.shouldGt = true
return f.raw(func(field string) interface{} {
return squirrel.Gt{field: e}
})
}

func (f *valuefilterimpl) raw(fn RawFilterFunc) *valuefilterimpl {
f.filterFn = fn
return f
}

func (f *valuefilterimpl) Apply(statement squirrel.SelectBuilder, tableName, fieldName string) squirrel.SelectBuilder {
computedField := fmt.Sprintf(`%s.%s`, tableName, fieldName)
if f.nil_ != nil {
if *f.nil_ == true {
statement = statement.Where(
squirrel.Eq{computedField: nil},
)
} else {
statement = statement.Where(
squirrel.NotEq{computedField: nil},
)
}
}
if f.IsEquality() {
statement = statement.Where(
squirrel.Eq{computedField: f.GetEquality()},
)
}
if f.IsInequality() {
statement = statement.Where(
squirrel.NotEq{computedField: f.GetInequality()},
)
}
if f.shouldLike {
statement = statement.Where(
fmt.Sprintf("%s LIKE ?", computedField), f.like_,
)
}
if f.shouldIn {
statement = statement.Where(
squirrel.Eq{computedField: f.in_},
)
}
if f.shouldNotIn {
statement = statement.Where(
squirrel.NotEq{computedField: f.notIn_},
)
}
if f.shouldLt {
statement = statement.Where(
squirrel.Lt{computedField: f.lt_},
)
}
if f.shouldLte {
statement = statement.Where(
squirrel.LtOrEq{computedField: f.lte_},
)
}
if f.shouldGt {
statement = statement.Where(
squirrel.Gt{computedField: f.gt_},
)
}
if f.shouldGte {
if f.filterFn != nil {
statement = statement.Where(
squirrel.GtOrEq{computedField: f.gte_},
f.filterFn(computedField),
)
}
return statement
Expand Down

0 comments on commit aa0bf5e

Please sign in to comment.