You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
mongox-go-driver/mongox/query/query.go

134 lines
2.7 KiB

package query
import (
"github.com/modern-go/reflect2"
"github.com/valyala/bytebufferpool"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
)
// Query is an enchanched primitive.M map
type Query struct {
m primitive.M
limiter Limiter
sorter Sorter
skipper Skipper
preloader Preloader
updater Updater
onDecode Callbacks
onClose Callbacks
onCreate Callbacks
}
// And function pushes the elem query to the $and array of the query
func (q *Query) And(elem primitive.M) (query *Query) {
if q.m == nil {
q.m = primitive.M{}
}
queries, exists := q.m["$and"].(primitive.A)
if !exists {
q.m["$and"] = primitive.A{elem}
return q
}
q.m["$and"] = append(queries, elem)
return q
}
// Limiter returns limiter value or nil
func (q *Query) Limiter() (limit *int64) {
if q.limiter == nil {
return nil
}
return q.limiter.Limit()
}
// Sorter is a sort rule for a query
func (q *Query) Sorter() (sort interface{}) {
if q.sorter == nil {
return nil
}
return q.sorter.Sort()
}
// Skipper is a skipper for a query
func (q *Query) Skipper() (skip *int64) {
if q.skipper == nil {
return nil
}
return q.skipper.Skip()
}
// Updater is an update command for a query
func (q *Query) Updater() (update primitive.M, err error) {
if q.updater == nil {
return primitive.M{}, nil
}
update = q.updater.Update()
if reflect2.IsNil(update) {
return primitive.M{}, nil
}
buffer := bytebufferpool.Get()
defer bytebufferpool.Put(buffer)
// convert update document to bson map values
buffer.Reset()
bsonBytes, err := bson.MarshalAppend(buffer.B, update)
if err != nil {
return primitive.M{}, err
}
update = primitive.M{} // reset update map and unmarshal bson bytes to it again
err = bson.Unmarshal(bsonBytes, update)
if err != nil {
return primitive.M{}, err
}
return update, nil
}
// Preloader is a preloader list for a query
func (q *Query) Preloader() (preloads []string, ok bool) {
if q.preloader == nil {
return nil, false
}
preloads = q.preloader.Preload()
return preloads, len(preloads) > 0
}
// OnDecode callback is called after the mongo decode function
func (q *Query) OnDecode() (callbacks Callbacks) {
return q.onDecode
}
// OnClose callback is called after the mongox ends a loading procedure
func (q *Query) OnClose() (callbacks Callbacks) {
return q.onClose
}
// OnCreate callback is called if the mongox creates a new document instance during loading
func (q *Query) OnCreate() (callbacks Callbacks) {
return q.onClose
}
// Empty checks the query for any content
func (q *Query) Empty() (isEmpty bool) {
return len(q.m) == 0
}
// M returns underlying query map
func (q *Query) M() (m primitive.M) {
return q.m
}
// New creates a new query
func New() (query *Query) {
return &Query{}
}