service backend
This commit is contained in:
131
api/pkg/db/internal/mongo/repositoryimp/builderimp/pipeline.go
Normal file
131
api/pkg/db/internal/mongo/repositoryimp/builderimp/pipeline.go
Normal file
@@ -0,0 +1,131 @@
|
||||
package builderimp
|
||||
|
||||
import (
|
||||
"github.com/tech/sendico/pkg/db/repository/builder"
|
||||
"github.com/tech/sendico/pkg/mservice"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
type unwindOpts = builder.UnwindOpts
|
||||
|
||||
// UnwindOption is the same type defined in the builder package.
|
||||
type UnwindOption = builder.UnwindOption
|
||||
|
||||
// NewUnwindOpts applies all UnwindOption's to a fresh unwindOpts.
|
||||
func NewUnwindOpts(opts ...UnwindOption) *unwindOpts {
|
||||
cfg := &unwindOpts{}
|
||||
for _, opt := range opts {
|
||||
opt(cfg)
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
type PipelineImp struct {
|
||||
pipeline mongo.Pipeline
|
||||
}
|
||||
|
||||
func (b *PipelineImp) Match(filter builder.Query) builder.Pipeline {
|
||||
b.pipeline = append(b.pipeline, filter.BuildPipeline())
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *PipelineImp) Lookup(from mservice.Type, localField, foreignField, as builder.Field) builder.Pipeline {
|
||||
b.pipeline = append(b.pipeline, bson.D{{Key: string(builder.Lookup), Value: bson.D{
|
||||
{Key: string(builder.MKFrom), Value: from},
|
||||
{Key: string(builder.MKLocalField), Value: localField.Build()},
|
||||
{Key: string(builder.MKForeignField), Value: foreignField.Build()},
|
||||
{Key: string(builder.MKAs), Value: as.Build()},
|
||||
}}})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *PipelineImp) LookupWithPipeline(
|
||||
from mservice.Type,
|
||||
nested builder.Pipeline,
|
||||
as builder.Field,
|
||||
let *map[string]builder.Field,
|
||||
) builder.Pipeline {
|
||||
lookupStage := bson.D{
|
||||
{Key: string(builder.MKFrom), Value: from},
|
||||
{Key: string(builder.MKPipeline), Value: nested.Build()},
|
||||
{Key: string(builder.MKAs), Value: as.Build()},
|
||||
}
|
||||
|
||||
// only add "let" if provided and not empty
|
||||
if let != nil && len(*let) > 0 {
|
||||
letDoc := bson.D{}
|
||||
for varName, fld := range *let {
|
||||
letDoc = append(letDoc, bson.E{Key: varName, Value: fld.Build()})
|
||||
}
|
||||
lookupStage = append(lookupStage, bson.E{Key: string(builder.MKLet), Value: letDoc})
|
||||
}
|
||||
|
||||
b.pipeline = append(b.pipeline, bson.D{{Key: string(builder.Lookup), Value: lookupStage}})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *PipelineImp) Unwind(path builder.Field, opts ...UnwindOption) builder.Pipeline {
|
||||
cfg := NewUnwindOpts(opts...)
|
||||
|
||||
var stageValue interface{}
|
||||
// if no options, shorthand
|
||||
if !cfg.PreserveNullAndEmptyArrays && cfg.IncludeArrayIndex == "" {
|
||||
stageValue = path.Build()
|
||||
} else {
|
||||
d := bson.D{{Key: string(builder.MKPath), Value: path.Build()}}
|
||||
if cfg.PreserveNullAndEmptyArrays {
|
||||
d = append(d, bson.E{Key: string(builder.MKPreserveNullAndEmptyArrays), Value: true})
|
||||
}
|
||||
if cfg.IncludeArrayIndex != "" {
|
||||
d = append(d, bson.E{Key: string(builder.MKIncludeArrayIndex), Value: cfg.IncludeArrayIndex})
|
||||
}
|
||||
stageValue = d
|
||||
}
|
||||
|
||||
b.pipeline = append(b.pipeline, bson.D{{Key: string(builder.Unwind), Value: stageValue}})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *PipelineImp) Count(field builder.Field) builder.Pipeline {
|
||||
b.pipeline = append(b.pipeline, bson.D{{Key: string(builder.Count), Value: field.Build()}})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *PipelineImp) Group(groupBy builder.Alias, accumulators ...builder.GroupAccumulator) builder.Pipeline {
|
||||
groupDoc := groupBy.Build()
|
||||
for _, acc := range accumulators {
|
||||
groupDoc = append(groupDoc, acc.Build()...)
|
||||
}
|
||||
|
||||
b.pipeline = append(b.pipeline, bson.D{
|
||||
{Key: string(builder.Group), Value: groupDoc},
|
||||
})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *PipelineImp) Project(projections ...builder.Projection) builder.Pipeline {
|
||||
projDoc := bson.D{}
|
||||
for _, pr := range projections {
|
||||
projDoc = append(projDoc, pr.Build()...)
|
||||
}
|
||||
b.pipeline = append(b.pipeline, bson.D{{Key: string(builder.Project), Value: projDoc}})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *PipelineImp) ReplaceRoot(newRoot builder.Expression) builder.Pipeline {
|
||||
b.pipeline = append(b.pipeline, bson.D{{Key: string(builder.ReplaceRoot), Value: bson.D{
|
||||
{Key: string(builder.MKNewRoot), Value: newRoot.Build()},
|
||||
}}})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *PipelineImp) Build() mongo.Pipeline {
|
||||
return b.pipeline
|
||||
}
|
||||
|
||||
func NewPipelineImp() builder.Pipeline {
|
||||
return &PipelineImp{
|
||||
pipeline: mongo.Pipeline{},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user