103 lines
2.2 KiB
Go
103 lines
2.2 KiB
Go
package builderimp
|
|
|
|
import (
|
|
"github.com/tech/sendico/pkg/db/repository/builder"
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
)
|
|
|
|
type aliasImp struct {
|
|
lhs builder.Field
|
|
rhs any
|
|
}
|
|
|
|
func (a *aliasImp) Field() builder.Field {
|
|
return a.lhs
|
|
}
|
|
|
|
func (a *aliasImp) Build() bson.D {
|
|
return bson.D{{Key: a.lhs.Build(), Value: a.rhs}}
|
|
}
|
|
|
|
// 1. Null alias (_id: null)
|
|
func NewNullAlias(lhs builder.Field) builder.Alias {
|
|
return &aliasImp{lhs: lhs, rhs: nil}
|
|
}
|
|
|
|
func NewAlias(lhs builder.Field, rhs any) builder.Alias {
|
|
return &aliasImp{lhs: lhs, rhs: rhs}
|
|
}
|
|
|
|
// 2. Simple alias (_id: "$taskRef")
|
|
func NewSimpleAlias(lhs, rhs builder.Field) builder.Alias {
|
|
return &aliasImp{lhs: lhs, rhs: rhs.Build()}
|
|
}
|
|
|
|
// 3. Complex alias (_id: { aliasName: "$originalField", ... })
|
|
type ComplexAlias struct {
|
|
lhs builder.Field
|
|
rhs []builder.Alias // Correcting handling of slice of aliases
|
|
}
|
|
|
|
func (a *ComplexAlias) Field() builder.Field {
|
|
return a.lhs
|
|
}
|
|
|
|
func (a *ComplexAlias) Build() bson.D {
|
|
fieldMap := bson.M{}
|
|
|
|
for _, alias := range a.rhs {
|
|
// Each alias.Build() still returns a bson.D
|
|
aliasDoc := alias.Build()
|
|
|
|
// 1. Marshal the ordered D into raw BSON bytes
|
|
raw, err := bson.Marshal(aliasDoc)
|
|
if err != nil {
|
|
panic("Failed to marshal alias document: " + err.Error())
|
|
}
|
|
|
|
// 2. Unmarshal those bytes into an unordered M
|
|
var docM bson.M
|
|
if err := bson.Unmarshal(raw, &docM); err != nil {
|
|
panic("Failed to unmarshal alias document: " + err.Error())
|
|
}
|
|
|
|
// Merge into our accumulator
|
|
for k, v := range docM {
|
|
fieldMap[k] = v
|
|
}
|
|
}
|
|
|
|
return bson.D{{Key: a.lhs.Build(), Value: fieldMap}}
|
|
}
|
|
|
|
func NewComplexAlias(lhs builder.Field, rhs []builder.Alias) builder.Alias {
|
|
return &ComplexAlias{lhs: lhs, rhs: rhs}
|
|
}
|
|
|
|
type aliasesImp struct {
|
|
aliases []builder.Alias
|
|
}
|
|
|
|
func (a *aliasesImp) Field() builder.Field {
|
|
if len(a.aliases) > 0 {
|
|
return a.aliases[0].Field()
|
|
}
|
|
return NewFieldImp("")
|
|
}
|
|
|
|
func (a *aliasesImp) Build() bson.D {
|
|
results := make([]bson.D, 0)
|
|
for _, alias := range a.aliases {
|
|
results = append(results, alias.Build())
|
|
}
|
|
aliases := bson.D{}
|
|
for _, r := range results {
|
|
aliases = append(aliases, r...)
|
|
}
|
|
return aliases
|
|
}
|
|
|
|
func NewAliases(aliases ...builder.Alias) builder.Alias {
|
|
return &aliasesImp{aliases: aliases}
|
|
}
|