public ObjectResultController(ISession session, HibernatePluginResources resource) { _session = session; _resource = resource; final SessionProperties props = session.getProperties(); _objectResultTabbedPane = UIFactory.getInstance().createTabbedPane(props.getSQLExecutionTabPlacement()); }
/** * Sesssion is ending. Remove all listeners that this component has setup. Close all torn off * result tab windows. */ void sessionClosing() { if (_propsListener != null) { _session.getProperties().removePropertyChangeListener(_propsListener); _propsListener = null; } closeAllSQLResultFrames(); }
/** * Set the current session. * * @param session Current session. * @throws IllegalArgumentException Thrown if a <TT>null</TT> <TT>ISession</TT> passed. */ public synchronized void setSession(ISession session) { if (session == null) { throw new IllegalArgumentException("Null ISession passed"); } sessionClosing(); _session = session; _propsListener = new MyPropertiesListener(); _session.getProperties().addPropertyChangeListener(_propsListener); }
private void createGUI() { final SessionProperties props = _session.getProperties(); _tabbedExecutionsPanel = UIFactory.getInstance().createTabbedPane(props.getSQLExecutionTabPlacement(), true); createTabPopup(); setLayout(new BorderLayout()); add(_tabbedExecutionsPanel, BorderLayout.CENTER); }
private void checkResultTabLimit() { SessionProperties props = _session.getProperties(); while (props.getLimitSQLResultTabs() && props.getSqlResultTabLimit() < _tabbedExecutionsPanel.getTabCount()) { if (_tabbedExecutionsPanel.getComponentAt(0) instanceof CancelPanel) { break; } closeTabAt(0); } }
private void createGUI() { setLayout(new BorderLayout()); _tabbedExecutionsPanel = UIFactory.getInstance() .createTabbedPane(_session.getProperties().getSQLExecutionTabPlacement()); initTabPopup(); add(_tabbedExecutionsPanel, BorderLayout.CENTER); }
public ExplainExecuterPanel(ISession session) { _session = session; _dialectType = DialectFactory.getDialectType(_session.getMetaData()); _session .getProperties() .addPropertyChangeListener( new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { onPropertyChange(evt.getPropertyName()); } }); createGUI(); }
private void secureAddTab(ExplainTab tab) { SessionProperties props = _session.getProperties(); if (s_log.isDebugEnabled()) { s_log.debug("secureAddTab - TabCount: " + _tabbedExecutionsPanel.getTabCount()); s_log.debug("secureAddTab - Limited?: " + props.getLimitSQLResultTabs()); s_log.debug("secureAddTab - TabLimit: " + props.getSqlResultTabLimit()); } if (props.getLimitSQLResultTabs() && props.getSqlResultTabLimit() <= _tabbedExecutionsPanel.getTabCount()) { closeTabAt(0); } _tabbedExecutionsPanel.addTab(tab.getTitle(), null, tab, tab.getToolTip()); _tabbedExecutionsPanel.setSelectedComponent(tab); }
private void validateSQL() { final ISQLPanelAPI api = _session.getSQLPanelAPI(_plugin); final String sql = api.getSQLScriptToBeExecuted(); if (sql != null && sql.trim().length() > 0) { final SessionProperties sessionProps = _session.getProperties(); final WebServiceSessionProperties wssProps = _plugin.getWebServiceSessionProperties(_session); final char stmtSepChar = sessionProps.getSQLStatementSeparatorChar(); final String solComment = sessionProps.getStartOfLineComment(); final ValidationProps valProps = new ValidationProps( _prefs, wssProps, _session.getMessageHandler(), sql, stmtSepChar, solComment); new Executor(_session.getApplication(), valProps).execute(); } else { _session.getMessageHandler().showErrorMessage("No SQL specified"); } }
private void propertiesHaveChanged(String propName) { final SessionProperties props = _session.getProperties(); if (propName == null || propName.equals(SessionProperties.IPropertyNames.AUTO_COMMIT)) { SetAutoCommitTask task = new SetAutoCommitTask(); if (SwingUtilities.isEventDispatchThread()) { _session.getApplication().getThreadPool().addTask(task); } else { task.run(); } } if (propName == null || propName.equals(SessionProperties.IPropertyNames.SQL_EXECUTION_TAB_PLACEMENT)) { _tabbedExecutionsPanel.setTabPlacement(props.getSQLExecutionTabPlacement()); } }
private void addResultsTab(ResultTab tab, IResultTab resultTabToReplace) { if (null == resultTabToReplace && null == _stickyTab) { _tabbedExecutionsPanel.addTab(tab.getTitle(), null, tab, tab.getViewableSqlString()); checkResultTabLimit(); } else { if (null != resultTabToReplace && _session.getProperties().getKeepTableLayoutOnRerun()) { TableState sortableTableState = resultTabToReplace.getResultSortableTableState(); if (null != sortableTableState) { tab.applyResultSortableTableState(sortableTableState); } } int indexToReplace = -1; ImageIcon tabIcon = null; // Either resultTabToReplace or _stickyTab must be not null here if (null != resultTabToReplace && _stickyTab != resultTabToReplace) { indexToReplace = getIndexOfTab(resultTabToReplace); } else { indexToReplace = getIndexOfTab(_stickyTab); if (-1 == indexToReplace) { // sticky tab was closed _stickyTab = null; } else { tabIcon = getStickyIcon(); _stickyTab = tab; } } if (-1 == indexToReplace) { // Just add the tab addResultsTab(tab, null); return; } closeTabAt(indexToReplace); _tabbedExecutionsPanel.insertTab( tab.getTitle(), tabIcon, tab, tab.getViewableSqlString(), indexToReplace); } }
/** * Create the child nodes for the passed parent node and return them. Note that this method should * <B>not</B> actually add the child nodes to the parent node as this is taken care of in the * caller. * * @param session Current session. * @param node Node to be expanded. * @return A list of <TT>ObjectTreeNode</TT> objects representing the child nodes for the passed * node. */ public List<ObjectTreeNode> createChildren(ISession session, ObjectTreeNode parentNode) throws SQLException { final List<ObjectTreeNode> childNodes = new ArrayList<ObjectTreeNode>(); final IDatabaseObjectInfo parentDbinfo = parentNode.getDatabaseObjectInfo(); final ISQLConnection conn = session.getSQLConnection(); final SQLDatabaseMetaData md = session.getSQLConnection().getSQLMetaData(); final String catalogName = parentDbinfo.getCatalogName(); final String schemaName = parentDbinfo.getSchemaName(); final ObjFilterMatcher filterMatcher = new ObjFilterMatcher(session.getProperties()); String sql = SQL; if (isOS400) { sql = OS_400_SQL; } final PreparedStatement pstmt = conn.prepareStatement(sql); ResultSet rs = null; try { pstmt.setString(1, schemaName); pstmt.setString(2, filterMatcher.getSqlLikeMatchString()); rs = pstmt.executeQuery(); while (rs.next()) { IDatabaseObjectInfo si = new DatabaseObjectInfo( catalogName, schemaName, rs.getString(1), DatabaseObjectType.SEQUENCE, md); if (filterMatcher.matches(si.getSimpleName())) { childNodes.add(new ObjectTreeNode(session, si)); } } } finally { SQLUtilities.closeResultSet(rs); SQLUtilities.closeStatement(pstmt); } return childNodes; }
/** Create the <TT>IDataSet</TT> to be displayed in this tab. */ protected IDataSet createDataSet() throws DataSetException { final ISession session = getSession(); final ISQLConnection conn = session.getSQLConnection(); ISQLDatabaseMetaData md = session.getMetaData(); try { final Statement stmt = conn.createStatement(); try { final SessionProperties props = session.getProperties(); if (props.getContentsLimitRows()) { try { stmt.setMaxRows(props.getContentsNbrRowsToShow()); } catch (Exception ex) { s_log.error("Error on Statement.setMaxRows()", ex); } } final ITableInfo ti = getTableInfo(); /** * When the SessionProperties are set to read-only (either table or text) but the user has * selected "Make Editable" on the Popup menu, we want to limit the edit capability to only * that table, and only for as long as the user is looking at that one table. When the user * switches away to another table, that new table should not be editable. */ final String currentTableName = ti.getQualifiedName(); if (!currentTableName.equals(previousTableName)) { previousTableName = currentTableName; // needed to prevent an infinite loop _dataSetUpdateableTableModel.setEditModeForced(false); /** * Tell the GUI to rebuild itself. Unfortunately, this has the side effect of calling this * same function another time. The second call does not seem to be a problem, but we need * to have reset the previousTableName before makeing this call or we will be in an * infinite loop. */ // props.forceTableContentsOutputClassNameChange(); } /** * If the table has a pseudo-column that is the best unique identifier for the rows (like * Oracle's rowid), then we want to include that field in the query so that it will be * available if the user wants to edit the data later. */ String pseudoColumn = ""; try { BestRowIdentifier[] rowIDs = md.getBestRowIdentifier(ti); for (int i = 0; i < rowIDs.length; ++i) { short pseudo = rowIDs[i].getPseudoColumn(); if (pseudo == DatabaseMetaData.bestRowPseudo) { pseudoColumn = " ," + rowIDs[i].getColumnName(); break; } } } // Some DBMS's (EG Think SQL) throw an exception on a call to // getBestRowIdentifier. catch (Throwable th) { if (s_log.isDebugEnabled()) { s_log.debug("getBestRowIdentifier not supported for table " + currentTableName, th); } } // TODO: - Col - Add method to Databasemetadata that returns array // of objects for getBestRowIdentifier. For PostgreSQL put this kludge in // the new function. THis way all the kludges are kept in one place. // // KLUDGE!!!!!! // // For some DBs (e.g. PostgreSQL) there is actually a pseudo-column // providing the rowId, but the getBestRowIdentifier function is not // implemented. This kludge hardcodes the knowledge that specific // DBs use a specific pseudo-column. Additionally, as of pg 8.1, // you must create the table using "WITH OID" appended to the create // statement. Otherwise, OID column is not available by default. // if (pseudoColumn.length() == 0) { if (DialectFactory.isPostgreSQL(md)) { pseudoColumn = ", oid"; } if (DialectFactory.isOracle(md)) { pseudoColumn = ", ROWID"; } } ResultSet rs = null; try { // Note. Some DBMSs such as Oracle do not allow: // "select *, rowid from table" // You cannot have any column name in the columns clause // if you have * in there. Aliasing the table name seems to // be the best way to get around the problem. final StringBuffer buf = new StringBuffer(); buf.append("select tbl.*") .append(pseudoColumn) .append(" from ") .append(ti.getQualifiedName()) .append(" tbl"); String clause = _sqlFilterClauses.get(WhereClausePanel.getClauseIdentifier(), ti.getQualifiedName()); if ((clause != null) && (clause.length() > 0)) { buf.append(" where ").append(clause); } clause = _sqlFilterClauses.get( OrderByClausePanel.getClauseIdentifier(), ti.getQualifiedName()); if ((clause != null) && (clause.length() > 0)) { buf.append(" order by ").append(clause); } if (s_log.isDebugEnabled()) { s_log.debug("createDataSet running SQL: " + buf.toString()); } showWaitDialog(stmt); rs = stmt.executeQuery(buf.toString()); } catch (SQLException ex) { if (s_log.isDebugEnabled()) { s_log.debug("createDataSet: exception from pseudocolumn query - " + ex, ex); } // We assume here that if the pseudoColumn was used in the query, // then it was likely to have caused the SQLException. If not, // (length == 0), then retrying the query won't help - just throw // the exception. if (pseudoColumn.length() == 0) { throw ex; } // pseudocolumn query failed, so reset it. Otherwise, we'll // mistake the last column for a pseudocolumn and make it // uneditable pseudoColumn = ""; // Some tables have pseudo column primary keys and others // do not. JDBC on some DBMSs does not handle pseudo // columns 'correctly'. Also, getTables returns 'views' as // well as tables, so the thing we are looking at might not // be a table. (JDBC does not give a simple way to // determine what we are looking at since the type of // object is described in a DBMS-specific encoding.) For // these reasons, rather than testing for all these // conditions, we just try using the pseudo column info to // get the table data, and if that fails, we try to get the // table data without using the pseudo column. // TODO: Should we change the mode from editable to // non-editable? final StringBuffer buf = new StringBuffer(); buf.append("select *").append(" from ").append(ti.getQualifiedName()).append(" tbl"); String clause = _sqlFilterClauses.get(WhereClausePanel.getClauseIdentifier(), ti.getQualifiedName()); if ((clause != null) && (clause.length() > 0)) { buf.append(" where ").append(clause); } clause = _sqlFilterClauses.get( OrderByClausePanel.getClauseIdentifier(), ti.getQualifiedName()); if ((clause != null) && (clause.length() > 0)) { buf.append(" order by ").append(clause); } rs = stmt.executeQuery(buf.toString()); } final ResultSetDataSet rsds = new ResultSetDataSet(); // to allow the fw to save and reload user options related to // specific columns, we construct a unique name for the table // so the column can be associcated with only that table. // Some drivers do not provide the catalog or schema info, so // those parts of the name will end up as null. That's ok since // this string is never viewed by the user and is just used to // distinguish this table from other tables in the DB. // We also include the URL used to connect to the DB so that // the same table/DB on different machines is treated differently. rsds.setContentsTabResultSet( rs, _dataSetUpdateableTableModel.getFullTableName(), DialectFactory.getDialectType(md)); if (rs != null) { try { rs.close(); } catch (SQLException e) { } } // KLUDGE: // We want some info about the columns to be available for validating the // user input during cell editing operations. Ideally we would get that // info inside the ResultSetDataSet class during the creation of the // columnDefinition objects by using various functions in ResultSetMetaData // such as isNullable(idx). Unfortunately, in at least some DBMSs (e.g. // Postgres, HSDB) the results of those calls are not the same (and are less accurate // than) the SQLMetaData.getColumns() call used in ColumnsTab to get the column info. // Even more unfortunate is the fact that the set of attributes reported on by the two // calls is not the same, with the ResultSetMetadata listing things not provided by // getColumns. Most of the data provided by the ResultSetMetaData calls is correct. // However, the nullable/not-nullable property is not set correctly in at least two // DBMSs, while it is correct for those DBMSs in the getColumns() info. Therefore, // we collect the collumn nullability information from getColumns() and pass that // info to the ResultSet to override what it got from the ResultSetMetaData. TableColumnInfo[] columnInfos = md.getColumnInfo(getTableInfo()); final ColumnDisplayDefinition[] colDefs = rsds.getDataSetDefinition().getColumnDefinitions(); // get the nullability information and pass it into the ResultSet // Unfortunately, not all DBMSs provide the column number in object 17 as stated in the // SQL documentation, so we have to guess that the result set is in column order for (int i = 0; i < columnInfos.length; i++) { boolean isNullable = true; TableColumnInfo info = columnInfos[i]; if (info.isNullAllowed() == DatabaseMetaData.columnNoNulls) { isNullable = false; } if (i < colDefs.length) { colDefs[i].setIsNullable(isNullable); } } // ?? remember which column is the rowID (if any) so we can // ?? prevent editing on it if (pseudoColumn.length() > 0) { _dataSetUpdateableTableModel.setRowIDCol(rsds.getColumnCount() - 1); } return rsds; } finally { SQLUtilities.closeStatement(stmt); } } catch (SQLException ex) { throw new DataSetException(ex); } finally { disposeWaitDialog(); } }
private void onPropertyChange(String propertyName) { if (propertyName.equals(SessionProperties.IPropertyNames.SQL_EXECUTION_TAB_PLACEMENT)) { _tabbedExecutionsPanel.setTabPlacement( _session.getProperties().getSQLExecutionTabPlacement()); } }