package com.salama.android.datacore;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.w3c.tools.codec.Base64FormatException;
import com.salama.android.util.SSLog;
import MetoXML.Base.XmlContentEncoder;
import MetoXML.Cast.BaseTypesMapping;
import MetoXML.Util.PropertyDescriptor;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
public class SqliteUtil {
/**
* Sqlite数据类型
* @author liuxinggu
*
*/
public enum SqliteColType {SQLITE_TEXT, SQLITE_FLOAT, SQLITE_INTEGER};
private SQLiteDatabase _db;
private String _dbFilePath;
// private static SimpleDateFormat JavaUtilDateFormatForParse = new
// SimpleDateFormat(
// "EEE MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
// private static SimpleDateFormat JavaSqlTimeStampFormatForParse = new
// SimpleDateFormat(
// "yyyy-MM-dd HH:mm:ss.SSS");
// private static SimpleDateFormat JavaSqlDateFormatForParse = new
// SimpleDateFormat(
// "yyyy-mm-dd");
/**
* 编码用于SQL文中的值
* <BR>仅将 ' 转换为 ''
* @param strValue 字符串
* @return 编码后的字符串
*/
public static String encodeQuoteChar(String strValue) {
if (strValue == null || strValue.length() == 0) {
return strValue;
} else {
return strValue.replaceAll("'", "''");
}
}
/**
* 根据属性类型取得SQLite数据类型
* @param propertyType 属性类型
* @return Sqlite数据类型
*/
public static SqliteColType getSQLiteColumnTypeByPropertyType(Class<?> propertyType) {
if (propertyType == boolean.class) {
return SqliteColType.SQLITE_TEXT;
} else if (propertyType == byte.class) {
return SqliteColType.SQLITE_INTEGER;
} else if (propertyType == short.class) {
return SqliteColType.SQLITE_INTEGER;
} else if (propertyType == int.class) {
return SqliteColType.SQLITE_INTEGER;
} else if (propertyType == long.class) {
return SqliteColType.SQLITE_INTEGER;
} else if (propertyType == float.class) {
return SqliteColType.SQLITE_FLOAT;
} else if (propertyType == double.class) {
return SqliteColType.SQLITE_FLOAT;
} else if (propertyType == char.class) {
return SqliteColType.SQLITE_TEXT;
} else if (propertyType == Boolean.class) {
return SqliteColType.SQLITE_TEXT;
} else if (propertyType == Byte.class) {
return SqliteColType.SQLITE_INTEGER;
} else if (propertyType == Short.class) {
return SqliteColType.SQLITE_INTEGER;
} else if (propertyType == Integer.class) {
return SqliteColType.SQLITE_INTEGER;
} else if (propertyType == Long.class) {
return SqliteColType.SQLITE_INTEGER;
} else if (propertyType == Float.class) {
return SqliteColType.SQLITE_FLOAT;
} else if (propertyType == Double.class) {
return SqliteColType.SQLITE_FLOAT;
} else if (propertyType == Character.class) {
return SqliteColType.SQLITE_TEXT;
} else if (propertyType == java.util.Date.class) {
return SqliteColType.SQLITE_TEXT;
} else if (propertyType == java.sql.Date.class) {
return SqliteColType.SQLITE_TEXT;
} else if (propertyType == java.sql.Timestamp.class) {
return SqliteColType.SQLITE_TEXT;
} else if (propertyType == BigDecimal.class) {
return SqliteColType.SQLITE_TEXT;
} else if (propertyType == byte[].class) {
return SqliteColType.SQLITE_TEXT;
} else {
return SqliteColType.SQLITE_TEXT;
}
}
/**
* 转换基础类型(byte,short,int,long,double,byte[],char,java.sql.date,java.util.date)为字符串
* @param obj
* @return 字符串
*/
public static String convertObjectToString(Object obj) {
if(obj == null) {
return "";
} else {
if (obj.getClass() == byte[].class) {
try {
return BaseTypesMapping.EncodeBase64((byte[])obj);
} catch (IOException e) {
Log.e("SqliteUtil", "Error occurred in fetchColumnToData() in doing DecodeBase64", e);
return "";
}
} else {
return BaseTypesMapping.ConvertBaseTypeValueToStr(obj.getClass(), obj);
}
}
}
/**
* 取得SQLiteDataBase
* @return SQLiteDataBase
*/
public SQLiteDatabase getDb() {
return _db;
}
/**
* 构造函数
* @param dbFilePath 数据库文件路径
*/
public SqliteUtil(String dbFilePath) {
this._dbFilePath = dbFilePath;
}
/**
* 打开数据库连接
*/
public void open() {
_db = SQLiteDatabase.openOrCreateDatabase(this._dbFilePath, null);
}
/**
* 关闭数据库连接
*/
public void close() {
if (_db != null) {
_db.close();
}
}
/**
* 查询整型字段
* @param sql SQL文
* @return 第1条记录的第1个字段
*/
public int executeIntScalar(String sql) {
Cursor cur = null;
int rtValue = 0;
try {
if(SSLog.getSSLogLevel() <= SSLog.SSLogLevelDebug) {
SSLog.d("SqliteUtil", "executeIntScalar() sql:".concat(sql));
}
cur = _db.rawQuery(sql, null);
if (cur.moveToNext()) {
rtValue = cur.getInt(0);
}
} catch (Exception e) {
Log.e("SqliteUtil", "", e);
} finally {
try {
cur.close();
} catch(Exception e) {}
}
return rtValue;
}
/**
* 查询长整型字段
* @param sql SQL文
* @return 第1条记录的第1个字段
*/
public long executeLongScalar(String sql) {
Cursor cur = null;
long rtValue = 0;
try {
if(SSLog.getSSLogLevel() <= SSLog.SSLogLevelDebug) {
SSLog.d("SqliteUtil", "executeLongScalar() sql:".concat(sql));
}
cur = _db.rawQuery(sql, null);
if (cur.moveToNext()) {
rtValue = cur.getLong(0);
}
} catch (Exception e) {
Log.e("SqliteUtil", "", e);
} finally {
try {
cur.close();
} catch(Exception e) {}
}
return rtValue;
}
/**
* 查询双精度浮点字段
* @param sql SQL文
* @return 第1条记录的第1个字段
*/
public double executeDoubleScalar(String sql) {
Cursor cur = null;
double rtValue = 0;
try {
if(SSLog.getSSLogLevel() <= SSLog.SSLogLevelDebug) {
SSLog.d("SqliteUtil", "executeDoubleScalar() sql:".concat(sql));
}
cur = _db.rawQuery(sql, null);
if (cur.moveToNext()) {
rtValue = cur.getDouble(0);
}
} catch (Exception e) {
Log.e("SqliteUtil", "", e);
} finally {
try {
cur.close();
} catch(Exception e) {}
}
return rtValue;
}
/**
* 查询字符串字段
* @param sql SQL文
* @return 第1条记录的第1个字段
*/
public String executeStringScalar(String sql) {
Cursor cur = null;
try {
if(SSLog.getSSLogLevel() <= SSLog.SSLogLevelDebug) {
SSLog.d("SqliteUtil", "executeStringScalar() sql:".concat(sql));
}
cur = _db.rawQuery(sql, null);
if (cur.moveToNext()) {
return cur.getString(0);
} else {
return "";
}
} catch (Exception e) {
Log.e("SqliteUtil", "", e);
return "";
} finally {
try {
cur.close();
} catch(Exception e) {}
}
}
/**
* 查询数据
* @param sql SQL文
* @param dataType 数据类型
* @return 数据列表
* @throws SqliteUtilException
*/
public List<?> findDataList(String sql, Class<?> dataType)
throws SqliteUtilException {
List<Object> returnList = new ArrayList<Object>();
Cursor cur = null;
try {
if(SSLog.getSSLogLevel() <= SSLog.SSLogLevelDebug) {
SSLog.d("SqliteUtil", "findDataList() sql:".concat(sql));
}
cur = _db.rawQuery(sql, null);
boolean isBaseObjectType = isSupportedBaseObjectType(dataType);
//SSLog.d("SqliteUtil", "findDataList() isBaseObjectType:".concat(String.valueOf(isBaseObjectType)));
if(isBaseObjectType) {
while (cur.moveToNext()) {
returnList.add(fetchRowForBaseType(cur, dataType));
}
} else {
while (cur.moveToNext()) {
returnList.add(fetchRowForDataType(cur, dataType));
}
}
} catch (SqliteUtilException e) {
throw e;
} catch (Exception e) {
Log.e("SqliteUtil", "", e);
} finally {
try {
cur.close();
} catch(Exception e) {}
}
return returnList;
}
private static boolean isSupportedBaseObjectType(Class<?> type) {
//SSLog.d("SqliteUtil", "isSupportedBaseObjectType() type:" + type + " String.class:" + String.class);
if(type == String.class) {
return true;
} else {
return false;
}
}
/**
* 查询数据
* @param sql SQL文
* @param dataType 数据类型
* @return 单条数据
* @throws SqliteUtilException
*/
public Object findData(String sql, Class<?> dataType)
throws SqliteUtilException {
Object data = null;
Cursor cur = null;
try {
if(SSLog.getSSLogLevel() <= SSLog.SSLogLevelDebug) {
SSLog.d("SqliteUtil", "findData() sql:".concat(sql));
}
cur = _db.rawQuery(sql, null);
if (cur.moveToNext()) {
data = fetchRowForDataType(cur, dataType);
}
} catch (Exception e) {
Log.e("SqliteUtil", "", e);
} finally {
try {
cur.close();
} catch(Exception e) {}
}
return data;
}
/**
* 查询数据
* @param sql SQL文
* @param dataType 数据类型
* @return 数据列表Xml内容
*/
public String findDataListXml(String sql, Class<?> dataType) {
String dataNodeName = dataType.getSimpleName();
return findDataListXml(sql, dataNodeName);
}
/**
* 查询数据
* @param sql
* @param dataNodeName
* @return 数据列表Xml内容
*/
public String findDataListXml(String sql, String dataNodeName) {
StringBuilder xmlResult = new StringBuilder();
Cursor cur = null;
try {
if(SSLog.getSSLogLevel() <= SSLog.SSLogLevelDebug) {
SSLog.d("SqliteUtil", "findDataListXml() sql:".concat(sql));
}
cur = _db.rawQuery(sql, null);
appendXmlTagBegin(xmlResult, "List");
while (cur.moveToNext()) {
appendXmlTagBegin(xmlResult, dataNodeName);
for (int i = 0; i < cur.getColumnCount(); i++) {
appendXmlLeafTag(xmlResult,
cur.getColumnName(i), cur.getString(i));
}
appendXmlTagEnd(xmlResult, dataNodeName);
}
appendXmlTagEnd(xmlResult, "List");
} catch (Exception e) {
Log.e("SqliteUtil", "", e);
} finally {
try {
cur.close();
} catch(Exception e) {}
}
return xmlResult.toString();
}
/**
* 查询数据
* @param sql SQL文
* @param dataType 数据类型
* @return 单条数据Xml内容
*/
public String findDataXml(String sql, Class<?> dataType) {
String dataNodeName = dataType.getSimpleName();
return findDataXml(sql, dataNodeName);
}
/**
* 查询数据
* @param sql SQL文
* @param dataType 数据类型
* @return 单条数据Xml内容
*/
public String findDataXml(String sql, String dataNodeName) {
StringBuilder xmlResult = new StringBuilder();
Cursor cur = null;
try {
if(SSLog.getSSLogLevel() <= SSLog.SSLogLevelDebug) {
SSLog.d("SqliteUtil", "findDataXml() sql:".concat(sql));
}
cur = _db.rawQuery(sql, null);
if (cur.moveToNext()) {
appendXmlTagBegin(xmlResult, dataNodeName);
for (int i = 0; i < cur.getColumnCount(); i++) {
appendXmlLeafTag(xmlResult,
cur.getColumnName(i), cur.getString(i));
}
appendXmlTagEnd(xmlResult, dataNodeName);
}
} catch (Exception e) {
Log.e("SqliteUtil", "", e);
} finally {
try {
cur.close();
} catch(Exception e) {}
}
return xmlResult.toString();
}
/**
* 执行更新语句
* @param sql SQL文
* @return 1:正常 0:出错
*/
public int executeUpdate(String sql) {
try {
if(SSLog.getSSLogLevel() <= SSLog.SSLogLevelDebug) {
SSLog.d("SqliteUtil", "executeUpdate() sql:".concat(sql));
}
_db.execSQL(sql);
return 1;
} catch (SQLException e) {
try {
if(e.getMessage().endsWith("(code 19)")) {
SSLog.i("SqliteUtil", e.getMessage() + "\n", e);
} else {
SSLog.e("SqliteUtil", e.getMessage() + "\n", e);
}
} catch(Exception e2) {
SSLog.e("SqliteUtil", e.getMessage() + "\n", e2);
}
return 0;
}
}
private Object fetchRowForBaseType(Cursor cur, Class<?> dataType) {
if(dataType.equals(String.class)) {
//String val = cur.getString(0);
//SSLog.d("SqliteUtil", "fetchRowForBaseType() val:" + val);
return cur.getString(0);
} else {
//SSLog.d("SqliteUtil", "fetchRowForBaseType() not supported type");
return null;
}
}
private Object fetchRowForDataType(Cursor cur, Class<?> dataType)
throws SqliteUtilException {
Object data;
try {
data = dataType.newInstance();
for (int i = 0; i < cur.getColumnCount(); i++) {
fetchColumnToData(dataType, data, cur, i);
}
} catch (InstantiationException e) {
throw new SqliteUtilException(e);
} catch (IllegalAccessException e) {
throw new SqliteUtilException(e);
} catch (IllegalArgumentException e) {
throw new SqliteUtilException(e);
} catch (InvocationTargetException e) {
throw new SqliteUtilException(e);
} catch (ParseException e) {
throw new SqliteUtilException(e);
} catch (UnsupportedEncodingException e) {
throw new SqliteUtilException(e);
} catch (IOException e) {
throw new SqliteUtilException(e);
} catch (Base64FormatException e) {
throw new SqliteUtilException(e);
}
return data;
}
private void fetchColumnToData(Class<?> dataType, Object data, Cursor cur,
int index) throws IllegalArgumentException, IllegalAccessException,
InvocationTargetException, ParseException,
UnsupportedEncodingException, IOException, Base64FormatException {
String colName = cur.getColumnName(index);
PropertyDescriptor pd;
Method getMethod = null;
Method setMethod = null;
try {
pd = new PropertyDescriptor(colName, dataType);
getMethod = pd.getReadMethod();
setMethod = pd.getWriteMethod();
} catch (NoSuchMethodException e) {
// do nothing
}
if (getMethod == null || setMethod == null) {
return;
}
Class<?> propertyType = (Class<?>) getMethod.getReturnType();
if (setMethod != null) {
if (propertyType == boolean.class) {
setMethod.invoke(data, Boolean.valueOf(cur.getString(index)));
} else if (propertyType == byte.class) {
setMethod.invoke(data, Byte.valueOf(cur.getString(index)));
} else if (propertyType == short.class) {
setMethod.invoke(data, cur.getShort(index));
} else if (propertyType == int.class) {
setMethod.invoke(data, cur.getInt(index));
} else if (propertyType == long.class) {
setMethod.invoke(data, cur.getLong(index));
} else if (propertyType == float.class) {
setMethod.invoke(data, cur.getFloat(index));
} else if (propertyType == double.class) {
setMethod.invoke(data, cur.getDouble(index));
} else if (propertyType == char.class) {
setMethod.invoke(data, cur.getString(index).charAt(0));
} else if (propertyType == Boolean.class) {
setMethod.invoke(data, Boolean.valueOf(cur.getString(index)));
} else if (propertyType == Byte.class) {
setMethod.invoke(data, Byte.valueOf(cur.getString(index)));
} else if (propertyType == Short.class) {
setMethod.invoke(data, cur.getShort(index));
} else if (propertyType == Integer.class) {
setMethod.invoke(data, cur.getInt(index));
} else if (propertyType == Long.class) {
setMethod.invoke(data, cur.getLong(index));
} else if (propertyType == Float.class) {
setMethod.invoke(data, cur.getFloat(index));
} else if (propertyType == Double.class) {
setMethod.invoke(data, cur.getDouble(index));
} else if (propertyType == Character.class) {
setMethod.invoke(data, cur.getString(index).charAt(0));
} else if (propertyType == java.util.Date.class) {
setMethod.invoke(data, BaseTypesMapping.ConvertStrToDate(cur.getString(index)));
} else if (propertyType == java.sql.Date.class) {
setMethod.invoke(data, BaseTypesMapping.ConvertStrToSqlDate(cur.getString(index)));
} else if (propertyType == java.sql.Timestamp.class) {
setMethod.invoke(data, BaseTypesMapping.ConvertStrToTimeStamp(cur.getString(index)));
} else if (propertyType == BigDecimal.class) {
setMethod.invoke(data, new BigDecimal(cur.getString(index)));
} else if (propertyType == byte[].class) {
setMethod.invoke(data, BaseTypesMapping.DecodeBase64(cur.getString(index)));
} else {
setMethod.invoke(data, propertyType.cast(cur.getString(index)));
}
}
}
// public Method getGetMethod(Class<?> dataType, String colName)
// {
// String mName = colName.substring(0, 1).toUpperCase()
// + colName.substring(1);
// Method method = null;
// try {
// method = dataType.getMethod("get" + mName, (Class<?>[]) null);
// if(method == null){
// method = dataType.getMethod("is" + mName, (Class<?>[]) null);
// }
// } catch (SecurityException e) {
// return null;
// } catch (NoSuchMethodException e) {
// return null;
// }
// return method;
// }
//
// public Method getSetMethod(Class<?> dataType, String colName)
// {
// String mName = colName.substring(0, 1).toUpperCase()
// + colName.substring(1);
// Method getMethod;
// Method method;
// try {
// getMethod = getGetMethod(dataType, colName);
// method = dataType.getMethod("set" + mName,
// getMethod.getReturnType());
// } catch (SecurityException e) {
// return null;
// } catch (NoSuchMethodException e) {
// return null;
// }
// return method;
// }
protected static void appendXmlTagBegin(StringBuilder xml, String tagName) {
xml.append("<");
xml.append(tagName);
xml.append(">");
}
protected static void appendXmlTagEnd(StringBuilder xml, String tagName) {
xml.append("</");
xml.append(tagName);
xml.append(">");
}
protected static void appendXmlLeafTag(StringBuilder xml, String tagName, String value) {
appendXmlTagBegin(xml, tagName);
//encode value
xml.append(XmlContentEncoder.EncodeContent(value));
appendXmlTagEnd(xml, tagName);
}
}