package com.smtaiserver.smtaiserver.javaai.querydetail; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.tree.DefaultText; import org.springframework.web.servlet.ModelAndView; import com.smtaiserver.smtaiserver.core.SMTAIServerRequest; import com.smtaiserver.smtaiserver.database.SMTDatabase; import com.smtaiserver.smtaiserver.database.SMTDatabase.DBRecord; import com.smtaiserver.smtaiserver.database.SMTDatabase.DBRecords; import com.smtaiserver.smtaiserver.javaai.SMTJavaAIError; import com.smtaiserver.smtaiserver.javaai.ast.ASTDBMap; import com.smtservlet.util.Json; import com.smtservlet.util.SMTJsonWriter; import com.smtservlet.util.SMTStatic; public class SMTAIQueryDetailSqlXml extends SMTAIQueryDetail { private static class SQLXMLExecArg { public StringBuilder _sbSQL = new StringBuilder(); public List _sqlParams = new ArrayList<>(); public SMTJsonWriter _jsonWr; //public SMTAIServerRequest _tranReq; public Json _jsonParams; public ASTDBMap _dbMap; public SQLXMLExecArg(SMTAIServerRequest tranReq, ASTDBMap dbMap, Json jsonParams) throws Exception { _dbMap = dbMap; //_tranReq = tranReq; _jsonParams = jsonParams; _jsonWr = tranReq.newReturnJsonWriter(true, null, null); } public String getSqlArg(String key) { Json jsonValue = _jsonParams.safeGetJson(key); if(jsonValue == null) return null; return jsonValue.asString(); } } /////////////////////////////////////////////////////////////////////////////////////// private static class SQLXMLNodeSQL_TIME_VALUE extends SQLXMLNode { private String _dsId; private List _listChildren = new ArrayList<>(); public SQLXMLNodeSQL_TIME_VALUE(Element xmlRoot) throws Exception { _dsId = SMTStatic.getXmlAttr(xmlRoot, "ds_id"); for (Iterator iterInner = xmlRoot.nodeIterator(); iterInner.hasNext();) { Node nodeInner = iterInner.next(); if(nodeInner.getNodeType() == Node.TEXT_NODE) { String text = ((DefaultText)nodeInner).getText(); int lastPos = _listChildren.size() - 1; if(lastPos >= 0 && _listChildren.get(lastPos) instanceof String) { _listChildren.set(lastPos, (String)_listChildren.get(lastPos) + text); } else { _listChildren.add(text); } } else { _listChildren.add(createSQLXMLNode((Element)nodeInner)); } } } @Override public SMTJavaAIError execute(SQLXMLExecArg execArg) throws Exception { for(Object oxmlNode : _listChildren) { if(oxmlNode instanceof String) { execArg._sbSQL.append(oxmlNode); } else if(oxmlNode instanceof SQLXMLNode) { SMTJavaAIError error = ((SQLXMLNode)oxmlNode).execute(execArg); if(error != null) return error; } } SMTDatabase db = execArg._dbMap.getDatabase(_dsId); DBRecords recs = db.querySQL(execArg._sbSQL.toString(), execArg._sqlParams.toArray(new Object[execArg._sqlParams.size()])); execArg._jsonWr.beginArray("values"); { for(DBRecord rec : recs.getRecords()) { execArg._jsonWr.beginArray(null); { execArg._jsonWr.addKeyValue(null, rec.getString("otime")); execArg._jsonWr.addKeyValue(null, rec.getString("ovalue")); } execArg._jsonWr.endArray(); } } execArg._jsonWr.endArray(); return null; } } /////////////////////////////////////////////////////////////////////////////////////// private static class SQLXMLNodePARAM extends SQLXMLNode { private String _key; public SQLXMLNodePARAM(Element xmlRoot) throws Exception { _key = SMTStatic.getXmlAttr(xmlRoot, "key"); } @Override public SMTJavaAIError execute(SQLXMLExecArg execArg) throws Exception { String value = execArg.getSqlArg(_key); if(value == null) throw new Exception("请输入参数:" + _key); execArg._sbSQL.append("?"); execArg._sqlParams.add(value); return null; } } /////////////////////////////////////////////////////////////////////////////////////// private static class SQLXMLNodePARAM_TIME_S extends SQLXMLNode { private String _key; public SQLXMLNodePARAM_TIME_S(Element xmlRoot) throws Exception { _key = SMTStatic.getXmlAttr(xmlRoot, "key"); } @Override public SMTJavaAIError execute(SQLXMLExecArg execArg) throws Exception { String value = execArg.getSqlArg(_key); if(value == null) { value = SMTStatic.toString(SMTStatic.calculateTime(new Date(), SMTStatic.SMTCalcTime.ZERO_TIME, 0)); } execArg._sbSQL.append("?"); execArg._sqlParams.add(value); return null; } } /////////////////////////////////////////////////////////////////////////////////////// private static class SQLXMLNodePARAM_TIME_E extends SQLXMLNode { private String _key; public SQLXMLNodePARAM_TIME_E(Element xmlRoot) throws Exception { _key = SMTStatic.getXmlAttr(xmlRoot, "key"); } @Override public SMTJavaAIError execute(SQLXMLExecArg execArg) throws Exception { String value = execArg.getSqlArg(_key); if(value == null) { value = SMTStatic.toString(SMTStatic.calculateTime(new Date(), SMTStatic.SMTCalcTime.ZERO_TIME, 0, SMTStatic.SMTCalcTime.ADD_DATE, 1)); } execArg._sbSQL.append("?"); execArg._sqlParams.add(value); return null; } } /////////////////////////////////////////////////////////////////////////////////////// private static abstract class SQLXMLNode { public abstract SMTJavaAIError execute(SQLXMLExecArg execArg) throws Exception; } private static SQLXMLNode createSQLXMLNode(Element xmlRoot) throws Exception { String name = xmlRoot.getName().toUpperCase(); if("SQL_TIME_VALUE".equals(name)) return new SQLXMLNodeSQL_TIME_VALUE(xmlRoot); else if("PARAM".equals(name)) return new SQLXMLNodePARAM(xmlRoot); else if("PARAM_TIME_S".equals(name)) return new SQLXMLNodePARAM_TIME_S(xmlRoot); else if("PARAM_TIME_E".equals(name)) return new SQLXMLNodePARAM_TIME_E(xmlRoot); else throw new Exception("unknow SQLXML : " + name); } private SQLXMLNode _sqlXmlRoot; //////////////////////////////////////////////////////////// public void initInstance(DBRecord rec) throws Exception { super.initInstance(rec); Document doc = SMTStatic.convStrToXmlDoc("" + rec.getString("sqlxml_config") + ""); Element xmlSQL = (Element) doc.selectSingleNode("ROOT/SQL_TIME_VALUE"); if(xmlSQL != null) _sqlXmlRoot = createSQLXMLNode(xmlSQL); else throw new Exception("can' find ROOT/SQL"); } @Override public ModelAndView executeQuery(SMTAIServerRequest tranReq, Json jsonParams) throws Exception { ASTDBMap dbMap = new ASTDBMap(); try { SQLXMLExecArg execArg = new SQLXMLExecArg(tranReq, dbMap, jsonParams); _sqlXmlRoot.execute(execArg); return tranReq.returnJson(execArg._jsonWr); } finally { dbMap.close(); } } }