diff --git a/go.sum b/go.sum index 300755d60..627a31aa1 100644 --- a/go.sum +++ b/go.sum @@ -148,6 +148,7 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384 h1:TFlARGu6Czu1z7q93HTxcP1P+/ZFC/IKythI5RzrnRg= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b h1:NVD8gBK33xpdqCaZVVtd6OFJp+3dxkXuz7+U7KaVN6s= golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/persistence/db_sql/index_repository.go b/persistence/db_sql/index_repository.go new file mode 100644 index 000000000..f4b343dee --- /dev/null +++ b/persistence/db_sql/index_repository.go @@ -0,0 +1,113 @@ +package db_sql + +import ( + "sort" + + "github.com/astaxie/beego/orm" + "github.com/cloudsonic/sonic-server/domain" +) + +type ArtistInfo struct { + ID int `orm:"pk;auto;column(id)"` + Idx string + ArtistID string `orm:"column(artist_id)"` + Artist string + AlbumCount int +} + +type artistIndexRepository struct { + sqlRepository +} + +func NewArtistIndexRepository() domain.ArtistIndexRepository { + r := &artistIndexRepository{} + r.entityName = "artist_info" + return r +} + +func (r *artistIndexRepository) CountAll() (int64, error) { + count := struct{ Count int64 }{} + err := Db().Raw("select count(distinct(idx)) as count from artist_info").QueryRow(&count) + if err != nil { + return 0, err + } + return count.Count, nil +} + +func (r *artistIndexRepository) Put(idx *domain.ArtistIndex) error { + return WithTx(func(o orm.Ormer) error { + _, err := r.newQuery(o).Filter("idx", idx.ID).Delete() + if err != nil { + return err + } + for _, artist := range idx.Artists { + a := ArtistInfo{ + Idx: idx.ID, + ArtistID: artist.ArtistID, + Artist: artist.Artist, + AlbumCount: artist.AlbumCount, + } + _, err := o.Insert(&a) + if err != nil { + return err + } + } + return nil + }) +} + +func (r *artistIndexRepository) Get(id string) (*domain.ArtistIndex, error) { + var ais []ArtistInfo + _, err := r.newQuery(Db()).Filter("idx", id).All(&ais) + if err != nil { + return nil, err + } + + idx := &domain.ArtistIndex{ID: id} + idx.Artists = make([]domain.ArtistInfo, len(ais)) + for i, a := range ais { + idx.Artists[i] = domain.ArtistInfo{ + ArtistID: a.ArtistID, + Artist: a.Artist, + AlbumCount: a.AlbumCount, + } + } + return idx, err +} + +func (r *artistIndexRepository) GetAll() (domain.ArtistIndexes, error) { + var all []ArtistInfo + _, err := r.newQuery(Db()).OrderBy("idx", "artist").All(&all) + if err != nil { + return nil, err + } + + fullIdx := make(map[string]*domain.ArtistIndex) + for _, a := range all { + idx, ok := fullIdx[a.Idx] + if !ok { + idx = &domain.ArtistIndex{ID: a.Idx} + fullIdx[a.Idx] = idx + } + idx.Artists = append(idx.Artists, domain.ArtistInfo{ + ArtistID: a.ArtistID, + Artist: a.Artist, + AlbumCount: a.AlbumCount, + }) + } + var result domain.ArtistIndexes + for _, idx := range fullIdx { + result = append(result, *idx) + } + sort.Slice(result, func(i, j int) bool { + return result[i].ID < result[j].ID + }) + return result, nil +} + +func (r *artistIndexRepository) DeleteAll() error { + _, err := r.newQuery(Db()).Exclude("idx", ".PHONY").Delete() + return err +} + +var _ domain.ArtistIndexRepository = (*artistIndexRepository)(nil) diff --git a/persistence/db_sql/index_repository_test.go b/persistence/db_sql/index_repository_test.go new file mode 100644 index 000000000..26cddeb96 --- /dev/null +++ b/persistence/db_sql/index_repository_test.go @@ -0,0 +1,45 @@ +package db_sql + +import ( + "github.com/cloudsonic/sonic-server/domain" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Artist Index", func() { + var repo domain.ArtistIndexRepository + + BeforeEach(func() { + repo = NewArtistIndexRepository() + err := repo.DeleteAll() + if err != nil { + panic(err) + } + }) + + It("successfully persists data", func() { + idx1 := domain.ArtistIndex{ + ID: "D", + Artists: domain.ArtistInfos{ + {ArtistID: "4", Artist: "Doobie Brothers", AlbumCount: 2}, + {ArtistID: "3", Artist: "The Doors", AlbumCount: 5}, + }, + } + idx2 := domain.ArtistIndex{ + ID: "S", + Artists: domain.ArtistInfos{ + {ArtistID: "1", Artist: "Saara Saara", AlbumCount: 3}, + {ArtistID: "2", Artist: "Seu Jorge", AlbumCount: 1}, + }, + } + + Expect(repo.Put(&idx1)).To(BeNil()) + Expect(repo.Put(&idx2)).To(BeNil()) + Expect(repo.Get("D")).To(Equal(&idx1)) + Expect(repo.Get("S")).To(Equal(&idx2)) + Expect(repo.GetAll()).To(Equal(domain.ArtistIndexes{idx1, idx2})) + Expect(repo.CountAll()).To(Equal(int64(2))) + Expect(repo.DeleteAll()).To(BeNil()) + Expect(repo.CountAll()).To(Equal(int64(0))) + }) +}) diff --git a/persistence/db_sql/sql.go b/persistence/db_sql/sql.go index 1990331ec..4beddbbd6 100644 --- a/persistence/db_sql/sql.go +++ b/persistence/db_sql/sql.go @@ -57,6 +57,7 @@ func initORM(dbPath string) error { orm.RegisterModel(new(Artist)) orm.RegisterModel(new(Album)) orm.RegisterModel(new(MediaFile)) + orm.RegisterModel(new(ArtistInfo)) orm.RegisterModel(new(CheckSums)) err := orm.RegisterDataBase("default", "sqlite3", dbPath) if err != nil { diff --git a/persistence/db_sql/wire_provider.go b/persistence/db_sql/wire_provider.go index 3868bf1bb..8312fa4a8 100644 --- a/persistence/db_sql/wire_provider.go +++ b/persistence/db_sql/wire_provider.go @@ -10,10 +10,10 @@ var Set = wire.NewSet( NewArtistRepository, NewMediaFileRepository, NewAlbumRepository, + NewArtistIndexRepository, + NewCheckSumRepository, db_ledis.NewPropertyRepository, - db_ledis.NewArtistIndexRepository, db_ledis.NewPlaylistRepository, - db_ledis.NewCheckSumRepository, persistence.NewNowPlayingRepository, persistence.NewMediaFolderRepository, wire.Value(persistence.ProviderIdentifier("sql")), diff --git a/wire_gen.go b/wire_gen.go index 20bc7a61f..ba0b7663a 100644 --- a/wire_gen.go +++ b/wire_gen.go @@ -65,8 +65,8 @@ func CreateSubsonicAPIRouter(p persistence.ProviderIdentifier) *api.Router { func createSQLProvider() *Provider { albumRepository := db_sql.NewAlbumRepository() artistRepository := db_sql.NewArtistRepository() - checkSumRepository := db_ledis.NewCheckSumRepository() - artistIndexRepository := db_ledis.NewArtistIndexRepository() + checkSumRepository := db_sql.NewCheckSumRepository() + artistIndexRepository := db_sql.NewArtistIndexRepository() mediaFileRepository := db_sql.NewMediaFileRepository() mediaFolderRepository := persistence.NewMediaFolderRepository() nowPlayingRepository := persistence.NewNowPlayingRepository()