Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handlerの構造体を実装 #32

Open
wants to merge 2 commits into
base: segatomo-master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 208 additions & 0 deletions handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
package main

import (
"net/http"
"encoding/json"
"strconv"
"fmt"
"database/sql"
)

// Handlers HTTPハンドラを集めた型
type Handlers struct {
DB *sql.DB
}

// AvailableListHandler 公開されている宝くじ情報の一覧を取得
func (hs *Handlers) AvailableListHandler(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
}
}

// GetHandler IDを指定して宝くじ情報を取得する
func (hs *Handlers) GetHandler(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
}
}

// PurchaseHandler 宝くじの購入
func (hs *Handlers) PurchaseHandler (w http.ResponseWriter, r *http.Request) {

db := hs.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)
}


// ResultHandler 結果を取得
func (hs *Handlers) ResultHandler(w http.ResponseWriter, r *http.Request) {

db := hs.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
}
}
Loading