package main import ( "arimelody.me/arimelody.me/api/v1/music" "fmt" "os" "time" _ "github.com/lib/pq" "github.com/jmoiron/sqlx" ) var schema = `CREATE TABLE IF NOT EXISTS Artists ( id SERIAL primary key, name text, website text ); CREATE TABLE IF NOT EXISTS Albums ( id varchar(64) primary key, title text not null, release_date date not null, artwork text, buyname text, buylink text, description text, lyrics text ); CREATE TABLE IF NOT EXISTS AlbumLinks ( album varchar(64) references Albums(id) on delete cascade, name text, url text, constraint albumlinks_pk primary key (album, name) ); CREATE TABLE IF NOT EXISTS AlbumCredits ( album varchar(64) references Albums(id) on delete cascade, artist int references Artists(id) on delete cascade, role text constraint albumcredits_pk primary key (album, artist, role) );` func PushArtist(db *sqlx.DB, artist music.Artist) { query := "SELECT count(*) FROM Artists WHERE name=$1" var count int err := db.Get(&count, query, artist.Name) if err != nil { fmt.Printf("error while pushing artist [%s] to the database: %v\n", artist.Name, err) } query = "INSERT INTO artists (name, website) VALUES ($1, $2)" if count != 0 { query = "UPDATE artists SET website=$2 WHERE name=$1" } fmt.Printf("saving artist [%s] to the database...", artist.Name) _, err = db.Exec(query, &artist.Name, &artist.Website, ) if err != nil { fmt.Printf("error while pushing artist [%s] to the database: %v\n", artist.Name, err) } fmt.Printf("done!\n") // defer db.Close() } func PushAlbum(db *sqlx.DB, album music.Album) { var count int err := db.Get(&count, "SELECT count(*) FROM Albums WHERE id=$1", album.Id) if err != nil { fmt.Printf("error while pushing album [%s] to the database: %v\n", album.Id, err) } artist_ids := map[string]int{}; for _, credit := range album.Credits { if _, ok := artist_ids[credit.Artist.Name]; ok { continue; } var id int err := db.Get(&id, "SELECT id FROM Artists WHERE name=$1", credit.Artist.Name) if err != nil { continue; } artist_ids[credit.Artist.Name] = id } if count == 0 { fmt.Printf("creating album [%s]...", album.Id) tx := db.MustBegin() tx.MustExec("INSERT INTO Albums VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", &album.Id, &album.Title, album.ReleaseDate.Format("2-Jan-2006"), &album.Artwork, &album.Buyname, &album.Buylink, &album.Description, &album.Lyrics) for _, link := range album.Links { tx.MustExec("INSERT INTO AlbumLinks (album, name, url) VALUES ($1, $2, $3)", &album.Id, &link.Name, &link.Url) } for _, credit := range album.Credits { artist_id := artist_ids[credit.Artist.Name] tx.MustExec("INSERT INTO AlbumCredits (album, artist, role) VALUES ($1, $2, $3)", &album.Id, &artist_id, &credit.Role) } tx.Commit() fmt.Printf("done!\n") return; } fmt.Printf("updating album [%s]...", album.Id) tx := db.MustBegin() tx.MustExec("UPDATE Albums SET title=$2, release_date=$3, artwork=$4, buyname=$5, buylink=$6, description=$7, lyrics=$8 WHERE id=$1", &album.Id, &album.Title, album.ReleaseDate.Format("2-Jan-2006"), &album.Artwork, &album.Buyname, &album.Buylink, &album.Description, &album.Lyrics, ) // we're just gonna completely fresh them because // like hell am i actually gonna comb through every // single one of these tx.MustExec("DELETE FROM AlbumLinks WHERE album=$1", &album.Id) tx.MustExec("DELETE FROM AlbumCredits WHERE album=$1", &album.Id) for _, link := range album.Links { tx.MustExec("INSERT INTO AlbumLinks (album, name, url) VALUES ($1, $2, $3)", &album.Id, &link.Name, &link.Url) } for _, credit := range album.Credits { artist_id := artist_ids[credit.Artist.Name] tx.MustExec("INSERT INTO AlbumCredits (album, artist, role) VALUES ($1, $2, $3)", &album.Id, &artist_id, &credit.Role) } tx.Commit() fmt.Printf("done!\n") } func InitDatabase() *sqlx.DB { db, err := sqlx.Connect("postgres", "user=arimimi 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) // db.MustExec(schema) return db }