Subscribed unsubscribe Subscribe Subscribe

Islands in the byte stream

Technical notes by a software engineer

Orma v4.2.0 の Relation#upsert() の設計

https://github.com/gfx/Android-Orma

Orma v4.2.0 で Relation#upsert() を実装しました。これは、モデルのインスタンスを渡すとその状態に応じて INSERT または UPDATE を実行するというメソッドです。

モデル同士の関連もよしなにしてくれるので、とりあえず #upsert() で突っ込むといい感じに保存されるという便利メソッドです。

ただひとつ注意点があって、primary key の自動採番モード(デフォルトの挙動)のときに #upsert() 後にそのモデルを参照する場合は、#upsert() の戻り値を使わなければいけません。というのも、Ormaは どんなモデルでもimmutableであるという仮定 を置いており、自動採番したprimary keyをモデルのフィールドに代入したりはしないからです。

つまり、次のようなモデルクラスがあったときに:

@Table
public class Todo {

    @PrimaryKey
    public long id;

    @Column(indexed = true)
    public String title;

#upsert() により次のような状態になります。

Todo todo = new Todo();
todo.title = "foo";

Todo newTodo = todoRelation.upsert(todo);

assert todo.id == 0; // todo.idは変化なし

assert newTodo.id > 0; // newTodoのほうは割り当てられたidを持っている

newTodo.title = "bar";

todoRelation.upsert(newTodo); // 変化する要素がないので戻り値は不要

associationについても同様です。

少し煩雑ですが、実は Inserter#execute() も渡されたモデルを変更しないという意味では同じで、モデルをimmutableと見なす設計です。

というわけで、ちょっとクセはありますが便利だと思いますので使ってみてください。