/** * <p>Copyright: Copyright (c) 2013</p> * <p>Company: �������ӹɷ����޹�˾</p> */ package com.hundsun.ares.studio.atom.compiler.mysql.macro.handlers; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import com.hundsun.ares.studio.atom.AtomFunction; import com.hundsun.ares.studio.atom.AtomService; import com.hundsun.ares.studio.atom.compiler.mysql.constant.IAtomEngineContextConstantMySQL; import com.hundsun.ares.studio.atom.compiler.mysql.exception.MacroParameterErrorException; import com.hundsun.ares.studio.atom.compiler.mysql.exception.TableNotFoundException; import com.hundsun.ares.studio.atom.compiler.mysql.macro.MacroConstant; import com.hundsun.ares.studio.atom.compiler.mysql.macro.TokenDomain; import com.hundsun.ares.studio.atom.compiler.mysql.skeleton.util.TableResourceUtil; import com.hundsun.ares.studio.atom.compiler.mysql.token.PROCResultSetStatementToken; import com.hundsun.ares.studio.core.IARESProject; import com.hundsun.ares.studio.engin.constant.IEngineContextConstant; import com.hundsun.ares.studio.engin.constant.ITokenConstant; import com.hundsun.ares.studio.engin.macrohandler.IMacroTokenHandler; import com.hundsun.ares.studio.engin.skeleton.ISkeletonAttributeHelper; import com.hundsun.ares.studio.engin.token.DefaultTokenEvent; import com.hundsun.ares.studio.engin.token.ICodeToken; import com.hundsun.ares.studio.engin.token.IDomainHandler; import com.hundsun.ares.studio.engin.token.ITokenDomain; import com.hundsun.ares.studio.engin.token.ITokenListenerManager; import com.hundsun.ares.studio.engin.token.macro.IMacroToken; import com.hundsun.ares.studio.jres.model.database.TableColumn; /** * @author zhuyf * */ public class PROCResultSetStatementMacroHandler implements IMacroTokenHandler { private List<String> queryFieldList;//���ڱ���Select���IJ�ѯ�ֶ� private List<String> inFieldList;//���ڱ��涯̬���������ֶ� /* (non-Javadoc) * @see com.hundsun.ares.studio.engin.macrohandler.IMacroTokenHandler#getKey() */ @Override public String getKey() { return MacroConstant.PROC_RESULTSET_STATEMENT_MACRONAME; } /* (non-Javadoc) * @see com.hundsun.ares.studio.engin.macrohandler.IMacroTokenHandler#handle(com.hundsun.ares.studio.engin.token.macro.IMacroToken, java.util.Map) */ @Override public Iterator<ICodeToken> handle(IMacroToken token, Map<Object, Object> context) throws Exception { /* * ���������� [PRO*C��������][ sql��ѯ���] �������̣� 1.��ȡselect���IJ�ѯ�ֶ� ��Ҫ��*�Ĵ������ܱ�����Ƿ���ڣ�����������ȡ�ֶΣ��ҿ���selectǶ�׵���������������select�ֶ�Ϊ׼ ȥ��ע������*��Ӱ�� ������ֶ��п��ܴ��к�������nvl �ֶο�����as�����������ô�ڽ��������ʱ��ʹ��as������ΪAddField���ֶ��� 2.��ѯ�ֶδ����У��������ĺ괦����[POR*C���������] 3.����������䣺 EXEC SQL DECLARE cursor[�����]+[���] CURSOR FOR [select���]; EXEC SQL OPEN cursor[�����]+[���]; if (CheckDbLinkMethod(lpConn,SQLCODE) < 0) { if ((SQLCODE<= ERR_DB_NO_CONTINUE_FETCH) && (SQLCODE>= ERR_DB_FAILOVER_NETWORK_OPER_FAIL)) { iReturnCode = SQLCODE; v_error_no = SQLCODE; hs_strncpy(v_error_info,sqlca.sqlerrm.sqlerrmc,sqlca.sqlerrm.sqlerrml); v_error_id = SQLCODE; hs_strncpy(v_error_sysinfo,sqlca.sqlerrm.sqlerrmc,sqlca.sqlerrm.sqlerrml); EXEC SQL rollback; goto svr_end; } lpConn->setErrMessage(HSDB_CONNECTION_STATUS_DISCONN,SQLCODE,sqlca.sqlerrm.sqlerrmc); } if (SQLCODE == OK_SUCCESS) ����[select���]��5���ֶ�Ϊһ�У������select��׷�Ӷ���ŵ�ע����Ϣ 4.�����α굽�����б��� 5.SQL���֧����ʷ���鵵�����ࡢ�������ձ� [PRO*C��������][select * from his_clientjour][clientjour] [PRO*C��������][select * from fil_clientjour][clientjour] [PRO*C��������][select * from r_clientjour][clientjour] [PRO*C��������][select * from rl_clientjour][clientjour] */ queryFieldList = new ArrayList<String>(); inFieldList = new ArrayList<String>(); addMacroNameToMacroList(token,context);//�Ѻ����ӵ������ݿ��б��Լ�proc�б��� List<ICodeToken> codeList = new ArrayList<ICodeToken>(); if(token.getParameters().length==3){//����û��г����ֶ� String[] tempSqlFields = StringUtils.split(token.getParameters()[2], ","); for(int i = 0;i<tempSqlFields.length;i++){ queryFieldList.add(StringUtils.trim(tempSqlFields[i])); } }else{//û���г��ֶ������sql���,��sql����л���ֶ� getAllFieldsFromSqlStr(getFieldString(token,context),context); splitFieldList(token,context); } ISkeletonAttributeHelper helper = (ISkeletonAttributeHelper)context.get(IAtomEngineContextConstantMySQL.SKELETON_ATTRIBUTE_HELPER); Set<String> rsList = helper.getAttribute(IAtomEngineContextConstantMySQL.ATTR_RESULTSET_LIST); Set<String> stateList = helper.getAttribute(IAtomEngineContextConstantMySQL.ATTR_STATEMENT_LIST); AtomFunction func = (AtomFunction)context.get(IAtomEngineContextConstantMySQL.ResourceModel); int rsTotalSizeAdd1 = rsList.size() + 1; int stateTotalSizeAdd1 = stateList.size() + 1; String objectId = func.getObjectId(); if(StringUtils.isBlank(objectId) && (func instanceof AtomService)){ ITokenListenerManager manager = (ITokenListenerManager)context.get(IEngineContextConstant.TOKEN_LISTENER_MANAGER); String message = "��ȡ���ܺ�ʧ��,�޷���������lpResultSet"; manager.fireEvent(new DefaultTokenEvent(ITokenConstant.EVENT_ENGINE_WARNNING,message)); }else if(StringUtils.isBlank(objectId) && !(func instanceof AtomService)){ objectId = func.getName(); } String rsID = objectId + rsTotalSizeAdd1; addDomain(token,context,queryFieldList,rsID);//����� String stateID = objectId + stateTotalSizeAdd1; helper.addAttribute(IAtomEngineContextConstantMySQL.ATTR_STATEMENT_LIST,stateID);//�����ͷŵĶ�̬����б� helper.addAttribute(IAtomEngineContextConstantMySQL.ATTR_RESULTSET_LIST,rsID);//�����ͷŵĽ�����б� helper.addAttribute(IAtomEngineContextConstantMySQL.ATTR_GETLAST_RESULTSET,rsID);// codeList.add(new PROCResultSetStatementToken(token,rsID,stateID,queryFieldList,inFieldList));//���codeToken return codeList.iterator(); } /** * ����� */ private void addDomain(IMacroToken token, Map<Object, Object> context,List<String> sqlFields,String rdId){ IDomainHandler handler = (IDomainHandler) context.get(IEngineContextConstant.DOMAIN_HANDLER); String key = getKey(); Object[] args = new Object[2]; args[0] = rdId;//��ӽ����Id��������������ػ�PRO*C��¼��ȡ��ʼ��PRO*C��¼��ȡ���������ɴ���ʱ��Ҫʹ�á� args[1] = sqlFields;//�α��ֶ����� ITokenDomain tokenDomain = new TokenDomain(key,args); handler.addDomain(tokenDomain); } /** * �Ѻ������뵽���б��� */ private void addMacroNameToMacroList(IMacroToken token, Map<Object, Object> context){ ISkeletonAttributeHelper helper = (ISkeletonAttributeHelper)context.get(IAtomEngineContextConstantMySQL.SKELETON_ATTRIBUTE_HELPER); helper.addAttribute(IAtomEngineContextConstantMySQL.ATTR_DATABASE_MACRO,token.getKeyword());//��ӵ����ݿ��б��� helper.addAttribute(IAtomEngineContextConstantMySQL.ATTR_PROC_MACRO,token.getKeyword());//��ӵ�proc���б��� } /** * ����[PRO*C��������]SQL��� * * @return ������sql��� * @throws TableNotFoundException */ private String getFieldString(IMacroToken token, Map<Object, Object> context) throws TableNotFoundException,MacroParameterErrorException{ String sqlStr = getSqlStrReplaceComm(token); String sTableName = ""; if (token.getParameters().length >= 2) { sTableName = token.getParameters()[1]; } Pattern p = Pattern.compile("\\s*select\\s+\\*\\s+from\\s*\\("); Matcher m = p.matcher(sqlStr); while (m.find()) { if (m.start() == 0) { sqlStr = sqlStr.substring(m.end()); m = p.matcher(sqlStr); } } String fieldStr = sqlStr.substring(sqlStr.indexOf("select ") + 7); p = Pattern.compile("(\\s+from\\s+)"); m = p.matcher(fieldStr); if (m.find()) { fieldStr = fieldStr.substring(0, m.start()).trim(); } String sFieldStr = fieldStr + ","; String result = ""; while (sFieldStr.indexOf(",") >= 0) { // ��ı������� String sOtherTableName = ""; // �滻*���ֶα��� String sOtherFieldStr = ""; String sTempField = sFieldStr.substring(0, sFieldStr.indexOf(",")).trim(); if(sTempField.indexOf ("*/") != -1 && sTempField.indexOf ("/*") != -1){ sTempField = sTempField.substring (sTempField.indexOf ("*/")+2); } if(sTempField.trim().startsWith("distinct") || sTempField.trim().startsWith("DISTINCT") || sTempField.trim().startsWith("Distinct")){ sTempField = sTempField.trim().substring(8); } // ����Ǵ��������ֶΣ�����ȥ������ if (sTempField.indexOf("(") >= 0) { if (sTempField.toLowerCase().indexOf(" as ") < 0) { sFieldStr = sFieldStr.substring(sFieldStr.indexOf(",") + 1).trim(); do { if (sFieldStr.indexOf(",") >= 0) { sTempField = sFieldStr.substring(0, sFieldStr.indexOf(",")).trim(); if (sTempField.toLowerCase().indexOf(" as ") >= 0) { break; } else { sFieldStr = sFieldStr.substring(sFieldStr.indexOf(",") + 1).trim(); } } else { break; } } while (true); } } // �п�����ȥ������ǰ�벿���Ժ����µ��ֶΣ���ʱӦ��AS���� if (sTempField.toLowerCase().indexOf(" as ") >= 0) { sTempField = sTempField.substring(sTempField.toLowerCase().indexOf(" as ") + 4); } // ����Ǵ��������ֶΣ�����ȥ������ if (sTempField.indexOf(".") >= 0) { // ȡ���� sOtherTableName = sTempField.substring(0, sTempField.indexOf(".")); sTempField = sTempField.substring(sTempField.toLowerCase().indexOf(".") + 1); } // ���ȡ�õ��ֶ��д�*�ţ�������Ҫ�ӱ���ȡ�ֶ� if (sTempField.trim().endsWith("*")&& sTempField.indexOf("/*") < 0) { if(token.getParameters().length<2 || StringUtils.isBlank(sTableName) ){ throw new RuntimeException("�������ĵڶ�������[����]!"); } if (!sTableName.equals("")) { if (!sTableName.substring(1).equals(",")) { sTableName = sTableName + ","; } if (sTableName.indexOf(",") >= 0) { String sTempTableName = sTableName.substring(0, sTableName.indexOf(",")); if (!sTempTableName.equals("")) { // �����ֶ�׷�ӵ��α��ֶ��б��� IARESProject project = (IARESProject) context.get(IAtomEngineContextConstantMySQL.Aresproject); List<TableColumn> fields = TableResourceUtil.getFieldsWithoutFlag("H",sTempTableName,project); for (int index = 0; index < fields.size(); index++) { TableColumn field = fields.get(index); if (sOtherTableName.equals("")) { if (index == fields.size() - 1) { sOtherFieldStr = sOtherFieldStr + field.getFieldName(); } else { sOtherFieldStr = sOtherFieldStr + field.getFieldName() + ","; } } else { if (index == fields.size() - 1) { sOtherFieldStr = sOtherFieldStr + sOtherTableName + "." + field.getFieldName(); } else { sOtherFieldStr = sOtherFieldStr + sOtherTableName + "." + field.getFieldName() + ","; } } } //��ͼ��������ٴ��� } if (result.equals("")) { result += sOtherFieldStr; } else { result += "," + sOtherFieldStr; } sTableName = sTableName.substring(sTableName.length() - sTableName.indexOf(",")); } } } else { if (sOtherTableName.equals("")) { if (result.equals("")) { result += sTempField; } else { result += "," + sTempField; } } else { if (result.equals("")) { result += sOtherTableName + "." + sTempField; } else { result += "," + sOtherTableName + "." + sTempField; } } } if (sFieldStr.length() > sFieldStr.indexOf(",")) { sFieldStr = sFieldStr.substring(sFieldStr.indexOf(",") + 1); } else { sFieldStr = ""; } } return result; } /** * ���ر��ֶ� * @param sqlStr * @return */ private void getAllFieldsFromSqlStr(String sqlStr,Map<Object, Object> context) { ISkeletonAttributeHelper helper = (ISkeletonAttributeHelper)context.get(IAtomEngineContextConstantMySQL.SKELETON_ATTRIBUTE_HELPER); List<String> popVarList = (List<String>)context.get(IEngineContextConstant.PSEUDO_CODE_PARA_LIST); int selectIndex = sqlStr.toLowerCase().indexOf("select"); int fromIndex = sqlStr.toLowerCase().indexOf("from"); if (selectIndex >= 0 && fromIndex >= 0) { sqlStr = sqlStr.substring(selectIndex + 6, fromIndex).trim();// ѡȡselect��from֮������� } String[] tfields = sqlStr.split(","); //List<String> fields = new ArrayList<String>(); for (int i = 0; i < tfields.length; i++) { // ȥ��as int asIndex = tfields[i].indexOf(" as "); if (asIndex >= 0) { String name = tfields[i].substring(asIndex + 4).trim(); queryFieldList.add(name); popVarList.add(name); } else { int dotIndex = tfields[i].indexOf("."); if (dotIndex >= 0) { String name = tfields[i].substring(dotIndex + 1).trim(); queryFieldList.add(name); popVarList.add(name); } else { String name = tfields[i].trim(); queryFieldList.add(name); popVarList.add(name); } } } } //����滻�������SQL��� private String getSqlStrReplaceComm(IMacroToken token) throws MacroParameterErrorException{ String str = token.getParameters()[0]; if(str.indexOf("insert into") >= 0){ throw new MacroParameterErrorException("[PRO*C��������]",str,"����ʹ��INSERT��"); }else if(str.indexOf("update ") >= 0){ throw new MacroParameterErrorException("[PRO*C��������]",str,"����ʹ��UPDATE��"); } //str = EngineUtil.replaceConstant(str, this.getFunction(), true);ȥ���dz����߻�����ֲ str = str.replaceAll("\\-\\-[^\n]*\n", "\n"); return str; } /** * ����SQL����е�@���������뵽set�б��� * @param procVarList */ private void splitFieldList(IMacroToken token,Map<Object, Object> context){ ISkeletonAttributeHelper helper = (ISkeletonAttributeHelper)context.get(IAtomEngineContextConstantMySQL.SKELETON_ATTRIBUTE_HELPER); List<String> popVarList = (List<String>)context.get(IEngineContextConstant.PSEUDO_CODE_PARA_LIST); String sql = token.getParameters()[0]; Pattern p = Pattern.compile("@[\\w\\d_]+"); Matcher m = p.matcher(sql); while (m.find()) { int index = m.group().indexOf("@"); String field = m.group().substring(index + 1); inFieldList.add(field);//�����ж��ٸ�@�ͼӶ��ٸ����ظ����ȥ�� //�����滻�б�ע�����ﲻ����helper.addAttribute(IAtomEngineContextConstant.PSEUDO_CODE_PARA_LIST, field); popVarList.add(field);//�ѱ����ӵ�porc�����б��Լ�α��������б��� } } }