Add count operation
This commit is contained in:
parent
c752849518
commit
496f9541cb
12 changed files with 858 additions and 261 deletions
internal/mongo
|
@ -85,6 +85,8 @@ func (g RepositoryGenerator) generateMethodImplementation(methodSpec spec.Method
|
|||
return g.generateUpdateImplementation(operation)
|
||||
case spec.DeleteOperation:
|
||||
return g.generateDeleteImplementation(operation)
|
||||
case spec.CountOperation:
|
||||
return g.generateCountImplementation(operation)
|
||||
}
|
||||
|
||||
return "", OperationNotSupportedError
|
||||
|
@ -98,8 +100,6 @@ func (g RepositoryGenerator) generateInsertImplementation(operation spec.InsertO
|
|||
}
|
||||
|
||||
func (g RepositoryGenerator) generateFindImplementation(operation spec.FindOperation) (string, error) {
|
||||
buffer := new(bytes.Buffer)
|
||||
|
||||
querySpec, err := g.mongoQuerySpec(operation.Query)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -111,31 +111,12 @@ func (g RepositoryGenerator) generateFindImplementation(operation spec.FindOpera
|
|||
}
|
||||
|
||||
if operation.Mode == spec.QueryModeOne {
|
||||
tmpl, err := template.New("mongo_repository_findone").Parse(findOneTemplate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := tmpl.Execute(buffer, tmplData); err != nil {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
tmpl, err := template.New("mongo_repository_findmany").Parse(findManyTemplate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := tmpl.Execute(buffer, tmplData); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return generateFromTemplate("mongo_repository_findone", findOneTemplate, tmplData)
|
||||
}
|
||||
|
||||
return buffer.String(), nil
|
||||
return generateFromTemplate("mongo_repository_findmany", findManyTemplate, tmplData)
|
||||
}
|
||||
|
||||
func (g RepositoryGenerator) generateUpdateImplementation(operation spec.UpdateOperation) (string, error) {
|
||||
buffer := new(bytes.Buffer)
|
||||
|
||||
var fields []updateField
|
||||
for _, field := range operation.Fields {
|
||||
bsonTag, err := g.bsonTagFromFieldName(field.Name)
|
||||
|
@ -156,31 +137,12 @@ func (g RepositoryGenerator) generateUpdateImplementation(operation spec.UpdateO
|
|||
}
|
||||
|
||||
if operation.Mode == spec.QueryModeOne {
|
||||
tmpl, err := template.New("mongo_repository_updateone").Parse(updateOneTemplate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := tmpl.Execute(buffer, tmplData); err != nil {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
tmpl, err := template.New("mongo_repository_updatemany").Parse(updateManyTemplate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := tmpl.Execute(buffer, tmplData); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return generateFromTemplate("mongo_repository_updateone", updateOneTemplate, tmplData)
|
||||
}
|
||||
|
||||
return buffer.String(), nil
|
||||
return generateFromTemplate("mongo_repository_updatemany", updateManyTemplate, tmplData)
|
||||
}
|
||||
|
||||
func (g RepositoryGenerator) generateDeleteImplementation(operation spec.DeleteOperation) (string, error) {
|
||||
buffer := new(bytes.Buffer)
|
||||
|
||||
querySpec, err := g.mongoQuerySpec(operation.Query)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
@ -191,26 +153,22 @@ func (g RepositoryGenerator) generateDeleteImplementation(operation spec.DeleteO
|
|||
}
|
||||
|
||||
if operation.Mode == spec.QueryModeOne {
|
||||
tmpl, err := template.New("mongo_repository_deleteone").Parse(deleteOneTemplate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return generateFromTemplate("mongo_repository_deleteone", deleteOneTemplate, tmplData)
|
||||
}
|
||||
return generateFromTemplate("mongo_repository_deletemany", deleteManyTemplate, tmplData)
|
||||
}
|
||||
|
||||
if err := tmpl.Execute(buffer, tmplData); err != nil {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
tmpl, err := template.New("mongo_repository_deletemany").Parse(deleteManyTemplate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := tmpl.Execute(buffer, tmplData); err != nil {
|
||||
return "", err
|
||||
}
|
||||
func (g RepositoryGenerator) generateCountImplementation(operation spec.CountOperation) (string, error) {
|
||||
querySpec, err := g.mongoQuerySpec(operation.Query)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return buffer.String(), nil
|
||||
tmplData := mongoCountTemplateData{
|
||||
QuerySpec: querySpec,
|
||||
}
|
||||
|
||||
return generateFromTemplate("mongo_repository_count", countTemplate, tmplData)
|
||||
}
|
||||
|
||||
func (g RepositoryGenerator) mongoQuerySpec(query spec.QuerySpec) (querySpec, error) {
|
||||
|
@ -252,3 +210,17 @@ func (g RepositoryGenerator) bsonTagFromFieldName(fieldName string) (string, err
|
|||
func (g RepositoryGenerator) structName() string {
|
||||
return g.InterfaceName + "Mongo"
|
||||
}
|
||||
|
||||
func generateFromTemplate(name string, templateString string, tmplData interface{}) (string, error) {
|
||||
tmpl, err := template.New(name).Parse(templateString)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
buffer := new(bytes.Buffer)
|
||||
if err := tmpl.Execute(buffer, tmplData); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return buffer.String(), nil
|
||||
}
|
||||
|
|
|
@ -1089,6 +1089,358 @@ func (r *UserRepositoryMongo) DeleteByGenderIn(arg0 context.Context, arg1 []Gend
|
|||
}
|
||||
}
|
||||
|
||||
func TestGenerateMethod_Count(t *testing.T) {
|
||||
testTable := []GenerateMethodTestCase{
|
||||
{
|
||||
Name: "simple count method",
|
||||
MethodSpec: spec.MethodSpec{
|
||||
Name: "CountByGender",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("Gender")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.CountOperation{
|
||||
Query: spec.QuerySpec{
|
||||
Predicates: []spec.Predicate{
|
||||
{Field: "Gender", Comparator: spec.ComparatorEqual, ParamIndex: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectedCode: `
|
||||
func (r *UserRepositoryMongo) CountByGender(arg0 context.Context, arg1 Gender) (int, error) {
|
||||
count, err := r.collection.CountDocuments(arg0, bson.M{
|
||||
"gender": arg1,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(count), nil
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
Name: "count with And operator",
|
||||
MethodSpec: spec.MethodSpec{
|
||||
Name: "CountByGenderAndCity",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("Gender")},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.CountOperation{
|
||||
Query: spec.QuerySpec{
|
||||
Operator: spec.OperatorAnd,
|
||||
Predicates: []spec.Predicate{
|
||||
{Field: "Gender", Comparator: spec.ComparatorEqual, ParamIndex: 1},
|
||||
{Field: "Age", Comparator: spec.ComparatorEqual, ParamIndex: 2},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectedCode: `
|
||||
func (r *UserRepositoryMongo) CountByGenderAndCity(arg0 context.Context, arg1 Gender, arg2 int) (int, error) {
|
||||
count, err := r.collection.CountDocuments(arg0, bson.M{
|
||||
"gender": arg1,
|
||||
"age": arg2,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(count), nil
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
Name: "count with Or operator",
|
||||
MethodSpec: spec.MethodSpec{
|
||||
Name: "CountByGenderOrCity",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("Gender")},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.CountOperation{
|
||||
Query: spec.QuerySpec{
|
||||
Operator: spec.OperatorOr,
|
||||
Predicates: []spec.Predicate{
|
||||
{Field: "Gender", Comparator: spec.ComparatorEqual, ParamIndex: 1},
|
||||
{Field: "Age", Comparator: spec.ComparatorEqual, ParamIndex: 2},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectedCode: `
|
||||
func (r *UserRepositoryMongo) CountByGenderOrCity(arg0 context.Context, arg1 Gender, arg2 int) (int, error) {
|
||||
count, err := r.collection.CountDocuments(arg0, bson.M{
|
||||
"$or": []bson.M{
|
||||
{"gender": arg1},
|
||||
{"age": arg2},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(count), nil
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
Name: "count with Not comparator",
|
||||
MethodSpec: spec.MethodSpec{
|
||||
Name: "CountByGenderNot",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("Gender")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.CountOperation{
|
||||
Query: spec.QuerySpec{
|
||||
Predicates: []spec.Predicate{
|
||||
{Field: "Gender", Comparator: spec.ComparatorNot, ParamIndex: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectedCode: `
|
||||
func (r *UserRepositoryMongo) CountByGenderNot(arg0 context.Context, arg1 Gender) (int, error) {
|
||||
count, err := r.collection.CountDocuments(arg0, bson.M{
|
||||
"gender": bson.M{"$ne": arg1},
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(count), nil
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
Name: "count with LessThan comparator",
|
||||
MethodSpec: spec.MethodSpec{
|
||||
Name: "CountByAgeLessThan",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.CountOperation{
|
||||
Query: spec.QuerySpec{
|
||||
Predicates: []spec.Predicate{
|
||||
{Field: "Age", Comparator: spec.ComparatorLessThan, ParamIndex: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectedCode: `
|
||||
func (r *UserRepositoryMongo) CountByAgeLessThan(arg0 context.Context, arg1 int) (int, error) {
|
||||
count, err := r.collection.CountDocuments(arg0, bson.M{
|
||||
"age": bson.M{"$lt": arg1},
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(count), nil
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
Name: "count with LessThanEqual comparator",
|
||||
MethodSpec: spec.MethodSpec{
|
||||
Name: "CountByAgeLessThanEqual",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.CountOperation{
|
||||
Query: spec.QuerySpec{
|
||||
Predicates: []spec.Predicate{
|
||||
{Field: "Age", Comparator: spec.ComparatorLessThanEqual, ParamIndex: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectedCode: `
|
||||
func (r *UserRepositoryMongo) CountByAgeLessThanEqual(arg0 context.Context, arg1 int) (int, error) {
|
||||
count, err := r.collection.CountDocuments(arg0, bson.M{
|
||||
"age": bson.M{"$lte": arg1},
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(count), nil
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
Name: "count with GreaterThan comparator",
|
||||
MethodSpec: spec.MethodSpec{
|
||||
Name: "CountByAgeGreaterThan",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.CountOperation{
|
||||
Query: spec.QuerySpec{
|
||||
Predicates: []spec.Predicate{
|
||||
{Field: "Age", Comparator: spec.ComparatorGreaterThan, ParamIndex: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectedCode: `
|
||||
func (r *UserRepositoryMongo) CountByAgeGreaterThan(arg0 context.Context, arg1 int) (int, error) {
|
||||
count, err := r.collection.CountDocuments(arg0, bson.M{
|
||||
"age": bson.M{"$gt": arg1},
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(count), nil
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
Name: "count with GreaterThanEqual comparator",
|
||||
MethodSpec: spec.MethodSpec{
|
||||
Name: "CountByAgeGreaterThanEqual",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.CountOperation{
|
||||
Query: spec.QuerySpec{
|
||||
Predicates: []spec.Predicate{
|
||||
{Field: "Age", Comparator: spec.ComparatorGreaterThanEqual, ParamIndex: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectedCode: `
|
||||
func (r *UserRepositoryMongo) CountByAgeGreaterThanEqual(arg0 context.Context, arg1 int) (int, error) {
|
||||
count, err := r.collection.CountDocuments(arg0, bson.M{
|
||||
"age": bson.M{"$gte": arg1},
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(count), nil
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
Name: "count with Between comparator",
|
||||
MethodSpec: spec.MethodSpec{
|
||||
Name: "CountByAgeBetween",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.SimpleType("int")},
|
||||
{Type: code.SimpleType("int")},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.CountOperation{
|
||||
Query: spec.QuerySpec{
|
||||
Predicates: []spec.Predicate{
|
||||
{Field: "Age", Comparator: spec.ComparatorBetween, ParamIndex: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectedCode: `
|
||||
func (r *UserRepositoryMongo) CountByAgeBetween(arg0 context.Context, arg1 int, arg2 int) (int, error) {
|
||||
count, err := r.collection.CountDocuments(arg0, bson.M{
|
||||
"age": bson.M{"$gte": arg1, "$lte": arg2},
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(count), nil
|
||||
}
|
||||
`,
|
||||
},
|
||||
{
|
||||
Name: "count with In comparator",
|
||||
MethodSpec: spec.MethodSpec{
|
||||
Name: "CountByAgeIn",
|
||||
Params: []code.Param{
|
||||
{Type: code.ExternalType{PackageAlias: "context", Name: "Context"}},
|
||||
{Type: code.ArrayType{ContainedType: code.SimpleType("int")}},
|
||||
},
|
||||
Returns: []code.Type{
|
||||
code.SimpleType("int"),
|
||||
code.SimpleType("error"),
|
||||
},
|
||||
Operation: spec.CountOperation{
|
||||
Query: spec.QuerySpec{
|
||||
Predicates: []spec.Predicate{
|
||||
{Field: "Age", Comparator: spec.ComparatorIn, ParamIndex: 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ExpectedCode: `
|
||||
func (r *UserRepositoryMongo) CountByAgeIn(arg0 context.Context, arg1 []int) (int, error) {
|
||||
count, err := r.collection.CountDocuments(arg0, bson.M{
|
||||
"age": bson.M{"$in": arg1},
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(count), nil
|
||||
}
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testTable {
|
||||
t.Run(testCase.Name, func(t *testing.T) {
|
||||
generator := mongo.NewGenerator(userModel, "UserRepository")
|
||||
buffer := new(bytes.Buffer)
|
||||
|
||||
err := generator.GenerateMethod(testCase.MethodSpec, buffer)
|
||||
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if err := testutils.ExpectMultiLineString(testCase.ExpectedCode, buffer.String()); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type GenerateMethodInvalidTestCase struct {
|
||||
Name string
|
||||
Method spec.MethodSpec
|
||||
|
|
|
@ -159,3 +159,15 @@ const deleteManyTemplate = ` result, err := r.collection.DeleteMany(arg0, bson.M
|
|||
return 0, err
|
||||
}
|
||||
return int(result.DeletedCount), nil`
|
||||
|
||||
type mongoCountTemplateData struct {
|
||||
QuerySpec querySpec
|
||||
}
|
||||
|
||||
const countTemplate = ` count, err := r.collection.CountDocuments(arg0, bson.M{
|
||||
{{.QuerySpec.Code}}
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(count), nil`
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue