Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
bfe62799d3
|
|||
ede912eb7b
|
|||
ff8f128fe8
|
|||
1971f1396f
|
|||
bf6c184d12
|
|||
770f5c5c64
|
|||
623c021689
|
|||
afcc89bf9e
|
|||
1672e8f8fd
|
|||
398ed56d32
|
@@ -46,6 +46,7 @@ var (
|
||||
TypeCursorTokenDecode = NewType("CURSOR_TOKEN_DECODE", langext.Ptr(500))
|
||||
TypeMongoFilter = NewType("MONGO_FILTER", langext.Ptr(500))
|
||||
TypeMongoReflection = NewType("MONGO_REFLECTION", langext.Ptr(500))
|
||||
TypeMongoInvalidOpt = NewType("MONGO_INVALIDOPT", langext.Ptr(500))
|
||||
|
||||
TypeWrap = NewType("Wrap", nil)
|
||||
|
||||
|
@@ -169,14 +169,32 @@ func (ee *ExErr) ShortLog(evt *zerolog.Event) {
|
||||
|
||||
// RecursiveMessage returns the message to show
|
||||
// = first error (top-down) that is not wrapping/foreign/empty
|
||||
// = lowest level error (that is not empty)
|
||||
// = fallback to self.message
|
||||
func (ee *ExErr) RecursiveMessage() string {
|
||||
|
||||
// ==== [1] ==== first error (top-down) that is not wrapping/foreign/empty
|
||||
|
||||
for curr := ee; curr != nil; curr = curr.OriginalError {
|
||||
if curr.Message != "" && curr.Category != CatWrap && curr.Category != CatForeign {
|
||||
return curr.Message
|
||||
}
|
||||
}
|
||||
|
||||
// fallback to self
|
||||
// ==== [2] ==== lowest level error (that is not empty)
|
||||
|
||||
deepestMsg := ""
|
||||
for curr := ee; curr != nil; curr = curr.OriginalError {
|
||||
if curr.Message != "" {
|
||||
deepestMsg = curr.Message
|
||||
}
|
||||
}
|
||||
if deepestMsg != "" {
|
||||
return deepestMsg
|
||||
}
|
||||
|
||||
// ==== [3] ==== fallback to self.message
|
||||
|
||||
return ee.Message
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,5 @@
|
||||
package goext
|
||||
|
||||
const GoextVersion = "0.0.304"
|
||||
const GoextVersion = "0.0.314"
|
||||
|
||||
const GoextVersionTimestamp = "2023-11-09T09:26:46+0100"
|
||||
const GoextVersionTimestamp = "2023-11-10T13:37:54+0100"
|
||||
|
@@ -18,6 +18,15 @@ func CreateGoExtBsonRegistry() *bsoncodec.Registry {
|
||||
rb.RegisterTypeDecoder(reflect.TypeOf(rfctime.RFC3339NanoTime{}), rfctime.RFC3339NanoTime{})
|
||||
rb.RegisterTypeDecoder(reflect.TypeOf(&rfctime.RFC3339NanoTime{}), rfctime.RFC3339NanoTime{})
|
||||
|
||||
rb.RegisterTypeDecoder(reflect.TypeOf(rfctime.UnixTime{}), rfctime.UnixTime{})
|
||||
rb.RegisterTypeDecoder(reflect.TypeOf(&rfctime.UnixTime{}), rfctime.UnixTime{})
|
||||
|
||||
rb.RegisterTypeDecoder(reflect.TypeOf(rfctime.UnixMilliTime{}), rfctime.UnixMilliTime{})
|
||||
rb.RegisterTypeDecoder(reflect.TypeOf(&rfctime.UnixMilliTime{}), rfctime.UnixMilliTime{})
|
||||
|
||||
rb.RegisterTypeDecoder(reflect.TypeOf(rfctime.UnixNanoTime{}), rfctime.UnixNanoTime{})
|
||||
rb.RegisterTypeDecoder(reflect.TypeOf(&rfctime.UnixNanoTime{}), rfctime.UnixNanoTime{})
|
||||
|
||||
rb.RegisterTypeDecoder(reflect.TypeOf(rfctime.Date{}), rfctime.Date{})
|
||||
rb.RegisterTypeDecoder(reflect.TypeOf(&rfctime.Date{}), rfctime.Date{})
|
||||
|
||||
|
@@ -1,29 +1,28 @@
|
||||
package pagination
|
||||
|
||||
import (
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
ct "gogs.mikescher.com/BlackForestBytes/goext/cursortoken"
|
||||
)
|
||||
|
||||
type Filter interface {
|
||||
FilterQuery() mongo.Pipeline
|
||||
Pagination() (string, ct.SortDirection)
|
||||
Sort() bson.D
|
||||
}
|
||||
|
||||
type dynamicFilter struct {
|
||||
pipeline mongo.Pipeline
|
||||
sortField string
|
||||
sortDir ct.SortDirection
|
||||
pipeline mongo.Pipeline
|
||||
sort bson.D
|
||||
}
|
||||
|
||||
func (d dynamicFilter) FilterQuery() mongo.Pipeline {
|
||||
return d.pipeline
|
||||
}
|
||||
|
||||
func (d dynamicFilter) Pagination() (string, ct.SortDirection) {
|
||||
return d.sortField, d.sortDir
|
||||
func (d dynamicFilter) Sort() bson.D {
|
||||
return d.sort
|
||||
}
|
||||
|
||||
func CreateFilter(pipeline mongo.Pipeline, sortField string, sortdir ct.SortDirection) Filter {
|
||||
return dynamicFilter{pipeline: pipeline, sortField: sortField, sortDir: sortdir}
|
||||
func CreateFilter(pipeline mongo.Pipeline, sort bson.D) Filter {
|
||||
return dynamicFilter{pipeline: pipeline, sort: sort}
|
||||
}
|
||||
|
@@ -2,7 +2,14 @@ package rfctime
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/bsoncodec"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/timeext"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -54,6 +61,63 @@ func (d SecondsF64) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(secs)
|
||||
}
|
||||
|
||||
func (d *SecondsF64) UnmarshalBSONValue(bt bsontype.Type, data []byte) error {
|
||||
if bt == bson.TypeNull {
|
||||
// we can't set nil in UnmarshalBSONValue (so we use default(struct))
|
||||
// Use mongoext.CreateGoExtBsonRegistry if you need to unmarsh pointer values
|
||||
// https://stackoverflow.com/questions/75167597
|
||||
// https://jira.mongodb.org/browse/GODRIVER-2252
|
||||
*d = SecondsF64(0)
|
||||
return nil
|
||||
}
|
||||
if bt != bson.TypeDouble {
|
||||
return errors.New(fmt.Sprintf("cannot unmarshal %v into SecondsF64", bt))
|
||||
}
|
||||
var tt float64
|
||||
err := bson.RawValue{Type: bt, Value: data}.Unmarshal(&tt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*d = SecondsF64(tt)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d SecondsF64) MarshalBSONValue() (bsontype.Type, []byte, error) {
|
||||
return bson.MarshalValue(d.Seconds())
|
||||
}
|
||||
|
||||
func (d SecondsF64) DecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if val.Kind() == reflect.Ptr && val.IsNil() {
|
||||
if !val.CanSet() {
|
||||
return errors.New("ValueUnmarshalerDecodeValue")
|
||||
}
|
||||
val.Set(reflect.New(val.Type().Elem()))
|
||||
}
|
||||
|
||||
tp, src, err := bsonrw.Copier{}.CopyValueToBytes(vr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if val.Kind() == reflect.Ptr && len(src) == 0 {
|
||||
val.Set(reflect.Zero(val.Type()))
|
||||
return nil
|
||||
}
|
||||
|
||||
err = d.UnmarshalBSONValue(tp, src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if val.Kind() == reflect.Ptr {
|
||||
val.Set(reflect.ValueOf(&d))
|
||||
} else {
|
||||
val.Set(reflect.ValueOf(d))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewSecondsF64(t time.Duration) SecondsF64 {
|
||||
return SecondsF64(t)
|
||||
}
|
||||
|
@@ -2,6 +2,13 @@ package rfctime
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/bsoncodec"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
@@ -59,6 +66,63 @@ func (t *UnixTime) UnmarshalText(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *UnixTime) UnmarshalBSONValue(bt bsontype.Type, data []byte) error {
|
||||
if bt == bson.TypeNull {
|
||||
// we can't set nil in UnmarshalBSONValue (so we use default(struct))
|
||||
// Use mongoext.CreateGoExtBsonRegistry if you need to unmarsh pointer values
|
||||
// https://stackoverflow.com/questions/75167597
|
||||
// https://jira.mongodb.org/browse/GODRIVER-2252
|
||||
*t = UnixTime{}
|
||||
return nil
|
||||
}
|
||||
if bt != bson.TypeDateTime {
|
||||
return errors.New(fmt.Sprintf("cannot unmarshal %v into UnixTime", bt))
|
||||
}
|
||||
var tt time.Time
|
||||
err := bson.RawValue{Type: bt, Value: data}.Unmarshal(&tt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*t = UnixTime(tt)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t UnixTime) MarshalBSONValue() (bsontype.Type, []byte, error) {
|
||||
return bson.MarshalValue(time.Time(t))
|
||||
}
|
||||
|
||||
func (t UnixTime) DecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if val.Kind() == reflect.Ptr && val.IsNil() {
|
||||
if !val.CanSet() {
|
||||
return errors.New("ValueUnmarshalerDecodeValue")
|
||||
}
|
||||
val.Set(reflect.New(val.Type().Elem()))
|
||||
}
|
||||
|
||||
tp, src, err := bsonrw.Copier{}.CopyValueToBytes(vr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if val.Kind() == reflect.Ptr && len(src) == 0 {
|
||||
val.Set(reflect.Zero(val.Type()))
|
||||
return nil
|
||||
}
|
||||
|
||||
err = t.UnmarshalBSONValue(tp, src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if val.Kind() == reflect.Ptr {
|
||||
val.Set(reflect.ValueOf(&t))
|
||||
} else {
|
||||
val.Set(reflect.ValueOf(t))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t UnixTime) Serialize() string {
|
||||
return strconv.FormatInt(t.Time().Unix(), 10)
|
||||
}
|
||||
|
@@ -2,6 +2,13 @@ package rfctime
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/bsoncodec"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
@@ -59,6 +66,63 @@ func (t *UnixMilliTime) UnmarshalText(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *UnixMilliTime) UnmarshalBSONValue(bt bsontype.Type, data []byte) error {
|
||||
if bt == bson.TypeNull {
|
||||
// we can't set nil in UnmarshalBSONValue (so we use default(struct))
|
||||
// Use mongoext.CreateGoExtBsonRegistry if you need to unmarsh pointer values
|
||||
// https://stackoverflow.com/questions/75167597
|
||||
// https://jira.mongodb.org/browse/GODRIVER-2252
|
||||
*t = UnixMilliTime{}
|
||||
return nil
|
||||
}
|
||||
if bt != bson.TypeDateTime {
|
||||
return errors.New(fmt.Sprintf("cannot unmarshal %v into UnixMilliTime", bt))
|
||||
}
|
||||
var tt time.Time
|
||||
err := bson.RawValue{Type: bt, Value: data}.Unmarshal(&tt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*t = UnixMilliTime(tt)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t UnixMilliTime) MarshalBSONValue() (bsontype.Type, []byte, error) {
|
||||
return bson.MarshalValue(time.Time(t))
|
||||
}
|
||||
|
||||
func (t UnixMilliTime) DecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if val.Kind() == reflect.Ptr && val.IsNil() {
|
||||
if !val.CanSet() {
|
||||
return errors.New("ValueUnmarshalerDecodeValue")
|
||||
}
|
||||
val.Set(reflect.New(val.Type().Elem()))
|
||||
}
|
||||
|
||||
tp, src, err := bsonrw.Copier{}.CopyValueToBytes(vr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if val.Kind() == reflect.Ptr && len(src) == 0 {
|
||||
val.Set(reflect.Zero(val.Type()))
|
||||
return nil
|
||||
}
|
||||
|
||||
err = t.UnmarshalBSONValue(tp, src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if val.Kind() == reflect.Ptr {
|
||||
val.Set(reflect.ValueOf(&t))
|
||||
} else {
|
||||
val.Set(reflect.ValueOf(t))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t UnixMilliTime) Serialize() string {
|
||||
return strconv.FormatInt(t.Time().UnixMilli(), 10)
|
||||
}
|
||||
|
@@ -2,6 +2,13 @@ package rfctime
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/bsoncodec"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/bsontype"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
@@ -59,6 +66,63 @@ func (t *UnixNanoTime) UnmarshalText(data []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *UnixNanoTime) UnmarshalBSONValue(bt bsontype.Type, data []byte) error {
|
||||
if bt == bson.TypeNull {
|
||||
// we can't set nil in UnmarshalBSONValue (so we use default(struct))
|
||||
// Use mongoext.CreateGoExtBsonRegistry if you need to unmarsh pointer values
|
||||
// https://stackoverflow.com/questions/75167597
|
||||
// https://jira.mongodb.org/browse/GODRIVER-2252
|
||||
*t = UnixNanoTime{}
|
||||
return nil
|
||||
}
|
||||
if bt != bson.TypeDateTime {
|
||||
return errors.New(fmt.Sprintf("cannot unmarshal %v into UnixNanoTime", bt))
|
||||
}
|
||||
var tt time.Time
|
||||
err := bson.RawValue{Type: bt, Value: data}.Unmarshal(&tt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*t = UnixNanoTime(tt)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t UnixNanoTime) MarshalBSONValue() (bsontype.Type, []byte, error) {
|
||||
return bson.MarshalValue(time.Time(t))
|
||||
}
|
||||
|
||||
func (t UnixNanoTime) DecodeValue(dc bsoncodec.DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
|
||||
if val.Kind() == reflect.Ptr && val.IsNil() {
|
||||
if !val.CanSet() {
|
||||
return errors.New("ValueUnmarshalerDecodeValue")
|
||||
}
|
||||
val.Set(reflect.New(val.Type().Elem()))
|
||||
}
|
||||
|
||||
tp, src, err := bsonrw.Copier{}.CopyValueToBytes(vr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if val.Kind() == reflect.Ptr && len(src) == 0 {
|
||||
val.Set(reflect.Zero(val.Type()))
|
||||
return nil
|
||||
}
|
||||
|
||||
err = t.UnmarshalBSONValue(tp, src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if val.Kind() == reflect.Ptr {
|
||||
val.Set(reflect.ValueOf(&t))
|
||||
} else {
|
||||
val.Set(reflect.ValueOf(t))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t UnixNanoTime) Serialize() string {
|
||||
return strconv.FormatInt(t.Time().UnixNano(), 10)
|
||||
}
|
||||
|
101
wmo/queryFind.go
101
wmo/queryFind.go
@@ -4,18 +4,52 @@ import (
|
||||
"context"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
)
|
||||
|
||||
func (c *Coll[TData]) Find(ctx context.Context, filter bson.M) ([]TData, error) {
|
||||
func (c *Coll[TData]) Find(ctx context.Context, filter bson.M, opts ...*options.FindOptions) ([]TData, error) {
|
||||
|
||||
pipeline := mongo.Pipeline{}
|
||||
pipeline = append(pipeline, bson.D{{Key: "$match", Value: filter}})
|
||||
|
||||
for _, opt := range opts {
|
||||
if opt != nil && opt.Sort != nil {
|
||||
pipeline = append(pipeline, bson.D{{Key: "$sort", Value: opt.Sort}})
|
||||
}
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
if opt != nil && opt.Skip != nil {
|
||||
pipeline = append(pipeline, bson.D{{Key: "$skip", Value: *opt.Skip}})
|
||||
}
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
if opt != nil && opt.Limit != nil {
|
||||
pipeline = append(pipeline, bson.D{{Key: "$limit", Value: *opt.Limit}})
|
||||
}
|
||||
}
|
||||
|
||||
pipeline = langext.ArrConcat(pipeline, c.extraModPipeline)
|
||||
|
||||
cursor, err := c.coll.Aggregate(ctx, pipeline)
|
||||
for _, opt := range opts {
|
||||
if opt != nil && opt.Projection != nil {
|
||||
pipeline = append(pipeline, bson.D{{Key: "$project", Value: opt.Projection}})
|
||||
}
|
||||
}
|
||||
|
||||
convOpts := make([]*options.AggregateOptions, 0, len(opts))
|
||||
for _, v := range opts {
|
||||
vConv, err := convertFindOpt(v)
|
||||
if err != nil {
|
||||
return nil, exerr.Wrap(err, "mongo-aggregation failed").Any("pipeline", pipeline).Str("collection", c.Name()).Build()
|
||||
}
|
||||
convOpts = append(convOpts, vConv)
|
||||
}
|
||||
|
||||
cursor, err := c.coll.Aggregate(ctx, pipeline, convOpts...)
|
||||
if err != nil {
|
||||
return nil, exerr.Wrap(err, "mongo-aggregation failed").Any("pipeline", pipeline).Str("collection", c.Name()).Build()
|
||||
}
|
||||
@@ -27,3 +61,66 @@ func (c *Coll[TData]) Find(ctx context.Context, filter bson.M) ([]TData, error)
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// converts FindOptions to AggregateOptions
|
||||
func convertFindOpt(v *options.FindOptions) (*options.AggregateOptions, error) {
|
||||
if v == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
r := options.Aggregate()
|
||||
|
||||
if v.AllowDiskUse != nil {
|
||||
r.SetAllowDiskUse(*v.AllowDiskUse)
|
||||
}
|
||||
if v.AllowPartialResults != nil {
|
||||
return nil, exerr.New(exerr.TypeMongoInvalidOpt, "Invalid option 'AllowPartialResults' (cannot convert to AggregateOptions)").Build()
|
||||
}
|
||||
if v.BatchSize != nil {
|
||||
r.SetBatchSize(*v.BatchSize)
|
||||
}
|
||||
if v.Collation != nil {
|
||||
r.SetCollation(v.Collation)
|
||||
}
|
||||
if v.Comment != nil {
|
||||
r.SetComment(*v.Comment)
|
||||
}
|
||||
if v.CursorType != nil {
|
||||
return nil, exerr.New(exerr.TypeMongoInvalidOpt, "Invalid option 'CursorType' (cannot convert to AggregateOptions)").Build()
|
||||
}
|
||||
if v.Hint != nil {
|
||||
r.SetHint(v.Hint)
|
||||
}
|
||||
if v.Max != nil {
|
||||
return nil, exerr.New(exerr.TypeMongoInvalidOpt, "Invalid option 'Max' (cannot convert to AggregateOptions)").Build()
|
||||
}
|
||||
if v.MaxAwaitTime != nil {
|
||||
r.SetMaxAwaitTime(*v.MaxAwaitTime)
|
||||
}
|
||||
if v.MaxTime != nil {
|
||||
r.SetMaxTime(*v.MaxTime)
|
||||
}
|
||||
if v.Min != nil {
|
||||
return nil, exerr.New(exerr.TypeMongoInvalidOpt, "Invalid option 'Min' (cannot convert to AggregateOptions)").Build()
|
||||
}
|
||||
if v.NoCursorTimeout != nil {
|
||||
return nil, exerr.New(exerr.TypeMongoInvalidOpt, "Invalid option 'NoCursorTimeout' (cannot convert to AggregateOptions)").Build()
|
||||
}
|
||||
if v.OplogReplay != nil {
|
||||
return nil, exerr.New(exerr.TypeMongoInvalidOpt, "Invalid option 'OplogReplay' (cannot convert to AggregateOptions)").Build()
|
||||
}
|
||||
if v.ReturnKey != nil {
|
||||
return nil, exerr.New(exerr.TypeMongoInvalidOpt, "Invalid option 'ReturnKey' (cannot convert to AggregateOptions)").Build()
|
||||
}
|
||||
if v.ShowRecordID != nil {
|
||||
return nil, exerr.New(exerr.TypeMongoInvalidOpt, "Invalid option 'ShowRecordID' (cannot convert to AggregateOptions)").Build()
|
||||
}
|
||||
if v.Snapshot != nil {
|
||||
return nil, exerr.New(exerr.TypeMongoInvalidOpt, "Invalid option 'Snapshot' (cannot convert to AggregateOptions)").Build()
|
||||
}
|
||||
if v.Let != nil {
|
||||
r.SetLet(v.Let)
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
@@ -21,6 +21,20 @@ func (c *Coll[TData]) InsertOne(ctx context.Context, valueIn TData) (TData, erro
|
||||
return *r, nil
|
||||
}
|
||||
|
||||
// InsertOneUnchecked behaves the same as InsertOne, but allows arbitrary data to be inserted (valueIn is any instead of TData)
|
||||
func (c *Coll[TData]) InsertOneUnchecked(ctx context.Context, valueIn any) (TData, error) {
|
||||
insRes, err := c.coll.InsertOne(ctx, valueIn)
|
||||
if err != nil {
|
||||
return *new(TData), exerr.Wrap(err, "mongo-query[insert-one] failed").Str("collection", c.Name()).Build()
|
||||
}
|
||||
|
||||
r, err := c.findOneInternal(ctx, bson.M{"_id": insRes.InsertedID}, false)
|
||||
if err != nil {
|
||||
return *new(TData), exerr.Wrap(err, "mongo-query[insert-one] failed").Str("collection", c.Name()).Build()
|
||||
}
|
||||
return *r, nil
|
||||
}
|
||||
|
||||
func (c *Coll[TData]) InsertMany(ctx context.Context, valueIn []TData) (*mongo.InsertManyResult, error) {
|
||||
insRes, err := c.coll.InsertMany(ctx, langext.ArrayToInterface(valueIn))
|
||||
if err != nil {
|
||||
@@ -29,3 +43,13 @@ func (c *Coll[TData]) InsertMany(ctx context.Context, valueIn []TData) (*mongo.I
|
||||
|
||||
return insRes, nil
|
||||
}
|
||||
|
||||
// InsertManyUnchecked behaves the same as InsertOne, but allows arbitrary data to be inserted (valueIn is []any instead of []TData)
|
||||
func (c *Coll[TData]) InsertManyUnchecked(ctx context.Context, valueIn []any) (*mongo.InsertManyResult, error) {
|
||||
insRes, err := c.coll.InsertMany(ctx, langext.ArrayToInterface(valueIn))
|
||||
if err != nil {
|
||||
return nil, exerr.Wrap(err, "mongo-query[insert-many] failed").Int("len(valueIn)", len(valueIn)).Str("collection", c.Name()).Build()
|
||||
}
|
||||
|
||||
return insRes, nil
|
||||
}
|
||||
|
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
ct "gogs.mikescher.com/BlackForestBytes/goext/cursortoken"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/exerr"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
pag "gogs.mikescher.com/BlackForestBytes/goext/pagination"
|
||||
@@ -21,18 +20,15 @@ func (c *Coll[TData]) Paginate(ctx context.Context, filter pag.Filter, page int,
|
||||
|
||||
pipelineSort := mongo.Pipeline{}
|
||||
pipelineFilter := mongo.Pipeline{}
|
||||
pf1 := "_id"
|
||||
pd1 := ct.SortASC
|
||||
sort := bson.D{}
|
||||
|
||||
if filter != nil {
|
||||
pipelineFilter = filter.FilterQuery()
|
||||
pf1, pd1 = filter.Pagination()
|
||||
sort = filter.Sort()
|
||||
}
|
||||
|
||||
if pd1 == ct.SortASC {
|
||||
pipelineSort = append(pipelineSort, bson.D{{Key: "$sort", Value: bson.D{{Key: pf1, Value: +1}}}})
|
||||
} else if pd1 == ct.SortDESC {
|
||||
pipelineSort = append(pipelineSort, bson.D{{Key: "$sort", Value: bson.D{{Key: pf1, Value: -1}}}})
|
||||
if len(sort) != 0 {
|
||||
pipelineSort = append(pipelineSort, bson.D{{Key: "$sort", Value: sort}})
|
||||
}
|
||||
|
||||
pipelinePaginate := mongo.Pipeline{}
|
||||
@@ -44,7 +40,7 @@ func (c *Coll[TData]) Paginate(ctx context.Context, filter pag.Filter, page int,
|
||||
}
|
||||
|
||||
pipelineCount := mongo.Pipeline{}
|
||||
pipelinePaginate = append(pipelinePaginate, bson.D{{Key: "$count", Value: "count"}})
|
||||
pipelineCount = append(pipelineCount, bson.D{{Key: "$count", Value: "count"}})
|
||||
|
||||
pipelineList := langext.ArrConcat(mongo.Pipeline{}, pipelineFilter, pipelinePaginate, c.extraModPipeline)
|
||||
pipelineTotalCount := langext.ArrConcat(mongo.Pipeline{}, pipelineFilter, pipelineCount)
|
||||
|
Reference in New Issue
Block a user