Created
February 21, 2017 07:45
-
-
Save sekky0905/4baadb7cadf7ee83312acd94300d38d0 to your computer and use it in GitHub Desktop.
GAE/Go Datastore manipulation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tictactoego | |
import ( | |
"fmt" | |
"net/http" | |
"time" | |
"google.golang.org/appengine" | |
"google.golang.org/appengine/datastore" | |
"html/template" | |
"google.golang.org/appengine/taskqueue" | |
"google.golang.org/appengine/log" | |
) | |
func init() { | |
// ハンドラ登録 | |
http.HandleFunc("/", DoPut) | |
http.HandleFunc("/result", DoGet) | |
http.HandleFunc("/job", DoJob) | |
} | |
// 過去の戦績を表す構造体 | |
type BattleResults struct { | |
// 確認用の数字 | |
CheckNum int | |
// 勝者のID | |
WinnerID int | |
// 敗者のID | |
LoserID int | |
// インタンス作成時のタイムスタンプ | |
CreateAt time.Time | |
// インタンス更新時のタイムスタンプ | |
UpdatedAt time.Time | |
} | |
// 実験的 | |
func DoPut(w http.ResponseWriter, r *http.Request) { | |
fmt.Println(Sum(1, 2)) | |
c := appengine.NewContext(r) | |
t := taskqueue.NewPOSTTask("/job", nil) | |
taskqueue.Add(c, t, "") | |
fmt.Fprintf(w, "書き込み完了") | |
} | |
func DoJob(w http.ResponseWriter, r *http.Request) { | |
c := appengine.NewContext(r) | |
// 要素数と容量が1000であるスライス作成 | |
s := make([]BattleResults, 0, 1000) | |
// 1000個のインスタンスを作成 | |
for i := 0; i < 1000; i++ { | |
// 構造体BattleResultsをインスタンス化 | |
battleResults := BattleResults{ | |
CheckNum: i, | |
WinnerID: 1, | |
LoserID: 2, | |
CreateAt: time.Now(), | |
UpdatedAt: time.Now(), | |
} | |
// スライスへappend | |
s = append(s, battleResults) | |
} | |
var wkey *datastore.Key | |
// Datastoreへの書き込み | |
ks := make([]*datastore.Key, 1000) | |
// 1000個のインスタンスをスライスに格納 | |
for i := 0; i < 1000; i++ { | |
// key発行 | |
key := datastore.NewIncompleteKey(c, "battleResults", nil) | |
var err error | |
// データストアに書き込みを行う | |
wkey, err = datastore.Put(c, key, &s[i]) | |
if err != nil { | |
http.Error(w, err.Error(), http.StatusInternalServerError) | |
} | |
//ks[i] = wkey | |
ks = append(ks, wkey) | |
} | |
} | |
func DoGet(w http.ResponseWriter, r *http.Request) { | |
q := datastore.NewQuery("battleResults").Filter("WinnerID =", 1).Offset(0).Limit(1000).Order("CheckNum") | |
cursorStr := "" | |
i := 0 | |
for i < 20 { | |
cursorStr = routine(w, r, q, cursorStr) | |
i ++ | |
} | |
} | |
func routine(w http.ResponseWriter, r *http.Request, q *datastore.Query, cursorStr string) string { | |
c := appengine.NewContext(r) | |
// FetchOptions的なことをする | |
// Queryを発行しつつ、Filter、Offset、Limitを設定する | |
// 10件に絞る | |
q = q.Limit(50) | |
// 取得したEntityを格納するためのSliceを用意 | |
es := make([]BattleResults, 0, 1000) | |
cursor, err := datastore.DecodeCursor(cursorStr) | |
if err == nil { | |
q = q.Start(cursor) | |
} | |
// Iteratorの取得 | |
iter := q.Run(c) | |
for { | |
var br BattleResults | |
// 10個のうち、1つを取得 | |
_, err := iter.Next(&br) | |
es = append(es, br) | |
// 次がなければ終了 | |
if err == datastore.Done { | |
break | |
} | |
if err != nil { | |
log.Errorf(c, "fetching next battleResults:", err) | |
break | |
} | |
} | |
cursor, err = iter.Cursor() // 次がなければ終了 | |
if err == datastore.Done { | |
} | |
if err != nil { | |
} | |
cursorStr = cursor.String() | |
html := ` | |
ここから | |
{{range .}} | |
{{.CheckNum}} | |
{{.WinnerID}} | |
{{.LoserID}} | |
{{.CreateAt}} | |
{{.UpdatedAt}}<br> | |
{{end}} | |
` | |
tmpl := template.Must(template.New("view").Parse(html)) | |
tmpl.Execute(w, es) | |
return cursorStr | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment