/* *------------------- * The GanttSqls.java is part of ASH Viewer *------------------- * * ASH Viewer is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * ASH Viewer 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ASH Viewer. If not, see <http://www.gnu.org/licenses/>. * * Copyright (c) 2009, Alex Kardapolov, All rights reserved. * */ package org.ash.detail; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import org.ash.database.ASHDatabase; import org.ash.util.Utils; import com.egantt.model.drawing.DrawingState; import com.egantt.model.drawing.part.ListDrawingPart; import ext.egantt.model.drawing.state.BasicDrawingState; import ext.egantt.drawing.module.BasicPainterModule; import ext.egantt.swing.GanttDrawingPartHelper; public class GanttSqls { /** The database. */ private ASHDatabase database; /** The prev percent. */ private long percentPrev = 0; /** The SUM var. */ private String SUM = "SUM"; /** The COUNT var. */ private String COUNT = "COUNT"; /** The UNKNOWN var. */ private String UNKNOWN = "UNKNOWN"; /** The scale toggle: * < 30 => 2 * 30-70 => 1 * > 70 => 0 * */ private int scaleToggle = 0; /** The scale. */ private double scale = 0.8; /** The detail for top sql, default 10, max - 50, minimum - 0 values*/ private int topSqlsSqlText = 10; /** The TEXT_PAINTER. */ final String TEXT_PAINTER = "MyTextPainter"; /** Is select sql plan*/ private boolean isSelectSqlPlan = false; /** * Constructor Gantt for sqls * * @param database0 the database0 */ public GanttSqls(ASHDatabase database0){ this.database = database0; } /** * Load data to sessions gantt. * * @return SESSIONID, USERNAME, PROGRAM */ public Object[][] getDataToSqlsGantt(Map<Integer,String> arraySqlIdTSQLTextTab){ return this.loadDataToSqlsGanttPr(arraySqlIdTSQLTextTab); } /** * Load data to sqls gantt. * * @return the object[][] */ private Object[][] loadDataToSqlsGanttPr(Map<Integer,String> arraySqlIdTSQLTextTab){ int i = 0; int ii = 0; int sizeGanttTable = 100; int sizeMainSqls = database.getSqlsTempDetail().getMainSqls().size(); StringBuilder clipBoardContent = new StringBuilder(); Object[][] data = new Object[Math.min(sizeGanttTable, sizeMainSqls)][3]; final GanttDrawingPartHelper partHelper = new GanttDrawingPartHelper(); double countOfSqls = database.getSqlsTempDetail().getCountSql(); double sumOfRange = database.getSqlsTempDetail().get_sum(); // Desc sorting HashMap<String, HashMap<String, Object>> sortedSessionMap = Utils.sortHashMapByValues(database.getSqlsTempDetail().getMainSqls(),COUNT); List<String> arraySqlId = new ArrayList<String>(); for (Entry<String, HashMap<String, Object>> me : sortedSessionMap.entrySet()) { data[i][0] = createDrawingState(partHelper, me,countOfSqls,sumOfRange); data[i][1] = me.getKey(); data[i][2] = UNKNOWN; /** Load sqlid, sqltype, sqltext from local storage */ if (ii < this.topSqlsSqlText) { arraySqlId.add(me.getKey()); } /** Exit when rows > 100 */ if (i+1==Math.min(sizeGanttTable, sizeMainSqls)){ break; } i++; ii++; } /** Load commandType, sqlText from Oracle database*/ database.loadSqlTextCommandTypeFromDB(arraySqlId); /** Load sql plan to local BDB*/ if (isSelectSqlPlan){ database.loadSqlPlanFromDB(arraySqlId, true); } /** Load CommandType, SqlText to gantt*/ ii = 0; for (Entry<String, HashMap<String, Object>> me : sortedSessionMap .entrySet()) { String sqlId = me.getKey(); String sqlText = database.getSqlText(sqlId); String sqlType = database.getSqlType(sqlId); data[ii][1] = createDrawingStateSqlId(partHelper, sqlId, sqlText); if (!sqlType.equals("")) data[ii][2] = sqlType; // Save clipboard content clipBoardContent.append(sqlId + ":::" + sqlText + "\n"); /** Save arraySqlIdText50 for SQL Text tab*/ if (!sqlType.equalsIgnoreCase("UNKNOWN")) { arraySqlIdTSQLTextTab.put(ii, sqlId); } /** Exit when rows > 500 */ if (ii + 1 == Math.min(sizeGanttTable, sizeMainSqls)) { break; } ii++; } /** Set clipboard content */ Utils.setClipBoardContent(clipBoardContent.toString()); percentPrev = 0; return data; } /** * Creates the drawing state for Sqls and Sessions. * * @param helper the helper * @param me the me * @param countOfSqls the sum of range * * @return the drawing state */ private DrawingState createDrawingState( GanttDrawingPartHelper helper, Entry<String, HashMap<String,Object>> me, double countOfSqls, double sumOfRange ) { BasicDrawingState state = helper.createDrawingState(); ListDrawingPart part = helper.createDrawingPart(false); ListDrawingPart textLayer = helper.createDrawingPart(true); double countPerSqlID = (Double)me.getValue().get(COUNT); double percent = Utils.round(countPerSqlID/countOfSqls*100,2); /* < 30 => 2 * 30-70 => 1 * > 70 => 0 */ if (percentPrev == 0){ if (percent > 70){ scaleToggle = 0; } else if (percent <70 && percent >30){ scaleToggle = 1; } else if (percent < 30){ scaleToggle = 2; } } if (percent<0.6){ // Show only percent String localizedText = ""+percent+"%"; helper.createActivityEntry(new StringBuffer(localizedText), new Date(0), new Date(100), BasicPainterModule.BASIC_STRING_PAINTER, TEXT_PAINTER, textLayer); state.addDrawingPart(part); state.addDrawingPart(textLayer); return state; } // Save to local map, sort by values HashMap tempKeyMap = new HashMap<String,Double>(); Iterator iterEvent = this.database.getSqlsTempDetail().getEventList().iterator(); while (iterEvent.hasNext()) { String eventName = (String) iterEvent.next(); Double eventValue = (Double)me.getValue().get(eventName); if (eventValue != null){ tempKeyMap.put(eventName, me.getValue().get(eventName)); } } HashMap sortedByKeyMap = new HashMap<String,Double>(); //Sort values on desc order sortedByKeyMap = Utils.sortHashMapByValuesDesc(tempKeyMap); // Calculate sum of event by SqlId Set keySetsorted = sortedByKeyMap.keySet(); long start = 0; scale = Utils.getScale(scaleToggle, percent); // Create activites for row on gantt Set keySetsorted1 = sortedByKeyMap.keySet(); Iterator jj = keySetsorted.iterator(); while (jj.hasNext()) { String key = (String) jj.next(); double value = (Double)sortedByKeyMap.get(key); // Show only not zero activites. if (value != 0 ){ double currentGroupPercentNotScale = (value/countPerSqlID)*percent; double currentGroupPercent = currentGroupPercentNotScale*scale; if (currentGroupPercent<1.0 && currentGroupPercent>=0.6){ currentGroupPercent = Utils.round(currentGroupPercent,0); } long currGroupPercentL = (long)Utils.round(currentGroupPercent,0); // Set tooltip final StringBuffer o = new StringBuffer(); { o.append("<HTML>"); o.append("<b>" + key + " " + Utils.round(currentGroupPercentNotScale,2) + "%" + "</b>"); o.append("</HTML>"); } // Exit when prev. egantt < than current egantt graph if (percentPrev != 0 && (start + currGroupPercentL) > percentPrev ){ currGroupPercentL = percentPrev - start; helper.createActivityEntry( o, new Date(start), new Date(start+currGroupPercentL), key,//getGradientContext(key), part); start = start + currGroupPercentL; break; } // If row only one if (currentGroupPercent == 100){ helper.createActivityEntry( o, new Date(start), new Date(currGroupPercentL), key,//getGradientContext(key), part); } else { helper.createActivityEntry( o, new Date(start), new Date(start+currGroupPercentL), key,//getGradientContext(key), part); start = start + currGroupPercentL; } } } // Show percent String localizedText = ""+percent+"%"; helper.createActivityEntry(new StringBuffer(localizedText), new Date(start), new Date(100), BasicPainterModule.BASIC_STRING_PAINTER, TEXT_PAINTER, textLayer); state.addDrawingPart(part); state.addDrawingPart(textLayer); percentPrev = start; return state; } /** * Creates the drawing state for SqlId. * * @param helper the helper * @return the drawing state */ private DrawingState createDrawingStateSqlId(GanttDrawingPartHelper helper, String key, String value) { BasicDrawingState state = helper.createDrawingState(); ListDrawingPart part = helper.createDrawingPart(false); ListDrawingPart textLayer = helper.createDrawingPart(true); //String key = ""; //String value = ""; // Set tooltip (sql_text) final StringBuffer o = new StringBuffer(); if (value.equals("")) { value = "No data"; } o.append(Utils.formatSqlQueryShort(value)); // Show sqlid helper.createActivityEntry(new StringBuffer(key), new Date(5), new Date(95), BasicPainterModule.BASIC_STRING_PAINTER, TEXT_PAINTER, textLayer); helper.createActivityEntry(o, new Date(0), new Date(100), BasicPainterModule.BASIC_STRING_PAINTER, part); state.addDrawingPart(part); state.addDrawingPart(textLayer); state.setTextValue(key); return state; } /** * @return the topSqlsSqlText */ public int getTopSqlsSqlText() { return topSqlsSqlText; } /** * @param topSqlsSqlText the topSqlsSqlText to set */ public void setTopSqlsSqlText(int topSqlsSqlText) { this.topSqlsSqlText = topSqlsSqlText; } /** * Is select sql plan * * @param isSelectSqlPlan */ public void setSelectSqlPlan(boolean isSelectSqlPlan) { this.isSelectSqlPlan = isSelectSqlPlan; } }