package com.litesuits.orm.db.utils; import android.annotation.TargetApi; import android.database.Cursor; import android.os.Build; import android.util.Log; import com.litesuits.orm.log.OrmLog; import com.litesuits.orm.db.assit.Checker; import com.litesuits.orm.db.model.EntityTable; import com.litesuits.orm.db.model.Property; import java.io.*; import java.lang.reflect.Field; import java.util.Arrays; import java.util.Collection; import java.util.Date; import java.util.List; /** * SQLite支持的数据类型 * 类型描述摘自sqlite官网 http://sqlite.org/datatype3.html * * @author mty * @date 2013-6-10下午5:28:10 */ public class DataUtil implements Serializable { public static final String TAG = DataUtil.class.getSimpleName(); private static final long serialVersionUID = 6668874253056236676L; /** * NULL. The value is a NULL value. */ public static final String NULL = " NULL "; /** * INTEGER. The value is a signed integer, stored in 1, 2, 3, 4, 6, or 8 * bytes depending on the magnitude of the value. */ public static final String INTEGER = " INTEGER "; /** * REAL. The value is a floating point value, stored as an 8-byte IEEE * floating point number. */ public static final String REAL = " REAL "; /** * TEXT. The value is a text string, stored using the database encoding * (UTF-8, UTF-16BE or UTF-16LE). */ public static final String TEXT = " TEXT "; /** * BLOB. The value is a blob of data, stored exactly as it was input. */ public static final String BLOB = " BLOB "; /** * Value returned by {@link #getType(Object)} if the specified column is null */ public static final int FIELD_TYPE_NULL = 0; /** * Value returned by {@link #getType(Object)} if the specified column type is * integer or long */ public static final int FIELD_TYPE_LONG = 1; /** * Value returned by {@link #getType(Object)} if the specified column type is * float or double */ public static final int FIELD_TYPE_REAL = 2; /** * Value returned by {@link #getType(Object)} if the specified column type is * string */ public static final int FIELD_TYPE_STRING = 3; /** * Value returned by {@link #getType(Object)} if the specified column type is * blob */ public static final int FIELD_TYPE_BLOB = 4; /** * Value returned by {@link #getType(Object)} if the specified column type is * date */ public static final int FIELD_TYPE_DATE = 5; /** * Value returned by {@link #getType(Object)} if the specified column type is * serializable */ public static final int FIELD_TYPE_SERIALIZABLE = 6; public static final int CLASS_TYPE_NONE = 0; public static final int CLASS_TYPE_STRING = 1; public static final int CLASS_TYPE_BOOLEAN = 2; public static final int CLASS_TYPE_DOUBLE = 3; public static final int CLASS_TYPE_FLOAT = 4; public static final int CLASS_TYPE_LONG = 5; public static final int CLASS_TYPE_INT = 6; public static final int CLASS_TYPE_SHORT = 7; public static final int CLASS_TYPE_BYTE = 8; public static final int CLASS_TYPE_BYTE_ARRAY = 9; public static final int CLASS_TYPE_CHAR = 10; public static final int CLASS_TYPE_DATE = 11; public static final int CLASS_TYPE_SERIALIZABLE = 12; public static final int CLASS_TYPE_UNKNOWN = 13; /** * Returns data type of the given object. * <p> * Returned column types are * <ul> * <li>{@link #FIELD_TYPE_NULL}</li> * <li>{@link #FIELD_TYPE_LONG}</li> * <li>{@link #FIELD_TYPE_REAL}</li> * <li>{@link #FIELD_TYPE_STRING}</li> * <li>{@link #FIELD_TYPE_BLOB}</li> * <li>{@link #FIELD_TYPE_DATE}</li> * <li>{@link #FIELD_TYPE_SERIALIZABLE}</li> * </ul> * </p> */ public static int getType(Object obj) { if (obj == null) { return FIELD_TYPE_NULL; } else if (obj instanceof CharSequence || obj instanceof Boolean || obj instanceof Character) { return FIELD_TYPE_STRING; } else if (obj instanceof Float || obj instanceof Double) { return FIELD_TYPE_REAL; } else if (obj instanceof Number) { return FIELD_TYPE_LONG; } else if (obj instanceof Date) { return FIELD_TYPE_DATE; } else if (obj instanceof byte[]) { return FIELD_TYPE_BLOB; } else if (obj instanceof Serializable) { return FIELD_TYPE_SERIALIZABLE; } else { return FIELD_TYPE_NULL; } } public static String getSQLDataType(int classType) { switch (classType) { case CLASS_TYPE_STRING: case CLASS_TYPE_BOOLEAN: case CLASS_TYPE_CHAR: return TEXT; case CLASS_TYPE_DOUBLE: case CLASS_TYPE_FLOAT: return REAL; case CLASS_TYPE_LONG: case CLASS_TYPE_INT: case CLASS_TYPE_SHORT: case CLASS_TYPE_BYTE: case CLASS_TYPE_DATE: return INTEGER; case CLASS_TYPE_BYTE_ARRAY: case CLASS_TYPE_SERIALIZABLE: default: return BLOB; } } /** * 将Cursor的数据注入模型 * 支持11种基本类型,见{@link ClassUtil#isBaseDataType(Class)} ()} * 同时支持序列化对象 * * @param c 数据库Cursor * @param entity 实体对象 */ public static void injectDataToObject(Cursor c, Object entity, EntityTable table) throws Exception { Field f; Property p; for (int i = 0, size = c.getColumnCount(); i < size; i++) { //long start = System.nanoTime(); String col = c.getColumnName(i); p = null; if (!Checker.isEmpty(table.pmap)) { p = table.pmap.get(col); } if (p == null && table.key != null && col.equals(table.key.column)) { p = table.key; } if (p == null) { if (OrmLog.isPrint) { OrmLog.w(TAG, "数据库字段[" + col + "]已在实体中被移除"); } continue; } f = p.field; f.setAccessible(true); //Log.i(TAG, "parse pre after " + ((System.nanoTime() - start) / 1000)); //start = System.nanoTime(); switch (p.classType) { case CLASS_TYPE_STRING: f.set(entity, c.getString(i)); break; case CLASS_TYPE_BOOLEAN: f.set(entity, Boolean.parseBoolean(c.getString(i))); break; case CLASS_TYPE_LONG: f.set(entity, c.getLong(i)); break; case CLASS_TYPE_INT: f.set(entity, c.getInt(i)); break; case CLASS_TYPE_DOUBLE: f.set(entity, c.getDouble(i)); break; case CLASS_TYPE_FLOAT: f.set(entity, c.getFloat(i)); break; case CLASS_TYPE_SHORT: f.set(entity, c.getShort(i)); break; case CLASS_TYPE_BYTE: if (c.getString(i) != null) { f.set(entity, Byte.parseByte(c.getString(i))); } break; case CLASS_TYPE_BYTE_ARRAY: f.set(entity, c.getBlob(i)); break; case CLASS_TYPE_CHAR: String value = c.getString(i); if (!Checker.isEmpty(value)) { f.set(entity, value.charAt(0)); } break; case CLASS_TYPE_DATE: Long time = c.getLong(i); if (time != null) { f.set(entity, new Date(time)); } break; case CLASS_TYPE_SERIALIZABLE: byte[] bytes = c.getBlob(i); if (bytes != null) { //序列化的对象 f.set(entity, byteToObject(bytes)); } break; default: break; } //Log.i(TAG, "parse set after " + ((System.nanoTime() - start) / 1000)); } } public static int getFieldClassType(Field f) { Class type = f.getType(); if (CharSequence.class.isAssignableFrom(type)) { return CLASS_TYPE_STRING; } else if (boolean.class.isAssignableFrom(type) || Boolean.class.isAssignableFrom(type)) { return CLASS_TYPE_BOOLEAN; } else if (double.class.isAssignableFrom(type) || Double.class.isAssignableFrom(type)) { return CLASS_TYPE_DOUBLE; } else if (float.class.isAssignableFrom(type) || Float.class.isAssignableFrom(type)) { return CLASS_TYPE_FLOAT; } else if (long.class.isAssignableFrom(type) || Long.class.isAssignableFrom(type)) { return CLASS_TYPE_LONG; } else if (int.class.isAssignableFrom(type) || Integer.class.isAssignableFrom(type)) { return CLASS_TYPE_INT; } else if (short.class.isAssignableFrom(type) || Short.class.isAssignableFrom(type)) { return CLASS_TYPE_SHORT; } else if (byte.class.isAssignableFrom(type) || Byte.class.isAssignableFrom(type)) { return CLASS_TYPE_BYTE; } else if (byte[].class.isAssignableFrom(type) || Byte[].class.isAssignableFrom(type)) { return CLASS_TYPE_BYTE_ARRAY; } else if (char.class.isAssignableFrom(type) || Character.class.isAssignableFrom(type)) { return CLASS_TYPE_CHAR; } else if (Date.class.isAssignableFrom(type)) { return CLASS_TYPE_DATE; } else if (Serializable.class.isAssignableFrom(type)) { return CLASS_TYPE_SERIALIZABLE; } return CLASS_TYPE_UNKNOWN; } /** * byte[] 转为 对象 */ public static Object byteToObject(byte[] bytes) throws Exception { ObjectInputStream ois = null; try { ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); return ois.readObject(); } finally { if (ois != null) ois.close(); } } /** * 对象 转为 byte[] */ public static byte[] objectToByte(Object obj) throws IOException { ObjectOutputStream oos = null; try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(bos); oos.writeObject(obj); return bos.toByteArray(); } finally { if (oos != null) oos.close(); } } public static List<?> arrayToList(Object[] array) { return Arrays.asList(array); } public static Object[] arrayToList(Collection<?> coll) { return coll.toArray(); } @TargetApi(Build.VERSION_CODES.GINGERBREAD) public static <T> T[] concat(T[] first, T[] second) { T[] result = Arrays.copyOf(first, first.length + second.length); System.arraycopy(second, 0, result, first.length, second.length); return result; } @TargetApi(Build.VERSION_CODES.GINGERBREAD) public static <T> T[] concatAll(T[] first, T[]... rest) { int totalLength = first.length; for (T[] array : rest) { totalLength += array.length; } T[] result = Arrays.copyOf(first, totalLength); int offset = first.length; for (T[] array : rest) { System.arraycopy(array, 0, result, offset, array.length); offset += array.length; } return result; } }