SQL/Orm AlbumRepository complete
This commit is contained in:
@@ -0,0 +1,102 @@
|
|||||||
|
package db_sql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/astaxie/beego/orm"
|
||||||
|
"github.com/cloudsonic/sonic-server/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Album struct {
|
||||||
|
ID string `orm:"pk;column(id)"`
|
||||||
|
Name string `orm:"index"`
|
||||||
|
ArtistID string `orm:"column(artist_id);index"`
|
||||||
|
CoverArtPath string ``
|
||||||
|
CoverArtId string ``
|
||||||
|
Artist string `orm:"index"`
|
||||||
|
AlbumArtist string ``
|
||||||
|
Year int `orm:"index"`
|
||||||
|
Compilation bool ``
|
||||||
|
Starred bool `orm:"index"`
|
||||||
|
PlayCount int `orm:"index"`
|
||||||
|
PlayDate time.Time `orm:"null;index"`
|
||||||
|
SongCount int ``
|
||||||
|
Duration int ``
|
||||||
|
Rating int `orm:"index"`
|
||||||
|
Genre string ``
|
||||||
|
StarredAt time.Time `orm:"null"`
|
||||||
|
CreatedAt time.Time `orm:"null"`
|
||||||
|
UpdatedAt time.Time `orm:"null"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type albumRepository struct {
|
||||||
|
sqlRepository
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewAlbumRepository() domain.AlbumRepository {
|
||||||
|
r := &albumRepository{}
|
||||||
|
r.entityName = "album"
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *albumRepository) Put(a *domain.Album) error {
|
||||||
|
ta := Album(*a)
|
||||||
|
return r.put(a.ID, &ta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *albumRepository) Get(id string) (*domain.Album, error) {
|
||||||
|
ta := Album{ID: id}
|
||||||
|
err := Db().Read(&ta)
|
||||||
|
if err == orm.ErrNoRows {
|
||||||
|
return nil, domain.ErrNotFound
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
a := domain.Album(ta)
|
||||||
|
return &a, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *albumRepository) FindByArtist(artistId string) (domain.Albums, error) {
|
||||||
|
var albums []Album
|
||||||
|
_, err := r.newQuery(Db()).Filter("artist_id", artistId).OrderBy("year", "name").All(&albums)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return r.toAlbums(albums)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *albumRepository) GetAll(options ...domain.QueryOptions) (domain.Albums, error) {
|
||||||
|
var all []Album
|
||||||
|
_, err := r.newQuery(Db(), options...).All(&all)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return r.toAlbums(all)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *albumRepository) toAlbums(all []Album) (domain.Albums, error) {
|
||||||
|
result := make(domain.Albums, len(all))
|
||||||
|
for i, a := range all {
|
||||||
|
result[i] = domain.Album(a)
|
||||||
|
}
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *albumRepository) PurgeInactive(activeList domain.Albums) ([]string, error) {
|
||||||
|
return r.purgeInactive(activeList, func(item interface{}) string {
|
||||||
|
return item.(domain.Album).ID
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *albumRepository) GetStarred(options ...domain.QueryOptions) (domain.Albums, error) {
|
||||||
|
var starred []Album
|
||||||
|
_, err := r.newQuery(Db(), options...).Filter("starred", true).All(&starred)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return r.toAlbums(starred)
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ domain.AlbumRepository = (*albumRepository)(nil)
|
||||||
|
var _ = domain.Album(Album{})
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package db_sql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/cloudsonic/sonic-server/domain"
|
||||||
|
. "github.com/onsi/ginkgo"
|
||||||
|
. "github.com/onsi/gomega"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = Describe("AlbumRepository", func() {
|
||||||
|
var repo domain.AlbumRepository
|
||||||
|
|
||||||
|
BeforeEach(func() {
|
||||||
|
repo = NewAlbumRepository()
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("GetAll", func() {
|
||||||
|
It("returns all records", func() {
|
||||||
|
Expect(repo.GetAll()).To(Equal(testAlbums))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns all records sorted", func() {
|
||||||
|
Expect(repo.GetAll(domain.QueryOptions{SortBy: "Name"})).To(Equal(domain.Albums{
|
||||||
|
{ID: "2", Name: "Abbey Road", Artist: "The Beatles", ArtistID: "1"},
|
||||||
|
{ID: "3", Name: "Radioactivity", Artist: "Kraftwerk", ArtistID: "2", Starred: true},
|
||||||
|
{ID: "1", Name: "Sgt Peppers", Artist: "The Beatles", ArtistID: "1"},
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns all records sorted desc", func() {
|
||||||
|
Expect(repo.GetAll(domain.QueryOptions{SortBy: "Name", Desc: true})).To(Equal(domain.Albums{
|
||||||
|
{ID: "1", Name: "Sgt Peppers", Artist: "The Beatles", ArtistID: "1"},
|
||||||
|
{ID: "3", Name: "Radioactivity", Artist: "Kraftwerk", ArtistID: "2", Starred: true},
|
||||||
|
{ID: "2", Name: "Abbey Road", Artist: "The Beatles", ArtistID: "1"},
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
|
||||||
|
It("paginates the result", func() {
|
||||||
|
Expect(repo.GetAll(domain.QueryOptions{Offset: 1, Size: 1})).To(Equal(domain.Albums{
|
||||||
|
{ID: "2", Name: "Abbey Road", Artist: "The Beatles", ArtistID: "1"},
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("GetAllIds", func() {
|
||||||
|
It("returns all records", func() {
|
||||||
|
Expect(repo.GetAllIds()).To(Equal([]string{"1", "2", "3"}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("GetStarred", func() {
|
||||||
|
It("returns all starred records", func() {
|
||||||
|
Expect(repo.GetStarred(domain.QueryOptions{})).To(Equal(domain.Albums{
|
||||||
|
{ID: "3", Name: "Radioactivity", Artist: "Kraftwerk", ArtistID: "2", Starred: true},
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
Describe("FindByArtist", func() {
|
||||||
|
It("returns all records from a given ArtistID", func() {
|
||||||
|
Expect(repo.FindByArtist("1")).To(Equal(domain.Albums{
|
||||||
|
{ID: "2", Name: "Abbey Road", Artist: "The Beatles", ArtistID: "1"},
|
||||||
|
{ID: "1", Name: "Sgt Peppers", Artist: "The Beatles", ArtistID: "1"},
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
@@ -27,7 +27,7 @@ var _ = Describe("ArtistRepository", func() {
|
|||||||
Expect(err).To(MatchError(domain.ErrNotFound))
|
Expect(err).To(MatchError(domain.ErrNotFound))
|
||||||
})
|
})
|
||||||
|
|
||||||
FDescribe("PurgeInactive", func() {
|
Describe("PurgeInactive", func() {
|
||||||
BeforeEach(func() {
|
BeforeEach(func() {
|
||||||
for _, a := range testArtists {
|
for _, a := range testArtists {
|
||||||
repo.Put(&a)
|
repo.Put(&a)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
|
|
||||||
"github.com/astaxie/beego/orm"
|
"github.com/astaxie/beego/orm"
|
||||||
"github.com/cloudsonic/sonic-server/domain"
|
"github.com/cloudsonic/sonic-server/domain"
|
||||||
"github.com/cloudsonic/sonic-server/persistence"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type MediaFile struct {
|
type MediaFile struct {
|
||||||
@@ -90,21 +89,6 @@ func (r *mediaFileRepository) GetStarred(options ...domain.QueryOptions) (domain
|
|||||||
return r.toMediaFiles(starred)
|
return r.toMediaFiles(starred)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *mediaFileRepository) GetAllIds() ([]string, error) {
|
|
||||||
qs := r.newQuery(Db())
|
|
||||||
var values []orm.Params
|
|
||||||
num, err := qs.Values(&values, "id")
|
|
||||||
if num == 0 {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
result := persistence.CollectValue(values, func(item interface{}) string {
|
|
||||||
return item.(orm.Params)["ID"].(string)
|
|
||||||
})
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *mediaFileRepository) PurgeInactive(activeList domain.MediaFiles) ([]string, error) {
|
func (r *mediaFileRepository) PurgeInactive(activeList domain.MediaFiles) ([]string, error) {
|
||||||
return r.purgeInactive(activeList, func(item interface{}) string {
|
return r.purgeInactive(activeList, func(item interface{}) string {
|
||||||
return item.(domain.MediaFile).ID
|
return item.(domain.MediaFile).ID
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ func WithTx(block func(orm.Ormer) error) error {
|
|||||||
func initORM(dbPath string) error {
|
func initORM(dbPath string) error {
|
||||||
orm.Debug = true
|
orm.Debug = true
|
||||||
orm.RegisterModel(new(Artist))
|
orm.RegisterModel(new(Artist))
|
||||||
|
orm.RegisterModel(new(Album))
|
||||||
orm.RegisterModel(new(MediaFile))
|
orm.RegisterModel(new(MediaFile))
|
||||||
err := orm.RegisterDataBase("default", "sqlite3", dbPath)
|
err := orm.RegisterDataBase("default", "sqlite3", dbPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -38,6 +38,22 @@ func (r *sqlRepository) Exists(id string) (bool, error) {
|
|||||||
return c == 1, err
|
return c == 1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO This is used to generate random lists. Can be optimized in SQL: https://stackoverflow.com/a/19419
|
||||||
|
func (r *sqlRepository) GetAllIds() ([]string, error) {
|
||||||
|
qs := r.newQuery(Db())
|
||||||
|
var values []orm.Params
|
||||||
|
num, err := qs.Values(&values, "id")
|
||||||
|
if num == 0 {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result := persistence.CollectValue(values, func(item interface{}) string {
|
||||||
|
return item.(orm.Params)["ID"].(string)
|
||||||
|
})
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *sqlRepository) put(id string, a interface{}) error {
|
func (r *sqlRepository) put(id string, a interface{}) error {
|
||||||
return WithTx(func(o orm.Ormer) error {
|
return WithTx(func(o orm.Ormer) error {
|
||||||
c, err := r.newQuery(o).Filter("id", id).Count()
|
c, err := r.newQuery(o).Filter("id", id).Count()
|
||||||
|
|||||||
@@ -38,5 +38,12 @@ var _ = Describe("Initialize test DB", func() {
|
|||||||
for _, a := range testArtists {
|
for _, a := range testArtists {
|
||||||
artistRepo.Put(&a)
|
artistRepo.Put(&a)
|
||||||
}
|
}
|
||||||
|
albumRepository := NewAlbumRepository()
|
||||||
|
for _, a := range testAlbums {
|
||||||
|
err := albumRepository.Put(&a)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import (
|
|||||||
var Set = wire.NewSet(
|
var Set = wire.NewSet(
|
||||||
NewArtistRepository,
|
NewArtistRepository,
|
||||||
NewMediaFileRepository,
|
NewMediaFileRepository,
|
||||||
|
NewAlbumRepository,
|
||||||
db_ledis.NewPropertyRepository,
|
db_ledis.NewPropertyRepository,
|
||||||
db_ledis.NewAlbumRepository,
|
|
||||||
db_ledis.NewArtistIndexRepository,
|
db_ledis.NewArtistIndexRepository,
|
||||||
db_ledis.NewPlaylistRepository,
|
db_ledis.NewPlaylistRepository,
|
||||||
db_ledis.NewCheckSumRepository,
|
db_ledis.NewCheckSumRepository,
|
||||||
|
|||||||
+1
-1
@@ -63,7 +63,7 @@ func CreateSubsonicAPIRouter(p persistence.ProviderIdentifier) *api.Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createSQLProvider() *Provider {
|
func createSQLProvider() *Provider {
|
||||||
albumRepository := db_ledis.NewAlbumRepository()
|
albumRepository := db_sql.NewAlbumRepository()
|
||||||
artistRepository := db_sql.NewArtistRepository()
|
artistRepository := db_sql.NewArtistRepository()
|
||||||
checkSumRepository := db_ledis.NewCheckSumRepository()
|
checkSumRepository := db_ledis.NewCheckSumRepository()
|
||||||
artistIndexRepository := db_ledis.NewArtistIndexRepository()
|
artistIndexRepository := db_ledis.NewArtistIndexRepository()
|
||||||
|
|||||||
Reference in New Issue
Block a user