package mysql import ( "context" "encoding/json" "git.aiterp.net/lucifer/new-server/models" "github.com/jmoiron/sqlx" ) type eventHandlerRecord struct { ID int `db:"id"` EventName string `db:"event_name"` OneShot bool `db:"one_shot"` Priority int `db:"priority"` TargetKind string `db:"target_kind"` TargetValue string `db:"target_value"` From *string `db:"from_tod"` To *string `db:"to_tod"` ConditionsJSON json.RawMessage `db:"conditions"` ActionsJSON json.RawMessage `db:"actions"` } type EventHandlerRepo struct { DBX *sqlx.DB } func (r *EventHandlerRepo) FindByID(ctx context.Context, id int) (*models.EventHandler, error) { var record eventHandlerRecord err := r.DBX.GetContext(ctx, &record, "SELECT * FROM event_handler WHERE id = ?", id) if err != nil { return nil, dbErr(err) } return r.populateOne(&record) } func (r *EventHandlerRepo) FetchAll(ctx context.Context) ([]models.EventHandler, error) { var records []eventHandlerRecord err := r.DBX.SelectContext(ctx, &records, "SELECT * FROM event_handler ORDER BY priority DESC, id") if err != nil { return nil, dbErr(err) } return r.populate(records) } func (r *EventHandlerRepo) Save(ctx context.Context, handler *models.EventHandler) error { conditionsJson, err := json.Marshal(handler.Conditions) if err != nil { return dbErr(err) } actionsJson, err := json.Marshal(handler.Actions) if err != nil { return dbErr(err) } record := eventHandlerRecord{ ID: handler.ID, EventName: handler.EventName, OneShot: handler.OneShot, Priority: handler.Priority, TargetKind: string(handler.TargetKind), TargetValue: handler.TargetValue, ConditionsJSON: conditionsJson, ActionsJSON: actionsJson, From: handler.From.StringPtr(), To: handler.To.StringPtr(), } if record.ID == 0 { res, err := r.DBX.NamedExecContext(ctx, ` INSERT INTO event_handler (event_name, one_shot, priority, target_kind, target_value, conditions, from_tod, to_tod, actions) VALUES (:event_name, :one_shot, :priority, :target_kind, :target_value, :conditions, :from_tod, :to_tod, :actions); `, record) if err != nil { return dbErr(err) } id, err := res.LastInsertId() if err != nil { return dbErr(err) } handler.ID = int(id) } else { _, err := r.DBX.NamedExecContext(ctx, ` UPDATE event_handler SET event_name = :event_name, one_shot = :one_shot, priority = :priority, target_kind = :target_kind, target_value = :target_value, conditions = :conditions, from_tod = :from_tod, to_tod = :to_tod, actions = :actions WHERE id = :id `, record) if err != nil { return dbErr(err) } } return nil } func (r *EventHandlerRepo) Delete(ctx context.Context, handler *models.EventHandler) error { _, err := r.DBX.ExecContext(ctx, "DELETE FROM event_handler WHERE id=?", handler.ID) if err != nil { return dbErr(err) } return nil } func (r *EventHandlerRepo) populateOne(record *eventHandlerRecord) (*models.EventHandler, error) { records, err := r.populate([]eventHandlerRecord{*record}) if err != nil { return nil, err } return &records[0], nil } func (r *EventHandlerRepo) populate(records []eventHandlerRecord) ([]models.EventHandler, error) { res := make([]models.EventHandler, 0, len(records)) for _, record := range records { handler := models.EventHandler{ ID: record.ID, EventName: record.EventName, OneShot: record.OneShot, Priority: record.Priority, TargetKind: models.ReferenceKind(record.TargetKind), TargetValue: record.TargetValue, Conditions: make(map[string]models.EventCondition), } err := json.Unmarshal(record.ConditionsJSON, &handler.Conditions) if err != nil { return nil, dbErr(err) } err = json.Unmarshal(record.ActionsJSON, &handler.Actions) if err != nil { return nil, dbErr(err) } handler.From, err = models.ParseTimeOfDayPtr(record.From) if err != nil { return nil, dbErr(err) } handler.To, err = models.ParseTimeOfDayPtr(record.To) if err != nil { return nil, dbErr(err) } res = append(res, handler) } return res, nil }