Skip to content

Commit

Permalink
Implement the playlists functionality
Browse files Browse the repository at this point in the history
For now they are exposed only through the Subsonic API. Creating the
Euterpe API endpoints will come shortly.
  • Loading branch information
ironsmile committed Oct 13, 2024
1 parent 6de0f0f commit ee6f390
Show file tree
Hide file tree
Showing 22 changed files with 1,582 additions and 25 deletions.
10 changes: 9 additions & 1 deletion sqls/migrations/010_playlists.sql
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,21 @@ CREATE TABLE IF NOT EXISTS `playlists` (
CREATE TABLE IF NOT EXISTS `playlists_tracks` (
`playlist_id` integer not null,
`track_id` integer not null,
`order` integer not null default 0,
`index` integer not null default 0,
FOREIGN KEY(playlist_id) REFERENCES playlists(id) ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY(track_id) REFERENCES tracks(id) ON UPDATE CASCADE ON DELETE CASCADE
);

CREATE TABLE IF NOT EXISTS `playlists_images` (
`playlist_id` integer unique not null,
`image` blob not null,
`updated_at` integer not null,
FOREIGN KEY(playlist_id) REFERENCES playlists(id) ON UPDATE CASCADE ON DELETE CASCADE
);

create unique index if not exists playlist_pairs on `playlists_tracks` ('playlist_id', `track_id`);

-- +migrate Down
drop table if exists `playlists`;
drop table if exists `playlists_tracks`;
drop table if exists `playlists_images`;
4 changes: 2 additions & 2 deletions src/library/local_browse.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,15 +377,15 @@ func (lib *LocalLibrary) BrowseTracks(args BrowseArgs) ([]TrackInfo, int) {
log.Printf("Query for getting tracks count not successful: %s\n", err)
}

rows, err := queryTracks(ctx, db, where, orderBy, queryArgs)
rows, err := QueryTracks(ctx, db, where, orderBy, queryArgs)
if err != nil {
log.Printf("Query for browsing songs not successful: %s\n", err.Error())
return nil
}

defer rows.Close()
for rows.Next() {
res, err := scanTrack(rows)
res, err := ScanTrack(rows)
if err != nil {
log.Printf("Error scanning search result: %s\n", err)
continue
Expand Down
8 changes: 4 additions & 4 deletions src/library/local_database_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"strings"
)

// queryTracks executes a database query for tracks and returns the result. The query
// QueryTracks executes a database query for tracks and returns the result. The query
// is written with the appropriate JOIN and following aliases are available:
//
// * `t` - the tracks table
Expand All @@ -26,7 +26,7 @@ import (
// - queryArgs - arguments to be used in the db.QueryContext call. If the two
// named arguments "offset" and "count", created with sql.Named(...) are set
// then the they will be used with LIMIT for the query.
func queryTracks(
func QueryTracks(
ctx context.Context,
db *sql.DB,
where []string,
Expand Down Expand Up @@ -68,8 +68,8 @@ func queryTracks(
)
}

// scanTrack scans a database row returned by `queryTracks` into a TrackInfo.
func scanTrack(rows scanner) (TrackInfo, error) {
// ScanTrack scans a database row returned by `queryTracks` into a TrackInfo.
func ScanTrack(rows scanner) (TrackInfo, error) {
var (
res TrackInfo

Expand Down
10 changes: 5 additions & 5 deletions src/library/local_library.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,15 @@ func (lib *LocalLibrary) Search(ctx context.Context, args SearchArgs) []SearchRe
sql.Named("count", limitCount),
}

rows, err := queryTracks(ctx, db, where, orderBy, queryArgs)
rows, err := QueryTracks(ctx, db, where, orderBy, queryArgs)
if err != nil {
log.Printf("Search query not successful: %s\n", err.Error())
return nil
}

defer rows.Close()
for rows.Next() {
res, err := scanTrack(rows)
res, err := ScanTrack(rows)
if err != nil {
log.Printf("Error scanning search result: %s\n", err)
continue
Expand Down Expand Up @@ -432,15 +432,15 @@ func (lib *LocalLibrary) GetAlbumFiles(ctx context.Context, albumID int64) []Tra
queryArgs = []any{sql.Named("albumID", albumID)}
)
work := func(db *sql.DB) error {
rows, err := queryTracks(ctx, db, where, orderBy, queryArgs)
rows, err := QueryTracks(ctx, db, where, orderBy, queryArgs)
if err != nil {
log.Printf("Query for getting albym files not successful: %s\n", err.Error())
return nil
}

defer rows.Close()
for rows.Next() {
res, err := scanTrack(rows)
res, err := ScanTrack(rows)
if err != nil {
return fmt.Errorf("scanning error: %w", err)
}
Expand All @@ -467,7 +467,7 @@ func (lib *LocalLibrary) GetTrack(ctx context.Context, trackID int64) (TrackInfo
t.id = ?
`, trackID)

track, err := scanTrack(row)
track, err := ScanTrack(row)
if err != nil && errors.Is(err, sql.ErrNoRows) {
return ErrNotFound
} else if err != nil {
Expand Down
6 changes: 6 additions & 0 deletions src/playlists/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package playlists

//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate

// This file is here just to hold the generate directives so that they are not duplicated
// in many places.
Loading

0 comments on commit ee6f390

Please sign in to comment.