package com.jqmobile.core.android.db.orm;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import android.database.Cursor;
import com.jqmobile.core.orm.DBColumn;
import com.jqmobile.core.orm.exception.ORMNotDBColumnException;
import com.jqmobile.core.orm.exception.ORMParamNotRecognitionException;
public class BaseDBColumn {
private final Field field;
private DBColumn dbLable;
private final static Map<Field, BaseDBColumn> map = new HashMap<Field, BaseDBColumn>();
public static BaseDBColumn getInstance(Field f) {
synchronized (map) {
if(!map.containsKey(f)){
map.put(f, new BaseDBColumn(f));
}
}
return map.get(f);
}
public BaseDBColumn(Field f){
this.field = f;
this.dbLable = f.getAnnotation(DBColumn.class);
}
public Field getField() {
return field;
}
public boolean isMapping(){
return null == dbLable || dbLable.mapping();
}
public String getColumnName(){
valiColumn();
if(null == dbLable || DBColumn.DefaultValue.equals(dbLable.name())) return field.getName();
return dbLable.name();
}
public DBColumn getDBColumn(){
return dbLable;
}
public boolean isPaimaryId() {
valiColumn();
return null != dbLable && dbLable.primaryId();
}
public String getColumnType() {
valiColumn();
if(null != dbLable && (dbLable.primaryId() || dbLable.id())){
return "binary(16)";
}else if(null == dbLable || DBColumn.DefaultValue.equals(dbLable.type())){
Class<?> fieldType = field.getType();
if (isIn(fieldType.getName(),"java.lang.Long","long")&&field.getAnnotation(DBColumn.class)!=null&&!field.getAnnotation(DBColumn.class).date()) {
return "bigint(20)";
} else if (isIn(fieldType.getName(),"java.lang.Double","double")) {
return "decimal(17,5)";
} else if (isIn(fieldType.getName(),"java.lang.Integer","int")) {
return "int";
} else if (isIn(fieldType.getName(),"java.lang.Float","float")) {
return "float";
}else if(isIn(fieldType.getName(), "java.util.Date","Date")){
return "timestamp";
} else if(isIn(fieldType.getName(), "java.sql.Date","Date")){
return "timestamp";
}else if(isIn(fieldType.getName(),"java.lang.Long","long")&&field.getAnnotation(DBColumn.class)!=null&&field.getAnnotation(DBColumn.class).date()){
return "timestamp";
}else {
int length = null==dbLable?DBColumn.DefaultLength:dbLable.length();
if (isIn(fieldType.getName(),"java.lang.Byte","byte")) {
return "binary("+length+")";
} else if (isIn(fieldType.getName(),"java.lang.Short", "short")) {
return "smallint";
} else if (isIn(fieldType.getName(),"java.lang.Boolean", "boolean")) {
return "boolean";
} else if (isIn(fieldType.getName(),"java.util.UUID")) {
return "binary(16)";
} else if (isIn(fieldType.getName(),"java.lang.String")) {
return "varchar("+length+")";
} else{
throw new ORMNotDBColumnException("暂时不支持此类型自动映射:【"+field.getName()+"】"+fieldType.getName());
}
}
}
return dbLable.type()+getColumnOther(field, dbLable, getColumnType(), getColumnName());
}
private String getColumnOther(Field f, DBColumn lable, String columnType,
String columnName) {
String str;
if(columnType.contains("varchar")){
str = "CHARACTER SET utf8 DEFAULT "+getColumnDefault(lable);
}else if(columnName.toUpperCase().equals("RECID")){
str = "NOT NULL";
}else if(!lable.canNull()){
str = "NOT Null";
}else{
str = "";
// str = "DEFAULT "+getColumnDefault(lable);
}
if(null != lable.comment() && !"".equals(lable.comment().trim())){
str = str + " COMMENT '"+ lable.comment()+"'";
}
return str;
}
private static String getColumnDefault(DBColumn lable) {
// if(DBColumn.DefaultValue.equals(lable.())){
return "NULL";
// }
// return lable.value();
}
public Object getFormatObj(Object obj){
if(null != dbLable && (dbLable.primaryId() || dbLable.id())){
if(obj instanceof UUID){
return obj.toString();
}else if(obj instanceof String){
return obj;
}else{
throw new ORMParamNotRecognitionException("guid类型:"+obj);
}
}
return obj;
}
public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException{
field.set(obj, value);
}
//
private void valiColumn() throws ORMNotDBColumnException{
if(!isMapping()) throw new ORMNotDBColumnException();
}
//
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((field == null) ? 0 : field.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BaseDBColumn other = (BaseDBColumn) obj;
if (field == null) {
if (other.field != null)
return false;
} else if (!field.equals(other.field))
return false;
return true;
}
public Object getValue(Cursor rs) {
return getFieldValue(this, rs);
}
private static Object getFieldValue(BaseDBColumn field, Cursor rs) {
Object obj = null;
String name = field.getColumnName();
int columnIndex = rs.getColumnIndex(name);
Class<?> fieldType = field.getField().getType();
DBColumn lable = field.getDBColumn();
if(null != lable && (lable.id() || lable.primaryId()) && isIn(fieldType.getName(),"java.lang.String")){
try {
obj = rs.getString(columnIndex);
} catch (Throwable e) {
return null;
}
}
else if (isIn(fieldType.getName(),"java.lang.Long","long")) {
// if(null != lable && field.getField().getAnnotation(DBColumn.class).date()){
// try {
// obj = rs.getTimestamp(columnIndex).getTime();
// } catch (Exception e) {
// obj = getLong(rs, obj, columnIndex, fieldType);
// }
// }else{
// obj = getLong(rs, obj, columnIndex, fieldType);
// }
try {
rs.getLong(columnIndex);
} catch (Throwable e) {
if(fieldType.getName().equals("double"))
obj = 0l;
else
return null;
}
} else if (isIn(fieldType.getName(),"java.lang.Double","double")) {
try {
obj = rs.getDouble(columnIndex);
} catch (Throwable e) {
if(fieldType.getName().equals("double"))
obj = 0d;
else
return null;
}
} else if (isIn(fieldType.getName(),"java.lang.Integer","int")) {
try {
obj = rs.getInt(columnIndex);
} catch (Throwable e) {
if(fieldType.getName().equals("int"))
obj = 0;
else
return null;
}
} else if (isIn(fieldType.getName(),"java.lang.Float","float")) {
try {
obj = rs.getFloat(columnIndex);
} catch (Throwable e) {
if(fieldType.getName().equals("float"))
obj = 0f;
else
return null;
}
} else if (isIn(fieldType.getName(),"java.lang.Byte","byte")) {
try {
obj = new Byte(rs.getString(columnIndex));
} catch (Throwable e) {
return null;
}
} else if (isIn(fieldType.getName(),"java.lang.Short", "short")) {
try {
obj = rs.getShort(columnIndex);
} catch (Throwable e) {
if(fieldType.getName().equals("short"))
obj = (short)0;
else
return null;
}
} else if (isIn(fieldType.getName(),"java.lang.Boolean", "boolean")) {
try {
obj = 1 == rs.getInt(columnIndex);
} catch (Throwable e) {
if(fieldType.getName().equals("boolean"))
obj = false;
else
return null;
}
} else if (isIn(fieldType.getName(),"java.util.UUID")) {
try {
obj = UUID.fromString(rs.getString(columnIndex));
} catch (Throwable e) {
return null;
}//UUID.valueOf(str);
} else if (isIn(fieldType.getName(),"java.lang.String")) {
try {
obj = rs.getString(columnIndex);
} catch (Throwable e) {
return null;
}
}else if(fieldType.isArray() && isIn(fieldType.getName(), "[B", "[Ljava.lang.Byte;")){
try{
obj = rs.getBlob(columnIndex);
}catch(Throwable e){
return null;
}
}else if(isIn(fieldType.getName(),"java.math.BigInteger")){
try {
obj = new BigInteger(rs.getString(columnIndex));
} catch (Throwable e) {
return null;
}
} else{
obj = null;
}
return obj;
}
public static boolean isIn(String str, String...ins){
for(String s : ins){
if(s.equals(str)){
return true;
}
}
return false;
}
}