Files
DeviceBookingAPI/databases/database.go
T
2022-09-26 16:40:40 -07:00

151 lines
3.9 KiB
Go

package databases
import (
"context"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"github.com/SowinskiBraeden/SulliCartShare/config"
)
// TODO: fix all update handlers because they don't work
// DatabaseHelper contains the collection and client to be used to access the methods
// defined below
type DatabaseHelper interface {
Collection(name string) CollectionHelper
Client() ClientHelper
}
// CollectionHelper contains all the methods defined for collection in this project
type CollectionHelper interface {
FindOne(context.Context, interface{}) SingleResultHelper
Find(context.Context, interface{}) CursorHelper
InsertOne(context.Context, interface{}) (mongoInsertOneResult, error)
UpdateOne(context.Context, interface{}, interface{}) (mongoUpdateResult, error)
}
// SingleResultHelper contains a single method to decode the result
type SingleResultHelper interface {
Decode(v interface{}) error
}
// CursorHelper contains a method to decode the cursor
type CursorHelper interface {
Decode(v interface{}) error
}
// ClientHelper defined to help at client creation inside main.go
type ClientHelper interface {
Database(string) DatabaseHelper
Connect() error
StartSession() (mongo.Session, error)
}
type mongoClient struct {
cl *mongo.Client
}
type mongoDatabase struct {
db *mongo.Database
}
type mongoCollection struct {
coll *mongo.Collection
}
type mongoSingleResult struct {
sr *mongo.SingleResult
}
type mongoCursor struct {
cr *mongo.Cursor
}
type mongoInsertOneResult struct {
ir *mongo.InsertOneResult
}
type mongoUpdateResult struct {
ur *mongo.UpdateResult
}
type mongoSession struct {
mongo.Session
}
// NewClient uses the values from the config and returns a mongo client
func NewClient(conf *config.Config) (ClientHelper, error) {
c, err := mongo.NewClient(options.Client().ApplyURI(conf.URL))
return &mongoClient{cl: c}, err
}
// NewDatabase uses the client from NewClient and sets the database name
func NewDatabase(conf *config.Config, client ClientHelper) DatabaseHelper {
return client.Database(conf.DatabaseName)
}
func (mc *mongoClient) Database(dbName string) DatabaseHelper {
db := mc.cl.Database(dbName)
return &mongoDatabase{db: db}
}
func (mc *mongoClient) StartSession() (mongo.Session, error) {
session, err := mc.cl.StartSession()
return &mongoSession{session}, err
}
func (mc *mongoClient) Connect() error {
return mc.cl.Connect(context.TODO()) // use context.TODO() instead of nil cause good practice ¯\_(ツ)_/¯
}
func (md *mongoDatabase) Collection(colName string) CollectionHelper {
collection := md.db.Collection(colName)
return &mongoCollection{coll: collection}
}
func (md *mongoDatabase) Client() ClientHelper {
client := md.db.Client()
return &mongoClient{cl: client}
}
func (mc *mongoCollection) FindOne(ctx context.Context, filter interface{}) SingleResultHelper {
singleResult := mc.coll.FindOne(ctx, filter)
return &mongoSingleResult{sr: singleResult}
}
func (mc *mongoCollection) Find(ctx context.Context, filter interface{}) CursorHelper {
cursor, _ := mc.coll.Find(ctx, filter)
return &mongoCursor{cr: cursor}
}
func (mc *mongoCollection) InsertOne(ctx context.Context, document interface{}) (mongoInsertOneResult, error) {
insertOneResult, err := mc.coll.InsertOne(ctx, document)
if err != nil {
return mongoInsertOneResult{}, err
}
return mongoInsertOneResult{ir: insertOneResult}, nil
}
func (mc *mongoCollection) UpdateOne(ctx context.Context, filter, update interface{}) (mongoUpdateResult, error) {
updateOneResult, err := mc.coll.UpdateOne(ctx, filter, update)
if err != nil {
return mongoUpdateResult{}, err
}
return mongoUpdateResult{ur: updateOneResult}, nil
}
func (sr *mongoSingleResult) Decode(v interface{}) error {
return sr.sr.Decode(v)
}
func (cr *mongoCursor) Decode(v interface{}) error {
return cr.All(context.Background(), v)
}
func (cr *mongoCursor) All(ctx context.Context, results interface{}) error {
return cr.cr.All(ctx, results)
}