package com.kurukurupapa.tryandroid.fw.apt;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class ManyEntityDao {
	public ManyEntityDao() {
	}

	/**
	 * テーブル作成
	 *
	 * @param db
	 *            書き込み権限付きDB接続
	 */
	public void create(SQLiteDatabase db) {
		db.execSQL("create table many_entity ("
				+ "_id integer primary key autoincrement"
				+ ",boolean_item integer not null"
				+ ",short_item integer not null"
				+ ",int_item integer not null"
				+ ",long_item integer not null"
				+ ",float_item real not null"
				+ ",double_item real not null"
				+ ",string_item text not null"
				+ ")");
	}

	/**
	 * テーブル削除
	 *
	 * @param db
	 *            書き込み権限付きDB接続
	 */
	public void drop(SQLiteDatabase db) {
		db.execSQL("drop table if exists many_entity");
	}

	/**
	 * テーブル更新
	 *
	 * @param db
	 *            書き込み権限付きDB接続
	 */
	public void upgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		drop(db);
		create(db);
	}

	/**
	 * レコード検索処理
	 *
	 * @param db
	 *            DB接続（書き込み権限不要）
	 * @param sql
	 *            SQL文。パラメータ部分は"?"のように記述する。
	 * @param args
	 *            検索条件のパラメータ配列。不要な場合null。
	 * @return エンティティのリスト
	 */
	public List<com.kurukurupapa.tryandroid.fw.apt.ManyEntity> rawQuery(
			SQLiteDatabase db, String sql, String[] args) {
		List<com.kurukurupapa.tryandroid.fw.apt.ManyEntity> result =
				new ArrayList<com.kurukurupapa.tryandroid.fw.apt.ManyEntity>();
		Cursor cursor = null;
		try {
			cursor = db.rawQuery(sql, args);
			while (cursor.moveToNext()) {
				result.add(getEntityFromCursor(cursor));
			}
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}
		return result;
	}

	/**
	 * SQL実行
	 *
	 * @param db
	 *            書き込み権限付きDB接続
	 * @param sql
	 *            SQL文。
	 */
	public void execSQL(SQLiteDatabase db, String sql) {
		db.execSQL(sql);
	}

	/**
	 * SQL実行
	 *
	 * @param db
	 *            書き込み権限付きDB接続
	 * @param sql
	 *            SQL文。パラメータ部分は"?"のように記述する。
	 * @param args
	 *            検索条件のパラメータ配列。不要な場合null。
	 */
	public void execSQL(SQLiteDatabase db, String sql, Object[] bindArgs) {
		db.execSQL(sql, bindArgs);
	}

	/**
	 * レコード検索処理
	 *
	 * @param db
	 *            DB接続（書き込み権限不要）
	 * @param where
	 *            検索条件。パラメータ部分は"?"のように記述する。nullの場合、条件なし。
	 * @param whereArgs
	 *            検索条件のパラメータ配列。不要な場合null。
	 * @param groupBy
	 *            未指定の場合null。
	 * @param having
	 *            未指定の場合null。
	 * @param orderBy
	 *            ソート条件。未指定の場合null。
	 * @param limit
	 *            取得件数。未指定の場合null。指定するとパフォーマンスアップ。
	 * @return エンティティのリスト
	 */
	public List<com.kurukurupapa.tryandroid.fw.apt.ManyEntity> query(SQLiteDatabase db,
			String selection, String[] selectionArgs, String groupBy, String having,
			String orderBy, String limit) {
		List<com.kurukurupapa.tryandroid.fw.apt.ManyEntity> result =
			new ArrayList<com.kurukurupapa.tryandroid.fw.apt.ManyEntity>();
		Cursor cursor = null;
		try {
			cursor = db.query("many_entity",
					getColumnNames(),
				selection, selectionArgs, groupBy, having, orderBy, limit);
			while (cursor.moveToNext()) {
				result.add(getEntityFromCursor(cursor));
			}
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}
		return result;
	}

	/**
	 * レコード検索処理（簡易版）
	 *
	 * @param db
	 *            DB接続（書き込み権限不要）
	 * @param where
	 *            検索条件。パラメータ部分は"?"のように記述する。nullの場合、条件なし。
	 * @param whereArgs
	 *            検索条件のパラメータ配列。不要な場合null。
	 * @param orderBy
	 *            ソート条件。未指定の場合null。
	 * @param limit
	 *            取得件数。未指定の場合null。指定するとパフォーマンスアップ。
	 * @return エンティティのリスト
	 */
	public List<com.kurukurupapa.tryandroid.fw.apt.ManyEntity> query(SQLiteDatabase db,
			String where, String[] whereArgs, String orderBy, String limit) {
		return query(db, where, whereArgs, null, null, orderBy, limit);
	}

	/**
	 * レコード検索処理（全件）
	 *
	 * @param db
	 *            DB接続（書き込み権限不要）
	 * @param limit
	 *            取得件数。未指定の場合null。指定するとパフォーマンスアップ。
	 * @return エンティティのリスト
	 */
	public List<com.kurukurupapa.tryandroid.fw.apt.ManyEntity> query(SQLiteDatabase db, String limit) {
		return query(db, null, null, null, null, "_id", limit);
	}

	/**
	 * 1レコード検索処理
	 *
	 * @param db
	 *            DB接続（書き込み権限不要）
	 * @param where
	 *            検索条件。パラメータ部分は"?"のように記述する。nullの場合、条件なし。
	 * @param whereArgs
	 *            検索条件のパラメータ配列。不要な場合null。
	 * @param groupBy
	 *            未指定の場合null。
	 * @param having
	 *            未指定の場合null。
	 * @param orderBy
	 *            ソート条件。未指定の場合null。指定するとパフォーマンスアップ。
	 * @return エンティティ
	 */
	public com.kurukurupapa.tryandroid.fw.apt.ManyEntity querySingle(SQLiteDatabase db,
			String where, String[] whereArgs, String groupBy, String having, String orderBy) {
		List<com.kurukurupapa.tryandroid.fw.apt.ManyEntity> list =
			query(db, where, whereArgs, groupBy, having, orderBy, "1");
		if (list.size() == 0) {
			return null;
		} else {
			return list.get(0);
		}
	}

	/**
	 * 1レコード検索処理（簡易版）
	 *
	 * @param db
	 *            DB接続（書き込み権限不要）
	 * @param where
	 *            検索条件。パラメータ部分は"?"のように記述する。nullの場合、条件なし。
	 * @param whereArgs
	 *            検索条件のパラメータ配列。不要な場合null。
	 * @param orderBy
	 *            ソート条件。未指定の場合null。
	 * @return エンティティ
	 */
	public com.kurukurupapa.tryandroid.fw.apt.ManyEntity querySingle(SQLiteDatabase db,
			String where, String[] whereArgs, String orderBy) {
		return querySingle(db, where, whereArgs, null, null, orderBy);
	}

	/**
	 * レコード件数取得処理
	 *
	 * @param db
	 *            DB接続（書き込み権限不要）
	 * @param where
	 *            検索条件。パラメータ部分は"?"のように記述する。nullの場合、条件なし。
	 * @param whereArgs
	 *            検索条件のパラメータ配列。不要な場合null。
	 * @param groupBy
	 *            未指定の場合null。
	 * @param having
	 *            未指定の場合null。
	 * @return 件数
	 */
	public int queryCount(SQLiteDatabase db,
			String where, String[] whereArgs, String groupBy, String having) {
		int count = 0;
		Cursor cursor = null;
		try {
			cursor = db.query("many_entity",
					new String[]{"count(_id)"},
					where, whereArgs, groupBy, having, null, "1");
			count = cursor.getInt(0);
		} finally {
			if (cursor != null) {
				cursor.close();
			}
		}
		return count;
	}

	/**
	 * レコード件数取得処理（簡易版）
	 *
	 * @param db
	 *            DB接続（書き込み権限不要）
	 * @param where
	 *            検索条件。パラメータ部分は"?"のように記述する。nullの場合、条件なし。
	 * @param whereArgs
	 *            検索条件のパラメータ配列。不要な場合null。
	 * @return 件数
	 */
	public int queryCount(SQLiteDatabase db, String where, String[] whereArgs) {
		return queryCount(db, where, whereArgs, null, null);
	}

	/**
	 * レコード件数取得処理（全件）
	 *
	 * @param db
	 *            DB接続（書き込み権限不要）
	 * @return 件数
	 */
	public int queryCount(SQLiteDatabase db) {
		return queryCount(db, null, null, null, null);
	}

	/**
	 * レコード追加
	 *
	 * @param db
	 *            書き込み権限付きDB接続
	 * @return ID
	 */
	public long insert(SQLiteDatabase db, com.kurukurupapa.tryandroid.fw.apt.ManyEntity entity) {
		ContentValues values = getContentValuesForInsert(entity);
		long id = db.insert("many_entity", null, values);
		return id;
	}

	/**
	 * レコード更新
	 *
	 * @param db
	 *            書き込み権限付きDB接続
	 * @return 件数
	 */
	public int update(SQLiteDatabase db, com.kurukurupapa.tryandroid.fw.apt.ManyEntity entity) {
		int count = db.update(
			"many_entity",
			getContentValuesForUpdate(entity),
			"_id=" + entity.get_id(),
			null);
		return count;
	}

	/**
	 * レコード削除
	 *
	 * @param db
	 *            書き込み権限付きDB接続
	 * @param where
	 *            削除条件。パラメータ部分は"?"のように記述する。nullの場合、条件なし。
	 * @param whereArgs
	 *            削除条件のパラメータ配列。不要な場合null。
	 * @return 件数
	 */
	public int delete(SQLiteDatabase db, String where, String[] whereArgs) {
		return db.delete("many_entity", where, whereArgs);
	}

	/**
	 * レコード削除
	 *
	 * @param db
	 *            書き込み権限付きDB接続
	 * @return 件数
	 */
	public int delete(SQLiteDatabase db, com.kurukurupapa.tryandroid.fw.apt.ManyEntity entity) {
		return delete(db, "_id=" + entity.get_id(), null);
	}

	/**
	 * カラム名を取得する
	 */
	public String[] getColumnNames() {
		return new String[] {
				"_id",
				"boolean_item",
				"short_item",
				"int_item",
				"long_item",
				"float_item",
				"double_item",
				"string_item",
			};
	}

	/**
	 * カラム名を取得する（JOIN用）
	 */
	public String getColumnNamesForJoin() {
		return ""
			+ "many_entity._id as _id"
			+ ",many_entity.boolean_item as boolean_item"
			+ ",many_entity.short_item as short_item"
			+ ",many_entity.int_item as int_item"
			+ ",many_entity.long_item as long_item"
			+ ",many_entity.float_item as float_item"
			+ ",many_entity.double_item as double_item"
			+ ",many_entity.string_item as string_item"
			;
	}

	protected ContentValues getContentValuesForInsert(com.kurukurupapa.tryandroid.fw.apt.ManyEntity entiry) {
		ContentValues values = new ContentValues();
		values.put("boolean_item", entiry.getBooleanItem());
		values.put("short_item", entiry.getShortItem());
		values.put("int_item", entiry.getIntItem());
		values.put("long_item", entiry.getLongItem());
		values.put("float_item", entiry.getFloatItem());
		values.put("double_item", entiry.getDoubleItem());
		values.put("string_item", entiry.getStringItem());
		return values;
	}

	protected ContentValues getContentValuesForUpdate(com.kurukurupapa.tryandroid.fw.apt.ManyEntity entiry) {
		ContentValues values = getContentValuesForInsert(entiry);
		values.put("_id", entiry.get_id());
		return values;
	}

	protected com.kurukurupapa.tryandroid.fw.apt.ManyEntity getEntityFromCursor(Cursor cursor) {
		com.kurukurupapa.tryandroid.fw.apt.ManyEntity entiry = new com.kurukurupapa.tryandroid.fw.apt.ManyEntity();
		entiry.set_id(cursor.getInt(cursor.getColumnIndexOrThrow("_id")));
		entiry.setBooleanItem(cursor.getInt(cursor.getColumnIndexOrThrow("boolean_item")) != 0);
		entiry.setShortItem(cursor.getShort(cursor.getColumnIndexOrThrow("short_item")));
		entiry.setIntItem(cursor.getInt(cursor.getColumnIndexOrThrow("int_item")));
		entiry.setLongItem(cursor.getLong(cursor.getColumnIndexOrThrow("long_item")));
		entiry.setFloatItem(cursor.getFloat(cursor.getColumnIndexOrThrow("float_item")));
		entiry.setDoubleItem(cursor.getDouble(cursor.getColumnIndexOrThrow("double_item")));
		entiry.setStringItem(cursor.getString(cursor.getColumnIndexOrThrow("string_item")));
		return entiry;
	}

}
