/**
* <p>Copyright: Copyright (c) 2013</p>
* <p>Company: �������ӹɷ�����˾</p>
*/
package com.hundsun.ares.studio.atom.compiler.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.Stack;
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.compiler.constant.IAtomEngineContextConstant;
import com.hundsun.ares.studio.atom.compiler.exception.MacroParameterErrorException;
import com.hundsun.ares.studio.atom.compiler.exception.TableNotFoundException;
import com.hundsun.ares.studio.atom.compiler.macro.MacroConstant;
import com.hundsun.ares.studio.atom.compiler.macro.TokenDomain;
import com.hundsun.ares.studio.atom.compiler.skeleton.util.TableResourceUtil;
import com.hundsun.ares.studio.atom.compiler.token.PROCResultSetStatementToken;
import com.hundsun.ares.studio.core.IARESProject;
import com.hundsun.ares.studio.engin.constant.IEngineContextConstant;
import com.hundsun.ares.studio.engin.macrohandler.IMacroTokenHandler;
import com.hundsun.ares.studio.engin.skeleton.ISkeletonAttributeHelper;
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.macro.IMacroToken;
import com.hundsun.ares.studio.jres.model.database.TableColumn;
/**
* @author zhuyf
*
*/
public class PROCResultSetStatementMacroHandler implements IMacroTokenHandler {
/*
* (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]
*/
ISkeletonAttributeHelper helper = (ISkeletonAttributeHelper) context
.get(IAtomEngineContextConstant.SKELETON_ATTRIBUTE_HELPER);
addMacroNameToMacroList(token, context);// �Ѻ����ӵ������ݿ��б��Լ�proc�б���
Set<String> cursorList = helper
.getAttribute(IAtomEngineContextConstant.ATTR_CURSOR_LIST);
AtomFunction func = (AtomFunction) context
.get(IAtomEngineContextConstant.ResourceModel);
int cursorTotalSizeAdd1 = cursorList.size() + 1;
String cursorID = func.getObjectId() + cursorTotalSizeAdd1;
helper.addAttribute(IAtomEngineContextConstant.ATTR_CURSOR_LIST,
cursorID);
String sql = "";
List<ICodeToken> codeList = new ArrayList<ICodeToken>();
String[] sqlFields = {};
if (token.getParameters().length == 3) {// ����û��г����ֶ�
sql = token.getParameters()[0];
String[] tempSqlFields = StringUtils.split(token.getParameters()[2], ",");
sqlFields = new String[tempSqlFields.length];
for (int i = 0; i < tempSqlFields.length; i++) {
sqlFields[i] = StringUtils.trim(tempSqlFields[i]);
}
} else {// û���г��ֶ������sql���,��sql����л���ֶ�
sql = this.getSqlStatement(token, context);
sqlFields = getAllFieldsFromSqlStr(getFieldString(token, context));// sql����е��ֶ�
}
addVarList(token, context, sqlFields);// �ѱ����ӵ�porc�����б��Լ�α��������б���
addDomain(token, context, sqlFields);// �����
String cursorName = getCursorName(context);
codeList.add(new
PROCResultSetStatementToken(token,cursorName,sql));//���codeToken
return codeList.iterator();
}
/**
* �ѱ�����ӵ�proc�б���ȥ
*
* @param procVarList
*/
private void addVarList(IMacroToken token, Map<Object, Object> context,
String[] sqlField) {
List<String> popVarList = (List<String>) context
.get(IEngineContextConstant.PSEUDO_CODE_PARA_LIST);
ISkeletonAttributeHelper helper = (ISkeletonAttributeHelper) context
.get(IAtomEngineContextConstant.SKELETON_ATTRIBUTE_HELPER);
Pattern p = Pattern.compile("@[\\w\\d_]+");
// sql����ڵ�һ������
Matcher m = p.matcher(token.getParameters()[0]);
while (m.find()) {
String fieldName = m.group().substring(1);
// ���뵽proc�����б��У�����proc����������proc����������
helper.addAttribute(
IAtomEngineContextConstant.ATTR_PROC_VARIABLE_LIST,
fieldName);
// �����滻�б�ע�����ﲻ����helper.addAttribute(IAtomEngineContextConstant.PSEUDO_CODE_PARA_LIST,
// field);
popVarList.add(fieldName);
}
for (String field : sqlField) {
// ���뵽proc�α�����б��У�����proc�α����������proc����������
helper.addAttribute(
IAtomEngineContextConstant.ATTR_CURSOR_PROC_VARIABLE_LIST,
field);// ע�����ﲻ��Ҫ��_cur���������ʱ����Ҫ�õ�ԭ�������Ա���ԭ�����ڱ�������ʱ���ż�_cur
// �����滻�б�ע�����ﲻ����helper.addAttribute(IAtomEngineContextConstant.PSEUDO_CODE_PARA_LIST,
// field);
// ��������_cur
popVarList.add(field + "_cur");
}
}
/**
* �����
*/
private void addDomain(IMacroToken token, Map<Object, Object> context,
String[] sqlFields) {
IDomainHandler handler = (IDomainHandler) context
.get(IEngineContextConstant.DOMAIN_HANDLER);
String key = getKey();
Object[] args = new Object[2];
args[0] = getCursorName(context);// ������cursor[�����]+[���]�����
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(IAtomEngineContextConstant.SKELETON_ATTRIBUTE_HELPER);
helper.addAttribute(IAtomEngineContextConstant.ATTR_DATABASE_MACRO,
token.getKeyword());// ��ӵ����ݿ��б���
helper.addAttribute(IAtomEngineContextConstant.ATTR_PROC_MACRO,
token.getKeyword());// ��ӵ�proc���б���
}
/**
*���sql���
*/
private String getSqlStatement(IMacroToken token,Map<Object, Object> context) throws TableNotFoundException,MacroParameterErrorException {
String sqlStr = getSqlStrReplaceComm(token);
String sTableName = "";
Stack<String> addHead = new Stack<String>();
if (token.getParameters().length >= 2) {
sTableName = token.getParameters()[1];
}
// ȥ��Ƕ��select
Pattern p = Pattern.compile("\\s*select\\s+\\*\\s+from\\s*\\(");
Matcher m = p.matcher(sqlStr);
while (m.find()) {
if (m.start() == 0) {
addHead.add(sqlStr.substring(0, m.end()));
sqlStr = sqlStr.substring(m.end());
m = p.matcher(sqlStr);
}
}
// ȡ��select��from�м�ı�������
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 + ",";
// ����ij������
int k = 0;
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.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 (!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(IAtomEngineContextConstant.Aresproject);
List<TableColumn> fields = TableResourceUtil
.getFieldsWithoutFlag("H", sTempTableName,
project);
if (fields.size() == 0) {
if ("1" == null) {
// ��ͼ��������ٴ���Ļ�ͨ����ͼ���fields
} else {
String errorInfo = "";
for (int index = 0; index < fields.size(); index++) {
TableColumn field = fields.get(index);
if (sOtherTableName.equals("")) {
if (index == fields.size() - 1) {
sOtherFieldStr = sOtherFieldStr
+ field.getName();
} else {
sOtherFieldStr = sOtherFieldStr
+ field.getName() + ",";
}
} else {
if (index == fields.size() - 1) {
sOtherFieldStr = sOtherFieldStr
+ sOtherTableName + "."
+ field.getName();
} else {
sOtherFieldStr = sOtherFieldStr
+ sOtherTableName + "."
+ field.getName() + ",";
}
}
k++;
// ÿ4���ֶλ���
if (k % 4 == 0)
sOtherFieldStr += "\n";
}
}
} else {
// �����ֶ��ӵ��α��ֶ��б���
for (int index = 0; index < fields.size(); index++) {
TableColumn field = fields.get(index);
if (sOtherTableName.equals("")) {
if (index == fields.size() - 1) {
sOtherFieldStr = sOtherFieldStr
+ field.getName();
} else {
sOtherFieldStr = sOtherFieldStr
+ field.getName() + ",";
}
} else {
if (index == fields.size() - 1) {
sOtherFieldStr = sOtherFieldStr
+ sOtherTableName + "."
+ field.getName();
} else {
sOtherFieldStr = sOtherFieldStr
+ sOtherTableName + "."
+ field.getName() + ",";
}
}
k++;
// ÿ4���ֶλ���
if (k % 4 == 0)
sOtherFieldStr += "\n";
}
}
}
// �滻.*
if (!sOtherFieldStr.equals("")) {
if (sOtherTableName.equals("")) {
sqlStr = sqlStr.replace("*", sOtherFieldStr);
} else {
sqlStr = sqlStr.replace(sOtherTableName + ".*",
sOtherFieldStr);
}
}
sTableName = sTableName.substring(sTableName.length()
- sTableName.indexOf(","));
}
}
}
if (sFieldStr.length() > sFieldStr.indexOf(",")) {
sFieldStr = sFieldStr.substring(sFieldStr.indexOf(",") + 1);
} else {
sFieldStr = "";
}
k++;
// ÿ4���ֶλ���
if (k % 4 == 0)
sFieldStr += "\n";
}
while (addHead.size() > 0) {
sqlStr = addHead.pop().replace("*",
removeOtherName(getFieldString(token, context)))
+ sqlStr;
}
// ��where��䣬ÿһ��and��һ��
sqlStr = sqlStr.replaceAll(" and ", "\n and ");
sqlStr = sqlStr.replaceAll(" order by ", "\n order by ");
return sqlStr;
}
/**
* ����[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];
}
//�����Ƕ��select * from(����ȥ��
Pattern p = Pattern.compile("\\s*(select|SELECT)\\s+\\*\\s+(from|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|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(IAtomEngineContextConstant.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;
}
// ȥ������ǰ�ı����
public String removeOtherName(String str) {
String result = "";
List<String> para = new ArrayList<String>();
str = str + ",";
int k = 0;
while (str.indexOf(",") != -1) {
String sTempField = str.substring(0, str.indexOf(",")).trim();
str = str.substring(str.indexOf(",") + 1).trim();
para.add(sTempField);
}
for (int i = 0; i < para.size(); i++) {
if (para.get(i).indexOf(".") != -1) {
result = result
+ para.get(i).substring(para.get(i).indexOf(".") + 1)
.trim();
} else {
result = result + para.get(i).trim();
}
if (i != para.size() - 1)
result = result + ",";
if (i % 4 == 0)
result += "\n";
}
return result;
}
/**
* ���ر��ֶ�
*
* @param sqlStr
* @return
*/
private String[] getAllFieldsFromSqlStr(String sqlStr) {
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();
fields.add(name);
} else {
int dotIndex = tfields[i].indexOf(".");
if (dotIndex >= 0) {
String name = tfields[i].substring(dotIndex + 1).trim();
fields.add(name);
} else {
String name = tfields[i].trim();
fields.add(name);
}
}
}
return fields.toArray(new String[fields.size()]);
}
// ����滻�������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;
}
/**
* ����α��ֶδ�
*
* @return
*/
private String getCursorName(Map<Object, Object> context) {
ISkeletonAttributeHelper helper = (ISkeletonAttributeHelper) context
.get(IAtomEngineContextConstant.SKELETON_ATTRIBUTE_HELPER);
Set<String> cursorList = helper
.getAttribute(IAtomEngineContextConstant.ATTR_CURSOR_LIST);
if (cursorList.size() > 0) {
return "cursor"
+ (cursorList.toArray(new String[cursorList.size()]))[cursorList
.size() - 1];// LinkHashSet�ṹ�����µ������
}
return "cursor";
}
}