Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
d44e971325
|
|||
fe4cdc48af
|
|||
631006a4e1
|
@@ -35,6 +35,23 @@ func (s *SyncMap[TKey, TData]) SetIfNotContains(key TKey, data TData) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SyncMap[TKey, TData]) SetIfNotContainsFunc(key TKey, data func() TData) bool {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
if s.data == nil {
|
||||||
|
s.data = make(map[TKey]TData)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, existsInPreState := s.data[key]; existsInPreState {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
s.data[key] = data()
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SyncMap[TKey, TData]) Get(key TKey) (TData, bool) {
|
func (s *SyncMap[TKey, TData]) Get(key TKey) (TData, bool) {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
@@ -66,6 +83,23 @@ func (s *SyncMap[TKey, TData]) GetAndSetIfNotContains(key TKey, data TData) TDat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SyncMap[TKey, TData]) GetAndSetIfNotContainsFunc(key TKey, data func() TData) TData {
|
||||||
|
s.lock.Lock()
|
||||||
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
|
if s.data == nil {
|
||||||
|
s.data = make(map[TKey]TData)
|
||||||
|
}
|
||||||
|
|
||||||
|
if v, ok := s.data[key]; ok {
|
||||||
|
return v
|
||||||
|
} else {
|
||||||
|
dataObj := data()
|
||||||
|
s.data[key] = dataObj
|
||||||
|
return dataObj
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (s *SyncMap[TKey, TData]) Delete(key TKey) bool {
|
func (s *SyncMap[TKey, TData]) Delete(key TKey) bool {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
package goext
|
package goext
|
||||||
|
|
||||||
const GoextVersion = "0.0.446"
|
const GoextVersion = "0.0.449"
|
||||||
|
|
||||||
const GoextVersionTimestamp = "2024-05-10T21:31:36+0200"
|
const GoextVersionTimestamp = "2024-05-12T16:51:52+0200"
|
||||||
|
@@ -52,6 +52,7 @@ type Coll[TData any] struct {
|
|||||||
customDecoder *func(ctx context.Context, dec Decodable) (TData, error) // custom decoding function (useful if TData is an interface)
|
customDecoder *func(ctx context.Context, dec Decodable) (TData, error) // custom decoding function (useful if TData is an interface)
|
||||||
isInterfaceDataType bool // true if TData is an interface (not a struct)
|
isInterfaceDataType bool // true if TData is an interface (not a struct)
|
||||||
unmarshalHooks []func(d TData) TData // called for every object after unmarshalling
|
unmarshalHooks []func(d TData) TData // called for every object after unmarshalling
|
||||||
|
marshalHooks []func(d TData) TData // called for every object before marshalling
|
||||||
extraModPipeline []func(ctx context.Context) mongo.Pipeline // appended to pipelines after filter/limit/skip/sort, used for $lookup, $set, $unset, $project, etc
|
extraModPipeline []func(ctx context.Context) mongo.Pipeline // appended to pipelines after filter/limit/skip/sort, used for $lookup, $set, $unset, $project, etc
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,18 +84,32 @@ func (c *Coll[TData]) WithDecodeFunc(cdf func(ctx context.Context, dec Decodable
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithUnmarshalHook
|
||||||
|
// function that is called for every object after reading from DB
|
||||||
func (c *Coll[TData]) WithUnmarshalHook(fn func(d TData) TData) *Coll[TData] {
|
func (c *Coll[TData]) WithUnmarshalHook(fn func(d TData) TData) *Coll[TData] {
|
||||||
c.unmarshalHooks = append(c.unmarshalHooks, fn)
|
c.unmarshalHooks = append(c.unmarshalHooks, fn)
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithMarshalHook
|
||||||
|
// function that is called for every object before writing to DB
|
||||||
|
func (c *Coll[TData]) WithMarshalHook(fn func(d TData) TData) *Coll[TData] {
|
||||||
|
c.marshalHooks = append(c.marshalHooks, fn)
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithModifyingPipeline
|
||||||
|
// pipeline that is appended to all read operations (after filtering)
|
||||||
func (c *Coll[TData]) WithModifyingPipeline(p mongo.Pipeline) *Coll[TData] {
|
func (c *Coll[TData]) WithModifyingPipeline(p mongo.Pipeline) *Coll[TData] {
|
||||||
c.extraModPipeline = append(c.extraModPipeline, func(ctx context.Context) mongo.Pipeline { return p })
|
c.extraModPipeline = append(c.extraModPipeline, func(ctx context.Context) mongo.Pipeline { return p })
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithModifyingPipelineFunc
|
||||||
|
// pipeline that is appended to all read operations (after filtering)
|
||||||
func (c *Coll[TData]) WithModifyingPipelineFunc(fn func(ctx context.Context) mongo.Pipeline) *Coll[TData] {
|
func (c *Coll[TData]) WithModifyingPipelineFunc(fn func(ctx context.Context) mongo.Pipeline) *Coll[TData] {
|
||||||
c.extraModPipeline = append(c.extraModPipeline, fn)
|
c.extraModPipeline = append(c.extraModPipeline, fn)
|
||||||
|
|
||||||
|
@@ -9,6 +9,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (c *Coll[TData]) InsertOne(ctx context.Context, valueIn TData) (TData, error) {
|
func (c *Coll[TData]) InsertOne(ctx context.Context, valueIn TData) (TData, error) {
|
||||||
|
for _, hook := range c.marshalHooks {
|
||||||
|
valueIn = hook(valueIn)
|
||||||
|
}
|
||||||
|
|
||||||
insRes, err := c.coll.InsertOne(ctx, valueIn)
|
insRes, err := c.coll.InsertOne(ctx, valueIn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return *new(TData), exerr.Wrap(err, "mongo-query[insert-one] failed").Str("collection", c.Name()).Build()
|
return *new(TData), exerr.Wrap(err, "mongo-query[insert-one] failed").Str("collection", c.Name()).Build()
|
||||||
@@ -36,6 +40,12 @@ func (c *Coll[TData]) InsertOneUnchecked(ctx context.Context, valueIn any) (TDat
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Coll[TData]) InsertMany(ctx context.Context, valueIn []TData) (*mongo.InsertManyResult, error) {
|
func (c *Coll[TData]) InsertMany(ctx context.Context, valueIn []TData) (*mongo.InsertManyResult, error) {
|
||||||
|
for _, hook := range c.marshalHooks {
|
||||||
|
for i := 0; i < len(valueIn); i++ {
|
||||||
|
valueIn[i] = hook(valueIn[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
insRes, err := c.coll.InsertMany(ctx, langext.ArrayToInterface(valueIn))
|
insRes, err := c.coll.InsertMany(ctx, langext.ArrayToInterface(valueIn))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, exerr.Wrap(err, "mongo-query[insert-many] failed").Int("len(valueIn)", len(valueIn)).Str("collection", c.Name()).Build()
|
return nil, exerr.Wrap(err, "mongo-query[insert-many] failed").Int("len(valueIn)", len(valueIn)).Str("collection", c.Name()).Build()
|
||||||
|
@@ -61,6 +61,10 @@ func (c *Coll[TData]) UpdateMany(ctx context.Context, filterQuery bson.M, update
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Coll[TData]) ReplaceOne(ctx context.Context, filterQuery bson.M, value TData) error {
|
func (c *Coll[TData]) ReplaceOne(ctx context.Context, filterQuery bson.M, value TData) error {
|
||||||
|
for _, hook := range c.marshalHooks {
|
||||||
|
value = hook(value)
|
||||||
|
}
|
||||||
|
|
||||||
_, err := c.coll.UpdateOne(ctx, filterQuery, bson.M{"$set": value})
|
_, err := c.coll.UpdateOne(ctx, filterQuery, bson.M{"$set": value})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return exerr.Wrap(err, "mongo-query[replace-one] failed").
|
return exerr.Wrap(err, "mongo-query[replace-one] failed").
|
||||||
@@ -73,6 +77,10 @@ func (c *Coll[TData]) ReplaceOne(ctx context.Context, filterQuery bson.M, value
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Coll[TData]) FindOneAndReplace(ctx context.Context, filterQuery bson.M, value TData) (TData, error) {
|
func (c *Coll[TData]) FindOneAndReplace(ctx context.Context, filterQuery bson.M, value TData) (TData, error) {
|
||||||
|
for _, hook := range c.marshalHooks {
|
||||||
|
value = hook(value)
|
||||||
|
}
|
||||||
|
|
||||||
mongoRes := c.coll.FindOneAndReplace(ctx, filterQuery, value, options.FindOneAndReplace().SetReturnDocument(options.After))
|
mongoRes := c.coll.FindOneAndReplace(ctx, filterQuery, value, options.FindOneAndReplace().SetReturnDocument(options.After))
|
||||||
if err := mongoRes.Err(); err != nil {
|
if err := mongoRes.Err(); err != nil {
|
||||||
return *new(TData), exerr.Wrap(err, "mongo-query[find-one-and-update] failed").
|
return *new(TData), exerr.Wrap(err, "mongo-query[find-one-and-update] failed").
|
||||||
|
Reference in New Issue
Block a user