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.

104 lines
2.2 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. }
  32. if filter.Author != nil && *filter.Author != "" {
  33. query["author"] = *filter.Author
  34. }
  35. if filter.Limit != nil {
  36. limit = *filter.Limit
  37. }
  38. initialSize := 64
  39. if limit > 0 && limit < 256 {
  40. initialSize = limit
  41. }
  42. changes := make([]*models.Change, 0, initialSize)
  43. err := r.changes.Find(query).Sort("-date").Limit(limit).All(&changes)
  44. if err != nil {
  45. return nil, err
  46. }
  47. return changes, nil
  48. }
  49. func (r *changeRepository) Insert(ctx context.Context, change models.Change) (*models.Change, error) {
  50. next, err := r.idCounter.Increment(1)
  51. if err != nil {
  52. return nil, err
  53. }
  54. change.ID = "Change_" + strconv.Itoa(next)
  55. err = r.changes.Insert(&change)
  56. if err != nil {
  57. return nil, err
  58. }
  59. return &change, nil
  60. }
  61. func (r *changeRepository) Remove(ctx context.Context, change models.Change) error {
  62. return r.changes.RemoveId(change.ID)
  63. }
  64. func newChangeRepository(db *mgo.Database) (repositories.ChangeRepository, error) {
  65. collection := db.C("common.changes")
  66. err := collection.EnsureIndex(mgo.Index{
  67. Name: "expiry",
  68. Key: []string{"date"},
  69. ExpireAfter: time.Hour * 2400, // 100 days
  70. })
  71. if err != nil {
  72. return nil, err
  73. }
  74. err = collection.EnsureIndexKey("author")
  75. if err != nil {
  76. return nil, err
  77. }
  78. err = collection.EnsureIndexKey("keys")
  79. if err != nil {
  80. return nil, err
  81. }
  82. return &changeRepository{
  83. changes: collection,
  84. idCounter: newCounter(db, "auto_increment", "Change"),
  85. }, nil
  86. }