/* * 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.util.ArrayList; import java.util.List; import com.wabacus.config.Config; import com.wabacus.config.component.application.report.ColBean; import com.wabacus.config.component.application.report.ReportBean; import com.wabacus.config.database.type.AbsDatabaseType; import com.wabacus.exception.WabacusConfigLoadingException; 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.EditableReportParamBean; import com.wabacus.system.dataset.update.action.AbsUpdateAction; import com.wabacus.util.Tools; public class SQLInsertAction extends AbsRationalDBUpdateAction implements Cloneable { public SQLInsertAction(AbsEditableReportEditDataBean ownerUpdateBean) { super(ownerUpdateBean); } public void parseActionScript(String sql,List<AbsUpdateAction> lstInsertActionsResult,String reportTypeKey) { if(this.isStandardInsertSql(sql)) { List<EditableReportParamBean> lstDynParamsTmp=new ArrayList<EditableReportParamBean>(); this.sqlsp=this.ownerUpdateBean.parseStandardEditSql(sql,lstDynParamsTmp,reportTypeKey,this.isPreparedStatement,this.isOriginalParams); this.lstParamBeans=lstDynParamsTmp; this.isStandardSql=true; lstInsertActionsResult.add(this); }else { AbsDatabaseType dbtype=Config.getInstance().getDataSource(this.datasource).getDbType(); if(dbtype==null) { throw new WabacusConfigLoadingException("没有实现数据源"+this.datasource+"对应数据库类型的相应实现类"); } dbtype.constructInsertSql(sql,this.ownerUpdateBean.getOwner().getReportBean(),reportTypeKey,this,lstInsertActionsResult); } } public void constructInsertSql(String configInsertSql,ReportBean rbean,String reportTypeKey,List<AbsUpdateAction> lstInsertActionsResult) { List lstParams=new ArrayList(); StringBuilder sqlBuffer=new StringBuilder(); sqlBuffer.append("insert into "); configInsertSql=configInsertSql.substring("insert".length()).trim(); if(configInsertSql.toLowerCase().indexOf("into ")==0) configInsertSql=configInsertSql.substring(4).trim(); int idxleft=configInsertSql.indexOf("("); if(idxleft<0||configInsertSql.endsWith("()")) {//没有指定要更新的字段,则将所有符合要求的从数据库取数据的<col/>全部更新到表中 if(!this.ownerUpdateBean.isAutoReportdata()) { throw new WabacusConfigLoadingException("加载报表"+rbean.getPath()+"失败,在autoreportdata属性为false的<button/>中,不能配置insert into table这种格式的SQL语句"); } if(configInsertSql.endsWith("()")) configInsertSql=configInsertSql.substring(0,configInsertSql.length()-2).trim(); sqlBuffer.append(configInsertSql).append("("); for(ColBean cbean:rbean.getDbean().getLstCols()) { EditableReportParamBean paramBean=createParamBeanByColbean(cbean.getProperty(),reportTypeKey,false,false); if(paramBean!=null) { sqlBuffer.append(cbean.getColumn()+","); lstParams.add(paramBean); } } }else { sqlBuffer.append(configInsertSql.substring(0,idxleft)).append("("); int idxright=configInsertSql.lastIndexOf(")"); if(idxright!=configInsertSql.length()-1) { throw new WabacusConfigLoadingException("加载报表"+rbean.getPath()+"失败,配置的修改数据SQL语句"+configInsertSql+"不合法"); } String cols=configInsertSql.substring(idxleft+1,idxright); List<String> lstInsertCols=Tools.parseStringToList(cols,",",new String[]{"'","'"},false); String columnname=null; String columnvalue=null; ColBean cb; for(String updatecol:lstInsertCols) { if(updatecol==null||updatecol.trim().equals("")) continue; int idxequals=updatecol.indexOf("="); if(idxequals>0) { columnname=updatecol.substring(0,idxequals).trim(); columnvalue=updatecol.substring(idxequals+1).trim(); Object paramObjTmp=this.createEditParams(columnvalue,reportTypeKey); if(paramObjTmp==null) continue; lstParams.add(paramObjTmp); sqlBuffer.append(columnname+","); }else { if(!Tools.isDefineKey("@",updatecol)) { throw new WabacusConfigLoadingException("加载报表"+rbean.getPath()+"失败,配置的添加数据SQL语句"+configInsertSql+"不合法"); } if(this.ownerUpdateBean.isAutoReportdata()) { updatecol=Tools.getRealKeyByDefine("@",updatecol); String realColProperty=updatecol.trim(); if(realColProperty.endsWith("__old")) realColProperty=realColProperty.substring(0,realColProperty.length()-"__old".length()); cb=rbean.getDbean().getColBeanByColProperty(realColProperty); if(cb==null) { throw new WabacusConfigLoadingException("加载报表"+rbean.getPath()+"失败,配置的要更新字段"+updatecol+"不合法,没有取到其值对应的<col/>"); } sqlBuffer.append(cb.getColumn()+","); lstParams.add(createParamBeanByColbean(updatecol,reportTypeKey,true,true)); }else {//对于直接配置更新脚本的<button/>,且@{}数据来自于客户端传入的 ((EditableReportSQLButtonDataBean)this.ownerUpdateBean).setHasReportDataParams(true); EditableReportParamBean paramBean=new EditableReportParamBean(); paramBean.setParamname(updatecol); lstParams.add(paramBean); sqlBuffer.append(Tools.getRealKeyByDefine("@",updatecol)+","); } } } } if(lstParams.size()==0) { throw new WabacusConfigLoadingException("解析报表"+rbean.getPath()+"的sql语句:"+configInsertSql+"失败,SQL语句格式不对"); } if(sqlBuffer.charAt(sqlBuffer.length()-1)==',') sqlBuffer.deleteCharAt(sqlBuffer.length()-1); sqlBuffer.append(") values("); this.lstParamBeans=constructParamsInSql(lstParams,sqlBuffer); sqlBuffer.append(")"); this.sqlsp=sqlBuffer.toString(); lstInsertActionsResult.add(this); } private List<EditableReportParamBean> constructParamsInSql(List lstParams,StringBuilder sqlBuffer) { List<EditableReportParamBean> lstDynParamsBean=new ArrayList<EditableReportParamBean>(); int placeholderIdxTmp=0; EditableReportParamBean paramBeanTmp; for(int i=0;i<lstParams.size();i++) { if(lstParams.get(i) instanceof EditableReportParamBean) { paramBeanTmp=(EditableReportParamBean)lstParams.get(i); if(this.isPreparedStatement) { sqlBuffer.append("?"); }else { paramBeanTmp.setPlaceholder("[PLACE_HOLDER_"+(placeholderIdxTmp++)+"]"); sqlBuffer.append(paramBeanTmp.getPlaceholder()); } lstDynParamsBean.add(paramBeanTmp); }else {//常量或直接从数据库取数据的数据库函数 sqlBuffer.append(lstParams.get(i)); } sqlBuffer.append(","); } if(sqlBuffer.charAt(sqlBuffer.length()-1)==',') sqlBuffer.deleteCharAt(sqlBuffer.length()-1); return lstDynParamsBean; } private boolean isStandardInsertSql(String insertsql) { insertsql=insertsql==null?"":insertsql.toLowerCase().trim(); if(!insertsql.startsWith("insert")) return true; insertsql=insertsql.substring("insert".length()).trim(); if(insertsql.startsWith("into ")) insertsql=insertsql.substring("into ".length()).trim(); if(insertsql.equals("")) return true; insertsql=Tools.replaceCharacterInQuote(insertsql,'(',"$_LEFTBRACKET_$",true); insertsql=Tools.replaceCharacterInQuote(insertsql,')',"$_RIGHTBRACKET_$",true); int idx=insertsql.indexOf("("); if(idx<0) return insertsql.trim().indexOf(" ")>0; insertsql=insertsql.substring(idx+1).trim(); int idxleft=1; int idxRightBacket=-1; for(int i=0;i<insertsql.length();i++) { if(insertsql.charAt(i)=='(') {//又出现一个左括号 idxleft++; }else if(insertsql.charAt(i)==')') { if(idxleft==1) { idxRightBacket=i; break; }else if(idxleft<=0) { return true; }else { idxleft--; } } } if(idxRightBacket==-1) return true; if(idxRightBacket==0&&(insertsql.equals(")")||insertsql.substring(1).trim().startsWith("where "))) return false; insertsql=insertsql.substring(idxRightBacket+1).trim(); if(insertsql.equals("")||insertsql.startsWith("where ")) return false; return true; } public SQLInsertAction cloneWithAllDefaultValues() { try { return (SQLInsertAction)super.clone(); }catch(CloneNotSupportedException e) { throw new WabacusConfigLoadingException("clone对象失败",e); } } }