67 lines
2 KiB
Go
67 lines
2 KiB
Go
|
|
package persistence
|
||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/json"
|
||
|
|
"fmt"
|
||
|
|
|
||
|
|
. "github.com/Masterminds/squirrel"
|
||
|
|
"github.com/navidrome/navidrome/model"
|
||
|
|
"github.com/navidrome/navidrome/utils/slice"
|
||
|
|
)
|
||
|
|
|
||
|
|
type participant struct {
|
||
|
|
ID string `json:"id"`
|
||
|
|
Name string `json:"name"`
|
||
|
|
SubRole string `json:"subRole,omitempty"`
|
||
|
|
}
|
||
|
|
|
||
|
|
func marshalParticipants(participants model.Participants) string {
|
||
|
|
dbParticipants := make(map[model.Role][]participant)
|
||
|
|
for role, artists := range participants {
|
||
|
|
for _, artist := range artists {
|
||
|
|
dbParticipants[role] = append(dbParticipants[role], participant{ID: artist.ID, SubRole: artist.SubRole, Name: artist.Name})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
res, _ := json.Marshal(dbParticipants)
|
||
|
|
return string(res)
|
||
|
|
}
|
||
|
|
|
||
|
|
func unmarshalParticipants(data string) (model.Participants, error) {
|
||
|
|
var dbParticipants map[model.Role][]participant
|
||
|
|
err := json.Unmarshal([]byte(data), &dbParticipants)
|
||
|
|
if err != nil {
|
||
|
|
return nil, fmt.Errorf("parsing participants: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
participants := make(model.Participants, len(dbParticipants))
|
||
|
|
for role, participantList := range dbParticipants {
|
||
|
|
artists := slice.Map(participantList, func(p participant) model.Participant {
|
||
|
|
return model.Participant{Artist: model.Artist{ID: p.ID, Name: p.Name}, SubRole: p.SubRole}
|
||
|
|
})
|
||
|
|
participants[role] = artists
|
||
|
|
}
|
||
|
|
return participants, nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (r sqlRepository) updateParticipants(itemID string, participants model.Participants) error {
|
||
|
|
ids := participants.AllIDs()
|
||
|
|
sqd := Delete(r.tableName + "_artists").Where(And{Eq{r.tableName + "_id": itemID}, NotEq{"artist_id": ids}})
|
||
|
|
_, err := r.executeSQL(sqd)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
if len(participants) == 0 {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
sqi := Insert(r.tableName+"_artists").
|
||
|
|
Columns(r.tableName+"_id", "artist_id", "role", "sub_role").
|
||
|
|
Suffix(fmt.Sprintf("on conflict (artist_id, %s_id, role, sub_role) do nothing", r.tableName))
|
||
|
|
for role, artists := range participants {
|
||
|
|
for _, artist := range artists {
|
||
|
|
sqi = sqi.Values(itemID, artist.ID, role.String(), artist.SubRole)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
_, err = r.executeSQL(sqi)
|
||
|
|
return err
|
||
|
|
}
|