From 688c60ed478ee8616240aaf0a736390b1fb8dcba Mon Sep 17 00:00:00 2001 From: tomowarkar <3104kawamoto@gmail.com> Date: Sun, 27 Oct 2019 17:32:25 +0900 Subject: [PATCH 1/2] fix typo --- types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types.go b/types.go index 0f88802..77e8c81 100644 --- a/types.go +++ b/types.go @@ -14,7 +14,7 @@ type Lottery struct { type Prize struct { ID string `json:"id"` - Name string `json:"name` + Name string `json:"name"` Num int64 `json:"num"` Amount int64 `json:"amount"` } From 5dee6ae6da3c6605aedfb2013b4fc9fe41d1d58a Mon Sep 17 00:00:00 2001 From: tomowarkar <3104kawamoto@gmail.com> Date: Sun, 27 Oct 2019 17:33:02 +0900 Subject: [PATCH 2/2] =?UTF-8?q?handler=20dir=E5=88=86=E5=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handler.go | 195 +++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 188 ++------------------------------------------------- 2 files changed, 202 insertions(+), 181 deletions(-) create mode 100644 handler.go diff --git a/handler.go b/handler.go new file mode 100644 index 0000000..bba7f1c --- /dev/null +++ b/handler.go @@ -0,0 +1,195 @@ +package main + +import ( + "database/sql" + "encoding/json" + "net/http" + "fmt" + "strconv" +) + +type handler struct { + DB *sql.DB +} + +func (h *handler) Index(w http.ResponseWriter, r *http.Request) { + resp, err := http.Get("https://lottery-dot-tenntenn-samples.appspot.com/available_lotteries") + if err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + defer resp.Body.Close() + + var lotteries []*Lottery + if err := json.NewDecoder(resp.Body).Decode(&lotteries); err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + + if err := listTmpl.Execute(w, lotteries); err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } +} +func (h *handler) PurchasePage(w http.ResponseWriter, r *http.Request) { + resp, err := http.Get("https://lottery-dot-tenntenn-samples.appspot.com/lottery?id=" + r.FormValue("id")) + if err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + defer resp.Body.Close() + + var l Lottery + if err := json.NewDecoder(resp.Body).Decode(&l); err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + + data := struct { + Lottery + Remain int64 + }{ + Lottery: l, + Remain: l.Num, // TODO: 残りを計算する + } + if err := purchasePageTmpl.Execute(w, data); err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } +} +func (h *handler) Purchase(w http.ResponseWriter, r *http.Request) { + db := h.DB + id := r.FormValue("id") + num, err := strconv.Atoi(r.FormValue("num")) + if err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + // TODO: パラメタのバリデーション + + resp, err := http.Get("https://lottery-dot-tenntenn-samples.appspot.com/lottery?id=" + id) + if err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + defer resp.Body.Close() + + var l Lottery + if err := json.NewDecoder(resp.Body).Decode(&l); err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + + var count int + if err := db.QueryRow("SELECT COUNT(*) FROM purchased WHERE lottery_id = ?", l.ID).Scan(&count); err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + + for i := 1; i <= num; i++ { + const sql = "INSERT INTO purchased(lottery_id, number) values (?,?)" + format := fmt.Sprintf(`%%0%dd`, len(strconv.FormatInt(l.Num-1, 10))) + n := fmt.Sprintf(format, count+i) + if _, err := db.Exec(sql, id, n); err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + } + + http.Redirect(w, r, "/purchase_page?id="+l.ID, http.StatusFound) +} +func (h *handler) Result(w http.ResponseWriter, r *http.Request) { + db := h.DB + resp1, err := http.Get("https://lottery-dot-tenntenn-samples.appspot.com/result?id=" + r.FormValue("id")) + if err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + defer resp1.Body.Close() + + var result Result + if err := json.NewDecoder(resp1.Body).Decode(&result); err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + + resp2, err := http.Get("https://lottery-dot-tenntenn-samples.appspot.com/lottery?id=" + r.FormValue("id")) + if err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + defer resp2.Body.Close() + + var l Lottery + if err := json.NewDecoder(resp2.Body).Decode(&l); err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + + type winner struct { + Prize *Prize + Numbers []string + } + + data := struct { + Lottery + Winners map[string]*winner + }{ + Lottery: l, + Winners: map[string]*winner{}, + } + + rows, err := db.Query("SELECT number FROM purchased WHERE lottery_id = ?", l.ID) + if err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + for rows.Next() { + var number string + if err := rows.Scan(&number); err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } + + for i := range result.Winners { + for _, n := range result.Winners[i].Numbers { + if number == n { + prizeID := result.Winners[i].PrizeID + if data.Winners[prizeID] == nil { + for _, p := range l.Prizes { + if p.ID == prizeID { + data.Winners[prizeID] = &winner{ + Prize: p, + } + } + } + } + data.Winners[prizeID].Numbers = append(data.Winners[prizeID].Numbers, n) + } + } + } + } + + if err := resultTmpl.Execute(w, data); err != nil { + const status = http.StatusInternalServerError + http.Error(w, http.StatusText(status), status) + return + } +} \ No newline at end of file diff --git a/main.go b/main.go index 34194b1..9ab5680 100644 --- a/main.go +++ b/main.go @@ -11,12 +11,9 @@ TODO import ( "database/sql" - "encoding/json" - "fmt" "net" "net/http" "os" - "strconv" _ "github.com/mattn/go-sqlite3" ) @@ -32,188 +29,17 @@ func main() { panic(err) } - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - resp, err := http.Get("https://lottery-dot-tenntenn-samples.appspot.com/available_lotteries") - if err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - defer resp.Body.Close() - - var lotteries []*Lottery - if err := json.NewDecoder(resp.Body).Decode(&lotteries); err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - - if err := listTmpl.Execute(w, lotteries); err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - }) - - http.HandleFunc("/purchase_page", func(w http.ResponseWriter, r *http.Request) { - resp, err := http.Get("https://lottery-dot-tenntenn-samples.appspot.com/lottery?id=" + r.FormValue("id")) - if err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - defer resp.Body.Close() - - var l Lottery - if err := json.NewDecoder(resp.Body).Decode(&l); err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - - data := struct { - Lottery - Remain int64 - }{ - Lottery: l, - Remain: l.Num, // TODO: 残りを計算する - } - if err := purchasePageTmpl.Execute(w, data); err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - }) - - http.HandleFunc("/purchase", func(w http.ResponseWriter, r *http.Request) { - id := r.FormValue("id") - num, err := strconv.Atoi(r.FormValue("num")) - if err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - // TODO: パラメタのバリデーション - - resp, err := http.Get("https://lottery-dot-tenntenn-samples.appspot.com/lottery?id=" + id) - if err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - defer resp.Body.Close() - - var l Lottery - if err := json.NewDecoder(resp.Body).Decode(&l); err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - - var count int - if err := db.QueryRow("SELECT COUNT(*) FROM purchased WHERE lottery_id = ?", l.ID).Scan(&count); err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - - for i := 1; i <= num; i++ { - const sql = "INSERT INTO purchased(lottery_id, number) values (?,?)" - format := fmt.Sprintf(`%%0%dd`, len(strconv.FormatInt(l.Num-1, 10))) - n := fmt.Sprintf(format, count+i) - if _, err := db.Exec(sql, id, n); err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - } - - http.Redirect(w, r, "/purchase_page?id="+l.ID, http.StatusFound) - }) - - http.HandleFunc("/result", func(w http.ResponseWriter, r *http.Request) { - resp1, err := http.Get("https://lottery-dot-tenntenn-samples.appspot.com/result?id=" + r.FormValue("id")) - if err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - defer resp1.Body.Close() - - var result Result - if err := json.NewDecoder(resp1.Body).Decode(&result); err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - - resp2, err := http.Get("https://lottery-dot-tenntenn-samples.appspot.com/lottery?id=" + r.FormValue("id")) - if err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - defer resp2.Body.Close() - - var l Lottery - if err := json.NewDecoder(resp2.Body).Decode(&l); err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - - type winner struct { - Prize *Prize - Numbers []string - } + h := &handler{ + DB: db, + } - data := struct { - Lottery - Winners map[string]*winner - }{ - Lottery: l, - Winners: map[string]*winner{}, - } + http.HandleFunc("/", h.Index) - rows, err := db.Query("SELECT number FROM purchased WHERE lottery_id = ?", l.ID) - if err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - for rows.Next() { - var number string - if err := rows.Scan(&number); err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } + http.HandleFunc("/purchase_page", h.PurchasePage) - for i := range result.Winners { - for _, n := range result.Winners[i].Numbers { - if number == n { - prizeID := result.Winners[i].PrizeID - if data.Winners[prizeID] == nil { - for _, p := range l.Prizes { - if p.ID == prizeID { - data.Winners[prizeID] = &winner{ - Prize: p, - } - } - } - } - data.Winners[prizeID].Numbers = append(data.Winners[prizeID].Numbers, n) - } - } - } - } + http.HandleFunc("/purchase", h.Purchase) - if err := resultTmpl.Execute(w, data); err != nil { - const status = http.StatusInternalServerError - http.Error(w, http.StatusText(status), status) - return - } - }) + http.HandleFunc("/result", h.Result) port := os.Getenv("PORT") if port == "" {