/
mongo.go
100 lines (78 loc) · 2.01 KB
/
mongo.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package repository
import (
"context"
"errors"
"time"
"github.com/Trojan295/discord-bingo-bot/pkg/bingo/game"
"github.com/mitchellh/mapstructure"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type MongoGameRepository struct {
client *mongo.Client
}
func NewMongoGameRepository(URI string) (*MongoGameRepository, error) {
client, err := mongo.NewClient(options.Client().ApplyURI(URI))
if err != nil {
return nil, err
}
repo := &MongoGameRepository{
client: client,
}
if err = repo.connect(); err != nil {
return nil, err
}
return repo, nil
}
func (r *MongoGameRepository) connect() error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
return r.client.Connect(ctx)
}
func serializeGame(g *game.Game) bson.M {
var doc bson.M
err := mapstructure.Decode(g, &doc)
if err != nil {
panic(err)
}
return doc
}
func (r *MongoGameRepository) Persist(g *game.Game) error {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
collection := r.client.Database("bingo").Collection("games")
doc := serializeGame(g)
result := collection.FindOne(ctx, bson.D{{Key: "ID", Value: g.ID}})
err := result.Err()
if err != nil {
if errors.Is(err, mongo.ErrNoDocuments) {
_, err2 := collection.InsertOne(ctx, doc)
return err2
}
return err
}
_, err = collection.UpdateOne(ctx, bson.D{{Key: "ID", Value: g.ID}}, bson.M{
"$set": doc,
})
if err != nil {
return err
}
return nil
}
func (r *MongoGameRepository) Get(GameID string) (*game.Game, error) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
collection := r.client.Database("bingo").Collection("games")
result := collection.FindOne(ctx, bson.D{{Key: "ID", Value: GameID}})
err := result.Err()
if err != nil {
if errors.Is(err, mongo.ErrNoDocuments) {
return nil, nil
}
return nil, err
}
var g game.Game
result.Decode(&g)
return &g, nil
}