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

  1. package mongodb
  2. import (
  3. "fmt"
  4. "github.com/globalsign/mgo/bson"
  5. "time"
  6. "git.aiterp.net/rpdata/api/internal/config"
  7. "git.aiterp.net/rpdata/api/repositories"
  8. "github.com/globalsign/mgo"
  9. )
  10. // Init initializes the mongodb database
  11. func Init(cfg config.Database) (bundle *repositories.Bundle, closeFn func() error, err error) {
  12. port := cfg.Port
  13. if port <= 0 {
  14. port = 27017
  15. }
  16. session, err := mgo.DialWithInfo(&mgo.DialInfo{
  17. Addrs: []string{fmt.Sprintf("%s:%d", cfg.Host, port)},
  18. Timeout: 30 * time.Second,
  19. Database: cfg.Db,
  20. Username: cfg.Username,
  21. Password: cfg.Password,
  22. Mechanism: cfg.Mechanism,
  23. Source: cfg.Db,
  24. })
  25. if err != nil {
  26. return
  27. }
  28. db := session.DB(cfg.Db)
  29. characters, err := newCharacterRepository(db)
  30. if err != nil {
  31. session.Close()
  32. return nil, nil, err
  33. }
  34. bundle = &repositories.Bundle{
  35. Characters: characters,
  36. Tags: newTagRepository(db),
  37. }
  38. closeFn = func() error {
  39. session.Close()
  40. return nil
  41. }
  42. return
  43. }
  44. type counter struct {
  45. coll *mgo.Collection
  46. category string
  47. name string
  48. }
  49. func newCounter(db *mgo.Database, category, name string) *counter {
  50. return &counter{
  51. coll: db.C("core.counters"),
  52. category: category,
  53. name: name,
  54. }
  55. }
  56. func (c *counter) WithName(name string) *counter {
  57. return &counter{
  58. coll: c.coll,
  59. category: c.category,
  60. name: name,
  61. }
  62. }
  63. func (c *counter) Increment(amount int) (int, error) {
  64. type counterDoc struct {
  65. ID string `bson:"_id"`
  66. Value int `bson:"value"`
  67. }
  68. id := c.category + "." + c.name
  69. doc := counterDoc{}
  70. _, err := c.coll.Find(bson.M{"_id": id}).Apply(mgo.Change{
  71. Update: bson.M{"$inc": bson.M{"value": amount}},
  72. Upsert: true,
  73. ReturnNew: true,
  74. }, &doc)
  75. if err != nil {
  76. return -1, err
  77. }
  78. return doc.Value, nil
  79. }