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 TEXT PRIMARY KEY, name TEXT, website TEXT ); CREATE TABLE IF NOT EXISTS musicreleases ( id VARCHAR(64) PRIMARY KEY, title TEXT NOT NULL, type TEXT, release_date DATE NOT NULL, artwork TEXT, buyname TEXT, buylink TEXT ); CREATE TABLE IF NOT EXISTS musiclinks ( release VARCHAR(64) REFERENCES musicreleases(id) ON DELETE CASCADE ON UPDATE CASCADE, name TEXT, url TEXT, CONSTRAINT musiclinks_pk PRIMARY KEY (release, name) ); CREATE TABLE IF NOT EXISTS musiccredits ( release VARCHAR(64) REFERENCES musicreleases(ID) ON DELETE CASCADE, artist TEXT REFERENCES artists(id) ON DELETE CASCADE, role TEXT, meta BOOLEAN, constraint musiccredits_pk PRIMARY KEY (release, artist) ); CREATE TABLE IF NOT EXISTS musictracks ( release VARCHAR(64) REFERENCES musicreleases(ID) ON DELETE CASCADE, number INT NOT NULL, title TEXT NOT NULL, description TEXT, lyrics TEXT, preview_url TEXT, CONSTRAINT musictracks_pk PRIMARY KEY (release, number) );` func PushArtist(db *sqlx.DB, artist music.Artist) { fmt.Printf("syncing 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 PushRelease(db *sqlx.DB, release music.MusicRelease) { fmt.Printf("syncing 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, meta) VALUES ($1, $2, $3, $4) ON CONFLICT DO NOTHING", &release.Id, &credit.Artist.Id, &credit.Role, &credit.Meta) } 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 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) db.MustExec(schema) fmt.Printf("database schema synchronised.\n") return db }