001: /**
002: * Sequoia: Database clustering technology.
003: * Copyright (C) 2005 Continuent, Inc.
004: * Contact: sequoia@continuent.org
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: *
018: * Initial developer(s): Emmanuel Cecchet
019: * Contributor(s): ______________________.
020: */package org.continuent.sequoia.console.text.commands.dbadmin;
021:
022: import org.continuent.sequoia.common.i18n.ConsoleTranslate;
023: import org.continuent.sequoia.console.text.module.VirtualDatabaseAdmin;
024:
025: /**
026: * This class display statistics of the SQL monitoring module of the controller.
027: *
028: * @author <a href="mailto:emmanuel.cecchet@continuent.com">Emmanuel Cecchet</a>
029: * @version 1.0
030: */
031: public class ShowSqlStats extends AbstractAdminCommand {
032: private String[] columnNames;
033:
034: /**
035: * Creates a new <code>ShowSqlStats</code> object
036: *
037: * @param module virtual database admin module
038: */
039: public ShowSqlStats(VirtualDatabaseAdmin module) {
040: super (module);
041: columnNames = new String[9];
042: columnNames[0] = "SQL statement";
043: columnNames[1] = "Count";
044: columnNames[2] = "Error";
045: columnNames[3] = "Cache hits";
046: columnNames[4] = "% hits";
047: columnNames[5] = "Min time (ms)";
048: columnNames[6] = "Max time (ms)";
049: columnNames[7] = "Avg time (ms)";
050: columnNames[8] = "Total time (ms)";
051: }
052:
053: /**
054: * @see org.continuent.sequoia.console.text.commands.ConsoleCommand#parse(java.lang.String)
055: */
056: public void parse(String commandText) throws Exception {
057: String[][] stats = jmxClient.getDataCollectorProxy()
058: .retrieveSQLStats(dbName);
059: if (stats == null)
060: console
061: .printError("No SQL statistics are available on this controller");
062: else
063: console.println(displayStats(stats));
064: }
065:
066: /**
067: * @see org.continuent.sequoia.console.text.commands.ConsoleCommand#getCommandName()
068: */
069: public String getCommandName() {
070: return "show sql statistics"; //$NON-NLS-1$
071: }
072:
073: /**
074: * @see org.continuent.sequoia.console.text.commands.ConsoleCommand#getCommandDescription()
075: */
076: public String getCommandDescription() {
077: return ConsoleTranslate
078: .get("admin.command.show.sql.stats.description");
079: }
080:
081: /**
082: * Format data for text consoles
083: *
084: * @param data to display
085: * @return a formatted string with tabs and end of line
086: */
087: public String displayStats(String[][] data) {
088: if (data == null)
089: return "";
090:
091: // constants used for formatting the output
092: final String columnPadding = " ";
093: final String nameValueSeparator = ": ";
094:
095: // solve the maximum length for column names
096: // TODO: refactor this into its own method
097: int maxNameLength = 0;
098: for (int i = 0; i < columnNames.length; i++) {
099: maxNameLength = Math.max(maxNameLength, columnNames[i]
100: .length());
101: }
102:
103: // solve the maximum length for column values
104: // TODO: refactor this into its own method
105: int maxValueLength = 0;
106: for (int i = 0; i < data.length; i++) {
107: for (int j = 0; j < data[i].length; j++) {
108: maxValueLength = Math.max(maxValueLength, data[i][j]
109: .length());
110: }
111: }
112:
113: // construct a separator line based on maximum column and value lengths
114: // TODO: extract numbers into constants and this block into a new method
115: char[] separator = new char[columnPadding.length()
116: + maxNameLength + nameValueSeparator.length()
117: + maxValueLength + 1]; /*
118: * the newline
119: * character
120: */
121: for (int i = 0; i < separator.length; i++) {
122: separator[i] = '-';
123: }
124: separator[separator.length - 1] = '\n';
125:
126: // loop through all the data and print padded lines into the StringBuffer
127: StringBuffer sb = new StringBuffer();
128: for (int i = 0; i < data.length; i++) {
129: sb.append(separator);
130: for (int j = 0; j < data[i].length; j++) {
131: // create the padding needed for this particular column
132: // TODO: extract this into its own method
133: char[] namePadding = new char[maxNameLength
134: - columnNames[j].length()];
135: for (int x = 0; x < namePadding.length; x++) {
136: namePadding[x] = ' ';
137: }
138:
139: sb.append(columnPadding);
140: sb.append(columnNames[j]);
141: sb.append(nameValueSeparator);
142: sb.append(namePadding);
143: sb.append(data[i][j]);
144: sb.append("\n");
145: }
146: if (i + 1 == data.length) {
147: sb.append(separator);
148: }
149: }
150: return sb.toString();
151: }
152:
153: }
|