Add simple comparison predicates
This commit is contained in:
parent
5e7d773e1b
commit
bc878c778c
9 changed files with 465 additions and 34 deletions
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
|
@ -7,7 +7,7 @@ on:
|
||||||
branches: [ main ]
|
branches: [ main ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
|
@ -5,3 +5,7 @@
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
Repogen is a code generator for database repository in Golang. (WIP)
|
Repogen is a code generator for database repository in Golang. (WIP)
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
Repogen is a library that generates MongoDB repository implementation from repository interface by using method name pattern.
|
||||||
|
|
|
@ -120,24 +120,24 @@ func (g mongoRepositoryGenerator) generateMethodImplementation(methodSpec spec.M
|
||||||
func (g mongoRepositoryGenerator) generateFindImplementation(operation spec.FindOperation) (string, error) {
|
func (g mongoRepositoryGenerator) generateFindImplementation(operation spec.FindOperation) (string, error) {
|
||||||
buffer := new(bytes.Buffer)
|
buffer := new(bytes.Buffer)
|
||||||
|
|
||||||
var queryFields []string
|
var predicates []predicate
|
||||||
for _, fieldName := range operation.Query.Fields {
|
for _, predicateSpec := range operation.Query.Predicates {
|
||||||
structField, ok := g.StructModel.Fields.ByName(fieldName)
|
structField, ok := g.StructModel.Fields.ByName(predicateSpec.Field)
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", fmt.Errorf("struct field %s not found", fieldName)
|
return "", fmt.Errorf("struct field %s not found", predicateSpec.Field)
|
||||||
}
|
}
|
||||||
|
|
||||||
bsonTag, ok := structField.Tags["bson"]
|
bsonTag, ok := structField.Tags["bson"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", fmt.Errorf("struct field %s does not have bson tag", fieldName)
|
return "", fmt.Errorf("struct field %s does not have bson tag", predicateSpec.Field)
|
||||||
}
|
}
|
||||||
|
|
||||||
queryFields = append(queryFields, bsonTag[0])
|
predicates = append(predicates, predicate{Field: bsonTag[0], Operator: predicateSpec.Operator})
|
||||||
}
|
}
|
||||||
|
|
||||||
tmplData := mongoFindTemplateData{
|
tmplData := mongoFindTemplateData{
|
||||||
EntityType: g.StructModel.Name,
|
EntityType: g.StructModel.Name,
|
||||||
QueryFields: queryFields,
|
Predicates: predicates,
|
||||||
}
|
}
|
||||||
|
|
||||||
if operation.Mode == spec.QueryModeOne {
|
if operation.Mode == spec.QueryModeOne {
|
||||||
|
|
|
@ -22,6 +22,16 @@ func TestGenerateMongoRepository(t *testing.T) {
|
||||||
Type: code.SimpleType("string"),
|
Type: code.SimpleType("string"),
|
||||||
Tags: map[string][]string{"bson": {"username"}},
|
Tags: map[string][]string{"bson": {"username"}},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "Gender",
|
||||||
|
Type: code.SimpleType("Gender"),
|
||||||
|
Tags: map[string][]string{"bson": {"gender"}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Age",
|
||||||
|
Type: code.SimpleType("int"),
|
||||||
|
Tags: map[string][]string{"bson": {"age"}},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
intf := code.Interface{
|
intf := code.Interface{
|
||||||
|
@ -69,6 +79,61 @@ func TestGenerateMongoRepository(t *testing.T) {
|
||||||
code.SimpleType("error"),
|
code.SimpleType("error"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "FindByGenderNot",
|
||||||
|
Params: []code.Param{
|
||||||
|
{Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||||
|
{Name: "gender", Type: code.SimpleType("int")},
|
||||||
|
},
|
||||||
|
Returns: []code.Type{
|
||||||
|
code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}},
|
||||||
|
code.SimpleType("error"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "FindByAgeLessThan",
|
||||||
|
Params: []code.Param{
|
||||||
|
{Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||||
|
{Name: "age", Type: code.SimpleType("int")},
|
||||||
|
},
|
||||||
|
Returns: []code.Type{
|
||||||
|
code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}},
|
||||||
|
code.SimpleType("error"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "FindByAgeLessThanEqual",
|
||||||
|
Params: []code.Param{
|
||||||
|
{Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||||
|
{Name: "age", Type: code.SimpleType("int")},
|
||||||
|
},
|
||||||
|
Returns: []code.Type{
|
||||||
|
code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}},
|
||||||
|
code.SimpleType("error"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "FindByAgeGreaterThan",
|
||||||
|
Params: []code.Param{
|
||||||
|
{Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||||
|
{Name: "age", Type: code.SimpleType("int")},
|
||||||
|
},
|
||||||
|
Returns: []code.Type{
|
||||||
|
code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}},
|
||||||
|
code.SimpleType("error"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "FindByAgeGreaterThanEqual",
|
||||||
|
Params: []code.Param{
|
||||||
|
{Name: "ctx", Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||||
|
{Name: "age", Type: code.SimpleType("int")},
|
||||||
|
},
|
||||||
|
Returns: []code.Type{
|
||||||
|
code.ArrayType{ContainedType: code.PointerType{ContainedType: code.SimpleType("UserModel")}},
|
||||||
|
code.SimpleType("error"),
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,6 +207,76 @@ func (r *UserRepositoryMongo) FindByIDAndUsername(ctx context.Context, arg0 prim
|
||||||
}
|
}
|
||||||
return &entity, nil
|
return &entity, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *UserRepositoryMongo) FindByGenderNot(ctx context.Context, arg0 int) ([]*UserModel, error) {
|
||||||
|
cursor, err := r.collection.Find(ctx, bson.M{
|
||||||
|
"gender": bson.M{"$ne": arg0},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var entities []*UserModel
|
||||||
|
if err := cursor.All(ctx, &entities); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return entities, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *UserRepositoryMongo) FindByAgeLessThan(ctx context.Context, arg0 int) ([]*UserModel, error) {
|
||||||
|
cursor, err := r.collection.Find(ctx, bson.M{
|
||||||
|
"age": bson.M{"$lt": arg0},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var entities []*UserModel
|
||||||
|
if err := cursor.All(ctx, &entities); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return entities, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *UserRepositoryMongo) FindByAgeLessThanEqual(ctx context.Context, arg0 int) ([]*UserModel, error) {
|
||||||
|
cursor, err := r.collection.Find(ctx, bson.M{
|
||||||
|
"age": bson.M{"$lte": arg0},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var entities []*UserModel
|
||||||
|
if err := cursor.All(ctx, &entities); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return entities, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *UserRepositoryMongo) FindByAgeGreaterThan(ctx context.Context, arg0 int) ([]*UserModel, error) {
|
||||||
|
cursor, err := r.collection.Find(ctx, bson.M{
|
||||||
|
"age": bson.M{"$gt": arg0},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var entities []*UserModel
|
||||||
|
if err := cursor.All(ctx, &entities); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return entities, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *UserRepositoryMongo) FindByAgeGreaterThanEqual(ctx context.Context, arg0 int) ([]*UserModel, error) {
|
||||||
|
cursor, err := r.collection.Find(ctx, bson.M{
|
||||||
|
"age": bson.M{"$gte": arg0},
|
||||||
|
})
|
||||||
|
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")
|
expectedCodeLines := strings.Split(expectedCode, "\n")
|
||||||
actualCodeLines := strings.Split(code, "\n")
|
actualCodeLines := strings.Split(code, "\n")
|
||||||
|
|
30
internal/mongo/models.go
Normal file
30
internal/mongo/models.go
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package mongo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/sunboyy/repogen/internal/spec"
|
||||||
|
)
|
||||||
|
|
||||||
|
type predicate struct {
|
||||||
|
Field string
|
||||||
|
Operator spec.Operator
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p predicate) Code(argIndex int) string {
|
||||||
|
switch p.Operator {
|
||||||
|
case spec.OperatorEqual:
|
||||||
|
return fmt.Sprintf(`"%s": arg%d`, p.Field, argIndex)
|
||||||
|
case spec.OperatorNot:
|
||||||
|
return fmt.Sprintf(`"%s": bson.M{"$ne": arg%d}`, p.Field, argIndex)
|
||||||
|
case spec.OperatorLessThan:
|
||||||
|
return fmt.Sprintf(`"%s": bson.M{"$lt": arg%d}`, p.Field, argIndex)
|
||||||
|
case spec.OperatorLessThanEqual:
|
||||||
|
return fmt.Sprintf(`"%s": bson.M{"$lte": arg%d}`, p.Field, argIndex)
|
||||||
|
case spec.OperatorGreaterThan:
|
||||||
|
return fmt.Sprintf(`"%s": bson.M{"$gt": arg%d}`, p.Field, argIndex)
|
||||||
|
case spec.OperatorGreaterThanEqual:
|
||||||
|
return fmt.Sprintf(`"%s": bson.M{"$gte": arg%d}`, p.Field, argIndex)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
|
@ -75,19 +75,19 @@ func (data mongoMethodTemplateData) Returns() string {
|
||||||
|
|
||||||
const findOneTemplate = ` var entity {{.EntityType}}
|
const findOneTemplate = ` var entity {{.EntityType}}
|
||||||
if err := r.collection.FindOne(ctx, bson.M{
|
if err := r.collection.FindOne(ctx, bson.M{
|
||||||
{{range $index, $field := .QueryFields}} "{{$field}}": arg{{$index}},
|
{{range $index, $field := .Predicates}} {{$field.Code $index}},
|
||||||
{{end}} }).Decode(&entity); err != nil {
|
{{end}} }).Decode(&entity); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &entity, nil`
|
return &entity, nil`
|
||||||
|
|
||||||
type mongoFindTemplateData struct {
|
type mongoFindTemplateData struct {
|
||||||
EntityType string
|
EntityType string
|
||||||
QueryFields []string
|
Predicates []predicate
|
||||||
}
|
}
|
||||||
|
|
||||||
const findManyTemplate = ` cursor, err := r.collection.Find(ctx, bson.M{
|
const findManyTemplate = ` cursor, err := r.collection.Find(ctx, bson.M{
|
||||||
{{range $index, $field := .QueryFields}} "{{$field}}": arg{{$index}},
|
{{range $index, $field := .Predicates}} {{$field.Code $index}},
|
||||||
{{end}} })
|
{{end}} })
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package spec
|
package spec
|
||||||
|
|
||||||
import "github.com/sunboyy/repogen/internal/code"
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/sunboyy/repogen/internal/code"
|
||||||
|
)
|
||||||
|
|
||||||
// QueryMode one or many
|
// QueryMode one or many
|
||||||
type QueryMode string
|
type QueryMode string
|
||||||
|
@ -35,12 +39,52 @@ type FindOperation struct {
|
||||||
Query QuerySpec
|
Query QuerySpec
|
||||||
}
|
}
|
||||||
|
|
||||||
// QuerySpec is a condition of querying the database
|
// QuerySpec is a set of conditions of querying the database
|
||||||
type QuerySpec struct {
|
type QuerySpec struct {
|
||||||
Fields []string
|
Predicates []Predicate
|
||||||
}
|
}
|
||||||
|
|
||||||
// NumberOfArguments returns number of arguments required to perform the query
|
// NumberOfArguments returns number of arguments required to perform the query
|
||||||
func (q QuerySpec) NumberOfArguments() int {
|
func (q QuerySpec) NumberOfArguments() int {
|
||||||
return len(q.Fields)
|
return len(q.Predicates)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Operator is an operator of the condition to query the data
|
||||||
|
type Operator string
|
||||||
|
|
||||||
|
// operator constants
|
||||||
|
const (
|
||||||
|
OperatorEqual Operator = "EQUAL"
|
||||||
|
OperatorNot Operator = "NOT"
|
||||||
|
OperatorLessThan Operator = "LESS_THAN"
|
||||||
|
OperatorLessThanEqual Operator = "LESS_THAN_EQUAL"
|
||||||
|
OperatorGreaterThan Operator = "GREATER_THAN"
|
||||||
|
OperatorGreaterThanEqual Operator = "GREATER_THAN_EQUAL"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Predicate is a criteria for querying a field
|
||||||
|
type Predicate struct {
|
||||||
|
Field string
|
||||||
|
Operator Operator
|
||||||
|
}
|
||||||
|
|
||||||
|
type predicateToken []string
|
||||||
|
|
||||||
|
func (t predicateToken) ToPredicate() Predicate {
|
||||||
|
if len(t) > 1 && t[len(t)-1] == "Not" {
|
||||||
|
return Predicate{Field: strings.Join(t[:len(t)-1], ""), Operator: OperatorNot}
|
||||||
|
}
|
||||||
|
if len(t) > 2 && t[len(t)-2] == "Less" && t[len(t)-1] == "Than" {
|
||||||
|
return Predicate{Field: strings.Join(t[:len(t)-2], ""), Operator: OperatorLessThan}
|
||||||
|
}
|
||||||
|
if len(t) > 3 && t[len(t)-3] == "Less" && t[len(t)-2] == "Than" && t[len(t)-1] == "Equal" {
|
||||||
|
return Predicate{Field: strings.Join(t[:len(t)-3], ""), Operator: OperatorLessThanEqual}
|
||||||
|
}
|
||||||
|
if len(t) > 2 && t[len(t)-2] == "Greater" && t[len(t)-1] == "Than" {
|
||||||
|
return Predicate{Field: strings.Join(t[:len(t)-2], ""), Operator: OperatorGreaterThan}
|
||||||
|
}
|
||||||
|
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], ""), Operator: OperatorGreaterThanEqual}
|
||||||
|
}
|
||||||
|
return Predicate{Field: strings.Join(t, ""), Operator: OperatorEqual}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,20 +130,21 @@ func (p repositoryInterfaceParser) parseQuery(tokens []string) (QuerySpec, error
|
||||||
if tokens[0] == "And" {
|
if tokens[0] == "And" {
|
||||||
return QuerySpec{}, errors.New("method name not supported")
|
return QuerySpec{}, errors.New("method name not supported")
|
||||||
}
|
}
|
||||||
var queryFields []string
|
|
||||||
var aggregatedToken string
|
var predicates []Predicate
|
||||||
|
var aggregatedToken predicateToken
|
||||||
for _, token := range tokens {
|
for _, token := range tokens {
|
||||||
if token != "And" {
|
if token != "And" {
|
||||||
aggregatedToken += token
|
aggregatedToken = append(aggregatedToken, token)
|
||||||
} else {
|
} else {
|
||||||
queryFields = append(queryFields, aggregatedToken)
|
predicates = append(predicates, aggregatedToken.ToPredicate())
|
||||||
aggregatedToken = ""
|
aggregatedToken = predicateToken{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if aggregatedToken == "" {
|
if len(aggregatedToken) == 0 {
|
||||||
return QuerySpec{}, errors.New("method name not supported")
|
return QuerySpec{}, errors.New("method name not supported")
|
||||||
}
|
}
|
||||||
queryFields = append(queryFields, aggregatedToken)
|
predicates = append(predicates, aggregatedToken.ToPredicate())
|
||||||
|
|
||||||
return QuerySpec{Fields: queryFields}, nil
|
return QuerySpec{Predicates: predicates}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,8 +57,10 @@ func TestParseRepositoryInterface(t *testing.T) {
|
||||||
code.SimpleType("error"),
|
code.SimpleType("error"),
|
||||||
},
|
},
|
||||||
Operation: spec.FindOperation{
|
Operation: spec.FindOperation{
|
||||||
Mode: spec.QueryModeOne,
|
Mode: spec.QueryModeOne,
|
||||||
Query: spec.QuerySpec{Fields: []string{"ID"}},
|
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||||
|
{Field: "ID", Operator: spec.OperatorEqual},
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -96,9 +98,10 @@ func TestParseRepositoryInterface(t *testing.T) {
|
||||||
code.SimpleType("error"),
|
code.SimpleType("error"),
|
||||||
},
|
},
|
||||||
Operation: spec.FindOperation{
|
Operation: spec.FindOperation{
|
||||||
|
Mode: spec.QueryModeOne,
|
||||||
Mode: spec.QueryModeOne,
|
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||||
Query: spec.QuerySpec{Fields: []string{"PhoneNumber"}},
|
{Field: "PhoneNumber", Operator: spec.OperatorEqual},
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -136,8 +139,10 @@ func TestParseRepositoryInterface(t *testing.T) {
|
||||||
code.SimpleType("error"),
|
code.SimpleType("error"),
|
||||||
},
|
},
|
||||||
Operation: spec.FindOperation{
|
Operation: spec.FindOperation{
|
||||||
Mode: spec.QueryModeMany,
|
Mode: spec.QueryModeMany,
|
||||||
Query: spec.QuerySpec{Fields: []string{"City"}},
|
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||||
|
{Field: "City", Operator: spec.OperatorEqual},
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -213,8 +218,216 @@ func TestParseRepositoryInterface(t *testing.T) {
|
||||||
code.SimpleType("error"),
|
code.SimpleType("error"),
|
||||||
},
|
},
|
||||||
Operation: spec.FindOperation{
|
Operation: spec.FindOperation{
|
||||||
Mode: spec.QueryModeMany,
|
Mode: spec.QueryModeMany,
|
||||||
Query: spec.QuerySpec{Fields: []string{"City", "Gender"}},
|
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||||
|
{Field: "City", Operator: spec.OperatorEqual},
|
||||||
|
{Field: "Gender", Operator: spec.OperatorEqual},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "FindByArgNot method",
|
||||||
|
Interface: code.Interface{
|
||||||
|
Name: "UserRepository",
|
||||||
|
Methods: []code.Method{
|
||||||
|
{
|
||||||
|
Name: "FindByCityNot",
|
||||||
|
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"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ExpectedOutput: spec.RepositorySpec{
|
||||||
|
InterfaceName: "UserRepository",
|
||||||
|
Methods: []spec.MethodSpec{
|
||||||
|
{
|
||||||
|
Name: "FindByCityNot",
|
||||||
|
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"),
|
||||||
|
},
|
||||||
|
Operation: spec.FindOperation{
|
||||||
|
Mode: spec.QueryModeMany,
|
||||||
|
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||||
|
{Field: "City", Operator: spec.OperatorNot},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "FindByArgLessThan method",
|
||||||
|
Interface: code.Interface{
|
||||||
|
Name: "UserRepository",
|
||||||
|
Methods: []code.Method{
|
||||||
|
{
|
||||||
|
Name: "FindByAgeLessThan",
|
||||||
|
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"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ExpectedOutput: spec.RepositorySpec{
|
||||||
|
InterfaceName: "UserRepository",
|
||||||
|
Methods: []spec.MethodSpec{
|
||||||
|
{
|
||||||
|
Name: "FindByAgeLessThan",
|
||||||
|
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"),
|
||||||
|
},
|
||||||
|
Operation: spec.FindOperation{
|
||||||
|
Mode: spec.QueryModeMany,
|
||||||
|
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||||
|
{Field: "Age", Operator: spec.OperatorLessThan},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "FindByArgLessThanEqual method",
|
||||||
|
Interface: code.Interface{
|
||||||
|
Name: "UserRepository",
|
||||||
|
Methods: []code.Method{
|
||||||
|
{
|
||||||
|
Name: "FindByAgeLessThanEqual",
|
||||||
|
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"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ExpectedOutput: spec.RepositorySpec{
|
||||||
|
InterfaceName: "UserRepository",
|
||||||
|
Methods: []spec.MethodSpec{
|
||||||
|
{
|
||||||
|
Name: "FindByAgeLessThanEqual",
|
||||||
|
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"),
|
||||||
|
},
|
||||||
|
Operation: spec.FindOperation{
|
||||||
|
Mode: spec.QueryModeMany,
|
||||||
|
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||||
|
{Field: "Age", Operator: spec.OperatorLessThanEqual},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "FindByArgGreaterThan method",
|
||||||
|
Interface: code.Interface{
|
||||||
|
Name: "UserRepository",
|
||||||
|
Methods: []code.Method{
|
||||||
|
{
|
||||||
|
Name: "FindByAgeGreaterThan",
|
||||||
|
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"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ExpectedOutput: spec.RepositorySpec{
|
||||||
|
InterfaceName: "UserRepository",
|
||||||
|
Methods: []spec.MethodSpec{
|
||||||
|
{
|
||||||
|
Name: "FindByAgeGreaterThan",
|
||||||
|
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"),
|
||||||
|
},
|
||||||
|
Operation: spec.FindOperation{
|
||||||
|
Mode: spec.QueryModeMany,
|
||||||
|
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||||
|
{Field: "Age", Operator: spec.OperatorGreaterThan},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "FindByArgGreaterThanEqual method",
|
||||||
|
Interface: code.Interface{
|
||||||
|
Name: "UserRepository",
|
||||||
|
Methods: []code.Method{
|
||||||
|
{
|
||||||
|
Name: "FindByAgeGreaterThanEqual",
|
||||||
|
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"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ExpectedOutput: spec.RepositorySpec{
|
||||||
|
InterfaceName: "UserRepository",
|
||||||
|
Methods: []spec.MethodSpec{
|
||||||
|
{
|
||||||
|
Name: "FindByAgeGreaterThanEqual",
|
||||||
|
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"),
|
||||||
|
},
|
||||||
|
Operation: spec.FindOperation{
|
||||||
|
Mode: spec.QueryModeMany,
|
||||||
|
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||||
|
{Field: "Age", Operator: spec.OperatorGreaterThanEqual},
|
||||||
|
}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -241,6 +454,10 @@ func TestParseRepositoryInterface(t *testing.T) {
|
||||||
Name: "City",
|
Name: "City",
|
||||||
Type: code.SimpleType("string"),
|
Type: code.SimpleType("string"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "Age",
|
||||||
|
Type: code.SimpleType("int"),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue