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.

106 lines
2.3 KiB

  1. package mongodb
  2. import (
  3. "context"
  4. "git.aiterp.net/rpdata/api/models"
  5. "git.aiterp.net/rpdata/api/repositories"
  6. "github.com/globalsign/mgo"
  7. "github.com/globalsign/mgo/bson"
  8. "strconv"
  9. "time"
  10. )
  11. type changeRepository struct {
  12. changes *mgo.Collection
  13. idCounter *counter
  14. }
  15. func (r *changeRepository) Find(ctx context.Context, id string) (*models.Change, error) {
  16. change := new(models.Change)
  17. err := r.changes.FindId(id).One(change)
  18. if err != nil {
  19. return nil, err
  20. }
  21. return change, nil
  22. }
  23. func (r *changeRepository) List(ctx context.Context, filter models.ChangeFilter) ([]*models.Change, error) {
  24. query := bson.M{}
  25. limit := 0
  26. if filter.EarliestDate != nil && !filter.EarliestDate.IsZero() {
  27. query["date"] = bson.M{"$gte": *filter.EarliestDate}
  28. }
  29. if len(filter.Keys) > 0 {
  30. query["keys"] = bson.M{"$in": filter.Keys}
  31. } else {
  32. query["listed"] = true
  33. }
  34. if filter.Author != nil && *filter.Author != "" {
  35. query["author"] = *filter.Author
  36. }
  37. if filter.Limit != nil {
  38. limit = *filter.Limit
  39. }
  40. initialSize := 64
  41. if limit > 0 && limit < 256 {
  42. initialSize = limit
  43. }
  44. changes := make([]*models.Change, 0, initialSize)
  45. err := r.changes.Find(query).Sort("-date").Limit(limit).All(&changes)
  46. if err != nil {
  47. return nil, err
  48. }
  49. return changes, nil
  50. }
  51. func (r *changeRepository) Insert(ctx context.Context, change models.Change) (*models.Change, error) {
  52. next, err := r.idCounter.Increment(1)
  53. if err != nil {
  54. return nil, err
  55. }
  56. change.ID = "Change_" + strconv.Itoa(next)
  57. err = r.changes.Insert(&change)
  58. if err != nil {
  59. return nil, err
  60. }
  61. return &change, nil
  62. }
  63. func (r *changeRepository) Remove(ctx context.Context, change models.Change) error {
  64. return r.changes.RemoveId(change.ID)
  65. }
  66. func newChangeRepository(db *mgo.Database) (repositories.ChangeRepository, error) {
  67. collection := db.C("common.changes")
  68. err := collection.EnsureIndex(mgo.Index{
  69. Name: "expiry",
  70. Key: []string{"date"},
  71. ExpireAfter: time.Hour * 2400, // 100 days
  72. })
  73. if err != nil {
  74. return nil, err
  75. }
  76. err = collection.EnsureIndexKey("author")
  77. if err != nil {
  78. return nil, err
  79. }
  80. err = collection.EnsureIndexKey("keys")
  81. if err != nil {
  82. return nil, err
  83. }
  84. return &changeRepository{
  85. changes: collection,
  86. idCounter: newCounter(db, "auto_increment", "Change"),
  87. }, nil
  88. }