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.

133 lines
2.8 KiB

  1. package mysql
  2. import (
  3. "context"
  4. "database/sql"
  5. "encoding/json"
  6. "git.aiterp.net/lucifer/new-server/models"
  7. "github.com/jmoiron/sqlx"
  8. )
  9. type sceneRecord struct {
  10. ID int `db:"id"`
  11. Name string `db:"name"`
  12. IntervalMS int64 `db:"interval_ms"`
  13. RoleJSON json.RawMessage `db:"roles"`
  14. }
  15. type SceneRepo struct {
  16. DBX *sqlx.DB
  17. }
  18. func (r *SceneRepo) Find(ctx context.Context, id int) (*models.Scene, error) {
  19. var scene sceneRecord
  20. err := r.DBX.GetContext(ctx, &scene, "SELECT * FROM scene WHERE id = ?", id)
  21. if err != nil {
  22. return nil, dbErr(err)
  23. }
  24. return r.populateOne(&scene)
  25. }
  26. func (r *SceneRepo) FindName(ctx context.Context, name string) (*models.Scene, error) {
  27. var scene sceneRecord
  28. err := r.DBX.GetContext(ctx, &scene, "SELECT * FROM scene WHERE name = ?", name)
  29. if err != nil {
  30. return nil, dbErr(err)
  31. }
  32. return r.populateOne(&scene)
  33. }
  34. func (r *SceneRepo) FetchAll(ctx context.Context) ([]models.Scene, error) {
  35. scenes := make([]sceneRecord, 0, 8)
  36. err := r.DBX.SelectContext(ctx, &scenes, "SELECT * FROM scene")
  37. if err != nil {
  38. if err == sql.ErrNoRows {
  39. return []models.Scene{}, nil
  40. }
  41. return nil, dbErr(err)
  42. }
  43. return r.populate(scenes)
  44. }
  45. func (r *SceneRepo) Save(ctx context.Context, scene *models.Scene) error {
  46. j, err := json.Marshal(scene.Roles)
  47. if err != nil {
  48. return err
  49. }
  50. if scene.ID > 0 {
  51. _, err := r.DBX.ExecContext(
  52. ctx,
  53. "UPDATE scene SET name = ?, interval_ms = ?, roles = ? WHERE id = ?",
  54. scene.Name, scene.IntervalMS, j, scene.ID,
  55. )
  56. if err != nil {
  57. return dbErr(err)
  58. }
  59. } else {
  60. rs, err := r.DBX.ExecContext(
  61. ctx,
  62. "INSERT INTO scene (name, interval_ms, roles) VALUES (?, ?, ?)",
  63. scene.Name, scene.IntervalMS, j,
  64. )
  65. if err != nil {
  66. return dbErr(err)
  67. }
  68. id, err := rs.LastInsertId()
  69. if err != nil {
  70. return dbErr(err)
  71. }
  72. scene.ID = int(id)
  73. }
  74. return nil
  75. }
  76. func (r *SceneRepo) Delete(ctx context.Context, scene *models.Scene) error {
  77. _, err := r.DBX.ExecContext(ctx, "DELETE FROM scene WHERE id = ?", scene.ID)
  78. if err != nil {
  79. return dbErr(err)
  80. }
  81. scene.ID = 0
  82. return nil
  83. }
  84. func (r *SceneRepo) populateOne(record *sceneRecord) (*models.Scene, error) {
  85. records, err := r.populate([]sceneRecord{*record})
  86. if err != nil {
  87. return nil, err
  88. }
  89. return &records[0], nil
  90. }
  91. func (r *SceneRepo) populate(records []sceneRecord) ([]models.Scene, error) {
  92. res := make([]models.Scene, 0, len(records))
  93. for _, record := range records {
  94. scene := models.Scene{
  95. ID: record.ID,
  96. Name: record.Name,
  97. IntervalMS: record.IntervalMS,
  98. Roles: make([]models.SceneRole, 0, 8),
  99. }
  100. err := json.Unmarshal(record.RoleJSON, &scene.Roles)
  101. if err != nil {
  102. return nil, dbErr(err)
  103. }
  104. res = append(res, scene)
  105. }
  106. return res, nil
  107. }