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.
1012type album struct {
11- ID string `json:"id"`
13+ ID int64 `json:"id"`
1214 Title string `json:"title"`
1315 Artist string `json:"artist"`
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 INTEGER PRIMARY KEY AUTOINCREMENT,
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+ {Title : "Blue Train" , Artist : "John Coltrane" , Price : 56.99 },
50+ {Title : "Jeru" , Artist : "Gerry Mulligan" , Price : 17.99 },
51+ {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 (title, artist, price) VALUES (?, ?, ?)" ,
56+ 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,22 @@ 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 and get the generated ID.
120+ result , err := db .Exec ("INSERT INTO albums (title, artist, price) VALUES (?, ?, ?)" ,
121+ newAlbum .Title , newAlbum .Artist , newAlbum .Price )
122+ if err != nil {
123+ c .IndentedJSON (http .StatusInternalServerError , gin.H {"error" : err .Error ()})
124+ return
125+ }
126+
127+ // Get the auto-generated ID
128+ id , err := result .LastInsertId ()
129+ if err != nil {
130+ c .IndentedJSON (http .StatusInternalServerError , gin.H {"error" : err .Error ()})
131+ return
132+ }
133+ newAlbum .ID = id
134+
56135 c .IndentedJSON (http .StatusCreated , newAlbum )
57136}
58137
@@ -61,13 +140,17 @@ func postAlbums(c *gin.Context) {
61140func getAlbumByID (c * gin.Context ) {
62141 id := c .Param ("id" )
63142
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- }
143+ var a album
144+ err := db .QueryRow ("SELECT id, title, artist, price FROM albums WHERE id = ?" , id ).
145+ Scan (& a .ID , & a .Title , & a .Artist , & a .Price )
146+
147+ if err == sql .ErrNoRows {
148+ c .IndentedJSON (http .StatusNotFound , gin.H {"message" : "album not found" })
149+ return
150+ } else if err != nil {
151+ c .IndentedJSON (http .StatusInternalServerError , gin.H {"error" : err .Error ()})
152+ return
71153 }
72- c .IndentedJSON (http .StatusNotFound , gin.H {"message" : "album not found" })
154+
155+ c .IndentedJSON (http .StatusOK , a )
73156}
0 commit comments