/* * Copyright (C) 2010---2014 星星(wuweixing)<349446658@qq.com> * * This file is part of Wabacus * * Wabacus is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.wabacus.system.dataset.update.action.rationaldb; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.List; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.wabacus.config.Config; import com.wabacus.config.component.application.report.ReportBean; import com.wabacus.config.database.type.AbsDatabaseType; import com.wabacus.config.database.type.Oracle; import com.wabacus.exception.WabacusRuntimeException; import com.wabacus.system.ReportRequest; import com.wabacus.system.assistant.WabacusAssistant; import com.wabacus.system.buttons.EditableReportSQLButtonDataBean; import com.wabacus.system.component.application.report.configbean.editablereport.AbsEditableReportEditDataBean; import com.wabacus.system.component.application.report.configbean.editablereport.EditableReportExternalValueBean; import com.wabacus.system.component.application.report.configbean.editablereport.EditableReportParamBean; import com.wabacus.system.dataset.update.action.AbsUpdateAction; import com.wabacus.system.datatype.BlobType; import com.wabacus.system.datatype.ClobType; import com.wabacus.util.Consts; import com.wabacus.util.Consts_Private; import com.wabacus.util.Tools; public abstract class AbsRationalDBUpdateAction extends AbsUpdateAction { private static Log log=LogFactory.getLog(AbsRationalDBUpdateAction.class); protected boolean isPreparedStatement; protected String datasource; protected boolean isOriginalParams; protected boolean isStandardSql; protected String sqlsp;//更新数据的SQL语句或存储过程 protected String returnValueParamname;//用于保存此SQL语句或存储过程返回值的变量名,可以是定义在<params/>的变量的name属性或rrequset的key public AbsRationalDBUpdateAction(AbsEditableReportEditDataBean ownerUpdateBean) { super(ownerUpdateBean); } public void setPreparedStatement(boolean isPreparedStatement) { this.isPreparedStatement=isPreparedStatement; } public void setDatasource(String datasource) { this.datasource=datasource; } public void setOriginalParams(boolean isOriginalParams) { this.isOriginalParams=isOriginalParams; } public void setSqlsp(String sqlsp) { this.sqlsp=sqlsp; } public String getSqlsp() { return sqlsp; } public String getReturnValueParamname() { return returnValueParamname; } public void setReturnValueParamname(String returnValueParamname) { this.returnValueParamname=returnValueParamname; } public void beginTransaction(ReportRequest rrequest) { Connection conn=rrequest.getConnection(this.datasource); String dsLevel=rrequest.getTransactionLevel(this.datasource); if(dsLevel!=null&&!dsLevel.trim().equals("")) { if(!Consts_Private.M_ALL_TRANSACTION_LEVELS.containsKey(dsLevel)) { throw new WabacusRuntimeException("为页面"+rrequest.getPagebean().getId()+"的数据源"+this.datasource+"设置事务隔离级别:"+dsLevel+"不合法,不支持这个事务隔离级别"); } if(dsLevel.equals(Consts.TRANS_NONE)) return; } try { if(!conn.getAutoCommit()) return; conn.setAutoCommit(false); if(!Tools.isEmpty(dsLevel)) conn.setTransactionIsolation(Consts_Private.M_ALL_TRANSACTION_LEVELS.get(dsLevel)); }catch(SQLException e) { throw new WabacusRuntimeException("启动报表"+this.ownerUpdateBean.getOwner().getReportBean().getPath()+"的数据源"+this.datasource+"事件失败",e); } } public void commitTransaction(ReportRequest rrequest) { Connection conn=rrequest.getConnection(this.datasource); try { if(conn.getAutoCommit()) return; conn.commit(); conn.setAutoCommit(true); }catch(SQLException e) { throw new WabacusRuntimeException("提交报表"+this.ownerUpdateBean.getOwner().getReportBean().getPath()+"的数据源"+this.datasource+"事件失败",e); } } public void rollbackTransaction(ReportRequest rrequest) { Connection conn=rrequest.getConnection(this.datasource); try { if(conn.getAutoCommit()) return; conn.rollback(); conn.setAutoCommit(true); }catch(SQLException e) { throw new WabacusRuntimeException("回滚报表"+this.ownerUpdateBean.getOwner().getReportBean().getPath()+"的数据源"+this.datasource+"事件失败",e); } } public String getExecuteSql(ReportRequest rrequest,Map<String,String> mRowData,Map<String,String> mParamValues) { String dynamicsql=getDynExecuteSql(rrequest,null); if(!Tools.isEmpty(dynamicsql)) return dynamicsql; if(this.isPreparedStatement) return this.sqlsp;//如果是preparedstatement方式执行,则直接返回带?的SQL语句 dynamicsql=getStatementExecuteSql(rrequest, mRowData,mParamValues); setExecuteSql(rrequest,dynamicsql); return dynamicsql; } protected String getDynExecuteSql(ReportRequest rrequest,String defaultsql) { String dynamicsql=(String)rrequest.getAttribute(this.ownerUpdateBean.getOwner().getReportBean().getId(),getExecuteSqlKey(rrequest)); return Tools.isEmpty(dynamicsql)?defaultsql:dynamicsql; } public void setExecuteSql(ReportRequest rrequest,String sql) { rrequest.setAttribute(this.ownerUpdateBean.getOwner().getReportBean().getId(),getExecuteSqlKey(rrequest),sql); } private String getExecuteSqlKey(ReportRequest rrequest) { String reportid=this.ownerUpdateBean.getOwner().getReportBean().getId(); String updateRowIdx=(String)rrequest.getAttribute(reportid,"update_datarow_index"); if(updateRowIdx==null) updateRowIdx=""; return "dynamicalsql_"+updateRowIdx+"_"+this.objectId; } public void updateData(ReportRequest rrequest,Map<String,String> mRowData,Map<String,String> mParamValues) throws SQLException { String realsql=getExecuteSql(rrequest,mRowData,mParamValues); if(Config.show_sql) log.info("Execute sql:"+realsql); Connection conn=rrequest.getConnection(this.datasource); Statement stmt=null; try { int rtnVal; if(this.isPreparedStatement) { stmt=conn.prepareStatement(realsql); rtnVal=updateDataByPreparedstatement(rrequest,mRowData,mParamValues,(PreparedStatement)stmt,realsql); }else { stmt=conn.createStatement(); rtnVal=stmt.executeUpdate(realsql); } storeReturnValue(rrequest,mParamValues,String.valueOf(rtnVal)); }finally { WabacusAssistant.getInstance().release(null,stmt); } } private String getStatementExecuteSql(ReportRequest rrequest,Map<String,String> mRowData,Map<String,String> mParamValues) { ReportBean rbean=this.ownerUpdateBean.getOwner().getReportBean(); String realsql=this.sqlsp; if(lstParamBeans!=null&&lstParamBeans.size()>0) { AbsDatabaseType dbtype=rrequest.getDbType(this.datasource); String paramValueTmp; for(EditableReportParamBean paramBean:lstParamBeans) { paramValueTmp=paramBean.getRuntimeParamValue(rrequest,rbean,mRowData,mParamValues,this.datasource,ownerUpdateBean.isAutoReportdata()); if(this.isOriginalParams&&this.isStandardSql) { if(paramValueTmp==null) paramValueTmp=""; }else { paramValueTmp=dbtype.getStatementValue(paramBean.getDataTypeObj(),paramValueTmp); if(paramValueTmp==null) paramValueTmp="null"; } realsql=Tools.replaceAll(realsql,paramBean.getPlaceholder(),paramValueTmp); } } return realsql; } private int updateDataByPreparedstatement(ReportRequest rrequest,Map<String,String> mRowData,Map<String,String> mParamValues,PreparedStatement pstmt,String sql) throws SQLException { AbsDatabaseType dbtype=rrequest.getDbType(this.datasource); Oracle oracleType=null; ReportBean rbean=this.ownerUpdateBean.getOwner().getReportBean(); int rtnVal=1; if(sql.trim().toLowerCase().startsWith("select ")&&(dbtype instanceof Oracle)) {//当前在执行更新大字段的SQL语句 oracleType=(Oracle)dbtype; if(lstParamBeans!=null&&lstParamBeans.size()>0) { int colidx=1; for(EditableReportParamBean paramBean:lstParamBeans) { if((paramBean.getDataTypeObj() instanceof ClobType)||(paramBean.getDataTypeObj() instanceof BlobType)) continue; paramBean.getDataTypeObj().setPreparedStatementValue(colidx++, paramBean.getRuntimeParamValue(rrequest,rbean,mRowData,mParamValues,this.datasource,ownerUpdateBean.isAutoReportdata()), pstmt,dbtype); } } ResultSet rs=pstmt.executeQuery(); while(rs.next()) { if(lstParamBeans!=null&&lstParamBeans.size()>0) { int colidx=1; for(EditableReportParamBean paramBean:lstParamBeans) { if(!(paramBean.getDataTypeObj() instanceof ClobType)&&!(paramBean.getDataTypeObj() instanceof BlobType)) continue; String paramvalue=paramBean.getRuntimeParamValue(rrequest,rbean,mRowData,mParamValues,this.datasource,ownerUpdateBean .isAutoReportdata()); if(paramBean.getDataTypeObj() instanceof ClobType) { oracleType.setClobValueInSelectMode(paramvalue,(oracle.sql.CLOB)rs.getClob(colidx++)); }else { oracleType.setBlobValueInSelectMode(paramBean.getDataTypeObj().label2value(paramvalue),(oracle.sql.BLOB)rs .getBlob(colidx++)); } } } } rs.close(); }else { if(lstParamBeans!=null&&lstParamBeans.size()>0) { int idx=1; for(EditableReportParamBean paramBean:lstParamBeans) { paramBean.getDataTypeObj().setPreparedStatementValue(idx++, paramBean.getRuntimeParamValue(rrequest,rbean,mRowData,mParamValues,this.datasource,ownerUpdateBean.isAutoReportdata()), pstmt,dbtype); } } rtnVal=pstmt.executeUpdate(); } return rtnVal; } protected void storeReturnValue(ReportRequest rrequest,Map<String,String> mExternalParamsValue,String rtnVal) { if(this.returnValueParamname==null||this.returnValueParamname.trim().equals("")) return; if(Tools.isDefineKey("#",this.returnValueParamname)) { if(mExternalParamsValue!=null) { mExternalParamsValue.put(Tools.getRealKeyByDefine("#",this.returnValueParamname),rtnVal); } }else if(Tools.isDefineKey("rrequest",this.returnValueParamname)) { rrequest.setAttribute(Tools.getRealKeyByDefine("rrequest",this.returnValueParamname),rtnVal); } } /*private String getExternalValueOfReferedCol(ReportBean rbean,ReportRequest rrequest,EditableReportParamBean paramBean,String paramvalue) { ColBean referredColBean=(ColBean)((EditableReportExternalValueBean)paramBean.getOwner()).getRefObj();//取到被引用的其它报表的列对象 String colParamname=referredColBean.getReportBean().getId()+referredColBean.getProperty(); if(paramvalue.indexOf(".insert.")>0) { List<Map<String,String>> lstInsertedCValues=rrequest.getLstInsertedData(referredColBean.getReportBean()); if(lstInsertedCValues!=null&&lstInsertedCValues.size()>0) { paramvalue=paramBean.getParamValue(lstInsertedCValues.get(0).get(colParamname),rrequest,rbean); }else { paramvalue=""; } }else if(paramvalue.indexOf(".update.")>0) { List<Map<String,String>> lstUpdatedCValues=rrequest.getLstUpdatedData(referredColBean.getReportBean());//取到被引用的报表本次保存时所有变量的数据 if(lstUpdatedCValues!=null&&lstUpdatedCValues.size()>0) { paramvalue=Tools.getRealKeyByDefine("@",paramvalue).trim(); if(paramvalue.endsWith(".old")) { paramvalue=lstUpdatedCValues.get(0).get(colParamname+"_old"); if(paramvalue==null) { paramvalue=lstUpdatedCValues.get(0).get(colParamname); } paramvalue=paramBean.getParamValue(paramvalue,rrequest,rbean); }else { paramvalue=paramBean.getParamValue(lstUpdatedCValues.get(0).get(colParamname),rrequest,rbean); } }else { paramvalue=""; } }else if(paramvalue.indexOf(".delete.")>0) { List<Map<String,String>> lstDeletedCValues=rrequest.getLstDeletedData(referredColBean.getReportBean());//取到被引用的报表本次保存时所有变量的数据 if(lstDeletedCValues!=null&&lstDeletedCValues.size()>0) { paramvalue=lstDeletedCValues.get(0).get(colParamname+"_old"); if(paramvalue==null) { paramvalue=lstDeletedCValues.get(0).get(colParamname); } paramvalue=paramBean.getParamValue(paramvalue,rrequest,rbean); }else { paramvalue=""; } }else { List<Map<String,String>> lstInsertedCValues=rrequest.getLstInsertedData(referredColBean.getReportBean()); if(lstInsertedCValues!=null&&lstInsertedCValues.size()>0) { paramvalue=paramBean.getParamValue(lstInsertedCValues.get(0).get(colParamname),rrequest,rbean); }else { List<Map<String,String>> lstUpdatedCValues=rrequest.getLstUpdatedData(referredColBean.getReportBean()); if(lstUpdatedCValues!=null&&lstUpdatedCValues.size()>0) { paramvalue=paramBean.getParamValue(lstUpdatedCValues.get(0).get(colParamname),rrequest,rbean); }else { List<Map<String,String>> lstDeletedCValues=rrequest.getLstDeletedData(referredColBean.getReportBean()); if(lstDeletedCValues!=null&&lstDeletedCValues.size()>0) { paramvalue=lstDeletedCValues.get(0).get(colParamname+"_old"); if(paramvalue==null) { paramvalue=lstDeletedCValues.get(0).get(colParamname); } paramvalue=paramBean.getParamValue(paramvalue,rrequest,rbean); }else { paramvalue=""; } } } } return paramvalue; }*/ /**private String getReferedOtherExternalValue(ReportBean rbean,ReportRequest rrequest,EditableReportParamBean paramBean,String paramvalue) { EditableReportExternalValueBean referredEValueBean=(EditableReportExternalValueBean)((EditableReportExternalValueBean)paramBean.getOwner()) .getRefObj(); ReportBean rbeanRefered=referredEValueBean.getOwner().getOwner().getOwner().getReportBean(); if(paramvalue.indexOf(".insert.")>0) {//是引用其它报表在<insert/>中定义的变量的值 List<Map<String,String>> lstInsertedEValues=rrequest.getLstInsertedExternalValues(rbeanRefered);//取到被引用的报表本次保存时所有变量的数据 if(lstInsertedEValues!=null&&lstInsertedEValues.size()>0) { paramvalue=paramBean.getParamValue(lstInsertedEValues.get(0).get(referredEValueBean.getName()),rrequest,rbean); }else { paramvalue=""; } }else if(paramvalue.indexOf(".update.")>0) {//是引用其它报表在<update/>中定义的变量的值 List<Map<String,String>> lstUpdatedEValues=rrequest.getLstUpdatedExternalValues(rbeanRefered); if(lstUpdatedEValues!=null&&lstUpdatedEValues.size()>0) { paramvalue=paramBean.getParamValue(lstUpdatedEValues.get(0).get(referredEValueBean.getName()),rrequest,rbean); }else { paramvalue=""; } }else if(paramvalue.indexOf(".delete.")>0) {//是引用其它报表在<delete/>中定义的变量的值 List<Map<String,String>> lstDeletedEValues=rrequest.getLstDeletedExternalValues(rbeanRefered); if(lstDeletedEValues!=null&&lstDeletedEValues.size()>0) { paramvalue=paramBean.getParamValue(lstDeletedEValues.get(0).get(referredEValueBean.getName()),rrequest,rbean); }else { paramvalue=""; } } return paramvalue; }*/ public Object createEditParams(String paramname,String reportTypeKey) { if(paramname==null) return null; Object objResult=null; EditableReportParamBean paramBean=new EditableReportParamBean(); if(Tools.isDefineKey("sequence",paramname)) { objResult=Config.getInstance().getDataSource(this.datasource).getDbType().getSequenceValueByName( Tools.getRealKeyByDefine("sequence",paramname)); }else if(Tools.isDefineKey("#",paramname)) {//是从<params/>中定义的变量中取值 paramname=Tools.getRealKeyByDefine("#",paramname); EditableReportExternalValueBean editparamsbean=this.ownerUpdateBean.getExternalValueBeanByName(paramname,true); paramBean.setParamname(paramname); paramBean.setOwner(editparamsbean); objResult=paramBean; }else if(Tools.isDefineKey("@",paramname)) { if(this.ownerUpdateBean.isAutoReportdata()) { objResult=createParamBeanByColbean(Tools.getRealKeyByDefine("@",paramname),reportTypeKey,true,true); }else { ((EditableReportSQLButtonDataBean)this.ownerUpdateBean).setHasReportDataParams(true); paramBean.setParamname(paramname); objResult=paramBean; } }else if(WabacusAssistant.getInstance().isGetRequestContextValue(paramname) ||Tools.isDefineKey("!",paramname)||paramname.equals("uuid{}")||Tools.isDefineKey("increment",paramname)) { paramBean.setParamname(paramname); objResult=paramBean; if(Tools.isDefineKey("url",paramname)) { this.ownerUpdateBean.getOwner().getReportBean().addParamNameFromURL(Tools.getRealKeyByDefine("url",paramname)); } }else { objResult=paramname; } return objResult; } // /** // * @param paramBean // */ // if(((EditableReportParamBean)paramBean).getOwner() instanceof EditableReportExternalValueBean) // {//是从<params/>中定义的变量中取值 // } public abstract void parseActionScript(String script,List<AbsUpdateAction> lstUpdateActions,String reportTypeKey); }