178 lines
4.4 KiB
Go
178 lines
4.4 KiB
Go
package mongo
|
|
|
|
import (
|
|
"context"
|
|
|
|
"fiskerinc.com/modules/db/queries"
|
|
e "fiskerinc.com/modules/mongo/error"
|
|
|
|
"github.com/pkg/errors"
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
"go.mongodb.org/mongo-driver/mongo/options"
|
|
)
|
|
|
|
func NewCollection(collection *mongo.Collection) CollectionInterface {
|
|
return &Collection{
|
|
collection: collection,
|
|
}
|
|
}
|
|
|
|
type CollectionInterface interface {
|
|
InsertOne(document interface{}) (interface{}, error)
|
|
FindOne(filter interface{}, object interface{}, projection interface{}) error
|
|
ReplaceOne(filter interface{}, update interface{}) error
|
|
DeleteOne(document interface{}) error
|
|
|
|
UpdateOne(filter interface{}, update interface{}) (*mongo.UpdateResult, error)
|
|
UpdateMany(filter interface{}, update interface{}) error
|
|
|
|
Find(filter interface{}, objects interface{}, pq *queries.PageQueryOptions) error
|
|
Count(filter interface{}) (int64, error)
|
|
|
|
Aggregate(pipeline mongo.Pipeline, object interface{}) error
|
|
}
|
|
|
|
type Collection struct {
|
|
collection *mongo.Collection
|
|
}
|
|
|
|
// InsertOne is an abstraction over Mongo's library
|
|
func (c *Collection) InsertOne(document interface{}) (interface{}, error) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
defer cancel()
|
|
|
|
r, err := c.collection.InsertOne(ctx, document)
|
|
if err != nil {
|
|
return r, errors.WithStack(err)
|
|
}
|
|
|
|
return r.InsertedID, nil
|
|
}
|
|
|
|
// FindOne is an abstraction over Mongo's library
|
|
func (c *Collection) FindOne(filter interface{}, object interface{}, projection interface{}) error {
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
defer cancel()
|
|
|
|
opts := options.FindOne().SetProjection(projection)
|
|
|
|
err := c.collection.FindOne(ctx, filter, opts).Decode(object)
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// ReplaceOne is an abstraction over Mongo's library
|
|
func (c *Collection) ReplaceOne(filter interface{}, update interface{}) error {
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
defer cancel()
|
|
|
|
r, err := c.collection.ReplaceOne(ctx, filter, update)
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
} else if r.MatchedCount == 0 {
|
|
return e.ErrInvalidNumberOfDocs
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// DeleteOne is an abstraction over Mongo's library
|
|
func (c *Collection) DeleteOne(document interface{}) error {
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
defer cancel()
|
|
|
|
r, err := c.collection.DeleteOne(ctx, document)
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
} else if r.DeletedCount != 1 {
|
|
return e.ErrUnableToDelete
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *Collection) UpdateOne(filter interface{}, update interface{}) (*mongo.UpdateResult, error) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
defer cancel()
|
|
|
|
r, err := c.collection.UpdateOne(ctx, filter, update)
|
|
if err != nil {
|
|
return nil, errors.WithStack(err)
|
|
} else if r.MatchedCount == 0 {
|
|
return nil, e.ErrInvalidNumberOfDocs
|
|
}
|
|
|
|
return r, nil
|
|
}
|
|
|
|
func (c *Collection) UpdateMany(filter interface{}, update interface{}) error {
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
defer cancel()
|
|
|
|
r, err := c.collection.UpdateMany(ctx, filter, update)
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
} else if r.MatchedCount == 0 {
|
|
return e.ErrInvalidNumberOfDocs
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *Collection) Find(filter interface{}, objects interface{}, pq *queries.PageQueryOptions) error {
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
defer cancel()
|
|
|
|
f, err := c.collection.Find(
|
|
ctx,
|
|
filter,
|
|
options.Find().SetLimit(int64(pq.Limit)),
|
|
options.Find().SetSkip(int64(pq.Offset)),
|
|
options.Find().SetSort(getOrder(pq.Order)),
|
|
options.Find().SetProjection(getFieldsToIgnore(pq.Ignore)),
|
|
)
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
err = f.All(ctx, objects)
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *Collection) Count(filter interface{}) (int64, error) {
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
defer cancel()
|
|
|
|
t, err := c.collection.CountDocuments(ctx, filter)
|
|
if err != nil {
|
|
return 0, errors.WithStack(err)
|
|
}
|
|
|
|
return t, nil
|
|
}
|
|
|
|
// Aggregate when all else fails
|
|
func (c *Collection) Aggregate(pipeline mongo.Pipeline, object interface{}) error {
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
defer cancel()
|
|
|
|
a, err := c.collection.Aggregate(ctx, pipeline)
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
err = a.All(ctx, object)
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
return nil
|
|
}
|