Add Or operator
This commit is contained in:
parent
bc878c778c
commit
153deb8f7d
8 changed files with 178 additions and 47 deletions
internal/mongo
|
@ -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 {
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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 ""
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue