-
Notifications
You must be signed in to change notification settings - Fork 0
/
skc_deck_db.go
115 lines (96 loc) · 4.27 KB
/
skc_deck_db.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package db
import (
"context"
"fmt"
"log"
"net/http"
"time"
"github.com/ygo-skc/skc-deck-api/model"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
var (
skcDeckDB *mongo.Database
deckListCollection *mongo.Collection
)
// interface
type SKCDeckAPIDAO interface {
GetSKCDeckAPIDBVersion() (string, error)
InsertDeckList(deckList model.DeckList) *model.APIError
GetDeckList(deckID string) (*model.DeckList, *model.APIError)
GetDecksThatFeatureCards([]string) (*[]model.DeckList, *model.APIError)
}
// impl
type SKCDeckAPIDAOImplementation struct{}
// Retrieves the version number of the SKC Deck API DB or throws an error if an exception occurs.
func (dbInterface SKCDeckAPIDAOImplementation) GetSKCDeckAPIDBVersion() (string, error) {
var commandResult bson.M
command := bson.D{{Key: "serverStatus", Value: 1}}
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
if err := skcDeckDB.RunCommand(ctx, command).Decode(&commandResult); err != nil {
log.Println("Error getting SKC Deck API DB version", err)
return "", err
} else {
return fmt.Sprintf("%v", commandResult["version"]), nil
}
}
func (dbInterface SKCDeckAPIDAOImplementation) InsertDeckList(deckList model.DeckList) *model.APIError {
deckList.CreatedAt = time.Now()
deckList.UpdatedAt = deckList.CreatedAt
log.Printf("Inserting deck with name %s with Main Deck size %d and Extra Deck size %d. List contents (in base64 and possibly reformatted) %s",
deckList.Name, deckList.NumMainDeckCards, deckList.NumExtraDeckCards, deckList.ContentB64)
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
if res, err := deckListCollection.InsertOne(ctx, deckList); err != nil {
log.Println("Error saving new deck list into DB", err)
return &model.APIError{Message: "There was a problem saving deck list", StatusCode: http.StatusInternalServerError}
} else {
log.Println("Successfully inserted new deck list into DB, ID:", res.InsertedID)
return nil
}
}
func (dbInterface SKCDeckAPIDAOImplementation) GetDeckList(deckID string) (*model.DeckList, *model.APIError) {
if objectId, err := primitive.ObjectIDFromHex(deckID); err != nil {
log.Printf("Invalid deck ID used by user %s", deckID)
return nil, &model.APIError{Message: "Deck ID not valid", StatusCode: http.StatusBadRequest}
} else {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
var dl model.DeckList
if err := deckListCollection.FindOne(ctx, bson.M{"_id": objectId}).Decode(&dl); err != nil {
log.Printf("Error retrieving deck list w/ ID %s. Err: %v", deckID, err)
if err.Error() == "mongo: no documents in result" {
return nil, &model.APIError{Message: "Deck w/ ID not found", StatusCode: http.StatusNotFound}
} else {
return nil, &model.APIError{Message: "Error retrieving deck", StatusCode: http.StatusInternalServerError}
}
} else {
return &dl, nil
}
}
}
func (dbInterface SKCDeckAPIDAOImplementation) GetDecksThatFeatureCards(cardIDs []string) (*[]model.DeckList, *model.APIError) {
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
// select only these fields from collection
opts := options.Find().SetProjection(
bson.D{
{Key: "name", Value: 1}, {Key: "videoUrl", Value: 1}, {Key: "uniqueCards", Value: 1}, {Key: "deckMascots", Value: 1}, {Key: "numMainDeckCards", Value: 1},
{Key: "numExtraDeckCards", Value: 1}, {Key: "tags", Value: 1}, {Key: "createdAt", Value: 1}, {Key: "updatedAt", Value: 1},
},
)
if cursor, err := deckListCollection.Find(ctx, bson.M{"uniqueCards": bson.M{"$in": cardIDs}}, opts); err != nil {
log.Printf("Error retrieving all deck lists that feature cards w/ ID %v. Err: %v", cardIDs, err)
return nil, &model.APIError{Message: "Error retrieving deck suggestions", StatusCode: http.StatusInternalServerError}
} else {
dl := []model.DeckList{}
if err := cursor.All(ctx, &dl); err != nil {
log.Printf("Error retrieving all deck lists that feature cards w/ ID %v. Err: %v", cardIDs, err)
return nil, &model.APIError{Message: "Error retrieving deck suggestions", StatusCode: http.StatusInternalServerError}
}
return &dl, nil
}
}