2012年1月11日水曜日

Slim3 Source Code Reading #3

Slim3ソースコード読書会(3)を開催しました。

今回は、前回のPutとかぶっていますが、以下のソースコードを読みました。
Datastore.java
DatastoreDelegate.java
AsyncDatastoreDelegate.java
ModelQuery.java
AbstractQuery.java
DatastoreUtil.java

そこで話題になったポイントをメモしておきます。

1点目。
AsyncDatastoreDelegate.javaの642行目で、

mm.validateKey(key);を呼び出し、KeyのKindとModelMetaで保持しているKindを
比較し、一致しなければIllegalArgumentExceptionをスローしている件。

これは、以下のように、取得しようとしているModelとKeyが一致しない時などに、
エラーにするための防波堤ではないか。という結論になりました。

例えば、以下のようにTweetクラスとTweet2クラスが存在したとして、
プロパティの構成が全く同じ場合で、データストアにKeyが存在している場合。

Tweet tweet = new Tweet();
Datastore.put(tweet);
Tweet2 tweet2 = Datastore.get(Tweet2.class, tweet.getKey());    // 指定したKeyとModelが不一致

データストアからのGetは成功しますから、構成が同じであれば、Tweet2クラスの
Modelとして値が取得されます。しかし、これは本来Tweetのデータであるため、
Modelが取れてはいけないのですが、データストアの仕組み上防ぐことができません。
したがって、ModelMetaで定義しているKindとKeyのKindを比較して一致しているか
どうかを確認していると思われます。

2点目。
ModelQuery.javaの241行目のasList()で最後にfilterInMemory()とsortInMemory()を
呼び出していることについて。

最初は、「DatastoreのQueryでsortやFilterを指定したらメモリ上でのソートやFilterは不要だろう」と
いう意見だったのですが、よく読んでみると、呼び出し元でfilterInMemory()を
呼び出していなければ、inMemoryCriteriaのSizeが0なので、実際には
Filter処理は実行されません。同様に、sortに関してもinMemorySortCriteriaの
Sizeが0であればSort処理も実行されません。

ただし、データストアでSortを実行したあと、sortInMemoryを呼び出していれば、
両方とも実行されることになります。

恐らく、inMemoryFilterについてはOR条件で抽出したい場合があれば、
それを実現するために利用するのではないかという結論になりました。
(AND条件での検索であれば、QueryにFilterを設定するだけで良いが、データストアでOR条件は指定できない。)

次回は1/17(火)19:00〜の予定です。