Files
sub-store/internal/database/template_repo.go
T

122 lines
2.7 KiB
Go

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,
}
}