Use structs lib to map models to DB. Fix #1266
This commit is contained in:
@@ -110,14 +110,11 @@ func (r *albumRepository) Get(id string) (*model.Album, error) {
|
||||
}
|
||||
|
||||
func (r *albumRepository) Put(m *model.Album) error {
|
||||
genres := m.Genres
|
||||
m.Genres = nil
|
||||
defer func() { m.Genres = genres }()
|
||||
_, err := r.put(m.ID, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return r.updateGenres(m.ID, r.tableName, genres)
|
||||
return r.updateGenres(m.ID, r.tableName, m.Genres)
|
||||
}
|
||||
|
||||
func (r *albumRepository) GetAll(options ...model.QueryOptions) (model.Albums, error) {
|
||||
|
||||
@@ -23,8 +23,8 @@ type artistRepository struct {
|
||||
}
|
||||
|
||||
type dbArtist struct {
|
||||
model.Artist
|
||||
SimilarArtists string `json:"similarArtists"`
|
||||
model.Artist `structs:",flatten"`
|
||||
SimilarArtists string `structs:"similar_artists" json:"similarArtists"`
|
||||
}
|
||||
|
||||
func NewArtistRepository(ctx context.Context, o orm.Ormer) model.ArtistRepository {
|
||||
@@ -60,16 +60,13 @@ func (r *artistRepository) Exists(id string) (bool, error) {
|
||||
}
|
||||
|
||||
func (r *artistRepository) Put(a *model.Artist) error {
|
||||
genres := a.Genres
|
||||
a.Genres = nil
|
||||
defer func() { a.Genres = genres }()
|
||||
a.FullText = getFullText(a.Name, a.SortArtistName)
|
||||
dba := r.fromModel(a)
|
||||
_, err := r.put(dba.ID, dba)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return r.updateGenres(a.ID, r.tableName, genres)
|
||||
return r.updateGenres(a.ID, r.tableName, a.Genres)
|
||||
}
|
||||
|
||||
func (r *artistRepository) Get(id string) (*model.Artist, error) {
|
||||
|
||||
+11
-20
@@ -2,38 +2,29 @@ package persistence
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/navidrome/navidrome/consts"
|
||||
"time"
|
||||
|
||||
"github.com/Masterminds/squirrel"
|
||||
"github.com/fatih/structs"
|
||||
"github.com/navidrome/navidrome/consts"
|
||||
"github.com/navidrome/navidrome/log"
|
||||
"github.com/navidrome/navidrome/model"
|
||||
"github.com/navidrome/navidrome/utils"
|
||||
)
|
||||
|
||||
func toSqlArgs(rec interface{}) (map[string]interface{}, error) {
|
||||
// Convert to JSON...
|
||||
b, err := json.Marshal(rec)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// ... then convert to map
|
||||
var m map[string]interface{}
|
||||
err = json.Unmarshal(b, &m)
|
||||
r := make(map[string]interface{}, len(m))
|
||||
for f, v := range m {
|
||||
isAnnotationField := utils.StringInSlice(f, model.AnnotationFields)
|
||||
isBookmarkField := utils.StringInSlice(f, model.BookmarkFields)
|
||||
if !isAnnotationField && !isBookmarkField && v != nil {
|
||||
r[toSnakeCase(f)] = v
|
||||
m := structs.Map(rec)
|
||||
for k, v := range m {
|
||||
if t, ok := v.(time.Time); ok {
|
||||
m[k] = t.Format(time.RFC3339Nano)
|
||||
}
|
||||
if t, ok := v.(*time.Time); ok && t != nil {
|
||||
m[k] = t.Format(time.RFC3339Nano)
|
||||
}
|
||||
}
|
||||
return r, err
|
||||
return m, nil
|
||||
}
|
||||
|
||||
var matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)")
|
||||
|
||||
+11
-16
@@ -26,31 +26,26 @@ var _ = Describe("Helpers", func() {
|
||||
})
|
||||
})
|
||||
Describe("toSqlArgs", func() {
|
||||
type Embed struct{}
|
||||
type Model struct {
|
||||
ID string `json:"id"`
|
||||
AlbumId string `json:"albumId"`
|
||||
PlayCount int `json:"playCount"`
|
||||
CreatedAt *time.Time
|
||||
Embed `structs:"-"`
|
||||
ID string `structs:"id" json:"id"`
|
||||
AlbumId string `structs:"album_id" json:"albumId"`
|
||||
PlayCount int `structs:"play_count" json:"playCount"`
|
||||
UpdatedAt *time.Time `structs:"updated_at"`
|
||||
CreatedAt time.Time `structs:"created_at"`
|
||||
}
|
||||
|
||||
It("returns a map with snake_case keys", func() {
|
||||
now := time.Now()
|
||||
m := &Model{ID: "123", AlbumId: "456", CreatedAt: &now, PlayCount: 2}
|
||||
m := &Model{ID: "123", AlbumId: "456", CreatedAt: now, UpdatedAt: &now, PlayCount: 2}
|
||||
args, err := toSqlArgs(m)
|
||||
Expect(err).To(BeNil())
|
||||
Expect(args).To(HaveKeyWithValue("id", "123"))
|
||||
Expect(args).To(HaveKeyWithValue("album_id", "456"))
|
||||
Expect(args).To(HaveKey("created_at"))
|
||||
Expect(args).To(HaveLen(3))
|
||||
})
|
||||
|
||||
It("remove null fields", func() {
|
||||
m := &Model{ID: "123", AlbumId: "456"}
|
||||
args, err := toSqlArgs(m)
|
||||
Expect(err).To(BeNil())
|
||||
Expect(args).To(HaveKey("id"))
|
||||
Expect(args).To(HaveKey("album_id"))
|
||||
Expect(args).To(HaveLen(2))
|
||||
Expect(args).To(HaveKeyWithValue("updated_at", now.Format(time.RFC3339Nano)))
|
||||
Expect(args).To(HaveKeyWithValue("created_at", now.Format(time.RFC3339Nano)))
|
||||
Expect(args).ToNot(HaveKey("Embed"))
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -51,14 +51,11 @@ func (r *mediaFileRepository) Exists(id string) (bool, error) {
|
||||
func (r *mediaFileRepository) Put(m *model.MediaFile) error {
|
||||
m.FullText = getFullText(m.Title, m.Album, m.Artist, m.AlbumArtist,
|
||||
m.SortTitle, m.SortAlbumName, m.SortArtistName, m.SortAlbumArtistName, m.DiscSubtitle)
|
||||
genres := m.Genres
|
||||
m.Genres = nil
|
||||
defer func() { m.Genres = genres }()
|
||||
_, err := r.put(m.ID, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return r.updateGenres(m.ID, r.tableName, genres)
|
||||
return r.updateGenres(m.ID, r.tableName, m.Genres)
|
||||
}
|
||||
|
||||
func (r *mediaFileRepository) selectMediaFile(options ...model.QueryOptions) SelectBuilder {
|
||||
|
||||
@@ -25,14 +25,14 @@ func NewPlayQueueRepository(ctx context.Context, o orm.Ormer) model.PlayQueueRep
|
||||
}
|
||||
|
||||
type playQueue struct {
|
||||
ID string `orm:"column(id)"`
|
||||
UserID string `orm:"column(user_id)"`
|
||||
Current string
|
||||
Position int64
|
||||
ChangedBy string
|
||||
Items string
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
ID string `structs:"id" orm:"column(id)"`
|
||||
UserID string `structs:"user_id" orm:"column(user_id)"`
|
||||
Current string `structs:"current"`
|
||||
Position int64 `structs:"position"`
|
||||
ChangedBy string `structs:"changed_by"`
|
||||
Items string `structs:"items"`
|
||||
CreatedAt time.Time `structs:"created_at"`
|
||||
UpdatedAt time.Time `structs:"updated_at"`
|
||||
}
|
||||
|
||||
func (r *playQueueRepository) Store(q *model.PlayQueue) error {
|
||||
|
||||
Reference in New Issue
Block a user