11package api
22
33import (
4+ "database/sql"
45 "net/http"
56
67 "github.com/gin-gonic/gin"
8+ _ "github.com/mattn/go-sqlite3"
79)
810
911// album represents data about a record album.
@@ -14,11 +16,51 @@ type album struct {
1416 Price float64 `json:"price"`
1517}
1618
17- // albums slice to seed record album data.
18- var albums = []album {
19- {ID : "1" , Title : "Blue Train" , Artist : "John Coltrane" , Price : 56.99 },
20- {ID : "2" , Title : "Jeru" , Artist : "Gerry Mulligan" , Price : 17.99 },
21- {ID : "3" , Title : "Sarah Vaughan and Clifford Brown" , Artist : "Sarah Vaughan" , Price : 39.99 },
19+ var db * sql.DB
20+
21+ func initDB () error {
22+ var err error
23+ db , err = sql .Open ("sqlite3" , "./albums.db" )
24+ if err != nil {
25+ return err
26+ }
27+
28+ createTableSQL := `CREATE TABLE IF NOT EXISTS albums (
29+ id TEXT PRIMARY KEY,
30+ title TEXT NOT NULL,
31+ artist TEXT NOT NULL,
32+ price REAL NOT NULL
33+ );`
34+
35+ _ , err = db .Exec (createTableSQL )
36+ if err != nil {
37+ return err
38+ }
39+
40+ // Check if table is empty and seed with initial data
41+ var count int
42+ err = db .QueryRow ("SELECT COUNT(*) FROM albums" ).Scan (& count )
43+ if err != nil {
44+ return err
45+ }
46+
47+ if count == 0 {
48+ seedData := []album {
49+ {ID : "1" , Title : "Blue Train" , Artist : "John Coltrane" , Price : 56.99 },
50+ {ID : "2" , Title : "Jeru" , Artist : "Gerry Mulligan" , Price : 17.99 },
51+ {ID : "3" , Title : "Sarah Vaughan and Clifford Brown" , Artist : "Sarah Vaughan" , Price : 39.99 },
52+ }
53+
54+ for _ , a := range seedData {
55+ _ , err = db .Exec ("INSERT INTO albums (id, title, artist, price) VALUES (?, ?, ?, ?)" ,
56+ a .ID , a .Title , a .Artist , a .Price )
57+ if err != nil {
58+ return err
59+ }
60+ }
61+ }
62+
63+ return nil
2264}
2365
2466// setupRouter configures and returns the Gin router with all routes
@@ -32,12 +74,35 @@ func setupRouter() *gin.Engine {
3274}
3375
3476func main () {
77+ if err := initDB (); err != nil {
78+ panic (err )
79+ }
80+ defer db .Close ()
81+
3582 router := setupRouter ()
3683 router .Run ("localhost:8080" )
3784}
3885
3986// getAlbums responds with the list of all albums as JSON.
4087func getAlbums (c * gin.Context ) {
88+ rows , err := db .Query ("SELECT id, title, artist, price FROM albums" )
89+ if err != nil {
90+ c .IndentedJSON (http .StatusInternalServerError , gin.H {"error" : err .Error ()})
91+ return
92+ }
93+ defer rows .Close ()
94+
95+ var albums []album
96+ for rows .Next () {
97+ var a album
98+ err := rows .Scan (& a .ID , & a .Title , & a .Artist , & a .Price )
99+ if err != nil {
100+ c .IndentedJSON (http .StatusInternalServerError , gin.H {"error" : err .Error ()})
101+ return
102+ }
103+ albums = append (albums , a )
104+ }
105+
41106 c .IndentedJSON (http .StatusOK , albums )
42107}
43108
@@ -51,8 +116,14 @@ func postAlbums(c *gin.Context) {
51116 return
52117 }
53118
54- // Add the new album to the slice.
55- albums = append (albums , newAlbum )
119+ // Insert the new album into the database.
120+ _ , err := db .Exec ("INSERT INTO albums (id, title, artist, price) VALUES (?, ?, ?, ?)" ,
121+ newAlbum .ID , newAlbum .Title , newAlbum .Artist , newAlbum .Price )
122+ if err != nil {
123+ c .IndentedJSON (http .StatusInternalServerError , gin.H {"error" : err .Error ()})
124+ return
125+ }
126+
56127 c .IndentedJSON (http .StatusCreated , newAlbum )
57128}
58129
@@ -61,13 +132,17 @@ func postAlbums(c *gin.Context) {
61132func getAlbumByID (c * gin.Context ) {
62133 id := c .Param ("id" )
63134
64- // Loop through the list of albums, looking for
65- // an album whose ID value matches the parameter.
66- for _ , a := range albums {
67- if a .ID == id {
68- c .IndentedJSON (http .StatusOK , a )
69- return
70- }
135+ var a album
136+ err := db .QueryRow ("SELECT id, title, artist, price FROM albums WHERE id = ?" , id ).
137+ Scan (& a .ID , & a .Title , & a .Artist , & a .Price )
138+
139+ if err == sql .ErrNoRows {
140+ c .IndentedJSON (http .StatusNotFound , gin.H {"message" : "album not found" })
141+ return
142+ } else if err != nil {
143+ c .IndentedJSON (http .StatusInternalServerError , gin.H {"error" : err .Error ()})
144+ return
71145 }
72- c .IndentedJSON (http .StatusNotFound , gin.H {"message" : "album not found" })
146+
147+ c .IndentedJSON (http .StatusOK , a )
73148}
0 commit comments