groupsummary-minute.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package model
  2. import (
  3. "errors"
  4. "time"
  5. "gorm.io/gorm"
  6. "gorm.io/gorm/clause"
  7. )
  8. // only summary result only requests
  9. type GroupSummaryMinute struct {
  10. ID int `gorm:"primaryKey"`
  11. Unique GroupSummaryMinuteUnique `gorm:"embedded"`
  12. Data SummaryData `gorm:"embedded"`
  13. }
  14. type GroupSummaryMinuteUnique struct {
  15. GroupID string `gorm:"size:64;not null;uniqueIndex:idx_groupsummary_minute_unique,priority:1"`
  16. TokenName string `gorm:"size:32;not null;uniqueIndex:idx_groupsummary_minute_unique,priority:2"`
  17. Model string `gorm:"size:64;not null;uniqueIndex:idx_groupsummary_minute_unique,priority:3"`
  18. MinuteTimestamp int64 `gorm:"not null;uniqueIndex:idx_groupsummary_minute_unique,priority:4,sort:desc"`
  19. }
  20. func (l *GroupSummaryMinute) BeforeCreate(_ *gorm.DB) (err error) {
  21. if l.Unique.Model == "" {
  22. return errors.New("model is required")
  23. }
  24. if l.Unique.MinuteTimestamp == 0 {
  25. return errors.New("minute timestamp is required")
  26. }
  27. if err := validateMinuteTimestamp(l.Unique.MinuteTimestamp); err != nil {
  28. return err
  29. }
  30. return err
  31. }
  32. func CreateGroupSummaryMinuteIndexs(db *gorm.DB) error {
  33. indexes := []string{
  34. "CREATE INDEX IF NOT EXISTS idx_groupsummary_minute_group_minute ON group_summary_minutes (group_id, minute_timestamp DESC)",
  35. "CREATE INDEX IF NOT EXISTS idx_groupsummary_minute_group_token_minute ON group_summary_minutes (group_id, token_name, minute_timestamp DESC)",
  36. "CREATE INDEX IF NOT EXISTS idx_groupsummary_minute_group_model_minute ON group_summary_minutes (group_id, model, minute_timestamp DESC)",
  37. }
  38. for _, index := range indexes {
  39. if err := db.Exec(index).Error; err != nil {
  40. return err
  41. }
  42. }
  43. return nil
  44. }
  45. func UpsertGroupSummaryMinute(unique GroupSummaryMinuteUnique, data SummaryData) error {
  46. err := validateMinuteTimestamp(unique.MinuteTimestamp)
  47. if err != nil {
  48. return err
  49. }
  50. for range 3 {
  51. result := LogDB.
  52. Model(&GroupSummaryMinute{}).
  53. Where(
  54. "group_id = ? AND token_name = ? AND model = ? AND minute_timestamp = ?",
  55. unique.GroupID,
  56. unique.TokenName,
  57. unique.Model,
  58. unique.MinuteTimestamp,
  59. ).
  60. Updates(data.buildUpdateData("group_summary_minutes"))
  61. err = result.Error
  62. if err != nil {
  63. return err
  64. }
  65. if result.RowsAffected > 0 {
  66. return nil
  67. }
  68. err = createGroupSummaryMinute(unique, data)
  69. if err == nil {
  70. return nil
  71. }
  72. if !errors.Is(err, gorm.ErrDuplicatedKey) {
  73. return err
  74. }
  75. }
  76. return err
  77. }
  78. func createGroupSummaryMinute(unique GroupSummaryMinuteUnique, data SummaryData) error {
  79. return LogDB.
  80. Clauses(clause.OnConflict{
  81. Columns: []clause.Column{
  82. {Name: "group_id"},
  83. {Name: "token_name"},
  84. {Name: "model"},
  85. {Name: "minute_timestamp"},
  86. },
  87. DoUpdates: clause.Assignments(data.buildUpdateData("group_summary_minutes")),
  88. }).
  89. Create(&GroupSummaryMinute{
  90. Unique: unique,
  91. Data: data,
  92. }).Error
  93. }
  94. func GetGroupLastRequestTimeMinute(group string) (time.Time, error) {
  95. if group == "" {
  96. return time.Time{}, errors.New("group is required")
  97. }
  98. var summary GroupSummaryMinute
  99. err := LogDB.
  100. Model(&GroupSummaryMinute{}).
  101. Where("group_id = ?", group).
  102. Order("minute_timestamp desc").
  103. First(&summary).Error
  104. if summary.Unique.MinuteTimestamp == 0 {
  105. return time.Time{}, nil
  106. }
  107. return time.Unix(summary.Unique.MinuteTimestamp, 0), err
  108. }
  109. func GetGroupTokenLastRequestTimeMinute(group, token string) (time.Time, error) {
  110. var summary GroupSummaryMinute
  111. err := LogDB.
  112. Model(&GroupSummaryMinute{}).
  113. Where("group_id = ? AND token_name = ?", group, token).
  114. Order("minute_timestamp desc").
  115. First(&summary).Error
  116. if summary.Unique.MinuteTimestamp == 0 {
  117. return time.Time{}, nil
  118. }
  119. return time.Unix(summary.Unique.MinuteTimestamp, 0), err
  120. }