package database import ( "database/sql" "time" "github.com/jmoiron/sqlx" "github.com/peterqiu0516/sub-store/internal/model" "github.com/peterqiu0516/sub-store/internal/util" ) type TemplateRepo struct { db *sqlx.DB } func NewTemplateRepo(db *sqlx.DB) *TemplateRepo { return &TemplateRepo{db: db} } type templateRow struct { ID string `db:"id"` Name string `db:"name"` Target string `db:"target"` ConfigJSON string `db:"config_json"` CreatedAt int64 `db:"created_at"` UpdatedAt int64 `db:"updated_at"` } func (r *TemplateRepo) List() ([]model.TemplateRecord, error) { var rows []templateRow if err := r.db.Select(&rows, "SELECT * FROM templates ORDER BY created_at ASC"); err != nil { return nil, err } result := make([]model.TemplateRecord, 0, len(rows)) for _, row := range rows { result = append(result, templateFromRow(row)) } return result, nil } func (r *TemplateRepo) Get(id string) (*model.TemplateRecord, error) { var row templateRow if err := r.db.Get(&row, "SELECT * FROM templates WHERE id = ?", id); err != nil { if err == sql.ErrNoRows { return nil, nil } return nil, err } rec := templateFromRow(row) return &rec, nil } func (r *TemplateRepo) Upsert(input model.TemplateRecord) (model.TemplateRecord, error) { now := time.Now().UnixMilli() id := input.ID if id == "" { id = util.ToId(input.Name) } existing, _ := r.Get(id) createdAt := now if existing != nil { createdAt = existing.CreatedAt } target := input.Target if target == "" { target = "mihomo" } config := input.Config if config == nil { config = map[string]any{} } rec := model.TemplateRecord{ ID: id, Name: input.Name, Target: target, Config: config, CreatedAt: createdAt, UpdatedAt: now, } configJSON := marshalJSON(rec.Config) _, err := r.db.Exec( `INSERT INTO templates (id, name, target, config_json, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET name = excluded.name, target = excluded.target, config_json = excluded.config_json, updated_at = excluded.updated_at`, rec.ID, rec.Name, rec.Target, configJSON, rec.CreatedAt, rec.UpdatedAt, ) if err != nil { return rec, err } return rec, nil } func (r *TemplateRepo) Delete(id string) error { _, err := r.db.Exec("DELETE FROM templates WHERE id = ?", id) return err } func templateFromRow(row templateRow) model.TemplateRecord { var config map[string]any jsonUnmarshal(row.ConfigJSON, &config) if config == nil { config = map[string]any{} } target := row.Target if target == "" { target = "mihomo" } return model.TemplateRecord{ ID: row.ID, Name: row.Name, Target: target, Config: config, CreatedAt: row.CreatedAt, UpdatedAt: row.UpdatedAt, } }