package com.jqmobile.core.android.db.orm.base;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.jqmobile.core.android.db.orm.BaseDBColumn;
import com.jqmobile.core.android.db.orm.BaseDBTable;
import com.jqmobile.core.android.db.orm.table.TableUtilFactory;
import com.jqmobile.core.orm.AutoVersionControl;
import com.jqmobile.core.orm.DBColumn;
import com.jqmobile.core.orm.ORM;
import com.jqmobile.core.orm.TableUtil;
import com.jqmobile.core.orm.exception.DefferentVersionException;
import com.jqmobile.core.orm.exception.ORMException;
import com.jqmobile.core.orm.exception.ORMNotDBTableException;
import com.jqmobile.core.orm.exception.VersionFieldTypeException;
import com.jqmobile.core.utils.plain.Log;
class ORMImpl<T> extends ORMSImpl implements ORM<T> {
private final BaseDBTable table;
private final Class<T> beanClass;
/**
* 初始化
*
* @param conn
* 数据库connection
* @param c
* 要操作的实体class
* @throws ORMNotDBTableException
* @throws ORMException
*/
public ORMImpl(SQLiteDatabase conn, Class<T> c)
throws ORMNotDBTableException, ORMException {
super(conn);
this.beanClass = c;
table = BaseDBTable.getInstance(c);
autoValiTable();
}
/**
* 自动验证表
*
* @throws ORMException
*/
private void autoValiTable() throws ORMException {
TableUtil tableUtil = TableUtilFactory.instance(getConnection());
tableUtil.autoUpdateTable(beanClass);
}
@Override
public int insert(T t) throws ORMException {
getConnection().execSQL(table.getInstnerSql(), getParams(t).toArray());
return -1;
}
protected List<Object> getParams(T t) {
List<Object> list = new ArrayList<Object>();
for (int i = 0; i < table.getMappingFields().size(); i++) {
try {
list.add(getParam(table.getMappingFields().get(i)
.getFormatObj(t)));
} catch (Exception e) {
Log.getLog(getClass()).e(e);
list.add(null);
continue;
}
}
return null;
}
@Override
public int update(T t) throws ORMException {
List<Object> params = getParams(t);
params.add(table.getParmaryId().getFormatObj(t));
if (versionValidate(t)) {
getConnection().execSQL(table.getInstnerSql(), params.toArray());
} else {
try {
throw new DefferentVersionException("版本不一致或不存在此记录");
} catch (DefferentVersionException e) {
e.printStackTrace();
}
}
return -1;
}
@Override
public int delete(String recid) throws ORMException {
getConnection().execSQL(table.getDeleteSqlByPID(),
new Object[] { recid });
return -1;
}
@Override
public T find(String recid) {
Cursor rs = getConnection().rawQuery(table.getFindSqlByPID(),
new String[] { recid });
try {
return instanceObject(rs);
} catch (Exception e) {
return null;
}
}
@Override
public int delete(UUID recid) throws ORMException {
return delete(recid.toString());
}
@Override
public T find(UUID recid) {
return find(recid.toString());
}
// 反射放入值
/**
* 反射获取返回对象结果list。数据库字段名称,必须和属性名称一致
*
* @param <T>
* @param c
* @param rs
* @return List<T>
* @throws Exception
*/
private List<T> getList(Cursor rs) throws Exception {
List<T> list = new ArrayList<T>();
List<BaseDBColumn> fields = table.getMappingFields();
for (rs.moveToFirst(); !rs.isAfterLast(); rs.moveToNext()) {
list.add(instanceObject(rs, fields));
}
return list;
}
private T instanceObject(Cursor rs, List<BaseDBColumn> fields)
throws InstantiationException, IllegalAccessException {
T t = beanClass.newInstance();
for (BaseDBColumn field : fields) {
// if(Modifier.isFinal(field.getModifiers())){
// continue;
// }
// field.setAccessible(true);
Object obj = field.getValue(rs);
if (null == obj) {
continue;
}
field.set(t, obj);
}
return t;
}
private T instanceObject(Cursor rs) throws Exception {
if (rs.getCount() <= 0) {
return null;
}
T t = beanClass.newInstance();
List<BaseDBColumn> fields = table.getMappingFields();
for (BaseDBColumn field : fields) {
// if (Modifier.isFinal(field.getModifiers())) {
// continue;
// }
// field.setAccessible(true);
Object obj = field.getValue(rs);// getFieldValue(field, rs);
if (null == obj) {
continue;
}
field.set(t, obj);
}
return t;
}
// =====================
@Override
public List<T> query(String where, Object... args) throws ORMException {
Cursor rs = getConnection().rawQuery(table.getQueryRowSql(where),
getParams(args));
try {
return getList(rs);
} catch (Exception e) {
throw new ORMException(e);
} finally {
rs.close();
}
}
@Override
public List<T> queryPage(String where, long startIndex, long endIndex,
Object... args) throws ORMException {
Cursor rs = getConnection().rawQuery(
table.getQuerySql(where) + " limit " + startIndex + ","
+ endIndex + "", getParams(args));
try {
return getList(rs);
} catch (Exception e) {
throw new ORMException(e);
} finally {
rs.close();
}
}
@Override
public T queryFirst(String where, Object... args) throws ORMException {
Cursor rs = getConnection().rawQuery(table.getQuerySql(where),
getParams(args));
try {
if (rs.moveToFirst())
return instanceObject(rs);
return null;
} catch (Exception e) {
throw new ORMException(e);
} finally {
rs.close();
}
}
@Override
public int queryRow(String where, Object... args) throws ORMException {
Cursor rs = getConnection().rawQuery(table.getQueryRowSql(where),
getParams(args));
try {
if (rs.moveToFirst())
return rs.getInt(1);
return 0;
} catch (Exception e) {
throw new ORMException(e);
} finally {
rs.close();
}
}
@Override
public int update(String set, Object... args) throws ORMException {
getConnection().execSQL(
table.getModifySql(set), args);
return -1;
}
@Override
public int delete(String where, Object... args) throws ORMException {
getConnection().execSQL(
table.getDeleteSql(where), args);
return -1;
}
@Override
public List<T> getAll() throws ORMException {
return query("select * from " + table.getTableName());
}
/**
* 版本验证
*
* @param t
* 实体对象
* @return
*/
private boolean versionValidate(T t) {
boolean flag = false;
// 判断是否实现版本接口
if (judgeInterface()) {
// 获取类中指定的版本字段
String validateWord = getValidateWord(t);
// 判断是否是日期格式
boolean isDate = isDate(validateWord);
// 通过类中指定的版本字段,获取数据库中该对象对应的数据
Object dataBaseVW = getDataBaseVW(t, validateWord, isDate);
// 获取对象中版本值
Object entityVW = getEntityVW(t, validateWord);
// 对比比较传入的对象中的版本值和数据库读取的版本值是否一致
if (dataBaseVW != null && entityVW != null
&& dataBaseVW.equals(entityVW)) {
return true;
}
}
return flag;
}
/**
* 判断是否是日期类型
*
* @param validateWord
* @return
*/
private boolean isDate(String validateWord) {
Field[] fields = beanClass.getDeclaredFields();
for (Field field : fields) {
if (field.getName().equals(validateWord)) {
if (field.getAnnotation(DBColumn.class) != null) {
return field.getAnnotation(DBColumn.class).date();
}
}
}
return false;
}
/**
* 获取实体对象中版本控制字段值
*
* @param t
* 实体对象
* @param validateWord
* 指定版本字段名称
* @return
*/
private Object getEntityVW(T t, String validateWord) {
try {
Field field = beanClass.getDeclaredField(validateWord);
if (field.getType() == long.class) {
String entityVW = "get"
+ validateWord.substring(0, 1).toUpperCase()
+ validateWord.substring(1, validateWord.length());
Method method = beanClass.getMethod(entityVW, null);
return (Object) method.invoke(t, null);
} else {
throw new VersionFieldTypeException("版本字段必修是long类型");
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (VersionFieldTypeException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取数据库中版本字段值
*
* @param t
* 实体对象
* @param validateWord
* 指定版本字段名称
* @param isDate
* @return
*/
private Object getDataBaseVW(T t, String validateWord, boolean isDate) {
String paimaryId = getPaimaryId(t);
Cursor rs = getConnection().rawQuery(table.getFindSqlByPID(),
new String[] { paimaryId });
if(rs.moveToFirst()){
return rs.getLong(rs.getColumnIndex(validateWord));
}
return null;
}
/**
* 获取类中指定的版本字段
*
* @param t
* 实体对象
* @return
*/
private String getValidateWord(T t) {
// TODO Auto-generated method stub
try {
Method method = beanClass.getMethod("getVersionWord", null);
return (String) method.invoke(t, null);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
/**
* 获取主键值
*
* @param t
* 实体对象
* @return 主键值
*/
private String getPaimaryId(T t) {
for (int i = 0; i < table.getMappingFields().size(); i++) {
try {
BaseDBColumn column = table.getMappingFields().get(i);
// 判断该值是否是主键,若是主键则返回
if (column.isPaimaryId()) {
String str = column.getColumnName();
String paimaryId = "get"
+ str.substring(0, 1).toUpperCase()
+ str.substring(1, str.length());
Method method = beanClass.getMethod(paimaryId, null);
return (String) method.invoke(t, null);
}
} catch (Exception e) {
Log.getLog(getClass()).e(e);
continue;
}
}
return null;
}
/**
* 判断是否实现版本控制接口
*
* @param t
* 实体对象
* @return 若实现返回true,反之,返回false
*/
private boolean judgeInterface() {
Class<?>[] classes = beanClass.getInterfaces();
for (Class<?> c : classes) {
if (c.equals(AutoVersionControl.class)) {
return true;
}
}
return false;
}
}