80 lines
2.5 KiB
Go
80 lines
2.5 KiB
Go
package database
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
|
|
"git.noroutes.net/NoRoutes/vibetunes/internal/idgen"
|
|
)
|
|
|
|
type CoverArt struct {
|
|
ID string
|
|
AlbumID sql.NullString
|
|
MediaFileID sql.NullString
|
|
Source string
|
|
SourcePath string
|
|
MimeType string
|
|
ContentHash string
|
|
Width int
|
|
Height int
|
|
}
|
|
|
|
const coverArtSelect = `SELECT id, album_id, media_file_id, source, source_path, mime_type, content_hash, width, height FROM cover_art`
|
|
|
|
func GetCoverArt(db *sql.DB, id string) (*CoverArt, error) {
|
|
return scanCoverArt(db.QueryRow(coverArtSelect+` WHERE id = ?`, id))
|
|
}
|
|
|
|
func GetCoverArtForAlbum(db *sql.DB, albumID string) (*CoverArt, error) {
|
|
return scanCoverArt(db.QueryRow(coverArtSelect+` WHERE album_id = ? ORDER BY updated_at DESC LIMIT 1`, albumID))
|
|
}
|
|
|
|
func scanCoverArt(row *sql.Row) (*CoverArt, error) {
|
|
var c CoverArt
|
|
err := row.Scan(&c.ID, &c.AlbumID, &c.MediaFileID, &c.Source, &c.SourcePath, &c.MimeType, &c.ContentHash, &c.Width, &c.Height)
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
return nil, ErrNotFound
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &c, nil
|
|
}
|
|
|
|
// UpsertAlbumCoverArt records (or replaces) the discovered cover art
|
|
// source for an album and links it as the album's cover. mediaFileID is
|
|
// set (with sourcePath empty) for embedded artwork, which is extracted
|
|
// on demand from the media file rather than at scan time.
|
|
func UpsertAlbumCoverArt(db *sql.DB, albumID, source, sourcePath, mediaFileID, mimeType, contentHash string, width, height int) (*CoverArt, error) {
|
|
var id string
|
|
err := db.QueryRow(`SELECT id FROM cover_art WHERE album_id = ?`, albumID).Scan(&id)
|
|
switch {
|
|
case err == nil:
|
|
_, err = db.Exec(`UPDATE cover_art SET source=?, source_path=?, media_file_id=?, mime_type=?, content_hash=?, width=?, height=?, updated_at=strftime('%Y-%m-%dT%H:%M:%fZ','now') WHERE id=?`,
|
|
source, sourcePath, nullEmptyStr(mediaFileID), mimeType, contentHash, width, height, id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
case errors.Is(err, sql.ErrNoRows):
|
|
id = idgen.New("ca")
|
|
_, err = db.Exec(`INSERT INTO cover_art (id, album_id, media_file_id, source, source_path, mime_type, content_hash, width, height) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
id, albumID, nullEmptyStr(mediaFileID), source, sourcePath, mimeType, contentHash, width, height)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
default:
|
|
return nil, err
|
|
}
|
|
if err := SetAlbumCoverArt(db, albumID, id); err != nil {
|
|
return nil, err
|
|
}
|
|
return GetCoverArt(db, id)
|
|
}
|
|
|
|
func nullEmptyStr(s string) any {
|
|
if s == "" {
|
|
return nil
|
|
}
|
|
return s
|
|
}
|