package com.hundsun.ares.studio.atom.compiler.mysql.token;
import java.util.HashMap;
import java.util.HashSet;
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.compiler.mysql.constant.IAtomEngineContextConstantMySQL;
import com.hundsun.ares.studio.atom.compiler.mysql.skeleton.util.AtomFunctionCompilerUtil;
import com.hundsun.ares.studio.biz.Parameter;
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.parser.PseudoCodeParser;
import com.hundsun.ares.studio.engin.token.ICodeToken;
import com.hundsun.ares.studio.engin.token.macro.IMacroToken;
import com.hundsun.ares.studio.engin.util.TypeRule;
import com.hundsun.ares.studio.jres.model.metadata.StandardDataType;
import com.hundsun.ares.studio.jres.model.metadata.TypeDefaultValue;
import com.hundsun.ares.studio.jres.model.metadata.util.MetadataServiceProvider;
import com.hundsun.ares.studio.procdure.Procedure;
public class ProcedureCallStaticToken implements ICodeToken {
Procedure procedure;
IMacroToken token;
String rsID;
String stateID;
public ProcedureCallStaticToken(Procedure procedure, IMacroToken token, String rsID, String stateID) {
this.procedure = procedure;
this.token = token;
this.rsID = rsID;
this.stateID = stateID;
}
@Override
public String getContent() {
return null;
}
@Override
public int getType() {
return 0;
}
@Override
public String genCode(Map<Object, Object> context) throws Exception {
StringBuffer buffer = new StringBuffer();
StringBuffer registersetsetBuffer = new StringBuffer();
StringBuffer getBuffer = new StringBuffer();
String proName = procedure.getName();
String[] params = token.getParameters();
Map<String, String> values = new HashMap<String, String>();
if(params.length>0){
values.putAll(PseudoCodeParser.parserKeyValueWithAt(params[0]));
}
int index = 1;
Map<String,Integer> out_indexs = new HashMap<String,Integer>();
Map<String,Integer> in_indexs = new HashMap<String,Integer>();
//�ȴ��������������洢���̶��屣��һ��
for(Parameter param: procedure.getInputParameters()){
if(!in_indexs.containsKey(param.getId())){
if(!out_indexs.containsKey(param.getId())){//������ţ���Ҫ���ã������Ѿ��ж��Ƿ��ظ������Խ�������϶������ظ�
String flag = param.getFlags();
//IO��־���������
if(StringUtils.isNotBlank(flag) && StringUtils.indexOf(flag, "IO") >= 0){
getBuffer.append(getInitCode(param,context,stateID,index));
registersetsetBuffer.append(getOutParameterRegisterCode(param,context,stateID,index));
}
in_indexs.put(param.getId(), index);//��¼��ţ�������ʱ���ò��ϣ���������ظ���飬���ֿ�������
registersetsetBuffer.append(getSetValueString(param, values, context, index));
index++;
}else{//�����������
registersetsetBuffer.append(getSetValueString(param, values, context, out_indexs.get(param.getId())));
//������������Ѿ�ע�ᣬ�ʼ�ʹIO������Ҳ��������
}
}
}
registersetsetBuffer.append(ITokenConstant.NL);//����������������֮�䣬�ÿ��зָ�
//����������������ٴ����������
for(Parameter param : procedure.getOutputParameters()){
if(!out_indexs.containsKey(param.getId())){//���ظ����
out_indexs.put(param.getId(), index);//��¼��ţ��������ظ��ģ��踴�����
getBuffer.append(getInitCode(param,context,stateID,index));
registersetsetBuffer.append(getOutParameterRegisterCode(param,context,stateID,index));
String flag = param.getFlags();
//IO��־���������
if(StringUtils.isNotBlank(flag) && StringUtils.indexOf(flag, "IO")>=0){//IO�������
if(!in_indexs.containsKey(param.getId())){//���ظ����
in_indexs.put(param.getId(), index);//��¼��ţ�������ʱ���ò��ϣ���������ظ���飬���ֿ�������
registersetsetBuffer.append(getSetValueString(param, values, context, index));
}
}
index++;//��ż�1
}
}
if(procedure.isOutputCollection()){//�����
String resultSetBufffer = "";
if(token.getFlag().indexOf("M") < 0){
resultSetBufffer = String.format(RESULTSET, rsID,proName,stateID);
}else{
resultSetBufffer = String.format(RESULTSET_NOEND, rsID,proName,stateID);
}
buffer.append(COMMENT_BEGIN);
buffer.append(String.format(CALL_BODY, proName,getQuestionMarkBuffer(),registersetsetBuffer.toString() + resultSetBufffer,stateID));
}else{//�����ؽ����
String execBufffer = "";
if(token.getFlag().indexOf("M") < 0){
execBufffer = String.format(EXEC, stateID,getBuffer.toString(),proName);
}else{
execBufffer = String.format(EXEC_NOEND, stateID,getBuffer.toString(),proName);
}
buffer.append(COMMENT_BEGIN);
buffer.append(String.format(CALL_BODY, proName,getQuestionMarkBuffer(),registersetsetBuffer.toString() + execBufffer,stateID));
}
return buffer.toString();
}
private String getSetValueString(Parameter param,Map<String, String> values,Map<Object, Object> context,int index) throws Exception{
IARESProject project = (IARESProject) context.get(IAtomEngineContextConstantMySQL.Aresproject);
AtomFunction callRes = (AtomFunction) context.get(IAtomEngineContextConstantMySQL.ResourceModel);
List<String> list = (List<String>) context.get(IEngineContextConstant.PSEUDO_CODE_PARA_LIST);
String id = param.getId();
String type = getRealType(param, project,context);
String setType = getSetType(type);
if(values.containsKey(id)){
//��Ĭ��ֵ
String value = values.get(id);
return String.format(SET_VALUE,setType,index,getRealFieldName(value,type,project),this.stateID);
}else if(AtomFunctionCompilerUtil.isParameterINAtomFunctionParameterByName(callRes, param.getId(),project) ||
list.contains(id)){
//��������������ڲ������л���α������ʹ�õ��ı�������ֱ���ڱ�����ǰ����@
String value = "@" + id;
return String.format(SET_VALUE,setType,index,value,stateID);
}else{
//����ֱ��ȡĬ��ֵ
TypeDefaultValue typeDftValue = MetadataServiceProvider.getTypeDefaultValueOfStdFieldByName(project, id);
String dv = typeDftValue.getValue(MetadataServiceProvider.C_TYPE);
if(TypeRule.typeRuleCharArray(type))
{
dv = "\" \"";
}
return String.format(SET_VALUE,setType,index,AtomFunctionCompilerUtil.getTrueDefaultValueByType(type, dv,project),stateID);
}
}
//��ȡ��ȷ�IJ�������@occur_balance*-1����ȡ����Ӧ����@occur_balance����@��ͷ����ȡ��ʵĬ��ֵ
private String getRealFieldName(String fieldName, String type, IARESProject project) throws Exception{
Pattern p = Pattern.compile("@[\\w\\d_]+");
Matcher m = p.matcher(fieldName);
if(m.find()){
return m.group();
}
return AtomFunctionCompilerUtil.getTrueDefaultValueByType(type, fieldName, project);
}
//����type��ȡ��������ʵ����
private String getRealType(Parameter param,IARESProject project,Map<Object,Object> context){
return AtomFunctionCompilerUtil.getRealDataType(param.getId(), project,context);
}
private String getSetType(String type) throws Exception{
if (TypeRule.typeRuleCharArray(type)) {
return "setString";
} else if (TypeRule.typeRuleChar(type)) {
return "setChar";
} else if (TypeRule.typeRuleInt(type)) {
return "setInt";
} else if (TypeRule.typeRuleDouble(type)) {
return "setDouble";
} else {
throw new Exception("������������");
}
}
/**
*
* @return String ���̵��õIJ���?��
*/
private StringBuffer getQuestionMarkBuffer() {
StringBuffer questionBuffer = new StringBuffer();
int paramNum = procedure.getInputParameters().size();
Set<String> in_names = new HashSet<String>();
for (int i = 0; i < paramNum; i++) {
if(!in_names.contains(procedure.getInputParameters().get(i).getId())){
in_names.add(procedure.getInputParameters().get(i).getId());//������ظ���
if (i == 0) {
questionBuffer.append("?");
} else {
questionBuffer.append(",");
questionBuffer.append("?");
}
}
}
Set<String> out_names = new HashSet<String>();
for (int i = 0; i < procedure.getOutputParameters().size(); i++) {
if(!out_names.contains(procedure.getOutputParameters().get(i).getId())){
out_names.add(procedure.getOutputParameters().get(i).getId());//������ظ���
if(!in_names.contains(procedure.getOutputParameters().get(i).getId())){//��������Ѿ����
if (questionBuffer.toString().equals("")) {
questionBuffer.append("?");
} else {
questionBuffer.append(",");
questionBuffer.append("?");
}
}
}
}
return questionBuffer;
}
/**
* �����ؽ����������£��������������ֵ
* @param param ����������п�����IO�����룩
* @param context ������
* @param stateId ��̬���Id
* @return String һ����������ı�����ֵ���
*/
private String getInitCode(Parameter param,Map<Object,Object> context,String stateId,int index){
IARESProject project = (IARESProject)context.get(IAtomEngineContextConstantMySQL.Aresproject);
String dataType = AtomFunctionCompilerUtil.getRealDataType(param,project,context);
if(TypeRule.typeRuleCharArray(dataType)){//�ַ���
String len = TypeRule.getCharLength(dataType);
//����Ż�ȡֵ
return "hs_strncpy(@" + param.getId() + ",conversion((char *)lpSP" + stateId + "->getString(" + index + "))," + len + ");\r\n";
}else if(TypeRule.typeRuleChar(dataType)){//�ַ�
return "@" + param.getId() + " = lpSP" + stateId + "->getChar(" + index + ");\r\n";
}else if(TypeRule.typeRuleDouble(dataType)){//������
return "@" + param.getId() + " = lpSP" + stateId + "->getDouble(" + index + ");\r\n";
}else if(TypeRule.typeRuleInt(dataType)){//����
return "@" + param.getId() + " = lpSP" + stateId + "->getInt(" + index + ");\r\n";
}else{
return "";
}
}
/**
* �������ע��
* @param param ����������п�����IO�����룩
* @param context ������
* @param stateId ��̬���Id
* @return String һ�����������ע�����
*/
private String getOutParameterRegisterCode(Parameter param,Map<Object,Object> context,String stateId,int index){
IARESProject project = (IARESProject)context.get(IAtomEngineContextConstantMySQL.Aresproject);
String dataType = AtomFunctionCompilerUtil.getRealDataType(param,project,context);
if(TypeRule.typeRuleCharArray(dataType)){//�ַ���
String len = TypeRule.getCharLength(dataType);
return "lpSP" + stateId + "->registerOutParameter(" + index + ",HSQL_DATATYPE_STRING," + len + ");//" + param.getId() + "\r\n";
}else if(TypeRule.typeRuleChar(dataType)){//�ַ�
return "lpSP" + stateId + "->registerOutParameter(" + index + ",HSQL_DATATYPE_CHAR,0);//" + param.getId() + "\r\n";
}else if(TypeRule.typeRuleDouble(dataType)){//������
return "lpSP" + stateId + "->registerOutParameter(" + index + ",HSQL_DATATYPE_DOUBLE,0);//" + param.getId() + "\r\n";
}else if(TypeRule.typeRuleInt(dataType)){//����
return "lpSP" + stateId + "->registerOutParameter(" + index + ",HSQL_DATATYPE_INT,0);//" + param.getId() + "\r\n";
}else{
return "";
}
}
private static final String COMMENT_BEGIN = "//�洢������" + ITokenConstant.NL;
private static final String CALL_BODY = "lpSP%4$s = lpConn->createCallableStatement();"+ITokenConstant.NL
+"if (lpSP%4$s)" + ITokenConstant.NL
+"{" + ITokenConstant.NL
+"iReturnCode = lpSP%4$s->prepare(\"call %1$s(%2$s)\");" + ITokenConstant.NL
//+"lpSP%4$s->registerOutParameter(1,HSQL_DATATYPE_INT,0); //��1���ʺ��Ƿ���ֵ" + ITokenConstant.NL
+"%3$s" + ITokenConstant.NL
+"}" + ITokenConstant.NL
+"else" + ITokenConstant.NL
+"{" + ITokenConstant.NL
+"iReturnCode = 102;" + ITokenConstant.NL
+"@error_no = 102;" + ITokenConstant.NL
+"hs_strcpy(@error_info, \"ICallableStatement is NULL��\");" + ITokenConstant.NL
+"@error_id = 0;" + ITokenConstant.NL
+"goto svr_end;" + ITokenConstant.NL+ITokenConstant.NL+"}";
private static final String SET_VALUE = "lpSP%4$s->%1$s(%2$d,%3$s);" + ITokenConstant.NL;
private static final String RESULTSET = "lpResultSet%1$s = lpSP%3$s->open();" + ITokenConstant.NL
+"//�������" + ITokenConstant.NL
+"if (lpResultSet%1$s)" + ITokenConstant.NL
+"{" + ITokenConstant.NL
+"if (lpResultSet%1$s->GetColCount() == 5 && strcmp(lpResultSet%1$s->GetColName(0),\"error_no\") == 0 )" + ITokenConstant.NL
+"{" + ITokenConstant.NL
+"@error_no = lpResultSet%1$s->GetInt(\"error_no\");" + ITokenConstant.NL
+"@error_id = lpResultSet%1$s->GetInt(\"error_id\");" + ITokenConstant.NL
+"hs_strncpy(@error_sysinfo,lpResultSet%1$s->GetStr(\"error_sysinfo\"),500);" + ITokenConstant.NL
+"hs_strncpy(@error_info,lpResultSet%1$s->GetStr(\"error_info\"),500);" + ITokenConstant.NL
+"hs_strncpy(@error_pathinfo,lpResultSet%1$s->GetStr(\"error_pathinfo\"),500);" + ITokenConstant.NL
+"GetErrorInfo(lpContext, lpResultSet%1$s->GetInt(\"error_no\"), @error_info);" + ITokenConstant.NL
+"if ((lpResultSet%1$s->GetInt(\"error_no\") == 1) || (lpResultSet%1$s->GetInt(\"error_no\") == -1))" + ITokenConstant.NL
+"iReturnCode = 100;" + ITokenConstant.NL
+"else" + ITokenConstant.NL
+"iReturnCode = lpResultSet%1$s->GetInt(\"error_no\");" + ITokenConstant.NL
+"}" + ITokenConstant.NL
+"}" + ITokenConstant.NL
+"else" + ITokenConstant.NL
+"{" + ITokenConstant.NL
+"iReturnCode = 101;" + ITokenConstant.NL
+"@error_no = 101;" + ITokenConstant.NL
+"hs_strcpy(@error_info, \"Exec SP ERROR��%2$s\");" + ITokenConstant.NL
+"@error_id = 0;" + ITokenConstant.NL
+"goto svr_end;" + ITokenConstant.NL
+"}" + ITokenConstant.NL;
private static final String RESULTSET_NOEND = "lpResultSet%1$s = lpSP%3$s->open();" + ITokenConstant.NL
+"//�������" + ITokenConstant.NL
+"if (lpResultSet%1$s)" + ITokenConstant.NL
+"{" + ITokenConstant.NL
+"if (lpResultSet%1$s->GetColCount() == 5 && strcmp(lpResultSet%1$s->GetColName(0),\"error_no\") == 0 )" + ITokenConstant.NL
+"{" + ITokenConstant.NL
+"@error_no = lpResultSet%1$s->GetInt(\"error_no\");" + ITokenConstant.NL
+"@error_id = lpResultSet%1$s->GetInt(\"error_id\");" + ITokenConstant.NL
+"hs_strncpy(@error_sysinfo,lpResultSet%1$s->GetStr(\"error_sysinfo\"),500);" + ITokenConstant.NL
+"hs_strncpy(@error_info,lpResultSet%1$s->GetStr(\"error_info\"),500);" + ITokenConstant.NL
+"hs_strncpy(@error_pathinfo,lpResultSet%1$s->GetStr(\"error_pathinfo\"),500);" + ITokenConstant.NL
+"GetErrorInfo(lpContext, lpResultSet%1$s->GetInt(\"error_no\"), @error_info);" + ITokenConstant.NL
+"if ((lpResultSet%1$s->GetInt(\"error_no\") == 1) || (lpResultSet%1$s->GetInt(\"error_no\") == -1))" + ITokenConstant.NL
+"iReturnCode = 100;" + ITokenConstant.NL
+"else" + ITokenConstant.NL
+"iReturnCode = lpResultSet%1$s->GetInt(\"error_no\");" + ITokenConstant.NL
+"}" + ITokenConstant.NL
+"}" + ITokenConstant.NL
+"else" + ITokenConstant.NL
+"{" + ITokenConstant.NL
+"iReturnCode = 101;" + ITokenConstant.NL
+"@error_no = 101;" + ITokenConstant.NL
+"hs_strcpy(@error_info, \"Exec SP ERROR��%2$s\");" + ITokenConstant.NL
+"@error_id = 0;" + ITokenConstant.NL
+"}" + ITokenConstant.NL;
private static final String EXEC = "iReturnCode = lpSP%1$s->exec();\r\n" +
"if(!iReturnCode){\r\n" +
"%2$s\r\n" +
"}else\r\n" +
"{\r\n" +
"iReturnCode = 101;\r\n" +
"@error_no = 101;\r\n" +
"hs_strcpy(@error_info, \"Exec SP ERROR��%3$s\");\r\n" +
"@error_id = 0;\r\n" +
"goto svr_end;\r\n" +
"}\r\n";
private static final String EXEC_NOEND = "iReturnCode = lpSP%1$s->exec();\r\n" +
"if(!iReturnCode){\r\n" +
"%2$s\r\n" +
"}else\r\n" +
"{\r\n" +
"iReturnCode = 101;\r\n" +
"@error_no = 101;\r\n" +
"hs_strcpy(@error_info, \"Exec SP ERROR��%3$s\");\r\n" +
"@error_id = 0;\r\n" +
"}\r\n";
}