Add Or operator

This commit is contained in:
sunboyy 2021-01-19 19:35:54 +07:00
parent bc878c778c
commit 153deb8f7d
8 changed files with 178 additions and 47 deletions

View file

@ -132,12 +132,15 @@ func (g mongoRepositoryGenerator) generateFindImplementation(operation spec.Find
return "", fmt.Errorf("struct field %s does not have bson tag", predicateSpec.Field)
}
predicates = append(predicates, predicate{Field: bsonTag[0], Operator: predicateSpec.Operator})
predicates = append(predicates, predicate{Field: bsonTag[0], Comparator: predicateSpec.Comparator})
}
tmplData := mongoFindTemplateData{
EntityType: g.StructModel.Name,
Predicates: predicates,
QuerySpec: querySpec{
Operator: operation.Query.Operator,
Predicates: predicates,
},
}
if operation.Mode == spec.QueryModeOne {

View file

@ -134,6 +134,18 @@ func TestGenerateMongoRepository(t *testing.T) {
code.SimpleType("error"),
},
},
{
Name: "FindByGenderOrAgeLessThan",
Params: []code.Param{
{Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
{Name: "gender", Type: code.SimpleType("Gender")},
{Name: "age", Type: code.SimpleType("int")},
},
Returns: []code.Type{
code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}},
code.SimpleType("error"),
},
},
},
}
@ -277,6 +289,23 @@ func (r *UserRepositoryMongo) FindByAgeGreaterThanEqual(ctx context.Context, arg
}
return entities, nil
}
func (r *UserRepositoryMongo) FindByGenderOrAgeLessThan(ctx context.Context, arg0 Gender, arg1 int) ([]*UserModel, error) {
cursor, err := r.collection.Find(ctx, bson.M{
"$or": []bson.M{
{"gender": arg0},
{"age": bson.M{"$lt": arg1}},
},
})
if err != nil {
return nil, err
}
var entities []*UserModel
if err := cursor.All(ctx, &entities); err != nil {
return nil, err
}
return entities, nil
}
`
expectedCodeLines := strings.Split(expectedCode, "\n")
actualCodeLines := strings.Split(code, "\n")

View file

@ -2,28 +2,56 @@ package mongo
import (
"fmt"
"strings"
"github.com/sunboyy/repogen/internal/spec"
)
type querySpec struct {
Operator spec.Operator
Predicates []predicate
}
func (q querySpec) Code() string {
var predicateCodes []string
for i, predicate := range q.Predicates {
predicateCodes = append(predicateCodes, predicate.Code(i))
}
var lines []string
switch q.Operator {
case spec.OperatorOr:
lines = append(lines, ` "$or": []bson.M{`)
for _, predicateCode := range predicateCodes {
lines = append(lines, fmt.Sprintf(` {%s},`, predicateCode))
}
lines = append(lines, ` },`)
default:
for _, predicateCode := range predicateCodes {
lines = append(lines, fmt.Sprintf(` %s,`, predicateCode))
}
}
return strings.Join(lines, "\n")
}
type predicate struct {
Field string
Operator spec.Operator
Field string
Comparator spec.Comparator
}
func (p predicate) Code(argIndex int) string {
switch p.Operator {
case spec.OperatorEqual:
switch p.Comparator {
case spec.ComparatorEqual:
return fmt.Sprintf(`"%s": arg%d`, p.Field, argIndex)
case spec.OperatorNot:
case spec.ComparatorNot:
return fmt.Sprintf(`"%s": bson.M{"$ne": arg%d}`, p.Field, argIndex)
case spec.OperatorLessThan:
case spec.ComparatorLessThan:
return fmt.Sprintf(`"%s": bson.M{"$lt": arg%d}`, p.Field, argIndex)
case spec.OperatorLessThanEqual:
case spec.ComparatorLessThanEqual:
return fmt.Sprintf(`"%s": bson.M{"$lte": arg%d}`, p.Field, argIndex)
case spec.OperatorGreaterThan:
case spec.ComparatorGreaterThan:
return fmt.Sprintf(`"%s": bson.M{"$gt": arg%d}`, p.Field, argIndex)
case spec.OperatorGreaterThanEqual:
case spec.ComparatorGreaterThanEqual:
return fmt.Sprintf(`"%s": bson.M{"$gte": arg%d}`, p.Field, argIndex)
}
return ""

View file

@ -75,7 +75,7 @@ func (data mongoMethodTemplateData) Returns() string {
const findOneTemplate = ` var entity {{.EntityType}}
if err := r.collection.FindOne(ctx, bson.M{
{{range $index, $field := .Predicates}} {{$field.Code $index}},
{{range $index, $field := .QuerySpec.Predicates}} {{$field.Code $index}},
{{end}} }).Decode(&entity); err != nil {
return nil, err
}
@ -83,12 +83,12 @@ const findOneTemplate = ` var entity {{.EntityType}}
type mongoFindTemplateData struct {
EntityType string
Predicates []predicate
QuerySpec querySpec
}
const findManyTemplate = ` cursor, err := r.collection.Find(ctx, bson.M{
{{range $index, $field := .Predicates}} {{$field.Code $index}},
{{end}} })
{{.QuerySpec.Code}}
})
if err != nil {
return nil, err
}