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.

125 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. for _, obj := range object {
  52. change.Logs = append(change.Logs, &obj)
  53. }
  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.Character:
  59. for _, obj := range object {
  60. change.Characters = append(change.Characters, &obj)
  61. }
  62. case models.Channel:
  63. change.Channels = append(change.Channels, &object)
  64. case *models.Channel:
  65. change.Channels = append(change.Channels, object)
  66. case []models.Channel:
  67. for _, obj := range object {
  68. change.Channels = append(change.Channels, &obj)
  69. }
  70. case models.Post:
  71. change.Posts = append(change.Posts, &object)
  72. case *models.Post:
  73. change.Posts = append(change.Posts, object)
  74. case []models.Post:
  75. for _, obj := range object {
  76. change.Posts = append(change.Posts, &obj)
  77. }
  78. case models.Story:
  79. change.Stories = append(change.Stories, &object)
  80. case *models.Story:
  81. change.Stories = append(change.Stories, object)
  82. case []models.Story:
  83. for _, obj := range object {
  84. change.Stories = append(change.Stories, &obj)
  85. }
  86. case models.Chapter:
  87. change.Chapters = append(change.Chapters, &object)
  88. case *models.Chapter:
  89. change.Chapters = append(change.Chapters, object)
  90. case []models.Chapter:
  91. for _, obj := range object {
  92. change.Chapters = append(change.Chapters, &obj)
  93. }
  94. case models.Comment:
  95. change.Comments = append(change.Comments, &object)
  96. case *models.Comment:
  97. change.Comments = append(change.Comments, object)
  98. case []models.Comment:
  99. for _, obj := range object {
  100. change.Comments = append(change.Comments, &obj)
  101. }
  102. default:
  103. log.Printf("Warning: unrecognized object in change: %#+v", object)
  104. }
  105. }
  106. pushToSubscribers(change)
  107. err = collection.Insert(&change)
  108. if err != nil {
  109. return models.Change{}, err
  110. }
  111. return change, nil
  112. }