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.
 
 
 
 

123 lines
2.5 KiB

package mysql
import (
"context"
"database/sql"
"encoding/json"
"git.aiterp.net/lucifer/new-server/models"
"github.com/jmoiron/sqlx"
)
type sceneRecord struct {
ID int `db:"id"`
Name string `db:"name"`
IntervalMS int64 `db:"interval_ms"`
RoleJSON json.RawMessage `db:"roles"`
}
type SceneRepo struct {
DBX *sqlx.DB
}
func (r *SceneRepo) Find(ctx context.Context, id int) (*models.Scene, error) {
var scene sceneRecord
err := r.DBX.GetContext(ctx, &scene, "SELECT * FROM scene WHERE id = ?", id)
if err != nil {
return nil, dbErr(err)
}
return r.populateOne(&scene)
}
func (r *SceneRepo) FetchAll(ctx context.Context) ([]models.Scene, error) {
scenes := make([]sceneRecord, 0, 8)
err := r.DBX.SelectContext(ctx, &scenes, "SELECT * FROM scene")
if err != nil {
if err == sql.ErrNoRows {
return []models.Scene{}, nil
}
return nil, dbErr(err)
}
return r.populate(scenes)
}
func (r *SceneRepo) Save(ctx context.Context, scene *models.Scene) error {
j, err := json.Marshal(scene.Roles)
if err != nil {
return err
}
if scene.ID > 0 {
_, err := r.DBX.ExecContext(
ctx,
"UPDATE scene SET name = ?, interval_ms = ?, roles = ? WHERE id = ?",
scene.Name, scene.IntervalMS, j, scene.ID,
)
if err != nil {
return dbErr(err)
}
} else {
rs, err := r.DBX.ExecContext(
ctx,
"INSERT INTO scene (name, interval_ms, roles) VALUES (?, ?, ?)",
scene.Name, scene.IntervalMS, j,
)
if err != nil {
return dbErr(err)
}
id, err := rs.LastInsertId()
if err != nil {
return dbErr(err)
}
scene.ID = int(id)
}
return nil
}
func (r *SceneRepo) Delete(ctx context.Context, scene *models.Scene) error {
_, err := r.DBX.ExecContext(ctx, "DELETE FROM scene WHERE id = ?", scene.ID)
if err != nil {
return dbErr(err)
}
scene.ID = 0
return nil
}
func (r *SceneRepo) populateOne(record *sceneRecord) (*models.Scene, error) {
records, err := r.populate([]sceneRecord{*record})
if err != nil {
return nil, err
}
return &records[0], nil
}
func (r *SceneRepo) populate(records []sceneRecord) ([]models.Scene, error) {
res := make([]models.Scene, 0, len(records))
for _, record := range records {
scene := models.Scene{
ID: record.ID,
Name: record.Name,
IntervalMS: record.IntervalMS,
Roles: make([]models.SceneRole, 0, 8),
}
err := json.Unmarshal(record.RoleJSON, &scene.Roles)
if err != nil {
return nil, dbErr(err)
}
res = append(res, scene)
}
return res, nil
}