add total_duration column to library and update user_library table

Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Deluan 2025-06-14 20:57:00 -04:00
commit b93a753b9f
4 changed files with 20 additions and 17 deletions

View file

@ -12,8 +12,8 @@ func init() {
}
func upAddUserLibraryTable(ctx context.Context, tx *sql.Tx) error {
// Create user_library association table
_, err := tx.ExecContext(ctx, `
-- Create user_library association table
CREATE TABLE user_library (
user_id VARCHAR(255) NOT NULL,
library_id INTEGER NOT NULL,
@ -21,26 +21,21 @@ func upAddUserLibraryTable(ctx context.Context, tx *sql.Tx) error {
FOREIGN KEY (user_id) REFERENCES user(id) ON DELETE CASCADE,
FOREIGN KEY (library_id) REFERENCES library(id) ON DELETE CASCADE
);
`)
if err != nil {
return err
}
// Create indexes for performance
_, err = tx.ExecContext(ctx, `
-- Create indexes for performance
CREATE INDEX idx_user_library_user_id ON user_library(user_id);
CREATE INDEX idx_user_library_library_id ON user_library(library_id);
`)
if err != nil {
return err
}
// Populate with existing users having access to library ID 1 (existing setup)
// Admin users get access to all libraries, regular users get access to library 1
_, err = tx.ExecContext(ctx, `
-- Populate with existing users having access to library ID 1 (existing setup)
-- Admin users get access to all libraries, regular users get access to library 1
INSERT INTO user_library (user_id, library_id)
SELECT u.id, 1
FROM user u;
-- Add total_duration column to library table
ALTER TABLE library ADD COLUMN total_duration INTEGER DEFAULT 0;
UPDATE library SET total_duration = (
SELECT IFNULL(SUM(duration),0) from album where album.library_id = library.id and missing = 0
);
`)
return err
@ -51,6 +46,7 @@ func downAddUserLibraryTable(ctx context.Context, tx *sql.Tx) error {
DROP INDEX IF EXISTS idx_user_library_library_id;
DROP INDEX IF EXISTS idx_user_library_user_id;
DROP TABLE IF EXISTS user_library;
ALTER TABLE library DROP COLUMN IF EXISTS total_duration;
`)
return err
}

View file

@ -21,6 +21,7 @@ type Library struct {
TotalFiles int `json:"totalFiles"`
TotalMissingFiles int `json:"totalMissingFiles"`
TotalSize int64 `json:"totalSize"`
TotalDuration int `json:"totalDuration"`
}
type Libraries []Library

View file

@ -167,7 +167,7 @@ func (r *libraryRepository) ScanInProgress() (bool, error) {
func (r *libraryRepository) RefreshStats(id int) error {
var songsRes, albumsRes, artistsRes, foldersRes, filesRes, missingRes struct{ Count int64 }
var sizeRes struct{ Sum int64 }
var sizeRes, durationRes struct{ Sum int64 }
err := run.Parallel(
func() error {
@ -198,6 +198,9 @@ func (r *libraryRepository) RefreshStats(id int) error {
func() error {
return r.queryOne(Select("ifnull(sum(size),0) as sum").From("album").Where(Eq{"library_id": id, "missing": false}), &sizeRes)
},
func() error {
return r.queryOne(Select("ifnull(sum(duration),0) as sum").From("album").Where(Eq{"library_id": id, "missing": false}), &durationRes)
},
)()
if err != nil {
return err
@ -211,6 +214,7 @@ func (r *libraryRepository) RefreshStats(id int) error {
Set("total_files", filesRes.Count).
Set("total_missing_files", missingRes.Count).
Set("total_size", sizeRes.Sum).
Set("total_duration", durationRes.Sum).
Set("updated_at", time.Now()).
Where(Eq{"id": id})
_, err = r.executeSQL(sq)

View file

@ -31,7 +31,7 @@ var _ = Describe("LibraryRepository", func() {
Expect(libAfter.UpdatedAt).To(BeTemporally(">", libBefore.UpdatedAt))
var songsRes, albumsRes, artistsRes, foldersRes, filesRes, missingRes struct{ Count int64 }
var sizeRes struct{ Sum int64 }
var sizeRes, durationRes struct{ Sum int64 }
Expect(conn.NewQuery("select count(*) as count from media_file where library_id = {:id} and missing = 0").Bind(dbx.Params{"id": 1}).One(&songsRes)).To(Succeed())
Expect(conn.NewQuery("select count(*) as count from album where library_id = {:id} and missing = 0").Bind(dbx.Params{"id": 1}).One(&albumsRes)).To(Succeed())
@ -40,6 +40,7 @@ var _ = Describe("LibraryRepository", func() {
Expect(conn.NewQuery("select ifnull(sum(num_audio_files + num_playlists + json_array_length(image_files)),0) as count from folder where library_id = {:id} and missing = 0").Bind(dbx.Params{"id": 1}).One(&filesRes)).To(Succeed())
Expect(conn.NewQuery("select count(*) as count from media_file where library_id = {:id} and missing = 1").Bind(dbx.Params{"id": 1}).One(&missingRes)).To(Succeed())
Expect(conn.NewQuery("select ifnull(sum(size),0) as sum from album where library_id = {:id} and missing = 0").Bind(dbx.Params{"id": 1}).One(&sizeRes)).To(Succeed())
Expect(conn.NewQuery("select ifnull(sum(duration),0) as sum from album where library_id = {:id} and missing = 0").Bind(dbx.Params{"id": 1}).One(&durationRes)).To(Succeed())
Expect(libAfter.TotalSongs).To(Equal(int(songsRes.Count)))
Expect(libAfter.TotalAlbums).To(Equal(int(albumsRes.Count)))
@ -48,5 +49,6 @@ var _ = Describe("LibraryRepository", func() {
Expect(libAfter.TotalFiles).To(Equal(int(filesRes.Count)))
Expect(libAfter.TotalMissingFiles).To(Equal(int(missingRes.Count)))
Expect(libAfter.TotalSize).To(Equal(sizeRes.Sum))
Expect(libAfter.TotalDuration).To(Equal(int(durationRes.Sum)))
})
})