+package artist
+
+import (
+ "database/sql"
+ "encoding/json"
+ "git.jacobcasper.com/brackets/env"
+ "git.jacobcasper.com/brackets/routes"
+ "git.jacobcasper.com/brackets/types"
+ "github.com/zmb3/spotify"
+ "log"
+ "net/http"
+)
+
+func Index(env *env.Env) routes.Handler {
+ return func(w http.ResponseWriter, r *http.Request) {
+ if r.Method != "GET" {
+ http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+
+ artistId := r.FormValue("id")
+ if artistId != "" {
+ artist := types.Artist{}
+ row := env.Db.Db.QueryRow(`
+SELECT ID, NAME, POPULARITY
+FROM ARTIST
+WHERE ID = ?`,
+ artistId,
+ )
+ if err := row.Scan(&artist.ID, &artist.Name, &artist.Popularity); err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ b, err := json.Marshal(artist)
+ if err != nil {
+ log.Print(err)
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ w.Write(b)
+ return
+ }
+
+ rows, err := env.Db.Db.Query(`
+SELECT ID, NAME, POPULARITY
+FROM ARTIST
+LIMIT 20`,
+ )
+ if err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ defer rows.Close()
+
+ artists := make([]types.Artist, 0)
+ for rows.Next() {
+ artist := types.Artist{}
+ if err := rows.Scan(&artist.ID, &artist.Name, &artist.Popularity); err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ artists = append(artists, artist)
+ }
+ if err = rows.Err(); err != nil {
+ log.Print(err)
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ b, err := json.Marshal(artists)
+ if err != nil {
+ log.Print(err)
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ w.Write(b)
+ }
+}
+
+func Add(env *env.Env) routes.Handler {
+ return func(w http.ResponseWriter, r *http.Request) {
+ if r.Method != "POST" {
+ http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
+ return
+ }
+
+ r.ParseForm()
+ artistId := r.PostForm.Get("id")
+
+ if artistId == "" {
+ http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
+ return
+ }
+
+ artist, err := env.C.GetArtist(spotify.ID(artistId))
+ if err != nil {
+ log.Printf("Failed to retrieve artist %s: %s", artistId, err.Error())
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+
+ env.Db.Mu.Lock()
+ defer env.Db.Mu.Unlock()
+ env.Db.Db.Exec(`
+INSERT INTO ARTIST
+(ID, NAME, POPULARITY)
+VALUES (?, ?, ?)`,
+ artist.ID,
+ artist.Name,
+ artist.Popularity,
+ )
+
+ for _, genre := range artist.Genres {
+ var genreId int64
+ row := env.Db.Db.QueryRow(`
+SELECT ID
+FROM GENRE
+WHERE NAME = lower(?)
+`,
+ genre,
+ )
+
+ err := row.Scan(&genreId)
+ if err == sql.ErrNoRows {
+ result, err := env.Db.Db.Exec(`
+INSERT INTO GENRE
+(NAME)
+VALUES (?)`,
+ genre,
+ )
+ if err != nil {
+ log.Printf("Failed to insert genre %s: %s", genre, err.Error())
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+
+ genreId, err = result.LastInsertId()
+ if err != nil {
+ log.Print("Failed to retrieve last insert id: ", err.Error())
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ }
+
+ env.Db.Db.Exec(`
+INSERT INTO ARTIST_GENRE_XREF
+(ARTIST_ID, GENRE_ID)
+VALUES (?, ?)`,
+ artist.ID,
+ genreId,
+ )
+ }
+ w.WriteHeader(http.StatusCreated)
+ }
+}
+
+func ByGenre(env *env.Env) routes.Handler {
+ return func(w http.ResponseWriter, r *http.Request) {
+ if r.Method != "GET" {
+ http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
+ return
+ }
+
+ w.Header().Set("Content-Type", "application/json")
+ genreName := r.FormValue("genre_name")
+ if genreName != "" {
+ rows, err := env.Db.Db.Query(`
+SELECT a.ID, a.NAME
+FROM ARTIST a
+JOIN ARTIST_GENRE_XREF x ON a.ID = x.ARTIST_ID
+JOIN GENRE g ON g.ID = x.GENRE_ID
+WHERE g.NAME = lower(?)
+`,
+ genreName,
+ )
+ if err != nil {
+ log.Print(err)
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ defer rows.Close()
+
+ artists := make([]types.Artist, 0)
+ for rows.Next() {
+ artist := types.Artist{}
+ if err := rows.Scan(&artist.ID, &artist.Name, &artist.Popularity); err != nil {
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ artists = append(artists, artist)
+ }
+ if err = rows.Err(); err != nil {
+ log.Print(err)
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ b, err := json.Marshal(artists)
+ if err != nil {
+ log.Print(err)
+ http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
+ return
+ }
+ w.Write(b)
+ }
+ }
+}