package com.salama.android.jsservice.base.natives.sql; import java.util.StringTokenizer; import java.util.concurrent.ConcurrentHashMap; import MetoXML.XmlDeserializer; import MetoXML.XmlReader; import MetoXML.Base.XmlNode; import android.util.Log; import com.salama.android.datacore.DBDataUtil; import com.salama.android.datacore.SqliteUtil; import com.salama.android.datacore.SqliteUtilException; import com.salama.android.datacore.TableDesc; import com.salama.android.dataservice.SalamaDataService; public class SqlService { private final SalamaDataService _dataService; private ConcurrentHashMap<String, String> _colTypeMapping = new ConcurrentHashMap<String, String>(); public SqlService(SalamaDataService dataService) { _dataService = dataService; } /** * 判断表是否已经存在 * @return 0:不存在 1:存在 */ public int isTableExists(String tableName) { DBDataUtil dbDataUtil = null; try { dbDataUtil = _dataService.getDbManager().createNewDBDataUtil(); return dbDataUtil.isTableExists(tableName)?1:0; } catch (SqliteUtilException e) { Log.e("SqlService", "isTableExists()", e); return 0; } finally { try{ dbDataUtil.close(); } catch(Exception e) { } } } /** * 建表(如果表已经存在,则不做任何事) * @param tableDesc 表结构描述 * @return 表名 */ public String createTable(TableDesc tableDesc) { DBDataUtil dbDataUtil = null; try { dbDataUtil = _dataService.getDbManager().createNewDBDataUtil(); if(!dbDataUtil.isTableExists(tableDesc.getTableName())) { dbDataUtil.createTable(tableDesc); } return tableDesc.getTableName(); } catch (SqliteUtilException e) { Log.e("SqlService", "createTable()", e); return tableDesc.getTableName(); } finally { try{ dbDataUtil.close(); } catch(Exception e) { } } } /** * 删表 * @param tableName 表名 * @return 表名 */ public String dropTable(String tableName) { DBDataUtil dbDataUtil = null; try { dbDataUtil = _dataService.getDbManager().createNewDBDataUtil(); dbDataUtil.dropTable(tableName); return tableName; } catch (SqliteUtilException e) { Log.e("SqlService", "dropTable()", e); return tableName; } finally { try{ dbDataUtil.close(); } catch(Exception e) { } } } /** * 执行查询语句 * @param sql sql文 * @return 查询结果(XML格式。例:<List><TestData>...</TestData><TestData>...</TestData>......</List>) */ public String executeQuery(String sql, String dataNodeName) { DBDataUtil dbDataUtil = null; try { dbDataUtil = _dataService.getDbManager().createNewDBDataUtil(); return dbDataUtil.getSqliteUtil().findDataListXml(sql, dataNodeName); } catch (SqliteUtilException e) { Log.e("SqlService", "executeQuery()", e); return ""; } finally { try{ dbDataUtil.close(); } catch(Exception e) { } } } /** * 执行更新语句(update或delete) * @param sql sql文 * @return 1:成功 0:失败 */ public int executeUpdate(String sql) { DBDataUtil dbDataUtil = null; try { dbDataUtil = _dataService.getDbManager().createNewDBDataUtil(); return dbDataUtil.getSqliteUtil().executeUpdate(sql); } catch (SqliteUtilException e) { Log.e("SqlService", "executeUpdate()", e); return 0; } finally { try{ dbDataUtil.close(); } catch(Exception e) { } } } /** * 插入数据 * @param dataTable 表名 * @param dataXml 数据XML * @return dataXml 数据XML。失败的场合,返回nil。 */ public String insertData(String dataTable, String dataXml) { //make sql ------------------ StringBuilder sqlColNamesPart = new StringBuilder(); StringBuilder sqlColValuesPart = new StringBuilder(); sqlColNamesPart.append("("); sqlColValuesPart.append("("); try { XmlReader xmlReader = new XmlReader(); XmlNode xmlRootNode = xmlReader.StringToXmlNode(dataXml, XmlDeserializer.DefaultCharset); XmlNode nodeTmp = null; nodeTmp = xmlRootNode.getFirstChildNode(); int colIndex = 0; String nodeName = null; String nodeValue = null; String colType = null; while(nodeTmp != null) { nodeName = nodeTmp.getName(); nodeValue = nodeTmp.getContent(); //col name if(colIndex != 0) { sqlColNamesPart.append(","); sqlColValuesPart.append(","); } sqlColNamesPart.append(nodeName); //col type colType = getColTypeOfTable(dataTable, nodeName); if(colType == null) { throw new RuntimeException("Column " + nodeName + " maybe not exists in table " + dataTable); } else { if(colType.equals("text")) { sqlColValuesPart.append("'").append(SqliteUtil.encodeQuoteChar(nodeValue)).append("'"); } else { sqlColValuesPart.append(nodeValue); } } nodeTmp = nodeTmp.getNextNode(); colIndex ++; } } catch(Exception e) { Log.e("SqlService", "insertData()", e); return null; } sqlColNamesPart.append(")"); sqlColValuesPart.append(")"); StringBuilder sql = new StringBuilder(); sql.append("insert into ").append(dataTable) .append(" ").append(sqlColNamesPart.toString()) .append(" values ").append(sqlColValuesPart); //execute sql ------------------ DBDataUtil dbDataUtil = null; try { dbDataUtil = _dataService.getDbManager().createNewDBDataUtil(); int success = dbDataUtil.getSqliteUtil().executeUpdate(sql.toString()); if(success != 0) { return dataXml; } else { return null; } } catch (SqliteUtilException e) { Log.e("SqlService", "insertData()", e); return null; } finally { try{ dbDataUtil.close(); } catch(Exception e) { } } } private String getColTypeMappingKeyOfTable(String table, String colName) { return table.toLowerCase().concat(".").concat(colName.toLowerCase()); } private void setColTypeOfTable(String table, String colName, String colType) { String colTypeLower = colType.toLowerCase(); if(colTypeLower.equals("text") || colTypeLower.equals("integer") || colTypeLower.equals("real")) { String key = getColTypeMappingKeyOfTable(table, colName); _colTypeMapping.put(key, colTypeLower); } } private String getColTypeOfTable(String table, String colName) { String key = getColTypeMappingKeyOfTable(table, colName); String colType = _colTypeMapping.get(key); if(colType == null) { loadColTypesOfTable(table); return _colTypeMapping.get(key); } else { return colType; } } private void loadColTypesOfTable(String table) { DBDataUtil dbDataUtil = null; String createTblSql = null; try { dbDataUtil = _dataService.getDbManager().createNewDBDataUtil(); createTblSql = dbDataUtil.getSqliteUtil().executeStringScalar( "select sql from sqlite_master where lower(tbl_name) = lower('".concat(table).concat("')")); } catch (SqliteUtilException e) { Log.e("SqlService", "loadColTypesOfTable()", e); return; } finally { try{ dbDataUtil.close(); } catch(Exception e) { } } if(createTblSql == null || createTblSql.length() == 0) { Log.e("SqlService", "loadColTypesOfTable() Warning: Table %@ does not exists in sqlite DB"); return; } int index0 = createTblSql.indexOf('('); int index1 = createTblSql.lastIndexOf(')'); String colsPart = createTblSql.substring(index0 + 1, index1); StringTokenizer stk = new StringTokenizer(colsPart, ","); String colPart = null; String colName = null; String colType = null; int index = 0; while(stk.hasMoreTokens()) { colPart = stk.nextToken().trim(); index = colPart.indexOf(' '); if(index > 0) { colName = colPart.substring(0, index).trim(); colType = colPart.substring(index + 1).trim(); setColTypeOfTable(table, colName, colType); } } } }