HEAVY: finish music service migration, tidy up services, more tests
This commit is contained in:
parent
9e311df462
commit
90a671982c
47 changed files with 2698 additions and 902 deletions
|
|
@ -27,11 +27,11 @@ type AccountRepository interface {
|
|||
UpdateAvatarURL(id string, avatarURL string) error
|
||||
RemoveAvatar(id string) error
|
||||
|
||||
Delete(id string) error
|
||||
|
||||
// Increment the number of account login failure attempts,
|
||||
// returning the current fail count.
|
||||
IncrementFails(id string) (int, error)
|
||||
ResetFails(id string) error
|
||||
SetLocked(id string, lock bool) error
|
||||
|
||||
Delete(id string) (string, error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
package account
|
||||
|
||||
import (
|
||||
"arimelody-web/errors"
|
||||
"arimelody-web/model"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"slices"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
|
|
@ -24,10 +25,11 @@ func (repo *AccountRepositoryMemory) GetCount() (int, error) {
|
|||
return len(repo.accounts), nil
|
||||
}
|
||||
func (repo *AccountRepositoryMemory) GetByID(id string) (*model.Account, error) {
|
||||
for _, account := range repo.accounts {
|
||||
if account.ID == id { return account, nil }
|
||||
}
|
||||
return nil, nil
|
||||
index := slices.IndexFunc(repo.accounts, func(account *model.Account) bool {
|
||||
return account.ID == id
|
||||
})
|
||||
if index == -1 { return nil, nil }
|
||||
return repo.accounts[index], nil
|
||||
}
|
||||
func (repo *AccountRepositoryMemory) GetByUsername(username string) (*model.Account, error) {
|
||||
for _, account := range repo.accounts {
|
||||
|
|
@ -47,9 +49,9 @@ func (repo *AccountRepositoryMemory) GetByEmail(email string) (*model.Account, e
|
|||
// Create an account, returning the new account ID.
|
||||
func (repo *AccountRepositoryMemory) Create(username string, password string, email *string, avatarURL *string) (string, error) {
|
||||
if account, err := repo.GetByUsername(username); err != nil {
|
||||
return "", errors.New("Failed to fetch other acccounts by username")
|
||||
return "", errors.NewNotExistError("Failed to fetch other acccounts by username")
|
||||
} else if account != nil {
|
||||
return "", errors.New("Account with this username already exists")
|
||||
return "", errors.NewNotExistError("Account with this username already exists")
|
||||
}
|
||||
|
||||
emailRef := ""
|
||||
|
|
@ -74,9 +76,9 @@ func (repo *AccountRepositoryMemory) Create(username string, password string, em
|
|||
// more specialised Update* and Remove* functions should be used.
|
||||
func (repo *AccountRepositoryMemory) Update(id string, username string, password string, email *string, avatarUrl *string) error {
|
||||
if account, err := repo.GetByUsername(username); err != nil {
|
||||
return errors.New("Failed to fetch other acccounts by username")
|
||||
return errors.NewNotExistError("Failed to fetch other acccounts by username")
|
||||
} else if account != nil && account.ID != id {
|
||||
return errors.New("Account with this username already exists")
|
||||
return errors.NewNotExistError("Account with this username already exists")
|
||||
}
|
||||
|
||||
account, err := repo.GetByID(id)
|
||||
|
|
@ -93,14 +95,14 @@ func (repo *AccountRepositoryMemory) Update(id string, username string, password
|
|||
}
|
||||
func (repo *AccountRepositoryMemory) UpdateUsername(id string, username string) error {
|
||||
if account, err := repo.GetByUsername(username); err != nil {
|
||||
return errors.New("Failed to fetch other acccounts by username")
|
||||
return errors.NewNotExistError("Failed to fetch other acccounts by username")
|
||||
} else if account != nil && account.ID != id {
|
||||
return errors.New("Account with this username already exists")
|
||||
return errors.NewNotExistError("Account with this username already exists")
|
||||
}
|
||||
|
||||
account, err := repo.GetByID(id)
|
||||
if err != nil { return err }
|
||||
if account == nil { return errors.New("Account does not exist") }
|
||||
if account == nil { return errors.NewNotExistError("Account does not exist") }
|
||||
|
||||
account.Username = username
|
||||
return nil
|
||||
|
|
@ -108,7 +110,7 @@ func (repo *AccountRepositoryMemory) UpdateUsername(id string, username string)
|
|||
func (repo *AccountRepositoryMemory) UpdatePassword(id string, password string) error {
|
||||
account, err := repo.GetByID(id)
|
||||
if err != nil { return err }
|
||||
if account == nil { return errors.New("Account does not exist") }
|
||||
if account == nil { return errors.NewNotExistError("Account does not exist") }
|
||||
|
||||
account.Password = password
|
||||
return nil
|
||||
|
|
@ -116,7 +118,7 @@ func (repo *AccountRepositoryMemory) UpdatePassword(id string, password string)
|
|||
func (repo *AccountRepositoryMemory) UpdateEmail(id string, email string) error {
|
||||
account, err := repo.GetByID(id)
|
||||
if err != nil { return err }
|
||||
if account == nil { return errors.New("Account does not exist") }
|
||||
if account == nil { return errors.NewNotExistError("Account does not exist") }
|
||||
|
||||
account.Email.Valid = true
|
||||
account.Email.String = email
|
||||
|
|
@ -125,7 +127,7 @@ func (repo *AccountRepositoryMemory) UpdateEmail(id string, email string) error
|
|||
func (repo *AccountRepositoryMemory) RemoveEmail(id string) error {
|
||||
account, err := repo.GetByID(id)
|
||||
if err != nil { return err }
|
||||
if account == nil { return errors.New("Account does not exist") }
|
||||
if account == nil { return errors.NewNotExistError("Account does not exist") }
|
||||
|
||||
account.Email.Valid = false
|
||||
account.Email.String = ""
|
||||
|
|
@ -134,7 +136,7 @@ func (repo *AccountRepositoryMemory) RemoveEmail(id string) error {
|
|||
func (repo *AccountRepositoryMemory) UpdateAvatarURL(id string, avatarURL string) error {
|
||||
account, err := repo.GetByID(id)
|
||||
if err != nil { return err }
|
||||
if account == nil { return errors.New("Account does not exist") }
|
||||
if account == nil { return errors.NewNotExistError("Account does not exist") }
|
||||
|
||||
account.AvatarURL.Valid = true
|
||||
account.AvatarURL.String = avatarURL
|
||||
|
|
@ -143,31 +145,13 @@ func (repo *AccountRepositoryMemory) UpdateAvatarURL(id string, avatarURL string
|
|||
func (repo *AccountRepositoryMemory) RemoveAvatar(id string) error {
|
||||
account, err := repo.GetByID(id)
|
||||
if err != nil { return err }
|
||||
if account == nil { return errors.New("Account does not exist") }
|
||||
if account == nil { return errors.NewNotExistError("Account does not exist") }
|
||||
|
||||
account.AvatarURL.Valid = false
|
||||
account.AvatarURL.String = ""
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *AccountRepositoryMemory) Delete(id string) error {
|
||||
accountIndex := -1
|
||||
for index, account := range repo.accounts {
|
||||
if account.ID == id {
|
||||
accountIndex = index
|
||||
break
|
||||
}
|
||||
}
|
||||
if accountIndex == -1 { return nil }
|
||||
|
||||
repo.accounts = append(
|
||||
repo.accounts[:accountIndex],
|
||||
repo.accounts[accountIndex+1:]...,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Increment the number of account login failure attempts,
|
||||
// returning the current fail count.
|
||||
func (repo *AccountRepositoryMemory) IncrementFails(id string) (int, error) {
|
||||
|
|
@ -188,3 +172,17 @@ func (repo *AccountRepositoryMemory) SetLocked(id string, locked bool) error {
|
|||
account.Locked = locked
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *AccountRepositoryMemory) Delete(id string) (string, error) {
|
||||
var deletedID string
|
||||
newAccounts := []*model.Account{}
|
||||
for _, account := range repo.accounts {
|
||||
if account.ID == id {
|
||||
deletedID = id
|
||||
continue
|
||||
}
|
||||
newAccounts = append(newAccounts, account)
|
||||
}
|
||||
repo.accounts = newAccounts
|
||||
return deletedID, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,11 +157,6 @@ func (repo *AccountRepositoryPostgres) RemoveAvatar(id string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (repo *AccountRepositoryPostgres) Delete(id string) error {
|
||||
_, err := repo.db.Exec("DELETE FROM account WHERE id=$1", id)
|
||||
return err
|
||||
}
|
||||
|
||||
// Increment the number of account login failure attempts,
|
||||
// returning the current fail count.
|
||||
func (repo *AccountRepositoryPostgres) IncrementFails(id string) (int, error) {
|
||||
|
|
@ -179,3 +174,9 @@ func (repo *AccountRepositoryPostgres) SetLocked(id string, locked bool) error {
|
|||
_, err := repo.db.Exec("UPDATE account SET locked = $2 WHERE id=$1", id, locked)
|
||||
return err
|
||||
}
|
||||
|
||||
func (repo *AccountRepositoryPostgres) Delete(id string) (string, error) {
|
||||
var deletedID string
|
||||
err := repo.db.Get(&deletedID, "DELETE FROM account WHERE id=$1", id)
|
||||
return deletedID, err
|
||||
}
|
||||
|
|
|
|||
135
repository/music/artist_memory.go
Normal file
135
repository/music/artist_memory.go
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
package music
|
||||
|
||||
import (
|
||||
"arimelody-web/errors"
|
||||
"arimelody-web/model"
|
||||
"slices"
|
||||
)
|
||||
|
||||
func (repo *MusicRepositoryMemory) GetAllArtists() ([]*model.Artist, error) {
|
||||
return repo.artists, nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) GetArtistCount() (int, error) {
|
||||
return len(repo.artists), nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) GetArtistByID(id string) (*model.Artist, error) {
|
||||
index := slices.IndexFunc(repo.artists, func(artist *model.Artist) bool {
|
||||
return artist.ID == id
|
||||
})
|
||||
if index == -1 { return nil, nil }
|
||||
return repo.artists[index], nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) GetArtistsNotOnRelease(releaseID string) ([]*model.Artist, error) {
|
||||
release, err := repo.GetReleaseByID(releaseID)
|
||||
if err != nil { return nil, err }
|
||||
artists, err := repo.GetAllArtists()
|
||||
if err != nil { return nil, err }
|
||||
|
||||
artistsNotOnRelease := []*model.Artist{}
|
||||
for _, artist := range artists {
|
||||
if !slices.ContainsFunc(release.Credits, func(credit *model.Credit) bool {
|
||||
return credit.Artist.ID == artist.ID
|
||||
}) {
|
||||
artistsNotOnRelease = append(artistsNotOnRelease, artist)
|
||||
}
|
||||
}
|
||||
|
||||
return artistsNotOnRelease, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) GetArtistCredits(artistID string, showHidden bool) ([]*model.Credit, error) {
|
||||
releases, err := repo.GetAllReleases(!showHidden, 0)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
credits := []*model.Credit{}
|
||||
for _, release := range releases {
|
||||
credits = append(credits, slices.DeleteFunc(
|
||||
release.Credits,
|
||||
func(credit *model.Credit) bool {
|
||||
return credit.Artist.ID != artistID
|
||||
},
|
||||
)...)
|
||||
}
|
||||
|
||||
return credits, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) CreateArtist(
|
||||
id string,
|
||||
name string,
|
||||
website string,
|
||||
avatar string,
|
||||
) error {
|
||||
if artist, err := repo.GetArtistByID(id); err != nil {
|
||||
if !errors.IsNotExistError(err) { return err }
|
||||
} else {
|
||||
if artist != nil { return errors.NewValidationError("Artist with this ID already exists") }
|
||||
}
|
||||
|
||||
repo.artists = append(repo.artists, &model.Artist{
|
||||
ID: id,
|
||||
Name: name,
|
||||
Website: website,
|
||||
Avatar: avatar,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) UpdateArtist(artist *model.Artist) error {
|
||||
repoArtist, err := repo.GetArtistByID(artist.ID)
|
||||
if err != nil { return err }
|
||||
if repoArtist == nil { return errors.NewNotExistError("Artist does not exist") }
|
||||
|
||||
repoArtist.Name = artist.Name
|
||||
repoArtist.Website = artist.Website
|
||||
repoArtist.Avatar = artist.Avatar
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateArtistID(oldID string, newID string) error {
|
||||
artist, err := repo.GetArtistByID(oldID)
|
||||
if err != nil { return err }
|
||||
if artist == nil { return errors.NewNotExistError("Artist does not exist") }
|
||||
|
||||
artist.ID = newID
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateArtistName(id string, name string) error {
|
||||
artist, err := repo.GetArtistByID(id)
|
||||
if err != nil { return err }
|
||||
if artist == nil { return errors.NewNotExistError("Artist does not exist") }
|
||||
|
||||
artist.Name = name
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateArtistWebsite(id string, website string) error {
|
||||
artist, err := repo.GetArtistByID(id)
|
||||
if err != nil { return err }
|
||||
if artist == nil { return errors.NewNotExistError("Artist does not exist") }
|
||||
|
||||
artist.Website = website
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateArtistAvatar(id string, avatar string) error {
|
||||
artist, err := repo.GetArtistByID(id)
|
||||
if err != nil { return err }
|
||||
if artist == nil { return errors.NewNotExistError("Artist does not exist") }
|
||||
|
||||
artist.Avatar = avatar
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) DeleteArtist(id string) (string, error) {
|
||||
var deletedID string
|
||||
newArtists := []*model.Artist{}
|
||||
for _, artist := range repo.artists {
|
||||
if artist.ID == id {
|
||||
deletedID = id
|
||||
continue
|
||||
}
|
||||
newArtists = append(newArtists, artist)
|
||||
}
|
||||
repo.artists = newArtists
|
||||
return deletedID, nil
|
||||
}
|
||||
154
repository/music/artist_postgres.go
Normal file
154
repository/music/artist_postgres.go
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
package music
|
||||
|
||||
import (
|
||||
"arimelody-web/model"
|
||||
)
|
||||
|
||||
func (repo *MusicRepositoryPostgres) GetAllArtists() ([]*model.Artist, error) {
|
||||
var artists = []*model.Artist{}
|
||||
|
||||
err := repo.db.Select(&artists, "SELECT * FROM artist")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return artists, nil
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) GetArtistCount() (int, error) {
|
||||
var count int
|
||||
err := repo.db.Get(&count, "SELECT count(*) FROM artist")
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) GetArtistByID(id string) (*model.Artist, error) {
|
||||
var artist = model.Artist{}
|
||||
|
||||
err := repo.db.Get(&artist, "SELECT * FROM artist WHERE id=$1", id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &artist, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) GetArtistsNotOnRelease(releaseID string) ([]*model.Artist, error) {
|
||||
var artists = []*model.Artist{}
|
||||
|
||||
err := repo.db.Select(&artists,
|
||||
"SELECT * FROM artist "+
|
||||
"WHERE id NOT IN "+
|
||||
"(SELECT artist FROM musiccredit WHERE release=$1)",
|
||||
releaseID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return artists, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) GetArtistCredits(artistID string, showHidden bool) ([]*model.Credit, error) {
|
||||
var query string = "SELECT release.id,title,artwork,release_date,artist.id,name,website,avatar,role,is_primary "+
|
||||
"FROM musiccredit "+
|
||||
"JOIN musicrelease AS release ON release=release.id "+
|
||||
"JOIN artist ON artist=artist.id "+
|
||||
"WHERE artist=$1 "
|
||||
if !showHidden { query += "AND visible=true " }
|
||||
query += "ORDER BY release_date DESC"
|
||||
rows, err := repo.db.Query(query, artistID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
type NamePrimary struct {
|
||||
Name string `json:"name"`
|
||||
Primary bool `json:"primary" db:"is_primary"`
|
||||
}
|
||||
var credits []*model.Credit
|
||||
for rows.Next() {
|
||||
credit := &model.Credit{
|
||||
Release: &model.Release{},
|
||||
Artist: &model.Artist{},
|
||||
}
|
||||
err = rows.Scan(
|
||||
&credit.Release.ID,
|
||||
&credit.Release.Title,
|
||||
&credit.Release.Artwork,
|
||||
&credit.Release.ReleaseDate,
|
||||
&credit.Artist.ID,
|
||||
&credit.Artist.Name,
|
||||
&credit.Artist.Website,
|
||||
&credit.Artist.Avatar,
|
||||
&credit.Role,
|
||||
&credit.Primary,
|
||||
)
|
||||
|
||||
otherArtists := []NamePrimary{}
|
||||
err = repo.db.Select(&otherArtists,
|
||||
"SELECT name,is_primary FROM artist "+
|
||||
"JOIN musiccredit ON artist=id "+
|
||||
"WHERE release=$1",
|
||||
credit.Release.ID)
|
||||
for _, otherCredit := range otherArtists {
|
||||
credit.Release.Credits = append(credit.Release.Credits, &model.Credit{
|
||||
Artist: &model.Artist{
|
||||
Name: otherCredit.Name,
|
||||
},
|
||||
Primary: otherCredit.Primary,
|
||||
})
|
||||
}
|
||||
|
||||
credits = append(credits, credit)
|
||||
}
|
||||
|
||||
return credits, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) CreateArtist(
|
||||
id string,
|
||||
name string,
|
||||
website string,
|
||||
avatar string,
|
||||
) error {
|
||||
_, err := repo.db.Exec(
|
||||
"INSERT INTO artist (id, name, website, avatar) "+
|
||||
"VALUES ($1, $2, $3, $4)",
|
||||
id, name, website, avatar,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) UpdateArtist(artist *model.Artist) error {
|
||||
_, err := repo.db.Exec(
|
||||
"UPDATE artist "+
|
||||
"SET name=$2, website=$3, avatar=$4 "+
|
||||
"WHERE id=$1",
|
||||
artist.ID,
|
||||
artist.Name,
|
||||
artist.Website,
|
||||
artist.Avatar,
|
||||
)
|
||||
return err
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateArtistID(oldID string, newID string) error {
|
||||
_, err := repo.db.Exec("UPDATE artist SET id=$2 WHERE id=$1", oldID, newID)
|
||||
return err
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateArtistName(id string, name string) error {
|
||||
_, err := repo.db.Exec("UPDATE artist SET name=$2 WHERE id=$1", id, name)
|
||||
return err
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateArtistWebsite(id string, website string) error {
|
||||
_, err := repo.db.Exec("UPDATE artist SET website=$2 WHERE id=$1", id, website)
|
||||
return err
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateArtistAvatar(id string, avatar string) error {
|
||||
_, err := repo.db.Exec("UPDATE artist SET avatar=$2 WHERE id=$1", id, avatar)
|
||||
return err
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) DeleteArtist(id string) (string, error) {
|
||||
var deletedID string
|
||||
err := repo.db.Get(&deletedID, "DELETE FROM artist WHERE id=$1", id)
|
||||
return deletedID, err
|
||||
}
|
||||
110
repository/music/interface.go
Normal file
110
repository/music/interface.go
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
package music
|
||||
|
||||
import (
|
||||
"arimelody-web/model"
|
||||
"time"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
type MusicRepository interface {
|
||||
// artists
|
||||
|
||||
GetAllArtists() ([]*model.Artist, error)
|
||||
GetArtistCount() (int, error)
|
||||
// Fetches an artist by ID, returning an error if one was encountered.
|
||||
// If the artist does not exist, both response fields are nil.
|
||||
GetArtistByID(id string) (*model.Artist, error)
|
||||
GetArtistsNotOnRelease(releaseID string) ([]*model.Artist, error)
|
||||
GetArtistCredits(artistID string, showHidden bool) ([]*model.Credit, error)
|
||||
|
||||
CreateArtist(id string, name string, website string, avatar string) error
|
||||
|
||||
UpdateArtist(artist *model.Artist) error
|
||||
UpdateArtistID(oldID string, newID string) error
|
||||
UpdateArtistName(id string, name string) error
|
||||
UpdateArtistWebsite(id string, website string) error
|
||||
UpdateArtistAvatar(id string, avatar string) error
|
||||
|
||||
DeleteArtist(id string) (string, error)
|
||||
|
||||
// releases
|
||||
|
||||
// Fetch all releases.
|
||||
// Filters to visible releases if `onlyVisible = true`.
|
||||
// If `limit > 0`, limits the number of results.
|
||||
GetAllReleases(onlyVisible bool, limit int) ([]*model.Release, error)
|
||||
GetReleaseCount(onlyVisible bool) (int, error)
|
||||
GetReleaseByID(id string) (*model.Release, error)
|
||||
|
||||
GetReleaseTracks(id string) ([]*model.Track, error)
|
||||
GetReleaseCredits(id string) ([]*model.Credit, error)
|
||||
GetReleaseLinks(id string) ([]*model.Link, error)
|
||||
|
||||
CreateRelease(id string, title string, releaseType model.ReleaseType, releaseDate time.Time, artworkURL string) error
|
||||
|
||||
UpdateRelease(release *model.Release) error
|
||||
UpdateReleaseID(oldID string, newID string) error
|
||||
UpdateReleaseVisibility(id string, visible bool) error
|
||||
UpdateReleaseTitle(id string, title string) error
|
||||
UpdateReleaseDescription(id string, description string) error
|
||||
UpdateReleaseType(id string, releaseType model.ReleaseType) error
|
||||
UpdateReleaseDate(id string, releaseDate time.Time) error
|
||||
UpdateReleaseArtwork(id string, artwork string) error
|
||||
UpdateReleaseBuyInfo(id string, buyName string, buyLink string) error
|
||||
UpdateReleaseCopyright(id string, copyright string, url string) error
|
||||
UpdateReleaseTracks(id string, newTrackIDs []string) error
|
||||
UpdateReleaseCredits(id string, newCredits []*model.Credit) error
|
||||
UpdateReleaseLinks(id string, newLinks []*model.Link) error
|
||||
|
||||
DeleteRelease(id string) (string, error)
|
||||
|
||||
// tracks
|
||||
|
||||
GetAllTracks() ([]*model.Track, error)
|
||||
GetTrackCount() (int, error)
|
||||
GetTrackByID(id string) (*model.Track, error)
|
||||
GetOrphanTracks() ([]*model.Track, error)
|
||||
GetTracksNotOnRelease(releaseID string) ([]*model.Track, error)
|
||||
GetTrackReleases(trackID string) ([]*model.Release, error)
|
||||
|
||||
CreateTrack(title string, description string, lyrics string, previewURL string) (string, error)
|
||||
|
||||
UpdateTrack(track *model.Track) error
|
||||
UpdateTrackTitle(id string, title string) error
|
||||
UpdateTrackDescription(id string, description string) error
|
||||
UpdateTrackLyrics(id string, lyrics string) error
|
||||
UpdateTrackPreviewURL(id string, previewURL string) error
|
||||
|
||||
DeleteTrack(id string) (string, error)
|
||||
}
|
||||
|
||||
type (
|
||||
MusicRepositoryPostgres struct {
|
||||
db *sqlx.DB
|
||||
}
|
||||
|
||||
MusicRepositoryMemory struct {
|
||||
artists []*model.Artist
|
||||
releases []*model.Release
|
||||
tracks []*model.Track
|
||||
}
|
||||
)
|
||||
|
||||
var _ MusicRepository = new(MusicRepositoryPostgres)
|
||||
func NewMusicRepositoryPostgres(db *sqlx.DB) *MusicRepositoryPostgres {
|
||||
return &MusicRepositoryPostgres{ db: db }
|
||||
}
|
||||
|
||||
var _ MusicRepository = new(MusicRepositoryMemory)
|
||||
func NewMusicRepositoryMemory(
|
||||
artists []*model.Artist,
|
||||
releases []*model.Release,
|
||||
tracks []*model.Track,
|
||||
) *MusicRepositoryMemory {
|
||||
return &MusicRepositoryMemory{
|
||||
artists: artists,
|
||||
releases: releases,
|
||||
tracks: tracks,
|
||||
}
|
||||
}
|
||||
228
repository/music/release_memory.go
Normal file
228
repository/music/release_memory.go
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
package music
|
||||
|
||||
import (
|
||||
"arimelody-web/errors"
|
||||
"arimelody-web/model"
|
||||
"fmt"
|
||||
"slices"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (repo *MusicRepositoryMemory) GetAllReleases(onlyVisible bool, limit int) ([]*model.Release, error) {
|
||||
releases := []*model.Release{}
|
||||
for _, release := range repo.releases {
|
||||
if !onlyVisible || release.Visible {
|
||||
releases = append(releases, release)
|
||||
}
|
||||
}
|
||||
return releases, nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) GetReleaseCount(onlyVisible bool) (int, error) {
|
||||
releaseCount := 0
|
||||
for _, release := range repo.releases {
|
||||
if !onlyVisible || release.Visible {
|
||||
releaseCount++
|
||||
}
|
||||
}
|
||||
return releaseCount, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) GetReleaseByID(id string) (*model.Release, error) {
|
||||
index := slices.IndexFunc(repo.releases, func(release *model.Release) bool {
|
||||
return release.ID == id
|
||||
})
|
||||
if index == -1 { return nil, nil }
|
||||
return repo.releases[index], nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) GetReleaseTracks(id string) ([]*model.Track, error) {
|
||||
release, err := repo.GetReleaseByID(id)
|
||||
if err != nil { return nil, err }
|
||||
return release.Tracks, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) GetReleaseCredits(id string) ([]*model.Credit, error) {
|
||||
release, err := repo.GetReleaseByID(id)
|
||||
if err != nil { return nil, err }
|
||||
return release.Credits, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) GetReleaseLinks(id string) ([]*model.Link, error) {
|
||||
release, err := repo.GetReleaseByID(id)
|
||||
if err != nil { return nil, err }
|
||||
return release.Links, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) CreateRelease(
|
||||
id string,
|
||||
title string,
|
||||
releaseType model.ReleaseType,
|
||||
releaseDate time.Time,
|
||||
artworkURL string,
|
||||
) error {
|
||||
if release, err := repo.GetReleaseByID(id); err != nil {
|
||||
if !errors.IsNotExistError(err) { return err }
|
||||
} else {
|
||||
if release != nil { return errors.NewValidationError("Release with this ID already exists") }
|
||||
}
|
||||
|
||||
repo.releases = append(repo.releases, &model.Release{
|
||||
ID: id,
|
||||
Title: title,
|
||||
ReleaseType: releaseType,
|
||||
ReleaseDate: releaseDate,
|
||||
Artwork: artworkURL,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) UpdateRelease(release *model.Release) error {
|
||||
repoRelease, err := repo.GetReleaseByID(release.ID)
|
||||
if err != nil { return err }
|
||||
if repoRelease == nil { return errors.NewNotExistError("Release does not exist") }
|
||||
|
||||
repoRelease.Visible = release.Visible
|
||||
repoRelease.Title = release.Title
|
||||
repoRelease.Description = release.Description
|
||||
repoRelease.ReleaseType = release.ReleaseType
|
||||
repoRelease.ReleaseDate = release.ReleaseDate
|
||||
repoRelease.Artwork = release.Artwork
|
||||
repoRelease.Buyname = release.Buyname
|
||||
repoRelease.Buylink = release.Buylink
|
||||
repoRelease.Copyright = release.Copyright
|
||||
repoRelease.CopyrightURL = release.CopyrightURL
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) UpdateReleaseID(oldID string, newID string) error {
|
||||
release, err := repo.GetReleaseByID(oldID)
|
||||
if err != nil { return err }
|
||||
if release == nil { return errors.NewNotExistError("Release does not exist") }
|
||||
release.ID = newID
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateReleaseVisibility(id string, visible bool) error {
|
||||
release, err := repo.GetReleaseByID(id)
|
||||
if err != nil { return err }
|
||||
if release == nil { return errors.NewNotExistError("Release does not exist") }
|
||||
release.Visible = visible
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateReleaseTitle(id string, title string) error {
|
||||
release, err := repo.GetReleaseByID(id)
|
||||
if err != nil { return err }
|
||||
if release == nil { return errors.NewNotExistError("Release does not exist") }
|
||||
release.Title = title
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateReleaseDescription(id string, description string) error {
|
||||
release, err := repo.GetReleaseByID(id)
|
||||
if err != nil { return err }
|
||||
if release == nil { return errors.NewNotExistError("Release does not exist") }
|
||||
release.Description = description
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateReleaseType(id string, releaseType model.ReleaseType) error {
|
||||
release, err := repo.GetReleaseByID(id)
|
||||
if err != nil { return err }
|
||||
if release == nil { return errors.NewNotExistError("Release does not exist") }
|
||||
release.ReleaseType = releaseType
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateReleaseDate(id string, releaseDate time.Time) error {
|
||||
release, err := repo.GetReleaseByID(id)
|
||||
if err != nil { return err }
|
||||
if release == nil { return errors.NewNotExistError("Release does not exist") }
|
||||
release.ReleaseDate = releaseDate
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateReleaseArtwork(id string, artwork string) error {
|
||||
release, err := repo.GetReleaseByID(id)
|
||||
if err != nil { return err }
|
||||
if release == nil { return errors.NewNotExistError("Release does not exist") }
|
||||
release.Artwork = artwork
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateReleaseBuyInfo(id string, buyName string, buyLink string) error {
|
||||
release, err := repo.GetReleaseByID(id)
|
||||
if err != nil { return err }
|
||||
if release == nil { return errors.NewNotExistError("Release does not exist") }
|
||||
release.Buyname = buyName
|
||||
release.Buylink = buyLink
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateReleaseCopyright(id string, copyright string, url string) error {
|
||||
release, err := repo.GetReleaseByID(id)
|
||||
if err != nil { return err }
|
||||
if release == nil { return errors.NewNotExistError("Release does not exist") }
|
||||
release.Copyright = copyright
|
||||
release.CopyrightURL = url
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) UpdateReleaseTracks(id string, newTrackIDs []string) error {
|
||||
release, err := repo.GetReleaseByID(id)
|
||||
if err != nil { return err }
|
||||
if release == nil { return errors.NewNotExistError("Release does not exist") }
|
||||
|
||||
tracks := []*model.Track{}
|
||||
for _, trackID := range newTrackIDs {
|
||||
track, err := repo.GetTrackByID(trackID)
|
||||
if err != nil {
|
||||
if errors.IsNotExistError(err) {
|
||||
return errors.NewNotExistError(fmt.Sprintf("Track %s does not exist", trackID))
|
||||
}
|
||||
return err
|
||||
}
|
||||
tracks = append(tracks, track)
|
||||
}
|
||||
release.Tracks = tracks
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) UpdateReleaseCredits(id string, newCredits []*model.Credit) error {
|
||||
release, err := repo.GetReleaseByID(id)
|
||||
if err != nil { return err }
|
||||
if release == nil { return errors.NewNotExistError("Release does not exist") }
|
||||
|
||||
for _, credit := range newCredits {
|
||||
if credit.Artist == nil { return errors.NewValidationError("Credit artist cannot be empty") }
|
||||
if len(credit.Artist.ID) == 0 { return errors.NewValidationError("Credit artist ID cannot be empty") }
|
||||
if artist, err := repo.GetArtistByID(credit.Artist.ID); err != nil {
|
||||
return err
|
||||
} else if artist == nil {
|
||||
return errors.NewNotExistError(fmt.Sprintf("Artist '%s' does not exist", credit.Artist.ID))
|
||||
} else {
|
||||
credit.Release = release
|
||||
credit.Artist = artist
|
||||
}
|
||||
}
|
||||
|
||||
release.Credits = newCredits
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) UpdateReleaseLinks(id string, newLinks []*model.Link) error {
|
||||
release, err := repo.GetReleaseByID(id)
|
||||
if err != nil { return err }
|
||||
if release == nil { return errors.NewNotExistError("Release does not exist") }
|
||||
release.Links = newLinks
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) DeleteRelease(id string) (string, error) {
|
||||
var deletedID string
|
||||
newReleases := []*model.Release{}
|
||||
for _, release := range repo.releases {
|
||||
if release.ID == id {
|
||||
deletedID = id
|
||||
continue
|
||||
}
|
||||
newReleases = append(newReleases, release)
|
||||
}
|
||||
repo.releases = newReleases
|
||||
return deletedID, nil
|
||||
}
|
||||
303
repository/music/release_postgres.go
Normal file
303
repository/music/release_postgres.go
Normal file
|
|
@ -0,0 +1,303 @@
|
|||
package music
|
||||
|
||||
import (
|
||||
"arimelody-web/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (repo *MusicRepositoryPostgres) GetAllReleases(onlyVisible bool, limit int) ([]*model.Release, error) {
|
||||
var releases = []*model.Release{}
|
||||
|
||||
query := "SELECT * FROM musicrelease"
|
||||
if onlyVisible {
|
||||
query += " WHERE visible=true"
|
||||
}
|
||||
query += " ORDER BY release_date DESC"
|
||||
var err error
|
||||
if limit > 0 {
|
||||
err = repo.db.Select(&releases, query + " LIMIT $1", limit)
|
||||
} else {
|
||||
err = repo.db.Select(&releases, query)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return releases, nil
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) GetReleaseCount(onlyVisible bool) (int, error) {
|
||||
query := "SELECT count(*) FROM musicrelease"
|
||||
if onlyVisible {
|
||||
query += " WHERE visible=true"
|
||||
}
|
||||
|
||||
var count int
|
||||
err := repo.db.Get(&count, query)
|
||||
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) GetReleaseByID(id string) (*model.Release, error) {
|
||||
var release = model.Release{}
|
||||
err := repo.db.Get(&release, "SELECT * FROM musicrelease WHERE id=$1", id)
|
||||
if err != nil { return nil, err }
|
||||
return &release, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) GetReleaseTracks(releaseID string) ([]*model.Track, error) {
|
||||
var tracks = []*model.Track{}
|
||||
|
||||
err := repo.db.Select(&tracks,
|
||||
"SELECT musictrack.* FROM musictrack "+
|
||||
"JOIN musicreleasetrack ON track=id "+
|
||||
"WHERE release=$1 "+
|
||||
"ORDER BY number ASC",
|
||||
releaseID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tracks, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) GetReleaseCredits(releaseID string) ([]*model.Credit, error) {
|
||||
rows, err := repo.db.Query(
|
||||
"SELECT artist.id,artist.name,artist.website,artist.avatar,role,is_primary "+
|
||||
"FROM musiccredit "+
|
||||
"JOIN artist ON artist=artist.id "+
|
||||
"JOIN musicrelease ON release=musicrelease.id "+
|
||||
"WHERE musicrelease.id=$1 "+
|
||||
"ORDER BY is_primary DESC",
|
||||
releaseID,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var credits []*model.Credit
|
||||
for rows.Next() {
|
||||
credit := &model.Credit{
|
||||
Artist: &model.Artist{},
|
||||
}
|
||||
rows.Scan(
|
||||
&credit.Artist.ID,
|
||||
&credit.Artist.Name,
|
||||
&credit.Artist.Website,
|
||||
&credit.Artist.Avatar,
|
||||
&credit.Role,
|
||||
&credit.Primary)
|
||||
credits = append(credits, credit)
|
||||
}
|
||||
|
||||
return credits, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) GetReleaseLinks(releaseID string) ([]*model.Link, error) {
|
||||
var links = []*model.Link{}
|
||||
|
||||
err := repo.db.Select(&links, "SELECT name,url FROM musiclink WHERE release=$1", releaseID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return links, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) CreateRelease(
|
||||
id string,
|
||||
title string,
|
||||
releaseType model.ReleaseType,
|
||||
releaseDate time.Time,
|
||||
artworkURL string,
|
||||
) error {
|
||||
_, err := repo.db.Exec(
|
||||
"INSERT INTO musicrelease "+
|
||||
"(id, title, type, release_date, artwork) "+
|
||||
"VALUES ($1, $2, $3, $4, $5)",
|
||||
id,
|
||||
title,
|
||||
releaseType,
|
||||
releaseDate.Format("2006-01-02 15:04:05"),
|
||||
artworkURL,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) UpdateRelease(release *model.Release) error {
|
||||
_, err := repo.db.Exec(
|
||||
"UPDATE musicrelease SET "+
|
||||
"visible=$2, title=$3, description=$4, type=$5, release_date=$6, artwork=$7, buyname=$8, buylink=$9, copyright=$10, copyrighturl=$11 "+
|
||||
"WHERE id=$1",
|
||||
release.ID,
|
||||
release.Visible,
|
||||
release.Title,
|
||||
release.Description,
|
||||
release.ReleaseType,
|
||||
release.ReleaseDate.Format("2006-01-02 15:04:05"),
|
||||
release.Artwork,
|
||||
release.Buyname,
|
||||
release.Buylink,
|
||||
release.Copyright,
|
||||
release.CopyrightURL,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) UpdateReleaseID(oldID string, newID string) error {
|
||||
_, err := repo.db.Exec("UPDATE musicrelease SET id=$2 WHERE id=$1", oldID, newID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) UpdateReleaseVisibility(id string, visible bool) error {
|
||||
_, err := repo.db.Exec("UPDATE musicrelease SET visible=$2 WHERE id=$1", id, visible)
|
||||
return err
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateReleaseTitle(id string, title string) error {
|
||||
_, err := repo.db.Exec("UPDATE musicrelease SET title=$2 WHERE id=$1", id, title)
|
||||
return err
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateReleaseDescription(id string, description string) error {
|
||||
_, err := repo.db.Exec("UPDATE musicrelease SET description=$2 WHERE id=$1", id, description)
|
||||
return err
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateReleaseType(id string, releaseType model.ReleaseType) error {
|
||||
_, err := repo.db.Exec("UPDATE musicrelease SET type=$2 WHERE id=$1", id, releaseType)
|
||||
return err
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateReleaseDate(id string, releaseDate time.Time) error {
|
||||
_, err := repo.db.Exec(
|
||||
"UPDATE musicrelease SET release_date=$2 WHERE id=$1",
|
||||
id,
|
||||
releaseDate.Format("2006-01-02 15:04:05"),
|
||||
)
|
||||
return err
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateReleaseArtwork(id string, artwork string) error {
|
||||
_, err := repo.db.Exec("UPDATE musicrelease SET artwork=$2 WHERE id=$1", id, artwork)
|
||||
return err
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateReleaseBuyInfo(id string, buyName string, buyLink string) error {
|
||||
_, err := repo.db.Exec(
|
||||
"UPDATE musicrelease SET buyname=$2,buylink=$3 WHERE id=$1",
|
||||
id, buyName, buyLink,
|
||||
)
|
||||
return err
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateReleaseCopyright(id string, copyright string, url string) error {
|
||||
_, err := repo.db.Exec(
|
||||
"UPDATE musicrelease SET copyright=$2,copyrighturl=$3 WHERE id=$1",
|
||||
id, copyright, url,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) UpdateReleaseTracks(releaseID string, newTrackIDs []string) error {
|
||||
tx, err := repo.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec("DELETE FROM musicreleasetrack WHERE release=$1", releaseID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i, trackID := range newTrackIDs {
|
||||
_, err = tx.Exec(
|
||||
"INSERT INTO musicreleasetrack "+
|
||||
"(release, track, number) "+
|
||||
"VALUES ($1, $2, $3)",
|
||||
releaseID,
|
||||
trackID,
|
||||
i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) UpdateReleaseCredits(releaseID string, newCredits []*model.Credit) error {
|
||||
tx, err := repo.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec("DELETE FROM musiccredit WHERE release=$1", releaseID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, credit := range newCredits {
|
||||
_, err = tx.Exec(
|
||||
"INSERT INTO musiccredit "+
|
||||
"(release, artist, role, is_primary) "+
|
||||
"VALUES ($1, $2, $3, $4)",
|
||||
releaseID,
|
||||
credit.Artist.ID,
|
||||
credit.Role,
|
||||
credit.Primary,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) UpdateReleaseLinks(releaseID string, newLinks []*model.Link) error {
|
||||
tx, err := repo.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = tx.Exec("DELETE FROM musiclink WHERE release=$1", releaseID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, link := range newLinks {
|
||||
_, err := tx.Exec(
|
||||
"INSERT INTO musiclink "+
|
||||
"(release, name, url) "+
|
||||
"VALUES ($1, $2, $3)",
|
||||
releaseID,
|
||||
link.Name,
|
||||
link.URL,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) DeleteRelease(id string) (string, error) {
|
||||
var deletedID string
|
||||
err := repo.db.Get(&deletedID, "DELETE FROM musicrelease WHERE id=$1", id)
|
||||
return deletedID, err
|
||||
}
|
||||
123
repository/music/track_memory.go
Normal file
123
repository/music/track_memory.go
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package music
|
||||
|
||||
import (
|
||||
"arimelody-web/errors"
|
||||
"arimelody-web/model"
|
||||
"slices"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func (repo *MusicRepositoryMemory) GetAllTracks() ([]*model.Track, error) {
|
||||
return repo.tracks, nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) GetTrackCount() (int, error) {
|
||||
return len(repo.tracks), nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) GetTrackByID(id string) (*model.Track, error) {
|
||||
index := slices.IndexFunc(repo.tracks, func(track *model.Track) bool {
|
||||
return track.ID == id
|
||||
})
|
||||
if index == -1 { return nil, nil }
|
||||
return repo.tracks[index], nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) GetOrphanTracks() ([]*model.Track, error) {
|
||||
return slices.DeleteFunc(repo.tracks, func(track *model.Track) bool {
|
||||
return slices.ContainsFunc(repo.releases, func(release *model.Release) bool {
|
||||
return slices.ContainsFunc(release.Tracks, func(releaseTrack *model.Track) bool {
|
||||
return releaseTrack.ID == track.ID
|
||||
})
|
||||
})
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) GetTracksNotOnRelease(releaseID string) ([]*model.Track, error) {
|
||||
release, err := repo.GetReleaseByID(releaseID)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
return slices.DeleteFunc(repo.tracks, func(track *model.Track) bool {
|
||||
return slices.ContainsFunc(release.Tracks, func(releaseTrack *model.Track) bool {
|
||||
return releaseTrack.ID == track.ID
|
||||
})
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) GetTrackReleases(trackID string) ([]*model.Release, error) {
|
||||
return slices.DeleteFunc(repo.releases, func(release *model.Release) bool {
|
||||
return !slices.ContainsFunc(release.Tracks, func(track *model.Track) bool {
|
||||
return track.ID == trackID
|
||||
})
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) CreateTrack(
|
||||
title string,
|
||||
description string,
|
||||
lyrics string,
|
||||
previewURL string,
|
||||
) (string, error) {
|
||||
id := strconv.Itoa(len(repo.tracks))
|
||||
repo.tracks = append(repo.tracks, &model.Track{
|
||||
ID: id,
|
||||
Title: title,
|
||||
Description: description,
|
||||
Lyrics: lyrics,
|
||||
PreviewURL: previewURL,
|
||||
})
|
||||
return id, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) UpdateTrack(track *model.Track) error {
|
||||
repoTrack, err := repo.GetTrackByID(track.ID)
|
||||
if err != nil { return err }
|
||||
if repoTrack == nil { return errors.NewNotExistError("Track does not exist") }
|
||||
|
||||
repoTrack.Title = track.Title
|
||||
repoTrack.Description = track.Description
|
||||
repoTrack.Lyrics = track.Lyrics
|
||||
repoTrack.PreviewURL = track.PreviewURL
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateTrackTitle(id string, title string) error {
|
||||
repoTrack, err := repo.GetTrackByID(id)
|
||||
if err != nil { return err }
|
||||
if repoTrack == nil { return errors.NewNotExistError("Track does not exist") }
|
||||
repoTrack.Title = title
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateTrackDescription(id string, description string) error {
|
||||
repoTrack, err := repo.GetTrackByID(id)
|
||||
if err != nil { return err }
|
||||
if repoTrack == nil { return errors.NewNotExistError("Track does not exist") }
|
||||
repoTrack.Description = description
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateTrackLyrics(id string, lyrics string) error {
|
||||
repoTrack, err := repo.GetTrackByID(id)
|
||||
if err != nil { return err }
|
||||
if repoTrack == nil { return errors.NewNotExistError("Track does not exist") }
|
||||
repoTrack.Lyrics = lyrics
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryMemory) UpdateTrackPreviewURL(id string, previewURL string) error {
|
||||
repoTrack, err := repo.GetTrackByID(id)
|
||||
if err != nil { return err }
|
||||
if repoTrack == nil { return errors.NewNotExistError("Track does not exist") }
|
||||
repoTrack.PreviewURL = previewURL
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryMemory) DeleteTrack(id string) (string, error) {
|
||||
var deletedID string
|
||||
newTracks := []*model.Track{}
|
||||
for _, track := range repo.tracks {
|
||||
if track.ID == id {
|
||||
deletedID = id
|
||||
continue
|
||||
}
|
||||
newTracks = append(newTracks, track)
|
||||
}
|
||||
repo.tracks = newTracks
|
||||
return deletedID, nil
|
||||
}
|
||||
137
repository/music/track_postgres.go
Normal file
137
repository/music/track_postgres.go
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
package music
|
||||
|
||||
import (
|
||||
"arimelody-web/model"
|
||||
)
|
||||
|
||||
func (repo *MusicRepositoryPostgres) GetAllTracks() ([]*model.Track, error) {
|
||||
var tracks = []*model.Track{}
|
||||
|
||||
err := repo.db.Select(&tracks, "SELECT * FROM musictrack")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tracks, nil
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) GetTrackCount() (int, error) {
|
||||
var count int
|
||||
err := repo.db.Get(&count, "SELECT count(*) FROM musictrack")
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) GetTrackByID(id string) (*model.Track, error) {
|
||||
var track = model.Track{}
|
||||
|
||||
stmt, _ := repo.db.Preparex("SELECT * FROM musictrack WHERE id=$1")
|
||||
err := stmt.Get(&track, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &track, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) GetOrphanTracks() ([]*model.Track, error) {
|
||||
var tracks = []*model.Track{}
|
||||
|
||||
err := repo.db.Select(&tracks, "SELECT * FROM musictrack WHERE id NOT IN (SELECT track FROM musicreleasetrack)")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tracks, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) GetTracksNotOnRelease(releaseID string) ([]*model.Track, error) {
|
||||
var tracks = []*model.Track{}
|
||||
|
||||
err := repo.db.Select(&tracks,
|
||||
"SELECT * FROM musictrack "+
|
||||
"WHERE id NOT IN "+
|
||||
"(SELECT track FROM musicreleasetrack WHERE release=$1)",
|
||||
releaseID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tracks, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) GetTrackReleases(trackID string) ([]*model.Release, error) {
|
||||
var releases = []*model.Release{}
|
||||
|
||||
err := repo.db.Select(&releases,
|
||||
"SELECT id,title,type,release_date,artwork,buylink "+
|
||||
"FROM musicrelease "+
|
||||
"JOIN musicreleasetrack ON release=id "+
|
||||
"WHERE track=$1 "+
|
||||
"ORDER BY release_date",
|
||||
trackID,
|
||||
)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
return releases, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) CreateTrack(
|
||||
title string,
|
||||
description string,
|
||||
lyrics string,
|
||||
previewURL string,
|
||||
) (string, error) {
|
||||
var trackID string
|
||||
err := repo.db.QueryRow(
|
||||
"INSERT INTO musictrack (title, description, lyrics, preview_url) "+
|
||||
"VALUES ($1, $2, $3, $4) "+
|
||||
"RETURNING id",
|
||||
title,
|
||||
description,
|
||||
lyrics,
|
||||
previewURL,
|
||||
).Scan(&trackID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return trackID, nil
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) UpdateTrack(track *model.Track) error {
|
||||
_, err := repo.db.Exec(
|
||||
"UPDATE musictrack "+
|
||||
"SET title=$2, description=$3, lyrics=$4, preview_url=$5 "+
|
||||
"WHERE id=$1",
|
||||
track.ID,
|
||||
track.Title,
|
||||
track.Description,
|
||||
track.Lyrics,
|
||||
track.PreviewURL,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateTrackTitle(id string, title string) error {
|
||||
_, err := repo.db.Exec("UPDATE musictrack SET title=$2 WHERE id=$1", id, title)
|
||||
return err
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateTrackDescription(id string, description string) error {
|
||||
_, err := repo.db.Exec("UPDATE musictrack SET description=$2 WHERE id=$1", id, description)
|
||||
return err
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateTrackLyrics(id string, lyrics string) error {
|
||||
_, err := repo.db.Exec("UPDATE musictrack SET lyrics=$2 WHERE id=$1", id, lyrics)
|
||||
return err
|
||||
}
|
||||
func (repo *MusicRepositoryPostgres) UpdateTrackPreviewURL(id string, previewURL string) error {
|
||||
_, err := repo.db.Exec("UPDATE musictrack SET preview_url=$2 WHERE id=$1", id, previewURL)
|
||||
return err
|
||||
}
|
||||
|
||||
func (repo *MusicRepositoryPostgres) DeleteTrack(id string) (string, error) {
|
||||
var deletedID string
|
||||
err := repo.db.Get(&deletedID, "DELETE FROM musictrack WHERE id=$1 RETURNING id", id)
|
||||
return deletedID, err
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue