001: package net.sourceforge.squirrel_sql.plugins.oracle.sessioninfo;
002:
003: /*
004: * Copyright (C) 2004 Jason Height
005: * jmheight@users.sourceforge.net
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021:
022: import java.awt.BorderLayout;
023: import java.sql.Connection;
024: import java.sql.PreparedStatement;
025: import java.sql.ResultSet;
026: import java.sql.SQLException;
027: import java.util.Timer;
028: import java.util.TimerTask;
029:
030: import javax.swing.JPanel;
031: import javax.swing.JScrollPane;
032: import javax.swing.JTable;
033: import javax.swing.table.DefaultTableModel;
034:
035: import net.sourceforge.squirrel_sql.client.session.ISession;
036: import net.sourceforge.squirrel_sql.fw.gui.GUIUtils;
037: import net.sourceforge.squirrel_sql.fw.sql.SQLUtilities;
038: import net.sourceforge.squirrel_sql.fw.util.log.ILogger;
039: import net.sourceforge.squirrel_sql.fw.util.log.LoggerController;
040: import net.sourceforge.squirrel_sql.plugins.oracle.OraclePlugin;
041: import net.sourceforge.squirrel_sql.plugins.oracle.common.AutoWidthResizeTable;
042:
043: public class SessionInfoPanel extends JPanel {
044: private static final long serialVersionUID = 1L;
045:
046: /**
047: * Logger for this class.
048: */
049: private static final ILogger s_log = LoggerController
050: .createLogger(SessionInfoPanel.class);
051:
052: //JMH Remove the current sql text. Create a tabbed pane for session details (including sql text)
053: private static final String SESSION_INFO_SQL = "SELECT sess.Sid, "
054: + " sess.serial#, "
055: + " NVL(sess.username, bgproc.name), "
056: + " sess.schemaname, "
057: + " sess.status, "
058: + " sess.server, "
059: + " sess.osuser, "
060: + " sess.machine, "
061: + " sess.terminal, "
062: + " sess.program, "
063: + " sess.process, "
064: + " sess.type, "
065: + " sess.module, "
066: + " sess.action, "
067: + " sess.client_Info, "
068: + " sess_io.block_gets, "
069: + " sess_io.consistent_gets, "
070: + " sess_io.physical_reads, "
071: + " sess_io.block_changes, "
072: + " sess_io.consistent_changes, "
073: + " sess_stat.value*10, "
074: + " sess.last_call_et, "
075: + " d.sql_text, "
076: + " sess.sql_address || ':' || sql_hash_value, "
077: + " sess.prev_sql_addr || ':' || prev_hash_value, "
078: + " sess.logon_time "
079: + "FROM v$session sess, "
080: + " v$bgprocess bgproc,"
081: + " v$sess_io sess_io, "
082: + " v$sesstat sess_stat, "
083: + " v$sql d "
084: + "WHERE sess.sid = sess_io.sid ( + ) "
085: + " AND sess.sid = sess_stat.sid ( + ) "
086: + " AND sess.paddr = bgproc.paddr ( + ) "
087: + " AND ( sess_stat.statistic# = 12 OR sess_stat.statistic# IS NULL ) "
088: + " AND sess.sql_address = d.address ( + ) "
089: + " AND sess.sql_hash_value = d.hash_value ( + ) "
090: + " AND ( d.child_number = 0 OR d.child_number IS NULL ) "
091: + "ORDER BY sess.sid ";
092: //JMH: For additional performance we could utilise the fixed_table_sequence column
093: //from the session, to investigate which rows need to be updated on a refresh
094: //See V$SESSION doco for more info.
095:
096: /**
097: * Current session.
098: */
099: transient private ISession _session;
100:
101: private AutoWidthResizeTable _sessionInfo;
102: private boolean hasResized = false;
103: transient private Timer _refreshTimer = new Timer(true);
104:
105: private boolean _autoRefresh = false;
106: private int _refreshPeriod = 10;
107:
108: public class RefreshTimerTask extends TimerTask {
109: public void run() {
110: populateSessionInfo();
111: }
112: }
113:
114: /**
115: * Ctor.
116: *
117: * @param autoRefeshPeriod
118: * @param session Current session.
119: * @throws IllegalArgumentException Thrown if a <TT>null</TT> <TT>ISession</TT> passed.
120: */
121: public SessionInfoPanel(ISession session, int autoRefeshPeriod) {
122: super ();
123: _session = session;
124: _refreshPeriod = autoRefeshPeriod;
125: createGUI();
126: }
127:
128: /**
129: * Current session.
130: */
131: public ISession getSession() {
132: return _session;
133: }
134:
135: private void resetTimer() {
136: if (_refreshTimer != null) {
137: _refreshTimer.cancel();
138: //Nil out the timer so that it can be gc'd
139: _refreshTimer = null;
140: }
141: if (_autoRefresh && (_refreshPeriod > 0)) {
142: _refreshTimer = new Timer(true);
143: _refreshTimer.scheduleAtFixedRate(new RefreshTimerTask(),
144: _refreshPeriod * 1000, _refreshPeriod * 1000);
145: }
146: }
147:
148: public void setAutoRefresh(boolean enable) {
149: if (enable != _autoRefresh) {
150: _autoRefresh = enable;
151: resetTimer();
152: }
153: }
154:
155: public boolean getAutoRefesh() {
156: return _autoRefresh;
157: }
158:
159: public void setAutoRefreshPeriod(int seconds) {
160: if (_refreshPeriod != seconds) {
161: _refreshPeriod = seconds;
162: resetTimer();
163: }
164: }
165:
166: public int getAutoRefreshPeriod() {
167: return _refreshPeriod;
168: }
169:
170: protected DefaultTableModel createTableModel() {
171: DefaultTableModel tm = new DefaultTableModel();
172: tm.addColumn("Sid");
173: tm.addColumn("Serial #");
174: tm.addColumn("Session Name");
175: tm.addColumn("Schema");
176: tm.addColumn("Status");
177: tm.addColumn("Server");
178: tm.addColumn("OS user");
179: tm.addColumn("Machine");
180: tm.addColumn("Terminal");
181: tm.addColumn("Program");
182: tm.addColumn("Process");
183: tm.addColumn("Type");
184: tm.addColumn("Module");
185: tm.addColumn("Action");
186: tm.addColumn("Client Info");
187: tm.addColumn("Block Gets");
188: tm.addColumn("Consistent Gets");
189: tm.addColumn("Physical Reads");
190: tm.addColumn("Block Changes");
191: tm.addColumn("Consistent Changes");
192: tm.addColumn("CPU time (ms)");
193: tm.addColumn("Last SQL");
194: tm.addColumn("Current SQL Statement");
195: tm.addColumn("SQL Address");
196: tm.addColumn("Prev SQL Address");
197: tm.addColumn("Logon Time");
198: return tm;
199: }
200:
201: public synchronized void populateSessionInfo() {
202: if (!OraclePlugin.checkObjectAccessible(_session,
203: SESSION_INFO_SQL)) {
204: return;
205: }
206: PreparedStatement pstmt = null;
207: ResultSet rs = null;
208: try {
209: Connection con = _session.getSQLConnection()
210: .getConnection();
211: if (s_log.isDebugEnabled()) {
212: s_log.debug("populateSessionInfo: running sql - "
213: + SESSION_INFO_SQL);
214: }
215: pstmt = con.prepareStatement(SESSION_INFO_SQL);
216: rs = pstmt.executeQuery();
217: final DefaultTableModel tm = createTableModel();
218: while (rs.next()) {
219: String sid = rs.getString(1);
220: String serNum = rs.getString(2);
221: String sessionName = rs.getString(3);
222: String schema = rs.getString(4);
223: String status = rs.getString(5);
224: String server = rs.getString(6);
225: String OSusr = rs.getString(7);
226: String machine = rs.getString(8);
227: String terminal = rs.getString(9);
228: String program = rs.getString(10);
229: String process = rs.getString(11);
230: String type = rs.getString(12);
231: String module = rs.getString(13);
232: String action = rs.getString(14);
233: String clientInfo = rs.getString(15);
234: String blockGets = rs.getString(16);
235: String consistentGets = rs.getString(17);
236: String physReads = rs.getString(18);
237: String blockChanges = rs.getString(19);
238: String consistentChanges = rs.getString(20);
239: String CPUtime = rs.getString(21);
240: String lastSQL = rs.getString(22);
241: String currSQL = rs.getString(23);
242: String SQLaddr = rs.getString(24);
243: String prevSQLaddr = rs.getString(25);
244: String logonTime = rs.getString(26);
245:
246: //Should probably create my own table model but i am being a bit slack.
247: tm.addRow(new Object[] { sid, serNum, sessionName,
248: schema, status, server, OSusr, machine,
249: terminal, program, process, type, module,
250: action, clientInfo, blockGets, consistentGets,
251: physReads, blockChanges, consistentChanges,
252: CPUtime, lastSQL, currSQL, SQLaddr,
253: prevSQLaddr, logonTime });
254: }
255: updateTableModel(tm);
256: } catch (SQLException ex) {
257: _session.showErrorMessage(ex);
258: } finally {
259: SQLUtilities.closeResultSet(rs);
260: SQLUtilities.closeStatement(pstmt);
261: }
262: }
263:
264: /**
265: * Sets the specified updated TableModel using the EDT.
266: *
267: * @param tm the TableModel to set.
268: */
269: private void updateTableModel(final DefaultTableModel tm) {
270: GUIUtils.processOnSwingEventThread(new Runnable() {
271: public void run() {
272: _sessionInfo.setModel(tm);
273: if (!hasResized) {
274: //Only resize once.
275: hasResized = true;
276: _sessionInfo.resizeColumnWidth(300);
277: }
278: }
279: });
280: }
281:
282: private void createGUI() {
283: setLayout(new BorderLayout());
284: _sessionInfo = new AutoWidthResizeTable(new DefaultTableModel());
285: _sessionInfo.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
286: add(new JScrollPane(_sessionInfo));
287: populateSessionInfo();
288: }
289: }
|