GraphQL API and utilities for the rpdata project
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

95 lines
1.8 KiB

package mongodb
import (
"fmt"
"github.com/globalsign/mgo/bson"
"time"
"git.aiterp.net/rpdata/api/internal/config"
"git.aiterp.net/rpdata/api/repositories"
"github.com/globalsign/mgo"
)
// Init initializes the mongodb database
func Init(cfg config.Database) (bundle *repositories.Bundle, closeFn func() error, err error) {
port := cfg.Port
if port <= 0 {
port = 27017
}
session, err := mgo.DialWithInfo(&mgo.DialInfo{
Addrs: []string{fmt.Sprintf("%s:%d", cfg.Host, port)},
Timeout: 30 * time.Second,
Database: cfg.Db,
Username: cfg.Username,
Password: cfg.Password,
Mechanism: cfg.Mechanism,
Source: cfg.Db,
})
if err != nil {
return
}
db := session.DB(cfg.Db)
characters, err := newCharacterRepository(db)
if err != nil {
session.Close()
return nil, nil, err
}
bundle = &repositories.Bundle{
Characters: characters,
Tags: newTagRepository(db),
}
closeFn = func() error {
session.Close()
return nil
}
return
}
type counter struct {
coll *mgo.Collection
category string
name string
}
func newCounter(db *mgo.Database, category, name string) *counter {
return &counter{
coll: db.C("core.counters"),
category: category,
name: name,
}
}
func (c *counter) WithName(name string) *counter {
return &counter{
coll: c.coll,
category: c.category,
name: name,
}
}
func (c *counter) Increment(amount int) (int, error) {
type counterDoc struct {
ID string `bson:"_id"`
Value int `bson:"value"`
}
id := c.category + "." + c.name
doc := counterDoc{}
_, err := c.coll.Find(bson.M{"_id": id}).Apply(mgo.Change{
Update: bson.M{"$inc": bson.M{"value": amount}},
Upsert: true,
ReturnNew: true,
}, &doc)
if err != nil {
return -1, err
}
return doc.Value, nil
}