Something went wrong. Try again.
mongo db generics functions wrapper
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192package simon
import ( "context" "errors" "fmt"
"go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options")
type Map map[string]any
var ( ErrEmptyCollection = fmt.Errorf("collection has no documents"))
type Filters struct { id func(bson.ObjectID) Map}
var filters Filters = Filters{ id: idFilter,}
func idFilter(id bson.ObjectID) Map { return Map{"_id": id}}
func Update( ctx context.Context, collection *mongo.Collection, filter any, newValues any, opts ...options.Lister[options.FindOneAndUpdateOptions],) error { result := collection.FindOneAndUpdate(ctx, filter, Map{"$set": newValues}, opts...) err := result.Err() return err}
func UpdateAndReturn[T any]( ctx context.Context, collection *mongo.Collection, filter any, newValues any, opts ...options.Lister[options.FindOneAndUpdateOptions],) (*T, error) { var tmp T result := collection.FindOneAndUpdate(ctx, filter, Map{"$set": newValues}, opts...) err := result.Err() if err != nil { return nil, err } err = result.Decode(&tmp) if err != nil { return nil, err } return &tmp, err}
func UpdateMany( ctx context.Context, collection *mongo.Collection, filter any, newValues any,) error { _, err := collection.UpdateMany( ctx, filter, Map{"$set": newValues}, ) return err}
func InsertOneAndRetrieve[T any]( ctx context.Context, collection *mongo.Collection, v any,) (*T, error) { id, err := InsertOne(ctx, collection, v)
if err != nil { return nil, err }
return FindOne[T](ctx, collection, Map{"_id": id})}
func InsertOne(ctx context.Context, collection *mongo.Collection, v any) (bson.ObjectID, error) { var noID bson.ObjectID result, err := collection.InsertOne(ctx, v) if err != nil { return noID, err }
id, ok := result.InsertedID.(bson.ObjectID)
if !ok { return noID, fmt.Errorf("type assertion for id,ok := result.InsertedID.(bson.ObjectID) failed: InsertedID: %v", result.InsertedID) } return id, nil}
func InsertOneAndReturn[T any](ctx context.Context, collection *mongo.Collection, v any) (*T, error) { result, err := collection.InsertOne(ctx, v) if err != nil { return nil, err }
id, ok := result.InsertedID.(bson.ObjectID)
if !ok { return nil, fmt.Errorf("type assertion for id,ok := result.InsertedID.(bson.ObjectID) failed: InsertedID: %v", result.InsertedID) } return FindOne[T](ctx, collection, filters.id(id))}
func FindOne[T any](ctx context.Context, collection *mongo.Collection, filter any, opts ...options.Lister[options.FindOneOptions]) (*T, error) { var tmp T result := collection.FindOne(ctx, filter) err := result.Err() if err != nil { return nil, err }
result.Decode(&tmp)
return &tmp, nil}
func Append[T any](ctx context.Context, collection *mongo.Collection, filter any, value any) (*T, error) { var tmp T result := collection.FindOne(ctx, filter) err := result.Err() if err != nil { return nil, err }
result.Decode(&tmp)
return &tmp, nil}
func List[T any](ctx context.Context, collection *mongo.Collection, filter any) ([]*T, error) { var list []*T cursor, err := collection.Find(ctx, filter) if err != nil { return nil, err } for cursor.Next(ctx) { var tmp T err := cursor.Decode(&tmp) if err != nil { return nil, err } list = append(list, &tmp) }
err = cursor.Err() if err != nil { return nil, err }
return list, nil}
func Upsert[T any](ctx context.Context, collection *mongo.Collection, params T, filter any) (*T, error) { item, err := FindOne[T](ctx, collection, filters)
if err != nil { switch { case errors.Is(err, ErrEmptyCollection): return InsertOneAndRetrieve[T](ctx, collection, params) default: return nil, err } }
item, err = UpdateAndReturn[T]( ctx, collection, filter, //nolint params, options.FindOneAndUpdate().SetReturnDocument(options.After), )
return item, err}