package com.android_mvc.framework.db.entity;
import java.util.Map.Entry;
import com.android_mvc.framework.annotations.SuppressDebugLog;
import com.android_mvc.framework.common.FWUtil;
import com.android_mvc.framework.controller.routing.IntentPortable;
import com.android_mvc.framework.db.DBHelper;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
/**
* 論理エンティティの基底クラス。派生クラスは,Java内での処理のために使用。
* Intent経由で運搬可能。
* @author id:language_and_engineering
*
*/
@SuppressDebugLog(false)
public abstract class BaseLogicalEntity<T> implements IntentPortable
{
protected Long id = null;
/**
* Serializableなので。
*/
private static final long serialVersionUID = 1L;
/**
* 主キー「id」を返す。
*/
public Long getId() {
return id;
}
/**
* 主キー「id」をセットする。
*/
public void setId(Long id) {
this.id = id;
}
/**
* 自身がDBに未登録の新規レコードであるかどうかを返す。
*/
private boolean is_new_record()
{
return (getId() == null);
}
// ----- LP変換(Logical ⇔ Physical) -----
/**
* DB内の格納値(物理値)から,論理エンティティを構築する。
* 物理値から論理値へ変換し,論理エンティティの各フィールドにセットする。
* @param c カーソル
*/
public abstract T logicalFromPhysical(Cursor c);
/**
* 自身を,DBに新規登録可能なデータ型に変換して返す。
* 論理値から物理値へ変換し,ContentValuesの各キーにセットする。
*/
protected abstract ContentValues toPhysicalEntity( ContentValues values );
// NOTE: 本当はここで「PhysicalEntity」を返却するようにしたかった。
// しかしContentValuesはfinalなので,継承してPhysicalEntityクラスを作れぬ。
// ラッパーメソッドも多すぎるので,コンポジションも無理。
// finalじゃなければいいのに・・・。
/**
* FW内で,DB登録用の「物理エンティティ」を取得するためのメソッド。
*/
public ContentValues toContentValues()
{
ContentValues values = new ContentValues();
return toPhysicalEntity( values );
}
// ----- CRUD -----
/**
* テーブル名。
*/
public abstract String tableName();
/**
* カラム名たち。
*/
public abstract String[] columns();
// C,U:
/**
* 自身を保存。
* 主キーがなければ,新規保存になる。主キーがあれば,更新になる。
*/
public boolean save(DBHelper helper)
{
boolean ret = false;
FWUtil.d("DB接続をオープンします。");
SQLiteDatabase db = helper.getWritableDatabase();
try{
// 物理エンティティに変換
ContentValues values = this.toContentValues();
FWUtil.d("物理エンティティへの変換が成功しました。");
// 登録しようとしている物理エンティティの中身をデバッグ表示
for( Entry<String, Object> ent : values.valueSet() )
{
FWUtil.d("key = " + ent.getKey() + ", value = " + ent.getValue());
}
// CまたはUを振り分ける
if( this.is_new_record() )
{
db.insert(this.tableName(), null, values);
FWUtil.d("DB新規登録に成功しました。");
}
else
{
// 主キーをもとに1件だけ更新
db.update( this.tableName(), values, "id = " + this.getId(), null );
FWUtil.d("DB更新に成功しました。");
}
ret = true;
} finally {
db.close();
}
return ret;
}
// R:
// Finderを使って検索してもらう
// D:
/**
* 自身を削除。
*/
public void delete(DBHelper helper)
{
FWUtil.d("DB接続をオープンします。");
SQLiteDatabase db = helper.getWritableDatabase();
try{
db.delete( this.tableName(), "id = " + getId().toString(), null );
FWUtil.d("DBからの削除に成功しました。");
} finally {
db.close();
}
}
}