Skip to content

Instantly share code, notes, and snippets.

@keima
Last active August 29, 2015 14:06
Show Gist options
  • Save keima/331aa8b74b36d08b8e9f to your computer and use it in GitHub Desktop.
Save keima/331aa8b74b36d08b8e9f to your computer and use it in GitHub Desktop.

How to use Model

github.com/knightso/base/gae/model を組み込むと、 痒い所に手が届くdatastoreEntityを作成することが出来ます。

この使い方をまとめておきます。

structの定義方法

type Greeting struct {
    Meta // ←
    Id      string `datastore:"-" json:"id"` // for output json
    Name    string `json:"name"`
    Message string `json:"message"`
}

Idは個人的に必要だったので付けましたが、要らないなら用意しなくても良い。

Metaが提供するもの

type Meta struct {
	Key       *datastore.Key `datastore:"-" json:"-"`
	Version   int            `json:"version"`
	Deleted   bool           `json:"deleted"`
	CreatedAt time.Time      `json:"createdAt"`
	UpdatedAt time.Time      `json:"updatedAt"`
}

これらの最低限必要そうなものは定義済みなので、わざわざ自分で作らなくても良い。

Metaがやってくれること

  • Key
  • SetするときにこのKeyを用いる
  • GetしたときにEntityに対応するKeyが入っている
  • Version
  • Putが呼ばれるたびにincrementされる。
  • Deleted
  • これを執筆している段階(2014/09/26)では何をしているのか特定できていない
  • 論理削除フラグっぽいけど・・・?
  • CreatedAt
  • UpdatedAt
  • 作成日時と更新日時が自動で割り当てられる

加えて、modelがgithub.com/qedus/ndsを使用してmemcacheを使用したDBアクセスを提供する。

データの格納

いつもどおりです。

g1 := Greeting {
    Name: "Kouta Imanaka"
    Message: "Hello, Gopher!"
}

Idはデータ返すときに使う予定なので、今は定義しません。

Keyの作成

いつもどおりです。

key := datastore.NewIncompleteKey(c, "Greeting", nil)
// 以下でも良い
// key := datastore.NewKey(c, "Greeting", "hogefugahogehoge", 0, nil)

PUT,GET

// PUT
g1.SetKey(key)
err1 := model.Put(c, g1)
if err != nil {
   http.error(...)
   return
}

// GET
g2 := Greeting{}
err2 := model.Get(c, key, &g2)
if err != nil {
   http.error(...)
   return
}

// GET(version check)
g3 := Greeting{}
err3 := model.GetWithVersion(c, key, g2.GetVersion(), &g3)
if err3 != nil {
   err3 == OptimisticLockError {
       // 取得しようとしたEntityのバージョンが指定値より大きかった時、
       // どこからか書き込みが行われたということになる
   } else {
       http.error(...)
   }
   return
}

GETしたGreetingを、go-json-restなどで投げ返すときに、一手間加える。

g1.Id = g1.GetKey().StringId() // or IntId()
w.WriteJson(&g1)

これで、Entityを特定するJSONを返すことが出来たりする。

QUERY

greetings := make([]Greeting, 0, 10)
q := datastore.NewQuery("Greeting").Order("-UpdatedAt").Limit(10)
model.ExecuteQuery(c, &q, &greetings)

// set id
for index,value := range greetings {
    greetings[index].Id = value.GetKey().StringId()
}

w.WriteJson(&greetings)

Orderに存在しない変数名(フィールド名)を入れてしまうと、結果が0件となるのは地味にハマるので注意。

あと、for文もvalueのフィールドに代入してもgreetingsには変更が反映されないのもハマる。

GetMulti, PutMulti

TBD

FindIndexedKey, PutKeyToIndex

TBD (というかIndex関連よく分かってない、、、)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment