/******************************************************************************* * Copyright (c) 2013 hangum. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Lesser Public License v2.1 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * hangum - initial API and implementation ******************************************************************************/ package com.hangum.tadpole.rdb.core.editors.main.utils.plan; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import com.hangum.tadpole.commons.libs.core.define.PublicTadpoleDefine.SQL_STATEMENT_TYPE; import com.hangum.tadpole.engine.manager.TadpoleSQLManager; import com.hangum.tadpole.engine.query.dao.system.UserDBDAO; import com.hangum.tadpole.engine.sql.util.resultset.TadpoleResultSet; import com.hangum.tadpole.engine.utils.RequestQuery; import cubrid.jdbc.driver.CUBRIDStatement; /** * cubrid execute plan * * <pre> * 쿼리 실행시 / *+ recompile * / 를 붙여야합니다. * * 자세한 정보는 다음을 참조합니다. * q&a : http://www.cubrid.com/zbxe/bbs_developer_qa/346565 * </pre> * * @author hangum * */ public class CubridExecutePlanUtils { /** * Logger for this class */ private static final Logger logger = Logger.getLogger(CubridExecutePlanUtils.class); /** 쿼리 플랜을 수행하기 위한 옵션 */ private static final String RECOMPILE = " /*+ recompile */ "; /** * cubrid execute plan * * @param userDB * @param reqQuery * @return * @throws Exception */ public static String plan(UserDBDAO userDB, final RequestQuery reqQuery) throws Exception { String sql = reqQuery.getSql(); if(!sql.toLowerCase().startsWith("select")) { logger.error("[cubrid execute plan ]" + sql); throw new Exception ("This statment not select. please check."); } Connection conn = null; ResultSet rs = null; PreparedStatement pstmt = null; try { conn = TadpoleSQLManager.getConnection(userDB); conn.setAutoCommit(false); // 플랜 정보를 가져오기 위해서는 auto commit을 false로 설정해야 함. sql = StringUtils.trim(sql).substring(6); if(logger.isDebugEnabled()) logger.debug("[qubrid modifying query]" + sql); sql = "select " + RECOMPILE + sql; pstmt = conn.prepareStatement(sql); if(reqQuery.getSqlStatementType() == SQL_STATEMENT_TYPE.PREPARED_STATEMENT) { final Object[] statementParameter = reqQuery.getStatementParameter(); for (int i=1; i<=statementParameter.length; i++) { pstmt.setObject(i, statementParameter[i-1]); } } ((CUBRIDStatement) pstmt).setQueryInfo(true); rs = pstmt.executeQuery(); String plan = ((CUBRIDStatement) pstmt).getQueryplan(); // 수행한 질의 플랜 정보를 가져오는 메소드. if(logger.isDebugEnabled()) logger.debug("cubrid plan text : " + plan); return plan; } finally { if (rs != null) rs.close(); if (pstmt != null) pstmt.close(); if (conn != null) conn.close(); } } /** * cubrid plan은 text로 결과가 넘오 와서 올챙이 테이블 <헤더> 만들어 줍니다. * * @return */ public static HashMap<Integer, String> getMapColumns() { HashMap<Integer, String> mapColumns = new HashMap<Integer, String>(); mapColumns.put(0, "Query Plan"); return mapColumns; } /** * cubrid plan은 text로 결과가 넘오 와서 올챙이 테이블 <데이터>로 만들어 줍니다. * * @param data * @return */ public static TadpoleResultSet getMakeData(String data) { List<Map<Integer, Object>> sourceDataList = new ArrayList<Map<Integer, Object>>(); HashMap<Integer, Object> tmpRs = new HashMap<Integer, Object>(); tmpRs.put(0, data); sourceDataList.add(tmpRs); TadpoleResultSet trs = new TadpoleResultSet(sourceDataList); return trs; } }