package goscrobble import ( "database/sql" "errors" "log" ) type Album struct { UUID string `json:"uuid"` Name string `json:"name"` Desc string `json:"desc"` Img string `json:"img"` MusicBrainzID string `json:"mbid"` SpotifyID string `json:"spotify_id"` } // insertAlbum - This will return if it exists or create it based on MBID > Name func insertAlbum(name string, mbid string, spotifyId string, artists []string, img string, tx *sql.Tx) (Album, error) { album := Album{} // Try locate our album if mbid != "" { album = getAlbumByCol("mbid", mbid, tx) } else if spotifyId != "" { album = getAlbumByCol("spotify_id", spotifyId, tx) } // If it didn't match above, lookup by name if album.UUID == "" { album = getAlbumByCol("name", name, tx) } // If we can't find it. Lets add it! if album.UUID == "" { err := insertNewAlbum(&album, name, mbid, spotifyId, img, tx) if err != nil { return album, errors.New("Failed to insert album") } if album.UUID == "" { return album, errors.New("Failed to fetch album") } // Try linkem up err = album.linkAlbumToArtists(artists, tx) if err != nil { return album, errors.New("Unable to link albums!") } } // Updates these values if we match earlier! if album.MusicBrainzID != mbid { album.MusicBrainzID = mbid album.updateAlbum("mbid", mbid, tx) } if album.SpotifyID != spotifyId { album.SpotifyID = spotifyId album.updateAlbum("spotify_id", spotifyId, tx) } if album.Img == "" { if img != "" { album.Img = img album.updateAlbum("img", img, tx) } } return album, nil } func getAlbumByCol(col string, val string, tx *sql.Tx) Album { var album Album err := tx.QueryRow( `SELECT uuid, name, COALESCE(desc, ''), COALESCE(img,''), mbid, spotify_id FROM albums WHERE "`+col+`" = $1`, val).Scan(&album.UUID, &album.Name, &album.Desc, &album.Img, &album.MusicBrainzID, &album.SpotifyID) if err != nil { if err != sql.ErrNoRows { log.Printf("Error fetching albums: %+v", err) } } return album } func insertNewAlbum(album *Album, name string, mbid string, spotifyId string, img string, tx *sql.Tx) error { album.UUID = newUUID() album.Name = name album.MusicBrainzID = mbid album.SpotifyID = spotifyId album.Img = img _, err := tx.Exec(`INSERT INTO albums (uuid, name, mbid, spotify_id, img) `+ `VALUES ($1,$2,$3,$4,$5)`, album.UUID, album.Name, album.MusicBrainzID, album.SpotifyID, album.Img) return err } func (album *Album) linkAlbumToArtists(artists []string, tx *sql.Tx) error { var err error for _, artist := range artists { _, err = tx.Exec(`INSERT INTO album_artist (album, artist) `+ `VALUES ($1,$2)`, album.UUID, artist) if err != nil { return err } } return err } func (album *Album) updateAlbum(col string, val string, tx *sql.Tx) error { _, err := tx.Exec(`UPDATE albums SET "`+col+`" = $1 WHERE uuid = $2`, val, album.UUID) return err } func getAlbumByUUID(uuid string) (Album, error) { var album Album err := db.QueryRow(`SELECT uuid, name, COALESCE(desc,''), COALESCE(img,''), mbid, spotify_id FROM albums WHERE uuid = $1`, uuid).Scan(&album.UUID, &album.Name, &album.Desc, &album.Img, &album.MusicBrainzID, &album.SpotifyID) if err != nil { return album, errors.New("Invalid UUID") } return album, nil }