Add IN comparator

This commit is contained in:
sunboyy 2021-01-22 09:56:30 +07:00
parent 847d5add53
commit ba77c93d64
6 changed files with 174 additions and 1 deletions

View file

@ -64,8 +64,17 @@ const (
ComparatorLessThanEqual Comparator = "LESS_THAN_EQUAL"
ComparatorGreaterThan Comparator = "GREATER_THAN"
ComparatorGreaterThanEqual Comparator = "GREATER_THAN_EQUAL"
ComparatorIn Comparator = "IN"
)
// ArgumentTypeFromFieldType returns a type of required argument from the given struct field type
func (c Comparator) ArgumentTypeFromFieldType(t code.Type) code.Type {
if c == ComparatorIn {
return code.ArrayType{ContainedType: t}
}
return t
}
// Predicate is a criteria for querying a field
type Predicate struct {
Field string
@ -90,5 +99,8 @@ func (t predicateToken) ToPredicate() Predicate {
if len(t) > 3 && t[len(t)-3] == "Greater" && t[len(t)-2] == "Than" && t[len(t)-1] == "Equal" {
return Predicate{Field: strings.Join(t[:len(t)-3], ""), Comparator: ComparatorGreaterThanEqual}
}
if len(t) > 1 && t[len(t)-1] == "In" {
return Predicate{Field: strings.Join(t[:len(t)-1], ""), Comparator: ComparatorIn}
}
return Predicate{Field: strings.Join(t, ""), Comparator: ComparatorEqual}
}

View file

@ -157,7 +157,8 @@ func (p interfaceMethodParser) validateMethodSignature(querySpec QuerySpec) erro
return StructFieldNotFoundError
}
if structField.Type != p.Method.Params[currentParamIndex].Type {
if p.Method.Params[currentParamIndex].Type != predicate.Comparator.ArgumentTypeFromFieldType(
structField.Type) {
return InvalidParamError
}

View file

@ -390,6 +390,37 @@ func TestParseInterfaceMethod(t *testing.T) {
},
},
},
{
Name: "FindByArgIn method",
Method: code.Method{
Name: "FindByCityIn",
Params: []code.Param{
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
{Type: code.ArrayType{ContainedType: code.SimpleType("string")}},
},
Returns: []code.Type{
code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}},
code.SimpleType("error"),
},
},
ExpectedOutput: spec.MethodSpec{
Name: "FindByCityIn",
Params: []code.Param{
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
{Type: code.ArrayType{ContainedType: code.SimpleType("string")}},
},
Returns: []code.Type{
code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}},
code.SimpleType("error"),
},
Operation: spec.FindOperation{
Mode: spec.QueryModeMany,
Query: spec.QuerySpec{Predicates: []spec.Predicate{
{Field: "City", Comparator: spec.ComparatorIn},
}},
},
},
},
}
for _, testCase := range testTable {
@ -566,6 +597,21 @@ func TestParseInterfaceMethodInvalid(t *testing.T) {
},
ExpectedError: spec.InvalidParamError,
},
{
Name: "mismatched method parameter type for special case",
Method: code.Method{
Name: "FindByCityIn",
Params: []code.Param{
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
{Type: code.SimpleType("string")},
},
Returns: []code.Type{
code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}},
code.SimpleType("error"),
},
},
ExpectedError: spec.InvalidParamError,
},
}
for _, testCase := range testTable {