service backend
This commit is contained in:
156
api/pkg/db/internal/mongo/repositoryimp/builderimp/query.go
Normal file
156
api/pkg/db/internal/mongo/repositoryimp/builderimp/query.go
Normal file
@@ -0,0 +1,156 @@
|
||||
package builderimp
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/tech/sendico/pkg/db/repository/builder"
|
||||
"github.com/tech/sendico/pkg/db/storable"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type QueryImp struct {
|
||||
filter bson.D
|
||||
sort bson.D
|
||||
limit *int64
|
||||
offset *int64
|
||||
}
|
||||
|
||||
func (b *QueryImp) Filter(field builder.Field, value any) builder.Query {
|
||||
b.filter = append(b.filter, bson.E{Key: field.Build(), Value: value})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *QueryImp) And(filters ...builder.Query) builder.Query {
|
||||
andFilters := bson.A{}
|
||||
for _, f := range filters {
|
||||
andFilters = append(andFilters, f.BuildQuery())
|
||||
}
|
||||
b.filter = append(b.filter, bson.E{Key: string(builder.And), Value: andFilters})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *QueryImp) Or(filters ...builder.Query) builder.Query {
|
||||
orFilters := bson.A{}
|
||||
for _, f := range filters {
|
||||
orFilters = append(orFilters, f.BuildQuery())
|
||||
}
|
||||
b.filter = append(b.filter, bson.E{Key: string(builder.Or), Value: orFilters})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *QueryImp) Comparison(field builder.Field, operator builder.MongoOperation, value any) builder.Query {
|
||||
b.filter = append(b.filter, bson.E{Key: field.Build(), Value: bson.M{string(operator): value}})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *QueryImp) Expression(value builder.Expression) builder.Query {
|
||||
b.filter = append(b.filter, bson.E{Key: string(builder.Expr), Value: value.Build()})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *QueryImp) RegEx(field builder.Field, pattern, options string) builder.Query {
|
||||
b.filter = append(b.filter, bson.E{Key: field.Build(), Value: primitive.Regex{Pattern: pattern, Options: options}})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *QueryImp) opIn(field builder.Field, op builder.MongoOperation, values ...any) builder.Query {
|
||||
var flattenedValues []any
|
||||
|
||||
for _, v := range values {
|
||||
switch reflect.TypeOf(v).Kind() {
|
||||
case reflect.Slice:
|
||||
slice := reflect.ValueOf(v)
|
||||
for i := range slice.Len() {
|
||||
flattenedValues = append(flattenedValues, slice.Index(i).Interface())
|
||||
}
|
||||
default:
|
||||
flattenedValues = append(flattenedValues, v)
|
||||
}
|
||||
}
|
||||
|
||||
b.filter = append(b.filter, bson.E{Key: field.Build(), Value: bson.M{string(op): flattenedValues}})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *QueryImp) NotIn(field builder.Field, values ...any) builder.Query {
|
||||
return b.opIn(field, builder.NotIn, values...)
|
||||
}
|
||||
|
||||
func (b *QueryImp) In(field builder.Field, values ...any) builder.Query {
|
||||
return b.opIn(field, builder.In, values...)
|
||||
}
|
||||
|
||||
func (b *QueryImp) Archived(isArchived *bool) builder.Query {
|
||||
if isArchived == nil {
|
||||
return b
|
||||
}
|
||||
return b.And(NewQueryImp().Filter(NewFieldImp(storable.IsArchivedField), *isArchived))
|
||||
}
|
||||
|
||||
func (b *QueryImp) Sort(field builder.Field, ascending bool) builder.Query {
|
||||
order := 1
|
||||
if !ascending {
|
||||
order = -1
|
||||
}
|
||||
b.sort = append(b.sort, bson.E{Key: field.Build(), Value: order})
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *QueryImp) BuildPipeline() bson.D {
|
||||
query := bson.D{}
|
||||
|
||||
if len(b.filter) > 0 {
|
||||
query = append(query, bson.E{Key: string(builder.Match), Value: b.filter})
|
||||
}
|
||||
|
||||
if len(b.sort) > 0 {
|
||||
query = append(query, bson.E{Key: string(builder.Sort), Value: b.sort})
|
||||
}
|
||||
|
||||
if b.limit != nil {
|
||||
query = append(query, bson.E{Key: string(builder.Limit), Value: *b.limit})
|
||||
}
|
||||
|
||||
if b.offset != nil {
|
||||
query = append(query, bson.E{Key: string(builder.Skip), Value: *b.offset})
|
||||
}
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
func (b *QueryImp) BuildQuery() bson.D {
|
||||
return b.filter
|
||||
}
|
||||
|
||||
func (b *QueryImp) Limit(limit *int64) builder.Query {
|
||||
b.limit = limit
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *QueryImp) Offset(offset *int64) builder.Query {
|
||||
b.offset = offset
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *QueryImp) BuildOptions() *options.FindOptions {
|
||||
opts := options.Find()
|
||||
if b.limit != nil {
|
||||
opts.SetLimit(*b.limit)
|
||||
}
|
||||
if b.offset != nil {
|
||||
opts.SetSkip(*b.offset)
|
||||
}
|
||||
if len(b.sort) > 0 {
|
||||
opts.SetSort(b.sort)
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
func NewQueryImp() builder.Query {
|
||||
return &QueryImp{
|
||||
filter: bson.D{},
|
||||
sort: bson.D{},
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user