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.

97 lines
2.4 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.Character:
  51. change.Characters = append(change.Characters, object)
  52. case []models.Character:
  53. change.Characters = append(change.Characters, object...)
  54. case models.Channel:
  55. change.Channels = append(change.Channels, object)
  56. case []models.Channel:
  57. change.Channels = append(change.Channels, object...)
  58. case models.Post:
  59. change.Posts = append(change.Posts, object)
  60. case []models.Post:
  61. change.Posts = append(change.Posts, object...)
  62. case models.Story:
  63. change.Stories = append(change.Stories, object)
  64. case []models.Story:
  65. change.Stories = append(change.Stories, object...)
  66. case models.Tag:
  67. change.Tags = append(change.Tags, object)
  68. case []models.Tag:
  69. change.Tags = append(change.Tags, object...)
  70. case models.Chapter:
  71. change.Chapters = append(change.Chapters, object)
  72. case []models.Chapter:
  73. change.Chapters = append(change.Chapters, object...)
  74. default:
  75. log.Printf("Warning: unrecognized object in change: %#+v", object)
  76. }
  77. }
  78. pushToSubscribers(change)
  79. err = collection.Insert(&change)
  80. if err != nil {
  81. return models.Change{}, err
  82. }
  83. return change, nil
  84. }