2011年9月10日土曜日

JDOで作成した単純なDataStoreをSlim3に移行してみた

GAEの値上げもあり、思い切ってSlim3に移行を試しましたのでその内容です。

通常Slim3使う場合はblankプロジェクトを使って作っていくようですが、もうすでにあるプロジェクトをSlim3に移行したかったので下記を参考にさせていただきました。
http://songofcloud.gluegent.com/2009/11/slim3-datastore2.html

試しに移行してみたのは2つのkindです。

---- Alert ---------移行前 自動でキーのIDが振られるタイプ
package com.hayato.dstest;

import javax.jdo.annotations.*;

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable="true")
public class Alert {
@PrimaryKey
@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
private Long alertId;
@Persistent
private String userId;
@Persistent
private String message;

public Alert(String userId, String message) {
this.userId = userId;
this.message= message;
}

public Long getAlertID() {
return alertId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message= message;
}
}

---- TestUser ---------移行前 StringのIDをキーで指定するタイプ
package com.hayato.dstest;

import javax.jdo.annotations.*;

@PersistenceCapable(identityType = IdentityType.APPLICATION, detachable="true")
public class TestUser {
@PrimaryKey
@Persistent
private String userId;
@Persistent
private String email;

public TestUser(String userId, String email) {
this.userId = userId;
this.email= email;
}

public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email= email;
}
}

JDOの場合は、次のような操作でした。

-----------作成
PersistenceManager pm = PMF.createManager();
TestUser user = new TestUser("123", "abc");
try {
pm.makePersistent(user);
} catch (Exception e) {
// error
} finally {
pm.close();
}

-----------取得、変更
PersistenceManager pm = PMF.createManager();
try {
TestUser user = pm.getObjectById(TestUser.class, "123");
user.setEmail("upd");
} catch (JDOObjectNotFoundException e) {
// not found
} finally {
pm.close();
}

-----------クエリ
PersistenceManager pm = PMF.createManager();
try {
Query query = pm.newQuery(Alert.class);
query.setFilter("userId == :pUserId");
List alerts = (List)query.execute("123");
for (Alert alert : alerts)
// 処理
} catch (Exception e) {
// error
} finally {
pm.close();
}

これを、なるべく手間をかけずに移行します。
まずはSlim3のjar等を設定します。これは一番上で紹介したサイトに載ってます。
で、kindを修正するわけですが、ここでプライマリキーの扱いについて注意が必要です。
JDOの方ではオートナンバーのLongや任意指定のStringをキーにできましたが、これをKey型に変更しないといけません。このKey型ですが、DataStore上でEntityを識別するための一意のKey値と、Long型の値もしくはString型の値の2つを保持します。

Key値
 ├──────┐
Long値 String値

こんな感じです。
今回の例ですと、AlertがLong値を使い、TestUserがString値を使うようにします。

これらを考慮して変更すると、

---- Alert ---------移行後 自動でキーのIDが振られるタイプ
package com.hayato.dstest;

import org.slim3.datastore.Attribute;
import org.slim3.datastore.Datastore;
import org.slim3.datastore.Model;
import com.google.appengine.api.datastore.Key;

@Model(kind = "Alert", schemaVersion = 1)
public class Alert {
@Attribute(primaryKey = true)
private Key alertId;
private String userId;
private String message;

public static Key createKey(Long alertId) {
return Datastore.createKey(Alert.class, alertId);
}

public Alert() {
}

public Alert(String userId, String message) {
this.userId = userId;
this.message= message;
}

public Key getAlertId() {
return alertId;
}
public void setAlertId(Key alertId) {
this.alertId = alertId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message= message;
}
}

---- TestUser ---------移行後 StringのIDをキーで指定するタイプ
package com.hayato.dstest;

import org.slim3.datastore.Attribute;
import org.slim3.datastore.Datastore;
import org.slim3.datastore.Model;
import com.google.appengine.api.datastore.Key;

@Model(kind = "TestUser", schemaVersion = 1)
public class TestUser{
@Attribute(primaryKey = true)
private Key userId;
private String email;

public static Key createKey(String userId) {
return Datastore.createKey(TestUser.class, userId);
}

public TestUser() {
}

public TestUser(String userId, String email) {
this.userId = createKey(userId);
this.email= email;
}

public Key getUserId() {
return userId;
}
public void setUserId(Key userId) {
this.userId = userId;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email= email;
}
}

こうなりました。ポイントとしては、プライマリキーがKey型に変更されたこと、もともとのLong値やString値からKeyオブジェクトを生成するためのcreateKeyというメソッドを追加したことです。
で、使い方は以下のように変わります。

-----------作成
try {
Alert alert = new Alert("123", "test message"); // <-Keyは指定してない
Datastore.put(alert);

TestUser user = new TestUser("123", "test@test.com"); // "123"がKey
Datastore.put(user);
} catch (Exception e) {
// error
}

-----------取得、変更
try {
Alert alert = Datastore.get(Alert.class, Alert.createKey(1L));
TestUser user = Datastore.get(TestUser.class, TestUser.createKey("123"));

// alertのプライマリキーを取得するには次のコード
Long alertId = alert.getAlertId().getId();
// TestUserのプライマリキーを取得するには次のコード この場合は"123"だけど
String userId = user.getUserId().getName();

alert.setMessage("update message");
Datastore.put(alert);
} catch (EntityNotFoundRuntimeException e) {
// not found
}

-----------クエリ
try {
AlertMeta alertMeta = AlertMeta.get(); // AlertMetaは、Slim3のジェネレータが自動作成したクラス
List alerts = Datastore.query(alertMeta)
.filter(alertMeta.userId.equal("123"))
.asList();
for (Alert alert : alerts) {
// 処理
}
} catch (Exception e) {
// error
}

これで一応動きました。まだ動いたというレベルですので何かしら問題がある可能性もあります。
動かしてみて気づいた点
・Key値を指定しないでputするとJDOのIdGeneratorStrategy.IDENTITYと同じ動きをするようだ。
・JDOではgetObjectByIdで取得してデータを変更するとDataStore上も変更されたが、Slim3では変更後にputしないと反映されない。

2010年5月1日土曜日

期間限定で無料です!AR わなげ

DL数の違いをみたかったので5月いっぱいまで無料にしてみました。
ぜひお試しください。

WineStampも値段下げました。

2009年12月14日月曜日

ようやくリリース! ARわなげ

長かった・・・
ようやくリリースされました。
もともと審査通すつもりはなかったんですが、リジェクト繰り返すうちにだんだん意地になってきてしまいました(笑)。

結局審査7回目でリリースでした。
はじめの提出が4月24日なので7ヶ月とちょっとかかりました。
6回目のリジェクトが致命的なリジェクトだったため、お蔵入り決定していたのですが他のアプリで同じ理由でリジェクトされていたものが通り始めたようだったので、ダメ元でアップルに「ねぇ~、こっちのアプリOKみたいなんだけどもう一回審査出したら通ったりする?」のようなメール出したところ、「おー、審査してやるからも一回提出しなさいよ」みたいな返事がきたので早速提出したら10日でリリースになりました。

ただ、当初の予想通り作った当時よりも動きがカクカクしてます。現時点ではこのあたりが限界のようです。

あと3本くらいアプリのアイデアがあるのでようやくそちらに取りかかろうと思います。

2009年8月6日木曜日

ARわなげの審査 4回目

またダメでした~(笑)
iPhone 3.0用にしてUIImagePickerをまったくいじらないようにして作ったんですがこれまでと同じ理由でダメでした。しかし今回は「iPhone3.1でカメラAPIが増えたから見てみて」みたいなコメントが追加してあったので、それを信じてiPhone3.1用に修正して提出してみます。
それにしても今回は6月9日に提出してようやく結果が出たので約2ヶ月近い審査期間でした。次回もこんなんだったらどうしよう・・・

2009年5月19日火曜日

ARわなげの審査 3回目

またまたダメでした(笑)

UIImagePickerControllerの「Take Picture」の部分を消してるだけなんですけどね。
iPhone3.0のUIImagePickerはそういうのが無いので、OS3.0が正式リリースされてからOS3.0用アプリとして申請してみます。

2009年5月8日金曜日

ARわなげの審査 2回目

またダメでした(笑)。

なんかUIImagePickerをいじくるアプリはすべてリジェクトされているようですね。

iPhoneOS3.0でUIImagePickerの内部構造が大きく変わってしまってるようなので、ほとんどのカメラアプリが動かなくなるそうです。これ以上動かなくなるアプリを増やさないようにしてるんでしょうね。

う~ん、困りますね~。まぁ、いじり方をもう少しソフトにして再度審査出してみます。

2009年5月2日土曜日

ARわなげの審査

やっぱりダメでした(笑)
少し修正して再度出してみます。