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.

161 lines
4.2 KiB

  1. package mysql
  2. import (
  3. "context"
  4. "encoding/json"
  5. "git.aiterp.net/lucifer/new-server/models"
  6. "github.com/jmoiron/sqlx"
  7. )
  8. type eventHandlerRecord struct {
  9. ID int `db:"id"`
  10. EventName string `db:"event_name"`
  11. OneShot bool `db:"one_shot"`
  12. Priority int `db:"priority"`
  13. TargetKind string `db:"target_kind"`
  14. TargetValue string `db:"target_value"`
  15. From *string `db:"from_tod"`
  16. To *string `db:"to_tod"`
  17. ConditionsJSON json.RawMessage `db:"conditions"`
  18. ActionsJSON json.RawMessage `db:"actions"`
  19. }
  20. type EventHandlerRepo struct {
  21. DBX *sqlx.DB
  22. }
  23. func (r *EventHandlerRepo) FindByID(ctx context.Context, id int) (*models.EventHandler, error) {
  24. var record eventHandlerRecord
  25. err := r.DBX.GetContext(ctx, &record, "SELECT * FROM event_handler WHERE id = ?", id)
  26. if err != nil {
  27. return nil, dbErr(err)
  28. }
  29. return r.populateOne(&record)
  30. }
  31. func (r *EventHandlerRepo) FetchAll(ctx context.Context) ([]models.EventHandler, error) {
  32. var records []eventHandlerRecord
  33. err := r.DBX.SelectContext(ctx, &records, "SELECT * FROM event_handler ORDER BY priority DESC, id")
  34. if err != nil {
  35. return nil, dbErr(err)
  36. }
  37. return r.populate(records)
  38. }
  39. func (r *EventHandlerRepo) Save(ctx context.Context, handler *models.EventHandler) error {
  40. conditionsJson, err := json.Marshal(handler.Conditions)
  41. if err != nil {
  42. return dbErr(err)
  43. }
  44. actionsJson, err := json.Marshal(handler.Actions)
  45. if err != nil {
  46. return dbErr(err)
  47. }
  48. record := eventHandlerRecord{
  49. ID: handler.ID,
  50. EventName: handler.EventName,
  51. OneShot: handler.OneShot,
  52. Priority: handler.Priority,
  53. TargetKind: string(handler.TargetKind),
  54. TargetValue: handler.TargetValue,
  55. ConditionsJSON: conditionsJson,
  56. ActionsJSON: actionsJson,
  57. From: handler.From.StringPtr(),
  58. To: handler.To.StringPtr(),
  59. }
  60. if record.ID == 0 {
  61. res, err := r.DBX.NamedExecContext(ctx, `
  62. INSERT INTO event_handler (event_name, one_shot, priority, target_kind, target_value, conditions, from_tod, to_tod, actions)
  63. VALUES (:event_name, :one_shot, :priority, :target_kind, :target_value, :conditions, :from_tod, :to_tod, :actions);
  64. `, record)
  65. if err != nil {
  66. return dbErr(err)
  67. }
  68. id, err := res.LastInsertId()
  69. if err != nil {
  70. return dbErr(err)
  71. }
  72. handler.ID = int(id)
  73. } else {
  74. _, err := r.DBX.NamedExecContext(ctx, `
  75. UPDATE event_handler SET
  76. event_name = :event_name,
  77. one_shot = :one_shot,
  78. priority = :priority,
  79. target_kind = :target_kind,
  80. target_value = :target_value,
  81. conditions = :conditions,
  82. from_tod = :from_tod,
  83. to_tod = :to_tod,
  84. actions = :actions
  85. WHERE id = :id
  86. `, record)
  87. if err != nil {
  88. return dbErr(err)
  89. }
  90. }
  91. return nil
  92. }
  93. func (r *EventHandlerRepo) Delete(ctx context.Context, handler *models.EventHandler) error {
  94. _, err := r.DBX.ExecContext(ctx, "DELETE FROM event_handler WHERE id=?", handler.ID)
  95. if err != nil {
  96. return dbErr(err)
  97. }
  98. return nil
  99. }
  100. func (r *EventHandlerRepo) populateOne(record *eventHandlerRecord) (*models.EventHandler, error) {
  101. records, err := r.populate([]eventHandlerRecord{*record})
  102. if err != nil {
  103. return nil, err
  104. }
  105. return &records[0], nil
  106. }
  107. func (r *EventHandlerRepo) populate(records []eventHandlerRecord) ([]models.EventHandler, error) {
  108. res := make([]models.EventHandler, 0, len(records))
  109. for _, record := range records {
  110. handler := models.EventHandler{
  111. ID: record.ID,
  112. EventName: record.EventName,
  113. OneShot: record.OneShot,
  114. Priority: record.Priority,
  115. TargetKind: models.ReferenceKind(record.TargetKind),
  116. TargetValue: record.TargetValue,
  117. Conditions: make(map[string]models.EventCondition),
  118. }
  119. err := json.Unmarshal(record.ConditionsJSON, &handler.Conditions)
  120. if err != nil {
  121. return nil, dbErr(err)
  122. }
  123. err = json.Unmarshal(record.ActionsJSON, &handler.Actions)
  124. if err != nil {
  125. return nil, dbErr(err)
  126. }
  127. handler.From, err = models.ParseTimeOfDayPtr(record.From)
  128. if err != nil {
  129. return nil, dbErr(err)
  130. }
  131. handler.To, err = models.ParseTimeOfDayPtr(record.To)
  132. if err != nil {
  133. return nil, dbErr(err)
  134. }
  135. res = append(res, handler)
  136. }
  137. return res, nil
  138. }