METANOIA/database/artist.go

167 lines
3.1 KiB
Go

package database
import (
"database/sql"
"encoding/json"
)
type Artist struct {
Type
id int
metadata []byte
}
type SongArtist struct {
Artist
kind string
}
type AlbumArtist struct {
Artist
kind string
}
func GetSongArtistFromRow(db *Database, row *sql.Rows) (*SongArtist, error) {
r := &SongArtist{
Artist: Artist{
Type: Type{
db: db,
},
},
}
err := row.Scan(&r.id, &r.metadata, &r.kind)
if err != nil {
return nil, err
}
return r, nil
}
func GetAlbumArtistFromRow(db *Database, row *sql.Rows) (*AlbumArtist, error) {
r := &AlbumArtist{
Artist: Artist{
Type: Type{
db: db,
},
},
}
err := row.Scan(&r.id, &r.metadata, &r.kind)
if err != nil {
return nil, err
}
return r, nil
}
func InsertArtistToDatabase(db *Database, names map[string]string) *Artist {
//TODO: do it in single tx
rows, err := db.Query("INSERT INTO artists DEFAULT VALUES RETURNING id;")
if err != nil {
return nil
}
defer rows.Close()
rows.Next()
var id int
err = rows.Scan(&id)
if err != nil {
return nil
}
artist := GetArtistFromDatabase(db, id)
if artist == nil {
return nil
}
for k, n := range names {
artist.AddName(k, n)
}
return artist
}
func GetArtistsFromDatabaseByName(db *Database, name string) (artists []*Artist) {
rows, err := db.Query("SELECT id, metadata FROM artists WHERE id IN(SELECT artist FROM artists_names WHERE name ILIKE $1);", name)
if err != nil {
return nil
}
defer rows.Close()
for rows.Next() {
artist, err := GetArtistFromRow(db, rows)
if err != nil {
break
}
artists = append(artists, artist)
}
return
}
func GetArtistFromDatabase(db *Database, id int) *Artist {
rows, err := db.Query("SELECT id, metadata FROM artists WHERE id = $1;", id)
if err != nil {
return nil
}
defer rows.Close()
rows.Next()
r, err := GetArtistFromRow(db, rows)
if err != nil {
return nil
}
return r
}
func GetArtistFromRow(db *Database, row *sql.Rows) (*Artist, error) {
r := &Artist{
Type: Type{
db: db,
},
}
err := row.Scan(&r.id, &r.metadata)
if err != nil {
return nil, err
}
return r, nil
}
func (r *Artist) GetId() int {
return r.id
}
func (r *Artist) GetNames() map[string]string {
result := make(map[string]string)
rows, err := r.db.Query("SELECT kind, name FROM artists_names WHERE id $1;", r.id)
if err != nil {
return nil
}
defer rows.Close()
for rows.Next() {
var kind string
var name string
err = rows.Scan(&kind, &name)
if err != nil {
break
}
result[kind] = name
}
return result
}
func (r *Artist) RemoveName(kind string) {
r.db.Exec("DELETE FROM artists_names WHERE id = $1 AND kind = $2;", r.id, kind)
}
func (r *Artist) AddName(kind, name string) {
r.db.Exec("INSERT INTO artists_names (artist, kind, name) VALUES ($1, $2, $3) ON CONFLICT (artist, kind) DO UPDATE SET name = $3;", r.id, kind, name)
}
func (r *Artist) GetMetadata() (result map[string]interface{}) {
json.Unmarshal(r.metadata, &result)
return result
}
func (r *Artist) SetMetadata(value map[string]interface{}) {
r.metadata, _ = json.Marshal(value)
r.db.Exec("UPDATE artists SET metadata = $2::jsonb WHERE id = $1;", r.id, r.metadata)
}