145 lines
3.8 KiB
Go
145 lines
3.8 KiB
Go
package mongo
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"git.kmsign.ru/royalcat/repogen/internal/code"
|
|
"git.kmsign.ru/royalcat/repogen/internal/codegen"
|
|
"git.kmsign.ru/royalcat/repogen/internal/spec"
|
|
)
|
|
|
|
// NewGenerator creates a new instance of MongoDB repository generator
|
|
func NewGenerator(structModel code.Struct, interfaceName string) RepositoryGenerator {
|
|
return RepositoryGenerator{
|
|
baseMethodGenerator: baseMethodGenerator{
|
|
structModel: structModel,
|
|
},
|
|
InterfaceName: interfaceName,
|
|
}
|
|
}
|
|
|
|
// RepositoryGenerator is a MongoDB repository generator that provides
|
|
// necessary information required to construct an implementation.
|
|
type RepositoryGenerator struct {
|
|
baseMethodGenerator
|
|
InterfaceName string
|
|
}
|
|
|
|
// Imports returns necessary imports for the mongo repository implementation.
|
|
func (g RepositoryGenerator) Imports() [][]code.Import {
|
|
return [][]code.Import{
|
|
{
|
|
{Path: "context"},
|
|
},
|
|
{
|
|
{Path: "go.mongodb.org/mongo-driver/bson"},
|
|
{Path: "go.mongodb.org/mongo-driver/bson/primitive"},
|
|
{Path: "go.mongodb.org/mongo-driver/mongo"},
|
|
{Path: "go.mongodb.org/mongo-driver/mongo/options"},
|
|
},
|
|
}
|
|
}
|
|
|
|
// GenerateStruct creates codegen.StructBuilder of mongo repository
|
|
// implementation struct.
|
|
func (g RepositoryGenerator) GenerateStruct() codegen.StructBuilder {
|
|
return codegen.StructBuilder{
|
|
Name: g.repoImplStructName(),
|
|
Fields: code.StructFields{
|
|
{
|
|
Name: "collection",
|
|
Type: code.PointerType{
|
|
ContainedType: code.ExternalType{
|
|
PackageAlias: "mongo",
|
|
Name: "Collection",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// GenerateConstructor creates codegen.FunctionBuilder of a constructor for
|
|
// mongo repository implementation struct.
|
|
func (g RepositoryGenerator) GenerateConstructor() (codegen.FunctionBuilder, error) {
|
|
return codegen.FunctionBuilder{
|
|
Name: "New" + g.InterfaceName,
|
|
Params: []code.Param{
|
|
{
|
|
Name: "collection",
|
|
Type: code.PointerType{
|
|
ContainedType: code.ExternalType{
|
|
PackageAlias: "mongo",
|
|
Name: "Collection",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Returns: []code.Type{
|
|
code.SimpleType(g.InterfaceName),
|
|
},
|
|
Body: codegen.FunctionBody{
|
|
codegen.ReturnStatement{
|
|
codegen.StructStatement{
|
|
Type: fmt.Sprintf("&%s", g.repoImplStructName()),
|
|
Pairs: []codegen.StructFieldPair{{
|
|
Key: "collection",
|
|
Value: codegen.Identifier("collection"),
|
|
}},
|
|
},
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// GenerateMethod creates codegen.MethodBuilder of repository method from the
|
|
// provided method specification.
|
|
func (g RepositoryGenerator) GenerateMethod(methodSpec spec.MethodSpec) (codegen.MethodBuilder, error) {
|
|
var params []code.Param
|
|
for i, param := range methodSpec.Params {
|
|
params = append(params, code.Param{
|
|
Name: fmt.Sprintf("arg%d", i),
|
|
Type: param.Type,
|
|
})
|
|
}
|
|
|
|
implementation, err := g.generateMethodImplementation(methodSpec)
|
|
if err != nil {
|
|
return codegen.MethodBuilder{}, err
|
|
}
|
|
|
|
return codegen.MethodBuilder{
|
|
Receiver: codegen.MethodReceiver{
|
|
Name: "r",
|
|
Type: code.SimpleType(g.repoImplStructName()),
|
|
Pointer: true,
|
|
},
|
|
Name: methodSpec.Name,
|
|
Params: params,
|
|
Returns: methodSpec.Returns,
|
|
Body: implementation,
|
|
}, nil
|
|
}
|
|
|
|
func (g RepositoryGenerator) generateMethodImplementation(
|
|
methodSpec spec.MethodSpec) (codegen.FunctionBody, error) {
|
|
|
|
switch operation := methodSpec.Operation.(type) {
|
|
case spec.InsertOperation:
|
|
return g.generateInsertBody(operation), nil
|
|
case spec.FindOperation:
|
|
return g.generateFindBody(operation)
|
|
case spec.UpdateOperation:
|
|
return g.generateUpdateBody(operation)
|
|
case spec.DeleteOperation:
|
|
return g.generateDeleteBody(operation)
|
|
case spec.CountOperation:
|
|
return g.generateCountBody(operation)
|
|
default:
|
|
return nil, NewOperationNotSupportedError(operation.Name())
|
|
}
|
|
}
|
|
|
|
func (g RepositoryGenerator) repoImplStructName() string {
|
|
return g.InterfaceName + "Mongo"
|
|
}
|