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
133 lines
2.8 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) FindName(ctx context.Context, name string) (*models.Scene, error) {
|
|
var scene sceneRecord
|
|
err := r.DBX.GetContext(ctx, &scene, "SELECT * FROM scene WHERE name = ?", name)
|
|
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
|
|
}
|