2012年6月5日火曜日

GAE/Gで時間のチェック(Datastore編)

GAE/GのSDK 1.6.4からGo Ver 1が適用され、
時間をデータストアに保存する時は、datastore.Time(int64のtype。今は削除されている)では無く、time.Timeが利用できるようになっています。(参考Blog記事

time.Timeをデータストアに格納しようと思うと、普通に日時が設定されていれば問題ないのですが、
例えば、データストアのプロパティの追加した時など、日時のプロパティに時間が設定されていない時があります。

日時が設定されていないまま、Putを行うと、"time value out of range"のエラーが
発生してしまいます。

これを回避するためには、

  1. PropertyLoadSaverのLoadかSaveで日付をセットする。
  2. リリース前にデータの移行をしておく。(未設定の日時が発生しないようにしておく)
のどちらかになると思います。2のケースだと全件Putされるので問題ないと思いますが、
移行プログラムでデータを移行させない事の方が多いと思います。

したがって、PropertyLoadSaverインターフェイスを実装して、以下のように、
時間がZeroかどうかを判定するロジックを入れておかないと、Putが成功しません。
判定メソッドはGo言語標準で用意されているIsZero()を利用します。
LoadとSaveどちらで設定するのも構わないと思いますが、ここでは、Load時に設定する
方針にしてみます。(if文1つなら処理コストはあまり変わらないだろうと言っても、読み込み時に毎回実行するのは無駄だ。と思われる場合はSaveで実装するのが良いでしょう)

func(hoge *Hoge) Load(c <-chan datastore.Property) error {
        // データストアから読み出し。
 if err := datastore.LoadStruct(hoge, c); err != nil {
  return err
 }

 if hoge.Date.IsZero() {
  // データがない(0000/01/01状態)ものは現在時刻にするなど。
  hoge.Date = time.Now().Format(TimeFormat)
 }

 return nil
}

データが既に入っている場合はIsZero()がfalseになると思われるので、
特に時間の設定は不要(データストアから読みだした時点で代入されている)でしょう。