navidrome/persistence/annotation_repository.go

91 lines
2.4 KiB
Go

package persistence
import (
"context"
"time"
. "github.com/Masterminds/squirrel"
"github.com/astaxie/beego/orm"
"github.com/deluan/navidrome/model"
"github.com/google/uuid"
)
type annotationRepository struct {
sqlRepository
}
func NewAnnotationRepository(ctx context.Context, o orm.Ormer) model.AnnotationRepository {
r := &annotationRepository{}
r.ctx = ctx
r.ormer = o
r.tableName = "annotation"
return r
}
func (r *annotationRepository) upsert(values map[string]interface{}, itemType string, itemIDs ...string) error {
upd := Update(r.tableName).Where(r.getId(itemType, itemIDs...))
for f, v := range values {
upd = upd.Set(f, v)
}
c, err := r.executeSQL(upd)
if c == 0 || err == orm.ErrNoRows {
for _, itemID := range itemIDs {
id, _ := uuid.NewRandom()
values["ann_id"] = id.String()
values["user_id"] = userId(r.ctx)
values["item_type"] = itemType
values["item_id"] = itemID
ins := Insert(r.tableName).SetMap(values)
_, err = r.executeSQL(ins)
if err != nil {
return err
}
}
}
return err
}
func (r *annotationRepository) IncPlayCount(itemType, itemID string, ts time.Time) error {
upd := Update(r.tableName).Where(r.getId(itemType, itemID)).
Set("play_count", Expr("play_count+1")).
Set("play_date", ts)
c, err := r.executeSQL(upd)
if c == 0 || err == orm.ErrNoRows {
id, _ := uuid.NewRandom()
values := map[string]interface{}{}
values["ann_id"] = id.String()
values["user_id"] = userId(r.ctx)
values["item_type"] = itemType
values["item_id"] = itemID
values["play_count"] = 1
values["play_date"] = ts
ins := Insert(r.tableName).SetMap(values)
_, err = r.executeSQL(ins)
if err != nil {
return err
}
}
return err
}
func (r *annotationRepository) getId(itemType string, itemID ...string) And {
return And{
Eq{"user_id": userId(r.ctx)},
Eq{"item_type": itemType},
Eq{"item_id": itemID},
}
}
func (r *annotationRepository) SetStar(starred bool, itemType string, ids ...string) error {
starredAt := time.Now()
return r.upsert(map[string]interface{}{"starred": starred, "starred_at": starredAt}, itemType, ids...)
}
func (r *annotationRepository) SetRating(rating int, itemType, itemID string) error {
return r.upsert(map[string]interface{}{"rating": rating}, itemType, itemID)
}
func (r *annotationRepository) Delete(itemType string, itemIDs ...string) error {
return r.delete(r.getId(itemType, itemIDs...))
}