diff --git a/.gitignore b/.gitignore index aa592f7f5..a6faec04b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ Artwork sonic.toml master.zip Jamstash-master +storm.db diff --git a/api/wire_gen.go b/api/wire_gen.go index 966be65ad..82b092972 100644 --- a/api/wire_gen.go +++ b/api/wire_gen.go @@ -9,6 +9,7 @@ import ( "github.com/cloudsonic/sonic-server/engine" "github.com/cloudsonic/sonic-server/itunesbridge" "github.com/cloudsonic/sonic-server/persistence/ledis" + "github.com/cloudsonic/sonic-server/persistence/storm" "github.com/deluan/gomate" ledis2 "github.com/deluan/gomate/ledis" "github.com/google/wire" @@ -22,10 +23,10 @@ func initSystemController() *SystemController { } func initBrowsingController() *BrowsingController { - propertyRepository := ledis.NewPropertyRepository() + propertyRepository := storm.NewPropertyRepository() mediaFolderRepository := ledis.NewMediaFolderRepository() artistIndexRepository := ledis.NewArtistIndexRepository() - artistRepository := ledis.NewArtistRepository() + artistRepository := storm.NewArtistRepository() albumRepository := ledis.NewAlbumRepository() mediaFileRepository := ledis.NewMediaFileRepository() browser := engine.NewBrowser(propertyRepository, mediaFolderRepository, artistIndexRepository, artistRepository, albumRepository, mediaFileRepository) @@ -48,7 +49,7 @@ func initMediaAnnotationController() *MediaAnnotationController { nowPlayingRepository := ledis.NewNowPlayingRepository() scrobbler := engine.NewScrobbler(itunesControl, mediaFileRepository, nowPlayingRepository) albumRepository := ledis.NewAlbumRepository() - artistRepository := ledis.NewArtistRepository() + artistRepository := storm.NewArtistRepository() ratings := engine.NewRatings(itunesControl, mediaFileRepository, albumRepository, artistRepository) mediaAnnotationController := NewMediaAnnotationController(scrobbler, ratings) return mediaAnnotationController @@ -64,7 +65,7 @@ func initPlaylistsController() *PlaylistsController { } func initSearchingController() *SearchingController { - artistRepository := ledis.NewArtistRepository() + artistRepository := storm.NewArtistRepository() albumRepository := ledis.NewAlbumRepository() mediaFileRepository := ledis.NewMediaFileRepository() db := newDB() @@ -94,7 +95,7 @@ func initStreamController() *StreamController { // wire_injectors.go: -var allProviders = wire.NewSet(itunesbridge.NewItunesControl, ledis.Set, engine.Set, NewSystemController, +var allProviders = wire.NewSet(itunesbridge.NewItunesControl, ledis.Set, storm.Set, engine.Set, NewSystemController, NewBrowsingController, NewAlbumListController, NewMediaAnnotationController, diff --git a/api/wire_injectors.go b/api/wire_injectors.go index 80beee0fd..e2ae4e19e 100644 --- a/api/wire_injectors.go +++ b/api/wire_injectors.go @@ -6,6 +6,7 @@ import ( "github.com/cloudsonic/sonic-server/engine" "github.com/cloudsonic/sonic-server/itunesbridge" ledis2 "github.com/cloudsonic/sonic-server/persistence/ledis" + "github.com/cloudsonic/sonic-server/persistence/storm" "github.com/deluan/gomate" "github.com/deluan/gomate/ledis" "github.com/google/wire" @@ -14,6 +15,7 @@ import ( var allProviders = wire.NewSet( itunesbridge.NewItunesControl, ledis2.Set, + storm.Set, engine.Set, NewSystemController, NewBrowsingController, diff --git a/persistence/ledis/wire_providers.go b/persistence/ledis/wire_providers.go index 7cbf5e17b..4cf7a5999 100644 --- a/persistence/ledis/wire_providers.go +++ b/persistence/ledis/wire_providers.go @@ -4,12 +4,10 @@ import "github.com/google/wire" var Set = wire.NewSet( NewAlbumRepository, - NewArtistRepository, NewCheckSumRepository, NewArtistIndexRepository, NewMediaFileRepository, NewMediaFolderRepository, NewNowPlayingRepository, NewPlaylistRepository, - NewPropertyRepository, ) diff --git a/persistence/storm/artist_repository_test.go b/persistence/storm/artist_repository_test.go index 88800023b..c6f0843dd 100644 --- a/persistence/storm/artist_repository_test.go +++ b/persistence/storm/artist_repository_test.go @@ -10,6 +10,7 @@ var _ = Describe("ArtistRepository", func() { var repo domain.ArtistRepository BeforeEach(func() { + Db().Drop(&_Artist{}) repo = NewArtistRepository() }) @@ -24,18 +25,29 @@ var _ = Describe("ArtistRepository", func() { Expect(repo.Get("1")).To(Equal(artist)) }) - It("purges inactive records", func() { - data := domain.Artists{ - {ID: "1", Name: "Saara Saara"}, - {ID: "2", Name: "Kraftwerk"}, - {ID: "3", Name: "The Beatles"}, - } - active := domain.Artists{ - {ID: "1"}, {ID: "3"}, - } - for _, a := range data { - repo.Put(&a) - } - Expect(repo.PurgeInactive(active)).To(Equal([]string{"2"})) + Describe("PurgeInactive", func() { + var data domain.Artists + + BeforeEach(func() { + data = domain.Artists{ + {ID: "1", Name: "Saara Saara"}, + {ID: "2", Name: "Kraftwerk"}, + {ID: "3", Name: "The Beatles"}, + } + for _, a := range data { + repo.Put(&a) + } + }) + + It("purges inactive records", func() { + active := domain.Artists{{ID: "1"}, {ID: "3"}} + Expect(repo.PurgeInactive(active)).To(Equal([]string{"2"})) + }) + + It("doesn't delete anything if all is active", func() { + active := domain.Artists{{ID: "1"}, {ID: "2"}, {ID: "3"}} + Expect(repo.PurgeInactive(active)).To(BeEmpty()) + }) }) + }) diff --git a/persistence/storm/property_repository.go b/persistence/storm/property_repository.go index d0186061b..5d90c1178 100644 --- a/persistence/storm/property_repository.go +++ b/persistence/storm/property_repository.go @@ -1,6 +1,7 @@ package storm import ( + "github.com/asdine/storm" "github.com/cloudsonic/sonic-server/domain" ) @@ -25,7 +26,14 @@ func (r *propertyRepository) Get(id string) (string, error) { } func (r *propertyRepository) DefaultGet(id string, defaultValue string) (string, error) { - return defaultValue, nil + value, err := r.Get(id) + if err == storm.ErrNotFound { + return defaultValue, nil + } + if err != nil { + return defaultValue, err + } + return value, nil } var _ domain.PropertyRepository = (*propertyRepository)(nil) diff --git a/persistence/storm/property_repository_test.go b/persistence/storm/property_repository_test.go new file mode 100644 index 000000000..248158a3e --- /dev/null +++ b/persistence/storm/property_repository_test.go @@ -0,0 +1,30 @@ +package storm + +import ( + "github.com/cloudsonic/sonic-server/domain" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("PropertyRepository", func() { + var repo domain.PropertyRepository + + BeforeEach(func() { + Db().Drop(propertyBucket) + repo = NewPropertyRepository() + }) + + It("saves and retrieves data", func() { + Expect(repo.Put("1", "test")).To(BeNil()) + Expect(repo.Get("1")).To(Equal("test")) + }) + + It("returns default if data is not found", func() { + Expect(repo.DefaultGet("2", "default")).To(Equal("default")) + }) + + It("returns value if found", func() { + Expect(repo.Put("3", "test")).To(BeNil()) + Expect(repo.DefaultGet("3", "default")).To(Equal("test")) + }) +}) diff --git a/persistence/storm/storm_repository.go b/persistence/storm/storm_repository.go index 0b1cab68b..26e3a97c2 100644 --- a/persistence/storm/storm_repository.go +++ b/persistence/storm/storm_repository.go @@ -34,12 +34,18 @@ func (r *stormRepository) Exists(id string) (bool, error) { return err != storm.ErrNotFound, nil } +func (r *stormRepository) getID(record interface{}) string { + v := reflect.ValueOf(record).Elem() + id := v.FieldByName("ID").String() + return id +} + func (r *stormRepository) purgeInactive(ids []string) (deleted []string, err error) { query := Db().Select(q.Not(q.In("ID", ids))) + // Collect IDs that will be deleted err = query.Each(r.bucket, func(record interface{}) error { - v := reflect.ValueOf(record).Elem() - id := v.FieldByName("ID").String() + id := r.getID(record) deleted = append(deleted, id) return nil }) @@ -47,6 +53,10 @@ func (r *stormRepository) purgeInactive(ids []string) (deleted []string, err err return nil, err } + if len(deleted) == 0 { + return + } + err = query.Delete(r.bucket) if err != nil { return nil, err diff --git a/scanner/importer.go b/scanner/importer.go index 6f79be537..f3d263402 100644 --- a/scanner/importer.go +++ b/scanner/importer.go @@ -144,7 +144,7 @@ func (i *Importer) importLibrary() (err error) { i.search.RemoveAlbum(deleted...) } if deleted, err := i.artistRepo.PurgeInactive(ars); err != nil { - log.Error(err) + log.Error("Deleting inactive artists", err) } else { i.search.RemoveArtist(deleted...) } diff --git a/wire_gen.go b/wire_gen.go index 65074ec93..4a7818ee2 100644 --- a/wire_gen.go +++ b/wire_gen.go @@ -9,6 +9,7 @@ import ( "github.com/cloudsonic/sonic-server/engine" "github.com/cloudsonic/sonic-server/itunesbridge" "github.com/cloudsonic/sonic-server/persistence/ledis" + "github.com/cloudsonic/sonic-server/persistence/storm" "github.com/cloudsonic/sonic-server/scanner" "github.com/deluan/gomate" ledis2 "github.com/deluan/gomate/ledis" @@ -22,10 +23,10 @@ func initImporter(musicFolder string) *scanner.Importer { itunesScanner := scanner.NewItunesScanner(checkSumRepository) mediaFileRepository := ledis.NewMediaFileRepository() albumRepository := ledis.NewAlbumRepository() - artistRepository := ledis.NewArtistRepository() + artistRepository := storm.NewArtistRepository() artistIndexRepository := ledis.NewArtistIndexRepository() playlistRepository := ledis.NewPlaylistRepository() - propertyRepository := ledis.NewPropertyRepository() + propertyRepository := storm.NewPropertyRepository() db := newDB() search := engine.NewSearch(artistRepository, albumRepository, mediaFileRepository, db) importer := scanner.NewImporter(musicFolder, itunesScanner, mediaFileRepository, albumRepository, artistRepository, artistIndexRepository, playlistRepository, propertyRepository, search) @@ -34,7 +35,7 @@ func initImporter(musicFolder string) *scanner.Importer { // wire_injectors.go: -var allProviders = wire.NewSet(itunesbridge.NewItunesControl, ledis.Set, engine.Set, scanner.Set, newDB) +var allProviders = wire.NewSet(itunesbridge.NewItunesControl, ledis.Set, storm.Set, engine.Set, scanner.Set, newDB) func newDB() gomate.DB { return ledis2.NewEmbeddedDB(ledis.Db()) diff --git a/wire_injectors.go b/wire_injectors.go index 2887d4569..c3df0ccb5 100644 --- a/wire_injectors.go +++ b/wire_injectors.go @@ -6,6 +6,7 @@ import ( "github.com/cloudsonic/sonic-server/engine" "github.com/cloudsonic/sonic-server/itunesbridge" ledis2 "github.com/cloudsonic/sonic-server/persistence/ledis" + "github.com/cloudsonic/sonic-server/persistence/storm" "github.com/cloudsonic/sonic-server/scanner" "github.com/deluan/gomate" "github.com/deluan/gomate/ledis" @@ -15,6 +16,7 @@ import ( var allProviders = wire.NewSet( itunesbridge.NewItunesControl, ledis2.Set, + storm.Set, engine.Set, scanner.Set, newDB,