groupsummary.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package model
  2. import (
  3. "errors"
  4. "gorm.io/gorm"
  5. "gorm.io/gorm/clause"
  6. )
  7. // only summary result only requests
  8. type GroupSummary struct {
  9. ID int `gorm:"primaryKey"`
  10. Unique GroupSummaryUnique `gorm:"embedded"`
  11. Data SummaryData `gorm:"embedded"`
  12. }
  13. type GroupSummaryUnique struct {
  14. GroupID string `gorm:"size:64;not null;uniqueIndex:idx_groupsummary_unique,priority:1"`
  15. TokenName string `gorm:"size:32;not null;uniqueIndex:idx_groupsummary_unique,priority:2"`
  16. Model string `gorm:"size:64;not null;uniqueIndex:idx_groupsummary_unique,priority:3"`
  17. HourTimestamp int64 `gorm:"not null;uniqueIndex:idx_groupsummary_unique,priority:4,sort:desc"`
  18. }
  19. func (l *GroupSummary) BeforeCreate(_ *gorm.DB) (err error) {
  20. if l.Unique.Model == "" {
  21. return errors.New("model is required")
  22. }
  23. if l.Unique.HourTimestamp == 0 {
  24. return errors.New("hour timestamp is required")
  25. }
  26. if err := validateHourTimestamp(l.Unique.HourTimestamp); err != nil {
  27. return err
  28. }
  29. return err
  30. }
  31. func CreateGroupSummaryIndexs(db *gorm.DB) error {
  32. indexes := []string{
  33. "CREATE INDEX IF NOT EXISTS idx_groupsummary_group_hour ON group_summaries (group_id, hour_timestamp DESC)",
  34. "CREATE INDEX IF NOT EXISTS idx_groupsummary_group_token_hour ON group_summaries (group_id, token_name, hour_timestamp DESC)",
  35. "CREATE INDEX IF NOT EXISTS idx_groupsummary_group_model_hour ON group_summaries (group_id, model, hour_timestamp DESC)",
  36. }
  37. for _, index := range indexes {
  38. if err := db.Exec(index).Error; err != nil {
  39. return err
  40. }
  41. }
  42. return nil
  43. }
  44. func UpsertGroupSummary(unique GroupSummaryUnique, data SummaryData) error {
  45. err := validateHourTimestamp(unique.HourTimestamp)
  46. if err != nil {
  47. return err
  48. }
  49. for range 3 {
  50. result := LogDB.
  51. Model(&GroupSummary{}).
  52. Where(
  53. "group_id = ? AND token_name = ? AND model = ? AND hour_timestamp = ?",
  54. unique.GroupID,
  55. unique.TokenName,
  56. unique.Model,
  57. unique.HourTimestamp,
  58. ).
  59. Updates(data.buildUpdateData("group_summaries"))
  60. err = result.Error
  61. if err != nil {
  62. return err
  63. }
  64. if result.RowsAffected > 0 {
  65. return nil
  66. }
  67. err = createGroupSummary(unique, data)
  68. if err == nil {
  69. return nil
  70. }
  71. if !errors.Is(err, gorm.ErrDuplicatedKey) {
  72. return err
  73. }
  74. }
  75. return err
  76. }
  77. func createGroupSummary(unique GroupSummaryUnique, data SummaryData) error {
  78. return LogDB.
  79. Clauses(clause.OnConflict{
  80. Columns: []clause.Column{
  81. {Name: "group_id"},
  82. {Name: "token_name"},
  83. {Name: "model"},
  84. {Name: "hour_timestamp"},
  85. },
  86. DoUpdates: clause.Assignments(data.buildUpdateData("group_summaries")),
  87. }).
  88. Create(&GroupSummary{
  89. Unique: unique,
  90. Data: data,
  91. }).Error
  92. }