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.

117 lines
3.2 KiB

  1. package changes
  2. import (
  3. "log"
  4. "strconv"
  5. "time"
  6. "git.aiterp.net/rpdata/api/internal/counter"
  7. "git.aiterp.net/rpdata/api/models"
  8. )
  9. // Submit a change to the database. The objects may be any supported model, or arrays.
  10. func Submit(model, op, author string, listed bool, keys []models.ChangeKey, objects ...interface{}) (models.Change, error) {
  11. submitMutex.Lock()
  12. defer submitMutex.Unlock()
  13. id, err := counter.Next("auto_increment", "Change")
  14. if err != nil {
  15. return models.Change{}, err
  16. }
  17. if !models.ChangeModel(model).IsValid() {
  18. panic("Invalid model")
  19. }
  20. // Silently discard * keys on unlisted changes.
  21. if !listed {
  22. keysCopy := make([]models.ChangeKey, len(keys))
  23. copy(keysCopy, keys)
  24. keys = keysCopy
  25. deletes := make([]int, 0, 1)
  26. for i, key := range keys {
  27. if key.ID == "*" {
  28. deletes = append(deletes, i-len(deletes))
  29. }
  30. }
  31. for _, index := range deletes {
  32. keys = append(keys[:index], keys[index+1:]...)
  33. }
  34. }
  35. change := models.Change{
  36. ID: "Change_" + strconv.Itoa(id),
  37. Model: models.ChangeModel(model),
  38. Date: time.Now(),
  39. Op: op,
  40. Author: author,
  41. Keys: keys,
  42. Listed: listed,
  43. }
  44. for _, object := range objects {
  45. switch object := object.(type) {
  46. case models.Log:
  47. change.Logs = append(change.Logs, object)
  48. case *models.Log:
  49. change.Logs = append(change.Logs, *object)
  50. case []models.Log:
  51. change.Logs = append(change.Logs, object...)
  52. case models.Character:
  53. change.Characters = append(change.Characters, object)
  54. case *models.Character:
  55. change.Characters = append(change.Characters, *object)
  56. case []models.Character:
  57. change.Characters = append(change.Characters, object...)
  58. case models.Channel:
  59. change.Channels = append(change.Channels, object)
  60. case *models.Channel:
  61. change.Channels = append(change.Channels, *object)
  62. case []models.Channel:
  63. change.Channels = append(change.Channels, object...)
  64. case models.Post:
  65. change.Posts = append(change.Posts, object)
  66. case *models.Post:
  67. change.Posts = append(change.Posts, *object)
  68. case []models.Post:
  69. change.Posts = append(change.Posts, object...)
  70. case models.Story:
  71. change.Stories = append(change.Stories, object)
  72. case *models.Story:
  73. change.Stories = append(change.Stories, *object)
  74. case []models.Story:
  75. change.Stories = append(change.Stories, object...)
  76. case models.Tag:
  77. change.Tags = append(change.Tags, object)
  78. case *models.Tag:
  79. change.Tags = append(change.Tags, *object)
  80. case []models.Tag:
  81. change.Tags = append(change.Tags, object...)
  82. case models.Chapter:
  83. change.Chapters = append(change.Chapters, object)
  84. case *models.Chapter:
  85. change.Chapters = append(change.Chapters, *object)
  86. case []models.Chapter:
  87. change.Chapters = append(change.Chapters, object...)
  88. case models.Comment:
  89. change.Comments = append(change.Comments, object)
  90. case *models.Comment:
  91. change.Comments = append(change.Comments, *object)
  92. case []models.Comment:
  93. change.Comments = append(change.Comments, object...)
  94. default:
  95. log.Printf("Warning: unrecognized object in change: %#+v", object)
  96. }
  97. }
  98. pushToSubscribers(change)
  99. err = collection.Insert(&change)
  100. if err != nil {
  101. return models.Change{}, err
  102. }
  103. return change, nil
  104. }