diff --git a/app/main.go b/app/main.go index 15d2f69..02d38c3 100644 --- a/app/main.go +++ b/app/main.go @@ -20,19 +20,20 @@ var ( ) type CertFilter struct { - Alive *bool `filterfield:"field=alive,operator=EQ"` - SerialNumber *string `filterfield:"field=serial_number,operator=NE"` - SerialNumberContains *string `filterfield:"field=serial_number,operator=LIKE"` - IssuerContains *string `filterfield:"field=issuer,operator=ILIKE"` - Id *uuid.UUID `filterfield:"field=id,operator=EQ"` - Ids *[]uuid.UUID `filterfield:"field=id,operator=IN"` - IdsNot *[]string `filterfield:"field=id,operator=NOT_IN"` - CreatedAt_Lt *time.Time `filterfield:"field=created_at,operator=LT"` - Timestamps *[]time.Time `filterfield:"field=created_at,operator=IN"` + Alive *bool `filterfield:"field=alive;operator=EQ"` + SerialNumber *string `filterfield:"field=serial_number;operator=NE"` + SerialNumberContains *string `filterfield:"field=serial_number;operator=LIKE"` + IssuerContains *string `filterfield:"field=issuer;operator=ILIKE"` + Id *uuid.UUID `filterfield:"field=id;operator=EQ"` + Ids *[]uuid.UUID `filterfield:"field=id;operator=IN"` + IdsNot *[]string `filterfield:"field=id;operator=NOT_IN"` + CreatedAt_Lt *time.Time `filterfield:"field=created_at;operator=LT"` + Timestamps *[]time.Time `filterfield:"field=created_at;operator=IN"` + // CompanyIsActive *bool `filterfield:"joins=companies;field=is_active;operator=EQ"` } type CompanyFilter struct { - IsActive *bool `filterfield:"field=is_active,operator=EQ"` + IsActive *bool `filterfield:"field=is_active;operator=EQ"` } func doMagic(db *gorm.DB) { @@ -93,6 +94,24 @@ func doList(db *gorm.DB) { } } +func doListWithJoins(db *gorm.DB) { + repo := repository.RepoBase[models.Cert]{} + repo.Init(db, nil) + + filter := CertFilter{ + Alive: &TRUE, + } + + certs, err := repo.List(filter, nil) + if err != nil { + panic(err) + } + + for n, cert := range *certs { + fmt.Printf(">> [%d] %+v %s (alive %t)\n", n, cert.Id, cert.CreatedAt, cert.Alive) + } +} + func doCount(db *gorm.DB) { repo := repository.RepoBase[models.Cert]{} repo.Init(db, nil) @@ -184,7 +203,8 @@ func main() { db := db.InitDB() // doMagic(db) - // doList(db) + doList(db) + // doListWithJoins(db) // doCount(db) // doSave(db) doDelete(db) diff --git a/app/repository/method_list_test.go b/app/repository/method_list_test.go index 16b1195..cd2341a 100644 --- a/app/repository/method_list_test.go +++ b/app/repository/method_list_test.go @@ -43,10 +43,10 @@ func (m MyModel) TableName() string { } type MyModelFilter struct { - Id *uuid.UUID `filterfield:"field=id,operator=EQ"` - Ids *[]uuid.UUID `filterfield:"field=id,operator=IN"` - Value *string `filterfield:"field=value,operator=EQ"` - CntGT *int `filterfield:"field=cnt,operator=GT"` + Id *uuid.UUID `filterfield:"field=id;operator=EQ"` + Ids *[]uuid.UUID `filterfield:"field=id;operator=IN"` + Value *string `filterfield:"field=value;operator=EQ"` + CntGT *int `filterfield:"field=cnt;operator=GT"` } func TestListMethod(t *testing.T) { diff --git a/app/repository/smartfilter/filterfield.go b/app/repository/smartfilter/filterfield.go index a4cf4b8..8cc2c06 100644 --- a/app/repository/smartfilter/filterfield.go +++ b/app/repository/smartfilter/filterfield.go @@ -11,6 +11,7 @@ import ( type FilterField struct { Name string Operator Operator + Joins []string valueKind reflect.Kind boolValue *bool diff --git a/app/repository/smartfilter/smartfilter.go b/app/repository/smartfilter/smartfilter.go index b77ba4d..84bd8d9 100644 --- a/app/repository/smartfilter/smartfilter.go +++ b/app/repository/smartfilter/smartfilter.go @@ -11,7 +11,7 @@ import ( ) const TAG_NAME = "filterfield" -const TAG_PAIRS_SEPARATOR = "," +const TAG_PAIRS_SEPARATOR = ";" const TAG_KEYVALUE_SEPARATOR = "=" type handlerFunc func(query *gorm.DB, tableName string, filterField *FilterField) *gorm.DB diff --git a/app/repository/smartfilter/smartfilter_test.go b/app/repository/smartfilter/smartfilter_test.go index 13ab166..c9834d6 100644 --- a/app/repository/smartfilter/smartfilter_test.go +++ b/app/repository/smartfilter/smartfilter_test.go @@ -101,11 +101,11 @@ func TestGetFilterFields(t *testing.T) { t.Run("Skip nil fields", func(t *testing.T) { type TestFilter struct { - Alive *bool `filterfield:"alive,EQ"` - Id *int64 `filterfield:"id,EQ"` - Ids *[]uint `filterfield:"id,IN"` - IdsNot *[]uint `filterfield:"id,NOT_IN"` - FirstName *string `filterfield:"first_name,EQ"` + Alive *bool `filterfield:"alive;EQ"` + Id *int64 `filterfield:"id;EQ"` + Ids *[]uint `filterfield:"id;IN"` + IdsNot *[]uint `filterfield:"id;NOT_IN"` + FirstName *string `filterfield:"first_name;EQ"` } filter := TestFilter{} result := getFilterFields(filter) @@ -119,7 +119,7 @@ func TestGetFilterFields(t *testing.T) { ) type TestFilter struct { Alive *bool - Id *int64 `funnytag:"created_at,LT"` + Id *int64 `funnytag:"created_at;LT"` } filter := TestFilter{ Alive: &alive, @@ -140,7 +140,7 @@ func TestFilterField(t *testing.T) { testCases := []TagParseTestCase{ { name: "Parse without spaces", - tagValue: "field=field_1,operator=EQ", + tagValue: "field=field_1;operator=EQ", expected: FilterField{ Name: "field_1", Operator: OperatorEQ, @@ -148,7 +148,7 @@ func TestFilterField(t *testing.T) { }, { name: "Parse spaces between pairs", - tagValue: " field=field_2 , operator=LT ", + tagValue: " field=field_2 ; operator=LT ", expected: FilterField{ Name: "field_2", Operator: OperatorLT, @@ -156,7 +156,7 @@ func TestFilterField(t *testing.T) { }, { name: "Parse spaces between around keys and values", - tagValue: "operator = LIKE , field = field_3", + tagValue: "operator = LIKE ; field = field_3", expected: FilterField{ Name: "field_3", Operator: OperatorLIKE, @@ -174,19 +174,19 @@ func TestFilterField(t *testing.T) { } t.Run("Fail on invalid tag value", func(t *testing.T) { - filterField, err := newFilterField("field=field_1=fail, operator=EQ") + filterField, err := newFilterField("field=field_1=fail; operator=EQ") assert.Nil(t, filterField) assert.EqualError(t, err, "invalid tag value: field=field_1=fail") }) t.Run("Fail on invalid operator", func(t *testing.T) { - filterField, err := newFilterField("field=field_1, operator=FAIL") + filterField, err := newFilterField("field=field_1; operator=FAIL") assert.Nil(t, filterField) assert.EqualError(t, err, "unknown operator: FAIL") }) t.Run("Fail on invalid value key", func(t *testing.T) { - filterField, err := newFilterField("failkey=field_1, operator=FAIL") + filterField, err := newFilterField("failkey=field_1; operator=FAIL") assert.Nil(t, filterField) assert.EqualError(t, err, "invalid value key: failkey") })