Skip to content

Instantly share code, notes, and snippets.

@sekky0905
Created February 21, 2017 07:45
Show Gist options
  • Save sekky0905/4baadb7cadf7ee83312acd94300d38d0 to your computer and use it in GitHub Desktop.
Save sekky0905/4baadb7cadf7ee83312acd94300d38d0 to your computer and use it in GitHub Desktop.
GAE/Go Datastore manipulation
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