package main import ( "arimelody.me/arimelody.me/api/v1/music" "fmt" "os" "time" "github.com/jmoiron/sqlx" _ "github.com/lib/pq" ) func PushArtist(db *sqlx.DB, artist music.Artist) { fmt.Printf("pushing artist [%s] to database...", artist.Name) db.MustExec("INSERT INTO artists (id, name, website) VALUES ($1, $2, $3) ON CONFLICT (id) DO UPDATE SET name=$2, website=$3", &artist.Id, &artist.Name, &artist.Website, ) fmt.Printf("done!\n") } func PullAllArtists(db *sqlx.DB) ([]*music.Artist, error) { artists := []*music.Artist{} rows, err := db.Query("SELECT id, name, website FROM artists") if err != nil { return nil, err } for rows.Next() { var artist = music.Artist{} err = rows.Scan(&artist.Id, &artist.Name, &artist.Website) if err != nil { return nil, err } artists = append(artists, &artist) } return artists, nil } func PullArtist(db *sqlx.DB, artistID string) (music.Artist, error) { artist := music.Artist{} err := db.Get(&artist, "SELECT id, name, website FROM artists WHERE id=$1", artistID) if err != nil { return music.Artist{}, err } return artist, nil } func PushRelease(db *sqlx.DB, release music.MusicRelease) { fmt.Printf("pushing release [%s] to database...", release.Id) tx := db.MustBegin() tx.MustExec("INSERT INTO musicreleases (id, title, type, release_date, artwork, buyname, buylink) VALUES ($1, $2, $3, $4, $5, $6, $7) "+ "ON CONFLICT (id) DO UPDATE SET title=$2, type=$3, release_date=$4, artwork=$5, buyname=$6, buylink=$7", &release.Id, &release.Title, &release.Type, release.ReleaseDate.Format("2-Jan-2006"), &release.Artwork, &release.Buyname, &release.Buylink) for _, link := range release.Links { tx.MustExec("INSERT INTO musiclinks (release, name, url) VALUES ($1, $2, $3) ON CONFLICT (release, name) DO UPDATE SET url=$3", &release.Id, &link.Name, &link.Url) } for _, credit := range release.Credits { tx.MustExec("INSERT INTO musiccredits (release, artist, role, is_primary) VALUES ($1, $2, $3, $4) ON CONFLICT DO NOTHING", &release.Id, &credit.Artist.Id, &credit.Role, &credit.Primary) } for _, track := range release.Tracks { tx.MustExec("INSERT INTO musictracks (release, number, title, description, lyrics, preview_url) VALUES ($1, $2, $3, $4, $5, $6) "+ "ON CONFLICT (release, number) DO UPDATE SET title=$3, description=$4, lyrics=$5, preview_url=$6", &release.Id, &track.Number, &track.Title, &track.Description, &track.Lyrics, &track.PreviewUrl) } tx.Commit() fmt.Printf("done!\n") } func PullAllReleases(db *sqlx.DB) ([]*music.MusicRelease, error) { releases := []*music.MusicRelease{} rows, err := db.Query("SELECT id, title, type, release_date, artwork, buyname, buylink FROM musicreleases") if err != nil { return nil, err } for rows.Next() { var release = music.MusicRelease{} release.Credits = []music.MusicCredit{} release.Links = []music.MusicLink{} release.Tracks = []music.MusicTrack{} err = rows.Scan( &release.Id, &release.Title, &release.Type, &release.ReleaseDate, &release.Artwork, &release.Buyname, &release.Buylink) if err != nil { continue } // pull musiccredits for artist data credit_rows, err := db.Query("SELECT artist, role, is_primary FROM musiccredits WHERE release=$1", release.Id) if err != nil { fmt.Printf("error pulling credits for %s: %v\n", release.Id, err) continue } for credit_rows.Next() { var artistID string var credit = music.MusicCredit{} err = credit_rows.Scan( &artistID, &credit.Role, &credit.Primary) if err != nil { fmt.Printf("error pulling credit for %s: %v\n", release.Id, err) continue } artist, err := music.GetArtist(artistID) if err != nil { fmt.Printf("error pulling credit for %s: %v\n", release.Id, err) continue } credit.Artist = artist release.Credits = append(release.Credits, credit) } // pull musiclinks for link data link_rows, err := db.Query("SELECT name, url FROM musiclinks WHERE release=$1", release.Id); if err != nil { fmt.Printf("error pulling links for %s: %v\n", release.Id, err) continue } for link_rows.Next() { var link = music.MusicLink{} err = link_rows.Scan( &link.Name, &link.Url) if err != nil { fmt.Printf("error pulling link for %s: %v\n", release.Id, err) continue } release.Links = append(release.Links, link) } // pull musictracks for track data track_rows, err := db.Query("SELECT number, title, description, lyrics, preview_url FROM musictracks WHERE release=$1", release.Id); if err != nil { fmt.Printf("error pulling tracks for %s: %v\n", release.Id, err) continue } for track_rows.Next() { var track = music.MusicTrack{} err = track_rows.Scan( &track.Number, &track.Title, &track.Description, &track.Lyrics, &track.PreviewUrl) if err != nil { fmt.Printf("error pulling track for %s: %v\n", release.Id, err) continue } release.Tracks = append(release.Tracks, track) } releases = append(releases, &release) } return releases, nil } func PullRelease(db *sqlx.DB, releaseID string) (music.MusicRelease, error) { release := music.MusicRelease{} err := db.Get(&release, "SELECT id, title, type, release_date, artwork, buyname, buylink FROM musicreleases WHERE id=$1", releaseID) if err != nil { return music.MusicRelease{}, err } return release, nil } func InitDatabase() *sqlx.DB { db, err := sqlx.Connect("postgres", "user=arimelody dbname=arimelody password=fuckingpassword sslmode=disable") if err != nil { fmt.Fprintf(os.Stderr, "unable to create database connection pool: %v\n", err) os.Exit(1) } db.SetConnMaxLifetime(time.Minute * 3) db.SetMaxOpenConns(10) db.SetMaxIdleConns(10) return db }